Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

CSWorld.cpp

Go to the documentation of this file.
00001 /**
00002 */
00003 
00004 #ifdef WIN32
00005 #pragma warning(disable : 4786 )
00006 #endif
00007 
00008 #include "CSWorld.h"
00009 #include "CSXMLHelper.h"
00010 #include "CSMusic.h"
00011 
00012 CSWorldLoader CSWorldLoader::INSTANCE;
00013 const char *CSWorld::CLASS = "CSWorld";
00014 
00015 CSWorld::CSWorld(const std::string &filename)
00016 {
00017     static char *functionName="CSWorld";
00018     LOG_ENTER 
00019     CSWorldData data;
00020     loadWorldData(filename, data);
00021     initialize(data);
00022     LOG_EXIT
00023 }
00024 
00025 // not Done!
00026 CSWorld::CSWorld(const CSWorld &world)
00027 {
00028     static char *functionName="CSWorld";
00029     LOG_ENTER 
00030     initialize();
00031     mId = strdup(world.mId);
00032     mLayers = world.mLayers;
00033     LOG_EXIT
00034 }
00035 
00036 void CSWorld::initialize(void)
00037 {
00038     static char *functionName="initialize";
00039     LOG_ENTER 
00040     mFactor = 0;
00041     mId = 0;
00042     mScaleMapCount = 0;
00043     mWorld = 0;
00044     mLayers = 0;
00045     mMapArea.x = 0;
00046     mMapArea.y = 0;
00047     mMapArea.w = 0;
00048     mMapArea.h = 0;
00049     mXOffset = 0;
00050     mYOffset = 0;
00051     mHeight = 0;
00052     mWidth = 0;
00053     mXPos = 0;
00054     mYPos = 0;
00055     mWorldNo = 0;
00056     mMusic = 0;
00057     mActive = false;
00058     mScaledWorldDestination.x = 0;
00059     mScaledWorldDestination.y = 0;
00060     mScaledWorldDestination.w = 0;
00061     mScaledWorldDestination.h = 0;
00062     LOG_EXIT
00063 }
00064 
00065 void CSWorld::scaleBackgroundTiles(int w, int h)
00066 {
00067     static char *functionName="scaleBackgroundTiles";
00068     LOG_ENTER 
00069     if (mWorld != 0)
00070     {
00071         for (int l=0; l< mLayers; l++)
00072         {
00073             if (mWorld[l]->isBackground())
00074             {
00075                 mWorld[l]->scaleMapToFit(w, h);
00076             }
00077         }
00078     }
00079     LOG_EXIT
00080 }
00081 
00082 void CSWorld::initialize(const CSWorldData &data)
00083 {
00084     static char *functionName="initialize";
00085     LOG_ENTER 
00086     initialize();
00087     mId = strdup(data.id);
00088     mLayers = data.layers;
00089     
00090     mWorld = (CSTileMap **) new void *[data.layers];
00091     
00092     for (int l=0; l< data.layers; l++)
00093     {
00094         MapData *mapData = data.maps->at(l);
00095         CSTileMap *map = CSTileMapLoader::INSTANCE.load(mapData->name);
00096         map->setOffset(mapData->offsetX, mapData->offsetY);
00097         map->setBackground(mapData->isBackground);
00098 
00099         map->setParallax(mapData->isParallax);
00100         if (l==0)
00101         {
00102             map->setSolid(true);
00103         }
00104         mWorld[l] = map;
00105         if (!mapData->isBackground)
00106         {
00107             if (map->getHeight() > mHeight) mHeight = map->getHeight();
00108             if (map->getWidth() > mWidth) mWidth = map->getWidth();
00109         }
00110     }
00111     if (mWorld != 0)
00112     {
00113         for (int l=0; l< mLayers; l++)
00114         {
00115             mWorld[l]->setWorldMax(mWidth, mHeight);
00116         }
00117     }
00118     if (data.musicName != 0)
00119     {
00120         mMusic = CSMusicLoader::INSTANCE.load(data.musicName);
00121         mMusic->play();
00122     }
00123     LOG_EXIT
00124 }
00125 
00126 CSWorld::~CSWorld()
00127 {
00128     static char *functionName="~CSWorld";
00129     LOG_ENTER 
00130     if (mId != 0)
00131     {
00132         free(mId);
00133         mId = 0;
00134     }
00135     
00136     if (mWorld != 0)
00137     {
00138         for (int l=0; l< mLayers; l++)
00139         {
00140             delete mWorld[l];
00141         }
00142         delete[] mWorld;
00143         mWorld = 0;
00144     }
00145     if (mMusic != 0)
00146     {
00147         // delete mMusic; is a singleton!
00148         mMusic->stop();
00149         mMusic = 0;
00150     }
00151     LOG_EXIT
00152 }
00153 
00154 void CSWorld::display()
00155 {
00156     static char *functionName="display";
00157     SDL_SetClipRect(SDLMain::getScreen(), &mMapArea);
00158 
00159     if (mWorld != 0)
00160     {
00161         for (int l=0; l< mLayers; l++)
00162         {
00163             mWorld[l]->display();
00164         }
00165     }
00166     SDL_SetClipRect(SDLMain::getScreen(), 0);
00167 }
00168 
00169 void CSWorld::setWorldNo(unsigned int no) 
00170 {
00171     static char *functionName="setWorldNo";
00172     LOG_ENTER 
00173     mWorldNo = no;
00174     if (mWorld != 0)
00175     {
00176         for (int l=0; l< mLayers; l++)
00177         {
00178             mWorld[l]->setWorldNo(no);
00179         }
00180     }
00181     LOG_EXIT
00182 }
00183 
00184 void CSWorld::setTile(unsigned int x, unsigned int y, unsigned int z, char idChar)
00185 {
00186     static char *functionName="setTile";
00187     mWorld[z]->setTile(x, y, idChar);
00188 }
00189 
00190 void CSWorld::setTile(unsigned int x, unsigned int y, unsigned int z, CSTile *tile)
00191 {
00192     static char *functionName="setTile";
00193     mWorld[z]->setTile(x, y, tile);
00194 }
00195 
00196 void CSWorld::update()
00197 {
00198     static char *functionName="update";
00199     if (mWorld != 0)
00200     {
00201         for (int l=0; l< mLayers; l++)
00202         {
00203             mWorld[l]->update();
00204         }
00205     }
00206 }
00207 
00208 void CSWorld::setDisplayArea(SDL_Rect area)
00209 {
00210     static char *functionName="setDisplayArea";
00211     LOG_ENTER 
00212     mMapArea = area;
00213     mXOffset = area.x;
00214     mYOffset = area.y;
00215 
00216     if (mWorld != 0)
00217     {
00218         for (int l=0; l< mLayers; l++)
00219         {
00220             mWorld[l]->setDisplayOffset(mXOffset, mYOffset);
00221             mWorld[l]->setDisplaySize(mMapArea.w, mMapArea.h);
00222         }
00223     }
00224     LOG_EXIT
00225 }
00226 
00227 void CSWorld::setWorldPosition(int x, int y)
00228 {
00229     static char *functionName="setWorldPosition";
00230     mXPos = x;
00231     mYPos = y;
00232     if (mWorld != 0)
00233     {
00234         for (int l=0; l< mLayers; l++)
00235         {
00236             mWorld[l]->setMapPosition(x,y);
00237         }
00238     }
00239 
00240     CSSprites::iterator iter = mSprites.begin();
00241     while (iter != mSprites.end())
00242     {
00243         CSSprite *sprite = *iter;
00244         sprite->setWorldPosition(x, y);
00245         iter++;
00246     }
00247 }
00248 
00249 void CSWorld::setSecPerFrame(float secPerFrame)
00250 {
00251     static char *functionName="setSecPerFrame";
00252     LOG_ENTER 
00253     if (mWorld != 0)
00254     {
00255         for (int l=0; l< mLayers; l++)
00256         {
00257             mWorld[l]->setSecPerFrame(secPerFrame);
00258         }
00259     }
00260     CSSprites::iterator iter = mSprites.begin();
00261     while (iter != mSprites.end())
00262     {
00263         CSSprite *sprite = *iter;
00264         sprite->setSecPerFrame(secPerFrame);
00265         iter++;
00266     }
00267     LOG_EXIT
00268 }
00269 
00270 void CSWorld::loadWorldData(const std::string &filename, CSWorldData &data)
00271 {
00272     static char *functionName="loadWorldData";
00273     LOG_ENTER 
00274     char tmp[10];
00275     CSXMLHelper xmlSupport(filename, "WORLD");
00276     try
00277     {
00278         if (xmlSupport.getError())
00279         {
00280             LOG_EXIT
00281             throw "error";
00282         }
00283 
00284         data.id = strdup(xmlSupport.getString("ID").c_str());
00285         int mapCount = xmlSupport.getInt("count(MAPS/MAP)");
00286         for (int i=0; i<mapCount; i++)
00287         {
00288             MapData *map = new MapData();
00289             // i+1, predicates in xpath start with 1
00290             std::string a = xmlSupport.getString((std::string)"MAPS/MAP["+itoa(i+1,tmp,10)+"]/NAME");
00291             map->name =  strdup(a.c_str());
00292 
00293             int hasOffsetData = xmlSupport.getInt((std::string)"count(MAPS/MAP["+itoa(i+1,tmp,10)+"]/OFFSET_X)");
00294             if (hasOffsetData == 1)
00295             {
00296                 map->offsetX = xmlSupport.getInt((std::string)"MAPS/MAP["+itoa(i+1,tmp,10)+"]/OFFSET_X");
00297                 map->offsetY = xmlSupport.getInt((std::string)"MAPS/MAP["+itoa(i+1,tmp,10)+"]/OFFSET_Y");
00298             }
00299             map->isBackground = xmlSupport.getInt((std::string)"count(MAPS/MAP["+itoa(i+1,tmp,10)+"]/BACKGROUND)") == 1;
00300             map->isParallax = xmlSupport.getInt((std::string)"count(MAPS/MAP["+itoa(i+1,tmp,10)+"]/PARALLAX)") == 1;
00301             data.maps->push_back(map);
00302         }
00303         data.layers = mapCount;
00304         bool hasMusic = xmlSupport.getInt((std::string)"count(MUSIC)") == 1;
00305         if (hasMusic)
00306         {
00307             data.musicName = strdup(xmlSupport.getString("MUSIC").c_str());
00308         }
00309     }
00310     catch(...)
00311     {
00312         LOG_EXIT
00313         SDLMain::shutdown((std::string)"XML error \"" + filename + "\": " + xmlSupport.getErrorMessage().c_str(), 1);
00314     }
00315     LOG_EXIT
00316 }
00317 
00318 // sprites are displayed by there corresponding layer!
00319 void CSWorld::addSprite(CSSprite *sprite)
00320 {
00321     static char *functionName="addSprite";
00322     LOG_ENTER 
00323     // savety meassure, not to add twice!
00324     removeSprite(sprite);
00325     mSprites.push_back(sprite);
00326 
00327     if (mWorld != 0)
00328     {
00329         if (sprite->getLayer() < 0)
00330         {
00331             // add to topmost layer!
00332             mWorld[mLayers-1]->addSprite(sprite);
00333             return;
00334             LOG_EXIT
00335         }
00336         if (sprite->getLayer() < mLayers)
00337         {
00338             mWorld[sprite->getLayer()]->addSprite(sprite);
00339         }
00340         else
00341         {
00342             LOG_EXIT
00343             SDLMain::shutdown((std::string)"Sprite-Layer-Error!", 1);
00344         }
00345     }
00346     LOG_EXIT
00347 }
00348 
00349 void CSWorld::removeSprite(CSSprite *sprite)
00350 {
00351     static char *functionName="removeSprite";
00352     LOG_ENTER 
00353     CSSprites::iterator iter = mSprites.begin();
00354     while (iter != mSprites.end())
00355     {
00356         if ((*iter) == sprite)
00357         {
00358             mSprites.erase(iter);
00359             iter = mSprites.begin();    // restart!
00360         }
00361         else
00362         {
00363             iter++;
00364         }
00365     }
00366     if (mWorld != 0)
00367     {
00368         if (sprite->getLayer() < 0)
00369         {
00370             // add to topmost layer!
00371             mWorld[mLayers-1]->removeSprite(sprite);
00372             LOG_EXIT
00373             return;
00374         }
00375         if (sprite->getLayer() < mLayers)
00376         {
00377             mWorld[sprite->getLayer()]->removeSprite(sprite);
00378         }
00379         else
00380         {
00381             LOG_EXIT
00382             SDLMain::shutdown((std::string)"Sprite-Layer-Error!", 1);
00383         }
00384     }
00385     LOG_EXIT
00386 }
00387 
00388 void CSWorld::buildScaledWorld(double factor, const SDL_Rect &sourceRect, SDL_Surface *destination, const SDL_Rect &displayRect)
00389 {
00390     static char *functionName="buildScaledWorld";
00391     bool isNew = false;
00392     mFactor = factor;
00393     SDL_Rect destRect;
00394     SDL_Rect srcRect;
00395     bool first = true;
00396     if (mWorld != 0)
00397     {
00398         for (int l=0; l< mLayers; l++)
00399         {
00400             if (mWorld[l]->isScaleDisplay())
00401             {
00402                 destRect.x = displayRect.x;
00403                 destRect.y = displayRect.y;
00404                 destRect.w = displayRect.w;
00405                 destRect.h = displayRect.h;
00406                 srcRect.x = sourceRect.x;
00407                 srcRect.y = sourceRect.y;
00408                 srcRect.w = sourceRect.w;
00409                 srcRect.h = sourceRect.h;
00410                 SDL_Surface *src = mWorld[l]->getScaledMap(factor, first);
00411                 first = false;
00412                 
00413                 if (SDL_BlitSurface(src, &srcRect, destination, &destRect) < 0)
00414                 {
00415                     SDLMain::shutdown((std::string)"Display Format error (buildScaledWorld()): " + SDL_GetError(), 1);
00416                 }
00417             }
00418         }
00419     }
00420 
00421     if (mWorld != 0)
00422     {
00423         for (int l=0; l< mLayers; l++)
00424         {
00425             mWorld[l]->addScaledSprites(factor, sourceRect, destination, displayRect);
00426         }
00427     }
00428 }
00429 
00430 void CSWorld::resetScaledWorld()
00431 {
00432     static char *functionName="resetScaledWorld";
00433     LOG_ENTER 
00434     if (mWorld != 0)
00435     {
00436         for (int l=0; l< mLayers; l++)
00437         {
00438             mWorld[l]->resetScaledMap();
00439         }
00440     }
00441     LOG_EXIT
00442 }
00443 
00444 void CSWorld::displayScaled(CSSprite *centerSprite)
00445 {
00446     static char *functionName="displayScaled";
00447     if ((mScaledWorldDestination.w == 0) || (mScaledWorldDestination.h == 0) || (mFactor == 0))
00448     {
00449         return;
00450     }
00451     int x = ((double)centerSprite->getXPos() + centerSprite->getMaxWidth()/2) * mFactor;
00452     int y = ((double)centerSprite->getYPos() + centerSprite->getMaxHeight()/2) * mFactor;
00453     int xOffset;
00454     int yOffset;
00455     int thresholdX = mScaledWorldDestination.w/2;
00456     int thresholdY = mScaledWorldDestination.h/2;
00457 
00458     SDL_Rect srcRect;
00459     srcRect.w = mScaledWorldDestination.w;
00460     srcRect.h = mScaledWorldDestination.h;
00461 
00462     xOffset = x-thresholdX;
00463     yOffset = y-thresholdY;
00464     
00465     if (xOffset + mScaledWorldDestination.w > ((double)mWidth) * mFactor)
00466     {
00467         xOffset = ((double) (((double)mWidth) * mFactor)) - mScaledWorldDestination.w;
00468     }
00469     if (yOffset + mScaledWorldDestination.h >((double)mHeight) * mFactor)
00470     {
00471         yOffset = ((double) (((double)mHeight) * mFactor)) - mScaledWorldDestination.h;
00472     }
00473 
00474     if (xOffset < 0)
00475     {
00476         xOffset = 0;
00477     }
00478     if (yOffset < 0)
00479     {
00480         yOffset = 0;
00481     }
00482 
00483     srcRect.x = xOffset; 
00484     srcRect.y = yOffset;
00485     
00486     SDL_SetClipRect(SDLMain::getScreen(), &mScaledWorldDestination);
00487     SDL_Rect destRect = mScaledWorldDestination;
00488 
00489     buildScaledWorld(mFactor, srcRect, SDLMain::getScreen(),destRect);
00490     SDL_SetClipRect(SDLMain::getScreen(), 0);
00491 }
00492 
00493 void CSWorld::setScaleDisplayArea(SDL_Rect area)
00494 {
00495     static char *functionName="setScaleDisplayArea";
00496     LOG_ENTER 
00497     mScaledWorldDestination = area;
00498     LOG_EXIT
00499 }

Generated on Wed Jul 14 00:43:43 2004 for CSLib by doxygen 1.3.6