Search code examples
c++makefilesdl

Program immediately closes in SDL


I am trying to build my first program in SDL 1.2 simply to get familiar with SDL. I have a headache trying to understand why my program immediately closes.

Does this have to do with the way I'm compiling it?

Here is all of my code and don't worry about trying to find logical errors that don't have to do with the error at hand. I simply want to find out why the program is immediately closing upon starting it.

Guy.h:

#ifndef GUY_H
#define GUY_H

class Guy{
    public:
        Guy(int, int);
        void move();
        void adjustVelocity(int, int);
        int getX();
        int getY();
        int getXVel();
        int getYVel();
    private:
        int xPos, yPos, xVel, yVel;
};
#endif

Guy.cpp:

#include "Guy.h"

Guy::Guy(int x, int y){
    xPos = x;
    yPos = y;
}
void Guy::move(){
    xPos += xVel;
    yPos += yVel;
}
void Guy::adjustVelocity(int x, int y){
    xVel += x;
    yVel += y;
}
int Guy::getX(){
    return xPos;
}
int Guy::getY(){
        return yPos;
}
int Guy::getXVel(){
    return xVel;
}
int Guy::getYVel(){
    return yVel;
}

main.cpp:

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "Guy.h"
#include <string>
#include <iostream>

bool init();
bool loadAllFiles();
void paintScreen();
void update();
bool handle();
void cleanUp();

void addSurface(int, int, SDL_Surface*, SDL_Surface*, SDL_Rect* clip = NULL);
SDL_Surface* loadFile(std::string);
SDL_Surface* Screen;
SDL_Surface* BackgroundIMG;
SDL_Surface* GuyIMG;
Guy* Hunter;


int main(int argc, char* args[]){
    std::cout << "Why won't it even cout this?? :(" << endl;
    if(!init()){
        return 1;
    }
    if(!loadAllFiles()){
        return 2;
    }
    Hunter = new Guy(0,0);
    paintScreen();
    while(handle()){
        update();
    }

    cleanUp();
    return 0;

    SDL_Init(SDL_INIT_EVERYTHING);
    Screen = SDL_SetDisplayMode(640, 480, 32, SDL_SWSURFACE);
    SDL_Flip(Screen);
    SDL_Delay(1000);
}

bool init(){
    if(SDL_Init(SDL_INIT_EVERYTHING)==-1){
        return false;
    }
    Screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
    if(Screen==NULL){
        return false;
    }
    SDL_WM_SetCaption("First SDL Test On Own", NULL);
    return true;
}

bool loadAllFiles(){
    BackgroundIMG = loadFile("Background.png");
    GuyIMG = loadFile("Guy.png");
    if(BackgroundIMG==NULL || GuyIMG==NULL){
        return false;
    }
    else{
        return true;
    }
}

void paintScreen(){
    addSurface(0, 0, BackgroundIMG, Screen);
    addSurface(Hunter->getX(), Hunter->getY(), GuyIMG, Screen);
    SDL_Flip(Screen);
}

void update(){
    Hunter->move();
    addSurface(Hunter->getX(), Hunter->getY(), GuyIMG, Screen);
    SDL_Flip(Screen);
}

bool handle(){ 
    SDL_Event event;
    while(SDL_PollEvent(&event)){
        if(event.type==SDL_QUIT){
            return false;
        }
        else if(event.type==SDL_KEYDOWN){
            switch(event.key.keysym.sym){
                case SDLK_UP:
                    Hunter->adjustVelocity(0, -1);
                    break;
                case SDLK_DOWN:
                    Hunter->adjustVelocity(0, 1);
                    break;
                case SDLK_RIGHT:
                    Hunter->adjustVelocity(1, 0);
                    break;
                case SDLK_LEFT:
                    Hunter->adjustVelocity(-1, 0);
                    break;
            }
        }
    }
    return true;
}

void cleanUp(){
    SDL_FreeSurface(GuyIMG);
    SDL_FreeSurface(BackgroundIMG);
    SDL_Quit();
    delete Hunter;
}



void addSurface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip){
    SDL_Rect offset;
    offset.x = x;
    offset.y = y;
    SDL_BlitSurface(source, clip, destination, &offset);
}

SDL_Surface* loadFile(std::string s){
    SDL_Surface* surface = IMG_Load(s.c_str());
    if(surface==NULL){
        return NULL;
    }
    else{
        SDL_Surface* opsurface = SDL_DisplayFormat(surface);
        SDL_FreeSurface(surface);
        return opsurface;
    }
}

My makefile:

all: main.o
        g++ -o run main.o Guy.o -lSDL -lSDL_image
main.o: Guy.o
        g++ -c main.cpp
Guy.o:
        g++ -c Guy.cpp

Whenever I compile it with this makefile, I get no errors.


Solution

  • Your program immediately closes because you are using SDL_PollEvent(&event). This function will return false if there is no event to process, which in your case is happening when the program starts. If a user has to provide window inputs, the fact that there is no event to process is the rule and not the exception.

    You have 2 alternatives :

    1. Switch to SDL_WaitEvent. It is really similar to SDL_PollEvent, but the difference is that it is a blocking call.It has the advantage of being simple to obtain the behavior you expect from your app.
    2. Stay with SDL_PollEvent, and add a mechanism to defer execution when there is no event to process. In general people use a SDL_Delay with a delay of 0 or 10. The advantage is that you have control of what the app does when there is no events.

    Example of process loop scenario.

    SDL_Event event;
    bool stop = false;
    while(!stop){
        bool got_event = SDL_PollEvent(&event) > 0;
        if(got_event){
           stop = processEvent(event);
        }
        else {
            if(backGroundWorkTodo()){
               doBackGroundWork();
            }
            else{
              //may defer execution
              SDL_Delay(0);
            }
        }
    }