Hi,
I know C pretty well, but now am learning C++.
I am writing a maze program that wants to have a Windows (SDL) timer call back to a
member function in the Maze class.
The compiler is complaining, and I can't quite figure it out. It has to do with the SDL_AddTimer() function which needs a function pointer to Maze::Maze_timer_update() (see red in maze.cpp below).
Also, I'm not clear on how the member declaration should work to allow access toCode:C:\Prj\codeblocks\Amazing\maze.cpp||In constructor `Maze::Maze(unsigned int, unsigned int, unsigned int)':| C:\Prj\codeblocks\Amazing\maze.cpp|24|error: cannot convert `Uint32 (Maze::*)(Uint32, void*)' to `Uint32 (*)(Uint32, void*)' for argument `2' to `_SDL_TimerID* SDL_AddTimer(Uint32, Uint32 (*)(Uint32, void*), void*)'| C:\Prj\codeblocks\Amazing\maze.cpp|20|warning: unused variable 'Maze_array'| C:\Prj\codeblocks\Amazing\maze.cpp|24|warning: unused variable 'Maze_timer'| ||=== Build finished: 1 errors, 2 warnings ===|
Maze::Maze_timer_update(). It shouldn't be public, but private doesn't seem right
either. It should probably be a friend, but I don't see how to give just SDL access to it.
Any help is appreciated.
Maze.h:maze.cpp:Code:#ifdef __cplusplus #include <cstdlib> #else #include <stdlib.h> #endif #ifdef __APPLE__ #include <SDL/SDL.h> #else #include <SDL.h> #endif #ifndef maze_h #define maze_h #include <stack> #include <time.h> typedef struct int_vector_s { int x; int y; } int_vector_t; typedef enum MazeDirs_e { up=0, dn, lf, rt, dirs_last } MazeDirs_t; class Maze { private: bool *WallLocations; SDL_Surface *screen; MazeDirs_t MazeOptsMoves[dirs_last]; int MazeOptsMovesAvail; bool MazeDirsOK[dirs_last]; std::stack <int_vector_t> MazeTravelStack; uint16_t MazeTravelDist; MazeDirs_t MazeTravelDir; uint16_t MazeTravelXpos; uint16_t MazeTravelYpos; bool *Maze_array; SDL_Surface *Maze_screen; SDL_TimerID Maze_timer; public: Uint8 WallThickness; // Thickness of wall in pizxels Uint16 Width; // Width of maze in wall thicknesses (must be odd) Uint16 Height; // Height of maze in wall thicknesses (must be odd) Uint32 Maze_timer_update(Uint32 interval, void *UserData); Maze::Maze( unsigned int Width, unsigned int Height, unsigned int Wallthickness ); Maze::~Maze(); void Maze_iterate(class Maze* const); void Maze::Maze_draw(class Maze* const); }; #endifCode:#ifdef __cplusplus #include <cstdlib> #else #include <stdlib.h> #endif #ifdef __APPLE__ #include <SDL/SDL.h> #else #include <SDL.h> #endif #include "maze.h" #define MAZE_WALL_ELEMENT(MAZE,X,Y) (*((MAZE)->WallLocations+(MAZE)->Width*(Y)+(X))) Maze::Maze( unsigned int Width, unsigned int Height, unsigned int Wallthickness ) { MazeTravelStack.push( (int_vector_t){1,1} ); bool Maze_array = malloc( Width * Height * sizeof(bool) ); Maze_screen = SDL_SetVideoMode(Width*Wallthickness, Height*Wallthickness, 8, SDL_HWSURFACE|SDL_DOUBLEBUF); SDL_TimerID Maze_timer = SDL_AddTimer(2000, &Maze::Maze_timer_update, this); srand ( time(NULL) ); // clear screen SDL_FillRect(this->screen, 0, SDL_MapRGB(this->screen->format, 0xff, 0xff, 0xff)); { this->MazeTravelXpos = 1; this->MazeTravelYpos = 1; int x; int y; for (x=0; x<this->Width; x++) { for (y=0; y<this->Height; y++) { MAZE_WALL_ELEMENT(this,x,y) = x&1 && y&1 ? false : true; } } } } Maze::~Maze() { free (Maze::Maze_array); } Uint32 Maze::Maze_timer_update(Uint32 interval, void *UserData) { Maze_iterate(this); Maze_draw(this); return interval; } void Maze::Maze_iterate(class Maze* const) { if ( this->MazeTravelStack.size() || this->MazeOptsMovesAvail ) { this->MazeOptsMovesAvail = 0; if ( MazeTravelYpos>2 && MAZE_WALL_ELEMENT(this,MazeTravelXpos ,MazeTravelYpos-1) && MAZE_WALL_ELEMENT(this,MazeTravelXpos ,MazeTravelYpos-3) && MAZE_WALL_ELEMENT(this,MazeTravelXpos-1,MazeTravelYpos-2) && MAZE_WALL_ELEMENT(this,MazeTravelXpos+1,MazeTravelYpos-2) ) { MazeDirsOK[up]=true; this->MazeOptsMoves[this->MazeOptsMovesAvail++] = up; } else { MazeDirsOK[up]=false; } if ( MazeTravelYpos<this->Height-3 && MAZE_WALL_ELEMENT(this,MazeTravelXpos ,MazeTravelYpos+1) && MAZE_WALL_ELEMENT(this,MazeTravelXpos ,MazeTravelYpos+3) && MAZE_WALL_ELEMENT(this,MazeTravelXpos-1,MazeTravelYpos+2) && MAZE_WALL_ELEMENT(this,MazeTravelXpos+1,MazeTravelYpos+2) ) { MazeDirsOK[dn]=true; this->MazeOptsMoves[this->MazeOptsMovesAvail++] = dn; } else { MazeDirsOK[dn]=false; } if ( MazeTravelXpos>2 && MAZE_WALL_ELEMENT(this,MazeTravelXpos-1,MazeTravelYpos ) && MAZE_WALL_ELEMENT(this,MazeTravelXpos-3,MazeTravelYpos ) && MAZE_WALL_ELEMENT(this,MazeTravelXpos-2,MazeTravelYpos-1) && MAZE_WALL_ELEMENT(this,MazeTravelXpos-2,MazeTravelYpos+1) ) { MazeDirsOK[lf]=true; this->MazeOptsMoves[this->MazeOptsMovesAvail++] = lf; } else { MazeDirsOK[lf]=false; } if ( MazeTravelXpos<this->Width-3 && MAZE_WALL_ELEMENT(this,MazeTravelXpos+1,MazeTravelYpos ) && MAZE_WALL_ELEMENT(this,MazeTravelXpos+3,MazeTravelYpos ) && MAZE_WALL_ELEMENT(this,MazeTravelXpos+2,MazeTravelYpos-1) && MAZE_WALL_ELEMENT(this,MazeTravelXpos+2,MazeTravelYpos+1) ) { MazeDirsOK[rt]=true; this->MazeOptsMoves[this->MazeOptsMovesAvail++] = rt; } else { MazeDirsOK[rt]=false; } // We know which directions are OK, so now check: // if we run out of travel distance or the next step in the // current direction is not valid, we must pick a new acceptable direction. if ( this->MazeOptsMovesAvail ) { if ( !MazeTravelDist || !MazeDirsOK[MazeTravelDir] ) { MazeTravelDist = rand()%6+1; MazeTravelDir = this->MazeOptsMoves[rand()%this->MazeOptsMovesAvail]; MazeTravelStack.top().x = MazeTravelXpos; MazeTravelStack.top().y = MazeTravelYpos; } else { MazeTravelDist--; } // Ok, now we punch through a wall. switch ( MazeTravelDir ) { case up: MAZE_WALL_ELEMENT(this,MazeTravelXpos ,MazeTravelYpos-1) = false; MazeTravelYpos-=2; break; case dn: MAZE_WALL_ELEMENT(this,MazeTravelXpos ,MazeTravelYpos+1) = false; MazeTravelYpos+=2; break; case lf: MAZE_WALL_ELEMENT(this,MazeTravelXpos-1,MazeTravelYpos ) = false; MazeTravelXpos-=2; break; case rt: MAZE_WALL_ELEMENT(this,MazeTravelXpos+1,MazeTravelYpos ) = false; MazeTravelXpos+=2; break; case dirs_last: break; } } else { // Can't turn anywhere, so we must pop back on the stack. if ( MazeTravelStack.size()>1 ) { MazeTravelXpos = MazeTravelStack.top().x; MazeTravelYpos = MazeTravelStack.top().y; } } } } void Maze::Maze_draw(class Maze* const) { // Draw the maze on the screen int x; int y; Uint8 *p; Uint8 MazeWallBlockX; // This is for filling in blocks in the wall when the block is more than 1 pizel across. Uint8 MazeWallBlockY; // This is for filling in blocks in the wall when the block is more than 1 pizel across. for (x=0; x<this->Width; x++) { for (y=0; y<this->Height; y++) { if ( MAZE_WALL_ELEMENT(this,x,y) ) { for (MazeWallBlockX=0; MazeWallBlockX<this->WallThickness; MazeWallBlockX++) { for (MazeWallBlockY=0; MazeWallBlockY<this->WallThickness; MazeWallBlockY++) { p = (Uint8 *)(this->screen->pixels) + (y*this->WallThickness+MazeWallBlockY) * this->screen->pitch + (x*this->WallThickness+MazeWallBlockX) * this->screen->format->BytesPerPixel; *p = 0; } } } } } SDL_Flip(this->screen); }



LinkBack URL
About LinkBacks



