Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/gui/src/story_entities/simple_game_menu.cc @ 8009

Last change on this file since 8009 was 8009, checked in by bensch, 18 years ago

orxonox/gui: image is loaded and displayed

File size: 18.7 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: Patrick Boenzli
13
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
17
18
19#include "simple_game_menu.h"
20
21#include "event_handler.h"
22
23#include "state.h"
24#include "class_list.h"
25
26#include "util/loading/load_param.h"
27#include "fast_factory.h"
28#include "util/loading/factory.h"
29
30#include "world_entity.h"
31#include "elements/image_entity.h"
32#include "terrain.h"
33#include "camera.h"
34
35#include "graphics_engine.h"
36#include "object_manager.h"
37#include "sound_engine.h"
38#include "sound_source.h"
39
40#include "cd_engine.h"
41
42#include "glgui.h"
43
44//! This creates a Factory to fabricate a SimpleGameMenu
45CREATE_FACTORY(SimpleGameMenu, CL_SIMPLE_GAME_MENU);
46
47
48
49SimpleGameMenu::SimpleGameMenu(const TiXmlElement* root)
50    : GameWorld()
51{
52  this->setClassID(CL_SIMPLE_GAME_MENU, "SimpleGameMenu");
53  this->setName("SimpleGameMenu uninitialized");
54
55  this->dataTank = new SimpleGameMenuData();
56
57  this->cameraVector = Vector(50.0, 0.0, 0.0);
58  this->menuLayers.push_back(MenuLayer());
59  this->menuLayers.push_back(MenuLayer());
60
61  this->layerIndex = 0;
62  this->menuSelectedIndex = 0;
63  this->selectorSource = NULL;
64
65
66  /// GUI
67  ///(this is as modular as it is possible).
68  OrxGui::GLGuiPushButton* pb = new OrxGui::GLGuiPushButton("PUSH ME");
69  //pb->connectSignal(OrxGui::Signal_release, this, createExecutor<SimpleGameMenu>(&SimpleGameMenu::enterGui));
70  pb->connect(SIGNAL(pb, released), this, SLOT(SimpleGameMenu, enterGui));
71  pb->show();
72  pb->setAbsCoor2D(50, 50);
73
74  OrxGui::GLGuiHandler::getInstance()->activateCursor();
75  OrxGui::GLGuiHandler::getInstance()->activate();
76  /////
77
78  if (root != NULL)
79    this->loadParams(root);
80
81  State::setMenuID(this->getNextStoryID());
82}
83
84/// HACK only for testing.
85void SimpleGameMenu::enterGui()
86{
87
88  OrxGui::GLGuiBox* box = new OrxGui::GLGuiBox();
89  {
90    ///
91    OrxGui::GLGuiButton* dnpb = new OrxGui::GLGuiCheckButton("Push the button");
92
93    box->pack(dnpb);
94
95    OrxGui::GLGuiPushButton* rdnpb = new OrxGui::GLGuiPushButton("Quit ORXONOX!!");
96    rdnpb->connect(SIGNAL(rdnpb, released), this, SLOT(SimpleGameMenu, quitMenu));
97
98    box->pack(rdnpb);
99
100    OrxGui::GLGuiInputLine* input = new OrxGui::GLGuiInputLine();
101    input->setText("input some text here");
102    input->connect(SIGNAL(input, textChanged), this, SLOT(SimpleGameMenu, TEST));
103    box->pack(input);
104
105    OrxGui::GLGuiSlider* slider = new OrxGui::GLGuiSlider();
106    slider->connect(SIGNAL(slider, valueChanged), this, SLOT(SimpleGameMenu, TEST));
107    slider->connect(SIGNAL(slider, valueChanged), box, SLOT(OrxGui::GLGuiWidget, setBackgroundColor));
108    slider->setRange(0, 1);
109    slider->setValue(slider->min());
110    box->pack(slider);
111  }
112  box->setAbsCoor2D(50, 200);
113
114  box->showAll();
115
116  OrxGui::GLGuiImage* image = new OrxGui::GLGuiImage();
117  image->show();
118  image->loadImageFromFile( "death_screen.png" );
119  image->setWidgetSize(200, 200);
120  image->setAbsCoor2D(300, 300);
121
122  OrxGui::GLGuiSlider* slider = new OrxGui::GLGuiSlider();
123  slider->connect(SIGNAL(slider, valueChanged), box, SLOT(Element2D, setRelCoorX2D));
124  slider->setRange(100, 500);
125  slider->setStep(50);
126  slider->setValue(slider->min());
127  slider->show();
128  slider->setAbsCoor2D(100, 00);
129
130  /////
131}
132
133
134#include "threading.h"
135void SimpleGameMenu::execURL() const
136{
137  std::string URL = "http://www.orxonox.net";
138  SDL_CreateThread(startURL, (void*)&URL);
139}
140
141#ifdef __OSX__
142#include <ApplicationServices/ApplicationServices.h>
143#elif defined __WIN32__
144#include <shellapi.h>
145#endif
146
147int SimpleGameMenu::startURL(void* url)
148{
149  std::string URL = *(std::string*)url;
150#ifdef __linux__
151  system ((std::string("firefox ") + URL).c_str());
152#elif defined __OSX__
153  CFURLRef url_handle = CFURLCreateWithBytes (NULL, (UInt8 *)URL.c_str(), URL.size(),
154                        kCFStringEncodingASCII, NULL);
155  LSOpenCFURLRef (url_handle, NULL);
156  CFRelease (url_handle);
157#elif defined __WIN32__
158  ShellExecute(GetActiveWindow(),
159               "open", URL.c_str(), NULL, NULL, SW_SHOWNORMAL);
160}
161#endif
162  PRINTF(3)("loaded external webpage %s\n", URL.c_str());
163}
164
165/**
166*  @brief remove the SimpleGameMenu from memory
167*
168*  delete everything explicitly, that isn't contained in the parenting tree!
169*  things contained in the tree are deleted automaticaly
170*/
171SimpleGameMenu::~SimpleGameMenu ()
172{
173  PRINTF(3)("SimpleGameMenu::~SimpleGameMenu() - deleting current world\n");
174
175  if( this->dataTank)
176    delete this->dataTank;
177  delete OrxGui::GLGuiHandler::getInstance( );
178}
179
180
181/**
182* @brief loads the parameters of a SimpleGameMenu from an XML-element
183* @param root the XML-element to load from
184*/
185void SimpleGameMenu::loadParams(const TiXmlElement* root)
186{
187  /* skip the GameWorld, since it does not define any useful loadParams for this class */
188  //static_cast<GameWorld*>(this)->loadParams(root);
189  GameWorld::loadParams(root);
190
191  PRINTF(4)("Loaded SimpleGameMenu specific stuff\n");
192}
193
194
195/**
196* @brief this is executed just before load
197*
198* since the load function sometimes needs data, that has been initialized
199* before the load and after the proceeding storyentity has finished
200*/
201ErrorMessage SimpleGameMenu::init()
202{
203  /* call underlying init funciton */
204  GameWorld::init();
205
206  this->subscribeEvent(ES_MENU, SDLK_UP);
207  this->subscribeEvent(ES_MENU, SDLK_DOWN);
208  this->subscribeEvent(ES_MENU, SDLK_RETURN);
209  this->subscribeEvent(ES_MENU, SDLK_SPACE);
210  this->subscribeEvent(ES_MENU, SDLK_ESCAPE);
211
212  this->dataTank->localCamera->setRelCoor(this->cameraVector);
213
214  GraphicsEngine::getInstance()->displayFPS(false);
215
216  this->layerIndex = 0;
217  this->menuSelectedIndex = 0;
218}
219
220
221/**
222* @brief load the data
223*/
224ErrorMessage SimpleGameMenu::loadData()
225{
226  GameWorld::loadData();
227
228  if (this->dataXML != NULL)
229  {
230    LoadParam(dataXML, "selector-sound", this, SimpleGameMenu, setSelectorSound);
231
232    TiXmlElement* element = this->dataXML->FirstChildElement("Elements");
233
234
235    if( element == NULL)
236    {
237      PRINTF(1)("SimpleGameMenu is missing 'Elements'\n");
238    }
239    else
240    {
241      element = element->FirstChildElement();
242      // load Players/Objects/Whatever
243      PRINTF(4)("Loading Elements\n");
244      while( element != NULL)
245      {
246        BaseObject* created = Factory::fabricate(element);
247        if( created != NULL )
248        {
249          PRINTF(4)("Created a %s::%s\n", created->getClassName(), created->getName());
250          if (!created->isA(CL_ELEMENT_2D))
251            PRINTF(2)("Error the Created Entity is not an Element2D but an %s::%s\n", created->getClassName(), created->getName());
252        }
253        element = element->NextSiblingElement();
254      }
255      PRINTF(4)("Done loading Elements\n");
256    }
257  }
258
259  /* get the menu list */
260  const std::list<BaseObject*>* imageEntityList = ClassList::getList(CL_IMAGE_ENTITY);
261  std::list<BaseObject*>::const_iterator entity;
262  for (entity = imageEntityList->begin(); entity != imageEntityList->end(); entity++)
263  {
264
265    if( !strcmp("Selector_Menu", (*entity)->getName()))
266    {
267      this->menuSelector = dynamic_cast<ImageEntity*>(*entity);
268      this->menuSelector->setBindNode((const PNode*)NULL);
269    }
270  }
271
272  imageEntityList = ClassList::getList(CL_TEXT_ELEMENT);
273  for (entity = imageEntityList->begin(); entity != imageEntityList->end(); entity++)
274  {
275    if( !strcmp( "StartGame_Menu", (*entity)->getName()))
276    {
277      this->menuStartGame = dynamic_cast<TextElement*>(*entity);
278      this->menuStartGame->setBindNode((const PNode*)NULL);
279      this->menuStartGame->setRelCoor2D(State::getResX() / 2.0f,
280                                        State::getResY() / 2.0f - 60.0f);
281      this->menuLayers[0].menuList.push_back(dynamic_cast<TextElement*>(*entity));
282
283    }
284    else if( !strcmp( "Multiplayer_Menu", (*entity)->getName()))
285    {
286      this->menuStartMultiplayerGame = dynamic_cast<TextElement*>(*entity);
287      this->menuStartMultiplayerGame->setBindNode((const PNode*)NULL);
288      this->menuStartMultiplayerGame->setRelCoor2D(State::getResX() / 2.0f,
289          State::getResY() / 2.0f + ((this->menuLayers[0].menuList.size() -1 ) * 60.0f));
290      this->menuLayers[0].menuList.push_back(dynamic_cast<TextElement*>(*entity));
291    }
292    else if( !strcmp( "Quit_Menu", (*entity)->getName()))
293    {
294      this->menuQuitGame = dynamic_cast<TextElement*>(*entity);
295      this->menuQuitGame->setBindNode((const PNode*)NULL);
296      this->menuQuitGame->setRelCoor2D(State::getResX() / 2.0f,
297                                       State::getResY() / 2.0f + ((this->menuLayers[0].menuList.size() -1 )* 60.0f));
298      this->menuLayers[0].menuList.push_back(dynamic_cast<TextElement*>(*entity));
299    }
300  }
301  this->menuSelected->getNullElement()->update2D(0.1f);
302  this->menuSelectedIndex = 0;
303  this->menuSelected = this->menuLayers[0].menuList[this->menuSelectedIndex];
304  this->sliderTo(this->menuSelected, 0.0f);
305
306
307  // loading the storyentities submenu (singleplayer)
308  const std::list<BaseObject*>* storyEntities = ClassList::getList(CL_STORY_ENTITY);
309  std::list<BaseObject*>::const_iterator it;
310  for( it = storyEntities->begin(); it != storyEntities->end(); it++)
311  {
312    StoryEntity* se = dynamic_cast<StoryEntity*>(*it);
313    if( se->isContainedInMenu())
314    {
315      this->menuLayers[1].storyList.push_back(se);
316
317      // generating menu item
318      TextElement* te = new TextElement();
319      te->setVisibility(false);
320      te->setText(se->getName());
321      te->setRelCoor2D(State::getResX() / 2.0f - 200.0f, State::getResY() / 2.0f + ((this->menuLayers[1].menuList.size() - 2.0f) * 60.0f));
322      this->menuLayers[1].menuList.push_back(te);
323
324      // generating screenshoot item
325      ImageEntity* ie = new ImageEntity();
326      ie->setVisibility(false);
327      ie->setBindNode((const PNode*)NULL);
328      ie->setTexture(se->getMenuScreenshoot());
329      ie->setRelCoor2D(State::getResX() / 2.0f + 250.0f, State::getResY() / 2.0f);
330      ie->setSize2D(140.0f, 105.0f);
331      this->menuLayers[1].screenshootList.push_back(ie);
332    }
333  }
334}
335
336/**
337* @brief set the Sound to play when switching menu entry.
338* @param selectorSound the sound to load.
339*/
340void SimpleGameMenu::setSelectorSound(const std::string& selectorSound)
341{
342  this->selectorSource = OrxSound::SoundEngine::getInstance()->createSource(selectorSound, NULL);
343}
344
345ErrorMessage SimpleGameMenu::unloadData()
346{
347  this->unsubscribeEvents(ES_MENU);
348
349  std::vector<MenuLayer>::iterator mit;
350  for(mit = this->menuLayers.begin(); mit != this->menuLayers.end(); mit++)
351  {
352    while(!(*mit).menuList.empty())
353    {
354      delete (*mit).menuList.back();
355      (*mit).menuList.pop_back();
356    }
357
358    (*mit).menuList.clear();
359    (*mit).storyList.clear();
360    (*mit).screenshootList.clear();
361  }
362
363  // delete the SoundSource.
364  if (this->selectorSource != NULL)
365    delete this->selectorSource;
366  this->selectorSource = NULL;
367
368  GameWorld::unloadData();
369}
370
371
372/**
373* @brief start the menu
374*/
375bool SimpleGameMenu::start()
376{
377  EventHandler::getInstance()->pushState(ES_MENU);
378
379  /* now call the underlying*/
380  GameWorld::start();
381}
382
383
384
385/**
386* stop the menu
387*/
388bool SimpleGameMenu::stop()
389{
390  EventHandler::getInstance()->popState();
391
392  /* now call the underlying*/
393  GameWorld::stop();
394}
395
396
397/**
398*  override the standard tick for more functionality
399*/
400void SimpleGameMenu::tick()
401{
402  GameWorld::tick();
403
404  // Make the GLGui tick.
405  OrxGui::GLGuiHandler::getInstance()->tick(this->dtS);
406
407  this->animateScene(this->dtS);
408}
409
410
411/**
412* @brief no collision detection in the menu
413*/
414void SimpleGameMenu::collide()
415{
416  //   this->dataTank->localCamera->
417}
418
419
420/**
421* @brief animate the scene
422*/
423void SimpleGameMenu::animateScene(float dt)
424{
425  Quaternion q(/*0.00005*/ dt * .1, Vector(0.0, 1.0, 0.0));
426  this->cameraVector = q.apply(this->cameraVector);
427  this->dataTank->localCamera->setRelCoor(this->cameraVector);
428  this->dataTank->localCamera->getTarget()->setRelCoorSoft(0,0,0);
429}
430
431void SimpleGameMenu::quitMenu()
432{
433  this->setNextStoryID(WORLD_ID_GAMEEND);
434  this->stop();
435}
436
437
438/**
439* @brief event dispatcher funciton
440* @param event the incoming event
441*/
442void SimpleGameMenu::process(const Event &event)
443{
444  /* ----------------- LAYER 1 ---------------*/
445  if( this->layerIndex == 0)
446  {
447    if( event.type == SDLK_RETURN && event.bPressed == true)
448    {
449      if( this->menuSelected == this->menuQuitGame)
450      {
451        this->setNextStoryID(WORLD_ID_GAMEEND);
452        this->stop();
453      }
454      if( this->menuSelected == this->menuStartGame)
455      {
456        // switch to first submenu
457        if( this->menuLayers[1].menuList.size() == 0)
458        {
459          PRINTF(1)("Haven't got any StoryEntities to play!\n");
460          return;
461        }
462
463        this->switchMenuLayer(this->layerIndex, 1);
464      }
465    }
466    if( event.type == SDLK_ESCAPE && event.bPressed == true)
467    {
468      this->setNextStoryID(WORLD_ID_GAMEEND);
469      this->stop();
470    }
471  }  /* ----------------- LAYER 2 ---------------*/
472  else if( this->layerIndex == 1)
473  {
474    if( event.type == SDLK_RETURN && event.bPressed == true)
475    {
476      this->setNextStoryID( this->menuLayers[1].storyList[this->menuSelectedIndex]->getStoryID());
477      this->stop();
478    }
479    if( event.type == SDLK_ESCAPE && event.bPressed == true)
480    {
481      this->switchMenuLayer(this->layerIndex, 0);
482    }
483  }
484
485
486
487  // The menu selction cursor
488  if( event.type == SDLK_DOWN && event.bPressed == true)
489  {
490    if(this->menuSelectedIndex < (this->menuLayers[this->layerIndex].menuList.size() - 1))
491    {
492      this->menuSelected = this->menuLayers[this->layerIndex].menuList[++this->menuSelectedIndex];
493      this->sliderTo(this->menuSelected, 5.0f);
494      if (this->selectorSource != NULL)
495        this->selectorSource->play();
496
497      if( this->layerIndex == 1)
498      {
499        this->menuLayers[1].screenshootList[this->menuSelectedIndex]->setVisibility(true);
500        this->menuLayers[1].screenshootList[this->menuSelectedIndex-1]->setVisibility(false);
501      }
502    }
503  }
504  else if( event.type == SDLK_UP && event.bPressed == true)
505  {
506    if(this->menuSelectedIndex > 0)
507    {
508      this->menuSelected = this->menuLayers[this->layerIndex].menuList[--this->menuSelectedIndex];
509      this->sliderTo(this->menuSelected, 5.0f);
510      if (this->selectorSource != NULL)
511        this->selectorSource->play();
512
513      if( this->layerIndex == 1)
514      {
515        this->menuLayers[1].screenshootList[this->menuSelectedIndex]->setVisibility(true);
516        this->menuLayers[1].screenshootList[this->menuSelectedIndex+1]->setVisibility(false);
517      }
518    }
519  }
520}
521
522
523/**
524* @brief switches to from one meny layer to an other
525* @param layer1 from layer
526* @param layer2 to layer
527*/
528void SimpleGameMenu::switchMenuLayer(int layer1, int layer2)
529{
530  // wrong sizes
531  if(layer1 >= this->menuLayers.size() || layer2 >= this->menuLayers.size())
532    return;
533
534
535  PRINTF(0)("Removing layer %i\n", layer1);
536  std::vector<TextElement*>::iterator te;
537  // fade old menu
538  for( te = this->menuLayers[layer1].menuList.begin(); te != this->menuLayers[layer1].menuList.end(); te++)
539  {
540    (*te)->setVisibility(false);
541  }
542
543  std::vector<ImageEntity*>::iterator it;
544
545  //also fade the screenshots if in level choosement mode
546  for( it = this->menuLayers[layer1].screenshootList.begin(); it != this->menuLayers[layer1].screenshootList.end(); it++)
547  {
548    (*it)->setVisibility(false);
549  }
550
551
552  PRINTF(0)("Showing layer %i\n", layer1);
553  // beam here the new menu
554  for( te = this->menuLayers[layer2].menuList.begin(); te != this->menuLayers[layer2].menuList.end(); te++ )
555  {
556    (*te)->setVisibility(true);
557  }
558
559
560  this->layerIndex = layer2;
561  this->menuSelected = this->menuLayers[layer2].menuList[0];
562  this->menuSelector->setAbsCoor2D(this->menuSelected->getAbsCoor2D() + Vector2D(0, this->menuSelected->getSizeY2D() *.5));
563  this->menuSelector->setSize2D(this->menuSelected->getSizeX2D()*.7, this->menuSelected->getSizeY2D());
564  this->menuSelectedIndex = 0;
565
566  if( layer2 == 1)
567    this->menuLayers[layer2].screenshootList[0]->setVisibility(true);
568}
569
570void SimpleGameMenu::sliderTo(const Element2D* element, float bias)
571{
572  if (bias > 0.0)
573  {
574    this->menuSelector->setAbsCoorSoft2D(element->getAbsCoor2D() + Vector2D(0, element->getSizeY2D() *.5), bias);
575    this->menuSelector->setSizeSoft2D(element->getSizeX2D()*.7, element->getSizeY2D(), bias);
576  }
577  else
578  {
579    this->menuSelector->setAbsCoor2D(element->getAbsCoor2D() + Vector2D(0, element->getSizeY2D() *.5));
580    this->menuSelector->setSize2D(element->getSizeX2D()*.7, element->getSizeY2D());
581  }
582}
583
584
585
586/**********************************************************************************************
587SimpleGameMenuData
588**********************************************************************************************/
589
590
591/**
592* SimpleGameMenuData constructor
593*/
594SimpleGameMenuData::SimpleGameMenuData()
595{}
596
597/**
598* SimpleGameMenuData decontructor
599*/
600SimpleGameMenuData::~SimpleGameMenuData()
601{}
602
603
604/**
605*  initialize the GameWorldDataData
606*/
607ErrorMessage SimpleGameMenuData::init()
608{
609  /* call underlying function */
610  GameWorldData::init();
611}
612
613
614/**
615*  loads the GUI data
616* @param root reference to the xml root element
617*/
618ErrorMessage SimpleGameMenuData::loadGUI(const TiXmlElement* root)
619{
620  /* call underlying function */
621  GameWorldData::loadGUI(root);
622}
623
624
625/**
626*  unloads the GUI data
627*/
628ErrorMessage SimpleGameMenuData::unloadGUI()
629{
630  /* call underlying function */
631  GameWorldData::unloadGUI();
632}
633
634
635/**
636*  overloads the GameWorld::loadWorldEntities(...) class since the menu WorldEntity loading is different (less loading stuff)
637* @param root reference to the xml root parameter
638*/
639ErrorMessage SimpleGameMenuData::loadWorldEntities(const TiXmlElement* root)
640{
641  GameWorldData::loadWorldEntities(root);
642  /*
643  const TiXmlElement* element = root->FirstChildElement("WorldEntities");
644
645  if( element != NULL)
646  {
647  element = element->FirstChildElement();
648  PRINTF(4)("Loading WorldEntities\n");
649  while(element != NULL)
650  {
651  BaseObject* created = Factory::fabricate(element);
652  if( created != NULL )
653  printf("Created a %s: %s\n", created->getClassName(), created->getName());
654
655  if( element->Value() == "SkyBox")
656  this->sky = dynamic_cast<WorldEntity*>(created);
657  if( element->Value() == "Terrain")
658  this->terrain = dynamic_cast<Terrain*>(created);
659  element = element->NextSiblingElement();
660  }
661
662  PRINTF(4)("Done loading WorldEntities\n");
663  }
664
665  // init the pnode tree
666  PNode::getNullParent()->init();
667  */
668}
669
670
671/**
672*  unloads the world entities from the xml file
673*/
674ErrorMessage SimpleGameMenuData::unloadWorldEntities()
675{
676  /* call underlying function */
677  GameWorldData::unloadWorldEntities();
678}
679
680
681/**
682*  loads the scene data
683* @param root reference to the xml root element
684*/
685ErrorMessage SimpleGameMenuData::loadScene(const TiXmlElement* root)
686{
687  /* call underlying function */
688  GameWorldData::loadScene(root);
689}
690
691
692/**
693*  unloads the scene data
694*/
695ErrorMessage SimpleGameMenuData::unloadScene()
696{
697  /* call underlying function */
698  GameWorldData::unloadScene();
699}
700
701
702
Note: See TracBrowser for help on using the repository browser.