I've been stuck on this for a couple days now. Here's a link to the tutorial I tried to follow:
http://cone3d.gamedev.net/cgi-bin/index.pl?page=tutorials/gfxsdl/tut3
Here's my program. I pretty much went word for word with what that page said to do. Here is my source and data files:
http://www.tcbembroidery.com/colin/cpp/orex.zip
Here is just the source
//CSprite.h
#ifndef __CSPRITE_H__
#define __CSPRITE_H__
#include "CSpriteBase.h"
class CSprite
{
public:
int init(CSpriteBase *base, SDL_Surface *screen);
void draw();
void clearBG();
void updateBG();
void setFrame(int nr) { mFrame = nr; }
int getFrame() { return mFrame; }
void setSpeed(float nr) { mSpeed = nr; }
float getSpeed() { return mSpeed; }
void toggleAnim() { mAnimating = !mAnimating; }
void startAnim() { mAnimating = 1; }
void stopAnim() { mAnimating = 0; }
void rewind() { mFrame = 0; }
void xadd(int nr) { mX+=nr; }
void yadd(int nr) { mY+=nr; }
void xset(int nr) { mX=nr; }
void yset(int nr) { mY=nr; }
void set(int xx, int yy) { mX=xx; mY=yy; }
private:
int mFrame;
int mX, mY, mOldX, mOldY;
int mAnimating;
int mDrawn;
float mSpeed;
long mLastupdate;
CSpriteBase *mSpriteBase;
SDL_Surface *mBackreplacement;
SDL_Surface *mScreen;
};
#endif
//CSpriteBase.h
#ifndef __CSPRITEBASE_H__
#define __CSPRITEBASE_H__
#include <SDL/SDL.h>
struct CSpriteFrame
{
SDL_Surface *image;
int pause;
};
class CSpriteBase
{
public:
~CSpriteBase();
int init(char *dir);
CSpriteFrame *mAnim;
int mBuilt, mNumframes, mW, mH;
};
#endif
//CSprite.cpp
#include "CSprite.h"
int CSprite::init(CSpriteBase *base, SDL_Surface *screen)
{
mSpriteBase = base;
if(mSpriteBase->mBuilt)
{
if(mSpriteBase->mNumframes>1) mAnimating=1;
mBackreplacement =
SDL_DisplayFormat(mSpriteBase->mAnim[0].image);
}
mScreen = screen;
return 0;
}
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);
}
}
void CSprite::updateBG()
{
SDL_Rect srcrect;
srcrect.w = mSpriteBase->mW;
srcrect.h = mSpriteBase->mH;
srcrect.x = mX;
srcrect.y = mY;
mOldX=mX;mOldY=mY;
SDL_BlitSurface(mScreen, &srcrect, mBackreplacement, NULL);
}
void CSprite::draw()
{
if(mAnimating == 1)
{
if(mLastupdate+mSpriteBase->mAnim[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->mAnim[mFrame].image, NULL, mScreen,
&dest);
}
//CSpriteBase.cpp
#include <SDL/sdl.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <string>
#include "CSpriteBase.h"
CSpriteBase::~CSpriteBase()
{
delete[] mAnim;
}
int CSpriteBase::init(char *dir)
{
char buffer[255];
char filename[255];
char name[255];
int pause=0, r=0, g=0, b=0;
FILE *fp;
// Get info from info file
sprintf(filename, "%s/info", dir);
fp = fopen(filename, "r");
fgets(buffer, 255, fp);
sscanf(buffer, "FILES: %d", &mNumframes);
mAnim = new CSpriteFrame[mNumframes];
mBuilt = 1;
int count = 0;
// Loop through info file
while(!feof(fp) && count < mNumframes)
{
fgets(buffer, 255, fp);
if(buffer[0] != '#' && buffer[0] != '\r' && buffer[0] != '\0'
&& buffer[0] != '\n' && strlen(buffer) != 0)
{
// Since we now know that the line will be useful, we'll extract the name of the frame image,
// the milliseconds to pause after displaying it and the r, g and b of the transparent color.
// We'll then make the string filename equal the full path to the frame file and load it in.
sscanf(buffer, "%s %d %d %d %d", name, &pause, &r, &g, &b);
sprintf(filename, "%s/%s", dir, name);
SDL_Surface *temp;
temp = SDL_LoadBMP(filename);
// Now we'll check if the transparent color's r component is greater than or equal to zero. If so, we'll make temp transparent. But if r would be -1 or so, then we wouldn't have made the surface transparent.
if(r >= 0)
SDL_SetColorKey(temp, SDL_SRCCOLORKEY, SDL_MapRGB(temp->format, r, g, b));
mAnim[count].image = SDL_DisplayFormat(temp);
SDL_FreeSurface(temp);
mAnim[count].pause = pause;
if(!mW) mW = mAnim[count].image->w;
if(!mH) mH = mAnim[count].image->h;
count ++;
}
}
// close the file
fclose(fp);
return 0;
}
//main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#include <SDL/SDL.h>
#include "CSpriteBase.h"
#include "CSprite.h"
SDL_Surface *screen, *back;
CSpriteBase swordbase;
CSpriteBase moonbase;
CSprite sword;
CSprite moon;
SDL_Surface * ImageLoad(char *file)
{
SDL_Surface *temp1, *temp2;
temp1 = SDL_LoadBMP(file);
temp2 = SDL_DisplayFormat(temp1);
SDL_FreeSurface(temp1);
return temp2;
}
int InitImages()
{
back = ImageLoad("data/bg.bmp");
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);
SDL_Flip(screen);
DrawIMG(back, 0, 0);
}
void DrawScene()
{
moon.clearBG();
sword.clearBG();
moon.updateBG();
sword.updateBG();
moon.draw();
sword.draw();
SDL_Flip(screen);
}
void oxGameLoop()
{
// Initialize SDL video and audio systems.
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
atexit(SDL_Quit);
// Pointer to keyboard keys.
Uint8* keys;
// Create a screen surface.
screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
// Initialize images and sprites.
swordbase.init("data/sword");
moonbase.init("data/moon");
moon.init(&moonbase, screen);
moon.set(480, 50);
moon.setSpeed(1);
sword.init(&swordbase, screen);
sword.set(150, 300);
sword.setSpeed(1);
//Hide the mouse cursor
SDL_ShowCursor(0);
InitImages();
DrawBG();
// Main game loop.
bool bRunning = 1;
while(bRunning)
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
bRunning = 0;
if(event.type == SDL_KEYDOWN)
{
if(event.key.keysym.sym == SDLK_ESCAPE)
bRunning = 0;
if(event.key.keysym.sym == SDLK_SPACE)
moon.toggleAnim();
}
}
// input
keys = SDL_GetKeyState(NULL);
if (keys[SDLK_UP]) { sword.yadd(-1); }
if (keys[SDLK_DOWN]) { sword.yadd(1); }
if (keys[SDLK_LEFT]) { sword.xadd(-1); }
if (keys[SDLK_RIGHT]) { sword.xadd(1); }
DrawScene();
}// End main game loop.
}
//winmain.cpp
#include <windows.h>
#include <windowsx.h>
#define WIN32_LEAN_AND_MEAN
void oxGameLoop();
LRESULT CALLBACK MsgHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){
switch(msg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return(0);
}
default: break;
}
return(DefWindowProc(hwnd, msg, wparam, lparam));
}
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
oxGameLoop();
}
Now you'll see stuff in there like standard headers that I don't need. This is in from suggestions by other users at the bottom of that page. The program will compile fine, but when running only shows a black window before crashing.