Thread: maps, tilesets, and blitting (SDL)

  1. #1
    Registered User
    Join Date
    Sep 2001
    Posts
    305

    maps, tilesets, and blitting (SDL)

    my prog segfaults on the line that i try to blit on. everything is loaded correctly... but its just being stupid or whatever. rect.x and rect.y are correct, so forget about that (i kno that they are going to be either 0 or negative numbers but thats what i wnat). please help!
    Code:
    struct rpgOnMap{
        int ref;
        int x, y;
    };
    
    class rpgTileset{
      public:
        vector<SDL_Surface*> set;
    
        void init( const char* filename ){
            int i;
            string image_file;
            SDL_Surface* tmpsurface;
            ifstream file( filename );
            if( file.bad() ){ cerr << "Could not find tileset file!"; exit(1); }
            for( i = 0; i != 256; i++ ){
                getline( file, image_file );
                tmpsurface = IMG_Load( image_file.c_str() );
                if( tmpsurface == NULL ){ cerr << image_file << " not loaded correctly.\n"; exit(1); }
                set.push_back( tmpsurface );
                SDL_FreeSurface( tmpsurface );
                if( file.eof() ) break;
            }
        }
    
        rpgTileset( const char* filename ){
            init( filename );
        }
        rpgTileset(){}
    }; vector<rpgTileset> tileset;
    
    class rpgMap{
      public:
        int x, y;
        int w, h;
        vector< vector<bool> > wall;
        int tileset_ref;
        vector< vector<int> > data[3];
        char frame;
         
        vector<rpgOnMap> object[7];
    
        void init( const char* filename );
        rpgMap( const char* filename ){ init( filename ); }
        rpgMap(){}
    
        void Blit( int xparam, int yparam );
        void Move( char direction );
        void Animate();
    }; vector<rpgMap> map;
    
    void rpgMap::init( const char* filename ){
        ifstream file( filename );
        if( file.bad() ){ cerr << "Could not find map file!"; exit(1); }
        char erase;   
        int i, j = 0, tmpint, temp;
        bool tmpbool;
        rpgOnMap tmpobj;
        vector<rpgOnMap> tmpobjvec;
        vector<int> tmpvec;
        vector<bool> tmpboolvec;
    
        frame = 0;
    
        file >> x;
        file.get( erase );
        file >> y;
    
        file >> w;
        file.get( erase );
        file >> h;
        file >> tileset_ref;
        if( tileset.size() < tileset_ref ){ cerr << "Tilesets loaded incorrectly!\n"; exit(1); }
     
        for( i = 0; i != h; i++ ){
            for( j = 0; j != w; j++ ){
                file >> tmpbool;
                tmpboolvec.push_back( tmpbool );
            }
            wall.push_back( tmpboolvec );
            tmpboolvec.clear();
        }
        file.get( erase );
    
        for( temp = 0; temp != sizeof(data)/sizeof(data[0]); temp++ ){
        for( i = 0; i != h; i++ ){
            for( j = 0; j != w; j++ ){
                file >> tmpint;
                tmpvec.push_back( tmpint );
            }
            data[i].push_back( tmpvec );
            tmpvec.clear();
        }
            file.get( erase );
        }
    
        for( i = 0; i != sizeof(object)/sizeof(object[0]); i++ ){
           erase = '\0';
        while( erase != '\n' ){
           file >> tmpobj.ref;
           file >> tmpobj.x;
           file >> tmpobj.y;
           file.get( erase );
           object[i].push_back( tmpobj );
           if( file.eof() ) break;
        }
        }
    
        file.close();
    }   
    
    void rpgMap::Blit( int xparam, int yparam ){
        SDL_FillRect( screen, NULL, 0 );
        int i, j, temp = 0;
        x = xparam;
        y = yparam;
    
        SDL_Rect rect;
        rect.w = TILE_W;
        rect.h = TILE_H;
        for( i = 0; i != h; i++ ){
            rect.y = -y + ( TILE_H * i );
            for( j = 0; j != w; j++ ){
                //check if the current tile is on the screen, and if so, blit
                if( j * TILE_W > x - (TILE_W - 1) && j * TILE_W < SCREEN_W + (TILE_W - 1) && i > y - (TILE_H - 1) && i < SCREEN_H + (TILE_H - 1) ){
                    if( i == 0 ) rect.y = -y;
                    rect.x = -x + ( TILE_W * j );
                    if( tileset[tileset_ref].set.size() < data[frame][i][j] ){ cerr << "Tilesets loaded incorrectly!\n"; exit(1); }
                    if( SDL_BlitSurface( tileset[tileset_ref].set[data[frame][i][j]], NULL, screen, &rect ) < 0 )
                        cout << "BlitSurface error: " << SDL_GetError() << endl;
                }
            }
        }
    }
    
    void rpgMap::Move( char direction ){
        switch( direction ){
            case UP: Blit( x, y - 1 ); break;
            case DOWN: Blit( x, y + 1 ); break;
            case LEFT: Blit( x - 1, y ); break;
            case RIGHT: Blit( x + 1, y ); break;
            case UPLEFT: Blit( x - 1, y - 1 ); break;
            case UPRIGHT: Blit( x + 1, y - 1 ); break;
            case DOWNLEFT: Blit( x - 1, y + 1 ); break;
            case DOWNRIGHT: Blit( x + 1, y - 1 ); break;
        }
    }
    
    void rpgMap::Animate(){
        if( frame == 2 ) frame = 0;
        else frame++;
        Blit( x, y );
    }
    Last edited by Flikm; 07-30-2002 at 04:15 PM.

  2. #2
    Registered User
    Join Date
    Sep 2001
    Posts
    305
    i got it to work... freeing the image too soon. thx for checking the thread tho.

Popular pages Recent additions subscribe to a feed