3 #include "viewframelistener.h"
4 #include "viewconstants.h"
5 #include "../middleman.h"
6 #include "animationfactory.h"
7 #include "bleedinganimation.h"
8 #include "../logic/chessboard.h"
14 mInputManager
->destroyInputObject( mMouse
);
15 mInputManager
->destroyInputObject( mKeyboard
);
16 OIS::InputManager::destroyInputSystem(mInputManager
);
31 void View::createRoot()
33 #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
34 mRoot
= new Root("plugins-windows.cfg");
36 mRoot
= new Root("plugins-linux.cfg");
40 void View::defineResources()
42 String secName
, typeName
, archName
;
44 cf
.load("resources.cfg");
45 ConfigFile::SectionIterator seci
= cf
.getSectionIterator();
46 while (seci
.hasMoreElements())
48 secName
= seci
.peekNextKey();
49 ConfigFile::SettingsMultiMap
*settings
= seci
.getNext();
50 ConfigFile::SettingsMultiMap::iterator i
;
51 for (i
= settings
->begin(); i
!= settings
->end(); ++i
)
55 ResourceGroupManager::getSingleton().addResourceLocation(archName
, typeName
, secName
);
60 void View::setupRenderSystem()
62 if (!mRoot
->restoreConfig() && !mRoot
->showConfigDialog())
63 throw Exception(52, "User canceled the config dialog!", "Application::setupRenderSystem()");
66 void View::createRenderWindow()
68 mRoot
->initialise(true, "NALCG");
71 void View::initializeResourceGroups()
73 TextureManager::getSingleton().setDefaultNumMipmaps(5);
74 ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
77 void View::setupScene()
79 mSceneMgr
= mRoot
->createSceneManager(ST_GENERIC
, "Default SceneManager");
81 mWindow
= mRoot
->getAutoCreatedWindow();
85 void View::setupInputSystem()
88 std::ostringstream windowHndStr
;
91 mWindow
->getCustomAttribute("WINDOW", &windowHnd
);
92 windowHndStr
<< windowHnd
;
93 pl
.insert(std::make_pair(std::string("WINDOW"), windowHndStr
.str()));
94 if (!mWindow
->isFullScreen())
96 pl
.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
97 pl
.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
99 pl
.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
100 pl
.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
102 pl
.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
104 mInputManager
= OIS::InputManager::createInputSystem(pl
);
108 mKeyboard
= static_cast<OIS::Keyboard
*>(mInputManager
->createInputObject(OIS::OISKeyboard
, true));
109 mMouse
= static_cast<OIS::Mouse
*>(mInputManager
->createInputObject(OIS::OISMouse
, true));
111 catch (const OIS::Exception
&e
)
113 throw Exception(42, e
.eText
, "Application::setupInputSystem");
115 const OIS::MouseState
&ms
= mMouse
->getMouseState();
116 ms
.width
= mWindow
->getWidth();
117 ms
.height
= mWindow
->getHeight();
120 void View::setupCEGUI()
122 mRenderer
= new CEGUI::OgreCEGUIRenderer(mWindow
, Ogre::RENDER_QUEUE_OVERLAY
, false, 3000, mSceneMgr
);
123 mSystem
= new CEGUI::System(mRenderer
);
125 CEGUI::SchemeManager::getSingleton().loadScheme("TaharezLookSkin.scheme");
127 mSystem
->setDefaultMouseCursor("TaharezLook", "MouseArrow");
128 mSystem
->setDefaultFont("BlueHighway-12");
130 CEGUI::MouseCursor::getSingleton().setImage(CEGUI::System::getSingleton().getDefaultMouseCursor());
131 mSystem
->setMultiClickTimeout(std::numeric_limits
<double>::min());
132 CEGUI::MouseCursor::getSingleton().setVisible(false);
135 void View::createFrameListener()
137 mListener
= new ViewFrameListener(mKeyboard
, mMouse
, mWindow
, mCamera
, mSceneMgr
, this);
138 mRoot
->addFrameListener(mListener
);
141 WindowEventUtilities::addWindowEventListener(mWindow
, this);
144 void View::startRenderLoop()
146 mRoot
->startRendering();
149 //Unattach OIS before window shutdown (very important under Linux)
150 void View::windowClosed(RenderWindow
* rw
)
152 //Only close for window that created OIS (the main window in these demos)
157 mInputManager
->destroyInputObject( mMouse
);
158 mInputManager
->destroyInputObject( mKeyboard
);
159 OIS::InputManager::destroyInputSystem(mInputManager
);
161 mListener
->quit(CEGUI::EventArgs());
166 void View::createCamera()
168 mCamera
= mSceneMgr
->createCamera("PlayerCam");
170 mCamera
->setPosition(ViewConstants::WHITE_CAMERA_POSITION
* 10);
171 mCamera
->lookAt(Vector3::ZERO
);
172 mCamera
->setNearClipDistance(5);
175 void View::createViewports()
177 // Create one viewport, entire window
178 Viewport
* vp
= mWindow
->addViewport(mCamera
);
179 vp
->setBackgroundColour(ColourValue(0,0,0));
180 // Alter the camera aspect ratio to match the viewport
181 mCamera
->setAspectRatio(Real(vp
->getActualWidth()) / Real(vp
->getActualHeight()));
184 Entity
* View::loadEntity(const std::string
& entityName
, const std::string
& modelName
)
187 if (mSceneMgr
->hasEntity(entityName
))
189 ent
= mSceneMgr
->getEntity(entityName
);
193 ent
= mSceneMgr
->createEntity(entityName
, modelName
);
196 ent
->setQueryFlags(0);
198 AnimationStateSet
* animations
= ent
->getAllAnimationStates();
201 AnimationStateIterator it
= animations
->getAnimationStateIterator();
202 while (it
.hasMoreElements())
204 AnimationState
* animationState
= it
.getNext();
205 animationState
->setEnabled(true);
206 animationState
->setLoop(true);
207 animationState
->setTimePosition(0);
213 SceneNode
* View::createPiece(char type
, const std::string
& modelName
,
214 const Vector3
& location
, SceneNode
* parent
)
218 parent
= mSceneMgr
->getRootSceneNode();
221 std::ostringstream entityName
;
222 entityName
<< type
<< modelName
<< location
.x
<< location
.y
<< location
.z
<< parent
->getName() << GenericAnimation::nextName();
224 SceneNode
* node
= parent
->createChildSceneNode(entityName
.str(), location
);
227 if (mSceneMgr
->hasEntity(entityName
.str()))
229 ent
= mSceneMgr
->getEntity(entityName
.str());
233 ent
= mSceneMgr
->createEntity(entityName
.str(), modelName
+ ".mesh");
235 //ent->setCastShadows(true);
236 ent
->setQueryFlags(0);
237 node
->attachObject(ent
);
239 if (type
== 'P' || type
== 'R')
241 node
->attachObject(loadEntity(entityName
.str() + "l", modelName
+ "_left_leg.mesh"));
242 node
->attachObject(loadEntity(entityName
.str() + "r", modelName
+ "_right_leg.mesh"));
245 node
->attachObject(loadEntity(entityName
.str() + "a", modelName
+ "_right_arm.mesh"));
246 node
->attachObject(loadEntity(entityName
.str() + "wb", modelName
+ "_weapon_base.mesh"));
247 node
->attachObject(loadEntity(entityName
.str() + "w", modelName
+ "_weapon.mesh"));
251 // Make white models face the opposite direction.
252 if (modelName
.find("white") == 0)
254 node
->yaw(Degree(180));
256 node
->setInitialState();
260 CEGUI::Window
* View::createGUIComponent(const std::string
& text
, double x
, double y
,
261 double sizeX
, double sizeY
, const std::string
& type
, bool setText
, bool visible
)
263 CEGUI::WindowManager
* win
= CEGUI::WindowManager::getSingletonPtr();
264 CEGUI::Window
* sheet
= win
->getWindow("View/Sheet");
266 CEGUI::Window
* button
= win
->createWindow("TaharezLook/" + type
, "View/" + text
+ type
);
269 button
->setText(text
);
271 button
->setPosition(CEGUI::UVector2(CEGUI::UDim(x
, 0), CEGUI::UDim(y
, 0)));
272 button
->setSize(CEGUI::UVector2(CEGUI::UDim(sizeX
, 0), CEGUI::UDim(sizeY
, 0)));
274 sheet
->addChildWindow(button
);
275 button
->setVisible(visible
);
279 void View::createGUI()
281 CEGUI::WindowManager
* win
= CEGUI::WindowManager::getSingletonPtr();
282 CEGUI::Window
* sheet
= win
->createWindow("DefaultGUISheet", "View/Sheet");
283 mSystem
->setGUISheet(sheet
);
285 createGUIComponent("Animation speed", 0.0, 0.165, 0.19, 0.05, "StaticText", false, false)
286 ->setText("Animation speed: 1x");
288 CEGUI::Scrollbar
* animationSpeedSlider
= static_cast<CEGUI::Scrollbar
*>(
289 createGUIComponent("Animation speed", 0.0, 0.215, 0.19, 0.02, "HorizontalScrollbar", false, false));
290 animationSpeedSlider
->setDocumentSize(4);
291 animationSpeedSlider
->setScrollPosition(1);
292 animationSpeedSlider
->subscribeEvent(
293 CEGUI::Scrollbar::EventScrollPositionChanged
,
294 CEGUI::Event::Subscriber(&ViewFrameListener::handleAnimationSpeedChanged
, mListener
));
296 createGUIComponent("Undo", 0.875, 0.45, 0.12, 0.04)->subscribeEvent(CEGUI::PushButton::EventClicked
,
297 CEGUI::Event::Subscriber(&View::undo
, this));
299 createGUIComponent("Restart", 0.875, 0.505, 0.12, 0.04)->subscribeEvent(CEGUI::PushButton::EventClicked
,
300 CEGUI::Event::Subscriber(&View::restart
, this));
302 createGUIComponent("Quit", 0.875, 0.55, 0.12, 0.04)->subscribeEvent(CEGUI::PushButton::EventClicked
,
303 CEGUI::Event::Subscriber(&ViewFrameListener::quit
, mListener
));
305 createGUIComponent("FPS info", 0.875, 0.6, 0.12, 0.04, "Button", true,
306 false)->subscribeEvent(CEGUI::PushButton::EventClicked
,
307 CEGUI::Event::Subscriber(&ViewFrameListener::toggleDebugInfo
, mListener
));
309 createGUIComponent("Game log", 0.875, 0.005, 0.12, 0.05, "StaticText");
310 createGUIComponent("Log", 0.875, 0.05, 0.12, 0.4, "Listbox")
311 ->subscribeEvent(CEGUI::Listbox::EventSelectionChanged
,
312 CEGUI::Event::Subscriber(&View::visitSelectedLog
, this));
314 CEGUI::Window
* chooseButton
= createGUIComponent("Choose queen", 0.4, 0.30, 0.2, 0.1);
315 chooseButton
->subscribeEvent(CEGUI::PushButton::EventClicked
, CEGUI::Event::Subscriber(&View::chooseQueen
, this));
316 chooseButton
->setVisible(false);
318 chooseButton
= createGUIComponent("Choose rook", 0.4, 0.40, 0.2, 0.1);
319 chooseButton
->subscribeEvent(CEGUI::PushButton::EventClicked
, CEGUI::Event::Subscriber(&View::chooseRook
, this));
320 chooseButton
->setVisible(false);
322 chooseButton
= createGUIComponent("Choose knight", 0.4, 0.50, 0.2, 0.1);
323 chooseButton
->subscribeEvent(CEGUI::PushButton::EventClicked
, CEGUI::Event::Subscriber(&View::chooseKnight
, this));
324 chooseButton
->setVisible(false);
326 chooseButton
= createGUIComponent("Choose bishop", 0.4, 0.60, 0.2, 0.1);
327 chooseButton
->subscribeEvent(CEGUI::PushButton::EventClicked
, CEGUI::Event::Subscriber(&View::chooseBishop
, this));
328 chooseButton
->setVisible(false);
330 createGUIComponent("Move assistance level", 0.00, 0.09, 0.18, 0.05, "StaticText", true, false);
332 CEGUI::Spinner
* moveAssistanceSpinner
= static_cast<CEGUI::Spinner
*>(
333 createGUIComponent("Move assistance", 0.18, 0.09, 0.05, 0.05, "Spinner", false, false));
334 moveAssistanceSpinner
->setCurrentValue(3.0);
335 moveAssistanceSpinner
->setMinimumValue(0.0);
336 moveAssistanceSpinner
->setMaximumValue(3.0);
337 moveAssistanceSpinner
->subscribeEvent(
338 CEGUI::Spinner::EventValueChanged
,
339 CEGUI::Event::Subscriber(&BufferedInputHandler::handleMoveAssistanceChanged
,
340 mListener
->getHandler()));
342 CEGUI::Window
* unsafe
= createGUIComponent("Unsafe mode", 0.25, 0.045, 0.3, 0.04, "Checkbox", true, false);
343 unsafe
->setText("Allow concurrent animations (UNSAFE!)");
344 unsafe
->subscribeEvent(CEGUI::Checkbox::EventCheckStateChanged
,
345 CEGUI::Event::Subscriber(&BufferedInputHandler::handleSafeModeChanged
, mListener
->getHandler()));
347 createGUIComponent(ViewConstants::SHOW_ADDITIONAL
, 0.005, 0.005, 0.22, 0.05)->subscribeEvent(CEGUI::PushButton::EventClicked
,
348 CEGUI::Event::Subscriber(&ViewFrameListener::hideGUI
, mListener
));
350 // White dropdown menus
351 createGUIComponent("White:", 0.25, 0.0, 0.15, 0.04, "StaticText", true, true);
353 CEGUI::Combobox
* white
= static_cast<CEGUI::Combobox
*>(createGUIComponent(
354 "White", 0.25, 0.045, 0.15, 0.2, "Combobox", false, true));
355 white
->setReadOnly(true);
356 white
->setText("Human");
357 white
->subscribeEvent(CEGUI::Combobox::EventListSelectionAccepted
,
358 CEGUI::Event::Subscriber(&View::updateControllers
, this));
360 // White depth spinner
361 CEGUI::Spinner
* whiteDepthSpinner
= static_cast<CEGUI::Spinner
*>(
362 createGUIComponent("White depth", 0.4, 0.00, 0.05, 0.08, "Spinner", false, true));
363 whiteDepthSpinner
->setCurrentValue(4.0);
364 whiteDepthSpinner
->setMinimumValue(3.0);
365 whiteDepthSpinner
->setMaximumValue(6.0);
366 whiteDepthSpinner
->subscribeEvent(
367 CEGUI::Spinner::EventValueChanged
,
368 CEGUI::Event::Subscriber(&View::handleDepthChanged
, this));
371 createGUIComponent("<=>", 0.475, 0.02, 0.04, 0.05)->subscribeEvent(CEGUI::PushButton::EventClicked
,
372 CEGUI::Event::Subscriber(&View::swapPlayers
, this));
374 // Black dropdown menus
375 createGUIComponent("Black:", 0.54, 0.0, 0.15, 0.04, "StaticText", true, true);
377 CEGUI::Combobox
* black
= static_cast<CEGUI::Combobox
*>(createGUIComponent(
378 "Black", 0.54, 0.045, 0.15, 0.2, "Combobox", false, true));
379 black
->setReadOnly(true);
380 black
->setText("Human");
381 black
->subscribeEvent(CEGUI::Combobox::EventListSelectionAccepted
,
382 CEGUI::Event::Subscriber(&View::updateControllers
, this));
384 // Black depth spinner
385 CEGUI::Spinner
* blackDepthSpinner
= static_cast<CEGUI::Spinner
*>(
386 createGUIComponent("Black depth", 0.69, 0.00, 0.05, 0.08, "Spinner", false, true));
387 blackDepthSpinner
->setCurrentValue(4.0);
388 blackDepthSpinner
->setMinimumValue(3.0);
389 blackDepthSpinner
->setMaximumValue(6.0);
390 blackDepthSpinner
->subscribeEvent(
391 CEGUI::Spinner::EventValueChanged
,
392 CEGUI::Event::Subscriber(&View::handleDepthChanged
, this));
394 createGUIComponent("Connect", 0.0, 0.25, 0.1, 0.04, "Button", true, false)
395 ->subscribeEvent(CEGUI::PushButton::EventClicked
, CEGUI::Event::Subscriber(&View::connect
, this));
397 updateUsers(std::vector
<std::string
>());
401 void View::recreateLog()
403 CEGUI::WindowManager
& wmgr
= CEGUI::WindowManager::getSingleton();
404 CEGUI::Window
* logWindow
= wmgr
.getWindow("View/LogListbox");
405 CEGUI::Listbox
* logList
= static_cast<CEGUI::Listbox
*>(logWindow
);
406 logList
->resetList();
408 const std::vector
<std::string
>& gameLog
= mMiddleman
->getGameLog();
410 for (std::size_t i
= 0; i
< gameLog
.size(); i
++)
412 std::ostringstream text
;
413 text
<< (i
+ 1) << ". " << gameLog
.at(i
);
414 CEGUI::ListboxTextItem
* item
= new CEGUI::ListboxTextItem(text
.str());
415 logList
->addItem(item
);
417 logList
->ensureItemIsVisible(logList
->getItemCount() - 1);
420 void View::recreateDeadPieces()
422 // TODO: Check why this crashes on undo during an animation.
423 const Board
* board
= mMiddleman
->getGameStateAt(mMiddleman
->getGameLog().size());
424 const std::vector
<Piece
*> deadPieces
= board
->getDeadPieces();
425 SceneNode
* whiteDeads
= mSceneMgr
->getSceneNode("White dead pieces");
426 SceneNode
* blackDeads
= mSceneMgr
->getSceneNode("Black dead pieces");
427 blackDeads
->removeAndDestroyAllChildren();
428 whiteDeads
->removeAndDestroyAllChildren();
430 for (std::vector
<Piece
*>::const_iterator it
= deadPieces
.begin();
431 it
!= deadPieces
.end(); it
++)
433 char symbol
= (*it
)->getSymbol();
434 char upperCaseSymbol
= symbol
& (~(1 << 5));
435 SceneNode
* parent
= (*it
)->getColour() == BLACK
? blackDeads
: whiteDeads
;
437 int nChildren
= parent
->numChildren();
438 int xPosition
, yPosition
;
441 xPosition
= (nChildren
+ 1) % 3;
442 yPosition
= (nChildren
+ 1) / 3;
446 xPosition
= nChildren
% 2;
447 yPosition
= nChildren
/ 2;
449 createPiece(upperCaseSymbol
, getMeshName(symbol
),
450 convertPosition(xPosition
, yPosition
* 1.5), parent
)->pitch(Degree(-90));
454 void View::createScene()
458 mSceneMgr
->setAmbientLight(ViewConstants::AMBIENT_COLOUR
);
459 //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
461 light
= mSceneMgr
->createLight("Yellow");
462 light
->setType(Light::LT_POINT
);
463 light
->setPosition(Vector3(1500, -25000, 1500));
464 light
->setDiffuseColour(ViewConstants::YELLOW_COLOUR
);
465 light
->setSpecularColour(1.0, 1.0, 1.0);
467 light
= mSceneMgr
->createLight("Blue");
468 light
->setType(Light::LT_POINT
);
469 light
->setPosition(Vector3(-1500, 1500, -1500));
470 light
->setDiffuseColour(ViewConstants::BLUE_COLOUR
);
471 light
->setSpecularColour(1.0, 1.0, 1.0);
473 // Loading the sky material so it doesn't have to be loaded while
474 // playing the opening animation sequence.
475 mSceneMgr
->setSkyDome(true, "Sky");
476 mSceneMgr
->setSkyDome(false, "Sky");
478 mSceneMgr
->createParticleSystem("Selection", "Effects/Selection");
482 void View::createInitialExplosion()
484 SceneNode
* explosion
= mSceneMgr
->getRootSceneNode()->createChildSceneNode(
485 "Initial explosion", Vector3(0, 0, 0));
486 BleedingAnimation
* anim
= AnimationFactory::createBleedingAnimation(
487 explosion
, mSceneMgr
, 0, 1.8, "Effects/Explosion");
488 mListener
->getAnimationManager().addAnimation(anim
);
492 void View::createGround(bool visible
)
494 SceneNode
* ground
= mSceneMgr
->getRootSceneNode()->createChildSceneNode("ground", Vector3(0, -50, 0));
495 SceneNode
* water
= ground
->createChildSceneNode("water");
497 Entity
* ent
= mSceneMgr
->createEntity("ground", "ground.mesh");
498 ent
->setQueryFlags(0);
499 ground
->attachObject(ent
);
501 ent
= mSceneMgr
->createEntity("water", "water.mesh");
502 ent
->setQueryFlags(0);
503 water
->attachObject(ent
);
505 ground
->setVisible(visible
);
508 void View::createBoard(const Board
* board
)
510 mBoardWidth
= board
->getWidth();
511 mBoardHeight
= board
->getHeight();
513 using ViewConstants::SQUARE_SIDE_LENGTH
;
515 for (int i
= 0; i
< 8; i
++)
517 for (int j
= 0; j
< 8; j
++)
519 char symbol
= board
->getSymbolAt(i
, j
);
522 char upperCaseSymbol
= symbol
& (~(1 << 5));
523 createPiece(upperCaseSymbol
, getMeshName(symbol
), convertPosition(i
, j
));
528 for (int j
= 0; j
< int(mBoardHeight
); j
++)
530 for (int i
= 0; i
< int(mBoardWidth
); i
++)
532 std::ostringstream name
;
533 name
<< i
<< " " << j
;
534 Entity
* ent
= mSceneMgr
->createEntity(name
.str(), "square.mesh");
536 Vector3 position
= convertPosition(i
, j
);
537 SceneNode
* node
= mSceneMgr
->getRootSceneNode()->createChildSceneNode(
538 name
.str(), position
);
539 node
->attachObject(ent
);
541 if ((i
+ j
) % 2 == 1)
543 ent
->setMaterialName("board/square/black");
547 ent
->setMaterialName("board/square/white");
549 ent
->setQueryFlags(1 << 0);
551 // Create transparent squares on top of normal squares.
552 // These squares indicate possible movement locations.
554 ent
= mSceneMgr
->createEntity(name
.str(), "square.mesh");
555 ent
->setMaterialName("board/square/move");
556 ent
->setQueryFlags(0);
557 SceneNode
* indicatorNode
= node
->createChildSceneNode(Vector3(0, 1, 0));
558 indicatorNode
->attachObject(ent
);
559 indicatorNode
->scale(1.01, 1.0, 1.01);
560 ent
->setVisible(false);
563 SceneNode
* invalidMoveNode
= mSceneMgr
->getRootSceneNode()->createChildSceneNode("InvalidMove");
564 Entity
* ent
= mSceneMgr
->createEntity("InvalidMove", "invalid_move.mesh");
565 ent
->setQueryFlags(0);
566 invalidMoveNode
->attachObject(ent
);
567 invalidMoveNode
->setVisible(false);
569 SceneNode
* selectionNode
= mSceneMgr
->getRootSceneNode()->createChildSceneNode("Selection");
570 selectionNode
->attachObject(mSceneMgr
->getParticleSystem("Selection"));
571 selectionNode
->setVisible(false);
573 mSceneMgr
->getRootSceneNode()->createChildSceneNode("Black dead pieces",
574 Vector3(ViewConstants::SQUARE_SIDE_LENGTH
* 9, -40,
575 ViewConstants::SQUARE_SIDE_LENGTH
* 0.5));
576 mSceneMgr
->getRootSceneNode()->createChildSceneNode("White dead pieces",
577 Vector3(-ViewConstants::SQUARE_SIDE_LENGTH
* 9, -40,
578 ViewConstants::SQUARE_SIDE_LENGTH
* 0.5))->yaw(Degree(180));
580 showSelectablePiecesIfInControl();
581 mListener
->clearSelectedObject();
584 std::string
View::getMeshName(char symbol
) const
588 case 'P': return "black_pawn";
589 case 'R': return "black_rook";
590 case 'N': return "black_knight";
591 case 'B': return "black_bishop";
592 case 'Q': return "black_queen";
593 case 'K': return "black_king";
595 case 'p': return "white_pawn";
596 case 'r': return "white_rook";
597 case 'n': return "white_knight";
598 case 'b': return "white_bishop";
599 case 'q': return "white_queen";
600 case 'k': return "white_king";
602 std::ostringstream errorMessage
;
603 errorMessage
<< "getMeshName(): Unknown symbol: " << symbol
;
604 errorMessage
<< " (" << int(symbol
) << ")";
605 throw std::runtime_error(errorMessage
.str());
609 void View::convertPosition(const Vector3
& position
, int* x
, int* y
) const
611 int sideLength
= ViewConstants::SQUARE_SIDE_LENGTH
;
612 int offsetX
= (getBoardWidth() - 1) * sideLength
/ 2;
613 int offsetY
= (getBoardHeight() - 1) * sideLength
/ 2;
614 // +0.5 for rounding.
615 *x
= (position
.x
+ offsetX
+ 0.5) / sideLength
;
616 *y
= (position
.z
+ offsetY
+ 0.5) / sideLength
;
619 Vector3
View::convertPosition(double x
, double y
) const
621 int sideLength
= ViewConstants::SQUARE_SIDE_LENGTH
;
622 int offsetX
= (getBoardWidth() - 1) * sideLength
/ 2;
623 int offsetY
= (getBoardHeight() - 1) * sideLength
/ 2;
625 return Vector3(x
* sideLength
- offsetX
, 0, y
* sideLength
- offsetY
);
628 bool View::undo(const CEGUI::EventArgs
& e
)
632 mMiddleman
->undo(mMiddleman
->getGameLog().size() - mRound
);
642 bool View::restart(const CEGUI::EventArgs
& e
)
645 mMiddleman
->undo(mRound
);
649 bool View::visitSelectedLog(const CEGUI::EventArgs
& e
)
651 CEGUI::WindowManager
& wmgr
= CEGUI::WindowManager::getSingleton();
652 CEGUI::Window
* logWindow
= wmgr
.getWindow("View/LogListbox");
653 CEGUI::Listbox
* logList
= static_cast<CEGUI::Listbox
*>(logWindow
);
655 CEGUI::ListboxItem
* selected
= logList
->getFirstSelectedItem();
659 std::size_t selectedIndex
= logList
->getItemIndex(selected
);
660 if (selectedIndex
+ 1 != mMiddleman
->getGameLog().size())
662 setBoard(mMiddleman
->getGameStateAt(selectedIndex
+ 1), selectedIndex
+ 1);
664 mSceneMgr
->setAmbientLight(ColourValue(0.43, 0.25, 0.07));
665 mSceneMgr
->getLight("Yellow")->setDiffuseColour(0.86, 0.5, 0.14);
666 mSceneMgr
->getLight("Blue")->setDiffuseColour(0.86, 0.5, 0.14);
668 wmgr
.getWindow("View/UndoButton")->setText("Undo future");
675 CEGUI::ListboxItem
* newSelected
= logList
->getListboxItemFromIndex(selectedIndex
);
676 if (*newSelected
->getText().rbegin() != '<')
678 newSelected
->setText(newSelected
->getText() + " <");
684 void View::setPromotionMove(int fromX
, int fromY
, int toX
, int toY
)
686 // TODO: change to actual move class.
687 promotionMove
.clear();
688 promotionMove
.push_back(fromX
);
689 promotionMove
.push_back(fromY
);
690 promotionMove
.push_back(toX
);
691 promotionMove
.push_back(toY
);
694 bool View::chooseQueen(const CEGUI::EventArgs
& e
)
696 sendPromotionMove(ChessBoard::PROMOTE_TO_QUEEN
);
700 bool View::chooseRook(const CEGUI::EventArgs
& e
)
702 sendPromotionMove(ChessBoard::PROMOTE_TO_ROOK
);
706 bool View::chooseKnight(const CEGUI::EventArgs
& e
)
708 sendPromotionMove(ChessBoard::PROMOTE_TO_KNIGHT
);
712 bool View::chooseBishop(const CEGUI::EventArgs
& e
)
714 sendPromotionMove(ChessBoard::PROMOTE_TO_BISHOP
);
718 void View::sendPromotionMove(unsigned int promoteTo
)
720 mMiddleman
->move(promotionMove
.at(0), promotionMove
.at(1),
721 promotionMove
.at(2), promotionMove
.at(3),
724 setChooseButtonsVisibility(false);
727 void View::setChooseButtonsVisibility(bool visible
)
729 CEGUI::WindowManager
& wmgr
= CEGUI::WindowManager::getSingleton();
730 wmgr
.getWindow("View/Choose queenButton")->setVisible(visible
);
731 wmgr
.getWindow("View/Choose rookButton")->setVisible(visible
);
732 wmgr
.getWindow("View/Choose knightButton")->setVisible(visible
);
733 wmgr
.getWindow("View/Choose bishopButton")->setVisible(visible
);
736 void View::ensureLatestState()
741 CEGUI::WindowManager
& wmgr
= CEGUI::WindowManager::getSingleton();
742 wmgr
.getWindow("View/UndoButton")->setText("Undo");
744 std::size_t latestRound
= mMiddleman
->getGameLog().size();
745 setBoard(mMiddleman
->getGameStateAt(latestRound
), latestRound
);
747 mSceneMgr
->setAmbientLight(ViewConstants::AMBIENT_COLOUR
);
748 mSceneMgr
->getLight("Yellow")->setDiffuseColour(ViewConstants::YELLOW_COLOUR
);
749 mSceneMgr
->getLight("Blue")->setDiffuseColour(ViewConstants::BLUE_COLOUR
);
759 createRenderWindow();
760 initializeResourceGroups();
764 createFrameListener();
767 createBoard(mMiddleman
->getGameStateAt(0));
769 createInitialExplosion();
771 } catch( Exception
& e
) {
772 fprintf(stderr
, "An exception has occurred: %s\n", e
.what());
777 bool View::updateControllers(const CEGUI::EventArgs
& e
)
779 CEGUI::WindowManager
& wmgr
= CEGUI::WindowManager::getSingleton();
780 CEGUI::Combobox
* white
= static_cast<CEGUI::Combobox
*>(wmgr
.getWindow("View/WhiteCombobox"));
781 CEGUI::Combobox
* black
= static_cast<CEGUI::Combobox
*>(wmgr
.getWindow("View/BlackCombobox"));
783 std::size_t whiteIndex
= white
->getItemIndex(white
->findItemWithText(white
->getText(), 0));
784 std::size_t blackIndex
= black
->getItemIndex(black
->findItemWithText(black
->getText(), 0));
786 mMiddleman
->setControl(whiteIndex
, blackIndex
);
788 if (whiteIndex
> mMiddleman
->getAICount())
790 mMiddleman
->sendChallenge(white
->getText().c_str());
793 if (blackIndex
> mMiddleman
->getAICount())
795 mMiddleman
->sendChallenge(black
->getText().c_str());
801 bool View::swapPlayers(const CEGUI::EventArgs
& e
)
803 CEGUI::WindowManager
& wmgr
= CEGUI::WindowManager::getSingleton();
804 CEGUI::Window
* white
= wmgr
.getWindow("View/WhiteCombobox");
805 CEGUI::Window
* black
= wmgr
.getWindow("View/BlackCombobox");
807 const CEGUI::String whitePlayer
= white
->getText();
808 white
->setText(black
->getText());
809 black
->setText(whitePlayer
);
811 return updateControllers(e
);
814 void View::promptChallenge(const std::string
& challengerName
)
816 mMiddleman
->respondToChallenge(true);
820 void View::updateUsers(const std::vector
<std::string
>& users
)
822 CEGUI::WindowManager
& wmgr
= CEGUI::WindowManager::getSingleton();
823 CEGUI::Combobox
* white
= static_cast<CEGUI::Combobox
*>(wmgr
.getWindow("View/WhiteCombobox"));
824 CEGUI::Combobox
* black
= static_cast<CEGUI::Combobox
*>(wmgr
.getWindow("View/BlackCombobox"));
828 white
->addItem(new CEGUI::ListboxTextItem("Human"));
829 black
->addItem(new CEGUI::ListboxTextItem("Human"));
831 for (std::size_t i
= 0; i
< mMiddleman
->getAICount(); i
++)
833 std::string name
= mMiddleman
->getAIInfoAt(i
).getName();
834 white
->addItem(new CEGUI::ListboxTextItem(name
));
835 black
->addItem(new CEGUI::ListboxTextItem(name
));
838 for (std::size_t i
= 0; i
< users
.size(); i
++)
840 const std::string
& user
= users
.at(i
);
841 white
->addItem(new CEGUI::ListboxTextItem(user
));
842 black
->addItem(new CEGUI::ListboxTextItem(user
));
846 bool View::connect(const CEGUI::EventArgs
& e
)
848 mMiddleman
->connect();
853 bool View::handleDepthChanged(const CEGUI::EventArgs
& e
)
855 CEGUI::WindowManager
& wmgr
= CEGUI::WindowManager::getSingleton();
856 CEGUI::Spinner
* white
= static_cast<CEGUI::Spinner
*>(wmgr
.getWindow("View/White depthSpinner"));
857 CEGUI::Spinner
* black
= static_cast<CEGUI::Spinner
*>(wmgr
.getWindow("View/Black depthSpinner"));
859 mMiddleman
->setAICutoffDepth(white
->getCurrentValue() + 0.5f
, black
->getCurrentValue() + 0.5f
);