MainCamera.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <client/ClientState.h>
00022 #include <client/ScorchedClient.h>
00023 #include <client/ClientParams.h>
00024 #include <graph/MainCamera.h>
00025 #include <graph/Main2DCamera.h>
00026 #include <graph/OptionsDisplay.h>
00027 #include <landscapemap/LandscapeMaps.h>
00028 #include <landscapedef/LandscapeDefn.h>
00029 #include <engine/ViewPoints.h>
00030 #include <image/ImageFactory.h>
00031 #include <image/ImagePng.h>
00032 #include <dialogs/MainMenuDialog.h>
00033 #include <sound/Sound.h>
00034 #include <sound/SoundUtils.h>
00035 #include <common/Keyboard.h>
00036 #include <common/Defines.h>
00037 #include <common/Logger.h>
00038 #include <coms/ComsOperationResultMessage.h>
00039 #include <coms/ComsMessageSender.h>
00040 #include <tank/TankContainer.h>
00041 #include <tank/TankCamera.h>
00042 #include <lang/LangResource.h>
00043 #include <math.h>
00044 #include <time.h>
00045 
00046 MainCamera *MainCamera::instance_ = 0;
00047 
00048 MainCamera *MainCamera::instance()
00049 {
00050         if (!instance_)
00051         {
00052                 instance_ = new MainCamera;
00053         }
00054 
00055         return instance_;
00056 }
00057 
00058 MainCamera::MainCamera() : 
00059         GameStateI("MainCamera"),
00060         mouseDown_(false), keyDown_(false), scrolling_(false), showArena_(false)
00061 {
00062         Image *map = ImageFactory::loadImage(
00063                 S3D::getDataFile("data/windows/camera.bmp"),
00064                 S3D::getDataFile("data/windows/cameraa.bmp"),
00065                 false);
00066         DIALOG_ASSERT(map->getBits());
00067         MainMenuDialog::instance()->addMenu(
00068                 LANG_RESOURCE("CAMERA", "Camera"),
00069                 "Camera", 
00070                 LANG_RESOURCE("CAMERA_MENU", "Change the current camera view."),
00071                 32, 0, this, map);
00072 }
00073 
00074 MainCamera::~MainCamera()
00075 {
00076 
00077 }
00078 
00079 bool MainCamera::getEnabled(const char* menuName)
00080 {
00081         unsigned int state = ScorchedClient::instance()->getGameState().getState();
00082         return (state >= ClientState::StateWait);
00083 }
00084 
00085 bool MainCamera::getMenuItems(const char* menuName, 
00086         std::list<GLMenuItem> &result)
00087 {
00088         for (int i=0; i<TargetCamera::getNoCameraNames(); i++)
00089         {
00090                 result.push_back(GLMenuItem(
00091                         LANG_RESOURCE(TargetCamera::getCameraNames()[i], TargetCamera::getCameraNames()[i]),
00092                         &TargetCamera::getCameraToolTips()[i],
00093                         (targetCam_.getCameraType() == 
00094                         (TargetCamera::CamType) i)));
00095         }
00096         return true;
00097 }
00098 
00099 void MainCamera::menuSelection(const char* menuName, 
00100         const int position, GLMenuItem &item)
00101 {
00102         targetCam_.setCameraType((TargetCamera::CamType) position);
00103 }
00104 
00105 static int getNumberOfPlayers()
00106 {
00107         int count = 0;
00108         std::map<unsigned int, Tank *> &tanks = 
00109                 ScorchedClient::instance()->getTankContainer().getAllTanks();
00110         std::map<unsigned int, Tank *>::iterator mainitor;
00111         for (mainitor = tanks.begin();
00112                 mainitor != tanks.end();
00113                 mainitor++)
00114         {
00115                 Tank *current = (*mainitor).second;
00116                 if (current->getTankAI()) count++;
00117         }
00118         return count;
00119 }
00120 
00121 void MainCamera::simulate(const unsigned state, float frameTime)
00122 {
00123         scrolling_ = false;
00124         if (state != 0 &&
00125                 state != ClientState::StateOptions &&
00126                 OptionsDisplay::instance()->getFullScreen() &&
00127                 OptionsDisplay::instance()->getSideScroll())
00128         {
00129                 int mouseX = ScorchedClient::instance()->getGameState().getMouseX();
00130                 int mouseY = ScorchedClient::instance()->getGameState().getMouseY();
00131                 int windowX = Main2DCamera::instance()->getViewPort().getWidth();
00132                 int windowY = Main2DCamera::instance()->getViewPort().getHeight();
00133 
00134                 float arenaWidth = (float) ScorchedClient::instance()->getLandscapeMaps().
00135                         getGroundMaps().getArenaWidth();
00136                 float arenaHeight = (float) ScorchedClient::instance()->getLandscapeMaps().
00137                         getGroundMaps().getArenaHeight();
00138                 float arenaX = (float) ScorchedClient::instance()->getLandscapeMaps().
00139                         getGroundMaps().getArenaX();
00140                 float arenaY = (float) ScorchedClient::instance()->getLandscapeMaps().
00141                         getGroundMaps().getArenaY();
00142 
00143                 {
00144                         const int scrollWindow = 5;
00145                         if (mouseX < scrollWindow)
00146                         {
00147                                 targetCam_.setCameraType(TargetCamera::CamFree);
00148                                 if (Keyboard::instance()->getKeyboardState() & KMOD_LSHIFT)
00149                                 {
00150                                         scrolling_ = true;
00151                                         targetCam_.getCamera().movePositionDelta(-1.0f * frameTime, 0.0f, 0.0f);
00152                                 }
00153                                 else
00154                                 {
00155                                         scrolling_ = true;
00156                                         targetCam_.getCamera().scroll(GLCamera::eScrollLeft, 
00157                                                 arenaX, arenaY, arenaX + arenaWidth, arenaY + arenaHeight,
00158                                                 100.0f * frameTime);
00159                                 }
00160                         }
00161                         else if (mouseX > windowX - scrollWindow)
00162                         {
00163                                 targetCam_.setCameraType(TargetCamera::CamFree);
00164                                 if (Keyboard::instance()->getKeyboardState() & KMOD_LSHIFT)
00165                                 {
00166                                         scrolling_ = true;
00167                                         targetCam_.getCamera().movePositionDelta(+1.0f * frameTime, 0.0f, 0.0f);
00168                                 }
00169                                 else
00170                                 {
00171                                         scrolling_ = true;
00172                                         targetCam_.getCamera().scroll(GLCamera::eScrollRight,
00173                                                 arenaX, arenaY, arenaX + arenaWidth, arenaY + arenaHeight,
00174                                                 100.0f * frameTime);
00175                                 }
00176                         }
00177                 
00178                         if (mouseY < scrollWindow)
00179                         {
00180                                 targetCam_.setCameraType(TargetCamera::CamFree);
00181                                 if (Keyboard::instance()->getKeyboardState() & KMOD_LSHIFT)
00182                                 {
00183                                         scrolling_ = true;
00184                                         targetCam_.getCamera().movePositionDelta(0.0f, 1.0f * frameTime, 0.0f);
00185                                 }
00186                                 else if (Keyboard::instance()->getKeyboardState() & KMOD_LCTRL)
00187                                 {
00188                                         scrolling_ = true;
00189                                         targetCam_.getCamera().movePositionDelta(0.0f, 0.0f, +100.0f * frameTime);
00190                                 }
00191                                 else
00192                                 {
00193                                         scrolling_ = true;
00194                                         targetCam_.getCamera().scroll(GLCamera::eScrollDown, 
00195                                                 arenaX, arenaY, arenaX + arenaWidth, arenaY + arenaHeight,
00196                                                 100.0f * frameTime);
00197                                 }
00198                         }
00199                         else if (mouseY > windowY - scrollWindow)
00200                         {
00201                                 targetCam_.setCameraType(TargetCamera::CamFree);
00202                                 if (Keyboard::instance()->getKeyboardState() & KMOD_LSHIFT)
00203                                 {
00204                                         scrolling_ = true;
00205                                         targetCam_.getCamera().movePositionDelta(0.0f, -1.0f * frameTime, 0.0f);
00206                                 }
00207                                 else if (Keyboard::instance()->getKeyboardState() & KMOD_LCTRL)
00208                                 {
00209                                         scrolling_ = true;
00210                                         targetCam_.getCamera().movePositionDelta(0.0f, 0.0f, -100.0f * frameTime);
00211                                 }
00212                                 else
00213                                 {
00214                                         scrolling_ = true;
00215                                         targetCam_.getCamera().scroll(GLCamera::eScrollUp, 
00216                                                 arenaX, arenaY, arenaX + arenaWidth, arenaY + arenaHeight,
00217                                                 100.0f * frameTime);
00218                                 }
00219                         }
00220                 }
00221         }
00222 
00223         ScorchedClient::instance()->getContext().getViewPoints().simulate(
00224                 fixed::fromFloat(frameTime));
00225         targetCam_.simulate(frameTime, (state == ClientState::StatePlaying));
00226 
00227         Sound::instance()->getDefaultListener()->setPosition(
00228                 targetCam_.getCamera().getCurrentPos());
00229         Sound::instance()->getDefaultListener()->setVelocity(
00230                 targetCam_.getCamera().getVelocity());
00231         Vector direction = 
00232                 targetCam_.getCamera().getLookAt() -
00233                 targetCam_.getCamera().getCurrentPos();
00234         Sound::instance()->getDefaultListener()->setOrientation(
00235                 direction);
00236 
00237         // Update the current tank's camera attributes
00238         if (state == ClientState::StatePlaying ||
00239                 ClientParams::instance()->getConnectedToServer() ||
00240                 getNumberOfPlayers() <= 1)
00241         {
00242                 Tank *current = ScorchedClient::instance()->getTankContainer().getCurrentTank();
00243                 if (current)
00244                 {
00245                         Vector rotation(
00246                                 targetCam_.getCamera().getRotationXY(),
00247                                 targetCam_.getCamera().getRotationYZ(),
00248                                 targetCam_.getCamera().getZoom());
00249                         current->getCamera().setCameraLookAt(targetCam_.getCamera().getLookAt());
00250                         current->getCamera().setCameraRotation(rotation);
00251                         current->getCamera().setCameraType((int) targetCam_.getCameraType());
00252                 }
00253         }
00254 }
00255 
00256 void MainCamera::draw(const unsigned state)
00257 {
00258         targetCam_.draw();
00259 }
00260 
00261 void MainCamera::mouseDrag(const unsigned state, 
00262         GameState::MouseButton button, 
00263         int mx, int my, int x, int y, bool &skipRest)
00264 {
00265         targetCam_.mouseDrag(button, mx, my, x, y, skipRest);
00266 }
00267 
00268 void MainCamera::mouseWheel(const unsigned state, int x, int y, int z, bool &skipRest)
00269 {
00270         targetCam_.mouseWheel(x, y, z, skipRest);
00271 }
00272 
00273 void MainCamera::mouseDown(const unsigned state, GameState::MouseButton button, 
00274         int x, int y, bool &skipRest)
00275 {
00276         mouseDown_ = true;
00277         if (button == GameState::MouseButtonLeft) 
00278         {
00279                 targetCam_.mouseDown(button, x, y, skipRest);
00280         }
00281 }
00282 
00283 void MainCamera::mouseUp(const unsigned state, GameState::MouseButton button,
00284         int x, int y, bool &skipRest)
00285 {
00286         mouseDown_ = false;
00287         if (button == GameState::MouseButtonLeft) 
00288         {
00289                 targetCam_.mouseUp(button, x, y, skipRest);
00290         }
00291 }
00292 
00293 void MainCamera::keyboardCheck(const unsigned state, float frameTime, 
00294                                                            char *buffer, unsigned int keyState,
00295                                                            KeyboardHistory::HistoryElement *history, 
00296                                                            int hisCount, 
00297                                                            bool &skipRest)
00298 {
00299         keyDown_ = targetCam_.keyboardCheck(frameTime, buffer,
00300                 keyState, history, hisCount, skipRest);
00301 
00302         KEYBOARDKEY("SAVE_SCREEN", saveScreenKey);
00303         if (saveScreenKey->keyDown(buffer, keyState, false))
00304         {
00305                 saveScreen_.saveScreen_ = true;
00306         }
00307 
00308         KEYBOARDKEY("SHOW_ARENA", showArena);
00309         showArena_ = showArena->keyDown(buffer, keyState);
00310 
00311         KEYBOARDKEY("CAMERA_SCROLL_UP", scrollUp);
00312         KEYBOARDKEY("CAMERA_SCROLL_DOWN", scrollDown);
00313         KEYBOARDKEY("CAMERA_SCROLL_LEFT", scrollLeft);
00314         KEYBOARDKEY("CAMERA_SCROLL_RIGHT", scrollRight);
00315 
00316         float arenaWidth = (float) ScorchedClient::instance()->getLandscapeMaps().
00317                 getGroundMaps().getArenaWidth();
00318         float arenaHeight = (float) ScorchedClient::instance()->getLandscapeMaps().
00319                 getGroundMaps().getArenaHeight();
00320         float arenaX = (float) ScorchedClient::instance()->getLandscapeMaps().
00321                 getGroundMaps().getArenaX();
00322         float arenaY = (float) ScorchedClient::instance()->getLandscapeMaps().
00323                 getGroundMaps().getArenaY();
00324 
00325         if (scrollUp->keyDown(buffer, keyState)) 
00326         {
00327                 keyDown_ = true;
00328                 targetCam_.setCameraType(TargetCamera::CamFree);
00329                 targetCam_.getCamera().scroll(GLCamera::eScrollUp, 
00330                         arenaX, arenaY, arenaX + arenaWidth, arenaY + arenaHeight,
00331                         100.0f * frameTime);
00332         }
00333         else if (scrollDown->keyDown(buffer, keyState)) 
00334         {
00335                 keyDown_ = true;
00336                 targetCam_.setCameraType(TargetCamera::CamFree);
00337                 targetCam_.getCamera().scroll(GLCamera::eScrollDown,
00338                         arenaX, arenaY, arenaX + arenaWidth, arenaY + arenaHeight,
00339                         100.0f * frameTime);
00340         }
00341         else if (scrollLeft->keyDown(buffer, keyState)) 
00342         {
00343                 keyDown_ = true;
00344                 targetCam_.setCameraType(TargetCamera::CamFree);
00345                 targetCam_.getCamera().scroll(GLCamera::eScrollLeft,
00346                         arenaX, arenaY, arenaX + arenaWidth, arenaY + arenaHeight,
00347                         100.0f * frameTime);
00348         }
00349         else if (scrollRight->keyDown(buffer, keyState)) 
00350         {
00351                 keyDown_ = true;
00352                 targetCam_.setCameraType(TargetCamera::CamFree);
00353                 targetCam_.getCamera().scroll(GLCamera::eScrollRight,
00354                         arenaX, arenaY, arenaX + arenaWidth, arenaY + arenaHeight,
00355                         100.0f * frameTime);
00356         }
00357 
00358         KEYBOARDKEY("HIDE_ALL_DIALOGS", hideWindows);
00359         if (hideWindows->keyDown(buffer, keyState, false)) 
00360         {
00361                 Main2DCamera::instance()->setHide(
00362                         !Main2DCamera::instance()->getHide());
00363         }
00364 
00365         KEYBOARDKEY("CAMERA_SET_QUICK_SLOT_1", setQuick1);
00366         KEYBOARDKEY("CAMERA_SET_QUICK_SLOT_2", setQuick2);
00367         KEYBOARDKEY("CAMERA_SET_QUICK_SLOT_3", setQuick3);
00368         KEYBOARDKEY("CAMERA_SET_QUICK_SLOT_4", setQuick4);
00369         KEYBOARDKEY("CAMERA_SET_QUICK_SLOT_5", setQuick5);
00370         KEYBOARDKEY("CAMERA_USE_QUICK_SLOT_1", useQuick1);
00371         KEYBOARDKEY("CAMERA_USE_QUICK_SLOT_2", useQuick2);
00372         KEYBOARDKEY("CAMERA_USE_QUICK_SLOT_3", useQuick3);
00373         KEYBOARDKEY("CAMERA_USE_QUICK_SLOT_4", useQuick4);
00374         KEYBOARDKEY("CAMERA_USE_QUICK_SLOT_5", useQuick5);
00375         if (setQuick1->keyDown(buffer, keyState, false)) 
00376                 setQuick(1);
00377         else if (setQuick2->keyDown(buffer, keyState, false)) 
00378                 setQuick(2);
00379         else if (setQuick3->keyDown(buffer, keyState, false)) 
00380                 setQuick(3);
00381         else if (setQuick4->keyDown(buffer, keyState, false)) 
00382                 setQuick(4);
00383         else if (setQuick5->keyDown(buffer, keyState, false)) 
00384                 setQuick(5);
00385         else if (useQuick1->keyDown(buffer, keyState, false)) 
00386                 useQuick(1);
00387         else if (useQuick2->keyDown(buffer, keyState, false)) 
00388                 useQuick(2);
00389         else if (useQuick3->keyDown(buffer, keyState, false)) 
00390                 useQuick(3);
00391         else if (useQuick4->keyDown(buffer, keyState, false)) 
00392                 useQuick(4);
00393         else if (useQuick5->keyDown(buffer, keyState, false)) 
00394                 useQuick(5);
00395 }
00396 
00397 void MainCamera::setQuick(int key)
00398 {
00399         std::pair<Vector, Vector> value(
00400                 targetCam_.getCamera().getLookAt(),
00401                 Vector(targetCam_.getCamera().getRotationXY(),
00402                 targetCam_.getCamera().getRotationYZ(),
00403                 targetCam_.getCamera().getZoom()));
00404         quickKeys_[key] = value;
00405         Logger::log(S3D::formatStringBuffer("Saved camera preset %i", key));
00406 }
00407 
00408 void MainCamera::useQuick(int key)
00409 {
00410         std::map<int, std::pair<Vector, Vector> >::iterator 
00411                 findItor = quickKeys_.find(key);
00412         if (findItor != quickKeys_.end())
00413         {
00414                 std::pair<Vector, Vector> value = (*findItor).second;
00415                 targetCam_.setCameraType(TargetCamera::CamFree);
00416                 targetCam_.getCamera().setLookAt(value.first);
00417                 targetCam_.getCamera().movePosition(value.second[0],
00418                         value.second[1], value.second[2]);
00419                 Logger::log(S3D::formatStringBuffer("Using camera preset %i", key));
00420         }
00421 }
00422 
00423 void MainCamera::SaveScreen::draw(const unsigned state)
00424 {
00425         if (saveScreen_)
00426         {
00427                 saveScreen_ = false;
00428 
00429                 bool hide = Main2DCamera::instance()->getHide();
00430                 Main2DCamera::instance()->setHide(false);
00431                 Main2DCamera::instance()->draw(0);
00432                 Main2DCamera::instance()->setHide(hide);
00433 
00434                 static unsigned counter = 0;
00435                 time_t currentTime = time(0);
00436                 std::string fileName = 
00437                         S3D::getHomeFile(S3D::formatStringBuffer("ScreenShot-%i-%i.png", currentTime, counter++));
00438 
00439                 ImageHandle screenMap = ImageFactory::grabScreen();
00440 
00441                 ImagePng png(screenMap.getWidth(), screenMap.getHeight());
00442                 memcpy(png.getBits(), screenMap.getBits(), screenMap.getWidth() * screenMap.getHeight() * 3);
00443 
00444                 NetBuffer buffer;
00445                 png.writeToBuffer(buffer);
00446 
00447                 FILE *out = fopen(fileName.c_str(), "wb");
00448                 fwrite(buffer.getBuffer(), 1, buffer.getBufferUsed(), out);
00449                 fclose(out);
00450 
00451                 // Don't print to banner otherwise this message will be in
00452                 // the screenshot!
00453                 Logger::log(S3D::formatStringBuffer("Screen shot saved as file \"%s\"", fileName.c_str()));
00454 
00455                 // snapshot sound
00456                 CACHE_SOUND(sound, S3D::getDataFile("data/wav/misc/camera.wav"));
00457                 SoundUtils::playRelativeSound(VirtualSoundPriority::eText, sound);
00458         }
00459         if (saveScreenTest_)
00460         {
00461                 saveScreenTest_ = false;
00462 
00463                 ImageHandle screenMap = ImageFactory::grabScreen();
00464                 ComsOperationResultMessage resultMessage;
00465                 resultMessage.getResultBuffer().addDataToBuffer(
00466                         screenMap.getBits(), 
00467                         screenMap.getWidth() * screenMap.getHeight() * 3);
00468                 resultMessage.getWidth() = screenMap.getWidth();
00469                 resultMessage.getHeight() = screenMap.getHeight();
00470                 ComsMessageSender::sendToServer(resultMessage);
00471         }
00472 }
00473 
00474 void MainCamera::Precipitation::draw(const unsigned state)
00475 {
00476         MainCamera::instance()->getTarget().drawPrecipitation();
00477 }

Generated on Mon Feb 16 15:14:46 2009 for Scorched3D by  doxygen 1.5.3