home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / core / main.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2008-09-26  |  27.6 KB  |  1,170 lines

  1. /***************************************************************************
  2.  * main.cpp  -  main routines and initialization
  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 "../core/game_core.h"
  18. #include "../core/main.h"
  19. #include "../level/level.h"
  20. #include "../gui/menu.h"
  21. #include "../core/framerate.h"
  22. #include "../core/camera.h"
  23. #include "../video/video.h"
  24. #include "../video/font.h"
  25. #include "../user/preferences.h"
  26. #include "../video/img_manager.h"
  27. #include "../audio/sound_manager.h"
  28. #include "../audio/audio.h"
  29. #include "../core/obj_manager.h"
  30. #include "../level/level_editor.h"
  31. #include "../overworld/world_editor.h"
  32. #include "../input/joystick.h"
  33. #include "../overworld/world_manager.h"
  34. #include "../overworld/overworld.h"
  35. #include "../player/player.h"
  36. #include "../input/mouse.h"
  37. #include "../user/savegame.h"
  38. #include "../input/keyboard.h"
  39. #include "../video/renderer.h"
  40. #include "../video/img_settings.h"
  41. #include "../objects/levelexit.h"
  42. #include "../level/level_settings.h"
  43. #include "../core/sprite_manager.h"
  44. #include "../core/i18n.h"
  45. #ifdef __APPLE__
  46. // needed for datapath detection
  47. #include <CoreFoundation/CoreFoundation.h>
  48. #include <unistd.h>
  49. #endif
  50.  
  51. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  52.  
  53. int main( int argc, char **argv )
  54. {
  55. #ifdef __APPLE__
  56.     // dynamic datapath detection for OS X
  57.     // change CWD to point inside bundle so it finds its data (if necessary)
  58.     char path[1024];
  59.     CFBundleRef mainBundle = CFBundleGetMainBundle();
  60.     assert(mainBundle);
  61.     CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
  62.     assert(mainBundleURL);
  63.     CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);
  64.     assert(cfStringRef);
  65.     CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);
  66.     CFRelease(mainBundleURL);
  67.     CFRelease(cfStringRef);
  68.  
  69.     std::string contents = std::string(path) + std::string("/Contents");
  70.     std::string datapath;
  71.  
  72.     if( contents.find(".app") != std::string::npos )
  73.     {
  74.         // executable is inside an app bundle, use app bundle-relative paths
  75.         datapath = contents + std::string("/Resources/data/");
  76.     }
  77.     else if( contents.find("/bin") != std::string::npos )
  78.     {
  79.         // executable is installed Unix-way
  80.         datapath = contents.substr( 0, contents.find("/bin") ) + "/share/smc";
  81.     }
  82.     else
  83.     {
  84.         std::cerr << "Warning: Could not determine installation type\n";
  85.     }
  86.  
  87.     if( !datapath.empty() )
  88.     {
  89.         std::cout << "setting CWD to " << datapath.c_str() << std::endl;
  90.         if( chdir( datapath.c_str() ) != 0 )
  91.         {
  92.             std::cerr << "Warning: Failed changing CWD\n";
  93.         }
  94.     }
  95.  
  96. #endif
  97.     // convert arguments to a vector string
  98.     vector<string> arguments( argv, argv + argc );
  99.  
  100.     if( argc >= 2 )
  101.     {
  102.         for( unsigned int i = 1; i < arguments.size(); i++ )
  103.         {
  104.             // help
  105.             if( arguments[i] == "--help" || arguments[i] == "-h" )
  106.             {
  107.                 printf( "Usage: %s [OPTIONS]\n", arguments[0].c_str() );
  108.                 printf( "Where OPTIONS is one of the following:\n" );
  109.                 printf( "-h, --help\tDisplay this message\n" );
  110.                 printf( "-v, --version\tShow the version of %s\n", CAPTION );
  111.                 printf( "-d, --debug\tEnable debug modes with the options : game performance\n" );
  112.                 printf( "-l, --level\tLoad the given level\n" );
  113.                 printf( "-w, --world\tLoad the given world\n" );
  114.                 return EXIT_SUCCESS;
  115.             }
  116.             // version
  117.             else if( arguments[i] == "--version" || arguments[i] == "-v" )
  118.             {
  119.                 printf( "%s %s\n", CAPTION, string_trim_from_end( float_to_string( smc_version, 6 ), '0' ).c_str() );
  120.                 return EXIT_SUCCESS;
  121.             }
  122.             // debug
  123.             else if( arguments[i] == "--debug" || arguments[i] == "-d" )
  124.             {
  125.                 // no value
  126.                 if( i + 1 >= arguments.size() )
  127.                 {
  128.                     printf( "%s requires a value\n", arguments[i].c_str() );
  129.                     return EXIT_FAILURE;
  130.                 }
  131.                 // with value
  132.                 else
  133.                 {
  134.                     for( unsigned int option = i + i; i < arguments.size(); i++ )
  135.                     {
  136.                         string option_str = arguments[option];
  137.  
  138.                         if( option_str == "game" )
  139.                         {
  140.                             game_debug = 1;
  141.                         }
  142.                         else if( option_str == "performance" )
  143.                         {
  144.                             game_debug_performance = 1;
  145.                         }
  146.                         else
  147.                         {
  148.                             printf( "Unknown debug option %s\n", option_str.c_str() );
  149.                             return EXIT_FAILURE;
  150.                         }
  151.                     }
  152.                 }
  153.             }
  154.             // level loading is handled later
  155.             else if( arguments[i] == "--level" || arguments[i] == "-l" )
  156.             {
  157.                 // skip
  158.             }
  159.             // world loading is handled later
  160.             else if( arguments[1] == "--world" || arguments[1] == "-w" )
  161.             {
  162.                 // skip
  163.             }
  164.             // unknown argument
  165.             else if( arguments[i].substr( 0, 1 ) == "-" )
  166.             {
  167.                 printf( "Unknown argument %s\nUse -h to list all possible arguments\n", arguments[i].c_str() );
  168.                 return EXIT_FAILURE;
  169.             }
  170.         }
  171.     }
  172.  
  173.     try
  174.     {
  175.         // initialize everything
  176.         Init_Game();
  177.     }
  178.     catch( const std::exception &e )
  179.     {
  180.         printf( "Initialization: Exception raised: %s\n", e.what() );
  181.         return EXIT_FAILURE;
  182.     }
  183.  
  184.     // command line level loading
  185.     if( argc > 2 && ( arguments[1] == "--level" || arguments[1] == "-l" ) && !arguments[2].empty() )
  186.     {
  187.         // set start menu active
  188.         pMenuCore->Load( MENU_START );
  189.         // enter level
  190.         Game_Action = GA_ENTER_LEVEL;
  191.         Game_Action_Data.add( "level", arguments[2] );
  192.     }
  193.     // command line world loading
  194.     else if( argc > 2 && ( arguments[1] == "--world" || arguments[1] == "-w" ) && !arguments[2].empty() )
  195.     {
  196.         // set start menu active
  197.         pMenuCore->Load( MENU_START );
  198.         // enter level
  199.         Game_Action = GA_ENTER_WORLD;
  200.         Game_Action_Data.add( "world", arguments[2] );
  201.     }
  202.     // enter main menu
  203.     else
  204.     {
  205.         Draw_Effect_Out( EFFECT_OUT_BLACK, 1.5f );
  206.         pMenuCore->Load();
  207.         Draw_Effect_In( EFFECT_IN_BLACK, 1.5f );
  208.     }
  209.  
  210.     // game loop
  211.     while( !game_exit )
  212.     {
  213.         // update
  214.         Update_Game();
  215.         // draw
  216.         Draw_Game();
  217.  
  218.         // performance measuring
  219.         pFramerate->perf_last_ticks = SDL_GetTicks();
  220.  
  221.         // render
  222.         pVideo->Render();
  223.  
  224.         // update performance timer
  225.         pFramerate->perf_timer[PERF_RENDERING]->Update();
  226.  
  227.         // update speedfactor
  228.         pFramerate->Update();
  229.     }
  230.  
  231.     // exit
  232.     Exit_Game();
  233.     // no errors
  234.     return EXIT_SUCCESS;
  235. }
  236.  
  237. void Init_Game( void )
  238. {
  239.     // init random number generator
  240.     srand( static_cast<unsigned int>(time( NULL )) );
  241.  
  242.  
  243.     // Init Stage 1 - core classes
  244.     pVideo = new cVideo();
  245.     pFont = new cFont_Manager();
  246.     pFramerate = new cFramerate();
  247.     pRenderer = new cRenderQueue( 200 );
  248.     pRenderer_GUI = new cRenderQueue( 5 );
  249.     pPreferences = new cPreferences();
  250.     pImage_Manager = new cImage_Manager();
  251.     pSound_Manager = new cSound_Manager();
  252.     pSettingsParser = new cImage_settings();
  253.  
  254.     // Init Stage 2 - set preferences and init audio and video screen
  255.     pAudio = new cAudio();
  256.     /* Set default user directory
  257.      * can get overridden later from the preferences
  258.     */
  259.     user_data_dir = Get_User_Directory();
  260.     /* Initialize the fake CEGUI renderer and system for the pPreferences XMLParser,
  261.      * because CEGUI creates the system normally with the OpenGL-Renderer and OpenGL calls may 
  262.      * only be made with a valid OpenGL-context, which we would get only by setting 
  263.      * the videomode first. That would mean we need to init the videomode twice.
  264.     */
  265.     pVideo->Init_CEGUI_Fake();
  266.     // load user data
  267.     pPreferences->Load();
  268.     // set game language
  269.     I18N_Set_Language( pPreferences->language );
  270.     // init translation support
  271.     I18N_Init();
  272.     // delete CEGUI System fake
  273.     pVideo->Delete_CEGUI_Fake();
  274.  
  275.     // init user dir directory
  276.     Init_User_Directory();
  277.     // video init
  278.     pVideo->Init_SDL();
  279.     pVideo->Init_Video();
  280.     pVideo->Init_CEGUI();
  281.     pVideo->Init_CEGUI_Data();
  282.     pFont->Init();
  283.     // audio init
  284.     pAudio->Init();
  285.  
  286.     pPlayer = new cPlayer();
  287.     // set the first active player available
  288.     pActive_Player = pPlayer;
  289.     pLevel_Manager = new cLevel_Manager();
  290.     // set the first active sprite manager available
  291.     pActive_Sprite_Manager = pActive_Level->pSprite_Manager;
  292.     // set the first camera available
  293.     pActive_Camera = pLevel_Manager->camera;
  294.  
  295.     // apply preferences
  296.     pPreferences->Apply();
  297.  
  298.     // draw generic loading screen
  299.     Loading_Screen_Init();
  300.     // initialize image cache
  301.     pVideo->Init_Image_Cache( 0, 1 );
  302.  
  303.     // Init Stage 3 - game classes
  304.     pPlayer->Init();
  305.     pLevel_Editor = new cEditor_Level();
  306.     pWorld_Editor = new cEditor_World();
  307.     pMouseCursor = new cMouseCursor();
  308.     pKeyboard = new cKeyboard();
  309.     pJoystick = new cJoystick();
  310.     pLevel_Manager->Init();
  311.     pOverworld_Player = new cOverworld_Player();
  312.     pOverworld_Manager = new cOverworld_Manager();
  313.     
  314.     pHud_Manager = new cHud_Manager();
  315.     pAnimation_Manager = new cAnimation_Manager();
  316.     pMenuCore = new cMenuCore();
  317.  
  318.     pSavegame = new cSavegame();
  319.  
  320.     // cache
  321.     Preload_Images( 1 );
  322.     Preload_Sounds( 1 );
  323.     Loading_Screen_Exit();
  324. }
  325.  
  326. void Exit_Game( void )
  327. {
  328.     if( pPreferences )
  329.     {
  330.         pPreferences->Save();
  331.     }
  332.  
  333.     pLevel_Manager->Unload();
  334.  
  335.     if( pAudio )
  336.     {
  337.         delete pAudio;
  338.         pAudio = NULL;
  339.     }
  340.  
  341.     if( pPlayer )
  342.     {
  343.         delete pPlayer;
  344.         pPlayer = NULL;
  345.     }
  346.  
  347.     if( pHud_Manager )
  348.     {
  349.         delete pHud_Manager;
  350.         pHud_Manager = NULL;
  351.     }
  352.  
  353.     if( pSound_Manager )
  354.     {
  355.         delete pSound_Manager;
  356.         pSound_Manager = NULL;
  357.     }
  358.  
  359.     if( pAnimation_Manager )
  360.     {
  361.         delete pAnimation_Manager;
  362.         pAnimation_Manager = NULL;
  363.     }
  364.  
  365.     if( pLevel_Editor )
  366.     {
  367.         delete pLevel_Editor;
  368.         pLevel_Editor = NULL;
  369.     }
  370.  
  371.     if( pWorld_Editor )
  372.     {
  373.         delete pWorld_Editor;
  374.         pWorld_Editor = NULL;
  375.     }
  376.  
  377.     if( pPreferences )
  378.     {
  379.         delete pPreferences;
  380.         pPreferences = NULL;
  381.     }
  382.  
  383.     if( pSavegame )
  384.     {
  385.         delete pSavegame;
  386.         pSavegame = NULL;
  387.     }
  388.  
  389.     if( pMouseCursor )
  390.     {
  391.         delete pMouseCursor;
  392.         pMouseCursor = NULL;
  393.     }
  394.  
  395.     if( pJoystick )
  396.     {
  397.         delete pJoystick;
  398.         pJoystick = NULL;
  399.     }
  400.  
  401.     if( pKeyboard )
  402.     {
  403.         delete pKeyboard;
  404.         pKeyboard = NULL;
  405.     }
  406.  
  407.     if( pOverworld_Manager )
  408.     {
  409.         delete pOverworld_Manager;
  410.         pOverworld_Manager = NULL;
  411.     }
  412.  
  413.     if( pOverworld_Player )
  414.     {
  415.         delete pOverworld_Player;
  416.         pOverworld_Player = NULL;
  417.     }
  418.  
  419.     if( pLevel_Manager )
  420.     {
  421.         delete pLevel_Manager;
  422.         pLevel_Manager = NULL;
  423.     }
  424.  
  425.     if( pMenuCore )
  426.     {
  427.         delete pMenuCore;
  428.         pMenuCore = NULL;
  429.     }
  430.  
  431.     if( pRenderer )
  432.     {
  433.         delete pRenderer;
  434.         pRenderer = NULL;
  435.     }
  436.  
  437.     if( pRenderer_GUI )
  438.     {
  439.         delete pRenderer_GUI;
  440.         pRenderer_GUI = NULL;
  441.     }
  442.  
  443.     if( pGuiSystem )
  444.     {
  445.         delete pGuiSystem;
  446.         pGuiSystem = NULL;
  447.     }
  448.  
  449.     if( pGuiRenderer )
  450.     {
  451.         delete pGuiRenderer;
  452.         pGuiRenderer = NULL;
  453.     }
  454.  
  455.     if( pVideo )
  456.     {
  457.         delete pVideo;
  458.         pVideo = NULL;
  459.     }
  460.  
  461.     if( pImage_Manager )
  462.     {
  463.         delete pImage_Manager;
  464.         pImage_Manager = NULL;
  465.     }
  466.  
  467.     if( pSettingsParser )
  468.     {
  469.         delete pSettingsParser;
  470.         pSettingsParser = NULL;
  471.     }
  472.  
  473.     if( pFont )
  474.     {
  475.         delete pFont;
  476.         pFont = NULL;
  477.     }
  478.  
  479.     if( strlen( SDL_GetError() ) > 0 )
  480.     {
  481.         printf( "Last known SDL Error : %s\n", SDL_GetError() );
  482.     }
  483.  
  484.     SDL_Quit();
  485. }
  486.  
  487. bool Handle_Input_Global( SDL_Event *ev )
  488. {
  489.     switch( ev->type )
  490.     {
  491.         case SDL_QUIT:
  492.         {
  493.             game_exit = 1;
  494.             Clear_Input_Events();
  495.  
  496.             // handle on all handlers ?
  497.             return 0;
  498.         }
  499.         case SDL_VIDEORESIZE:
  500.         {
  501.             pGuiRenderer->setDisplaySize( CEGUI::Size( static_cast<float>(ev->resize.w), static_cast<float>(ev->resize.h) ) );
  502.             break;
  503.         }
  504.         case SDL_KEYDOWN:
  505.         {
  506.             if( pKeyboard->Key_Down( ev->key.keysym.sym ) )
  507.             {
  508.                 return 1;
  509.             }
  510.             break;
  511.         }
  512.         case SDL_KEYUP:
  513.         {
  514.             if( pKeyboard->Key_Up( ev->key.keysym.sym ) )
  515.             {
  516.                 return 1;
  517.             }
  518.             break;
  519.         }
  520.         case SDL_JOYBUTTONDOWN:
  521.         {
  522.             if( pJoystick->Handle_Button_Down_Event( ev ) )
  523.             {
  524.                 return 1;
  525.             }
  526.             break;
  527.         }
  528.         case SDL_JOYBUTTONUP:
  529.         {
  530.             if( pJoystick->Handle_Button_Up_Event( ev ) )
  531.             {
  532.                 return 1;
  533.             }
  534.             break;
  535.         }
  536.         case SDL_JOYAXISMOTION:
  537.         {
  538.             pJoystick->Handle_Motion( ev );
  539.             break;
  540.         }
  541.         case SDL_ACTIVEEVENT:
  542.         {
  543.             // lost visibility
  544.             if( ev->active.gain == 0 )
  545.             {
  546.                 bool music_paused = 0;
  547.                 // pause music
  548.                 if( pAudio->Is_Music_Playing() )
  549.                 {
  550.                     pAudio->Pause_Music();
  551.                     music_paused = 1;
  552.                 }
  553.                 SDL_WaitEvent( NULL );
  554.                 // resume if music got paused
  555.                 if( music_paused )
  556.                 {
  557.                     pAudio->Resume_Music();
  558.                 }
  559.                 return 1;
  560.             }
  561.             break;
  562.         }
  563.         default: // other events
  564.         {
  565.             // mouse
  566.             if( pMouseCursor->Handle_Event( ev ) )
  567.             {
  568.                 return 1; 
  569.             }
  570.  
  571.             // send events
  572.             if( Game_Mode == MODE_LEVEL )
  573.             {
  574.                 // editor events
  575.                 if( pLevel_Editor->enabled )
  576.                 {
  577.                     if( pLevel_Editor->Handle_Event( ev ) )
  578.                     {
  579.                         return 1;
  580.                     }
  581.                 }
  582.             }
  583.             else if( Game_Mode == MODE_OVERWORLD )
  584.             {
  585.                 // editor events
  586.                 if( pWorld_Editor->enabled )
  587.                 {
  588.                     if( pWorld_Editor->Handle_Event( ev ) )
  589.                     {
  590.                         return 1;
  591.                     }
  592.                 }
  593.             }
  594.             else if( Game_Mode == MODE_MENU )
  595.             {
  596.                 if( pMenuCore->Handle_Event( ev ) )
  597.                 {
  598.                     return 1;
  599.                 }
  600.             }
  601.             break;
  602.         }
  603.     }
  604.  
  605.     return 0;
  606. }
  607.  
  608. void Update_Game( void )
  609. {
  610.     // do not update if exiting
  611.     if( game_exit )
  612.     {
  613.         return;
  614.     }
  615.  
  616.     // ## game events
  617.     // level mode
  618.     if( Game_Mode == MODE_LEVEL )
  619.     {
  620.         // if Game Action set
  621.         while( Game_Action != GA_NONE )
  622.         {
  623.             // get current data
  624.             GameAction Current_Game_Action = Game_Action;
  625.             CEGUI::XMLAttributes Current_Game_Action_Data = Game_Action_Data;
  626.             void *Current_Game_Action_ptr = Game_Action_ptr;
  627.             // clear
  628.             Game_Action = GA_NONE;
  629.             Game_Action_Data = CEGUI::XMLAttributes();
  630.             Game_Action_ptr = NULL;
  631.  
  632.             // handle player downgrade
  633.             if( Current_Game_Action == GA_DOWNGRADE_PLAYER )
  634.             {
  635.                 pPlayer->DownGrade( 0, CEGUI::PropertyHelper::stringToBool( Current_Game_Action_Data.getValueAsString( "force" ) ) );
  636.             }
  637.             // activate level exit
  638.             else if( Current_Game_Action == GA_ACTIVATE_LEVEL_EXIT )
  639.             {
  640.                 cLevel_Exit *level_exit = static_cast<cLevel_Exit *>(Current_Game_Action_ptr);
  641.                 level_exit->Activate();
  642.             }
  643.             // Enter Level
  644.             else if( Current_Game_Action == GA_ENTER_LEVEL )
  645.             {
  646.                 // fade out
  647.                 if( Game_Mode_Type == MODE_TYPE_LEVEL_CUSTOM )
  648.                 {
  649.                     Draw_Effect_Out( EFFECT_OUT_BLACK, 3 );
  650.                 }
  651.                 else
  652.                 {
  653.                     Draw_Effect_Out();
  654.                 }
  655.  
  656.                 string str_level = Current_Game_Action_Data.getValueAsString( "level" ).c_str();
  657.                 // load new level
  658.                 if( !pActive_Level->Load( str_level ) )
  659.                 {
  660.                     // if failed to load exit level
  661.                     pPlayer->Goto_Next_Level();
  662.                     continue;
  663.                 }
  664.  
  665.                 // load entry
  666.                 string str_entry = Current_Game_Action_Data.getValueAsString( "entry" ).c_str();
  667.                 cLevel_Entry *entry = pActive_Level->Get_Entry( str_entry );
  668.  
  669.                 if( !entry && !str_entry.empty() )
  670.                 {
  671.                     printf( "Warning : Level entry %s not found\n", str_entry.c_str() );
  672.                 }
  673.  
  674.                 // change game mode
  675.                 Change_Game_Mode( MODE_LEVEL );
  676.                 // set camera position to the entry 
  677.                 if( entry )
  678.                 {
  679.                     // set position
  680.                     pPlayer->Set_Pos( entry->Get_Player_Pos_X(), entry->Get_Player_Pos_Y() );
  681.                     // center camera position
  682.                     pActive_Camera->Center();
  683.                     // set invisible for warp animation
  684.                     pPlayer->Set_Visible( 0 );
  685.                 }
  686.  
  687.                 // play new music
  688.                 if( pActive_Level->valid_music )
  689.                 {
  690.                     pAudio->Play_Music( pActive_Level->musicfile, -1, 0, 1000 );
  691.                 }
  692.  
  693.                 // fade in
  694.                 if( Game_Mode_Type == MODE_TYPE_LEVEL_CUSTOM )
  695.                 {
  696.                     Draw_Effect_In( EFFECT_IN_BLACK, 3 );
  697.                 }
  698.                 else
  699.                 {
  700.                     Draw_Effect_In();
  701.                 }
  702.  
  703.                 // activate entry
  704.                 if( entry )
  705.                 {
  706.                     pPlayer->Goto_Sub_Level( str_level, str_entry, 0 );
  707.                 }
  708.             }
  709.             // Enter World
  710.             else if( Current_Game_Action == GA_ENTER_WORLD )
  711.             {
  712.                 // Random fade out effect
  713.                 Draw_Effect_Out();
  714.                 // delay unload level
  715.                 pActive_Level->Unload( 1 );
  716.                 // set active world
  717.                 if( Current_Game_Action_Data.exists( "world" ) )
  718.                 {
  719.                     pOverworld_Manager->Set_Active( Current_Game_Action_Data.getValueAsString( "world" ).c_str() );
  720.                 }
  721.                 // set player waypoint
  722.                 if( Current_Game_Action_Data.exists( "player_waypoint" ) )
  723.                 {
  724.                     // get world waypoint
  725.                     int waypoint_num = pActive_Overworld->Get_Waypoint_Num( Current_Game_Action_Data.getValueAsString( "player_waypoint" ).c_str() );
  726.  
  727.                     // waypoint available
  728.                     if( waypoint_num >= 0 )
  729.                     {
  730.                         // set all levels accessible until the world link
  731.                         pActive_Overworld->Set_Progress( waypoint_num, 0 );
  732.                         pOverworld_Player->Set_Waypoint( waypoint_num );
  733.                     }
  734.                 }
  735.                 // enter world
  736.                 pActive_Overworld->Enter();
  737.                 // draw fade in
  738.                 Draw_Effect_In();
  739.             }
  740.             // Enter Menu
  741.             else if( Current_Game_Action == GA_ENTER_MENU )
  742.             {
  743.                 // fade out
  744.                 Draw_Effect_Out( EFFECT_OUT_BLACK, 3 );
  745.  
  746.                 // custom level
  747.                 if( Game_Mode_Type == MODE_TYPE_LEVEL_CUSTOM )
  748.                 {
  749.                     pMenuCore->Load( MENU_START );
  750.  
  751.                     // Get Tab Control
  752.                     CEGUI::TabControl *tabcontrol = static_cast<CEGUI::TabControl *>(CEGUI::WindowManager::getSingleton().getWindow( "tabcontrol_main" ));
  753.                     // Select Level Tab
  754.                     tabcontrol->setSelectedTab( "tab_level" );
  755.  
  756.                     // Get Levels Listbox
  757.                     CEGUI::Listbox *listbox_levels = static_cast<CEGUI::Listbox *>(CEGUI::WindowManager::getSingleton().getWindow( "listbox_levels" ));
  758.                     // Get Item
  759.                     CEGUI::ListboxItem *list_item = listbox_levels->findItemWithText( Get_Filename( pActive_Level->data_file, 0, 0 ).c_str(), NULL );
  760.                     // select level
  761.                     if( list_item )
  762.                     {
  763.                         listbox_levels->setItemSelectState( list_item, 1 );
  764.                         listbox_levels->ensureItemIsVisible( list_item );
  765.                     }
  766.  
  767.                     Game_Mode_Type = MODE_TYPE_DEFAULT;
  768.                 }
  769.                 // default menu
  770.                 else
  771.                 {
  772.                     pMenuCore->Load();
  773.                 }
  774.                 
  775.                 // fade int
  776.                 Draw_Effect_In( EFFECT_IN_BLACK, 3 );
  777.             }
  778.             // Enter Settings
  779.             else if( Current_Game_Action == GA_ENTER_LEVEL_SETTINGS )
  780.             {
  781.                 // fade out
  782.                 Draw_Effect_Out( EFFECT_OUT_BLACK, 3 );
  783.                 // enter
  784.                 pLevel_Editor->pSettings->Enter();
  785.                 // fade in
  786.                 Draw_Effect_In( EFFECT_IN_BLACK, 3 );
  787.             }
  788.         }
  789.     }
  790.     // world mode
  791.     else if( Game_Mode == MODE_OVERWORLD )
  792.     {
  793.         // if Game Action set
  794.         while( Game_Action != GA_NONE )
  795.         {
  796.             // get current data
  797.             GameAction Current_Game_Action = Game_Action;
  798.             CEGUI::XMLAttributes Current_Game_Action_Data = Game_Action_Data;
  799.             void *Current_Game_Action_ptr = Game_Action_ptr;
  800.             // clear
  801.             Game_Action = GA_NONE;
  802.             Game_Action_Data = CEGUI::XMLAttributes();
  803.             Game_Action_ptr = NULL;
  804.  
  805.             // Enter Level
  806.             if( Current_Game_Action == GA_ENTER_LEVEL )
  807.             {
  808.                 // fade out
  809.                 Draw_Effect_Out( EFFECT_OUT_FIXED_COLORBOX );
  810.                 // load new level
  811.                 if( Current_Game_Action_Data.exists( "level" ) )
  812.                 {
  813.                     // load level
  814.                     pActive_Level->Load( Current_Game_Action_Data.getValueAsString( "level" ).c_str() );
  815.                     // play new music
  816.                     if( pActive_Level->valid_music )
  817.                     {
  818.                         pAudio->Play_Music( pActive_Level->musicfile, -1, 0, 1000 );
  819.                     }
  820.                 }
  821.                 // change game mode
  822.                 Change_Game_Mode( MODE_LEVEL );
  823.                 // reset player
  824.                 pPlayer->Reset();
  825.                 // fade in
  826.                 Draw_Effect_In();
  827.             }
  828.             // Enter World
  829.             else if( Current_Game_Action == GA_ENTER_WORLD )
  830.             {
  831.                 // Random fade out effect
  832.                 Draw_Effect_Out( EFFECT_OUT_TILE_PIXELATION );
  833.                 // set active world
  834.                 if( Current_Game_Action_Data.exists( "world" ) )
  835.                 {
  836.                     pOverworld_Manager->Set_Active( Current_Game_Action_Data.getValueAsString( "world" ).c_str() );
  837.                 }
  838.                 // set player waypoint
  839.                 if( Current_Game_Action_Data.exists( "player_waypoint" ) )
  840.                 {
  841.                     // get world waypoint
  842.                     int waypoint_num = pActive_Overworld->Get_Waypoint_Num( Current_Game_Action_Data.getValueAsString( "player_waypoint" ).c_str() );
  843.  
  844.                     // waypoint available
  845.                     if( waypoint_num >= 0 )
  846.                     {
  847.                         // set all levels accessible until the world link
  848.                         pActive_Overworld->Set_Progress( waypoint_num, 0 );
  849.                         pOverworld_Player->Set_Waypoint( waypoint_num );
  850.                     }
  851.                 }
  852.                 // enter world
  853.                 pActive_Overworld->Enter();
  854.                 // draw fade in
  855.                 Draw_Effect_In();
  856.             }
  857.             // Enter Menu
  858.             else if( Current_Game_Action == GA_ENTER_MENU )
  859.             {
  860.                 pMenuCore->Load();
  861.             }
  862.             // Enter Credits Menu
  863.             else if( Current_Game_Action == GA_ENTER_MENU_CREDITS )
  864.             {
  865.                 pMenuCore->Load( MENU_CREDITS );
  866.             }
  867.         }
  868.     }
  869.     // menu mode
  870.     else if( Game_Mode == MODE_MENU )
  871.     {
  872.         // if Game Action set
  873.         while( Game_Action != GA_NONE )
  874.         {
  875.             // get current data
  876.             GameAction Current_Game_Action = Game_Action;
  877.             CEGUI::XMLAttributes Current_Game_Action_Data = Game_Action_Data;
  878.             void *Current_Game_Action_ptr = Game_Action_ptr;
  879.             // clear
  880.             Game_Action = GA_NONE;
  881.             Game_Action_Data = CEGUI::XMLAttributes();
  882.             Game_Action_ptr = NULL;
  883.  
  884.             // Enter World
  885.             if( Current_Game_Action == GA_ENTER_WORLD )
  886.             {
  887.                 // fade out
  888.                 Draw_Effect_Out( EFFECT_OUT_BLACK, 3 );
  889.                 // todo : fade only out if not same music
  890.                 // if origin menu is start menu
  891.                 if( pMenuCore->menu_id == MENU_START )
  892.                 {
  893.                     // fade music out
  894.                     pAudio->Fadeout_Music( 1000 );
  895.                 }
  896.                 // unload menu
  897.                 pMenuCore->Unload();
  898.                 // set active world
  899.                 if( Current_Game_Action_Data.exists( "world" ) )
  900.                 {
  901.                     pOverworld_Manager->Set_Active( Current_Game_Action_Data.getValueAsString( "world" ).c_str() );
  902.                 }
  903.                 // set player waypoint
  904.                 if( Current_Game_Action_Data.exists( "player_waypoint" ) )
  905.                 {
  906.                     // get world waypoint
  907.                     int waypoint_num = pActive_Overworld->Get_Waypoint_Num( Current_Game_Action_Data.getValueAsString( "player_waypoint" ).c_str() );
  908.  
  909.                     // waypoint available
  910.                     if( waypoint_num >= 0 )
  911.                     {
  912.                         // set all levels accessible until the world link
  913.                         pActive_Overworld->Set_Progress( waypoint_num, 0 );
  914.                         pOverworld_Player->Set_Waypoint( waypoint_num );
  915.                     }
  916.                 }
  917.                 // enter world
  918.                 pActive_Overworld->Enter();
  919.                 // fade in
  920.                 Draw_Effect_In( EFFECT_IN_BLACK, 3 );
  921.             }
  922.             // Enter Level
  923.             if( Current_Game_Action == GA_ENTER_LEVEL )
  924.             {
  925.                 // if level not loaded or entering custom level
  926.                 if( !pActive_Level->Is_Loaded() || Current_Game_Action_Data.exists( "level" ) )
  927.                 {
  928.                     // fade music out
  929.                     pAudio->Fadeout_Music( 1000 );
  930.                 }
  931.                 // fade out
  932.                 Draw_Effect_Out( EFFECT_OUT_BLACK, 3 );
  933.                 // check if custom level mode
  934.                 bool custom_level_mode = 0;
  935.                 // if origin menu is start menu
  936.                 if( pMenuCore->menu_id == MENU_START )
  937.                 {
  938.                     custom_level_mode = 1;
  939.                 }
  940.                 // unload menu
  941.                 pMenuCore->Unload();
  942.                 // load custom level
  943.                 if( Current_Game_Action_Data.exists( "level" ) )
  944.                 {
  945.                     if( custom_level_mode )
  946.                     {
  947.                         pPlayer->Reset_Save();
  948.                     }
  949.                     // load new level
  950.                     pActive_Level->Load( Current_Game_Action_Data.getValueAsString( "level" ).c_str() );
  951.                     // reset player
  952.                     pPlayer->Reset( custom_level_mode );
  953.                 }
  954.                 // change mode
  955.                 Change_Game_Mode( MODE_LEVEL );
  956.                 // if custom level
  957.                 if( custom_level_mode )
  958.                 {
  959.                     Game_Mode_Type = MODE_TYPE_LEVEL_CUSTOM;
  960.                 }
  961.                 // fade in
  962.                 Draw_Effect_In( EFFECT_IN_BLACK, 3 );
  963.             }
  964.             // Enter Menu
  965.             else if( Current_Game_Action == GA_ENTER_MENU )
  966.             {
  967.                 if( pMenuCore->next_menu != MENU_NOTHING )
  968.                 {
  969.                     pMenuCore->Load( pMenuCore->next_menu );
  970.                 }
  971.             }
  972.         }
  973.     }
  974.     // level settings mode
  975.     else if( Game_Mode == MODE_LEVEL_SETTINGS )
  976.     {
  977.         // if Game Action set
  978.         while( Game_Action != GA_NONE )
  979.         {
  980.             // get current data
  981.             GameAction Current_Game_Action = Game_Action;
  982.             CEGUI::XMLAttributes Current_Game_Action_Data = Game_Action_Data;
  983.             void *Current_Game_Action_ptr = Game_Action_ptr;
  984.             // clear
  985.             Game_Action = GA_NONE;
  986.             Game_Action_Data = CEGUI::XMLAttributes();
  987.             Game_Action_ptr = NULL;
  988.  
  989.             // Enter Level
  990.             if( Current_Game_Action == GA_ENTER_LEVEL )
  991.             {
  992.                 // fade out
  993.                 Draw_Effect_Out( EFFECT_OUT_BLACK, 3 );
  994.                 // change mode
  995.                 pLevel_Editor->pSettings->Unload();
  996.                 Change_Game_Mode( MODE_LEVEL );
  997.                 // fade in
  998.                 Draw_Effect_In( EFFECT_IN_BLACK, 3 );
  999.             }
  1000.         }
  1001.     }
  1002.  
  1003.     // ## input
  1004.     while( SDL_PollEvent( &input_event ) )
  1005.     {
  1006.         // handle
  1007.         Handle_Input_Global( &input_event );
  1008.     }
  1009.  
  1010.     pMouseCursor->Update();
  1011.  
  1012.     // ## audio
  1013.     pAudio->Resume_Music();
  1014.     pAudio->Update();
  1015.  
  1016.     // performance measuring
  1017.     pFramerate->perf_last_ticks = SDL_GetTicks();
  1018.  
  1019.     // ## update
  1020.     if( Game_Mode == MODE_LEVEL )
  1021.     {
  1022.         // input
  1023.         pActive_Level->Process_Input();
  1024.         pLevel_Editor->Process_Input();
  1025.  
  1026.         // update performance timer
  1027.         pFramerate->perf_timer[PERF_UPDATE_PROCESS_INPUT]->Update();
  1028.  
  1029.         // update
  1030.         pActive_Level->Update();
  1031.  
  1032.         // update performance timer
  1033.         pFramerate->perf_timer[PERF_UPDATE_LEVEL]->Update();
  1034.  
  1035.         // editor
  1036.         pLevel_Editor->Update();
  1037.  
  1038.         // update performance timer
  1039.         pFramerate->perf_timer[PERF_UPDATE_LEVEL_EDITOR]->Update();
  1040.  
  1041.         // hud
  1042.         pHud_Manager->Update();
  1043.  
  1044.         // update performance timer
  1045.         pFramerate->perf_timer[PERF_UPDATE_HUD]->Update();
  1046.  
  1047.         // player
  1048.         pPlayer->Update();
  1049.  
  1050.         // update performance timer
  1051.         pFramerate->perf_timer[PERF_UPDATE_PLAYER]->Update();
  1052.  
  1053.         // collisions
  1054.         if( !editor_enabled )
  1055.         {
  1056.             pPlayer->Collide_Move();
  1057.             pPlayer->Handle_Collisions();
  1058.             pActive_Sprite_Manager->Handle_Collision_Items();
  1059.         }
  1060.  
  1061.         // update performance timer
  1062.         pFramerate->perf_timer[PERF_UPDATE_COLLISIONS]->Update();
  1063.  
  1064.         // Camera ( update after new player position was set )
  1065.         pActive_Camera->Update();
  1066.  
  1067.         // update performance timer
  1068.         pFramerate->perf_timer[PERF_UPDATE_CAMERA]->Update();
  1069.  
  1070.     }
  1071.     else if( Game_Mode == MODE_OVERWORLD )
  1072.     {
  1073.         pActive_Overworld->Update();
  1074.  
  1075.         // update performance timer
  1076.         pFramerate->perf_timer[PERF_UPDATE_OVERWORLD]->Update();
  1077.     }
  1078.     else if( Game_Mode == MODE_MENU )
  1079.     {
  1080.         pMenuCore->Update();
  1081.  
  1082.         // update performance timer
  1083.         pFramerate->perf_timer[PERF_UPDATE_MENU]->Update();
  1084.     }
  1085.     else if( Game_Mode == MODE_LEVEL_SETTINGS )
  1086.     {
  1087.         pLevel_Editor->pSettings->Update();
  1088.  
  1089.         // update performance timer
  1090.         pFramerate->perf_timer[PERF_UPDATE_LEVEL_SETTINGS]->Update();
  1091.     }
  1092.  
  1093.     // gui
  1094.     Gui_Handle_Time();
  1095. }
  1096.  
  1097. void Draw_Game( void )
  1098. {
  1099.     // don't draw if exiting
  1100.     if( game_exit )
  1101.     {
  1102.         return;
  1103.     }
  1104.  
  1105.     // performance measuring
  1106.     pFramerate->perf_last_ticks = SDL_GetTicks();
  1107.  
  1108.     if( Game_Mode == MODE_LEVEL )
  1109.     {
  1110.         // draw level layer 1
  1111.         pActive_Level->Draw_Layer1();
  1112.  
  1113.         // update performance timer
  1114.         pFramerate->perf_timer[PERF_DRAW_LEVEL_LAYER1]->Update();
  1115.  
  1116.         // player draw
  1117.         pPlayer->Draw();
  1118.  
  1119.         // update performance timer
  1120.         pFramerate->perf_timer[PERF_DRAW_LEVEL_PLAYER]->Update();
  1121.  
  1122.         // draw level layer 2
  1123.         pActive_Level->Draw_Layer2();
  1124.  
  1125.         // update performance timer
  1126.         pFramerate->perf_timer[PERF_DRAW_LEVEL_LAYER2]->Update();
  1127.  
  1128.         // hud
  1129.         pHud_Manager->Draw();
  1130.  
  1131.         // update performance timer
  1132.         pFramerate->perf_timer[PERF_DRAW_LEVEL_HUD]->Update();
  1133.  
  1134.         // level editor
  1135.         pLevel_Editor->Draw();
  1136.  
  1137.         // update performance timer
  1138.         pFramerate->perf_timer[PERF_DRAW_LEVEL_EDITOR]->Update();
  1139.  
  1140.     }
  1141.     else if( Game_Mode == MODE_OVERWORLD )
  1142.     {
  1143.         // world
  1144.         pActive_Overworld->Draw();
  1145.  
  1146.         // update performance timer
  1147.         pFramerate->perf_timer[PERF_DRAW_OVERWORLD]->Update();
  1148.     }
  1149.     else if( Game_Mode == MODE_MENU )
  1150.     {
  1151.         pMenuCore->Draw();
  1152.  
  1153.         // update performance timer
  1154.         pFramerate->perf_timer[PERF_DRAW_MENU]->Update();
  1155.     }
  1156.     else if( Game_Mode == MODE_LEVEL_SETTINGS )
  1157.     {
  1158.         pLevel_Editor->pSettings->Draw();
  1159.  
  1160.         // update performance timer
  1161.         pFramerate->perf_timer[PERF_DRAW_LEVEL_SETTINGS]->Update();
  1162.     }
  1163.  
  1164.     // Mouse
  1165.     pMouseCursor->Draw();
  1166.  
  1167.     // update performance timer
  1168.     pFramerate->perf_timer[PERF_DRAW_MOUSE]->Update();
  1169. }
  1170.