Can't Close Window - c++

I'm following the Lazy Foo tutorial on C++ and SDL2. I'm trying to learn it using regular C and noticed something interesting when following instructions on adding events to detect a close window event.
Here is the code.
#include <stdio.h>
#include <stdbool.h>
#include "SDL2/SDL.h"
bool init();
bool loadMedia();
void close();
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
SDL_Window *gWindow = NULL;
SDL_Surface *gScreenSurface = NULL;
SDL_Surface *gHelloWorld = NULL;
int main(int argc, char *argv[])
{
if(!init()) {
printf("Failed to initialize!\n");
}
else {
if(!loadMedia()) {
printf("Failed to load media!\n");
}
else {
bool quit = false;
SDL_Event e;
while(!quit) {
printf("%d", SDL_PollEvent(&e));
while(SDL_PollEvent(&e) != 0) {
if(e.type == SDL_QUIT) {
quit = true;
}
}
SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);
SDL_UpdateWindowSurface(gWindow);
}
}
}
close();
return 0;
}
bool init()
{
bool success = true;
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else {
gWindow = SDL_CreateWindow("SDL Tutorial 03", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(gWindow == NULL) {
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else {
gScreenSurface = SDL_GetWindowSurface(gWindow);
}
}
return success;
}
bool loadMedia()
{
bool success = true;
gHelloWorld = SDL_LoadBMP("images/hello_world.bmp");
if(gHelloWorld == NULL) {
printf("Unable to load image %s! SDL_Error: %s\n", "images/hello_world.bmp", SDL_GetError());
success = false;
}
return success;
}
void close()
{
SDL_FreeSurface(gHelloWorld);
gHelloWorld = NULL;
SDL_DestroyWindow(gWindow);
gWindow = NULL;
SDL_Quit();
}
If I compile this with a ".c" extension, it compiles without errors, but selecting the "X" on the window title bar does nothing. If I change said extension to ".cpp", the "X" works as intended.
I'm using the following command to compile the code.
gcc main.c -w -lSDL2 -o main
Any ideas why this may work with C++, but not with C?

The function SDL_PollEvent will remove the event from the internal event queue if an address of an SDL_event object is passed to it.
The printf call, that also calls the function SDL_PollEvent, before the event loop which will remove the quit event from the queue. This means the event loop won't find this event:
printf("%d", SDL_PollEvent(&e));
while(SDL_PollEvent(&e) != 0) {
if(e.type == SDL_QUIT) {
quit = true;
}
}
If you only want to check if there are events pending in the queue, then use the function SDL_PollEvent with a NULL argument:
printf("%d", SDL_PollEvent(NULL));

Related

Can't draw simple bitmap to window in SDL2

I'm currently trying to set up a few C++ libraries for a future project. Namely, SDL2.
Here's my code:
#include <iostream>
#include <fstream>
#include <SDL.h>
int SCREEN_WIDTH = 457;
int SCREEN_HEIGHT = 497;
const char* imgpath = "Sprite.bmp";
std::string errmsg;
SDL_Window* window = NULL;
SDL_Surface* screensurface = NULL;
SDL_Surface* image = NULL;
SDL_Rect rect;
struct {
bool wdown;
bool adown;
bool sdown;
bool ddown;
bool edown;
bool escdown;
} kpresses;
void clearkpresses() {
kpresses.wdown = false;
kpresses.adown = false;
kpresses.sdown = false;
kpresses.ddown = false;
kpresses.edown = false;
kpresses.escdown = false;
}
void setrect() {
rect.x = 0;
rect.y = 0;
rect.w = 457;
rect.h = 497;
}
bool gameinit() {
std::ofstream errfile;
errfile.open("errlog.txt");
clearkpresses();
setrect();
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0 ) {
errmsg = "SDL could not initialize! SDL_Error:";
std::cout << errmsg << SDL_GetError() << std::endl;
errfile << errmsg << SDL_GetError() << std::endl;
errfile.std::ofstream::close();
return false;
}
screensurface = SDL_GetWindowSurface(window);
window = SDL_CreateWindow("Transcend", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if( window == NULL ){
errmsg = "Window could not be created! SDL_Error:";
std::cout << errmsg << SDL_GetError() << std::endl;
errfile << errmsg << SDL_GetError() << std::endl;
errfile.std::ofstream::close();
return false;
}
image = SDL_LoadBMP(imgpath);
if (image == NULL) {
errmsg = "Media unable to load! IMG Error: ";
std::cout << errmsg << SDL_GetError() << std::endl;
errfile << errmsg << SDL_GetError() << std::endl;
errfile.std::ofstream::close();
return false;
}
return true;
}
void gamehalt()
{
SDL_DestroyWindow(window);
window = NULL;
SDL_Quit();
}
int main(int argc, char* args[]) {
if (!gameinit()) {
gamehalt();
return 0;
}
bool quit = false;
SDL_Event event;
while (!quit) {
while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT) {
quit = true;
}
switch(event.type) {
case SDLK_w:
kpresses.wdown = true;
case SDLK_a:
kpresses.adown = true;
case SDLK_s:
kpresses.sdown = true;
case SDLK_d:
kpresses.ddown = true;
case SDLK_e:
kpresses.edown = true;
case SDLK_ESCAPE:
kpresses.escdown = true;
}
}
//TODOUpdate
//TODORender
SDL_BlitSurface(image, NULL, screensurface, &rect);
SDL_UpdateWindowSurface(window);
//reset
clearkpresses();
}
gamehalt();
return 0;
}
Compiled, assembled, and linked with this windows cmd command:
g++ Main.cpp -static-libgcc -static-libstdc++ -I..\include\SDL2\include\SDL2 -I..\include\SDL2_image\include\SDL2 -L..\include\SDL2\lib -L..\include\SDL2_image\lib -w -lmingw32 -lSDL2main -lSDL2 -o ../Transcend.exe
It compiles and runs with no errors, but only displays a blank screen.
The problem is that you are trying to get the window surface, but the window isn't already created.
Please swap those two lines:
screensurface = SDL_GetWindowSurface(window);
window = SDL_CreateWindow("Transcend", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
This way:
window = SDL_CreateWindow("Transcend", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
screensurface = SDL_GetWindowSurface(window);

Program building correctly but not running

This is my code:
#include <SDL2/SDL.h>
#include <stdio.h>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
int main(int argc, char* args[])
{
SDL_Window* window = NULL;
SDL_Surface* screenSurface = NULL;
if (SDL_Init(SDL_INIT_VIDEO ) < 0 )
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
}
else
{
window = SDL_CreateWindow("Title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if (window == NULL)
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
}
else
{
screenSurface = SDL_GetWindowSurface(window);
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF ));
SDL_UpdateWindowSurface(window);
SDL_Event e; bool quit = false; while( quit == false ){ while( SDL_PollEvent( &e ) ){ if( e.type == SDL_QUIT ) quit = true; } }
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
}
}
The program builds all fine no errors no warnings no nothing. But when it comes to running it. My window pc says This app can't run on your pc. Does anyone know how to fix this?
The build system i am using is gcc mingw.
COMMAND:
g++ Test.cpp -I"include" -L"lib" -Wall -lmingw32 -lSDL2main -lSDL2 -mwindows -o Test.exe

SDL crashes itself and other windows

I've written small sdl application. Problem is that is crashes almost everything when I launch it. Every window loses title bar. Application sometimes pops up, sometimes doesn't. If it does, pressing q (key for quitting) closes it but other windows remains 'broken'. Only way to get rid of this is to logout and then log in again.
Here's code:
#include <bits/stdc++.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
const int screen_x = 800;
const int screen_y = 600;
SDL_Window* window = nullptr;
SDL_Texture* textures[3];
SDL_Texture* currentTexture = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_Event event;
bool running = true;
SDL_Texture* loadTexture(const char* path)
{
SDL_Texture* texture = nullptr;
SDL_Surface* load = IMG_Load(path);
if (!load)
{
printf("Failed to load image %s. Error: %s\n", path, IMG_GetError());
}
else
{
texture = SDL_CreateTextureFromSurface(renderer, load);
if (!texture)
{
printf("Failed to convert surface from %s. Error: %s\n", path, SDL_GetError());
}
SDL_FreeSurface(load);
}
return texture;
}
bool loadMedia()
{
bool success = true;
currentTexture = textures[0] = loadTexture("./img/1.png");
if (!textures[0])
{
printf("Failed to load texture\n");
success = false;
}
textures[1] = loadTexture("./img/2.png");
if (!textures[1])
{
printf("Failed to load texture\n");
success = false;
}
textures[2] = loadTexture("./img/3.png");
if (!textures[2])
{
printf("Failed to load texture\n");
success = false;
}
return success;
}
bool init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
else
{
window = SDL_CreateWindow("SDL with linux", 0, 0, screen_x, screen_y, SDL_WINDOW_SHOWN);
if (!window)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
else
{
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
else
{
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
int imgFlags = IMG_INIT_PNG;
if ((IMG_Init(imgFlags) & imgFlags) != imgFlags)
{
printf("Error: %s\n", SDL_GetError());
return false;
}
}
}
}
return true;
}
void close()
{
for (unsigned i = 0; i < 3; i++)
{
SDL_DestroyTexture(textures[i]);
textures[i] = nullptr;
}
SDL_DestroyRenderer(renderer);
renderer = nullptr;
SDL_DestroyWindow(window);
window = nullptr;
IMG_Quit();
SDL_Quit();
}
int main(int argc, char** argv)
{
if (!init())
{
printf("Initialization error\n");
}
else
{
if (!loadMedia())
{
printf("Media loading error\n");
}
else
{
while (running)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
running = false;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_q:
running = false;
break;
case SDLK_1:
currentTexture = textures[0];
break;
case SDLK_2:
currentTexture = textures[1];
break;
case SDLK_3:
currentTexture = textures[2];
break;
}
break;
}
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, currentTexture, nullptr, nullptr);
SDL_RenderPresent(renderer);
SDL_Delay(80);
}
}
}
close();
return 0;
}
Makefile:
CC = g++
CFlags = -Wall -std=c++11
Input = main.cpp
Output = -o ./bin/prog
Linker = -lSDL2 -lSDL2_image -lSDL2_ttf -lSDL2_mixer
all:
$(CC) $(Input) $(CFlags) $(Linker) $(Output)
Screenshot showing behavior of application
Im sorry this is going to be more like a comment but i dont have 50 reputation to comment in questions . Can you provide a screenshot of the window?
If not then try using SDL_WINDOWPOS_CENTERED at the x and y axis then see if the window is showing up. Please share if this worked

SDL fails to display image?

My code doesn't display anything. All I get is a window with no image.
#include <iostream>
#include <stdio.h>
#include <SDL2/SDL.h>
using namespace std;
SDL_Window *gWindow=NULL;
SDL_Surface *gScreenSurface=NULL;
SDL_Surface *gHelloWorld=NULL;
const int SCREEN_WIDTH=640, SCREEN_HEIGHT=480;
bool init(){
bool success = true;
if(SDL_Init (SDL_INIT_VIDEO) < 0 ) {
printf("SDL could not initialize! SDL_Error : %s \n", SDL_GetError() );
success=false;
}
else{
gWindow = SDL_CreateWindow ( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if( gWindow == NULL ){
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
success=false;
}
else {
gScreenSurface = SDL_GetWindowSurface (gWindow);
}
}
return success;
}
bool loadMedia(){
bool success=true;
gHelloWorld = SDL_LoadBMP ( "hello_world.bmp" );
if (gHelloWorld == NULL ){
printf( "Unable to load image %s! SDL Error: %s\n", "hello_world.bmp", SDL_GetError() );
success=false;
}
return success;
}
void close(){
SDL_FreeSurface( gHelloWorld );
gHelloWorld=NULL;
SDL_DestroyWindow( gWindow );
gWindow=NULL;
SDL_Quit();
}
int main(int argc, char* args[]){
if(!init()){
printf( "failed to initialize!\n" );
}
else {
if( !loadMedia() ) {
printf ("failed to laod media! \n");
}
else {
SDL_BlitSurface( gHelloWorld, NULL, SDL_GetWindowSurface(gWindow), NULL );
SDL_UpdateWindowSurface ( gWindow );
SDL_Delay (2000);
}
}
close();
I expect it to show me a bmp image which is in the path specified here in the loadBMP() function but all I get is an empty transparent window.
I am using KDE Konsole, if that has to do something with this.
KDE eh? Plasma composites by default; try disabling compositing or add a proper event-handling loop so your process has a chance to handle repaint events.

ld: library not found for

So I just started doing some SDL tutorials and I got to one when suddenly I get an error message saying "ld: library not found for -lstring". Says the same thing about stdio.
I tried adding the paths and libraries. I use the MacOS X C++ Linker (MacOSX GCC Tool Chain) but I just can't seem to get it to work. Any ideas?
I'm on Eclipse btw.
/*
* Main.cpp
*
* Created on: 29 jan 2014
* Author: CaptainAwesome
*/
//Using SDL and standard IO
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
#include <string>
//Starts up SDL and creates window
bool init();
//Loads media
bool loadMedia();
//Free media and shuts down SDL
void close();
//Loads individual image
SDL_Surface* loadSurface(std::string path);
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
enum KeyPressSurfaces
{
KEY_PRESS_SURFACE_DEFAULT,
KEY_PRESS_SURFACE_UP,
KEY_PRESS_SURFACE_DOWN,
KEY_PRESS_SURFACE_LEFT,
KEY_PRESS_SURFACE_RIGHT,
KEY_PRESS_SURFACE_TOTAL
};
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//The image that corresponds to a keypress
SDL_Surface* gKeyPressSurfaces[ KEY_PRESS_SURFACE_TOTAL];
//The image we will load and show on the screen
SDL_Surface* gCurrentSurface = NULL;
bool init()
{
//Init flag
bool success = true;
//Init SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Create window
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(gWindow == NULL)
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Get window surface
gScreenSurface = SDL_GetWindowSurface( gWindow );
}
}
return success;
}
SDL_Surface* loadSurface(std::string path)
{
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
if(loadedSurface == NULL)
{
printf("Unable to load image %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
}
return loadedSurface;
}
bool loadMedia()
{
//Load success flag
bool success = true;
//Load default surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT] = loadSurface("Assets/maxresdefault.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT] == NULL)
{
printf("Unable to load default image %s\n!");
success = false;
}
//Load up surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_UP] = loadSurface("Assets/1.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_UP] == NULL)
{
printf("Unable to load up image %s\n!");
success = false;
}
//Load down surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN] = loadSurface("Assets/duty_calls");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN] == NULL)
{
printf("Unable to load down image %s\n!");
success = false;
}
//Load up surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT] = loadSurface("Assets/mario-land.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT] == NULL)
{
printf("Unable to load left image %s\n!");
success = false;
}
//Load up surface
gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT] = loadSurface("Assets/ML.jpg");
if(gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT] == NULL)
{
printf("Unable to load right image %s\n!");
success = false;
}
return success;
}
void close()
{
//Deallocate surface
SDL_FreeSurface(gCurrentSurface);
gCurrentSurface = NULL;
//Destroooooy window
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//Quit SDL subsystems
SDL_Quit();
}
int main (int argc, char* args[])
{
//Start up SDL and create window
if(!init())
{
printf("Fail to init!\n");
}
else
{
//Load media
if(!loadMedia())
{
printf("Failed to load media!\n");
}
else
{
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//Set default current surface
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT];
//While app is running
while(!quit)
{
while(SDL_PollEvent(&e) != 0)
{
//User presses esc
if(e.type == SDL_QUIT)
{
quit = true;
}
//User presses a key (up, down, left, right)
else if(e.type)
{
//Select surfaces based on key pressed
switch(e.key.keysym.sym)
{
case SDLK_UP:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_UP];
break;
case SDLK_DOWN:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN];
break;
case SDLK_LEFT:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT];
break;
case SDLK_RIGHT:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT];
break;
case SDLK_ESCAPE:
quit = true;
break;
default:
gCurrentSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT];
break;
}
}
//Apply image
SDL_BlitScaled(gCurrentSurface, NULL, gScreenSurface, NULL);
//Update surface
SDL_UpdateWindowSurface(gWindow);
}
}
}
}
//Free resources and close SDL
close();
return 0;
}