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

CSGame.cpp

Go to the documentation of this file.
00001 #ifdef WIN32
00002 #pragma warning(disable : 4786 )
00003 #endif
00004 
00005 #include "SDLMain.h"
00006 #include "CSFont.h"
00007 #include <conio.h>
00008 #include <string>
00009 
00010 #include "CSPanel.h"
00011 #include "CSWindow.h"
00012 #include "CSLabel.h"
00013 #include "CSButton.h"
00014 #include "CSCheckBox.h"
00015 #include "CSTextfield.h"
00016 #include "CSScrollbar.h"
00017 #include "CSTextarea.h"
00018 #include "CSListbox.h"
00019 #include "CSCombobox.h"
00020 #include "CSHTMLArea.h"
00021 #include "CSMenu.h"
00022 
00023 #include "CSIcon.h"
00024 #include "CSMessageBox.h"
00025 #include "CSLAF.h"
00026 
00027 #include "CSGame.h"
00028 #include "CSMenu.h"
00029 #include "CSMenuItem.h"
00030 #include "CSSample.h"
00031 
00032 const char *CSGame::CLASS = "CSGame";
00033 
00034 const int QUIT_ACTION_ID = 1;
00035 const int ABOUT_ACTION_ID = 2;
00036 
00037 /** \mainpage Index done by Chrissalo
00038 
00039 
00040   \section gui something to about GUI
00041 
00042   \subsection widgets something to say about widgets
00043 */
00044 
00045 
00046 
00047 /*! \page page1 A documentation page
00048   Leading text.
00049   \section sec An example section
00050   This page contains the subsections \ref subsection1 and \ref subsection2.
00051   For more info see page \ref page2.
00052   \subsection subsection1 The first subsection
00053   Text.
00054   \subsection subsection2 The second subsection
00055   More text.
00056 */
00057 
00058 /*! \page page2 Another page
00059   Even more info.
00060 */
00061 
00062 
00063 
00064 
00065 
00066 CSGame::CSGame(std::string gameFileName)
00067 {
00068     static char *functionName="CSGame";
00069     LOG_ENTER 
00070     initialize();
00071     loadGameData(gameFileName);
00072     LOG_EXIT 
00073 }
00074 
00075 CSGame::~CSGame()
00076 {
00077     static char *functionName="~CSGame";
00078     LOG_ENTER 
00079     freeLevel();
00080     
00081     TileCollisionCheckDatas::iterator iter = mTileCollisionCheckDatas.begin();
00082     while (iter != mTileCollisionCheckDatas.end())
00083     {
00084         TileCollisionCheckData *data = *iter;
00085         mTileCollisionCheckDatas.erase(iter);
00086         delete data;
00087         iter = mTileCollisionCheckDatas.begin();
00088     }
00089 
00090     SpriteCollisionCheckDatas::iterator titer = mSpriteCollisionCheckDatas.begin();
00091     while (titer != mSpriteCollisionCheckDatas.end())
00092     {
00093         SpriteCollisionCheckData *data = *titer;
00094         mSpriteCollisionCheckDatas.erase(titer);
00095         delete data;
00096         titer = mSpriteCollisionCheckDatas.begin();
00097     }
00098     for (StringVector::iterator siter = mLevels.begin(); siter != mLevels.end(); siter++)
00099     {
00100         delete *siter;
00101     }
00102     mLevels.clear();
00103     if (mId)
00104     {
00105         free(mId);
00106         mId = 0;
00107     }
00108     if (mEventMap != 0)
00109     {
00110         CSEventMap::iterator iter;
00111         for (iter = mEventMap->begin(); iter!=mEventMap->end(); iter++)
00112         {
00113             delete (iter->second);
00114         }
00115         
00116         mEventMap->clear();
00117         delete mEventMap;
00118         mEventMap = 0;
00119     }
00120     if (mLevelData != 0)
00121     {
00122         delete mLevelData;
00123         mLevelData = 0;
00124     }
00125     if (mMenuBar)
00126     {
00127         delete (mMenuBar);
00128         mMenuBar = 0;
00129     }
00130     if (mDesktop)
00131     {
00132         delete (mDesktop);
00133         mDesktop = 0;
00134     }
00135     LOG_EXIT 
00136 }
00137 
00138 void CSGame::initialize()
00139 {
00140     static char *functionName="initialize";
00141     LOG_ENTER 
00142     dummyGame = false;
00143     mDesktop = new CSDesktop();
00144 
00145     mMenuBar = new CSMenuBar();
00146     mMenuBar->setVisible(true);
00147     mFileMenu = new CSMenu((std::string)"File");
00148     mFileMenu->setTooltipText("File menu, exit game with \"Exit\"...");
00149     mHelpMenu = new CSMenu((std::string)"Help");
00150     mHelpMenu->setTooltipText("Help and about...");
00151 
00152     mMenuItemExit = new CSMenuItem("Exit");
00153     mMenuItemAbout = new CSMenuItem("About");
00154     mMenuItemExit->setActionId(QUIT_ACTION_ID);
00155     mMenuItemExit->addMessageListener(this, GUI_MESSAGE);
00156     mMenuItemAbout->setActionId(ABOUT_ACTION_ID);
00157     mMenuItemAbout->addMessageListener(this, GUI_MESSAGE);
00158     mFileMenu->addMenuItem(mMenuItemExit);
00159     mHelpMenu->addMenuItem(mMenuItemAbout);
00160     mMenuBar->addElement(mFileMenu);
00161     mMenuBar->addElement(mHelpMenu);
00162 
00163 //  mDesktop->addElementNorth(mMenuBar);
00164 
00165     mIsGui = false;
00166     mLastIsGui = false;
00167     mEnableCheck = true;
00168     mDisplayScaled = false;
00169     mEventMap = new CSEventMap();
00170     mCurrentTime = 0;
00171     mGameTime = 0;
00172     mAverageFrameRate = 0;
00173     mDiffTime = 0;
00174     mLevelData = 0;
00175     mSecPerFrame = 0;
00176     mScaleCenterSprite = 0;
00177     mQuit = false;
00178     mPause = false;
00179     mLevelFinished = false;
00180     mStartLevel = 0;
00181     mMainSprite = 0;
00182     mWorld = 0;
00183     mWorldCount = 0;
00184     mThreshold = 150;
00185     mIsWorldOutOfBounds = false;
00186     mCurrentWorld = 0;
00187     mCurrentLevel = 0;
00188     mCurrentFrameRate;
00189     mDiffTimeGUI = 0;
00190     mDiffTimeGame = 0;
00191     mDiffTimeAll = 0;
00192     mId = 0;
00193     initSpeed();
00194     addMessageListener(this, GAME_MESSAGE);
00195     
00196     SDLMain::getInstance()->addMessageListener(this, SDL_MESSAGE);
00197     mFont = CSFontLoader::INSTANCE.load("font\\default_font.xml");
00198     mFont->setSolid(true);
00199 
00200     MESSAGE_END.setSubtype(END_MESSAGE);
00201     MESSAGE_PAUSE.setSubtype(PAUSE_MESSAGE);
00202     MESSAGE_TOGGLE_FULLSCREEN.setSubtype(TOGGLE_FULLSCREEN_MESSAGE);
00203     MESSAGE_SPRITE_TILE_COLLISION.setSubtype(SPRITE_TILE_COLLISION_MESSAGE);
00204     MESSAGE_SPRITE_SPRITE_COLLISION.setSubtype(SPRITE_SPRITE_COLLISION_MESSAGE);
00205     MESSAGE_SPRITE_OUT_OF_BOUNDS.setSubtype(SPRITE_OUT_OF_BOUNDS_MESSAGE);
00206 
00207     MESSAGE_DEFAULT.setSubtype(DEFAULT_MESSAGE);
00208     MESSAGE_UP.setSubtype(UP_MESSAGE);
00209     MESSAGE_DOWN.setSubtype(DOWN_MESSAGE);
00210     MESSAGE_LEFT.setSubtype(LEFT_MESSAGE);
00211     MESSAGE_RIGHT.setSubtype(RIGHT_MESSAGE);
00212     MESSAGE_FIRE.setSubtype(FIRE_MESSAGE);
00213     MESSAGE_DEATH.setSubtype(DEATH_MESSAGE);
00214     MESSAGE_KEY_UP.setSubtype(KEY_UP_MESSAGE);
00215     MESSAGE_KEY_DOWN.setSubtype(KEY_DOWN_MESSAGE);
00216     MESSAGE_KEY_LEFT.setSubtype(KEY_LEFT_MESSAGE);
00217     MESSAGE_KEY_RIGHT.setSubtype(KEY_RIGHT_MESSAGE);
00218     MESSAGE_KEY_FIRE.setSubtype(KEY_FIRE_MESSAGE);
00219     MESSAGE_TOGGLE_GUI.setSubtype(TOGGLE_GUI_MESSAGE);
00220 
00221     MESSAGE_SPRITE_STATE_CHANGE.setSubtype(SPRITE_STATE_CHANGE_MESSAGE);
00222     LOG_EXIT 
00223 }
00224 
00225 SDL_Rect CSGame::getDisplayArea()
00226 {
00227     static char *functionName="getDisplayArea";
00228     LOG_ENTER 
00229     SDL_Rect area;
00230     area.x = 0;
00231     area.y = 0;
00232     area.w = SDLMain::getInstance()->getScreenWidth();
00233     area.h = SDLMain::getInstance()->getScreenHeight();
00234     LOG_EXIT 
00235     return area;
00236 }
00237 
00238 SDL_Rect CSGame::getScaledDisplayArea()
00239 {
00240     static char *functionName="getScaledDisplayArea";
00241     LOG_ENTER 
00242     SDL_Rect area;
00243     area.x = 0;
00244     area.y = 0;
00245     area.w = 100;
00246     area.h = 100;
00247     LOG_EXIT 
00248     return area;
00249 }
00250 
00251 void CSGame::enableOutOfBoundsCheck(CSSprite *sprite, CSMessageListener *listener, int threshold)
00252 {
00253     static char *functionName="enableOutOfBoundsCheck";
00254     LOG_ENTER 
00255     OutOfBoundsData *data = new OutOfBoundsData();
00256     data->sprite = sprite;
00257     data->listener = listener;
00258     data->threshold = threshold;
00259     mOutOfBoundsDatas.push_back(data);
00260     LOG_EXIT 
00261 }
00262 
00263 void CSGame::disableOutOfBoundsCheck(CSSprite *sprite, CSMessageListener *listener)
00264 {
00265     static char *functionName="disableOutOfBoundsCheck";
00266     LOG_ENTER 
00267     OutOfBoundsDatas::iterator iter = mOutOfBoundsDatas.begin();
00268     while (iter != mOutOfBoundsDatas.end())
00269     {
00270         OutOfBoundsData *data = *iter;
00271         if ((data->sprite == sprite) &&
00272             (data->listener == listener) 
00273             )
00274         {
00275             mOutOfBoundsDatas.erase(iter);
00276             delete data;
00277             break;
00278         }
00279         iter++;
00280     }
00281     LOG_EXIT 
00282 }
00283 
00284 void CSGame::enableTileCollisionCheck(CSSprite *sprite, int layer, CSMessageListener *listener)
00285 {
00286     static char *functionName="enableTileCollisionCheck";
00287     LOG_ENTER 
00288     TileCollisionCheckData *data = new TileCollisionCheckData();
00289     data->type = CHECK_HIT;
00290     data->sprite = sprite;
00291     data->layer = layer;
00292     data->listener = listener;
00293     mTileCollisionCheckDatas.push_back(data);
00294     LOG_EXIT 
00295 }
00296 
00297 void CSGame::enableTileCollisionCheckJustHit(CSSprite *sprite, int layer, CSMessageListener *listener)
00298 {
00299     static char *functionName="enableTileCollisionCheckJustHit";
00300     LOG_ENTER 
00301     TileCollisionCheckData *data = new TileCollisionCheckData();
00302     data->type = CHECK_JUST_HIT;
00303     data->sprite = sprite;
00304     data->layer = layer;
00305     data->listener = listener;
00306     mTileCollisionCheckDatas.push_back(data);
00307     LOG_EXIT 
00308 }
00309 
00310 void CSGame::enableTileCollisionCheckPixel(CSSprite *sprite, int layer, CSMessageListener *listener, int pixelThreshold)
00311 {
00312     static char *functionName="enableTileCollisionCheckPixel";
00313     LOG_ENTER 
00314     TileCollisionCheckData *data = new TileCollisionCheckData();
00315     data->type = CHECK_PIXEL;
00316     data->sprite = sprite;
00317     data->layer = layer;
00318     data->listener = listener;
00319     data->threshold = pixelThreshold;
00320     mTileCollisionCheckDatas.push_back(data);
00321     LOG_EXIT 
00322 }
00323 
00324 void CSGame::enableSpriteCollisionCheck(CSSprite *sprite, CSSprite *other, CSMessageListener *listener)
00325 {
00326     static char *functionName="enableSpriteCollisionCheck";
00327     LOG_ENTER 
00328     SpriteCollisionCheckData *data = new SpriteCollisionCheckData();
00329     data->type = CHECK_HIT;
00330     data->sprite = sprite;
00331     data->other = other;
00332     data->listener = listener;
00333     mSpriteCollisionCheckDatas.push_back(data);
00334     LOG_EXIT 
00335 }
00336 
00337 void CSGame::enableSpriteCollisionCheckPixel(CSSprite *sprite, CSSprite *other, CSMessageListener *listener, int pixelThreshold)
00338 {
00339     static char *functionName="enableSpriteCollisionCheckPixel";
00340     LOG_ENTER 
00341     SpriteCollisionCheckData *data = new SpriteCollisionCheckData();
00342     data->type = CHECK_PIXEL;
00343     data->sprite = sprite;
00344     data->other = other;
00345     data->listener = listener;
00346     data->threshold = pixelThreshold;
00347     mSpriteCollisionCheckDatas.push_back(data);
00348     LOG_EXIT 
00349 }
00350 
00351 void CSGame::disableTileCollisionCheck(CSSprite *sprite, int layer, CSMessageListener *listener)
00352 {
00353     static char *functionName="disableTileCollisionCheck";
00354     LOG_ENTER 
00355     TileCollisionCheckDatas::iterator iter = mTileCollisionCheckDatas.begin();
00356     while (iter != mTileCollisionCheckDatas.end())
00357     {
00358         TileCollisionCheckData *data = *iter;
00359         if ((data->sprite == sprite) &&
00360             (data->layer == layer) &&
00361             (data->listener == listener) 
00362             )
00363         {
00364             mTileCollisionCheckDatas.erase(iter);
00365             delete data;
00366             break;
00367         }
00368         iter++;
00369     }
00370     LOG_EXIT 
00371 }
00372 
00373 void CSGame::disableSpriteCollisionCheck(CSSprite *sprite, CSSprite *other, CSMessageListener *listener)
00374 {
00375     static char *functionName="disableSpriteCollisionCheck";
00376     LOG_ENTER 
00377     SpriteCollisionCheckDatas::iterator iter = mSpriteCollisionCheckDatas.begin();
00378     while (iter != mSpriteCollisionCheckDatas.end())
00379     {
00380         SpriteCollisionCheckData *data = *iter;
00381         if ((data->sprite == sprite) &&
00382             (data->other == other) &&
00383             (data->listener == listener) 
00384             )
00385         {
00386             mSpriteCollisionCheckDatas.erase(iter);
00387             delete data;
00388             break;
00389         }
00390         iter++;
00391     }
00392     LOG_EXIT 
00393 }
00394 
00395 void CSGame::checkCollisions()
00396 {
00397     static char *functionName="checkCollisions";
00398     // sprite
00399     SpriteCollisionCheckDatas::iterator iter = mSpriteCollisionCheckDatas.begin();
00400     while (iter != mSpriteCollisionCheckDatas.end())
00401     {
00402         SpriteCollisionCheckData *data = *iter;
00403         int count = 0;
00404         if (data->type == CHECK_HIT)
00405         {
00406             if (data->sprite->checkCollision(data->other))
00407             {
00408                 count = 10000000; // something like max int
00409             }
00410         }
00411         else //CHECK_PIXEL
00412         {
00413             count = data->sprite->checkCollisionPixels(data->other);
00414         }
00415         if (count>data->threshold)
00416         {
00417             MESSAGE_SPRITE_SPRITE_COLLISION.tiles.clear();
00418             MESSAGE_SPRITE_SPRITE_COLLISION.tile = 0;
00419             MESSAGE_SPRITE_SPRITE_COLLISION.layer = -1;
00420 
00421             MESSAGE_SPRITE_SPRITE_COLLISION.sprite = data->sprite;
00422             MESSAGE_SPRITE_SPRITE_COLLISION.other = data->other;
00423             MESSAGE_SPRITE_SPRITE_COLLISION.pixels = count;
00424             sendMessage(MESSAGE_SPRITE_SPRITE_COLLISION);
00425         }
00426         iter++;
00427     }
00428 
00429     // tile
00430     TileCollisionCheckDatas::iterator titer = mTileCollisionCheckDatas.begin();
00431     while (titer != mTileCollisionCheckDatas.end())
00432     {
00433         TileCollisionCheckData *data = *titer;
00434         int count = 0;
00435         if (data->type == CHECK_HIT)
00436         {
00437             CSTiles tiles = data->sprite->getCollidingTiles(mCurrentWorld->getLayer(data->layer));
00438             if (tiles.size() >0)
00439             {
00440                 CSTiles::iterator ttiter = tiles.begin();
00441                 while (ttiter != tiles.end())
00442                 {
00443                     MESSAGE_SPRITE_TILE_COLLISION.tiles.clear();
00444                     MESSAGE_SPRITE_TILE_COLLISION.tile = *ttiter;
00445                     MESSAGE_SPRITE_TILE_COLLISION.other = 0;
00446                     MESSAGE_SPRITE_TILE_COLLISION.sprite = data->sprite;
00447                     MESSAGE_SPRITE_TILE_COLLISION.layer = data->layer;
00448                     MESSAGE_SPRITE_TILE_COLLISION.pixels = 1;
00449                     sendMessage(MESSAGE_SPRITE_TILE_COLLISION);
00450                     ttiter++;
00451                 }
00452             }
00453         }
00454         else if (data->type == CHECK_PIXEL)
00455         {
00456             CSTiles tiles = data->sprite->getCollidingTiles(mCurrentWorld->getLayer(data->layer));
00457             if (tiles.size() >0)
00458             {
00459                 CSTiles::iterator ttiter = tiles.begin();
00460                 while (ttiter != tiles.end())
00461                 {
00462                     MESSAGE_SPRITE_TILE_COLLISION.tiles.clear();
00463                     MESSAGE_SPRITE_TILE_COLLISION.tile = *ttiter;
00464                     MESSAGE_SPRITE_TILE_COLLISION.other = 0;
00465                     MESSAGE_SPRITE_TILE_COLLISION.sprite = data->sprite;
00466                     MESSAGE_SPRITE_TILE_COLLISION.layer = data->layer;
00467                     MESSAGE_SPRITE_TILE_COLLISION.pixels = data->sprite->checkCollisionPixels(*ttiter);
00468                     sendMessage(MESSAGE_SPRITE_TILE_COLLISION);
00469                     ttiter++;
00470                 }
00471             }
00472         }
00473         else // CHECK_JUST_HIT
00474         {
00475             CSTiles tiles = data->sprite->getCollidingTiles(mCurrentWorld->getLayer(data->layer));
00476             if (tiles.size() >0)
00477             {
00478                 MESSAGE_SPRITE_TILE_COLLISION.tiles = tiles;
00479                 MESSAGE_SPRITE_TILE_COLLISION.tile = 0;
00480                 MESSAGE_SPRITE_TILE_COLLISION.other = 0;
00481                 MESSAGE_SPRITE_TILE_COLLISION.sprite = data->sprite;
00482                 MESSAGE_SPRITE_TILE_COLLISION.layer = data->layer;
00483                 MESSAGE_SPRITE_TILE_COLLISION.pixels = 1;
00484                 sendMessage(MESSAGE_SPRITE_TILE_COLLISION);
00485             }
00486         }
00487         titer++;
00488     }
00489 }
00490     
00491 void CSGame::addSprite(CSSprite *sprite)
00492 {
00493     static char *functionName="addSprite";
00494     LOG_ENTER 
00495     // savety meassure, not to add twice!
00496     removeSprite(sprite);
00497     for (int i=0; i < mWorldCount; i++)
00498     {
00499         mWorld[i]->addSprite(sprite);
00500     }
00501     mSprites.push_back(sprite);
00502     LOG_EXIT 
00503 }
00504 
00505 void CSGame::removeSprite(CSSprite *sprite)
00506 {
00507     static char *functionName="removeSprite";
00508     LOG_ENTER 
00509     for (int i=0; i < mWorldCount; i++)
00510     {
00511         mWorld[i]->removeSprite(sprite);
00512     }
00513     CSSprites::iterator iter = mSprites.begin();
00514     while (iter != mSprites.end())
00515     {
00516         if ((*iter) == sprite)
00517         {
00518             mSprites.erase(iter);
00519             iter = mSprites.begin();    // restart!
00520         }
00521         else
00522         {
00523             iter++;
00524         }
00525     }
00526 
00527     // TODO: ensure, that the listener is not currently enqueued with
00528     //       a waiting message!
00529     LOG_EXIT 
00530 }
00531 
00532 void CSGame::toggleGui()
00533 {
00534     static char *functionName="toggleGui";
00535     LOG_ENTER 
00536     mIsGui = !mIsGui;
00537     initSpeed();
00538     LOG_EXIT 
00539 }
00540 
00541 void CSGame::toggleFullscreen()
00542 {
00543     static char *functionName="toggleFullscreen";
00544     LOG_ENTER 
00545     SDLMain *main = SDLMain::getInstance();
00546     main->toggleFullscreen();
00547     LOG_EXIT 
00548 }
00549 
00550 void CSGame::initSpeed()
00551 {
00552     static char *functionName="initSpeed";
00553     LOG_ENTER 
00554     mInitCount = INIT_COUNT;
00555     mSecPerFrame = 0.0f;
00556     LOG_EXIT 
00557 }
00558 
00559 void CSGame::reactOnMessage(CSMessage *message)
00560 {
00561     reactOnMessageGame(message);
00562 }
00563 
00564 void CSGame::reactOnMessageGame(CSMessage *message)
00565 {
00566     static char *functionName="reactOnMessage";
00567     switch (message->getType())
00568     {
00569         case GAME_MESSAGE:
00570         {
00571             switch (message->getSubtype())
00572             {
00573                 case END_MESSAGE:
00574                 {
00575                     mQuit = true;
00576                     return;
00577                 }
00578                 
00579                 case PAUSE_MESSAGE:
00580                 {
00581                     doPause();
00582                     return;
00583                 }
00584                 
00585                 case TOGGLE_FULLSCREEN_MESSAGE:
00586                 {
00587                     toggleFullscreen();
00588                     return;
00589                 }
00590                 case TOGGLE_GUI_MESSAGE:
00591                 {
00592                     toggleGui();
00593                     return;
00594                 }
00595             }
00596             break;
00597         }
00598         case SDL_MESSAGE:
00599         {
00600             switch (message->getSubtype())
00601             {
00602                 case SCREEN_CHANGED_MESSAGE:
00603                 {
00604                     screenChanged();
00605                     return;
00606                 }
00607             }
00608             break;
00609         }
00610         case GUI_MESSAGE:
00611         {
00612             GuiMessage *gm = (GuiMessage *) message;
00613             switch (gm->actionId)
00614             {
00615                 case QUIT_ACTION_ID:
00616                 {
00617                     mQuit = true;
00618                     return;
00619                 }
00620             }
00621             break;
00622         }
00623     }
00624 }
00625 
00626 void CSGame::nextLevel()
00627 {
00628     static char *functionName="nextLevel";
00629     LOG_ENTER 
00630     mCurrentLevel = (mCurrentLevel+1) % mLevels.size();
00631     freeLevel();
00632     initLevel(mLevels.at(mCurrentLevel));
00633     initSpeed();
00634     checkWorld();
00635     LOG_EXIT 
00636 }
00637 
00638 static int p = 0;
00639 void CSGame::run(void)
00640 {
00641     static char *functionName="run";
00642     LOG_ENTER 
00643     mCurrentTime = SDL_GetTicks();
00644     mDiffTime = 0;
00645     mSecPerFrame = 0;
00646     mGameTime = 0;
00647     mCurrentLevel = mStartLevel;
00648     
00649     initSpeed();
00650     if (!dummyGame)
00651     {
00652         freeLevel();
00653         initLevel(mLevels.at(mCurrentLevel));
00654 
00655         checkWorld();
00656 
00657         for (int i=0; i < mWorldCount; i++)
00658         {
00659             mWorld[i]->update();
00660         }
00661         if (mIsWorldOutOfBounds)
00662         {
00663             adjustDisplay();
00664         }
00665     }
00666     
00667     while (!mQuit)
00668     {
00669         static int count = 0;
00670         static int frameRateTotal = 0;
00671         long allDrawStart = SDL_GetTicks();
00672         
00673         mCurrentTime = SDL_GetTicks();
00674         do
00675         {
00676             handleEvents();
00677             if (mPause)
00678             {
00679                 SDL_Delay(50);
00680             }
00681         }
00682         while ((mPause) && (!mQuit));
00683 {
00684 char str[100];
00685 sprintf(str, "GUI Update time in millseconds: %i    ", mDiffTimeGUI);
00686 mFont->putString(SDLMain::getScreen(), 0, 40+50, str);
00687 
00688 sprintf(str, "Game Update time in millseconds: %i   ", mDiffTimeGame);
00689 mFont->putString(SDLMain::getScreen(), 0, 55+50, str);
00690 
00691 sprintf(str, "All Update time in millseconds: %i   ", mDiffTimeAll);
00692 mFont->putString(SDLMain::getScreen(), 0, 70+50, str);
00693 
00694 sprintf(str, "Framerate (average, current): %i, %i   ", mAverageFrameRate, mCurrentFrameRate);
00695 mFont->putString(SDLMain::getScreen(), 0, 85+50, str);
00696 }
00697  
00698         if (mIsGui)
00699         {
00700             long desktopDrawStart = SDL_GetTicks();
00701             
00702             SDL_Rect area;
00703             area.x = 0;
00704             area.y = 0;
00705             area.w = SDLMain::getScreenWidth();
00706             area.h = SDLMain::getScreenHeight();
00707             mDesktop->paint(SDLMain::getScreen(), 0);
00708             SDLMain::updateScreen();
00709             SDL_FillRect(SDLMain::getScreen(), &area, COLOR(SDLMain::getScreen(), 0));
00710             SDLMain::addUpdateRect(area);
00711             mDiffTimeGUI = SDL_GetTicks() - desktopDrawStart;
00712         }
00713         else
00714         {
00715             if (mLastIsGui) // make sure double buffers are deleted
00716             {
00717                 SDL_Rect area;
00718                 area.x = 0;
00719                 area.y = 0;
00720                 area.w = SDLMain::getScreenWidth();
00721                 area.h = SDLMain::getScreenHeight();
00722                 SDLMain::updateScreen();
00723                 SDL_FillRect(SDLMain::getScreen(), &area, COLOR(SDLMain::getScreen(), 0));
00724                 SDLMain::addUpdateRect(area);
00725             }
00726             else
00727             {
00728                 SDLMain::updateScreen();
00729             }
00730         }
00731         long gameStart = SDL_GetTicks();
00732         mLastIsGui = mIsGui;
00733         startRun();
00734         for (int i=0; i < mWorldCount; i++)
00735         {
00736             mWorld[i]->update();
00737         }
00738         if (mIsWorldOutOfBounds)
00739         {
00740             adjustDisplay();
00741         }
00742         checkOutOfBounds();
00743         // checkCollisions(); // before // - not done yet
00744         if (!dummyGame)
00745         {
00746             mCurrentWorld->display();
00747             if ((mDisplayScaled) && (mScaleCenterSprite != 0))
00748             {
00749                 mCurrentWorld->displayScaled(mScaleCenterSprite);
00750             }
00751         }
00752 
00753         dispatchQueuedMessages();
00754         if (mEnableCheck)
00755         {
00756             checkCollisions(); // after
00757         }
00758         checkTimedEvent();
00759         endRun();
00760         displayGameData();
00761         mDiffTime = SDL_GetTicks() - mCurrentTime;
00762         mGameTime += mDiffTime;
00763         mCurrentFrameRate = (int)(1/(float (mDiffTime/1000.0f)));
00764         frameRateTotal += mCurrentFrameRate;
00765         count++;
00766         mAverageFrameRate = frameRateTotal/count;
00767         mDiffTimeGame = SDL_GetTicks() - gameStart;
00768         if (mInitCount)
00769         {
00770             count = 0;
00771             frameRateTotal = 0;
00772             mInitCount--;
00773             mSecPerFrame += (float (mDiffTime/1000.0f));
00774 
00775             if (mInitCount == 0)
00776             {
00777                 mSecPerFrame = (float) (mSecPerFrame / ((float)INIT_COUNT));
00778                 for (int i=0; i < mWorldCount; i++)
00779                 {
00780                     mWorld[i]->setSecPerFrame(mSecPerFrame);
00781                 }
00782             }
00783         }
00784 
00785         if ((p==1) || (mLevelFinished))
00786         {
00787             nextLevel();
00788             p=0;
00789         }
00790         mDiffTimeAll = SDL_GetTicks() - allDrawStart;
00791     }
00792     LOG_EXIT 
00793 }
00794 
00795 // variable "mIsWorldOutOfBounds" is set to true or false, depending on the
00796 // current available world (bigger than screen resolution or not)
00797 void CSGame::checkWorld()
00798 {
00799     static char *functionName="checkWorld";
00800     LOG_ENTER 
00801     mIsWorldOutOfBounds = false;
00802 
00803     unsigned int ww = mCurrentWorld->getWidth();
00804     unsigned int wh = mCurrentWorld->getHeight();
00805 
00806     unsigned int dx = mCurrentWorld->getDisplayXLowerBound();
00807     unsigned int dX = mCurrentWorld->getDisplayXUpperBound();
00808     unsigned int dy = mCurrentWorld->getDisplayYLowerBound();
00809     unsigned int dY = mCurrentWorld->getDisplayYUpperBound();
00810 
00811     unsigned int dw = dX - dx;
00812     unsigned int dh = dY - dy;
00813 
00814     if ((ww > dw) || (wh > dh)) mIsWorldOutOfBounds = true;
00815     LOG_EXIT 
00816 }
00817 
00818 // TODO optimize the variables to class variables!
00819 // they don't change!
00820 void CSGame::adjustDisplay()
00821 {
00822     static char *functionName="adjustDisplay";
00823     unsigned int dx = mCurrentWorld->getDisplayXLowerBound();
00824     unsigned int dX = mCurrentWorld->getDisplayXUpperBound();
00825     unsigned int dy = mCurrentWorld->getDisplayYLowerBound();
00826     unsigned int dY = mCurrentWorld->getDisplayYUpperBound();
00827 
00828     unsigned int dw = dX - dx;
00829     unsigned int dh = dY - dy;
00830 
00831     unsigned int sx = mMainSprite->getDisplayXLower();
00832     unsigned int sX = mMainSprite->getDisplayXUpper();
00833     unsigned int sy = mMainSprite->getDisplayYLower();
00834     unsigned int sY = mMainSprite->getDisplayYUpper();
00835 
00836     // world coordinates of main sprite
00837     unsigned int swx = mMainSprite->getXPos();
00838     unsigned int swy = mMainSprite->getYPos();
00839     
00840 
00841     int x = mCurrentWorld->getWorldPositionX();
00842     int y = mCurrentWorld->getWorldPositionY();
00843 
00844     if (sx < dx + mThreshold)
00845     {
00846         x = x - (dx + mThreshold - sx);
00847     }
00848 
00849     if (sX > dX - mThreshold)
00850     {
00851         x = x + mThreshold - (dX-sX);
00852     }
00853 
00854     if (sy < dy + mThreshold)
00855     {
00856         y = y - (dy + mThreshold - sy);
00857     }
00858 
00859     if (sY > dY - mThreshold)
00860     {
00861         y = y + mThreshold - (dY-sY);
00862     }
00863 
00864     if (x < 0) x = 0;
00865     if (y < 0) y = 0;
00866     if (x+dw > mCurrentWorld->getWidth() ) x = mCurrentWorld->getWidth() - dw;
00867     if (y+dh > mCurrentWorld->getHeight()) y = mCurrentWorld->getHeight() - dh;
00868 
00869     mCurrentWorld->setWorldPosition(x, y);
00870 }
00871 
00872 void CSGame::loadLevelData(const std::string &filename, CSLevelData *data)
00873 {
00874     static char *functionName="loadLevelData";
00875     LOG_ENTER 
00876     char tmp[10];
00877     int i;
00878     CSXMLHelper xmlSupport(filename, "LEVEL");
00879     try
00880     {
00881         if (xmlSupport.getError())
00882         {
00883             throw "error";
00884         }
00885 
00886         data->id = strdup(xmlSupport.getString("ID").c_str());
00887         int dCount = xmlSupport.getInt("count(DESCRIPTION)");
00888         if (dCount > 0)
00889         {
00890             for (i=0; i<dCount; i++)
00891             {
00892                 char *line;
00893                 // i+1, predicates in xpath start with 1
00894                 std::string a = xmlSupport.getString((std::string)"DESCRIPTION["+itoa(i+1,tmp,10)+"]");
00895                 line =  strdup(a.c_str());
00896 
00897                 data->descriptions.push_back(line);
00898             }
00899         }
00900         int wCount = xmlSupport.getInt("count(WORLD)");
00901         for (i=0; i<wCount; i++)
00902         {
00903             char *line;
00904             // i+1, predicates in xpath start with 1
00905             std::string a = xmlSupport.getString((std::string)"WORLD["+itoa(i+1,tmp,10)+"]");
00906             line =  strdup(a.c_str());
00907 
00908             data->worlds.push_back(line);
00909         }
00910         data->mainSprite.name = strdup(xmlSupport.getString((std::string)"MAIN_SPRITE/NAME").c_str());
00911         data->mainSprite.speed = xmlSupport.getInt("MAIN_SPRITE/SPEED");
00912         data->mainSprite.x = xmlSupport.getInt("MAIN_SPRITE/START_POSITION/X");
00913         data->mainSprite.y = xmlSupport.getInt("MAIN_SPRITE/START_POSITION/Y");
00914         data->mainSprite.z = xmlSupport.getInt("MAIN_SPRITE/START_POSITION/Z");
00915 
00916         int sCount = xmlSupport.getInt("count(SPRITE)");
00917         for (i=0; i<sCount; i++)
00918         {
00919             SpriteData *sData = new SpriteData();
00920             sData->name = strdup(xmlSupport.getString((std::string)"SPRITE["+itoa(i+1,tmp,10)+"]/NAME").c_str());
00921             sData->speed = xmlSupport.getInt((std::string)"SPRITE["+itoa(i+1,tmp,10)+"]/SPEED");
00922             sData->x = xmlSupport.getInt((std::string)"SPRITE["+itoa(i+1,tmp,10)+"]/START_POSITION/X");
00923             sData->y = xmlSupport.getInt((std::string)"SPRITE["+itoa(i+1,tmp,10)+"]/START_POSITION/Y");
00924             sData->z = xmlSupport.getInt((std::string)"SPRITE["+itoa(i+1,tmp,10)+"]/START_POSITION/Z");
00925             sData->behaviour = xmlSupport.getInt((std::string)"SPRITE["+itoa(i+1,tmp,10)+"]/BEHAVIOUR");
00926 
00927             data->sprites.push_back(sData);
00928         }
00929 
00930         sCount = xmlSupport.getInt("count(SAMPLE)");
00931         for (i=0; i<sCount; i++)
00932         {
00933             SampleData *sData = new SampleData();
00934             sData->name = strdup(xmlSupport.getString((std::string)"SAMPLE["+itoa(i+1,tmp,10)+"]/NAME").c_str());
00935             sData->sid = strdup(xmlSupport.getString((std::string)"SAMPLE["+itoa(i+1,tmp,10)+"]/SID").c_str());
00936             data->samples.push_back(sData);
00937         }
00938         loadLevelDataSpecific(xmlSupport);
00939     }
00940     catch(...)
00941     {
00942         LOG_EXIT
00943         SDLMain::shutdown((std::string)"XML error \"" + filename + "\": " + xmlSupport.getErrorMessage().c_str(), 1);
00944     }
00945     LOG_EXIT 
00946 }
00947 
00948 void CSGame::freeLevel()
00949 {
00950     static char *functionName="freeLevel";
00951     LOG_ENTER 
00952     freeLevelSpecific();
00953     clearTimedEvents();
00954     clearSamples();
00955     if (mMainSprite != 0)
00956     {
00957         removeSprite(mMainSprite);
00958         delete mMainSprite;
00959         mMainSprite = 0;
00960     }
00961     mScaleCenterSprite = 0;
00962 
00963     CSSprites::iterator iter = mSprites.begin();
00964     while (iter != mSprites.end())
00965     {
00966         CSSprite *sprite = *iter;
00967         removeSprite(sprite);
00968         delete sprite;
00969         iter = mSprites.begin();    
00970     }
00971     mSprites.clear();
00972 
00973     if (mWorld != 0)
00974     {
00975         for (int i=0; i < mWorldCount; i++)
00976         {
00977             delete mWorld[i];
00978         }
00979 
00980         delete[] mWorld;
00981         mWorld = 0;
00982     }
00983     if (mLevelData != 0)
00984     {
00985         delete mLevelData;
00986         mLevelData = 0;
00987     }
00988     LOG_EXIT 
00989 }
00990 
00991 void CSGame::initLevel(std::string levelName)
00992 {
00993     static char *functionName="initLevel";
00994     LOG_ENTER 
00995     int i;
00996     mLevelData = new CSLevelData();
00997     loadLevelData(levelName, mLevelData);
00998 
00999     mWorld = (CSWorld **) new void *[mLevelData->worlds.size()];
01000     mWorldCount = 0;
01001     for (i = 0; i < mLevelData->worlds.size(); i++)
01002     {
01003         mWorld[i] = CSWorldLoader::INSTANCE.load(mLevelData->worlds.at(i));
01004         mWorld[i]->setWorldNo(i);
01005         mWorld[i]->scaleBackgroundTiles(getDisplayArea().w, getDisplayArea().h);
01006         mWorldCount++;
01007     }
01008 
01009     SpriteDatas::iterator iter = mLevelData->sprites.begin();
01010     for (i = 0; i < mLevelData->sprites.size(); i++)
01011     {
01012 //LOG_AMESSAGE("Loading Sprite: " +std::string(mLevelData->sprites.at(i)->name))
01013         CSSprite* sprite;
01014         sprite = CSSpriteLoader::INSTANCE.load(mLevelData->sprites.at(i)->name);
01015         sprite->setPosition(mLevelData->sprites.at(i)->x, 
01016                             mLevelData->sprites.at(i)->y, 
01017                             mLevelData->sprites.at(i)->z);
01018         sprite->adjustSpeed(mLevelData->sprites.at(i)->speed);
01019         addSprite(sprite);
01020     }
01021 //LOG_AMESSAGE("Done")
01022 
01023     if (mLevelData->mainSprite.name != 0)
01024     {
01025         mMainSprite = CSSpriteLoader::INSTANCE.load(mLevelData->mainSprite.name);
01026         mMainSprite->setPosition(mLevelData->mainSprite.x, mLevelData->mainSprite.y, mLevelData->mainSprite.z);
01027         mMainSprite->adjustSpeed(mLevelData->mainSprite.speed);
01028         addMainSprite(mMainSprite);
01029     }
01030     
01031     for (i = 0; i < mLevelData->samples.size(); i++)
01032     {
01033         CSSample* sample;
01034         sample = CSSampleLoader::INSTANCE.load(mLevelData->samples.at(i)->name);
01035         addSample(sample, mLevelData->samples.at(i)->sid);
01036     }
01037 
01038     setCurrentWorld(mMainSprite->getWorldPos());
01039     mScaleCenterSprite = mMainSprite;
01040     initLevelSpecific(mLevelData);
01041 
01042     if (mDisplayScaled)
01043     {
01044         mCurrentWorld->setScaleDisplayArea(getScaledDisplayArea());
01045         mCurrentWorld->setScaleFactor(getScaleFactor());
01046     }
01047     mLevelFinished = false;
01048 
01049     LOG_EXIT 
01050 }
01051 
01052 void CSGame::setCurrentWorld(unsigned int w)
01053 {
01054     static char *functionName="setCurrentWorld";
01055     LOG_ENTER 
01056     mCurrentWorld = mWorld[w];
01057     mCurrentWorld->setDisplayArea(getDisplayArea());
01058     for (int i=0; i < mWorldCount; i++)
01059     {
01060         mWorld[i]->setActive(i==w);
01061     }
01062     checkWorld();
01063     LOG_EXIT 
01064 }
01065 
01066 void CSGame::loadGameData(const std::string &filename)
01067 {
01068     static char *functionName="loadGameData";
01069     LOG_ENTER 
01070     char tmp[10];
01071     int i;
01072     if (filename.size() == 0)
01073     {
01074         // a dummy game?
01075         // just the gui?
01076         dummyGame = true;
01077         return;
01078     }
01079 
01080     CSXMLHelper xmlSupport(filename, "GAME");
01081     try
01082     {
01083         if (xmlSupport.getError())
01084         {
01085             throw "error";
01086         }
01087 
01088         mId = strdup(xmlSupport.getString("ID").c_str());
01089         int lCount = xmlSupport.getInt("count(LEVEL)");
01090         if (lCount > 0)
01091         {
01092             for (i=0; i<lCount; i++)
01093             {
01094                 char *line;
01095                 // i+1, predicates in xpath start with 1
01096                 std::string a = xmlSupport.getString((std::string)"LEVEL["+itoa(i+1,tmp,10)+"]");
01097                 line =  strdup(a.c_str());
01098                 mLevels.push_back(line);
01099             }
01100         }
01101     }
01102     catch(...)
01103     {
01104         LOG_EXIT
01105         SDLMain::shutdown((std::string)"XML error \"" + filename + "\": " + xmlSupport.getErrorMessage().c_str(), 1);
01106     }
01107     LOG_EXIT 
01108 }
01109 
01110 void CSGame::addSample(CSSample *sample, const char *sid)
01111 {
01112     static char *functionName="addSample";
01113     mSampleMap.insert(std::map<std::string, CSSample *>::value_type(sid, sample));
01114 }
01115 
01116 void CSGame::removeSample(const char *sid)
01117 {
01118     static char *functionName="removeSample";
01119     // delete single object
01120     std::map<std::string, CSSample *>::iterator iter;
01121     for (iter = mSampleMap.begin(); iter!=mSampleMap.end(); iter++)
01122     {
01123         if (strcmp(sid, iter->first.c_str()) == 0)
01124         {
01125             mSampleMap.erase(iter);
01126         }
01127     }
01128 }
01129 
01130 void CSGame::clearSamples()
01131 {
01132     static char *functionName="clearSamples";
01133     LOG_ENTER 
01134     mSampleMap.clear();
01135     LOG_EXIT 
01136 }
01137 
01138 void CSGame::playSample(const char *sid)
01139 {
01140     static char *functionName="playSample";
01141     std::map<std::string, CSSample *>::iterator iter = mSampleMap.find(sid);
01142     if (iter != mSampleMap.end())
01143     {
01144         iter->second->play();
01145     }
01146 }
01147 
01148 void CSGame::checkOutOfBounds()
01149 {
01150     static char *functionName="checkOutOfBounds";
01151     // sprite
01152     OutOfBoundsDatas::iterator iter = mOutOfBoundsDatas.begin();
01153     while (iter != mOutOfBoundsDatas.end())
01154     {
01155         OutOfBoundsData *data = *iter;
01156         int count = 0;
01157         int yl = data->sprite->getYPos() - data->threshold;
01158         int xl = data->sprite->getXPos() - data->threshold;
01159         int yh = yl+data->sprite->getMaxHeight() + data->threshold;
01160         int xh = xl+data->sprite->getMaxWidth() + data->threshold;
01161 
01162         if (yh > getWorld()->getHeight())
01163         {
01164             MESSAGE_SPRITE_OUT_OF_BOUNDS.setSubsubtype(Y_HIGHER);
01165             MESSAGE_SPRITE_OUT_OF_BOUNDS.sprite = data->sprite;
01166             sendMessage(MESSAGE_SPRITE_OUT_OF_BOUNDS);
01167         }
01168         else if (yl < 0)
01169         {
01170             MESSAGE_SPRITE_OUT_OF_BOUNDS.setSubsubtype(Y_LOWER);
01171             MESSAGE_SPRITE_OUT_OF_BOUNDS.sprite = data->sprite;
01172             sendMessage(MESSAGE_SPRITE_OUT_OF_BOUNDS);
01173         }
01174         if (xh > getWorld()->getWidth())
01175         {
01176             MESSAGE_SPRITE_OUT_OF_BOUNDS.setSubsubtype(X_HIGHER);
01177             MESSAGE_SPRITE_OUT_OF_BOUNDS.sprite = data->sprite;
01178             sendMessage(MESSAGE_SPRITE_OUT_OF_BOUNDS);
01179         }
01180         else if (xl < 0)
01181         {
01182             MESSAGE_SPRITE_OUT_OF_BOUNDS.setSubsubtype(X_LOWER);
01183             MESSAGE_SPRITE_OUT_OF_BOUNDS.sprite = data->sprite;
01184             sendMessage(MESSAGE_SPRITE_OUT_OF_BOUNDS);
01185         }
01186         iter++;
01187     }
01188 }
01189 
01190 void CSGame::doPause(void)
01191 {
01192     static char *functionName="doPause";
01193     LOG_ENTER 
01194     mPause = !mPause;
01195     if (mPause)
01196     {
01197         CSSample::pauseAll();
01198     }
01199     else
01200     {
01201         CSSample::resumeAll();
01202         mCurrentTime = SDL_GetTicks();
01203     }
01204     LOG_EXIT 
01205 }
01206 
01207 void CSGame::addTimedEvent(unsigned int timeSpace, int id, void *data, void (*answer)(TimedEvent *), int repeat, bool repeatUse)
01208 {
01209     static char *functionName="addTimedEvent";
01210     // don't add two events at exactly the same time!
01211     CSEventMap::iterator iter = mEventMap->find(mGameTime + timeSpace);
01212     while (iter != mEventMap->end())
01213     {
01214         timeSpace++;
01215         iter = mEventMap->find(mGameTime + timeSpace);
01216     }
01217     
01218     TimedEvent *event = new TimedEvent();
01219     event->id = id;
01220     event->data = data;
01221     event->repeat = repeat;
01222     event->finishTime = mGameTime + timeSpace;
01223     event->intervall = timeSpace;
01224     event->useRepeat = repeatUse;
01225     event->answer = answer;
01226 
01227     mEventMap->insert(CSEventMap::value_type(event->finishTime, event));
01228 }
01229 
01230 void CSGame::addTimedEvent(unsigned int timeSpace, int id, void *data, int repeat,  bool repeatUse)
01231 {
01232     static char *functionName="addTimedEvent";
01233     // don't add two events at exactly the same time!
01234     CSEventMap::iterator iter = mEventMap->find(mGameTime + timeSpace);
01235     while (iter != mEventMap->end())
01236     {
01237         timeSpace++;
01238         iter = mEventMap->find(mGameTime + timeSpace);
01239     }
01240     
01241     TimedEvent *event = new TimedEvent();
01242     event->id = id;
01243     event->data = data;
01244     event->repeat = repeat;
01245     event->finishTime = mGameTime + timeSpace;
01246     event->intervall = timeSpace;
01247     event->useRepeat = repeatUse;
01248 
01249     mEventMap->insert(CSEventMap::value_type(event->finishTime, event));
01250 }
01251 
01252 void CSGame::removeTimedEvent(int id, void *data)
01253 {
01254     static char *functionName="removeTimedEvent";
01255     CSEventMap::iterator iter = mEventMap->begin();
01256     while (iter!=mEventMap->end())
01257     {
01258         TimedEvent *event = iter->second;
01259         if ((event->id == id) && (data == event->data))
01260         {
01261             mEventMap->erase(iter);
01262             delete (event);
01263             iter = mEventMap->begin();
01264             continue;
01265         }
01266         iter++;
01267     }
01268 }
01269 
01270 void CSGame::removeTimedEvent(int id)
01271 {
01272     static char *functionName="removeTimedEvent";
01273     CSEventMap::iterator iter = mEventMap->begin();
01274     while (iter!=mEventMap->end())
01275     {
01276         TimedEvent *event = iter->second;
01277         if (event->id == id)
01278         {
01279             mEventMap->erase(iter);
01280             delete (event);
01281             iter = mEventMap->begin();
01282             continue;
01283         }
01284         iter++;
01285     }
01286 }
01287 
01288 void CSGame::clearTimedEvents()
01289 {
01290     static char *functionName="clearTimedEvents";
01291     LOG_ENTER 
01292     CSEventMap::iterator iter = mEventMap->begin();
01293     while (iter!=mEventMap->end())
01294     {
01295         TimedEvent *event = iter->second;
01296         mEventMap->erase(iter);
01297         delete (event);
01298         iter = mEventMap->begin();
01299     }
01300     LOG_EXIT 
01301 }
01302 
01303 // would be "better" if the map was sorted
01304 void CSGame::checkTimedEvent()
01305 {
01306     static char *functionName="checkTimedEvent";
01307     CSEventMap::iterator iter = mEventMap->begin();
01308     while (iter!=mEventMap->end())
01309     {
01310         if (iter->first <= mGameTime)
01311         {
01312             TimedEvent *event = iter->second;
01313             mEventMap->erase(iter); // erase befor the event,
01314                                     // since within the event, mEventMap might be changed (BAD!)
01315             if (event->answer == 0)
01316             {
01317                 reactOnTimedEvent(event);
01318             }
01319             else
01320             {
01321                 event->answer(event);
01322             }
01323             if (event->useRepeat)
01324             {
01325                 event->repeat--;
01326                 if (event->repeat > 0)
01327                 {
01328                     event->finishTime = mGameTime + event->intervall;
01329                     mEventMap->insert(CSEventMap::value_type(event->finishTime, event));
01330                 }
01331                 else
01332                 {
01333                     delete (event);
01334                 }
01335             }
01336             else
01337             {
01338                 delete (event);
01339             }
01340             iter = mEventMap->begin(); // restart, since mEventMap was surely changed!
01341             continue;
01342         }
01343         iter++;
01344     }
01345 }
01346 
01347 // resets sprite to initial Level values!
01348 void CSGame::resetSprites()
01349 {
01350     static char *functionName="resetSprites";
01351     LOG_ENTER 
01352     int i;
01353     CSSprites::iterator iter = mSprites.begin();
01354     for (i = 0; i < mLevelData->sprites.size(); i++)
01355     {
01356         CSSprite* sprite = *iter;
01357         sprite->setPosition(mLevelData->sprites.at(i)->x, 
01358                             mLevelData->sprites.at(i)->y, 
01359                             mLevelData->sprites.at(i)->z);
01360         iter++;
01361     }
01362 
01363     if (mMainSprite != 0)
01364     {
01365         mMainSprite->setPosition(mLevelData->mainSprite.x, mLevelData->mainSprite.y, mLevelData->mainSprite.z);
01366         setCurrentWorld(mLevelData->mainSprite.z);
01367     }
01368     resetSpritesSpecific();
01369     LOG_EXIT 
01370 }
01371 
01372 void CSGame::disableSpriteMovement()
01373 {
01374     static char *functionName="disableSpriteMovement";
01375     LOG_ENTER 
01376     CSSprites::iterator iter = mSprites.begin();
01377     while (iter != mSprites.end())
01378     {
01379         CSSprite *sprite = *iter;
01380         sprite->adjustSpeed(0);
01381         iter++;
01382     }
01383     LOG_EXIT 
01384 }
01385 
01386 bool CSGame::isSamplePlaying(void)
01387 {
01388     static char *functionName="isSamplePlaying";
01389     return CSSample::isPlaying();
01390 }
01391 
01392 void CSGame::screenChanged()
01393 {
01394     static char *functionName="screenChanged";
01395     LOG_ENTER 
01396     // following classes include surfaces that are screen dependent
01397     // the classes must take care of themselfs
01398     // but we must at least tell them that the video mode has changed!
01399     CSPicture::resetSurfaces();
01400     CSFont::resetSurfaces();
01401     initSpeed();
01402     if (mDisplayScaled)
01403     {
01404         mCurrentWorld->resetScaledWorld();
01405     }
01406     LOG_EXIT 
01407 }
01408                     
01409 void CSGame::setScaleDisplayLayer(bool b, int layer)
01410 {
01411     static char *functionName="setScaleDisplayLayer";
01412     LOG_ENTER 
01413     mCurrentWorld->setScaleDisplayLayer(b,layer);
01414     LOG_EXIT 
01415 }
01416 
01417 void CSGame::enableDesktop(bool b)
01418 {
01419     static char *functionName="enableDesktop";
01420     LOG_ENTER 
01421     if (b == mIsGui)
01422     {
01423         LOG_EXIT 
01424         return;
01425     }
01426     mIsGui = b;
01427     LOG_EXIT 
01428 }
01429 
01430 void CSGame::onMouseMotion(SDL_MouseMotionEvent event)
01431 {
01432     static char *functionName="onMouseMotion";
01433     if (mIsGui)
01434     {
01435         if (mDesktop->isIn(event.x,event.y, 0))
01436         {
01437             mDesktop->onMouseMotion(event.x,event.y);
01438         }
01439     }
01440 }
01441 
01442 void CSGame::onMouseButtonDown(SDL_MouseButtonEvent event)
01443 {
01444     static char *functionName="onMouseButtonDown";
01445     LOG_ENTER 
01446     if (mIsGui)
01447     {
01448         if (mDesktop->isIn(event.x,event.y, 0))
01449         {
01450             mDesktop->onMouseDown(event.x,event.y);
01451         }
01452     }
01453     LOG_EXIT 
01454 }
01455 
01456 void CSGame::onMouseButtonUp(SDL_MouseButtonEvent event)
01457 {
01458     static char *functionName="onMouseButtonUp";
01459     LOG_ENTER 
01460     if (mIsGui)
01461     {
01462         if (mDesktop->isIn(event.x,event.y, 0))
01463         {
01464             mDesktop->onMouseUp(event.x,event.y);
01465         }
01466     }
01467     LOG_EXIT 
01468 }
01469 
01470 void CSGame::handleEvents()
01471 {
01472     static char *functionName="handleEvents";
01473     SDL_Event event;
01474 
01475     if (SDL_PeepEvents(&event, 1, SDL_PEEKEVENT,SDL_MOUSEMOTIONMASK)==1)
01476     {
01477         do 
01478         {
01479             SDL_PeepEvents(&event,1, SDL_GETEVENT,SDL_MOUSEMOTIONMASK);
01480         } while (SDL_PeepEvents(&event,1 , SDL_PEEKEVENT,SDL_MOUSEMOTIONMASK)==1);
01481         
01482         onMouseMotion(event.motion);
01483     }
01484     
01485     if (SDL_PollEvent(&event))
01486     {
01487         switch(event.type)
01488         {
01489             case SDL_MOUSEMOTION:
01490             {
01491                 onMouseMotion(event.motion); 
01492                 break;
01493             }
01494             case SDL_MOUSEBUTTONDOWN:
01495             {
01496                 onMouseButtonDown(event.button); 
01497                 break;
01498             }
01499             case SDL_MOUSEBUTTONUP:
01500             {
01501                 onMouseButtonUp(event.button); 
01502                 break;
01503             }
01504             case SDL_KEYUP:
01505             {
01506                 if (mIsGui)
01507                 {
01508                     mDesktop->dispatchKeyEvent(event, SDL_KEYUP);
01509                 }
01510                 break;
01511             }
01512             case SDL_KEYDOWN:
01513             {
01514                 bool used = false;
01515                 if (mIsGui)
01516                 {
01517                     used = mDesktop->dispatchKeyEvent(event, SDL_KEYDOWN);
01518                 }
01519                 if (!used)
01520                 {
01521                     switch(event.key.keysym.sym) 
01522                     {
01523                         case SDLK_ESCAPE:
01524                             sendMessage(MESSAGE_END);
01525                             break;
01526 
01527                         case SDLK_RIGHT:
01528                         case SDLK_r:
01529                             sendMessage(MESSAGE_KEY_RIGHT);
01530                             break;
01531 
01532                         case SDLK_LEFT:
01533                         case SDLK_l:
01534                             sendMessage(MESSAGE_KEY_LEFT);
01535                             break;
01536 
01537                         case SDLK_UP:
01538                         case SDLK_u:
01539                             sendMessage(MESSAGE_KEY_UP);
01540                             break;
01541 
01542                         case SDLK_DOWN:
01543                         case SDLK_d:
01544                             sendMessage(MESSAGE_KEY_DOWN);
01545                             break;
01546                         case SDLK_p:
01547                             sendMessage(MESSAGE_PAUSE);
01548                             break;
01549                         case SDLK_g:
01550                             sendMessage(MESSAGE_TOGGLE_GUI);
01551                             break;
01552 
01553                         case SDLK_SPACE:
01554     //                      sendMessage(MESSAGE_KEY_FIRE);
01555     p = 1;
01556                             break;
01557 
01558                         case SDLK_F4:
01559                             sendMessage(MESSAGE_TOGGLE_FULLSCREEN);
01560                             break;
01561                         default:
01562                             break;
01563                     }
01564                 }
01565             }
01566             break;
01567         }
01568     }
01569 }
01570 
01571 void CSGame::intro(void)
01572 {
01573 }
01574 
01575 int CSGame::getLevelDataNum(CSSprite *sprite)
01576 {
01577     SpriteDatas::iterator iter = mLevelData->sprites.begin();
01578 
01579     for (int i = 0; i < mLevelData->sprites.size(); i++)
01580     {
01581         SpriteData* data = (SpriteData *) mLevelData->sprites.at(i);
01582         if (strcmp(data->name, sprite->getFilename().c_str()) == 0)
01583         {
01584             return i;
01585         }
01586     }
01587     return -1;
01588 }
01589 
01590 
01591 

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