00001 #include "Level.h"
00002 #include "Screen.h"
00003 #include "CommandManager.h"
00004 #include "Object.h"
00005 #include "Player.h"
00006 #include "Control.h"
00007 #include "Camera.h"
00008 #include "Parser.h"
00009
00010 #include <io.h>
00011 #include <iostream>
00012 #include <sstream>
00013 #include <cassert>
00014
00015 using namespace std;
00016
00017 Uint32 Level::WALKBEHIND = 0;
00018 Uint32 Level::WALKINTO = 0;
00019 Uint32 Level::WALKINFRONT = 0;
00020 bool Level::_objectsLoaded = false;
00021 map<Uint32,Sprite *> Level::TEXTURES;
00022 map<Uint32,string> Level::OBJECTS;
00023 Level *Level::_instance = NULL;
00024
00025 Level::Level()
00026 :_cutScene(false),_score(0)
00027 {
00028 loadObjects();
00029
00030
00031 _instance = this;
00032 }
00033
00034
00035 Level::~Level()
00036 {
00037 for(int i=0; i<_objects.size(); i++)
00038 delete _objects[i];
00039 for(int i=0; i<_tiles.size(); i++)
00040 delete _tiles[i];
00041 }
00042
00043 void Level::reset()
00044 {
00045 for(int i=0; i<_objects.size(); i++)
00046 delete _objects[i];
00047 for(int i=0; i<_tiles.size(); i++)
00048 delete _tiles[i];
00049
00050 _objects.clear();
00051 _tiles.clear();
00052 _drawnObjects.clear();
00053 _deleteQueue.clear();
00054
00055 _ids.clear();
00056
00057 while(!_addQueue.empty())
00058 {
00059 delete _addQueue.front();
00060 _addQueue.pop();
00061 }
00062
00063 levelLoad(_filenamebase);
00064
00065 }
00066
00067 void Level::loadObjects()
00068 {
00069 if(!_objectsLoaded) {
00070 readTextures("png");
00071 readTextures("txt");
00072
00073 WALKBEHIND = loadPixelFile("levels/walkbehind_p.png");
00074 WALKINFRONT = loadPixelFile("levels/walkinfront_p.png");
00075 WALKINTO = loadPixelFile("levels/walkinto_p.png");
00076
00077 readObjects("characters");
00078 readObjects("events");
00079 readObjects("cutscenes");
00080 readObjects("entities");
00081
00082 _objectsLoaded = true;
00083 }
00084 }
00085
00086 Uint32 Level::loadPixelFile(std::string filename)
00087 {
00088 SDL_Surface *surface = glfuncs::instance()->load_image(filename);
00089 SDL_LockSurface(surface);
00090 Uint32 pixel=*((Uint32*)surface->pixels);
00091 SDL_UnlockSurface(surface);
00092 SDL_FreeSurface(surface);
00093 return pixel;
00094 }
00095
00096 void Level::readObjects(std::string dir)
00097 {
00098 struct _finddata_t file;
00099 intptr_t hFile;
00100 string extension = "txt";
00101
00102 if( (hFile = _findfirst( (dir + "/*." + extension).c_str(), &file )) != -1L ) {
00103 do {
00104 string filename(file.name);
00105
00106 string end = filename.substr(filename.size() - 6,2);
00107 if(end != "_p") {
00108
00109 filename = dir + "/" + filename;
00110
00111 string objFile = filename;
00112
00113
00114 filename.erase(filename.find("."),4);
00115 filename += "_p.png";
00116
00117 SDL_Surface *surface = glfuncs::instance()->load_image(filename);
00118 SDL_LockSurface(surface);
00119 Uint32 pixel=*((Uint32*)surface->pixels);
00120
00121
00122
00123 SDL_UnlockSurface(surface);
00124 SDL_FreeSurface(surface);
00125
00126 OBJECTS[pixel] = objFile;
00127 }
00128 else
00129 continue;
00130 }
00131 while( _findnext( hFile, &file ) == 0 );
00132
00133 _findclose( hFile );
00134 }
00135 }
00136
00137 void Level::readTextures(std::string extension)
00138 {
00139 struct _finddata_t file;
00140 intptr_t hFile;
00141
00142 if( (hFile = _findfirst( ("textures/*." + extension).c_str(), &file )) != -1L ) {
00143 do {
00144 string filename(file.name);
00145
00146 string end = filename.substr(filename.size() - 6,2);
00147 if(end != "_p") {
00148
00149 filename = "textures/" + filename;
00150
00151 Sprite * sprite = Sprite::loadSprite(filename);
00152
00153
00154 filename.erase(filename.find("."),4);
00155 filename += "_p.png";
00156
00157 SDL_Surface *surface = glfuncs::instance()->load_image(filename);
00158 SDL_LockSurface(surface);
00159 Uint32 pixel=*((Uint32*)surface->pixels);
00160
00161
00162
00163 SDL_UnlockSurface(surface);
00164 SDL_FreeSurface(surface);
00165
00166 TEXTURES[pixel] = sprite;
00167 }
00168 else
00169 continue;
00170 }
00171 while( _findnext( hFile, &file ) == 0 );
00172
00173 _findclose( hFile );
00174 }
00175 }
00176
00177 void Level::levelLoad(std::string filenamebase)
00178 {
00179 _filenamebase = filenamebase;
00180
00181 levelTextureLoad(filenamebase);
00182 levelObjectLoad(filenamebase);
00183 levelSpecsLoad(filenamebase);
00184
00185
00186
00187
00188
00189 _player = (Player *)_ids["goudy1"];
00190
00191 Screen::instance()->registerFollowObj( (Object*)_player );
00192 Control::registerController((Object*)_player);
00193
00194
00195
00196 }
00197
00198 void Level::levelSpecsLoad(std::string filenamebase)
00199 {
00200 string specsFilename = filenamebase + ".txt";
00201 List *specsList = Parser::parse(specsFilename);
00202
00203 List *specs = specsList;
00204
00205 while(!specs->empty()) {
00206 List *current = specs->firstList();
00207
00208 Object *object = getObject(current->firstString());
00209 object->load(current->rest());
00210
00211 specs = specs->rest();
00212 }
00213
00214 delete specsList;
00215 }
00216
00217 void Level::levelObjectLoad(std::string filenamebase)
00218 {
00219 string objFilename = filenamebase + "obj.bmp";
00220 SDL_Surface *surface = glfuncs::load_image(objFilename);
00221 SDL_LockSurface(surface);
00222
00223 _height = surface->h*tileHeight;
00224 _width = surface->w*tileWidth;
00225
00226 Uint32* objectPixels = (Uint32*)surface->pixels;
00227
00228
00229 for(int i=0; i < surface->h ; i++ ){
00230 for( int j=0 ; j < surface->w ;j++){
00231
00232 if(OBJECTS[objectPixels[i*surface->w+j]] != "")
00233 {
00234 Object* o = Object::loadObject(OBJECTS[objectPixels[i*surface->w+j]], j*tileWidth, i*tileHeight);
00235 string id = o->id();
00236
00237
00238 int i = 0;
00239 do
00240 {
00241 i++;
00242 stringstream num;
00243 num << i;
00244 o->setId(id+num.str());
00245
00246
00247
00248 } while(_ids[o->id()] != NULL);
00249
00250 cerr << o->id() << endl;
00251
00252 addObject(o, _objects);
00253 }
00254 }
00255 }
00256
00257 SDL_UnlockSurface(surface);
00258 SDL_FreeSurface(surface);
00259 }
00260
00261
00262 void Level::levelTextureLoad(std::string filenamebase)
00263 {
00264 string texFilename = filenamebase + "tex.bmp";
00265 string colFilename = filenamebase + "col.bmp";
00266 string backFilename = filenamebase + "back.png";
00267 SDL_Surface *surface = glfuncs::load_image(texFilename);
00268 SDL_Surface* colSurface = glfuncs::load_image( colFilename );
00269
00270 SDL_LockSurface(surface);
00271 SDL_LockSurface(colSurface);
00272
00273 Tile* t = NULL;
00274
00275 _height = surface->h*tileHeight;
00276 _width = surface->w*tileWidth;
00277 _tiles = vector< Tile* >( _height*_width, t );
00278 _background = new Background( backFilename, 0.5 );
00279 _background->setHeight( _height );
00280 _background->setWidth( _width );
00281
00282 Uint32* texturePixels = (Uint32*)surface->pixels;
00283 Uint32* colPixels = (Uint32*)colSurface->pixels;
00284 Uint32 colPixel;
00285
00286
00287
00288 for(int i=0; i < surface->h ; i++ ){
00289 for( int j=0 ; j < surface->w ;j++){
00290 if(TEXTURES[texturePixels[i*surface->w+j]]!=NULL)
00291 {
00292 t = new Tile( TEXTURES[texturePixels[i*surface->w+j]]->instance(),
00293 true, j*tileWidth, i*tileHeight);
00294
00295 colPixel = colPixels[ i*colSurface->w + j ];
00296 if( colPixel == Level::WALKBEHIND )
00297 {
00298 t->setCollidable( false );
00299 t->setDepth( 5 );
00300 } else if( colPixel == Level::WALKINFRONT )
00301 {
00302 t->setCollidable( false );
00303 t->setDepth( -1 );
00304 } else if( colPixel == Level::WALKINTO )
00305 {
00306 t->setCollidable( true );
00307 t->setDepth( 0 );
00308 }
00309
00310 registerTile( t, i, j );
00311 }
00312 }
00313 }
00314
00315 SDL_UnlockSurface(surface);
00316 SDL_UnlockSurface(colSurface);
00317 SDL_FreeSurface(surface);
00318 SDL_FreeSurface(colSurface);
00319 }
00320
00321 bool Level::update()
00322 {
00323 Object* o;
00324
00325 while( !_deleteQueue.empty() )
00326 {
00327 o = _deleteQueue.front();
00328 _deleteQueue.erase( remove( _deleteQueue.begin(), _deleteQueue.end(), o ), _deleteQueue.end() );
00329 deleteObject( o );
00330
00331 if(o == this->_player)
00332 {
00333
00334 _player = NULL;
00335 return false;
00336 }
00337
00338 }
00339
00340 while( !_addQueue.empty() )
00341 {
00342 o = _addQueue.front();
00343 addObject( o, _objects );
00344 _addQueue.pop();
00345 }
00346
00347 CommandManager::instance()->startTimestep();
00348
00349 Control::update();
00350 Screen::instance()->update();
00351
00352 for( vector< Object* >::iterator i = _objects.begin(); i != _objects.end(); i++ )
00353 {
00354 (*i)->update();
00355 }
00356 return true;
00357 }
00358
00359 void Level::draw()
00360 {
00361
00362 _background->draw();
00363
00364
00365 for( vector< Object* >::iterator i = _drawnObjects.begin(); i != _drawnObjects.end(); i++ )
00366 {
00367 (*i)->draw();
00368 }
00369
00370 drawHUD();
00371
00372 if(_cutScene) {
00373 Screen::instance()->drawCutScene(_cutSceneText);
00374 }
00375 }
00376
00377 void Level::drawHUD()
00378 {
00379 SDL_Rect raster;
00380
00381 Sprite *health = Sprite::loadSprite("sprites/health.png");
00382 Sprite *heart = Sprite::loadSprite("sprites/heart.png");
00383
00384 raster.x = 5;
00385 raster.y = 5;
00386
00387 health->draw(raster.x,raster.y,Sprite::SCREEN);
00388
00389 raster.x += health->width() + 2;
00390 raster.y += 5;
00391
00392 for(int i = 0; i < _player->getHealth(); i++) {
00393 heart->draw(raster.x,raster.y,Sprite::SCREEN);
00394 raster.x += heart->width() + 2;
00395 }
00396
00397 glfuncs::instance()->glDisable(GL_TEXTURE_2D);
00398 raster.x = 710;
00399 raster.y = 30;
00400 glfuncs::instance()->glRasterPos2f(raster.x,raster.y);
00401
00402 stringstream score;
00403 score << "Score: ";
00404 score << _score;
00405 glfuncs::instance()->glPrint(score.str());
00406 glfuncs::instance()->glEnable(GL_TEXTURE_2D);
00407 }
00408
00409
00410 void Level::registerObject( Object* o )
00411 {
00412 _addQueue.push( o );
00413 }
00414
00415 void Level::registerTile( Tile* t, int h, int w )
00416 {
00417 if( t->collidable() )
00418 _tiles[ h*_width + w ] = t;
00419
00420
00421 vector< Object* >::iterator i = _drawnObjects.begin();
00422
00423 while( i != _drawnObjects.end() && t->getDepth() > (*i)->getDepth() )
00424 i++;
00425
00426 _drawnObjects.insert( i, t );
00427 }
00428
00429
00430
00431 void Level::addObject( Object* o, std::vector< Object* >& vec )
00432 {
00433
00434 vec.push_back( o );
00435
00436
00437 vector< Object* >::iterator i = _drawnObjects.begin();
00438
00439 while( i != _drawnObjects.end() && o->getDepth() > (*i)->getDepth() )
00440 i++;
00441
00442 _drawnObjects.insert( i, o );
00443 _ids[o->id()] = o;
00444
00445
00446
00447
00448
00449
00450
00451 }
00452
00453 Object *Level::getObject( std::string id )
00454 {
00455 return _ids[id];
00456 }
00457
00458 Level *Level::instance()
00459 {
00460 if(!_instance)
00461 return new Level();
00462 else
00463 return _instance;
00464 }
00465
00466 void Level::scheduleDelete( Object* o )
00467 {
00468 _deleteQueue.push_back( o );
00469 }
00470
00471 void Level::deleteObject( Object* o )
00472 {
00473 _objects.erase( remove( _objects.begin(), _objects.end(), o ), _objects.end() );
00474 _drawnObjects.erase( remove( _drawnObjects.begin(), _drawnObjects.end(), o ), _drawnObjects.end() );
00475 delete o;
00476 }
00477
00478
00479 void Level::setCutScene(bool cutScene)
00480 {
00481 _cutScene = cutScene;
00482 }
00483
00484 Mix_Chunk* Level::getSound( std::string filename )
00485 {
00486 assert( _sounds.find( filename ) != _sounds.end() );
00487 return _sounds[ filename ];
00488 }
00489
00490 void Level::loadSound( std::string filename )
00491 {
00492
00493 if( _sounds.find( filename ) == _sounds.end() )
00494 {
00495 _sounds[ filename ] = Mix_LoadWAV( filename.c_str() );
00496 }
00497 }