Original Post
Is SDL_SetTimer called from SDL_FreeSurface? The reason I ask is that I am getting a SIGSEGV fault occuring apparently within SDL_SetTimer and the stack trace says that the function that was called before hand was SDL_FreeSurface. I don't specifically call SDL_SetTimer in my program so I am confused as to why the program was in there at all. What I am tryig to do is to get my program to create a Sprite object: and then add two SpriteFrames to it. The code for adding the frames is this: When I only call add_frame once it seems to work fine, however when I tried to test the animation capabilities I encountered this error. Could someone please try and help me with this? Thanks in advance for the help.
struct SpriteFrame
{
// Holds the image data.
GLuint image;
// The time at which the next image is to
// be shown.
int endTime;
// Holds the width and height of the image.
int w, h;
};
class Sprite
{
protected:
// Vector holding the frames for the sprite.
std::vector<SpriteFrame> frames;
// Total duration of the sprite's animation.
int totalDuration;
// The current time passed since the sprite
// was last reset.
int currTime;
// The current frame index of the sprite.
int currIndex;
// The current x and y position of the sprite.
float x, y;
// Holds the horizontal and vertical velocities
// of the sprite in pixels per second.
float hVel, vVel;
// The binding rectangle of the sprite used for
// collision detection.
SDL_Rect binding;
// Can the image be cycled?
bool cycle;
public:
// Creates a new Sprite object.
Sprite();
// Adds an image to the sprite. Returns false
// if the image fails to load.
bool add_frame(std::string file, int endTime);
// Same as above but takes an image from a sprite sheet.
//bool add_frame(std::string file, int endTime, int xOffset, int yOffset,
// int imageWidthint, int imageHeight, int a);
// Same as above excepting that this takes r, g
// and b values for a colour key.
//bool add_frame(std::string file, int endTime, int a, int r, int g, int b);
// Same as above but takes an image from a sprite sheet.
//bool add_frame(std::string file, int endTime, int xOffset, int yOffset,
// int imageWidthint, int imageHeight, int a, int r, int g, int b);
// Removes a frame from the sprite.
//void remove_frame(int index);
// Resets the sprite to the beginning.
void reset();
// Updates the sprite based on elapsed time.
void update(int elapsedTime);
// Draws the current image of the sprite.
void draw();
// Sets and gets the current position of the sprite.
void set_position(float nx, float ny){ x = nx; y = ny; }
void set_x(float nx) { x = nx; }
void set_y(float ny) { y = ny; }
float get_x() { return x; }
float get_y() { return y; }
// Sets and gets the current horizontal and vertical
// velocities of the sprite.
void set_hVel(float x){ hVel = x; }
void set_vVel(float y){ vVel = y; }
float get_hVel() { return hVel; }
float get_vVel() { return vVel; }
// Sets and gets the current index of the animation.
void set_index(int i){ currIndex = i; }
int get_index() { return currIndex; }
// Sets and gets whether the image is cycling
void set_cycle(bool on){ cycle = on; }
bool is_cycling() { return cycle; }
// Gets and sets the binding rectangle for collision
// detection.
void set_binding(int width, int height){ binding.w = width; binding.h = height; }
SDL_Rect get_binding() { return binding; }
};
bool Sprite::add_frame(std::string file, int endTime)
{
// Create a frame object
SpriteFrame frame;
// Set the endTime for the frame.
frame.endTime = endTime;
// Create two SDL_Surface pointers for storing and
// optimizing the image.
SDL_Surface *loadedImage;
SDL_Surface *optimizedImage;
// Load the image.
loadedImage = IMG_Load(file.c_str());
// If the image loaded correctly...
if(loadedImage != NULL)
{
// Optimize the image
optimizedImage = SDL_DisplayFormat(loadedImage);
// Free the old image
SDL_FreeSurface(loadedImage);
}
else
{
// Quit the program.
std::cerr << "An Image loaded incorrectly...\n";
return false;
}
// Get the number of colours in the image.
int noOfColours = optimizedImage->format->BytesPerPixel;
GLenum texture_format;
if(noOfColours == 4)
{
// Alpha channel is present.
if(optimizedImage->format->Rmask == 0x000000FF)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
}
else if(noOfColours == 3)
{
// Aplha is not present.
if(optimizedImage->format->Rmask == 0x000000FF)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
}
else
{
std::cerr << "A loaded image was not true colour...\n";
return false;
}
// Create a texture holder.
glGenTextures(1, &(frame).image);
// Bind the texture.
glBindTexture(GL_TEXTURE_2D, frame.image);
// Create the actual texture using the image.
glTexImage2D(GL_TEXTURE_2D, 0, noOfColours, optimizedImage->w, optimizedImage->h,
0, texture_format, GL_UNSIGNED_BYTE, optimizedImage->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Set the width ad height of the frame.
frame.w = optimizedImage->w;
frame.h = optimizedImage->h;
// Free the SDL_Surfaces.
SDL_FreeSurface(optimizedImage);
SDL_FreeSurface(loadedImage);
// Add the frame to the frames vector.
frames.push_back(frame);
// Sets the total duration.
totalDuration = endTime;
// Reset the sprite.
reset();
// Everything worked, return true.
return true;
}