00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00452
00453 Logger::log(S3D::formatStringBuffer("Screen shot saved as file \"%s\"", fileName.c_str()));
00454
00455
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 }