Unhandled exception at 0x71002A95 (SDL2_ttf.dll) - c++

I've been writing some rudimentary code in C++ with the SDL2 library. It was working flawlessly, but I needed to print some text on screen, and to do that, I had to download the SDL2 TTF library. I installed it just like I did with SDL2. I tried to simply print a word, but once I compile the code, Visual Studio says the following:
Unhandled exception at 0x71002A95 (SDL2_ttf.dll) in nuevo proyecto.exe:
0xC0000005: Access violation reading location 0x00000000.
And the program just doesn't work, it's frozen in a white screen (it worked with no problems before I tried to use the TTF library). What can I do? Thanks in advance. Here's my code:
#include "stdafx.h"
#include <SDL.h>
#include <SDL_ttf.h>
#include <string>
SDL_Window * ventana;
SDL_Surface * superficie;
SDL_Surface * alpha;
SDL_Surface * renderizar;
SDL_Surface * texto;
bool inicia = false, cierra=false;
SDL_Point mouse;
TTF_Font *fuente = TTF_OpenFont("arial.ttf", 20);
char* palabras="hola";
SDL_Color color = { 0, 0, 0, 0 };
int controles(){
SDL_GetMouseState(&mouse.x,&mouse.y);
return 0;
}
int graficos(char *archivo){ //la primera vez inicia ventana
//el argumento es el nombre del bmp a renderizar
if (inicia == false){ ventana = SDL_CreateWindow("ventana", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0); } //abre ventana solo una vez
inicia = true; // no permite que se abra mas de una vez la ventana
superficie = SDL_GetWindowSurface(ventana);
alpha = SDL_LoadBMP("alpha.bmp");
texto = TTF_RenderText_Solid(fuente, palabras, color);
renderizar = SDL_LoadBMP(archivo);
SDL_Rect rectangulo = { 0, 0, 640, 480 };
SDL_Rect rrenderizar = { mouse.x, mouse.y, 4, 4 };
SDL_Rect rtexto = { 0, 0, 60, 60 };
SDL_BlitSurface(alpha, NULL, superficie, &rectangulo);
SDL_BlitSurface(renderizar, NULL, superficie, &rrenderizar);
SDL_BlitSurface(texto, NULL, superficie, &rtexto);
SDL_UpdateWindowSurface(ventana);
return 0;
}
int main(int argc, char **argv)
{
TTF_Init();
SDL_Init(SDL_INIT_VIDEO);
SDL_Event evento;
while (!cierra){
SDL_PollEvent(&evento);
switch (evento.type){
case SDL_QUIT:cierra = true; break;
}
//programa aqui abajo
controles();
graficos("hw.bmp");
}
TTF_Quit();
SDL_Quit();
return 0;
}
PS: I do have the DLL's, fonts and other files in the Debug folder.

According to SDL_TTF Documentation:
int TTF_Init()
Initialize the truetype font API. This must be called
before using other functions in this library, except TTF_WasInit. SDL
does not have to be initialized before this call.
You call TTF_OpenFont before calling TTF_Init when declaring your font variable. Instead you should do:
TTF_Font* fuente = NULL;
int main()
{
TTF_Init();
fuente = TTF_OpenFont("arial.ttf", 20);
...
}

Related

SDL Pong Movement Bug

The problem with my code is that I am making a pong game in SDL 2.0 in c++. I did everything until creating the movement. When the player paddle moves, it leaves behind a trail in the same color as the paddle. I watched some videos on YouTube, but when they do the movement it's nice and clear and for me to fix this but I need to recolor the background every time the player moves, which makes it being all flashy and if I hold the button I don't see the paddle at all.
#include<iostream>
#include<SDL2/SDL.h>
#include<SDL2/SDL_image.h>
#include<windows.h>
#define width 800
#define height 600
using namespace std;
bool run = true;
class Player{
private:
SDL_Window* window = SDL_CreateWindow("Pong!", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_RESIZABLE);
SDL_Surface* Screen = SDL_GetWindowSurface(window);
Uint32 screen_color = SDL_MapRGB(Screen->format, 0, 0, 0);
Uint32 In_game_RGB = SDL_MapRGB(Screen->format, 255, 255, 255);
SDL_Rect Pl;
SDL_Rect AI;
SDL_Rect Ball;
SDL_Rect ClearP;
SDL_Rect ClearAI;
public:
Player(){
//Player parameters
Pl.x = 60;Pl.y = 225;Pl.w = 25;Pl.h = 200;
//AI parameters
AI.x = 720;AI.y = 225;AI.w = 25;AI.h = 200;
//Ball parameters
Ball.x = width/2;Ball.y = height/2+10;Ball.w = 25;Ball.h = 25;
//Recoloring parameters
ClearP.x = 0;ClearP.y = 0; ClearP.w = 375;ClearP.h = height;
ClearAI.x = 425;ClearAI.y = 0;ClearAI.w = 375;ClearAI.h = height;
//Make the screen color black
SDL_FillRect(Screen, NULL, screen_color);
}
void scrUpdate(){
SDL_UpdateWindowSurface(window);
}
void drawPlayer(){
SDL_FillRect(Screen, &Pl, In_game_RGB);
}
void drawComputer(){
SDL_FillRect(Screen, &AI, In_game_RGB);
}
void ball(){
SDL_FillRect(Screen, &Ball, In_game_RGB);
}
void Movement(){
if(GetAsyncKeyState(VK_DOWN)){
Pl.y += 2;
SDL_FillRect(Screen,&ClearP,screen_color);
}
if(GetAsyncKeyState(VK_UP)){
SDL_FillRect(Screen,&ClearP,screen_color);
Pl.y -= 2;
}
}
};
void EventCheck(){
SDL_Event event;
if(SDL_PollEvent(&event)){
if(event.type == SDL_QUIT){
run = false;
}
}
}
int main( int argc, char *argv[] )
{
SDL_Init(SDL_INIT_EVERYTHING);
Player Play;
//Player Computer();
while(run){
Play.scrUpdate();
Play.drawPlayer();
Play.drawComputer();
Play.ball();
Play.Movement();
EventCheck();
}
SDL_Quit();
return EXIT_SUCCESS;
}
It would help to show some code or an example of what you have been doing, or a link to one of the videos you have been watching:
Youtube tutorial
but I suggest taking a look at:
screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE); and SDL_Flip(screen) as those have to do with screen buffering and drawing.
Another possibilty is that you are running an outdated version of SDL, or an incompatible one with your current system.
To be able to give a more complete and proper answer, I'd highly suggest adding more information about your code, screenshots of results and your version of SDL and operating system.
Also, you said it was flashy when you hold the paddle. I think it must be that you are performing your logic to move the paddle and you redraw the paddle once it's still. If you are redrawing the entire screen constantly, consider double buffering.

C++ Debian SDL segmentation fault

I am using SDL to create a quiz game program. The code compiles fine, but when I run the output executable, I get a segmentation fault. I am trying to blit a button onto the screen. Here is my code:
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <stdio.h>
#undef main
void ablit(SDL_Surface* source, SDL_Surface* destination, int x, int y){
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, NULL, destination, &offset);
}
void acreatebutton(int x, int y, int w, int h, SDL_Color fill, SDL_Surface*
screenSurface, const char* buttontext, int fontsize, SDL_Color textfill){
SDL_Rect* buttonrect;
buttonrect->x = x;
buttonrect->y = y;
buttonrect->w = w;
buttonrect->h = h;
int fillint = SDL_MapRGB(screenSurface -> format, fill.r, fill.g,
fill.b);
SDL_FillRect(screenSurface, buttonrect, fillint);
TTF_Font* font = TTF_OpenFont("/usr/share/fonts/truetype/droid/DroidSansMono.ttf", fontsize);
SDL_Surface* buttontextsurface = TTF_RenderText_Solid(font, buttontext, textfill);
ablit(buttontextsurface, screenSurface, 300, 300);
TTF_CloseFont(font);
}
int main(int argc, char** argv){
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
SDL_Window* screen = SDL_CreateWindow("Quiz Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 500, 400,SDL_WINDOW_RESIZABLE);
SDL_Surface* screenSurface = SDL_GetWindowSurface( screen );
SDL_FillRect (screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0, 0, 255 ) );
SDL_Color black = {0, 0, 0};
TTF_Font* afont = TTF_OpenFont("/usr/share/fonts/truetype/droid/DroidSansMono.ttf", 35);
SDL_Surface* aQuiz_Game = TTF_RenderText_Solid(afont, "Quiz Game", black);
ablit(aQuiz_Game, screenSurface, 150, 50);
acreatebutton(175, 350, 200, 50, black, screenSurface, "Take Quiz", 35, black);
SDL_UpdateWindowSurface( screen );
SDL_Event windowEvent;
while (true){
if (SDL_PollEvent(&windowEvent))
{
if (windowEvent.type == SDL_KEYUP &&
windowEvent.key.keysym.sym == SDLK_ESCAPE) break;
}
SDL_GL_SwapWindow(screen);
}
TTF_CloseFont(afont);
SDL_Quit();
TTF_Quit();
return 0;
}
Th ablit function is for blitting, and the abutton function is for creating button images.
You should show, where does you code gets to the segfault, otherwise it's difficult to guess.
First culprit could be the line:
TTF_Font* afont = TTF_OpenFont("/usr/share/fonts/truetype/droid/DroidSansMono.ttf", 35);
You create the font, but doesn't check if it succeeded. If the font file doesn't exist on you computer, you will probably get a segmentation fault.
Second problem is in the function acreatebutton. You declare buttonrect as a pointer, but never initialize it! It's an UB and may do anything, e.g. crashing your program.
In this case you probably don't need it to be a pointer at all, so changing it to a simple variable on the stack should work:
SDL_Rect buttonrect;
buttonrect.x = x;
/* more code ... */
SDL_FillRect(screenSurface, &buttonrect, fillint);
You can find both these problems very easily.
Enable all warnings. GCC will tell you about uninitialized pointer when compiling (I recommend adding -Wall -Wextra -pedantic to you g++ flags).
Learn to use a debugger (GDB is an excelent one). The would tell you everything.
Try a memory sanitizer (compile with -fsanitize=address -g). It will very nicely show you, what went wrong.

Elementary inquiry about C++ (SDL2 library)

I'm fairly new to programming, so this question will probably be basic. I'm writing a very basic program in C++ with the SDL2 library (in Visual Studio 2013). When I was writing it, I came across a problem. I wrote the following:
int controles(){
//declare actions that will happen when a key is pressed
const Uint8 * estado = SDL_GetKeyboardState(NULL);
if (estado[SDL_SCANCODE_UP]){ y--; SDL_UpdateWindowSurface(ventana); }
if (estado[SDL_SCANCODE_DOWN]){ y++; SDL_UpdateWindowSurface(ventana); }
return 0;
}
The problem is that I need to update the window surface after the value of y is modified, but I get an error because ventana, the name of the window, is defined in another function. I tried to define ventana globally, but the program won't work then. I then thought the following; write a goto statement in graficos, the function where ventana is defined, in order to skip every other statement in that function, except for the one that updates the window surface. However, when I did that, the program doesn't even compile:
int graficos(int caso){
if (caso == 1) {goto reload;} //skip to reload if (1)
SDL_Init(SDL_INIT_VIDEO); //load SDL
//load graphics in memory
SDL_Window * ventana = SDL_CreateWindow("ventana", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
SDL_Surface * superficie = SDL_GetWindowSurface(ventana);
SDL_Surface * pantallainicio = SDL_LoadBMP("pantallainicio.bmp");
SDL_Surface * paleta = SDL_LoadBMP("paleta.bmp");
SDL_Rect rpantallainicio = { 0, 0, 640, 480 };
SDL_Rect rpaleta = { x, y, 16, 16 };
//render graphics
SDL_BlitSurface(pantallainicio, NULL, superficie, &rpantallainicio);
SDL_BlitSurface(paleta, NULL, superficie, &rpaleta);
SDL_UpdateWindowSurface(ventana);
reload:SDL_UpdateWindowSurface(ventana);
return 0;
}
I get the following errors:
error C4533: initialization of 'rpaleta' is skipped by 'goto reload'
error C4533: initialization of 'rpantallainicio' is skipped by 'goto reload'
I hope I explained my issue well enough. What can I do? Is there a way to fix this? Or can I reference ventana in some other way? This issue might be very basic, sorry for that, and thanks in advance!
You can fix this issue by simply not using goto at all - use a sub-function instead. Also, extract the variable ventana, as you need it to be stored and usable by graficos whenever.
void init()
{
SDL_Init(SDL_INIT_VIDEO); //load SDL
//load graphics in memory
ventana = SDL_CreateWindow("ventana", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
SDL_Surface * superficie = SDL_GetWindowSurface(ventana);
SDL_Surface * pantallainicio = SDL_LoadBMP("pantallainicio.bmp");
SDL_Surface * paleta = SDL_LoadBMP("paleta.bmp");
SDL_Rect rpantallainicio = { 0, 0, 640, 480 };
SDL_Rect rpaleta = { x, y, 16, 16 };
//render graphics
SDL_BlitSurface(pantallainicio, NULL, superficie, &rpantallainicio);
SDL_BlitSurface(paleta, NULL, superficie, &rpaleta);
}
int graficos(int caso)
{
if (caso != 1) { init(); } //skip to reload if (1)
SDL_UpdateWindowSurface(ventana);
return 0;
}
SDL_Window * ventana;
Use of goto should generally be avoided. Use subroutines or other alternatives where possible. Here, the code does exactly the same thing as originally intended, but the "extra" flow that occurs when caso is not 1 is wrapped in its own subroutine named 'init'.

C++ SDL texture Error Microsoft Visual Studio 2013

I'm trying to run this code but it keeps giving me an error.
I copyed SDL2_image.lib in the debug folder but in vain.
I'm at the beggining of programming so please be patient.
Errors:
Error 1 error C3861: 'IMG_LoadTexture': identifier not found
Error 2 IntelliSense: identifier "IMG_LoadTexture" is undefined
#include<SDL/SDL.h>
#include<iostream>
using namespace std;
int main(int argc, char** argv)
{
bool quit = false;
//*Initializing Window;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = NULL;
window = SDL_CreateWindow("Game Test", 100, 100, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
//*If game Crushes;
if (window == NULL)
{
cout << "The game window is not working";
}
//*Creating Update Function
SDL_Renderer* render = NULL;
render = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_Event* mainEvent = new SDL_Event();
//*End Update Function
//*Adding Textures;
SDL_Texture* grass_image = NULL;
grass_image = IMG_LoadTexture(render, "grass.bmp");
//*Creating a Sprite;
SDL_Rect grass_rect;
grass_rect.x = 10;
grass_rect.y = 50;
grass_rect.w = 250;
grass_rect.h = 250;
//*Content Of the Window;
while (!quit && mainEvent->type!=SDL_QUIT)
{
SDL_PollEvent(mainEvent);
SDL_RenderClear(render);
SDL_RenderCopy(render, grass_image, NULL, &grass_rect);
SDL_RenderPresent(render);
}
//*End Window Content
//*Memory Cleaning
SDL_DestroyWindow(window);
SDL_DestroyRenderer(render);
delete mainEvent;
//*End Memory Cleaning
return 0;
}
You are missing to include the header that contains the declaration of IMG_LoadTexture():
#include <SDL/SDL_image.h>
It's a separate extension library for SDL, and besides including that header, you'll also need to link that library with your project.

C++ SDL2, How to regularly update a renderered text? (ttf)

So I've been practicing/making a quick game for the past 6 hours, then something stumped me.
The game had an integer, Score, which would be added up with one every time an ammo hits an alien.
int Score;
stringstream sstr;
sstr << Score;
string str1 = sstr.str();
TTF_Font* Sans = NULL;
Sans = TTF_OpenFont("Sans.ttf", 24);
SDL_Color White = {255, 255, 255};
SDL_Surface* surfaceMessage = NULL;
surfaceMessage = TTF_RenderText_Solid(Sans, str1.c_str(), White);
SDL_Texture* Message = NULL;
Message = SDL_CreateTextureFromSurface(renderer, surfaceMessage);
SDL_Rect Message_rect;
Message_rect.x = 0;
Message_rect.y = 0;
Message_rect.w = 100;
Message_rect.h = 100;
//UPDATE/GAMELOOP AREA, I DIDN'T REALLY PASTE THE WHOLE PART
SDL_RenderCopy(renderer, Message, NULL, &Message_rect);
Now I've been trying different roundabouts as to how to update the texture, Message.
I made a cout check to check if I did hit an alien and what my current score is, it appears perfectly fine, but the rendered texture, Message won't move from 0.
I created a texture from the surface (the message) because I mostly prefer textures and I don't have any surface since in my current knowledge, you'd at least need a filled surface where you could blitz this
And another question, I'm planning to make a dialogue heavy game, is there another way of doing the texts? I've got a strong feeling that I'm doing it wrong.
Minimal runnable example
The counter gets updated every second.
Ubuntu 16.10, SDL 2.0.4:
sudo apt-get install libsdl2-dev libsdl2-ttf-dev
./main /path/to/my.ttf
This method is easy to integrate, but not very efficient as it re-rasters and re-creates textures all the time. If you also want efficiency, see: Rendering fonts and text with SDL2 efficiently I get 4k FPS, so it might be fine for simple applications.
GitHub upstream with a ttf file to test with: https://github.com/cirosantilli/cpp-cheat/blob/d36527fe4977bb9ef4b885b1ec92bd0cd3444a98/sdl/ttf.c:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#define COMMON_COLOR_MAX 255
#define COMMON_WINDOW_WIDTH 500
#define COMMON_WINDOW_HEIGHT (COMMON_WINDOW_WIDTH)
double common_get_secs(void) {
struct timespec ts;
timespec_get(&ts, TIME_UTC);
return ts.tv_sec + (1e-9 * ts.tv_nsec);
}
const double COMMON_FPS_GRANULARITY_S = 0.5;
double common_fps_last_time_s;
unsigned int common_fps_nframes;
void common_fps_init() {
common_fps_nframes = 0;
common_fps_last_time_s = common_get_secs();
}
void common_fps_update_and_print() {
double dt, current_time_s;
current_time_s = common_get_secs();
common_fps_nframes++;
dt = current_time_s - common_fps_last_time_s;
if (dt > COMMON_FPS_GRANULARITY_S) {
printf("FPS = %f\n", common_fps_nframes / dt);
common_fps_last_time_s = current_time_s;
common_fps_nframes = 0;
}
}
#define MAX_STRING_LEN 4
/*
- x, y: upper left corner of string
- rect output Width and height contain rendered dimensions.
*/
void render_text(
SDL_Renderer *renderer,
int x,
int y,
const char *text,
TTF_Font *font,
SDL_Rect *rect,
SDL_Color *color
) {
SDL_Surface *surface;
SDL_Texture *texture;
surface = TTF_RenderText_Solid(font, text, *color);
texture = SDL_CreateTextureFromSurface(renderer, surface);
rect->x = x;
rect->y = y;
rect->w = surface->w;
rect->h = surface->h;
/* This is wasteful for textures that stay the same.
* But makes things less stateful and easier to use.
* Not going to code an atlas solution here... are we? */
SDL_FreeSurface(surface);
SDL_RenderCopy(renderer, texture, NULL, rect);
SDL_DestroyTexture(texture);
}
int main(int argc, char **argv) {
SDL_Color color;
SDL_Event event;
SDL_Rect rect;
SDL_Renderer *renderer;
SDL_Window *window;
char *font_path, text[MAX_STRING_LEN];
/* CLI arguments. */
if (argc == 1) {
font_path = "FreeSans.ttf";
} else if (argc == 2) {
font_path = argv[1];
} else {
fprintf(stderr, "error: too many arguments\n");
exit(EXIT_FAILURE);
}
/* initialize variables. */
color.r = COMMON_COLOR_MAX;
color.g = COMMON_COLOR_MAX;
color.b = COMMON_COLOR_MAX;
color.a = COMMON_COLOR_MAX;
/* Init window. */
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(
COMMON_WINDOW_WIDTH,
COMMON_WINDOW_WIDTH,
0,
&window,
&renderer
);
/* Init TTF. */
TTF_Init();
TTF_Font *font = TTF_OpenFont(font_path, 24);
if (font == NULL) {
fprintf(stderr, "error: font not found\n");
exit(EXIT_FAILURE);
}
/* Main loop. */
common_fps_init();
while (1) {
if (SDL_PollEvent(&event) && event.type == SDL_QUIT) {
break;
}
/* Use TTF. */
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
render_text(renderer, 0, 0, "hello", font, &rect, &color);
render_text(renderer, 0, rect.y + rect.h, "world", font, &rect, &color);
snprintf(text, MAX_STRING_LEN, "%u", (unsigned int)(time(NULL) % 1000));
render_text(renderer, 0, rect.y + rect.h, text, font, &rect, &color);
SDL_RenderPresent(renderer);
common_fps_update_and_print();
}
/* Cleanup. */
TTF_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
Well, obviously you need to recreate texture from surface with new text each time your score changes. That is not very efficient for texts that change frequently (since you create/destroy a lot of surfaces/textures), but can be fine for small games (since modern computers are very powerful).
But generally, as mentioned in comments, for this case font atlases are used with combination of custom text renderers. The trick is to store all characters in one texture and render its regions multiple times to produce necessary text. The AngelCode BMFont is popuar tool for creating font atlases.
For maximum performance both approaches are used in combination: precreated textures for static text, and font atlases for dynamic text.