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.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2008-06-20  |  14.6 KB  |  701 lines

  1. /***************************************************************************
  2.  * menu.cpp  -  menu handler
  3.  *
  4.  * Copyright (C) 2003 - 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.h"
  18. #include "../gui/menu_data.h"
  19. #include "../core/main.h"
  20. #include "../core/game_core.h"
  21. #include "../core/framerate.h"
  22. #include "../input/mouse.h"
  23. #include "../input/keyboard.h"
  24. #include "../audio/audio.h"
  25. #include "../player/player.h"
  26. #include "../core/camera.h"
  27. #include "../video/gl_surface.h"
  28. #include "../level/level.h"
  29. #include "../overworld/overworld.h"
  30. #include "../user/preferences.h"
  31.  
  32. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  33.  
  34. cMenu_Item :: cMenu_Item( void )
  35. : cHudSprite()
  36. {
  37.     Set_Scale_Directions( 1, 1, 1, 1 );
  38.     active = 0;
  39.     isquit = 0;
  40.  
  41.     image_default = new cHudSprite();
  42.     image_menu = new cHudSprite();
  43. }
  44.  
  45. cMenu_Item :: ~cMenu_Item( void )
  46. {
  47.     if( image_default )
  48.     {
  49.         delete image_default;
  50.     }
  51.  
  52.     if( image_menu )
  53.     {
  54.         delete image_menu;
  55.     }
  56. }
  57.  
  58. void cMenu_Item :: Set_Active( bool nactive /* = 0 */ )
  59. {
  60.     active = nactive;
  61.     rotz = 0;
  62.     Set_Scale( 1 );
  63.  
  64.     if( !nactive )
  65.     {
  66.         Set_Color_Combine( 0, 0, 0, 0 );
  67.     }
  68. }
  69.  
  70. void cMenu_Item :: Draw( cSurfaceRequest *request /* = NULL */ )
  71. {
  72.     if( active )
  73.     {
  74.         // rotation is used for the scale state
  75.         if( !rotz )
  76.         {
  77.             Add_Scale( ( 1.2f / image->w ) * pFramerate->speedfactor );
  78.         }
  79.         else
  80.         {
  81.             Add_Scale( -( 1.2f / image->w ) * pFramerate->speedfactor );
  82.         }
  83.  
  84.         if( image->w * scalex > image->w + 10 )
  85.         {
  86.             rotz = 0.0001f;
  87.         }
  88.         else if( scalex < 1 )
  89.         {
  90.             rotz = 0;
  91.         }
  92.     }
  93.  
  94.     cHudSprite::Draw( request );
  95.  
  96.     if( active )
  97.     {
  98.         float strength = image->w * ( scalex - 1 );
  99.  
  100.         // boost color to yellow
  101.         Set_Color_Combine( strength / 40, strength / 40, 0, GL_ADD );
  102.  
  103.         posx = startposx;
  104.         posy = startposy;
  105.  
  106.         image_menu->Draw();
  107.     }
  108. }
  109.  
  110. /* *** *** *** *** *** *** cMenuHandler *** *** *** *** *** *** *** *** *** *** *** */
  111.  
  112. cMenuHandler :: cMenuHandler( void )
  113. {
  114.     Reset();
  115.  
  116.     image_ground = pVideo->Get_Surface( "menu/ground.png" );
  117.  
  118.     // Logo Image
  119.     logo = new cHudSprite( pVideo->Get_Surface( "game/logo/lmario1.png" ), 50, 20 );
  120.     logo->posz = 0.16f;
  121.     // Ground Image
  122.     ground = new cHudSprite( image_ground, 0, 400 );
  123.     ground->posz = 0.11f;
  124.     // Moon Image
  125.     moon = new cHudSprite( pVideo->Get_Surface( "game/items/moon_1.png" ), 702, 39 );
  126.     moon->posz = 0.16f;
  127.     // Cloud Image
  128.     background = new cHudSprite( pVideo->Get_Surface( "game/background/blue_hills_1.png" ), 0, 88 );
  129.     background->posz = 0.09f;
  130. }
  131.  
  132. cMenuHandler :: ~cMenuHandler( void )
  133. {
  134.     Reset();
  135.  
  136.     delete logo;
  137.     delete ground;
  138.     delete moon;
  139.     delete background;
  140. }
  141.  
  142. void cMenuHandler :: Add_Menu_Item( cMenu_Item *item, float shadow_pos /* = 0 */, Color shadow_color /* = static_cast<Uint8>(0) */ )
  143. {
  144.     if( !item )
  145.     {
  146.         printf( "Menu item is NULL ( current Menu size : %d )\n", Get_Size() );
  147.         return;
  148.     }
  149.  
  150.     item->Set_Shadow_Pos( shadow_pos );
  151.     item->Set_Shadow_Color( shadow_color );
  152.     item->Set_Image( item->image_default->image );
  153.     items.push_back( item );
  154.  
  155.     if( active == -1 && Get_Size() == 1 )
  156.     {
  157.         Set_Active( 0 );
  158.     }
  159. }
  160.  
  161. void cMenuHandler :: Reset( void )
  162. {
  163.     for( MenuList::iterator itr = items.begin(), itr_end = items.end(); itr != itr_end; ++itr )
  164.     {
  165.         delete *itr;
  166.     }
  167.  
  168.     items.clear();
  169.  
  170.     // nothing is active
  171.     active = -1;
  172.     // disable quit logo
  173.     use_quit_image = 0;
  174.  
  175.     // Default Gradient Colors
  176.     color_start = Color( 0.7f, 0.93f, 1 );
  177.     color_end = Color( 0.26f, 0.8f, 1 );
  178. }
  179.  
  180. void cMenuHandler :: Set_Active( int num )
  181. {
  182.     // if not already active and exists
  183.     if( num == static_cast<int>(active) || num >= static_cast<int>(items.size()) || ( num >= 0 && !items[num] ) )
  184.     {
  185.         return;
  186.     }
  187.  
  188.     if( num >= 0 && static_cast<unsigned int>(num) < items.size() )
  189.     {
  190.         // set last active item un-active
  191.         if( active >= 0 && static_cast<unsigned int>(active) < items.size() )
  192.         {
  193.             items[active]->Set_Active( 0 );
  194.         }
  195.  
  196.         if( !items[num]->isquit )
  197.         {
  198.             ground->Set_Image( image_ground );
  199.         }
  200.         if( items[num]->isquit && use_quit_image )
  201.         {
  202.             // todo : not an image but a fade out ?
  203.         }
  204.     }
  205.     else if( num == -1 )
  206.     {
  207.         items[active]->Set_Active( 0 );
  208.     }
  209.  
  210.     active = num;
  211.  
  212.     if( active >= 0 )
  213.     {
  214.         items[active]->Set_Active( 1 );
  215.     }
  216. }
  217.  
  218. void cMenuHandler :: Use_Quit_Image( bool enabled /* = 1 */ )
  219. {
  220.     use_quit_image = enabled;
  221. }
  222.  
  223. void cMenuHandler :: Update_Mouse( void )
  224. {
  225.     int found = -1;
  226.  
  227.     // check
  228.     for( unsigned int i = 0; i < items.size(); i++ )
  229.     {
  230.         if( pMouseCursor->Collsion_Check( &items[i]->col_rect ) )
  231.         {
  232.             found = i;
  233.             break;
  234.         }
  235.     }
  236.  
  237.     // ignore mouse init
  238.     if( found < 0 && input_event.motion.x == pMouseCursor->x )
  239.     {
  240.         return;
  241.     }
  242.  
  243.     Set_Active( found );
  244. }
  245.  
  246. void cMenuHandler :: Draw( void )
  247. {
  248.     // Gradient
  249.     pVideo->Draw_Gradient( NULL, 0.08f, &color_start, &color_end, DIR_VERTICAL );
  250.  
  251.     // Logo Image
  252.     logo->Draw();
  253.     // Ground Image
  254.     ground->Draw();
  255.     // Moon Image
  256.     moon->Draw();
  257.     // Background Image
  258.     background->Draw();
  259.  
  260.     // menu items
  261.     for( MenuList::iterator itr = items.begin(), itr_end = items.end(); itr != itr_end; ++itr )
  262.     {
  263.         (*itr)->Draw();
  264.     }
  265. }
  266.  
  267. cMenu_Item *cMenuHandler :: Get_Active_Item( void )
  268. {
  269.     if( active < 0 || static_cast<unsigned int>(active) > items.size() )
  270.     {
  271.         return NULL;
  272.     }
  273.  
  274.     return items[active];
  275. }
  276.  
  277. unsigned int cMenuHandler :: Get_Size( void )
  278. {
  279.     return static_cast<unsigned int>(items.size());
  280. }
  281.  
  282. /* *** *** *** *** *** *** *** cMenuCore *** *** *** *** *** *** *** *** *** *** */
  283.  
  284. cMenuCore :: cMenuCore( void )
  285. {
  286.     menu_id = MENU_NOTHING;
  287.     next_menu = MENU_NOTHING;
  288.     options_menu_id = MENU_GAME;
  289.  
  290.     camera = new cCamera();
  291.     pMenu_Data = NULL;
  292.     handler = new cMenuHandler();
  293.  
  294.     // particle animation
  295.     pMenu_AnimManager = new cAnimation_Manager();
  296.  
  297.     // left side
  298.     cParticle_Emitter *anim = new cParticle_Emitter();
  299.     anim->Set_Emitter_Rect( -100, 0, 0, game_res_h * 0.5f );
  300.     anim->Set_Emitter_Time_to_Live( -1 );
  301.     anim->Set_Emitter_Iteration_Interval( 6 );
  302.     anim->Set_Direction_Range( 350, 20 );
  303.     anim->Set_Image( pVideo->Get_Surface( "clouds/default_1/1_middle.png" ) );
  304.     anim->Set_Time_to_Live( 400 );
  305.     anim->Set_Fading_Alpha( 0 );
  306.     anim->Set_Fading_Size( 1 );
  307.     anim->Set_Scale( 0.4f, 0.15f );
  308.     anim->Set_Color( Color( static_cast<Uint8>(220), 240, 255 ), Color( static_cast<Uint8>(25), 5, 0 ) );
  309.     anim->Set_Speed( 0.1f, 0.01f );
  310.     anim->Set_Pos_Z( 0.105f );
  311.  
  312.     pMenu_AnimManager->Add( anim );
  313.  
  314.     // right side
  315.     anim = new cParticle_Emitter();
  316.     anim->Set_Emitter_Rect( static_cast<float>(game_res_w) + 100, 0, 0, static_cast<float>(game_res_h) * 0.5f );
  317.     anim->Set_Emitter_Time_to_Live( -1 );
  318.     anim->Set_Emitter_Iteration_Interval( 6 );
  319.     anim->Set_Direction_Range( 170, 20 );
  320.     anim->Set_Image( pVideo->Get_Surface( "clouds/default_1/1_middle.png" ) );
  321.     anim->Set_Time_to_Live( 400 );
  322.     anim->Set_Fading_Alpha( 0 );
  323.     anim->Set_Fading_Size( 1 );
  324.     anim->Set_Scale( 0.4f, 0.15f );
  325.     anim->Set_Color( Color( static_cast<Uint8>(220), 240, 255 ), Color( static_cast<Uint8>(25), 5, 0 ) );
  326.     anim->Set_Speed( 0.1f, 0.01f );
  327.     anim->Set_Pos_Z( 0.105f );
  328.  
  329.     pMenu_AnimManager->Add( anim );
  330. }
  331.  
  332. cMenuCore :: ~cMenuCore( void )
  333. {
  334.     Unload();
  335.  
  336.     delete camera;
  337.     delete handler;
  338.     delete pMenu_AnimManager;
  339. }
  340.  
  341. bool cMenuCore :: Handle_Event( SDL_Event *ev )
  342. {
  343.     switch( ev->type )
  344.     {
  345.     case SDL_MOUSEMOTION:
  346.     {
  347.         handler->Update_Mouse();
  348.         break;
  349.     }
  350.     default: // other events
  351.     {
  352.         break;
  353.     }
  354.     }
  355.  
  356.     return 0;
  357. }
  358.  
  359. bool cMenuCore :: Key_Down( SDLKey key )
  360. {
  361.     // Down
  362.     if( key == SDLK_DOWN )
  363.     {
  364.         if( handler->Get_Size() <= static_cast<unsigned int>( handler->active + 1 ) )
  365.         {
  366.             handler->Set_Active( 0 );
  367.         }
  368.         else
  369.         {
  370.             handler->Set_Active( handler->active + 1 );
  371.         }
  372.     }
  373.     // Up
  374.     else if( key == SDLK_UP )
  375.     {
  376.         if( handler->active <= 0 )
  377.         {
  378.             handler->Set_Active( handler->Get_Size() - 1 );
  379.         }
  380.         else
  381.         {
  382.             handler->Set_Active( handler->active - 1 );
  383.         }
  384.     }
  385.     // Activate Button
  386.     else if( key == SDLK_RETURN || key == SDLK_KP_ENTER )
  387.     {
  388.         if( pMenu_Data )
  389.         {
  390.             pMenu_Data->action = 1;
  391.         }
  392.     }
  393.     // Fast Debug Level entering
  394.     else if( key == SDLK_x && ( input_event.key.keysym.mod & KMOD_LCTRL || input_event.key.keysym.mod & KMOD_RCTRL ) )
  395.     {
  396.         // random level name
  397.         string lvl_name;
  398.  
  399.         if( !CEGUI::WindowManager::getSingleton().isWindowPresent( "listbox_levels" ) )
  400.         {
  401.             // Create virtual start menu
  402.             cMenu_Start *menu_start = new cMenu_Start();
  403.  
  404.             menu_start->Init();
  405.             // Get Levels Listbox
  406.             CEGUI::Listbox *listbox_levels = static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_levels" ));
  407.             // select random level
  408.             listbox_levels->setItemSelectState( rand() % listbox_levels->getItemCount(), 1 );
  409.             // get level name
  410.             lvl_name = listbox_levels->getFirstSelectedItem()->getText().c_str();
  411.             // destroy virtual menu
  412.             delete menu_start;
  413.         }
  414.         else
  415.         {
  416.             // Get Levels Listbox
  417.             CEGUI::Listbox *listbox_levels = static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_levels" ));
  418.             // select random level
  419.             listbox_levels->setItemSelectState( rand() % listbox_levels->getItemCount(), 1 );
  420.             // get level name
  421.             lvl_name = listbox_levels->getFirstSelectedItem()->getText().c_str();
  422.         }
  423.  
  424.         Game_Action = GA_ENTER_LEVEL;
  425.         Game_Action_Data.add( "level", lvl_name.c_str() );
  426.     }
  427.     // exit
  428.     else if( key == SDLK_ESCAPE )
  429.     {
  430.         pMenu_Data->Exit();
  431.     }
  432.     else
  433.     {
  434.         // not processed
  435.         return 0;
  436.     }
  437.  
  438.     // key got processed
  439.     return 1;
  440. }
  441.  
  442. bool cMenuCore :: Key_Up( SDLKey key )
  443. {
  444.     // nothing yet
  445.     if( 0 )
  446.     {
  447.         //
  448.     }
  449.     else
  450.     {
  451.         // not processed
  452.         return 0;
  453.     }
  454.  
  455.     // key got processed
  456.     return 1;
  457. }
  458.  
  459. bool cMenuCore :: Joy_Button_Down( Uint8 button )
  460. {
  461.     // Activate Button
  462.     if( button == pPreferences->joy_button_action )
  463.     {
  464.         if( pMenu_Data )
  465.         {
  466.             pMenu_Data->action = 1;
  467.         }
  468.     }
  469.     // exit
  470.     else if( button == pPreferences->joy_button_exit )
  471.     {
  472.         pMenu_Data->Exit();
  473.     }
  474.     else
  475.     {
  476.         // not processed
  477.         return 0;
  478.     }
  479.  
  480.     // key got processed
  481.     return 1;
  482. }
  483.  
  484. bool cMenuCore :: Joy_Button_Up( Uint8 button )
  485. {
  486.     // nothing yet
  487.     if( 0 )
  488.     {
  489.         //
  490.     }
  491.     else
  492.     {
  493.         // not processed
  494.         return 0;
  495.     }
  496.  
  497.     // key got processed
  498.     return 1;
  499. }
  500.  
  501. bool cMenuCore :: Mouse_Down( Uint8 button )
  502. {
  503.     // nothing yet
  504.     if( button == SDL_BUTTON_LEFT )
  505.     {
  506.         cMenu_Item *item = handler->Get_Active_Item();
  507.  
  508.         if( item && pMouseCursor->Collsion_Check( &item->col_rect ) )
  509.         {
  510.             pMenu_Data->action = 1;
  511.             return 1;
  512.         }
  513.     }
  514.     else
  515.     {
  516.         // not processed
  517.         return 0;
  518.     }
  519.  
  520.     // button got processed
  521.     return 1;
  522. }
  523.  
  524. bool cMenuCore :: Mouse_Up( Uint8 button )
  525. {
  526.     // nothing yet
  527.     if( 0 )
  528.     {
  529.         //
  530.     }
  531.     else
  532.     {
  533.         // not processed
  534.         return 0;
  535.     }
  536.  
  537.     // button got processed
  538.     return 1;
  539. }
  540.  
  541. cMenu_Item *cMenuCore :: Auto_Menu( string imagename, string imagefilename_menu, float ypos /* = 0 */, bool is_quit /* = 0 */ )
  542. {
  543.     cMenu_Item *temp_item = new cMenu_Item();
  544.  
  545.     // The Menu Image
  546.     if( imagefilename_menu.length() > 0 )
  547.     {
  548.         temp_item->image_menu->Set_Image( pVideo->Get_Surface( DATA_DIR "/" GAME_PIXMAPS_DIR "/menu/" "items/" + imagefilename_menu ), 1 );
  549.     }
  550.  
  551.     // The Active Image
  552.     if( imagename.length() > 0 )
  553.     {
  554.         temp_item->image_default->Set_Image( pVideo->Get_Surface( DATA_DIR "/" GAME_PIXMAPS_DIR "/menu/" + imagename ), 1 );
  555.     }
  556.  
  557.     // Position and initialization
  558.     temp_item->Set_Pos( ( game_res_w / 2 ) - ( temp_item->image_default->col_rect.w / 2 ), ypos );
  559.     temp_item->isquit = is_quit;
  560.  
  561.     return temp_item;
  562. }
  563.  
  564. void cMenuCore :: Load( MenuID menu /* = MENU_MAIN */ )
  565. {
  566.     Unload();
  567.  
  568.     // unload level if possible
  569.     if( pActive_Level->delayed_unload )
  570.     {
  571.         pActive_Level->Unload();
  572.     }
  573.  
  574.     // Set ID
  575.     menu_id = menu;
  576.  
  577.     // check if not entering from another menu
  578.     if( next_menu == MENU_NOTHING )
  579.     {
  580.         // clear animations
  581.         static_cast<cParticle_Emitter *>(pMenu_AnimManager->objects[0])->Clear();
  582.  
  583.         // set camera position
  584.         camera->Set_Pos( 0, 0 );
  585.  
  586.         // pre render
  587.         pFramerate->speedfactor = 2;
  588.  
  589.         for( unsigned int i = 0; i < speedfactor_fps * 100; i++ )
  590.         {
  591.             pMenu_AnimManager->Update();
  592.         }
  593.  
  594.         pFramerate->Update();
  595.     }
  596.     
  597.     next_menu = MENU_NOTHING;
  598.  
  599.     // clear mouse active object
  600.     pMouseCursor->Double_Click( 0 );
  601.  
  602.     handler->Reset();
  603.  
  604.     // default white background
  605.     glClearColor( 1, 1, 1, 1 );
  606.  
  607.     // ## Create menu class
  608.     // Main
  609.     if( menu_id == MENU_MAIN )
  610.     {
  611.         pMenu_Data = static_cast<cMenu_Base *>(new cMenu_Main());
  612.     }
  613.     // Start
  614.     else if( menu_id == MENU_START )
  615.     {
  616.         pMenu_Data = static_cast<cMenu_Base *>(new cMenu_Start());
  617.     }
  618.     // Options
  619.     else if( menu_id == MENU_OPTIONS )
  620.     {
  621.         // Game
  622.         if( options_menu_id == MENU_GAME )
  623.         {
  624.             pMenu_Data = static_cast<cMenu_Base *>(new cMenu_Options_Game());
  625.         }
  626.         // Video
  627.         else if( options_menu_id == MENU_VIDEO )
  628.         {
  629.             pMenu_Data = static_cast<cMenu_Base *>(new cMenu_Options_Video());
  630.         }
  631.         // Audio
  632.         else if( options_menu_id == MENU_AUDIO )
  633.         {
  634.             pMenu_Data = static_cast<cMenu_Base *>(new cMenu_Options_Audio());
  635.         }
  636.         // Controls
  637.         else if( options_menu_id == MENU_CONTROLS )
  638.         {
  639.             pMenu_Data = static_cast<cMenu_Base *>(new cMenu_Options_Controls());
  640.         }
  641.     }
  642.     // Load
  643.     else if( menu_id == MENU_LOAD )
  644.     {
  645.         pMenu_Data = static_cast<cMenu_Base *>(new cMenu_Savegames( 0 ));
  646.     }
  647.     // Save
  648.     else if( menu_id == MENU_SAVE )
  649.     {
  650.         pMenu_Data = static_cast<cMenu_Base *>(new cMenu_Savegames( 1 ));
  651.     }
  652.     // Credits
  653.     else if( menu_id == MENU_CREDITS )
  654.     {
  655.         pMenu_Data = static_cast<cMenu_Base *>(new cMenu_Credits());
  656.     }
  657.  
  658.     pMenu_Data->Init();
  659. }
  660.  
  661. void cMenuCore :: Unload( void )
  662. {
  663.     menu_id = MENU_NOTHING;
  664.  
  665.     if( pMenu_Data )
  666.     {
  667.         delete pMenu_Data;
  668.         pMenu_Data = NULL;
  669.     }
  670. }
  671.  
  672. void cMenuCore :: Update( void ) 
  673. {
  674.     if( !pMenu_Data )
  675.     {
  676.         return;
  677.     }
  678.  
  679.     pMenu_Data->Update();
  680. }
  681.  
  682. void cMenuCore :: Draw( void ) 
  683. {
  684.     if( !pMenu_Data )
  685.     {
  686.         return;
  687.     }
  688.  
  689.     pMenu_Data->Draw();
  690.  
  691.     // if no vsync limit the fps for not stressing CPU usage
  692.     if( !pPreferences->video_vsync )
  693.     {
  694.         Correct_Frame_Time( 100 );
  695.     }
  696. }
  697.  
  698. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  699.  
  700. cMenuCore *pMenuCore = NULL;
  701.