Helo!
Last week i finished a tutorial about sprites and animations
with SDL.
The program compiles perfectly, but it throws an output error (Fatal signal:
Segmentation Fault (SDL Parachute Deployed). As i have seen this is a common
error message in SDL so it was a little hard to find it.
As i know (or i think i do) what the error is, i have been modifying the
code, trying to solve it. I must say that im not posting this mail as my
first solution, as i have been almost this two weeks trying to modify the
code in all ways to solve it, but as i cant repair it, i ask you for help.
Also, i didnt find a response from the autor of that tutorial, he never
replied. And I didnt found posts on forums about this.
Welll… the error (Full code at the end of the message)
I have a class called “SCspriteBase”, and a structure CSpriteFrame (public
class) wich is a class helper.
In this CSpriteBase class i will make new space for an array of
"CSpriteFrame"s.
This CSpriteFrames struct will hold all the images of a sprite animation.
struct CSpriteFrame // Class - Helper
{
SDL_Surface *frame_img; // Fram’s image
int pause;
};
class CSpriteBase
{
public:
int init(char *dir); // no class constructor. A init function instead.
CSpriteFrame *sAnim;
int mNumframes, mBuilt, mW, mH;
};
In the “CSpriteBase::init” function i do this in some place:
sAnim = new CSpriteFrame[number];
Well, as I THINK, the error is that, as i dont have a Class constructor -
destructor, where i can say “delete [] sAnim”. Those spaces reserved in
memory will never be freed.
I tryed all… i made again the class with a constructor and destructor, and
nothing. I tryed using “delete [] sAnim” inside the class, outside,
everywhere, and nothing.
I changed the code so may times with no results… it will ALWAYS compile,
but never run…
May be im confused and it is not a error about C++ or SDL implementation on
this program, i just dont know what else to do here.
Or may be I write the constructor-destructor de bad way when i tried to.
If someone can give me a TIP at list, it will be really apretiated.
THANKS A LOT IN ADVANTAGE!
If it helps, the tutorial is this one:
http://cone3d.gamedev.net/cgi-bin/index.pl?page=tutorials/gfxsdl/tut3
Here is the full code:
(NOTE: You will may be see some “disorganization” in my code… but its just
becouse i changed it lots of times trying to solve the problem.)
-------------------------------- the code -------------------------------
#include
#include <stdlib.h>
#include "SDL/SDL.h"
using namespace std;
// ------------------------- GLOBAL VARIABLES (BEFORE CLASSES)
SDL_Surface *screen, *back;
// ------------------------- NON-CLASS FUNCTIONS
SDL_Surface * ImageLoad(char *file)
{
SDL_Surface *tmp1, *tmp2;
tmp1 = SDL_LoadBMP(file);
tmp2 = SDL_DisplayFormat(tmp1);
SDL_FreeSurface(tmp1);
return tmp2;
}
int LoadBG()
{
back = ImageLoad(“data/bg.gmp”);
return 0;
}
void DrawIMG(SDL_Surface *img, int x, int y)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_BlitSurface(img, NULL, screen, &dest);
}
void DrawBG()
{
DrawIMG(back, 0, 0);
}
// -------------------------END OF NON-CLASS FUNCTIONS
// -------------------------CLASESSES
struct CSpriteFrame // Class - Helper
{
SDL_Surface *frame_img; // A FRAME IMAGE
int pause;
};
class CSpriteBase
{
public:
int init(char *dir);
CSpriteFrame *sAnim;
int mNumframes, mBuilt, mW, mH;
};
class CSprite
{
int mFrame;
int mX, mY, mOldX, mOldY;
int mAnimating;
int mDrawn;
float mSpeed;
long mLastupdate;
CSpriteBase *mSpriteBase;
SDL_Surface *mBackreplacement;
SDL_Surface *mScreen;
public:
// CSprite CLASS-FUNCTIONS Declaration.
int init(CSpriteBase *base, SDL_Surface *screen); // inicializacion
del objecto.
void draw(); // Dibujar objeto en supersficie.
void ClearBG(); // Limpiar el fondo del sprite.
void UpdateBG(); // Actualizar el FONDO del sprite.
// Currently displaying frame CONTROL
void setFrame(int fn) { mFrame = fn; }
int getFrame() { return mFrame; }
// SPEED Control
void setSpeed(float sn) { mSpeed = sn; }
float getSpeed() { return mSpeed; }
// ANIMATION Control
void TogAnim() { mAnimating = !mAnimating; }
void startAnim() { mAnimating = 1; }
void stopAnim() { mAnimating = 0; }
void rewind() { mFrame = 0; }
// SCREEN Positioning of Sprites CONTROL
void xadd(int nm) { mX+=nm; }
void yadd(int nm) { mY+=nm; }
void xset(int nm) { mX=nm; }
void yset(int nm) { mY=nm; }
void set(int nx, int ny) { mX = nx; mY = ny; }
};
// ------------------------- CLASS FUNCTIONS
// Function “init” of class CSpriteBase.
int CSpriteBase::init(char *dir)
{
char buffer[255]; // Buffer para guardar lineas del archivo de datos
char filename[50]; // Archivo de datos
char name_bmp[15]; // Archivo BMP de la frame
int pause=0,r=0,g=0,b=0;
FILE *fp;
sprintf(filename, "%s/info", dir);
if ((fp=fopen(filename, "r")) == NULL)
{
cout <<"Error abriendo archivo de datos: %s" << filename << endl;
return -1;
}
// Tomamos la primer linea, asi sabemos la cantidad de FRAMES de esta
animacion
fgets(buffer,255,fp);
sscanf(buffer, "FILES: %d", &mNumframes);
sAnim = new CSpriteFrame[mNumframes]; // Hacemos espacio para el sAnim
de este sprite.
mBuilt = 1;
int count = 0;
while (!feof(fp) && count < mNumframes)
{
fgets(buffer, 255, fp);
if (buffer[0] != '#' && buffer[0] != '\r' && buffer[0] != '\n' &&
buffer[0] != 0 && buffer[0] != ‘\0’)
{
sscanf(buffer, “%s %d %d %d %d”, name_bmp, &pause, &r, &g, &b);
// datos de la frame
sprintf(filename, “%s/%s”, dir, name_bmp);
SDL_Surface *temporal;
if ((temporal = SDL_LoadBMP(filename)) == NULL) // Cargamos la
frame en cuestion.
{
cout << "Error cargando frame: " << count+1 << endl <<
"archivo: "<<filename<<endl;
return -1;
}
if (r>=0)
SDL_SetColorKey (temporal, SDL_SRCCOLORKEY,
SDL_MapRGB(temporal->format, r,g,b) );
sAnim[count].frame_img = SDL_DisplayFormat(temporal);
SDL_FreeSurface(temporal);
sAnim[count].pause = pause;
if (!mW) mW = sAnim[count].frame_img->w;
if (!mH) mH = sAnim[count].frame_img->h;
count++;
} // End If
} // End While
fclose(fp);
return 0;
} // END of CSpriteBase::init function !
// CSprite CLASS functions
// CSprite::init()
int CSprite::init (CSpriteBase *base, SDL_Surface *screen)
{
mSpriteBase = base;
if (mSpriteBase->mBuilt)
{
if (mSpriteBase->mNumframes > 1)
{
mAnimating = 1;
mBackreplacement =
SDL_DisplayFormat(mSpriteBase->sAnim[0].frame_img);
}
mScreen = screen;
}
return 0;
} // END of CSprite::init(); FUNCTION
// Funcion UpdateBG() de la clase CSprite.
void CSprite::UpdateBG()
{
SDL_Rect srcrect;
srcrect.x = mX;
srcrect.y = mY;
srcrect.w = mSpriteBase->mW;
srcrect.h = mSpriteBase->mH;
mOldX = mX;
mOldY = mY;
SDL_BlitSurface(mScreen, &srcrect, mBackreplacement, NULL);
} // FIN CSprite::ClearBG();
// Funcion draw() de la clase CSprite
void CSprite::draw()
{
if (mAnimating == 1)
{
if (mLastupdate + mSpriteBase->sAnim[mFrame].pause * mSpeed <
SDL_GetTicks() );
{
mFrame++;
if (mFrame > mSpriteBase->mNumframes -1)
mFrame = 0;
mLastupdate = SDL_GetTicks();
}
}
if (mDrawn == 0) mDrawn = 1;
SDL_Rect dest;
dest.x = mX;
dest.y = mY;
SDL_BlitSurface(mSpriteBase->sAnim[mFrame].frame_img, NULL, mScreen,
&dest);
} // FIN CSprite::draw();
// Funcion ClearBG() de la clase CSprite.
void CSprite::ClearBG()
{
if (mDrawn == 1)
{
SDL_Rect dest;
dest.x = mOldX;
dest.y = mOldY;
dest.w = mSpriteBase->mW;
dest.h = mSpriteBase->mH;
SDL_BlitSurface(mBackreplacement, NULL, mScreen, &dest);
}
} // FIN funcion CSprite::ClearBG();
// ------------------------- POST-Class Global Variables
// Post-Class : Variables GLOBALES.
CSpriteBase vikingsbase, sunbase;
CSprite vikings1, vikings2, sun;
// Post-Class : Functions.
void MostrarEscena()
{
sun.ClearBG();
vikings1.ClearBG();
vikings2.ClearBG();
sun.UpdateBG();
vikings1.UpdateBG();
vikings2.UpdateBG();
sun.draw();
vikings1.draw();
vikings2.draw();
SDL_Flip(screen);
}
// ------------------------- MAIN FUNCTION
int main(int argc, char *argv[])
{
Uint8* keys;
if (SDL_Init(SDL_INIT_VIDEO) < 0 )
{
cout << "Error iniciando video: "<< SDL_GetError() <<endl;
return 1;
}
atexit(SDL_Quit);
screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE|SDL_HWPALETTE);
if (screen == NULL)
{
cout << "Error inicializando pantalla primaria: "<<
SDL_GetError()<< endl;
return 1;
}
// inicamos nuestras clases
vikingsbase.init("data/vikings");
sunbase.init("data/vun");
// iniciamos nuestras clases de objetos
sun.init(&sunbase, screen);
sun.set(480, 50);
sun.setSpeed(1);
vikings1.init(&vikingsbase, screen);
vikings1.set(150, 300);
vikings1.setSpeed(1);
vikings2.init(&vikingsbase, screen);
vikings2.set(350,300);
vikings2.setSpeed(1.5);
SDL_ShowCursor(0);
LoadBG();
DrawBG();
int done = 0;
SDL_Event salir;
while (done == 0)
{
while (SDL_PollEvent(&salir))
{
if (salir.type == SDL_QUIT) {done = 1;}
if (salir.type == SDL_KEYDOWN)
{
if (salir.key.keysym.sym == SDLK_ESCAPE) { done = 1; }
if (salir.key.keysym.sym == SDLK_SPACE)
sun.TogAnim(); }
}
}
keys = SDL_GetKeyState(NULL);
if ( keys[SDLK_UP] ) { vikings1.yadd(-1); }
if ( keys[SDLK_DOWN] ) { vikings1.yadd(1); }
if ( keys[SDLK_LEFT] ) { vikings1.xadd(-1); }
if ( keys[SDLK_RIGHT] ) { vikings1.xadd(1); }
MostrarEscena();
} DONE = 1
return 0;
}
Eduardo Garcia Rajo (h)------------------------------------------------------------------
Visite: http://www.solucion-digital.com.ar
SOLUCION DIGITAL
Redes - Software - Servicios