home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / gui / menu_data.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2008-09-27  |  86.2 KB  |  2,870 lines

  1. /***************************************************************************
  2.  * menu_data.cpp  -  menu data and handling classes
  3.  *
  4.  * Copyright (C) 2004 - 2008 Florian Richter
  5.  ***************************************************************************/
  6. /*
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 3 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. #include "../core/globals.h"
  17. #include "../gui/menu_data.h"
  18. #include "../audio/audio.h"
  19. #include "../core/camera.h"
  20. #include "../gui/hud.h"
  21. #include "../core/game_core.h"
  22. #include "../video/font.h"
  23. #include "../overworld/overworld.h"
  24. #include "../user/preferences.h"
  25. #include "../input/joystick.h"
  26. #include "../input/mouse.h"
  27. #include "../core/framerate.h"
  28. #include "../user/savegame.h"
  29. #include "../video/renderer.h"
  30. #include "../level/level.h"
  31. #include "../input/keyboard.h"
  32. #include "../level/level_editor.h"
  33. #include "../audio/sound_manager.h"
  34. #include "../core/math/utilities.h"
  35. #include "../core/i18n.h"
  36. #include "../core/math/size.h"
  37. // boost filesystem
  38. #include "boost/filesystem/convenience.hpp"
  39. namespace fs = boost::filesystem;
  40.  
  41. /* *** *** *** *** *** *** *** *** cMenu_Base *** *** *** *** *** *** *** *** *** */
  42.  
  43. cMenu_Base :: cMenu_Base( void )
  44. {
  45.     guiwindow = NULL;
  46.     action = 0;
  47.     menu_posy = 140;
  48.     text_color = Color( static_cast<Uint8>(255), 251, 98 );
  49.     text_color_value = Color( static_cast<Uint8>(255), 190, 30 );
  50. }
  51.  
  52. cMenu_Base :: ~cMenu_Base( void )
  53. {
  54.     if( guiwindow )
  55.     {
  56.         pGuiSystem->getGUISheet()->removeChildWindow( guiwindow );
  57.         CEGUI::WindowManager::getSingleton().destroyWindow( guiwindow );
  58.     }
  59.  
  60.     for( HudSpriteList::iterator itr = drawlist.begin(), itr_end = drawlist.end(); itr != itr_end; ++itr )
  61.     {
  62.         delete *itr;
  63.     }
  64.     
  65.     drawlist.clear();
  66. }
  67.  
  68. void cMenu_Base :: Init( void )
  69. {
  70.     // continue playing level/world music but not if finished level 
  71.     if( !pAudio->Is_Music_Playing() || ( Game_Mode_Type == MODE_TYPE_LEVEL_CUSTOM && !pActive_Level->Is_Loaded() ) )
  72.     {
  73.         pAudio->Play_Music( "game/menu.ogg", -1, 0, 1500 );
  74.     }
  75.  
  76.     // init
  77.     Change_Game_Mode( MODE_MENU );
  78.  
  79.     layout_file = "";
  80. }
  81.  
  82. void cMenu_Base :: Init_GUI( void )
  83. {
  84.     if( layout_file.empty() )
  85.     {
  86.         return;
  87.     }
  88.  
  89.     guiwindow = CEGUI::WindowManager::getSingleton().loadWindowLayout( layout_file.c_str() );
  90.     pGuiSystem->getGUISheet()->addChildWindow( guiwindow );
  91. }
  92.  
  93. void cMenu_Base :: Update( void )
  94. {
  95.     // animation
  96.     pMenuCore->pMenu_AnimManager->Update();
  97.     // hud
  98.     pHud_Manager->Update();
  99. }
  100.  
  101. void cMenu_Base :: Draw( void )
  102. {
  103.     pVideo->Clear_Screen();
  104.     // animation
  105.     pMenuCore->pMenu_AnimManager->Draw();
  106.     // gui
  107.     pMenuCore->handler->Draw();
  108.  
  109.     // menu items
  110.     for( HudSpriteList::iterator itr = drawlist.begin(), itr_end = drawlist.end(); itr != itr_end; ++itr )
  111.     {
  112.         (*itr)->Draw();
  113.     }
  114. }
  115.  
  116. void cMenu_Base :: Draw_End( void )
  117. {
  118.     // hud
  119.     pHud_Manager->Draw();
  120. }
  121.  
  122. void cMenu_Base :: Exit( void )
  123. {
  124.     // virtual
  125. }
  126.  
  127. /* *** *** *** *** *** *** *** *** cMenu_Main *** *** *** *** *** *** *** *** *** */
  128.  
  129. cMenu_Main :: cMenu_Main( void )
  130. : cMenu_Base()
  131. {
  132.  
  133. }
  134.  
  135. cMenu_Main :: ~cMenu_Main( void )
  136. {
  137.  
  138. }
  139.  
  140. void cMenu_Main :: Init( void )
  141. {
  142.     cMenu_Base::Init();
  143.  
  144.     // with exit image
  145.     pMenuCore->handler->Use_Quit_Image();
  146.  
  147.     cMenu_Item *temp_item = NULL;
  148.  
  149.     layout_file = "menu_main.layout";
  150.  
  151.     GL_Surface *credits = pFont->Render_Text( pFont->font_normal, _("Credits"), yellow );
  152.  
  153.     // Start
  154.     temp_item = pMenuCore->Auto_Menu( "start.png", "start.png", menu_posy );
  155.     temp_item->image_menu->Set_Pos( temp_item->posx + ( temp_item->image_default->col_rect.w + 16 ), temp_item->posy );
  156.     pMenuCore->handler->Add_Menu_Item( temp_item );
  157.     // Options
  158.     menu_posy += 60;
  159.     temp_item = pMenuCore->Auto_Menu( "options.png", "options.png", menu_posy );
  160.     temp_item->image_menu->Set_Pos( temp_item->posx - temp_item->image_menu->col_rect.w - 16, temp_item->posy );
  161.     pMenuCore->handler->Add_Menu_Item( temp_item );
  162.     // Load
  163.     menu_posy += 60;
  164.     temp_item = pMenuCore->Auto_Menu( "load.png", "load.png", menu_posy );
  165.     temp_item->image_menu->Set_Pos( temp_item->posx + ( temp_item->image_default->col_rect.w + 16 ), temp_item->posy );
  166.     pMenuCore->handler->Add_Menu_Item( temp_item );
  167.     // Save
  168.     menu_posy += 60;
  169.     temp_item = pMenuCore->Auto_Menu( "save.png", "save.png", menu_posy );
  170.     temp_item->image_menu->Set_Pos( temp_item->posx - temp_item->image_menu->col_rect.w - 16, temp_item->posy );
  171.     pMenuCore->handler->Add_Menu_Item( temp_item );
  172.     // Quit
  173.     menu_posy += 60;
  174.     temp_item = pMenuCore->Auto_Menu( "quit.png", "", menu_posy, 1 );
  175.     temp_item->image_menu->Set_Pos( temp_item->posx + temp_item->col_rect.w + 16, temp_item->posy );
  176.     pMenuCore->handler->Add_Menu_Item( temp_item );
  177.  
  178.     // Credits
  179.     temp_item = new cMenu_Item();
  180.     temp_item->image_default->Set_Image( credits );
  181.     temp_item->Set_Pos( static_cast<float>(game_res_w) * 0.45f, static_cast<float>(game_res_h) - 30 );
  182.     pMenuCore->handler->Add_Menu_Item( temp_item, 1.5f, grey );
  183.  
  184.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/logo_sdl.png" ), 10, static_cast<float>(game_res_h) * 0.935f ) );
  185.     drawlist.push_back( new cHudSprite( credits, -200, 0, 1 ) );
  186.  
  187.     Init_GUI();
  188. }
  189.  
  190. void cMenu_Main :: Init_GUI( void )
  191. {
  192.     cMenu_Base::Init_GUI();
  193.  
  194.     CEGUI::Window *text_version = CEGUI::WindowManager::getSingleton().getWindow( "text_version" );
  195.     text_version->setProperty( "Text", _("Version ") + string_trim_from_end( float_to_string( smc_version, 6 ), '0' ) );
  196. }
  197.  
  198. void cMenu_Main :: Update( void )
  199. {
  200.     cMenu_Base::Update();
  201.  
  202.     if( !action )
  203.     {
  204.         return;
  205.     }
  206.  
  207.     action = 0;
  208.  
  209.     // Start
  210.     if( pMenuCore->handler->active == 0 )
  211.     {
  212.         pMenuCore->next_menu = MENU_START;
  213.         Game_Action = GA_ENTER_MENU;
  214.     }
  215.     // Options
  216.     else if( pMenuCore->handler->active == 1 )
  217.     {
  218.         pMenuCore->next_menu = MENU_OPTIONS;
  219.         Game_Action = GA_ENTER_MENU;
  220.     }
  221.     // Load
  222.     else if( pMenuCore->handler->active == 2 )
  223.     {
  224.         pMenuCore->next_menu = MENU_LOAD;
  225.         Game_Action = GA_ENTER_MENU;
  226.     }
  227.     // Save
  228.     else if( pMenuCore->handler->active == 3 )
  229.     {
  230.         pMenuCore->next_menu = MENU_SAVE;
  231.         Game_Action = GA_ENTER_MENU;
  232.     }
  233.     // Quit
  234.     else if( pMenuCore->handler->active == 4 )
  235.     {
  236.         game_exit = 1;
  237.     }
  238.     // Credits
  239.     else if( pMenuCore->handler->active == 5 )
  240.     {
  241.         pMenuCore->next_menu = MENU_CREDITS;
  242.         Game_Action = GA_ENTER_MENU;
  243.     }
  244. }
  245.  
  246. void cMenu_Main :: Draw( void )
  247. {
  248.     cMenu_Base::Draw();
  249.     Draw_End();
  250. }
  251.  
  252. void cMenu_Main :: Exit( void )
  253. {
  254.     if( pActive_Level->Is_Loaded() )
  255.     {
  256.         Game_Action = GA_ENTER_LEVEL;
  257.     }
  258.     else if( pActive_Overworld )
  259.     {
  260.         Game_Action = GA_ENTER_WORLD;
  261.     }
  262. }
  263.  
  264. /* *** *** *** *** *** *** *** *** cMenu_Start *** *** *** *** *** *** *** *** *** */
  265.  
  266. cMenu_Start :: cMenu_Start( void )
  267. : cMenu_Base()
  268. {
  269.  
  270. }
  271.  
  272. cMenu_Start :: ~cMenu_Start( void )
  273. {
  274.  
  275. }
  276.  
  277. void cMenu_Start :: Init( void )
  278. {
  279.     cMenu_Base::Init();
  280.  
  281.     cMenu_Item *temp_item = NULL;
  282.  
  283.     layout_file = "menu_start.layout";
  284.  
  285.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/start.png" ), static_cast<float>(game_res_w) * 0.02f, 140 ) );
  286.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/items/overworld.png" ), static_cast<float>(game_res_w) / 20, 210 ) );
  287.  
  288.     Init_GUI();
  289. }
  290.  
  291. void cMenu_Start :: Init_GUI( void )
  292. {
  293.     cMenu_Base::Init_GUI();
  294.  
  295.     // Tab Control
  296.     CEGUI::TabControl *tabcontrol = static_cast<CEGUI::TabControl *>(CEGUI::WindowManager::getSingleton().getWindow( "tabcontrol_main" ));
  297.     tabcontrol->activate();
  298.  
  299.     // events
  300.     tabcontrol->subscribeEvent( CEGUI::Window::EventKeyDown, CEGUI::Event::Subscriber( &cMenu_Start::Window_Keydown, this ) );
  301.  
  302.     // Worlds
  303.     CEGUI::Listbox *listbox_worlds = static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_worlds" ));
  304.     
  305.     // overworld names
  306.     for( vector<cOverworld *>::iterator itr = pOverworld_Manager->objects.begin(), itr_end = pOverworld_Manager->objects.end(); itr != itr_end; ++itr )
  307.     {
  308.         cOverworld_description *world = (*itr)->description;
  309.  
  310. // show all worlds in debug builds
  311. #ifndef _DEBUG
  312.         if( !world->visible )
  313.         {
  314.             continue;
  315.         }
  316. #endif
  317.         
  318.         CEGUI::ListboxTextItem *item = new CEGUI::ListboxTextItem( reinterpret_cast<const CEGUI::utf8*>(world->name.c_str()), 0 );
  319.         // game world
  320.         if( !world->user )
  321.         {
  322.             item->setTextColours( CEGUI::colour( 1, 0.8f, 0.6f ) );
  323.         }
  324.         // user world
  325.         else
  326.         {
  327.             item->setTextColours( CEGUI::colour( 0.8f, 1, 0.6f ) );
  328.         }
  329.  
  330.         item->setSelectionColours( CEGUI::colour( 0.33f, 0.33f, 0.33f ) );
  331.         item->setSelectionBrushImage( "TaharezLook", "ListboxSelectionBrush" );
  332.         listbox_worlds->addItem( item );
  333.     }
  334.  
  335.     // Level Listbox
  336.     CEGUI::Listbox *listbox_levels = static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_levels" ));
  337.     listbox_levels->setSortingEnabled( 1 );
  338.  
  339.     // get game level
  340.     Get_Levels( DATA_DIR "/" GAME_LEVEL_DIR, CEGUI::colour( 1, 0.8f, 0.6f ) );
  341.     // get user level
  342.     Get_Levels( user_data_dir + USER_LEVEL_DIR, CEGUI::colour( 0.8f, 1, 0.6f ) );
  343.  
  344.     // World Listbox events
  345.     listbox_worlds->subscribeEvent( CEGUI::Listbox::EventSelectionChanged, CEGUI::Event::Subscriber( &cMenu_Start::World_Select, this ) );
  346.     listbox_worlds->subscribeEvent( CEGUI::Listbox::EventMouseDoubleClick, CEGUI::Event::Subscriber( &cMenu_Start::World_Select_final_list, this ) );
  347.     // Level Listbox events
  348.     listbox_levels->subscribeEvent( CEGUI::Listbox::EventSelectionChanged, CEGUI::Event::Subscriber( &cMenu_Start::Level_Select, this ) );
  349.     listbox_levels->subscribeEvent( CEGUI::Listbox::EventMouseDoubleClick, CEGUI::Event::Subscriber( &cMenu_Start::Level_Select_Final_List, this ) );
  350.     // Level Buttons
  351.     CEGUI::PushButton *button_new = static_cast<CEGUI::PushButton *>(CEGUI::WindowManager::getSingleton().getWindow( "button_level_new" ));
  352.     button_new->subscribeEvent( CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber( &cMenu_Start::Button_Level_New_Clicked, this ) );
  353.     CEGUI::PushButton *button_edit = static_cast<CEGUI::PushButton *>(CEGUI::WindowManager::getSingleton().getWindow( "button_level_edit" ));
  354.     button_edit->subscribeEvent( CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber( &cMenu_Start::Button_Level_Edit_Clicked, this ) );
  355.     CEGUI::PushButton *button_delete = static_cast<CEGUI::PushButton *>(CEGUI::WindowManager::getSingleton().getWindow( "button_level_delete" ));
  356.     button_delete->subscribeEvent( CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber( &cMenu_Start::Button_Level_Delete_Clicked, this ) );
  357.  
  358.     // select first Item
  359.     listbox_worlds->setItemSelectState( (size_t)0, 1 );
  360.  
  361.     // Button Enter 
  362.     CEGUI::PushButton *button_enter = static_cast<CEGUI::PushButton *>(CEGUI::WindowManager::getSingleton().getWindow( "button_enter" ));
  363.     // Button back
  364.     CEGUI::PushButton *button_back = static_cast<CEGUI::PushButton *>(CEGUI::WindowManager::getSingleton().getWindow( "button_back" ));
  365.  
  366.     // events
  367.     button_enter->subscribeEvent( CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber( &cMenu_Start::Button_Enter_Clicked, this ) );
  368.     button_back->subscribeEvent( CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber( &cMenu_Start::Button_Back_Clicked, this ) );
  369. }
  370.  
  371. void cMenu_Start :: Update( void )
  372. {
  373.     cMenu_Base::Update();
  374.  
  375.     if( !action )
  376.     {
  377.         return;
  378.     }
  379.  
  380.     action = 0;
  381.  
  382.     // enter
  383.     Load_Selected();
  384. }
  385.  
  386. void cMenu_Start :: Draw( void )
  387. {
  388.     cMenu_Base::Draw();
  389.     Draw_End();
  390. }
  391.  
  392. void cMenu_Start :: Exit( void )
  393. {
  394.     pMenuCore->next_menu = MENU_MAIN;
  395.     Game_Action = GA_ENTER_MENU;
  396. }
  397.  
  398. void cMenu_Start :: Get_Levels( string dir, CEGUI::colour color )
  399. {
  400.     // Level Listbox
  401.     CEGUI::Listbox *listbox_levels = static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_levels" ));
  402.  
  403.     // get directory length for erasing
  404.     int dir_length = dir.length() + 1;
  405.     // get all files
  406.     vector<string> lvl_files = Get_Directory_Files( dir, "", 0, 0 );
  407.  
  408.     // list all available levels
  409.     for( vector<string>::iterator itr = lvl_files.begin(), itr_end = lvl_files.end(); itr != itr_end; ++itr )
  410.     {
  411.         // get filename
  412.         string lvl_name = (*itr);
  413.         // remove base directory
  414.         lvl_name.erase( 0, dir_length );
  415.  
  416.         // erase file type only if smclvl
  417.         if( lvl_name.rfind( ".smclvl" ) != string::npos )
  418.         {
  419.             lvl_name.erase( lvl_name.rfind( ".smclvl" ) );
  420.         }
  421.  
  422.         // check if item with the same name already exists
  423.         CEGUI::ListboxItem *old_item = listbox_levels->findItemWithText( lvl_name, NULL );
  424.         // remove old item
  425.         if( old_item )
  426.         {
  427.             listbox_levels->removeItem( old_item );
  428.         }
  429.  
  430.         CEGUI::ListboxTextItem *item = new CEGUI::ListboxTextItem( reinterpret_cast<const CEGUI::utf8*>(lvl_name.c_str()), 0 );
  431.  
  432.         // smclvl
  433.         if( lvl_name.rfind( ".txt" ) == string::npos )
  434.         {
  435.             item->setTextColours( color );
  436.         }
  437.         // grey out old txt levels
  438.         else
  439.         {
  440.             item->setTextColours( CEGUI::colour( 0.6f, 0.6f, 0.6f ) );
  441.         }
  442.  
  443.         item->setSelectionColours( CEGUI::colour( 0.33f, 0.33f, 0.33f ) );
  444.         item->setSelectionBrushImage( "TaharezLook", "ListboxSelectionBrush" );
  445.         listbox_levels->addItem( item );
  446.     }
  447. }
  448.  
  449. void cMenu_Start :: Load_Selected( void )
  450. {
  451.     // Get Tab Control
  452.     CEGUI::TabControl *tabcontrol = static_cast<CEGUI::TabControl *>(CEGUI::WindowManager::getSingleton().getWindow( "tabcontrol_main" ));
  453.  
  454.     // World
  455.     if( tabcontrol->getSelectedTabIndex() == 0 )
  456.     {
  457.         CEGUI::ListboxItem *item = (static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_worlds" )))->getFirstSelectedItem();
  458.  
  459.         // load world
  460.         if( item )
  461.         {
  462.             Load_World( item->getText().c_str() );
  463.         }
  464.     }
  465.     // Level
  466.     else
  467.     {
  468.         CEGUI::ListboxItem *item = (static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_levels" )))->getFirstSelectedItem();
  469.  
  470.         // load level
  471.         if( item )
  472.         {
  473.             Load_Level( item->getText().c_str() );
  474.         }
  475.     }
  476. }
  477.  
  478. void cMenu_Start :: Load_World( string name )
  479. {
  480.     cOverworld *new_world = pOverworld_Manager->Get_from_Name( name );
  481.  
  482.     // if not available
  483.     if( !new_world )
  484.     {
  485.         debugdisplay->Set_Text( _("Couldn't load overworld ") + name, static_cast<float>(speedfactor_fps) );
  486.     }
  487.     // if successfully set active
  488.     else
  489.     {
  490.         // unload possible loaded level
  491.         pActive_Level->Unload();
  492.         // enter world
  493.         Game_Action = GA_ENTER_WORLD;
  494.         Game_Action_Data.add( "world", name.c_str() );
  495.     }
  496. }
  497.  
  498. bool cMenu_Start :: Load_Level( string level_name )
  499. {
  500.     // if not available
  501.     if( !pActive_Level->Get_Path( level_name ) )
  502.     {
  503.         pAudio->Play_Sound( "error.ogg" );
  504.         debugdisplay->Set_Text( _("Couldn't load level ") + level_name, static_cast<float>(speedfactor_fps) );
  505.         return 0;
  506.     }
  507.  
  508.     // enter level
  509.     Game_Action = GA_ENTER_LEVEL;
  510.     Game_Mode_Type = MODE_TYPE_LEVEL_CUSTOM;
  511.     Game_Action_Data.add( "level", level_name.c_str() );
  512.  
  513.     return 1;
  514. }
  515.  
  516. bool cMenu_Start :: Window_Keydown( const CEGUI::EventArgs &e )
  517. {
  518.     const CEGUI::KeyEventArgs &ke = static_cast<const CEGUI::KeyEventArgs &>(e);
  519.  
  520.     // Return
  521.     if( ke.scancode == CEGUI::Key::Return || ke.scancode == CEGUI::Key::NumpadEnter )
  522.     {
  523.         Load_Selected();
  524.  
  525.         return 1;
  526.     }
  527.     // Shift Tab
  528.     else if( ( pKeyboard->keys[SDLK_LSHIFT] || pKeyboard->keys[SDLK_RSHIFT] ) && ke.scancode == CEGUI::Key::Tab )
  529.     {
  530.         // Get Tab Control
  531.         CEGUI::TabControl *tabcontrol = static_cast<CEGUI::TabControl *>(CEGUI::WindowManager::getSingleton().getWindow( "tabcontrol_main" ));
  532.  
  533.         // if last tab
  534.         if( tabcontrol->getSelectedTabIndex() + 1 == tabcontrol->getTabCount() )
  535.         {
  536.             tabcontrol->setSelectedTabAtIndex( 0 );
  537.         }
  538.         // select next tab
  539.         else
  540.         {
  541.             tabcontrol->setSelectedTabAtIndex( tabcontrol->getSelectedTabIndex() + 1 );
  542.         }
  543.  
  544.         return 1;
  545.     }
  546.     // Down/Up
  547.     else if( ke.scancode == CEGUI::Key::ArrowDown || ke.scancode == CEGUI::Key::ArrowUp || ke.scancode == CEGUI::Key::PageDown || ke.scancode == CEGUI::Key::PageUp ||
  548.              ke.scancode == CEGUI::Key::Home || ke.scancode == CEGUI::Key::End )
  549.     {
  550.         // Get Tab Control
  551.         CEGUI::TabControl *tabcontrol = static_cast<CEGUI::TabControl *>(CEGUI::WindowManager::getSingleton().getWindow( "tabcontrol_main" ));
  552.  
  553.         // Items Listbox
  554.         CEGUI::Listbox *listbox;
  555.  
  556.         // World
  557.         if( tabcontrol->getSelectedTabIndex() == 0 )
  558.         {
  559.             listbox = static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_worlds" ));
  560.         }
  561.         // Level
  562.         else
  563.         {
  564.             listbox = static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_levels" ));
  565.         }
  566.  
  567.         
  568.         int new_selected = 0;
  569.         int last_selected = 0;
  570.  
  571.         // get selected item
  572.         CEGUI::ListboxItem *last_selected_item = listbox->getFirstSelectedItem();
  573.  
  574.         // if something is selected
  575.         if( last_selected_item != NULL )
  576.         {
  577.             last_selected = listbox->getItemIndex( last_selected_item );
  578.         }
  579.  
  580.         // down
  581.         if( ke.scancode == CEGUI::Key::ArrowDown )
  582.         {
  583.             new_selected = last_selected + 1;
  584.         }
  585.         // up
  586.         else if( ke.scancode == CEGUI::Key::ArrowUp )
  587.         {
  588.             new_selected = last_selected - 1;
  589.         }
  590.         // page down
  591.         else if( ke.scancode == CEGUI::Key::PageDown )
  592.         {
  593.             // todo : should skip all visible items
  594.             new_selected = last_selected + 10;
  595.         }
  596.         // page up
  597.         else if( ke.scancode == CEGUI::Key::PageUp )
  598.         {
  599.             // todo : should skip all visible items
  600.             new_selected = last_selected - 10;
  601.         }
  602.         // home
  603.         else if( ke.scancode == CEGUI::Key::Home )
  604.         {
  605.             new_selected = 0;
  606.         }
  607.         // end
  608.         else if( ke.scancode == CEGUI::Key::End )
  609.         {
  610.             new_selected = listbox->getItemCount() - 1;
  611.         }
  612.  
  613.         // if after last item
  614.         if( new_selected >= static_cast<int>(listbox->getItemCount()) )
  615.         {
  616.             // select first
  617.             if( last_selected == static_cast<int>(listbox->getItemCount()) - 1 )
  618.             {
  619.                 new_selected = 0;
  620.             }
  621.             // select last
  622.             else
  623.             {
  624.                 new_selected = listbox->getItemCount() - 1;
  625.             }
  626.         }
  627.         // if before first item
  628.         else if( new_selected < 0 )
  629.         {
  630.             // select last
  631.             if( last_selected == 0 )
  632.             {
  633.                 new_selected = listbox->getItemCount() - 1;
  634.             }
  635.             // select first
  636.             else
  637.             {
  638.                 new_selected = 0;
  639.             }
  640.         }
  641.  
  642.         listbox->setItemSelectState( new_selected, 1 );
  643.         listbox->ensureItemIsVisible( new_selected );
  644.  
  645.         return 1;
  646.     }
  647.  
  648.     return 0;
  649. }
  650.  
  651. bool cMenu_Start :: World_Select( const CEGUI::EventArgs &event )
  652. {
  653.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  654.     CEGUI::ListboxItem *item = static_cast<CEGUI::Listbox *>( windowEventArgs.window )->getFirstSelectedItem();
  655.  
  656.     // World Comment
  657.     CEGUI::Editbox *editbox_world_comment = static_cast<CEGUI::Editbox *>(CEGUI::WindowManager::getSingleton().getWindow( "editbox_world_comment" ));
  658.  
  659.     // set world comment
  660.     if( item )
  661.     {
  662.         editbox_world_comment->setText( reinterpret_cast<const CEGUI::utf8*>(pOverworld_Manager->Get_from_Name( item->getText().c_str() )->description->comment.c_str()) );
  663.     }
  664.     // clear
  665.     else
  666.     {
  667.         editbox_world_comment->setText( "" );
  668.     }
  669.  
  670.     return 1;
  671. }
  672.  
  673. bool cMenu_Start :: World_Select_final_list( const CEGUI::EventArgs &event )
  674. {
  675.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  676.     CEGUI::ListboxItem *item = static_cast<CEGUI::Listbox *>( windowEventArgs.window )->getFirstSelectedItem();
  677.  
  678.     // load world
  679.     if( item )
  680.     {
  681.         Load_World( item->getText().c_str() );
  682.     }
  683.  
  684.     return 1;
  685. }
  686.  
  687. bool cMenu_Start :: Level_Select( const CEGUI::EventArgs &event )
  688. {
  689.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  690.     CEGUI::ListboxItem *item = static_cast<CEGUI::Listbox *>( windowEventArgs.window )->getFirstSelectedItem();
  691.  
  692.     // set level something
  693.     if( item )
  694.     {
  695.         // todo : needs level manager
  696.     }
  697.     // clear
  698.     else
  699.     {
  700.         // todo : needs level manager
  701.     }
  702.  
  703.     return 1;
  704. }
  705.  
  706. bool cMenu_Start :: Level_Select_Final_List( const CEGUI::EventArgs &event )
  707. {
  708.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  709.     CEGUI::ListboxItem *item = static_cast<CEGUI::Listbox *>( windowEventArgs.window )->getFirstSelectedItem();
  710.  
  711.     // load level
  712.     if( item )
  713.     {
  714.         Load_Level( item->getText().c_str() );
  715.     }
  716.  
  717.     return 1;
  718. }
  719.  
  720.  
  721. bool cMenu_Start :: Button_Level_New_Clicked( const CEGUI::EventArgs &event )
  722. {
  723.     // Create level
  724.     if( !pLevel_Editor->Function_New() )
  725.     {
  726.         // aborted/failed
  727.         return 0;
  728.     }
  729.  
  730.     // Enter level
  731.     Game_Action = GA_ENTER_LEVEL;
  732.     Game_Mode_Type = MODE_TYPE_LEVEL_CUSTOM_EDITOR;
  733.  
  734.     return 1;
  735. }
  736.  
  737. bool cMenu_Start :: Button_Level_Edit_Clicked( const CEGUI::EventArgs &event )
  738. {
  739.     // Get Selected Level
  740.     CEGUI::Listbox *listbox_levels = static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_levels" ));
  741.     CEGUI::ListboxItem *item = listbox_levels->getFirstSelectedItem();
  742.  
  743.     // load level
  744.     if( item && Load_Level( item->getText().c_str() ) )
  745.     {
  746.         Game_Mode_Type = MODE_TYPE_LEVEL_CUSTOM_EDITOR;
  747.     }
  748.  
  749.     return 1;
  750. }
  751.  
  752. bool cMenu_Start :: Button_Level_Delete_Clicked( const CEGUI::EventArgs &event )
  753. {
  754.     // Get Selected Level
  755.     CEGUI::Listbox *listbox_levels = static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_levels" ));
  756.     CEGUI::ListboxItem *item = listbox_levels->getFirstSelectedItem();
  757.  
  758.     // load level
  759.     if( item )
  760.     {
  761.         string filename = item->getText().c_str();
  762.  
  763.         // if denied
  764.         if( !Box_Question( _("Delete ") + filename + " ?" ) )
  765.         {
  766.             return 1;
  767.         }
  768.  
  769.         // only user directory
  770.         if( pActive_Level->Get_Path( filename, 1 ) )
  771.         {
  772.             Delete_File( filename );
  773.             listbox_levels->removeItem( item );
  774.         }
  775.     }
  776.  
  777.     return 1;
  778. }
  779.  
  780. bool cMenu_Start :: Button_Enter_Clicked( const CEGUI::EventArgs &event )
  781. {
  782.     Load_Selected();
  783.     return 1;
  784. }
  785.  
  786. bool cMenu_Start :: Button_Back_Clicked( const CEGUI::EventArgs &event )
  787. {
  788.     Exit();
  789.     return 1;
  790. }
  791.  
  792. /* *** *** *** *** *** *** *** *** cMenu_Options *** *** *** *** *** *** *** *** *** */
  793.  
  794. cMenu_Options :: cMenu_Options( void )
  795. : cMenu_Base()
  796. {
  797.  
  798. }
  799.  
  800. cMenu_Options :: ~cMenu_Options( void )
  801. {
  802.  
  803. }
  804.  
  805. void cMenu_Options :: Init( void )
  806. {
  807.     cMenu_Base::Init();
  808.  
  809.     cMenu_Item *temp_item = NULL;
  810.     menu_posy = 210;
  811.  
  812.     GL_Surface *back1 = pFont->Render_Text( pFont->font_normal, _("Back"), text_color );
  813.  
  814.     // Game
  815.     temp_item = new cMenu_Item();
  816.     temp_item = pMenuCore->Auto_Menu( "game.png", "", menu_posy );
  817.     temp_item->Set_Scale( 0.7f );
  818.     temp_item->Set_Pos_X( game_res_w * 0.05f, 1 );
  819.     pMenuCore->handler->Add_Menu_Item( temp_item );
  820.     // Video
  821.     menu_posy += 60;
  822.     temp_item = new cMenu_Item();
  823.     temp_item = pMenuCore->Auto_Menu( "video.png", "", menu_posy );
  824.     temp_item->Set_Pos_X( game_res_w * 0.05f, 1 );
  825.     pMenuCore->handler->Add_Menu_Item( temp_item );
  826.     // Audio
  827.     menu_posy += 60;
  828.     temp_item = new cMenu_Item();
  829.     temp_item = pMenuCore->Auto_Menu( "audio.png", "", menu_posy );
  830.     temp_item->Set_Pos_X( game_res_w * 0.05f, 1 );
  831.     pMenuCore->handler->Add_Menu_Item( temp_item );
  832.     // Controls
  833.     menu_posy += 60;
  834.     temp_item = new cMenu_Item();
  835.     temp_item = pMenuCore->Auto_Menu( "controls.png", "", menu_posy );
  836.     temp_item->Set_Pos_X( game_res_w * 0.05f, 1 );
  837.     pMenuCore->handler->Add_Menu_Item( temp_item );
  838.     // back
  839.     temp_item = new cMenu_Item();
  840.     temp_item->image_default->Set_Image( back1 );
  841.     temp_item->Set_Pos( game_res_w * 0.11f, 450 );
  842.     temp_item->isquit = 1;
  843.     pMenuCore->handler->Add_Menu_Item( temp_item, 1.5f, grey );
  844.  
  845.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/options.png" ), game_res_w * 0.01f, 140, 0 ) );
  846.     drawlist.push_back( new cHudSprite( back1, -200, 0, 1 ) );
  847. }
  848.  
  849. void cMenu_Options :: Init_GUI( void )
  850. {
  851.     cMenu_Base::Init_GUI();
  852. }
  853.  
  854. void cMenu_Options :: Update( void )
  855. {
  856.     cMenu_Base::Update();
  857.  
  858.     if( !action )
  859.     {
  860.         return;
  861.     }
  862.  
  863.     // only menu actions
  864.     if( pMenuCore->handler->active > 4 )
  865.     {
  866.         return;
  867.     }
  868.  
  869.     action = 0;
  870.  
  871.     // Game
  872.     if( pMenuCore->handler->active == MENU_GAME )
  873.     {
  874.         pMenuCore->next_menu = MENU_OPTIONS;
  875.         pMenuCore->options_menu_id    = MENU_GAME;
  876.         Game_Action = GA_ENTER_MENU;
  877.     }
  878.      // Video
  879.     else if( pMenuCore->handler->active == MENU_VIDEO )
  880.     {
  881.         pMenuCore->next_menu = MENU_OPTIONS;
  882.         pMenuCore->options_menu_id    = MENU_VIDEO;
  883.         Game_Action = GA_ENTER_MENU;
  884.     }
  885.     // Audio
  886.     else if( pMenuCore->handler->active == MENU_AUDIO )
  887.     {
  888.         pMenuCore->next_menu = MENU_OPTIONS;
  889.         pMenuCore->options_menu_id    = MENU_AUDIO;
  890.         Game_Action = GA_ENTER_MENU;
  891.     }
  892.     // Controls
  893.     else if( pMenuCore->handler->active == MENU_CONTROLS )
  894.     {
  895.         pMenuCore->next_menu = MENU_OPTIONS;
  896.         pMenuCore->options_menu_id = MENU_CONTROLS;
  897.         Game_Action = GA_ENTER_MENU;
  898.     }
  899.     // back
  900.     else if( pMenuCore->handler->active == 4 )
  901.     {
  902.         Exit();
  903.     }
  904. }
  905.  
  906. void cMenu_Options :: Draw( void )
  907. {
  908.     cMenu_Base::Draw();
  909. }
  910.  
  911. void cMenu_Options :: Exit( void )
  912. {
  913.     pMenuCore->next_menu = MENU_MAIN;
  914.     pPreferences->Save();
  915.     Game_Action = GA_ENTER_MENU;
  916. }
  917.  
  918. /* *** *** *** *** *** *** *** *** cMenu_Options_Game *** *** *** *** *** *** *** *** *** */
  919.  
  920. cMenu_Options_Game :: cMenu_Options_Game( void )
  921. : cMenu_Options()
  922. {
  923.  
  924. }
  925.  
  926. cMenu_Options_Game :: ~cMenu_Options_Game( void )
  927. {
  928.  
  929. }
  930.  
  931. void cMenu_Options_Game :: Init( void )
  932. {
  933.     cMenu_Options::Init();
  934.  
  935.     cMenu_Item *temp_item = NULL;
  936.  
  937.     layout_file = "menu_game.layout";
  938.  
  939.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/game.png" ), game_res_w * 0.5f, game_res_h * 0.1f ) );
  940.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/items/game.png" ), game_res_w * 0.4f, game_res_h * 0.1f ) );
  941.  
  942.     pMenuCore->handler->Set_Active( MENU_GAME );
  943.  
  944.     Init_GUI();
  945. }
  946.  
  947. void cMenu_Options_Game :: Init_GUI( void )
  948. {
  949.     cMenu_Options::Init_GUI();
  950.  
  951.     // get the CEGUI window manager
  952.     CEGUI::WindowManager &windowmanager = CEGUI::WindowManager::getSingleton();
  953.  
  954.     // always run
  955.     CEGUI::Combobox *combo_always_run = static_cast<CEGUI::Combobox *>(windowmanager.getWindow( "combo_always_run" ));
  956.  
  957.     CEGUI::ListboxTextItem *item = new CEGUI::ListboxTextItem( UTF8_("On"), 0 );
  958.     item->setTextColours( CEGUI::colour( 0, 1, 0 ) );
  959.     combo_always_run->addItem( item );
  960.     item = new CEGUI::ListboxTextItem( UTF8_("Off"), 1 );
  961.     item->setTextColours( CEGUI::colour( 0, 0, 1 ) );
  962.     combo_always_run->addItem( item );
  963.  
  964.     if( pPreferences->always_run )
  965.     {
  966.         combo_always_run->setText( UTF8_("On") );
  967.     }
  968.     else
  969.     {
  970.         combo_always_run->setText( UTF8_("Off") );
  971.     }
  972.  
  973.     combo_always_run->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cMenu_Options_Game::Always_Run_Select, this ) );
  974.  
  975.     // Camera Horizontal Speed
  976.     CEGUI::Spinner *spinner_camera_hor_speed = static_cast<CEGUI::Spinner *>(windowmanager.getWindow( "spinner_camera_hor_speed" ));
  977.     spinner_camera_hor_speed->setCurrentValue( pLevel_Manager->camera->hor_offset_speed );
  978.  
  979.     spinner_camera_hor_speed->subscribeEvent( CEGUI::Spinner::EventValueChanged, CEGUI::Event::Subscriber( &cMenu_Options_Game::Camera_Hor_Select, this ) );
  980.  
  981.     // Camera Vertical Speed
  982.     CEGUI::Spinner *spinner_camera_ver_speed = static_cast<CEGUI::Spinner *>(windowmanager.getWindow( "spinner_camera_ver_speed" ));
  983.     spinner_camera_ver_speed->setCurrentValue( pLevel_Manager->camera->ver_offset_speed );
  984.  
  985.     spinner_camera_ver_speed->subscribeEvent( CEGUI::Spinner::EventValueChanged, CEGUI::Event::Subscriber( &cMenu_Options_Game::Camera_Ver_Select, this ) );
  986.  
  987.     // language
  988.     CEGUI::Combobox *combo_language = static_cast<CEGUI::Combobox *>(windowmanager.getWindow( "combo_language" ));
  989.  
  990.     item = new CEGUI::ListboxTextItem( UTF8_("default"), 0 );
  991.     item->setTextColours( CEGUI::colour( 0, 1, 0 ) );
  992.     combo_language->addItem( item );
  993.  
  994.     // get available languages
  995.     vector<string> language_files = Get_Directory_Files( DATA_DIR "/" GAME_TRANSLATION_DIR, ".none", 1, 0 );
  996.     // add english as it is the base language and not in the translation directory
  997.     language_files.push_back( DATA_DIR "/" GAME_TRANSLATION_DIR "/" "en" );
  998.  
  999.     for( vector<string>::iterator itr = language_files.begin(), itr_end = language_files.end(); itr != itr_end; ++itr )
  1000.     {
  1001.         // get filename
  1002.         string filename = (*itr);
  1003.  
  1004.         // if not directory
  1005.         if( filename.rfind( "." ) != string::npos )
  1006.         {
  1007.             continue;
  1008.         }
  1009.  
  1010.         // remove data dir
  1011.         filename.erase( 0, strlen( DATA_DIR "/" GAME_TRANSLATION_DIR "/" ) );
  1012.  
  1013.         item = new CEGUI::ListboxTextItem( filename, 1 );
  1014.         item->setTextColours( CEGUI::colour( 0, 0, 1 ) );
  1015.         combo_language->addItem( item );
  1016.     }
  1017.  
  1018.     if( pPreferences->language.empty() )
  1019.     {
  1020.         combo_language->setText( UTF8_("default") );
  1021.     }
  1022.     else
  1023.     {
  1024.         combo_language->setText( pPreferences->language );
  1025.     }
  1026.  
  1027.     combo_language->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cMenu_Options_Game::Language_Select, this ) );
  1028. }
  1029.  
  1030. void cMenu_Options_Game :: Update( void )
  1031. {
  1032.     cMenu_Options::Update();
  1033.  
  1034.     if( !action )
  1035.     {
  1036.         return;
  1037.     }
  1038.  
  1039.     cMenu_Options::Update();
  1040.  
  1041.     // only video actions
  1042.     if( pMenuCore->handler->active <= 4 )
  1043.     {
  1044.         return;
  1045.     }
  1046.  
  1047.     action = 0;
  1048.  
  1049.     // always run
  1050.     if( pMenuCore->handler->active == 5 )
  1051.     {
  1052.         pPreferences->always_run = !pPreferences->always_run;
  1053.  
  1054.         if( pPreferences->always_run )
  1055.         {
  1056.             CEGUI::WindowManager::getSingleton().getWindow( "combo_always_run" )->setText( UTF8_("On") );
  1057.         }
  1058.         else
  1059.         {
  1060.             CEGUI::WindowManager::getSingleton().getWindow( "combo_always_run" )->setText( UTF8_("Off") );
  1061.         }
  1062.     }
  1063.     // Camera Horizontal
  1064.     else if( pMenuCore->handler->active == 6 )
  1065.     {
  1066.         // nothing
  1067.     }
  1068.     // Camera Vertical
  1069.     else if( pMenuCore->handler->active == 7 )
  1070.     {
  1071.         // nothing
  1072.     }
  1073.     // language
  1074.     if( pMenuCore->handler->active == 8 )
  1075.     {
  1076.         CEGUI::Combobox *combo_language = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_language" ));
  1077.         unsigned int selected = combo_language->getItemIndex( combo_language->findItemWithText( combo_language->getText(), NULL ) );
  1078.  
  1079.         CEGUI::ListboxItem *new_selected = NULL;
  1080.  
  1081.         // last item selected
  1082.         if( selected == combo_language->getItemCount() - 1 )
  1083.         {
  1084.             new_selected = combo_language->getListboxItemFromIndex( 0 );
  1085.         }
  1086.         // select next item
  1087.         else
  1088.         {
  1089.             new_selected = combo_language->getListboxItemFromIndex( selected + 1 );
  1090.         }
  1091.         
  1092.         combo_language->setText( new_selected->getText() );
  1093.         combo_language->setItemSelectState( new_selected, 1 );
  1094.         Language_Select( CEGUI::WindowEventArgs( combo_language ) );
  1095.     }
  1096. }
  1097.  
  1098. void cMenu_Options_Game :: Draw( void )
  1099. {
  1100.     cMenu_Options::Draw();
  1101.     Draw_End();
  1102. }
  1103.  
  1104. bool cMenu_Options_Game :: Always_Run_Select( const CEGUI::EventArgs &event )
  1105. {
  1106.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1107.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox*>( windowEventArgs.window )->getSelectedItem();
  1108.  
  1109.     bool always_run = 0;
  1110.  
  1111.     if( item->getText().compare( UTF8_("On") ) == 0 )
  1112.     {
  1113.         always_run = 1;
  1114.     }
  1115.  
  1116.     pPreferences->always_run = always_run;
  1117.  
  1118.     return 1;
  1119. }
  1120.  
  1121. bool cMenu_Options_Game :: Camera_Hor_Select( const CEGUI::EventArgs &event )
  1122. {
  1123.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1124.     CEGUI::Spinner *spinner_camera_hor = static_cast<CEGUI::Spinner *>( windowEventArgs.window );
  1125.     
  1126.     pLevel_Manager->camera->hor_offset_speed = spinner_camera_hor->getCurrentValue();
  1127.     pPreferences->camera_hor_speed = spinner_camera_hor->getCurrentValue();
  1128.  
  1129.     return 1;
  1130. }
  1131.  
  1132. bool cMenu_Options_Game :: Camera_Ver_Select( const CEGUI::EventArgs &event )
  1133. {
  1134.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1135.     CEGUI::Spinner *spinner_camera_ver = static_cast<CEGUI::Spinner *>( windowEventArgs.window );
  1136.     
  1137.     pLevel_Manager->camera->ver_offset_speed = spinner_camera_ver->getCurrentValue();
  1138.     pPreferences->camera_ver_speed = spinner_camera_ver->getCurrentValue();
  1139.  
  1140.     return 1;
  1141. }
  1142.  
  1143. bool cMenu_Options_Game :: Language_Select( const CEGUI::EventArgs &event )
  1144. {
  1145.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1146.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox*>( windowEventArgs.window )->getSelectedItem();
  1147.  
  1148.     // default
  1149.     if( item->getText().compare( UTF8_("default") ) == 0 )
  1150.     {
  1151.         pPreferences->language = "";
  1152.     }
  1153.     // force
  1154.     else
  1155.     {
  1156.         pPreferences->language = item->getText().c_str();
  1157.     }
  1158.  
  1159.     return 1;
  1160. }
  1161.  
  1162. /* *** *** *** *** *** *** *** *** cMenu_Options_Video *** *** *** *** *** *** *** *** *** */
  1163.  
  1164. cMenu_Options_Video :: cMenu_Options_Video( void )
  1165. : cMenu_Options()
  1166. {
  1167.  
  1168. }
  1169.  
  1170. cMenu_Options_Video :: ~cMenu_Options_Video( void )
  1171. {
  1172.  
  1173. }
  1174.  
  1175. void cMenu_Options_Video :: Init( void )
  1176. {
  1177.     cMenu_Options::Init();
  1178.  
  1179.     layout_file = "menu_video.layout";
  1180.  
  1181.  
  1182.     // Video Info
  1183.     vid_w = pPreferences->video_screen_w;
  1184.     vid_h = pPreferences->video_screen_h;
  1185.     vid_bpp = pPreferences->video_screen_bpp;
  1186.     vid_fullscreen = pPreferences->video_fullscreen;
  1187.     vid_vsync = pPreferences->video_vsync;
  1188.     vid_geometry_detail = pVideo->geometry_detail;
  1189.     vid_texture_detail = pVideo->texture_detail;
  1190.  
  1191.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/video.png" ), game_res_w * 0.5f, game_res_h * 0.1f ) );
  1192.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/items/video.png" ), game_res_w * 0.4f, game_res_h * 0.1f ) );
  1193.  
  1194.     pMenuCore->handler->Set_Active( MENU_VIDEO );
  1195.  
  1196.     Init_GUI();
  1197. }
  1198.  
  1199. void cMenu_Options_Video :: Init_GUI( void )
  1200. {
  1201.     cMenu_Options::Init_GUI();
  1202.  
  1203.     // Resolution
  1204.     CEGUI::Combobox *combo_resolution = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_resolution" ));
  1205.  
  1206.     vector<cSize_Int> valid_resolutions = pVideo->Get_Supported_Resolutions();
  1207.  
  1208.     CEGUI::ListboxTextItem *item;
  1209.  
  1210.     // add to listbox
  1211.     for( vector<cSize_Int>::iterator itr = valid_resolutions.begin(), itr_end = valid_resolutions.end(); itr != itr_end; ++itr )
  1212.     {
  1213.         // get resolution
  1214.         cSize_Int res = (*itr);
  1215.  
  1216.         if( res.m_width <= 0 || res.m_height <= 0 )
  1217.         {
  1218.             continue;
  1219.         }
  1220.  
  1221.         // calculate aspect ratio
  1222.         float ar = static_cast<float>(res.m_width) / static_cast<float>(res.m_height);
  1223.  
  1224.         item = new CEGUI::ListboxTextItem( int_to_string( res.m_width ) + "x" + int_to_string( res.m_height ), 3 );
  1225.         CEGUI::colour color( 0, 0, 0 );
  1226.         // if badly stretched resolution display it in red
  1227.         if( ar < 1.1f || ar > 1.5f )
  1228.         {
  1229.             color.setGreen( 0 );
  1230.             color.setRed( 1 );
  1231.         }
  1232.         // good resolution
  1233.         else
  1234.         {
  1235.             // calculate difference from a default 1.333 resolution
  1236.             float diff_from_default;
  1237.  
  1238.             if( ar > 1.333f )
  1239.             {
  1240.                 diff_from_default = ( ar - 1.333f ) * 4;
  1241.             }
  1242.             else
  1243.             {
  1244.                 diff_from_default = -( ar - 1.333f ) * 4;
  1245.             }
  1246.  
  1247.             color.setGreen( 1 - diff_from_default );
  1248.             color.setRed( diff_from_default );
  1249.         }
  1250.         item->setTextColours( color );
  1251.         combo_resolution->addItem( item );
  1252.     }
  1253.  
  1254.     string temp = int_to_string( pPreferences->video_screen_w ) + "x" + int_to_string( pPreferences->video_screen_h );
  1255.     combo_resolution->setText( temp.c_str() );
  1256.  
  1257.     combo_resolution->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cMenu_Options_Video::Res_Select, this ) );
  1258.  
  1259.     // Bpp
  1260.     CEGUI::Combobox *combo_bpp = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_bpp" ));
  1261.  
  1262.     item = new CEGUI::ListboxTextItem( "16", 0 );
  1263.     item->setTextColours( CEGUI::colour( 1, 0.6f, 0.3f ) );
  1264.     combo_bpp->addItem( item );
  1265.     item = new CEGUI::ListboxTextItem( "32", 1 );
  1266.     item->setTextColours( CEGUI::colour( 0, 1, 0 ) );
  1267.     combo_bpp->addItem( item );
  1268.  
  1269.     combo_bpp->setText( int_to_string( pPreferences->video_screen_bpp ).c_str() );
  1270.  
  1271.     combo_bpp->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cMenu_Options_Video::Bpp_Select, this ) );
  1272.  
  1273.     // Fullscreen
  1274.     CEGUI::Combobox *combo_fullscreen = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_fullscreen" ));
  1275.  
  1276.     item = new CEGUI::ListboxTextItem( UTF8_("On"), 0 );
  1277.     item->setTextColours( CEGUI::colour( 0, 1, 0 ) );
  1278.     combo_fullscreen->addItem( item );
  1279.     item = new CEGUI::ListboxTextItem( UTF8_("Off"), 1 );
  1280.     item->setTextColours( CEGUI::colour( 0, 0, 1 ) );
  1281.     combo_fullscreen->addItem( item );
  1282.  
  1283.     if( pPreferences->video_fullscreen )
  1284.     {
  1285.         combo_fullscreen->setText( UTF8_("On") );
  1286.     }
  1287.     else
  1288.     {
  1289.         combo_fullscreen->setText( UTF8_("Off") );
  1290.     }
  1291.  
  1292.     combo_fullscreen->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cMenu_Options_Video::Fullscreen_Select, this ) );
  1293.  
  1294.     // VSync
  1295.     CEGUI::Combobox *combo_vsync = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_vsync" ));
  1296.  
  1297.     item = new CEGUI::ListboxTextItem( UTF8_("On"), 0 );
  1298.     item->setTextColours( CEGUI::colour( 0, 1, 0 ) );
  1299.     combo_vsync->addItem( item );
  1300.     item = new CEGUI::ListboxTextItem( UTF8_("Off"), 1 );
  1301.     item->setTextColours( CEGUI::colour( 0, 0, 1 ) );
  1302.     combo_vsync->addItem( item );
  1303.  
  1304.     if( pPreferences->video_vsync )
  1305.     {
  1306.         combo_vsync->setText( UTF8_("On") );
  1307.     }
  1308.     else
  1309.     {
  1310.         combo_vsync->setText( UTF8_("Off") );
  1311.     }
  1312.  
  1313.     combo_vsync->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cMenu_Options_Video::Vsync_Select, this ) );
  1314.  
  1315.     // Geometry detail
  1316.     CEGUI::Slider *slider_geometry_detail = static_cast<CEGUI::Slider *>(CEGUI::WindowManager::getSingleton().getWindow( "slider_geometry_detail" ));
  1317.     slider_geometry_detail->setCurrentValue( pVideo->geometry_detail );
  1318.     slider_geometry_detail->subscribeEvent( CEGUI::Slider::EventValueChanged, CEGUI::Event::Subscriber( &cMenu_Options_Video::Slider_Geometry_Detail_Changed, this ) );
  1319.  
  1320.     // Texture detail
  1321.     CEGUI::Slider *slider_texture_detail = static_cast<CEGUI::Slider *>(CEGUI::WindowManager::getSingleton().getWindow( "slider_texture_detail" ));
  1322.     slider_texture_detail->setCurrentValue( pVideo->texture_detail );
  1323.     slider_texture_detail->subscribeEvent( CEGUI::Slider::EventValueChanged, CEGUI::Event::Subscriber( &cMenu_Options_Video::Slider_Texture_Detail_Changed, this ) );
  1324.  
  1325.  
  1326.     // Apply
  1327.     CEGUI::PushButton *button_apply = static_cast<CEGUI::PushButton *>(CEGUI::WindowManager::getSingleton().getWindow( "button_apply" ));
  1328.     button_apply->subscribeEvent( CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber( &cMenu_Options_Video::Button_Apply_Clicked, this ) );
  1329.  
  1330.     // Recreate Cache
  1331.     CEGUI::PushButton *button_recreate_cache = static_cast<CEGUI::PushButton *>(CEGUI::WindowManager::getSingleton().getWindow( "button_recreate_cache" ));
  1332.     button_recreate_cache->subscribeEvent( CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber( &cMenu_Options_Video::Button_Recreate_Cache_Clicked, this ) );
  1333. }
  1334.  
  1335. void cMenu_Options_Video :: Update( void )
  1336. {
  1337.     cMenu_Options::Update();
  1338.  
  1339.     if( !action )
  1340.     {
  1341.         return;
  1342.     }
  1343.  
  1344.     cMenu_Options::Update();
  1345.  
  1346.     // only video actions
  1347.     if( pMenuCore->handler->active <= 4 )
  1348.     {
  1349.         return;
  1350.     }
  1351.  
  1352.     action = 0;
  1353.  
  1354.     // Resolution
  1355.     if( pMenuCore->handler->active == 5 )
  1356.     {
  1357.         // Resolution
  1358.         CEGUI::Combobox *combo_resolution = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_resolution" ));
  1359.         unsigned int selected = combo_resolution->getItemIndex( combo_resolution->findItemWithText( combo_resolution->getText(), NULL ) );
  1360.  
  1361.         CEGUI::ListboxItem *new_selected = NULL;
  1362.  
  1363.         // last item selected
  1364.         if( selected == combo_resolution->getItemCount() - 1 )
  1365.         {
  1366.             new_selected = combo_resolution->getListboxItemFromIndex( 0 );
  1367.         }
  1368.         // select next item
  1369.         else
  1370.         {
  1371.             new_selected = combo_resolution->getListboxItemFromIndex( selected + 1 );
  1372.         }
  1373.         
  1374.         combo_resolution->setText( new_selected->getText() );
  1375.         combo_resolution->setItemSelectState( new_selected, 1 );
  1376.         Res_Select( CEGUI::WindowEventArgs( combo_resolution ) );
  1377.     }
  1378.     // BPP
  1379.     else if( pMenuCore->handler->active == 6 )
  1380.     {
  1381.         if( vid_bpp == 16 )
  1382.         {
  1383.             vid_bpp = 32;
  1384.         }
  1385.         else if( vid_bpp == 32 )
  1386.         {
  1387.             vid_bpp = 16;
  1388.         }
  1389.  
  1390.         CEGUI::WindowManager::getSingleton().getWindow( "combo_bpp" )->setText( int_to_string( vid_bpp ).c_str() );    
  1391.     }
  1392.     // Fullscreen
  1393.     else if( pMenuCore->handler->active == 7 )
  1394.     {
  1395.         vid_fullscreen = !vid_fullscreen;
  1396.  
  1397.         if( vid_fullscreen )
  1398.         {
  1399.             CEGUI::WindowManager::getSingleton().getWindow( "combo_fullscreen" )->setText( UTF8_("On") );    
  1400.         }
  1401.         else
  1402.         {
  1403.             CEGUI::WindowManager::getSingleton().getWindow( "combo_fullscreen" )->setText( UTF8_("Off") );
  1404.         }
  1405.     }
  1406.     // VSync
  1407.     else if( pMenuCore->handler->active == 8 )
  1408.     {
  1409.         vid_vsync = !vid_vsync;
  1410.  
  1411.         if( vid_vsync )
  1412.         {
  1413.             CEGUI::WindowManager::getSingleton().getWindow( "combo_vsync" )->setText( UTF8_("On") );    
  1414.         }
  1415.         else
  1416.         {
  1417.             CEGUI::WindowManager::getSingleton().getWindow( "combo_vsync" )->setText( UTF8_("Off") );
  1418.         }
  1419.     }
  1420. }
  1421.  
  1422. void cMenu_Options_Video :: Draw( void )
  1423. {
  1424.     cMenu_Options::Draw();
  1425.  
  1426.     Draw_End();
  1427. }
  1428.  
  1429. bool cMenu_Options_Video :: Res_Select( const CEGUI::EventArgs &event )
  1430. {
  1431.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1432.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox *>( windowEventArgs.window )->getSelectedItem();
  1433.  
  1434.     std::string temp = item->getText().c_str();
  1435.  
  1436.     // get end of height value if text is after resolution string
  1437.     std::string::size_type height_end = temp.find( " " );
  1438.  
  1439.     if( height_end == std::string::npos )
  1440.     {
  1441.         height_end = temp.length();
  1442.     }
  1443.  
  1444.     // get resolution
  1445.     unsigned int w = string_to_int( temp.substr( 0, temp.find( "x" ) ) );
  1446.     unsigned int h = string_to_int( temp.substr( temp.find( "x" ) + 1, height_end ) );
  1447.  
  1448.     // is it supported
  1449.     if( !pVideo->Test_Video( w, h, vid_bpp ) )
  1450.     {
  1451.         return 0;
  1452.     }
  1453.  
  1454.     // set new selected resolution
  1455.     vid_w = w;
  1456.     vid_h = h;
  1457.  
  1458.     return 1;
  1459. }
  1460.  
  1461. bool cMenu_Options_Video :: Bpp_Select( const CEGUI::EventArgs &event )
  1462. {
  1463.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1464.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox *>( windowEventArgs.window )->getSelectedItem();
  1465.  
  1466.     unsigned int bpp = string_to_int( item->getText().c_str() );
  1467.  
  1468.     if( !pVideo->Test_Video( vid_w, vid_h, bpp ) )
  1469.     {
  1470.         return 0;
  1471.     }
  1472.  
  1473.     vid_bpp = bpp;
  1474.  
  1475.     return 1;
  1476. }
  1477.  
  1478. bool cMenu_Options_Video :: Fullscreen_Select( const CEGUI::EventArgs &event )
  1479. {
  1480.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1481.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox *>( windowEventArgs.window )->getSelectedItem();
  1482.  
  1483.     bool bfullscreen = 0;
  1484.  
  1485.     if( item->getText().compare( UTF8_("On") ) == 0 )
  1486.     {
  1487.         bfullscreen = 1;
  1488.     }
  1489.  
  1490.     vid_fullscreen = bfullscreen;
  1491.  
  1492.     return 1;
  1493. }
  1494.  
  1495. bool cMenu_Options_Video :: Vsync_Select( const CEGUI::EventArgs &event )
  1496. {
  1497.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1498.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox *>( windowEventArgs.window )->getSelectedItem();
  1499.  
  1500.     bool bvsync = 0;
  1501.  
  1502.     if( item->getText().compare( UTF8_("On") ) == 0 )
  1503.     {
  1504.         bvsync = 1;
  1505.     }
  1506.  
  1507.     vid_vsync = bvsync;
  1508.  
  1509.     return 1;
  1510. }
  1511.  
  1512. bool cMenu_Options_Video :: Slider_Geometry_Detail_Changed( const CEGUI::EventArgs &event )
  1513. {
  1514.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1515.     // set new value
  1516.     vid_geometry_detail = static_cast<CEGUI::Slider *>( windowEventArgs.window )->getCurrentValue();
  1517.  
  1518.     return 1;
  1519. }
  1520.  
  1521. bool cMenu_Options_Video :: Slider_Texture_Detail_Changed( const CEGUI::EventArgs &event )
  1522. {
  1523.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1524.     // set new value
  1525.     vid_texture_detail = static_cast<CEGUI::Slider *>( windowEventArgs.window )->getCurrentValue();
  1526.  
  1527.     return 1;
  1528. }
  1529.  
  1530. bool cMenu_Options_Video :: Button_Apply_Clicked( const CEGUI::EventArgs &event )
  1531. {
  1532.     // draw reinitialization text
  1533.     Draw_Static_Text( _("Reinitialization"), &green, NULL, 0 );
  1534.  
  1535.     pGuiSystem->renderGUI();
  1536.     pRenderer->Render();
  1537.     SDL_GL_SwapBuffers();
  1538.  
  1539.     // apply new settings
  1540.     pPreferences->Apply_Video( vid_w, vid_h, vid_bpp, vid_fullscreen, vid_vsync, vid_geometry_detail, vid_texture_detail );
  1541.  
  1542.     // clear
  1543.     pMenuCore->next_menu = MENU_OPTIONS;
  1544.     Game_Action = GA_ENTER_MENU;
  1545.  
  1546.     return 1;
  1547. }
  1548.  
  1549. bool cMenu_Options_Video :: Button_Recreate_Cache_Clicked( const CEGUI::EventArgs &event )
  1550. {
  1551.     Loading_Screen_Init();
  1552.  
  1553.     // save textures for reloading from file
  1554.     pImage_Manager->Grab_Textures( 1, 1 );
  1555.  
  1556.     // recreate cache
  1557.     pVideo->Init_Image_Cache( 1, 1 );
  1558.  
  1559.     // restore textures
  1560.     pImage_Manager->Restore_Textures( 1 );
  1561.  
  1562.     Loading_Screen_Exit();
  1563.  
  1564.     return 1;
  1565. }
  1566.  
  1567. /* *** *** *** *** *** *** *** *** cMenu_Options_Audio *** *** *** *** *** *** *** *** *** */
  1568.  
  1569. cMenu_Options_Audio :: cMenu_Options_Audio( void )
  1570. : cMenu_Options()
  1571. {
  1572.  
  1573. }
  1574.  
  1575. cMenu_Options_Audio :: ~cMenu_Options_Audio( void )
  1576. {
  1577.  
  1578. }
  1579.  
  1580. void cMenu_Options_Audio :: Init( void )
  1581. {
  1582.     cMenu_Options::Init();
  1583.  
  1584.     layout_file = "menu_audio.layout";
  1585.  
  1586.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/audio.png" ), game_res_w * 0.5f, game_res_h * 0.1f ) );
  1587.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/items/audio.png" ), game_res_w * 0.4f, game_res_h * 0.1f ) );
  1588.     
  1589.     pMenuCore->handler->Set_Active( MENU_AUDIO );
  1590.  
  1591.     Init_GUI();
  1592. }
  1593.  
  1594. void cMenu_Options_Audio :: Init_GUI( void )
  1595. {
  1596.     cMenu_Options::Init_GUI();
  1597.  
  1598.     // Audio Hz
  1599.     CEGUI::Combobox *combo_audio_hz = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_audio_hz" ));
  1600.  
  1601.     CEGUI::ListboxTextItem *item = new CEGUI::ListboxTextItem( "22050", 0 );
  1602.     item->setTextColours( CEGUI::colour( 1, 0, 0 ) );
  1603.     combo_audio_hz->addItem( item );
  1604.     item = new CEGUI::ListboxTextItem( "44100", 1 );
  1605.     item->setTextColours( CEGUI::colour( 0, 1, 0 ) );
  1606.     combo_audio_hz->addItem( item );
  1607.     item = new CEGUI::ListboxTextItem( "44800", 2 );
  1608.     item->setTextColours( CEGUI::colour( 0, 0, 1 ) );
  1609.     combo_audio_hz->addItem( item );
  1610.  
  1611.     // Set current value
  1612.     combo_audio_hz->setText( int_to_string( pPreferences->audio_hz ) );
  1613.  
  1614.     combo_audio_hz->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cMenu_Options_Audio::Audio_Hz_Select, this ) );
  1615.  
  1616.  
  1617.     // Music
  1618.     CEGUI::Combobox *combo_music = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_music" ));
  1619.  
  1620.     item = new CEGUI::ListboxTextItem( UTF8_("On"), 0 );
  1621.     item->setTextColours( CEGUI::colour( 0, 1, 0 ) );
  1622.     combo_music->addItem( item );
  1623.     item = new CEGUI::ListboxTextItem( UTF8_("Off"), 1 );
  1624.     item->setTextColours( CEGUI::colour( 0, 0, 1 ) );
  1625.     combo_music->addItem( item );
  1626.  
  1627.     if( pAudio->music_enabled )
  1628.     {
  1629.         combo_music->setText( UTF8_("On") );
  1630.     }
  1631.     else
  1632.     {
  1633.         combo_music->setText( UTF8_("Off") );
  1634.     }
  1635.  
  1636.     combo_music->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cMenu_Options_Audio::Music_Select, this ) );
  1637.  
  1638.     // music volume slider
  1639.     CEGUI::Slider *slider_music = static_cast<CEGUI::Slider *>(CEGUI::WindowManager::getSingleton().getWindow( "slider_music_volume" ));
  1640.     slider_music->setCurrentValue( static_cast<float>(pAudio->music_volume) );
  1641.     slider_music->subscribeEvent( CEGUI::Slider::EventValueChanged, CEGUI::Event::Subscriber( &cMenu_Options_Audio::Music_Vol_Changed, this ) );
  1642.     
  1643.  
  1644.     // Sounds
  1645.     CEGUI::Combobox *combo_sounds = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_sounds" ));
  1646.  
  1647.     item = new CEGUI::ListboxTextItem( UTF8_("On"), 0 );
  1648.     item->setTextColours( CEGUI::colour( 0, 1, 0 ) );
  1649.     combo_sounds->addItem( item );
  1650.     item = new CEGUI::ListboxTextItem( UTF8_("Off"), 1 );
  1651.     item->setTextColours( CEGUI::colour( 1, 0.6f, 0.3f ) );
  1652.     combo_sounds->addItem( item );
  1653.  
  1654.     if( pAudio->sound_enabled )
  1655.     {
  1656.         combo_sounds->setText( UTF8_("On") );
  1657.     }
  1658.     else
  1659.     {
  1660.         combo_sounds->setText( UTF8_("Off") );
  1661.     }
  1662.  
  1663.     combo_sounds->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cMenu_Options_Audio::Sound_Select, this ) );
  1664.  
  1665.     // sound volume slider
  1666.     CEGUI::Slider *slider_sound = static_cast<CEGUI::Slider *>(CEGUI::WindowManager::getSingleton().getWindow( "slider_sound_volume" ));
  1667.     slider_sound->setCurrentValue( static_cast<float>(pAudio->sound_volume) );
  1668.     slider_sound->subscribeEvent( CEGUI::Slider::EventValueChanged, CEGUI::Event::Subscriber( &cMenu_Options_Audio::Sound_Vol_Changed, this ) );
  1669. }
  1670.  
  1671. void cMenu_Options_Audio :: Update( void )
  1672. {
  1673.     cMenu_Options::Update();
  1674.  
  1675.     if( !action )
  1676.     {
  1677.         return;
  1678.     }
  1679.  
  1680.     cMenu_Options::Update();
  1681.  
  1682.     // only audio actions
  1683.     if( pMenuCore->handler->active <= 4 )
  1684.     {
  1685.         return;
  1686.     }
  1687.  
  1688.     action = 0;
  1689.  
  1690.     // Hz
  1691.     if( pMenuCore->handler->active == 5 )
  1692.     {
  1693.         CEGUI::Combobox *combo_hz = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_audio_hz" ));
  1694.         unsigned int selected = combo_hz->getItemIndex( combo_hz->findItemWithText( combo_hz->getText(), NULL ) );
  1695.  
  1696.         CEGUI::ListboxItem *new_selected = NULL;
  1697.  
  1698.         // last item selected
  1699.         if( selected == combo_hz->getItemCount() - 1 )
  1700.         {
  1701.             new_selected = combo_hz->getListboxItemFromIndex( 0 );
  1702.         }
  1703.         // select next item
  1704.         else
  1705.         {
  1706.             new_selected = combo_hz->getListboxItemFromIndex( selected + 1 );
  1707.         }
  1708.         
  1709.         combo_hz->setText( new_selected->getText() );
  1710.         combo_hz->setItemSelectState( new_selected, 1 );
  1711.         Audio_Hz_Select( CEGUI::WindowEventArgs( combo_hz ) );
  1712.     }
  1713.     // Music
  1714.     else if( pMenuCore->handler->active == 6 )
  1715.     {
  1716.         pAudio->Toggle_Music();
  1717.  
  1718.         if( pAudio->music_enabled )
  1719.         {
  1720.             CEGUI::WindowManager::getSingleton().getWindow( "combo_music" )->setText( UTF8_("On") );
  1721.         }
  1722.         else
  1723.         {
  1724.             CEGUI::WindowManager::getSingleton().getWindow( "combo_music" )->setText( UTF8_("Off") );
  1725.         }
  1726.     }
  1727.     // Sounds
  1728.     else if( pMenuCore->handler->active == 7 )
  1729.     {
  1730.         pAudio->Toggle_Sounds();
  1731.  
  1732.         if( pAudio->sound_enabled )
  1733.         {
  1734.             CEGUI::WindowManager::getSingleton().getWindow( "combo_sounds" )->setText( UTF8_("On") );
  1735.         }
  1736.         else
  1737.         {
  1738.             CEGUI::WindowManager::getSingleton().getWindow( "combo_sounds" )->setText( UTF8_("Off") );
  1739.         }
  1740.     }
  1741. }
  1742.  
  1743. void cMenu_Options_Audio :: Draw( void )
  1744. {
  1745.     cMenu_Options::Draw();
  1746.  
  1747.     Draw_End();
  1748. }
  1749.  
  1750. bool cMenu_Options_Audio :: Audio_Hz_Select( const CEGUI::EventArgs &event )
  1751. {
  1752.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1753.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox *>( windowEventArgs.window )->getSelectedItem();
  1754.  
  1755.     pPreferences->audio_hz = string_to_int( item->getText().c_str() );
  1756.  
  1757.     // draw reloading text
  1758.     Draw_Static_Text( _("Reloading"), &green, NULL, 0 );
  1759.     // reload
  1760.     pAudio->Close();
  1761.     pSound_Manager->Delete_All();
  1762.     pAudio->Init();
  1763.     // todo : add sound manager function to reload sounds and music when needed
  1764.     Preload_Sounds();
  1765.  
  1766.     return 1;
  1767. }
  1768.  
  1769. bool cMenu_Options_Audio :: Music_Select( const CEGUI::EventArgs &event )
  1770. {
  1771.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1772.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox *>( windowEventArgs.window )->getSelectedItem();
  1773.  
  1774.     bool bmusic = 0;
  1775.  
  1776.     if( item->getText().compare( UTF8_("On") ) == 0 )
  1777.     {
  1778.         bmusic = 1;
  1779.     }
  1780.  
  1781.     if( pAudio->music_enabled != bmusic )
  1782.     {
  1783.         pAudio->Toggle_Music();
  1784.     }
  1785.  
  1786.     return 1;
  1787. }
  1788.  
  1789. bool cMenu_Options_Audio :: Music_Vol_Changed( const CEGUI::EventArgs &event )
  1790. {
  1791.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1792.     Uint8 val = static_cast<Uint8>(static_cast<CEGUI::Slider *>( windowEventArgs.window )->getCurrentValue());
  1793.  
  1794.     pAudio->Set_Music_Volume( val );
  1795.  
  1796.     return 1;
  1797. }
  1798.  
  1799. bool cMenu_Options_Audio :: Sound_Select( const CEGUI::EventArgs &event )
  1800. {
  1801.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1802.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox *>( windowEventArgs.window )->getSelectedItem();
  1803.  
  1804.     bool bsound = 0;
  1805.  
  1806.     if( item->getText().compare( UTF8_("On") ) == 0 )
  1807.     {
  1808.         bsound= 1;
  1809.     }
  1810.  
  1811.     if( pAudio->sound_enabled != bsound )
  1812.     {
  1813.         pAudio->Toggle_Sounds();
  1814.     }
  1815.  
  1816.     return 1;
  1817. }
  1818.  
  1819. bool cMenu_Options_Audio :: Sound_Vol_Changed( const CEGUI::EventArgs &event )
  1820. {
  1821.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  1822.     Uint8 val = static_cast<Uint8>(static_cast<CEGUI::Slider *>( windowEventArgs.window )->getCurrentValue());
  1823.  
  1824.     pAudio->Set_Sound_Volume( val );
  1825.  
  1826.     return 1;
  1827. }
  1828.  
  1829. /* *** *** *** *** *** *** *** *** cMenu_Options_Controls *** *** *** *** *** *** *** *** *** */
  1830.  
  1831. cMenu_Options_Controls :: cMenu_Options_Controls( void )
  1832. : cMenu_Options()
  1833. {
  1834.     // Keyboard
  1835.     gamepad = new cHudSprite();
  1836. }
  1837.  
  1838. cMenu_Options_Controls :: ~cMenu_Options_Controls( void )
  1839. {
  1840.     delete gamepad;
  1841. }
  1842.  
  1843. void cMenu_Options_Controls :: Init( void )
  1844. {
  1845.     cMenu_Options::Init();
  1846.  
  1847.     cMenu_Item *temp_item = NULL;
  1848.  
  1849.     layout_file = "menu_controls.layout";
  1850.     menu_posy = 220;
  1851.     
  1852.     // gamepad
  1853.     gamepad->Set_Image( pVideo->Get_Surface( "menu/items/gamepad.png" ), 1 );
  1854.     gamepad->Set_Pos( game_res_w * 0.7f, game_res_h * 0.1f );
  1855.  
  1856.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/controls.png" ), game_res_w * 0.5f, game_res_h * 0.1f ) );
  1857.     drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/items/controls.png" ), game_res_w * 0.4f, game_res_h * 0.1f ) );
  1858.  
  1859.     pMenuCore->handler->Set_Active( MENU_CONTROLS );
  1860.  
  1861.     Init_GUI();
  1862. }
  1863.  
  1864. void cMenu_Options_Controls :: Init_GUI( void )
  1865. {
  1866.     cMenu_Options::Init_GUI();
  1867.  
  1868.     // Keyboard listbox
  1869.     CEGUI::MultiColumnList *listbox_keyboard = static_cast<CEGUI::MultiColumnList *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_keyboard" ));
  1870.  
  1871.     listbox_keyboard->addColumn( _("Name"), 0, CEGUI::UDim( 0.47f, 0 ) );
  1872.     listbox_keyboard->addColumn( _("Key"), 1, CEGUI::UDim( 0.47f, 0 ) );
  1873.     Build_Shortcut_List();
  1874.  
  1875.     listbox_keyboard->subscribeEvent( CEGUI::MultiColumnList::EventMouseDoubleClick, CEGUI::Event::Subscriber( &cMenu_Options_Controls::Keyboard_List_Double_Click, this ) );
  1876.  
  1877.     // Keyboard scroll speed
  1878.     CEGUI::Slider *slider_scoll_speed = static_cast<CEGUI::Slider *>(CEGUI::WindowManager::getSingleton().getWindow( "slider_keyboard_scroll_speed" ));
  1879.     slider_scoll_speed->setCurrentValue( pPreferences->scroll_speed );
  1880.     slider_scoll_speed->subscribeEvent( CEGUI::Slider::EventValueChanged, CEGUI::Event::Subscriber( &cMenu_Options_Controls::Keyboard_Slider_Scroll_Speed_Changed, this ) );
  1881.  
  1882.     // Joystick name text
  1883.     CEGUI::Window *text_joystick_name = CEGUI::WindowManager::getSingleton().getWindow( "text_joystick_name" );
  1884.     text_joystick_name->subscribeEvent( CEGUI::Window::EventMouseClick, CEGUI::Event::Subscriber( &cMenu_Options_Controls::Joystick_Name_Click, this ) );
  1885.  
  1886.     // Joystick analog jump text
  1887.     CEGUI::Window *text_joystick_analog_jump = CEGUI::WindowManager::getSingleton().getWindow( "text_joystick_analog_jump" );
  1888.     text_joystick_analog_jump->subscribeEvent( CEGUI::Window::EventMouseClick, CEGUI::Event::Subscriber( &cMenu_Options_Controls::Joystick_Analog_Jump_Click, this ) );
  1889.  
  1890.     // Joystick enabled
  1891.     CEGUI::Combobox *combo_joy = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_joy" ));
  1892.  
  1893.     // Add None
  1894.     CEGUI::ListboxTextItem *item = new CEGUI::ListboxTextItem( UTF8_("None"), 0 );
  1895.     item->setTextColours( CEGUI::colour( 0, 0, 1 ) );
  1896.     combo_joy->addItem( item );
  1897.  
  1898.     // Add all Joy names
  1899.     vector<string> joy_names = pJoystick->Get_Names();
  1900.  
  1901.     for( unsigned int i = 0; i < joy_names.size(); i++ )
  1902.     {
  1903.         item = new CEGUI::ListboxTextItem( joy_names[i], 1 );
  1904.         item->setTextColours( CEGUI::colour( 0.3f, 1, 0.3f ) );
  1905.         combo_joy->addItem( item );
  1906.     }
  1907.  
  1908.     // Selected Item
  1909.     CEGUI::ListboxTextItem *selected_item = NULL;
  1910.  
  1911.     // Set current Joy name
  1912.     if( pPreferences->joy_enabled )
  1913.     {
  1914.         selected_item = static_cast<CEGUI::ListboxTextItem *>( combo_joy->findItemWithText( pJoystick->Get_Name(), NULL ) );
  1915.     }
  1916.     // disabled
  1917.     else
  1918.     {
  1919.         selected_item = static_cast<CEGUI::ListboxTextItem *>( combo_joy->getListboxItemFromIndex( 0 ) );
  1920.     }
  1921.     // set Item
  1922.     combo_joy->setText( selected_item->getText() );
  1923.  
  1924.     combo_joy->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cMenu_Options_Controls::Joystick_Name_Select, this ) );
  1925.  
  1926.     // Joystick analog jump
  1927.     CEGUI::Combobox *combo_joy_analog_jump = static_cast<CEGUI::Combobox *>(CEGUI::WindowManager::getSingleton().getWindow( "combo_joy_analog_jump" ));
  1928.  
  1929.     item = new CEGUI::ListboxTextItem( _("On"), 0 );
  1930.     item->setTextColours( CEGUI::colour( 0, 0, 1 ) );
  1931.     combo_joy_analog_jump->addItem( item );
  1932.     item = new CEGUI::ListboxTextItem( _("Off"), 1 );
  1933.     item->setTextColours( CEGUI::colour( 0, 1, 0 ) );
  1934.     combo_joy_analog_jump->addItem( item );
  1935.  
  1936.     if( pPreferences->joy_analog_jump )
  1937.     {
  1938.         combo_joy_analog_jump->setText( _("On") );
  1939.     }
  1940.     else
  1941.     {
  1942.         combo_joy_analog_jump->setText( _("Off") );
  1943.     }
  1944.  
  1945.     combo_joy_analog_jump->subscribeEvent( CEGUI::Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber( &cMenu_Options_Controls::Joystick_Analog_Jump_Select, this ) );
  1946.  
  1947.     // Joystick axis horizontal
  1948.     CEGUI::Spinner *spinner_joystick_axis_hor = static_cast<CEGUI::Spinner *>(CEGUI::WindowManager::getSingleton().getWindow( "spinner_joystick_axis_hor" ));
  1949.     spinner_joystick_axis_hor->setCurrentValue( static_cast<float>(pPreferences->joy_axis_hor) );
  1950.     spinner_joystick_axis_hor->subscribeEvent( CEGUI::Spinner::EventValueChanged, CEGUI::Event::Subscriber( &cMenu_Options_Controls::Joystick_Spinner_Axis_Hor_Changed, this ) );
  1951.  
  1952.     // Joystick axis vertical
  1953.     CEGUI::Spinner *spinner_joystick_axis_ver = static_cast<CEGUI::Spinner *>(CEGUI::WindowManager::getSingleton().getWindow( "spinner_joystick_axis_ver" ));
  1954.     spinner_joystick_axis_ver->setCurrentValue( static_cast<float>(pPreferences->joy_axis_ver) );
  1955.     spinner_joystick_axis_ver->subscribeEvent( CEGUI::Spinner::EventValueChanged, CEGUI::Event::Subscriber( &cMenu_Options_Controls::Joystick_Spinner_Axis_Ver_Changed, this ) );
  1956.  
  1957.     // Joystick listbox
  1958.     CEGUI::MultiColumnList *listbox_joystick = static_cast<CEGUI::MultiColumnList *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_joystick" ));
  1959.  
  1960.     listbox_joystick->addColumn( UTF8_("Name"), 0, CEGUI::UDim( 0.47f, 0 ) );
  1961.     listbox_joystick->addColumn( UTF8_("Button"), 1, CEGUI::UDim( 0.47f, 0 ) );
  1962.     Build_Shortcut_List( 1 );
  1963.  
  1964.     listbox_joystick->subscribeEvent( CEGUI::MultiColumnList::EventMouseDoubleClick, CEGUI::Event::Subscriber( &cMenu_Options_Controls::Joystick_List_Double_Click, this ) );
  1965. }
  1966.  
  1967. void cMenu_Options_Controls :: Update( void )
  1968. {
  1969.     cMenu_Options::Update();
  1970.  
  1971.     if( !action )
  1972.     {
  1973.         return;
  1974.     }
  1975.  
  1976.     cMenu_Options::Update();
  1977.  
  1978.     // Controls
  1979.     if( pMenuCore->handler->active <= 4 )
  1980.     {
  1981.         return;
  1982.     }
  1983.  
  1984.     action = 0;
  1985. }
  1986.  
  1987. void cMenu_Options_Controls :: Draw( void )
  1988. {
  1989.     cMenu_Options::Draw();
  1990.  
  1991.     if( pPreferences->joy_enabled )
  1992.     {
  1993.         gamepad->Draw();
  1994.     }
  1995.  
  1996.     Draw_End();
  1997. }
  1998.  
  1999. void cMenu_Options_Controls :: Build_Shortcut_List( bool joystick /* = 0 */ )
  2000. {
  2001.     // Get Listbox
  2002.     CEGUI::MultiColumnList *listbox = NULL;
  2003.  
  2004.     // Keyboard
  2005.     if( !joystick )
  2006.     {
  2007.         listbox = static_cast<CEGUI::MultiColumnList *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_keyboard" ));
  2008.     }
  2009.     // Joystick
  2010.     else
  2011.     {
  2012.         listbox = static_cast<CEGUI::MultiColumnList *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_joystick" ));
  2013.     }
  2014.  
  2015.     listbox->resetList();
  2016.  
  2017.     // build shortcut list
  2018.     vector<cShortcut_item> shortcuts;
  2019.  
  2020.     // only keyboard
  2021.     if( !joystick )
  2022.     {
  2023.         shortcuts.push_back( cShortcut_item( _("Up"), INP_UP ) );
  2024.         shortcuts.push_back( cShortcut_item( _("Down"), INP_DOWN ) );
  2025.         shortcuts.push_back( cShortcut_item( _("Left"), INP_LEFT ) );
  2026.         shortcuts.push_back( cShortcut_item( _("Right"), INP_RIGHT ) );
  2027.     }
  2028.  
  2029.     shortcuts.push_back( cShortcut_item( _("Jump"), INP_JUMP ) );
  2030.     shortcuts.push_back( cShortcut_item( _("Shoot"), INP_SHOOT ) );
  2031.     shortcuts.push_back( cShortcut_item( _("Action"), INP_ACTION ) );
  2032.  
  2033.     // only joystick
  2034.     if( joystick )
  2035.     {
  2036.         shortcuts.push_back( cShortcut_item( _("Item"), INP_ITEM ) );
  2037.         shortcuts.push_back( cShortcut_item( _("Exit"), INP_EXIT ) );
  2038.     }
  2039.  
  2040.     // add all available shortcuts
  2041.     for( vector<cShortcut_item>::iterator itr = shortcuts.begin(), itr_end = shortcuts.end(); itr != itr_end; ++itr )
  2042.     {
  2043.         cShortcut_item shortcut_item = (*itr);
  2044.         
  2045.         CEGUI::ListboxTextItem *item = new CEGUI::ListboxTextItem( shortcut_item.m_name, shortcut_item.m_id );
  2046.         //item->setTextColours( colour( 0.6f, 0.6f, 0.6f ) );
  2047.         item->setSelectionColours( CEGUI::colour( 0.33f, 0.33f, 0.33f ) );
  2048.         item->setSelectionBrushImage( "TaharezLook", "ListboxSelectionBrush" );
  2049.         unsigned int row_id = listbox->addRow( item, 0 );
  2050.  
  2051.         // Get shortcut key name
  2052.         string shortcut_key;
  2053.         // Keyboard
  2054.         if( !joystick )
  2055.         {
  2056.             SDLKey *key = pKeyboard->Get_Shortcut( shortcut_item.m_id );
  2057.             shortcut_key = SDL_GetKeyName( *key );
  2058.         }
  2059.         // Joystick
  2060.         else
  2061.         {
  2062.             Uint8 *button = pJoystick->Get_Shortcut( shortcut_item.m_id );
  2063.             shortcut_key = int_to_string( *button );
  2064.         }
  2065.  
  2066.         item = new CEGUI::ListboxTextItem( shortcut_key, 0 );
  2067.         //item->setTextColours( colour( 0.6f, 0.6f, 0.6f ) );
  2068.         item->setSelectionColours( CEGUI::colour( 0.33f, 0.33f, 0.33f ) );
  2069.         item->setSelectionBrushImage( "TaharezLook", "ListboxSelectionBrush" );
  2070.         listbox->setItem( item, 1, row_id );
  2071.     }
  2072. }
  2073.  
  2074. void cMenu_Options_Controls :: Set_Shortcut( string shortcut_name, input_identifier shortcut_id, bool joystick /* = 0 */ )
  2075. {
  2076.     string info_text;
  2077.  
  2078.     if( !joystick )
  2079.     {
  2080.         info_text += _("Press a key");
  2081.     }
  2082.     else
  2083.     {
  2084.         info_text += _("Press a button");
  2085.     }
  2086.  
  2087.     Draw_Static_Text( info_text + _(" for ") + shortcut_name + _(". Press ESC to cancel."), &orange, NULL, 0 );
  2088.  
  2089.     bool sub_done = 0;
  2090.  
  2091.     while( !sub_done )
  2092.     {
  2093.         // no event
  2094.         if( !SDL_PollEvent( &input_event ) )
  2095.         {
  2096.             continue;
  2097.         }
  2098.  
  2099.         if( input_event.key.keysym.sym == SDLK_ESCAPE || input_event.key.keysym.sym == SDLK_BACKSPACE )
  2100.         {
  2101.             sub_done = 1;
  2102.             break;
  2103.         }
  2104.  
  2105.         if( !joystick && input_event.type != SDL_KEYDOWN )
  2106.         {
  2107.             continue;
  2108.         }
  2109.         else if( joystick && input_event.type != SDL_JOYBUTTONDOWN )
  2110.         {
  2111.             continue;
  2112.         }
  2113.  
  2114.         // Keyboard
  2115.         if( !joystick )
  2116.         {
  2117.             pKeyboard->Assign_Shortcut( shortcut_id, input_event.key.keysym.sym );
  2118.         }
  2119.         // Joystick
  2120.         else
  2121.         {
  2122.             pJoystick->Assign_Shortcut( shortcut_id, input_event.jbutton.button );
  2123.         }
  2124.  
  2125.         sub_done = 1;
  2126.     }
  2127.  
  2128.     Build_Shortcut_List( joystick );
  2129. }
  2130.  
  2131. void cMenu_Options_Controls :: Joy_Default( unsigned int index )
  2132. {
  2133.     pPreferences->joy_enabled = 1;
  2134.     pPreferences->joy_name = SDL_JoystickName( index );
  2135.  
  2136.     // initialize and if no joystick available disable
  2137.     pJoystick->Init();
  2138. }
  2139.  
  2140. void cMenu_Options_Controls :: Joy_Disable( void )
  2141. {
  2142.     pPreferences->joy_enabled = 0;
  2143.     pPreferences->joy_name.clear();
  2144.  
  2145.     // close the joystick
  2146.     pJoystick->Stick_Close();
  2147. }
  2148.  
  2149. bool cMenu_Options_Controls :: Keyboard_List_Double_Click( const CEGUI::EventArgs &event )
  2150. {
  2151.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  2152.     CEGUI::ListboxItem *item = static_cast<CEGUI::MultiColumnList *>( windowEventArgs.window )->getFirstSelectedItem();
  2153.  
  2154.     // set shortcut
  2155.     if( item )
  2156.     {
  2157.         Set_Shortcut( item->getText().c_str(), static_cast<input_identifier>(item->getID()) );
  2158.     }
  2159.  
  2160.     return 1;
  2161. }
  2162.  
  2163. bool cMenu_Options_Controls :: Keyboard_Slider_Scroll_Speed_Changed( const CEGUI::EventArgs &event )
  2164. {
  2165.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  2166.     // set new value
  2167.     pPreferences->scroll_speed = static_cast<CEGUI::Slider *>( windowEventArgs.window )->getCurrentValue();
  2168.  
  2169.     return 1;
  2170. }
  2171.  
  2172. bool cMenu_Options_Controls :: Joystick_Name_Click( const CEGUI::EventArgs &event )
  2173. {
  2174.     // Get Joystick Combo
  2175.     CEGUI::Combobox *combo_joy = static_cast<CEGUI::Combobox *>( CEGUI::WindowManager::getSingleton().getWindow( "combo_joy" ) );
  2176.     
  2177.     // selected item id
  2178.     int selected_item = 0;
  2179.     // current list item
  2180.     CEGUI::ListboxTextItem *list_item = static_cast<CEGUI::ListboxTextItem *>( combo_joy->findItemWithText( combo_joy->getText(), NULL ) );
  2181.  
  2182.     // if selected
  2183.     if( list_item )
  2184.     {
  2185.         selected_item = combo_joy->getItemIndex( list_item );
  2186.     }
  2187.  
  2188.     // select first
  2189.     if( selected_item >= SDL_NumJoysticks() )
  2190.     {
  2191.         selected_item = 0;
  2192.     }
  2193.     // select next item
  2194.     else
  2195.     {
  2196.         selected_item++;
  2197.     }
  2198.  
  2199.     // Disable Joy
  2200.     if( selected_item == 0 )
  2201.     {
  2202.         Joy_Disable();
  2203.     }
  2204.     // Select Joy
  2205.     else
  2206.     {
  2207.         Joy_Default( selected_item - 1 );
  2208.     }
  2209.  
  2210.     // check if initialization succeeded
  2211.     if( selected_item )
  2212.     {
  2213.         // initialised
  2214.         if( pPreferences->joy_enabled )
  2215.         {
  2216.             Draw_Static_Text( _("Enabled : ") + pJoystick->Get_Name(), &yellow );
  2217.         }
  2218.         // failed
  2219.         else
  2220.         {
  2221.             selected_item = 0;
  2222.         }
  2223.     }
  2224.  
  2225.     combo_joy->setText( combo_joy->getListboxItemFromIndex( selected_item )->getText() );
  2226.  
  2227.     return 1;
  2228. }
  2229.  
  2230. bool cMenu_Options_Controls :: Joystick_Analog_Jump_Click( const CEGUI::EventArgs &event )
  2231. {
  2232.     pPreferences->joy_analog_jump = !pPreferences->joy_analog_jump;
  2233.  
  2234.     if( pPreferences->joy_analog_jump )
  2235.     {
  2236.         CEGUI::WindowManager::getSingleton().getWindow( "combo_joy_analog_jump" )->setText( _("On") );
  2237.     }
  2238.     else
  2239.     {
  2240.         CEGUI::WindowManager::getSingleton().getWindow( "combo_joy_analog_jump" )->setText( _("Off") );
  2241.     }
  2242.  
  2243.     return 1;
  2244. }
  2245.  
  2246. bool cMenu_Options_Controls :: Joystick_Name_Select( const CEGUI::EventArgs &event )
  2247. {
  2248.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  2249.     CEGUI::Combobox *combo = static_cast<CEGUI::Combobox*>( windowEventArgs.window );
  2250.     CEGUI::ListboxItem *item = combo->getSelectedItem();
  2251.  
  2252.     if( item->getText().compare( _("None") ) == 0 )
  2253.     {
  2254.         Joy_Disable();
  2255.     }
  2256.     else
  2257.     {
  2258.         Joy_Default( combo->getItemIndex( item ) - 1 );
  2259.     }
  2260.  
  2261.     return 1;
  2262. }
  2263.  
  2264. bool cMenu_Options_Controls :: Joystick_Analog_Jump_Select( const CEGUI::EventArgs &event )
  2265. {
  2266.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  2267.     CEGUI::ListboxItem *item = static_cast<CEGUI::Combobox*>( windowEventArgs.window )->getSelectedItem();
  2268.  
  2269.     bool analog_jump = 0;
  2270.  
  2271.     if( item->getText().compare( _("On") ) == 0 )
  2272.     {
  2273.         analog_jump = 1;
  2274.     }
  2275.  
  2276.     pPreferences->joy_analog_jump = analog_jump;
  2277.  
  2278.     return 1;
  2279. }
  2280.  
  2281. bool cMenu_Options_Controls :: Joystick_Spinner_Axis_Hor_Changed( const CEGUI::EventArgs &event )
  2282. {
  2283.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  2284.     // set new value
  2285.     pPreferences->joy_axis_hor = static_cast<int>(static_cast<CEGUI::Spinner *>( windowEventArgs.window )->getCurrentValue());
  2286.  
  2287.     return 1;
  2288. }
  2289.  
  2290. bool cMenu_Options_Controls :: Joystick_Spinner_Axis_Ver_Changed( const CEGUI::EventArgs &event )
  2291. {
  2292.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  2293.     // set new value
  2294.     pPreferences->joy_axis_ver = static_cast<int>(static_cast<CEGUI::Spinner *>( windowEventArgs.window )->getCurrentValue());
  2295.  
  2296.     return 1;
  2297. }
  2298.  
  2299. bool cMenu_Options_Controls :: Joystick_List_Double_Click( const CEGUI::EventArgs &event )
  2300. {
  2301.     const CEGUI::WindowEventArgs &windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>( event );
  2302.     CEGUI::ListboxItem *item = static_cast<CEGUI::MultiColumnList *>( windowEventArgs.window )->getFirstSelectedItem();
  2303.  
  2304.     // set shortcut
  2305.     if( item )
  2306.     {
  2307.         Set_Shortcut( item->getText().c_str(), static_cast<input_identifier>(item->getID()), 1 );
  2308.     }
  2309.  
  2310.     return 1;
  2311. }
  2312.  
  2313. /* *** *** *** *** *** *** *** *** cMenu_Savegames *** *** *** *** *** *** *** *** *** */
  2314.  
  2315. cMenu_Savegames :: cMenu_Savegames( bool ntype_save )
  2316. : cMenu_Base()
  2317. {
  2318.     type_save = ntype_save;
  2319.  
  2320.     for( unsigned int i = 0; i < 9; i++ )
  2321.     {
  2322.         savegame_temp.push_back( new cHudSprite() );
  2323.     }
  2324. }
  2325.  
  2326. cMenu_Savegames :: ~cMenu_Savegames( void )
  2327. {
  2328.     for( HudSpriteList::iterator itr = savegame_temp.begin(), itr_end = savegame_temp.end(); itr != itr_end; ++itr )
  2329.     {
  2330.         delete *itr;
  2331.     }
  2332.  
  2333.     savegame_temp.clear();
  2334. }
  2335.  
  2336. void cMenu_Savegames :: Init( void )
  2337. {
  2338.     cMenu_Base::Init();
  2339.  
  2340.     cMenu_Item *temp_item = NULL;
  2341.  
  2342.     GL_Surface *back1 = pFont->Render_Text( pFont->font_normal, _("Back"), text_color );
  2343.  
  2344.     Update_Saved_Games_Text();
  2345.  
  2346.     // savegame descriptions
  2347.     for( HudSpriteList::iterator itr = savegame_temp.begin(), itr_end = savegame_temp.end(); itr != itr_end; ++itr )
  2348.     {
  2349.         temp_item = new cMenu_Item();
  2350.         temp_item->image_default->Set_Image( (*itr)->image );
  2351.         temp_item->Set_Pos( static_cast<float>(game_res_w) / 5, menu_posy );
  2352.         pMenuCore->handler->Add_Menu_Item( temp_item, 1.5f, grey );
  2353.         
  2354.         menu_posy += temp_item->image_default->col_rect.h;
  2355.     }
  2356.  
  2357.     // back
  2358.     temp_item = new cMenu_Item();
  2359.     temp_item->image_default->Set_Image( back1 );
  2360.     temp_item->Set_Pos( static_cast<float>(game_res_w) / 18, 450 );
  2361.     temp_item->isquit = 1;
  2362.     pMenuCore->handler->Add_Menu_Item( temp_item, 1.5f, grey );
  2363.  
  2364.     if( type_save )
  2365.     {
  2366.         drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/save.png" ), game_res_w * 0.5f, game_res_h * 0.1f ) );
  2367.         drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/items/save.png" ), game_res_w * 0.07f, game_res_h * 0.24f ) );
  2368.     }
  2369.     else
  2370.     {
  2371.         drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/load.png" ), game_res_w * 0.5f, game_res_h * 0.1f ) );
  2372.         drawlist.push_back( new cHudSprite( pVideo->Get_Surface( "menu/items/load.png" ), game_res_w * 0.07f, game_res_h * 0.24f ) );
  2373.     }
  2374.     drawlist.push_back( new cHudSprite( back1, -200, 0, 1 ) );
  2375.  
  2376.     Init_GUI();
  2377. }
  2378.  
  2379. void cMenu_Savegames :: Init_GUI( void )
  2380. {
  2381.     cMenu_Base::Init_GUI();
  2382. }
  2383.  
  2384. void cMenu_Savegames :: Update( void )
  2385. {
  2386.     cMenu_Base::Update();
  2387.  
  2388.     if( !action )
  2389.     {
  2390.         return;
  2391.     }
  2392.  
  2393.     action = 0;
  2394.  
  2395.     // back
  2396.     if( pMenuCore->handler->active == 9 )
  2397.     {
  2398.         Exit();
  2399.         return;
  2400.     }
  2401.  
  2402.     if( !type_save )
  2403.     {
  2404.         Update_Load();
  2405.     }
  2406.     else
  2407.     {
  2408.         Update_Save();
  2409.     }
  2410. }
  2411.  
  2412. void cMenu_Savegames :: Draw( void )
  2413. {
  2414.     cMenu_Base::Draw();
  2415.     Draw_End();
  2416. }
  2417.  
  2418. void cMenu_Savegames :: Exit( void )
  2419. {
  2420.     pMenuCore->next_menu = MENU_MAIN;
  2421.     Game_Action = GA_ENTER_MENU;
  2422. }
  2423.  
  2424. void cMenu_Savegames :: Update_Load( void )
  2425. {
  2426.     // savegame
  2427.     if( pSavegame->Is_Valid( pMenuCore->handler->active + 1 ) )
  2428.     {
  2429.         pAudio->Fadeout_Music( 1000 );
  2430.         pAudio->Play_Sound( "savegame_load.ogg" );
  2431.  
  2432.         int save_type = pSavegame->Load_Game( pMenuCore->handler->active + 1 );
  2433.  
  2434.         // Level save
  2435.         if( save_type == 1 )
  2436.         {
  2437.             Game_Action = GA_ENTER_LEVEL;
  2438.         }
  2439.         // World save
  2440.         else if( save_type == 2 )
  2441.         {
  2442.             Game_Action = GA_ENTER_WORLD;
  2443.         }
  2444.     }
  2445. }
  2446.  
  2447. void cMenu_Savegames :: Update_Save( void )
  2448. {
  2449.     // savegame
  2450.     if( pOverworld_Player->current_waypoint >= 0 || pActive_Level->Is_Loaded() )
  2451.     {
  2452.         string descripion = Set_Save_Description( pMenuCore->handler->active + 1 );
  2453.         
  2454.         pFramerate->Reset();
  2455.  
  2456.         if( descripion.compare( "Not enough Points" ) == 0 ) 
  2457.         {
  2458.             Game_Action = GA_ENTER_MENU;
  2459.             pMenuCore->next_menu = MENU_MAIN;
  2460.             return;
  2461.         }
  2462.  
  2463.         if( descripion.empty() )
  2464.         {
  2465.             return;
  2466.         }
  2467.  
  2468.         pAudio->Play_Sound( "savegame_save.ogg" );
  2469.  
  2470.         // no costs in debug builds
  2471. #ifndef _DEBUG
  2472.         if( pActive_Level->Is_Loaded() )
  2473.         {
  2474.             pointsdisplay->Set_Points( pPlayer->points - 3000 );
  2475.         }
  2476. #endif
  2477.         // save
  2478.         pSavegame->Save_Game( pMenuCore->handler->active + 1, descripion );
  2479.  
  2480.         Game_Action = GA_ENTER_MENU;
  2481.         pMenuCore->next_menu = MENU_MAIN;
  2482.     }
  2483. }
  2484. string cMenu_Savegames :: Set_Save_Description( unsigned int save_slot )
  2485. {
  2486.     if( save_slot == 0 || save_slot > 9 )
  2487.     {
  2488.         return "";
  2489.     }
  2490. // save always in debug builds
  2491. #ifndef _DEBUG
  2492.     if( pActive_Level->Is_Loaded() && pPlayer->points < 3000 )
  2493.     {
  2494.         Clear_Input_Events();
  2495.         Draw_Static_Text( _("3000 Points needed for saving in a level.\nSaving on the Overworld is free.") );
  2496.  
  2497.         return "Not enough Points";
  2498.     }
  2499. #endif
  2500.     string save_description;
  2501.  
  2502.     bool auto_erase_description = 0;
  2503.  
  2504.     // if Savegame exists use old description
  2505.     if( pSavegame->Is_Valid( save_slot ) )
  2506.     {
  2507.         save_description.clear();
  2508.         // get only the description
  2509.         save_description = pSavegame->Get_Description( save_slot, 1 );
  2510.     }
  2511.     else
  2512.     {
  2513.         // use default description
  2514.         save_description = _("No Description");
  2515.         auto_erase_description = 1;
  2516.     }
  2517.  
  2518.     return Box_Text_Input( save_description, _("Enter Description"), auto_erase_description );
  2519. }
  2520.  
  2521. void cMenu_Savegames :: Update_Saved_Games_Text( void )
  2522. {
  2523.     unsigned int save_slot = 0;
  2524.  
  2525.     for( HudSpriteList::iterator itr = savegame_temp.begin(), itr_end = savegame_temp.end(); itr != itr_end; ++itr )
  2526.     {
  2527.         save_slot++;
  2528.         (*itr)->Set_Image( pFont->Render_Text( pFont->font_normal, pSavegame->Get_Description( save_slot ), text_color_value ), 1, 1 );
  2529.     }
  2530. }
  2531.  
  2532. /* *** *** *** *** *** *** *** *** cMenu_Credits *** *** *** *** *** *** *** *** *** */
  2533.  
  2534. cMenu_Credits :: cMenu_Credits( void )
  2535. : cMenu_Base()
  2536. {
  2537.  
  2538. }
  2539.  
  2540. cMenu_Credits :: ~cMenu_Credits( void )
  2541. {
  2542.  
  2543. }
  2544.  
  2545. void cMenu_Credits :: Init( void )
  2546. {
  2547.     pAudio->Play_Music( "land/hyper_1.ogg", -1, 1, 1500 );
  2548.  
  2549.     cMenu_Base::Init();
  2550.  
  2551.     pAudio->Fadeout_Music( 1500 );
  2552.  
  2553.     cMenu_Item *temp_item = NULL;
  2554.     menu_posy = game_res_h * 1.1f;
  2555.  
  2556.     // black background
  2557.     glClearColor( 0, 0, 0, 1 );
  2558.  
  2559.     // fade out
  2560.     for( float i = 0; i < 180; i += 4.5f * pFramerate->speedfactor )
  2561.     {
  2562.         // clear
  2563.         pVideo->Clear_Screen();
  2564.  
  2565.         // Draw    
  2566.         pMenuCore->handler->Draw();
  2567.         pMenuCore->pMenu_AnimManager->Draw();
  2568.  
  2569.         // create request
  2570.         cRectRequest *request = new cRectRequest();
  2571.         pVideo->Draw_Rect( NULL, 0.108f, &black, request );
  2572.         request->color.alpha = static_cast<Uint8>(i);
  2573.         request->color.green = 20;
  2574.         request->color.blue = 32;
  2575.         // add request
  2576.         pRenderer->Add( request );
  2577.  
  2578.         pVideo->Render();
  2579.  
  2580.         pFramerate->Update();
  2581.         // maximum fps
  2582.         Correct_Frame_Time( 100 );
  2583.  
  2584.         // set menu gradient colors
  2585.         pMenuCore->handler->color_start.alpha = 255 - static_cast<Uint8>(i);
  2586.         pMenuCore->handler->color_end.alpha = pMenuCore->handler->color_start.alpha;
  2587.     }
  2588.  
  2589.     GL_Surface *back1 = pFont->Render_Text( pFont->font_normal, _("Back"), text_color );
  2590.  
  2591.     // clear credits
  2592.     drawlist.clear();
  2593.  
  2594.     // add credits texts
  2595.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Florian Richter (FluXy)", white ), 0, 20, 1 ) );
  2596.     drawlist.back()->Set_Shadow( black, 1 );
  2597.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Dedicated Developer", white ), 0, -3, 1 ) );
  2598.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Organizer and Project Leader", white ), 0, -3, 1 ) );
  2599.  
  2600.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Holger Fey (Nemo)", white ), 0, 20, 1 ) );
  2601.     drawlist.back()->Set_Shadow( lila, 1 );
  2602.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Game Tester", white ), 0, -3, 1 ) );
  2603.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - German Publicity", white ), 0, -3, 1 ) );
  2604.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Torrent Packager", white ), 0, -3, 1 ) );
  2605.  
  2606.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Grant ... (youngheart80)", white ), 0, 20, 1 ) );
  2607.     drawlist.back()->Set_Shadow( green, 1 );
  2608.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Graphic Designer", white ), 0, -3, 1 ) );
  2609.  
  2610.     // Most Valued Persons (MVP)
  2611.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "-- Most Valued Persons (MVP) --", white ), 0, 20, 1 ) );
  2612.     drawlist.back()->Set_Shadow( lightgrey, 1 );
  2613.  
  2614.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "... (Helios)", white ), 0, 20, 1 ) );
  2615.     drawlist.back()->Set_Shadow( Color( 0.8f, 0.8f, 0.1f ), 1 );
  2616.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Graphic Designer", white ), 0, -3, 1 ) );
  2617.  
  2618.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Robert W... (BowserJr)", white ), 0, 20, 1 ) );
  2619.     drawlist.back()->Set_Shadow( lightgreen, 1 );
  2620.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Forum and Wiki Moderator", white ), 0, -3, 1 ) );
  2621.  
  2622.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "... (Sauer2)", white ), 0, 20, 1 ) );
  2623.     drawlist.back()->Set_Shadow( Color( 0.1f, 0.6f, 0.1f ), 1 );
  2624.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Level Contributor", white ), 0, -3, 1 ) );
  2625.  
  2626.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "... (Simpletoon)", white ), 0, 20, 1 ) );
  2627.     drawlist.back()->Set_Shadow( Color( 0.2f, 0.2f, 0.8f ), 1 );
  2628.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Developer", white ), 0, -3, 1 ) );
  2629.  
  2630.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Markus Hiebl (Frostbringer)", white ), 0, 20, 1 ) );
  2631.     drawlist.back()->Set_Shadow( Color( 0.9f, 0.1f, 0.8f ), 1 );
  2632.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Graphic Designer", white ), 0, -3, 1 ) );
  2633.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Level Contributor", white ), 0, -3, 1 ) );
  2634.  
  2635.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Tristan Heaven (nyhm)", white ), 0, 20, 1 ) );
  2636.     drawlist.back()->Set_Shadow( lightblue, 1 );
  2637.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Gentoo eBuild Maintainer", white ), 0, -3, 1 ) );
  2638.  
  2639.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Muammar El Khatib (muammar)", white ), 0, 20, 1 ) );
  2640.     drawlist.back()->Set_Shadow( lightred, 1 );
  2641.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Debian Package Maintainer", white ), 0, -3, 1 ) );
  2642.  
  2643.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "David Hernandez (vencabot_teppoo)", white ), 0, 20, 1 ) );
  2644.     drawlist.back()->Set_Shadow( Color( 0.8f, 0.6f, 0.2f ), 1 );
  2645.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Music Artist", white ), 0, -3, 1 ) );
  2646.  
  2647.     // Retired
  2648.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "-- Retired --", white ), 0, 20, 1 ) );
  2649.     drawlist.back()->Set_Shadow( lightgrey, 1 );
  2650.  
  2651.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Mark Richards (dteck)", white ), 0, 20, 1 ) );
  2652.     drawlist.back()->Set_Shadow( blue, 1 );
  2653.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Graphic Designer", white ), 0, -3, 1 ) );
  2654.  
  2655.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Mario Fink (maYO)", white ), 0, 20, 1 ) );
  2656.     drawlist.back()->Set_Shadow( blue, 1 );
  2657.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Graphic Designer", white ), 0, -3, 1 ) );
  2658.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Website Graphic Designer", white ), 0, -3, 1 ) );
  2659.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Other Support", white ), 0, -3, 1 ) );
  2660.  
  2661.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "... (Polilla86)", white ), 0, 20, 1 ) );
  2662.     drawlist.back()->Set_Shadow( Color( 0.7f, 0.1f, 0.2f ), 1 );
  2663.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Graphic Designer", white ), 0, -3, 1 ) );
  2664.  
  2665.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Ursula ... (Pipgirl)", white ), 0, 20, 1 ) );
  2666.     drawlist.back()->Set_Shadow( Color( 0.2f, 0.9f, 0.2f ), 1 );
  2667.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Graphic Designer", white ), 0, -3, 1 ) );
  2668.  
  2669.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Tobias Maasland (Weirdnose)", white ), 0, 20, 1 ) );
  2670.     drawlist.back()->Set_Shadow( Color( 0.9f, 0.7f, 0.2f ), 1 );
  2671.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Level and World Contributor", white ), 0, -3, 1 ) );
  2672.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Assistant Developer", white ), 0, -3, 1 ) );
  2673.  
  2674.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Robert ... (Consonance)", white ), 0, 20, 1 ) );
  2675.     drawlist.back()->Set_Shadow( lightred, 1 );
  2676.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Sound and Music Artist", white ), 0, -3, 1 ) );
  2677.  
  2678.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Justin ... (LoXodonte)", white ), 0, 20, 1 ) );
  2679.     drawlist.back()->Set_Shadow( lightblue, 1 );
  2680.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Music Artist", white ), 0, -3, 1 ) );
  2681.  
  2682.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Matt J... (mattwj)", white ), 0, 20, 1 ) );
  2683.     drawlist.back()->Set_Shadow( red, 1 );
  2684.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - eDonkey Packager", white ), 0, -3, 1 ) );
  2685.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Quality Assurance", white ), 0, -3, 1 ) );
  2686.  
  2687.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Bodhi Crandall-Rus (Boder)", white ), 0, 20, 1 ) );
  2688.     drawlist.back()->Set_Shadow( green, 1 );
  2689.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - All Hands Person", white ), 0, -3, 1 ) );
  2690.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Game Tester", white ), 0, -3, 1 ) );
  2691.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Assistant Graphic Designer", white ), 0, -3, 1 ) );
  2692.  
  2693.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "John Daly (Johnlein)", white ), 0, 20, 1 ) );
  2694.     drawlist.back()->Set_Shadow( yellow, 1 );
  2695.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Graphic Designer", white ), 0, -3, 1 ) );
  2696.  
  2697.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Gustavo Gutierrez (Enzakun)", white ), 0, 20, 1 ) );
  2698.     drawlist.back()->Set_Shadow( lightred, 1 );
  2699.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Maryo Graphic Designer", white ), 0, -3, 1 ) );
  2700.  
  2701.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Thomas Huth (Thothy)", white ), 0, 20, 1 ) );
  2702.     drawlist.back()->Set_Shadow( greenyellow, 1 );
  2703.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, " - Linux Maintainer", white ), 0, -3, 1 ) );
  2704.  
  2705.     // Thanks
  2706.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "-- Thanks --", white ), 0, 20, 1 ) );
  2707.     drawlist.back()->Set_Shadow( lightblue, 1 );
  2708.  
  2709.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Jason Cox (XOC)", white ), 0, 0, 1 ) );
  2710.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Ricardo Cruz", white ), 0, 0, 1 ) );
  2711.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Devendra (Yuki),", white ), 0, 0, 1 ) );
  2712.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Hans de Goede (Hans)", white ), 0, 0, 1 ) );
  2713.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "... (xPatrickx)", white ), 0, 0, 1 ) );
  2714.     drawlist.push_back( new cHudSprite( pFont->Render_Text( pFont->font_normal, "Rolando Gonzalez (rolosworld)", white ), 0, 0, 1 ) );
  2715.  
  2716.     // set credits position
  2717.     for( HudSpriteList::iterator itr = drawlist.begin(), itr_end = drawlist.end(); itr != itr_end; ++itr )
  2718.     {
  2719.         // get object
  2720.         cHudSprite *obj = (*itr);
  2721.  
  2722.         // set shadow if not set
  2723.         if( obj->shadow_pos == 0 )
  2724.         {
  2725.             obj->Set_Shadow( grey, 1 );
  2726.         }
  2727.         // set position
  2728.         obj->posx += game_res_w / 5;
  2729.         obj->posy += menu_posy;
  2730.         // set posz behind ground
  2731.         obj->posz = 0.109f;
  2732.         // set color combine
  2733.         obj->Set_Color_Combine( 0, 0, 0, GL_MODULATE );
  2734.         obj->color.alpha = 0;
  2735.         obj->shadow_color.alpha = 0;
  2736.  
  2737.         menu_posy = obj->posy + obj->col_rect.h;
  2738.     }
  2739.  
  2740.     // back
  2741.     temp_item = new cMenu_Item();
  2742.     temp_item->image_default->Set_Image( back1 );
  2743.     temp_item->Set_Pos( static_cast<float>(game_res_w) / 18, 250 );
  2744.     temp_item->isquit = 1;
  2745.     pMenuCore->handler->Add_Menu_Item( temp_item, 2, grey );
  2746.     
  2747.     drawlist.push_back( new cHudSprite( back1, -200, 0, 1 ) );
  2748.  
  2749.     Init_GUI();
  2750. }
  2751.  
  2752. void cMenu_Credits :: Init_GUI( void )
  2753. {
  2754.     cMenu_Base::Init_GUI();
  2755. }
  2756.  
  2757. void cMenu_Credits :: Update( void )
  2758. {
  2759.     cMenu_Base::Update();
  2760.  
  2761.     for( HudSpriteList::iterator itr = drawlist.begin(), itr_end = drawlist.end(); itr != itr_end; ++itr )
  2762.     {
  2763.         cHudSprite *obj = (*itr);
  2764.  
  2765.         // long inactive reset
  2766.         if( obj->posy < -2400 )
  2767.         {
  2768.             obj->Set_Pos_Y( static_cast<float>(game_res_h) * 1.1f );
  2769.         }
  2770.         // fading out
  2771.         else if( obj->posy < game_res_h * 0.3f )
  2772.         {
  2773.             float new_value = obj->combine_col[0] - ( pFramerate->speedfactor * 0.01f );
  2774.  
  2775.             if( new_value < 0 )
  2776.             {
  2777.                 new_value = 0;
  2778.             }
  2779.  
  2780.             obj->Set_Color_Combine( new_value, new_value, new_value, GL_MODULATE );
  2781.             obj->color.alpha = static_cast<Uint8>( new_value * 255 );
  2782.             obj->shadow_color.alpha = obj->color.alpha;
  2783.         }
  2784.         // fading in
  2785.         else if( obj->posy < game_res_h * 0.9f )
  2786.         {
  2787.             float new_value = obj->combine_col[0] + ( pFramerate->speedfactor * 0.01f );
  2788.  
  2789.             if( new_value > 1 )
  2790.             {
  2791.                 new_value = 1;
  2792.  
  2793.                 // add particles
  2794.                 if( obj->combine_col[0] < 1 )
  2795.                 {
  2796.                     cParticle_Emitter *anim = new cParticle_Emitter();
  2797.                     anim->Set_Pos( Get_Random_Float( game_res_w * 0.1f, game_res_w * 0.8f ), Get_Random_Float( game_res_h * 0.1f, game_res_h * 0.2f ) );
  2798.                     anim->Set_Quota( 5 + (rand() % 25) );
  2799.                     if( rand() % 2 )
  2800.                     {
  2801.                         anim->Set_Image( pVideo->Get_Surface( "animation/particles/snowflake_1.png" ) );
  2802.                         anim->Set_Direction_Range( Get_Random_Float( 30, 70 ), 80 );
  2803.                         anim->Set_Scale( 0.3f, 0.2f );
  2804.                         anim->Set_Blending( BLEND_ADD );
  2805.                     }
  2806.                     else
  2807.                     {
  2808.                         anim->Set_Image( pVideo->Get_Surface( "animation/particles/star.png" ) );
  2809.                         anim->Set_Direction_Range( 0, 360 );
  2810.                         anim->Set_Scale( 0.2f, 0.1f );
  2811.                     }
  2812.                     anim->Set_Time_to_Live( 1.4f, 0.5f );
  2813.                     anim->Set_Fading_Size( 1 );
  2814.                     anim->Set_Color( Color( static_cast<Uint8>( 100 + ( rand() % 155 ) ), 100 + ( rand() % 155 ), 100 + ( rand() % 155 ) ) );
  2815.                     anim->Set_Speed( 1.6f, 0.7f );
  2816.                     anim->Set_Const_Rotation_Z( -5, 10 );
  2817.                     anim->Set_Vertical_Gravity( 0.02f );
  2818.                     anim->Set_Pos_Z( 0.16f );
  2819.                     pMenuCore->pMenu_AnimManager->Add( anim );
  2820.                 }
  2821.             }
  2822.  
  2823.             obj->Set_Color_Combine( new_value, new_value, new_value, GL_MODULATE );
  2824.             obj->color.alpha = static_cast<Uint8>( new_value * 255 );
  2825.             obj->shadow_color.alpha = obj->color.alpha;
  2826.         }
  2827.  
  2828.         // default upwards scroll
  2829.         obj->Move( 0, -1.1f );
  2830.     }
  2831.  
  2832.     if( !action )
  2833.     {
  2834.         return;
  2835.     }
  2836.  
  2837.     action = 0;
  2838.  
  2839.     // back
  2840.     if( pMenuCore->handler->active == 0 )
  2841.     {
  2842.         Exit();
  2843.     }
  2844. }
  2845.  
  2846. void cMenu_Credits :: Draw( void )
  2847. {
  2848.     cMenu_Base::Draw();
  2849.  
  2850.     // darken background
  2851.     cRectRequest *request = new cRectRequest();
  2852.     pVideo->Draw_Rect( NULL, 0.108f, &black, request );
  2853.     request->color.green = 20;
  2854.     request->color.blue = 32;
  2855.     request->color.alpha = 180;
  2856.     pRenderer->Add( request );
  2857.  
  2858.     Draw_End();
  2859. }
  2860.  
  2861. void cMenu_Credits :: Exit( void )
  2862. {
  2863.     // stop credits music
  2864.     pAudio->Fadeout_Music();
  2865.     pAudio->Play_Music( "game/menu.ogg", -1, 0, 1500 );
  2866.  
  2867.     pMenuCore->next_menu = MENU_MAIN;
  2868.     Game_Action = GA_ENTER_MENU;
  2869. }
  2870.