Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

main.cpp

00001 /***************************************************************************
00002                         main.cpp  -  description
00003                             -------------------
00004     project              : OpenCity
00005     codename             : Delphine
00006     begin                : mer mai 28 2003
00007     copyright            : (C) 2003-2006 by Duong-Khang NGUYEN
00008     email                : neoneurone @ users sourceforge net
00009 
00010     details              :
00011             This is a game project which targets the ultimate city
00012         simulation just like like xxxCity or something like that :)
00013 
00014     $Id: main.cpp 83 2006-11-05 20:46:42Z neoneurone $
00015  ***************************************************************************/
00016 
00017 /***************************************************************************
00018  *                                                                         *
00019  *   This program is free software; you can redistribute it and/or modify  *
00020  *   it under the terms of the GNU General Public License as published by  *
00021  *   the Free Software Foundation; either version 2 of the License, or     *
00022  *   any later version.                                                    *
00023  *                                                                         *
00024  ***************************************************************************/
00025 
00026 //========================================================================
00049 #include "main.h"
00050 #include "city.h"               // The heart of the project
00051 #include "conf.h"               // Parser for .conf file
00052 #include "agentpolice.h"        // MAS testing
00053 #include "agentdemonstrator.h"
00054 
00055 #include "globalvar.h"          // Global settings variable: gVars
00056 
00057 #include "SDL_image.h"
00058 #include "binreloc.h"           // BinReloc routines from AutoPackage
00059 #include "tinyxml/tinyxml.h"
00060 
00061 #include <cmath>                // For log10
00062 #include <cstdlib>              // For getenv
00063 
00064 
00065    /*=====================================================================*/
00066    /*                        GLOBAL    VARIABLES                          */
00067    /*=====================================================================*/
00068     GlobalVar gVars;
00069 
00070 
00071    /*=====================================================================*/
00072    /*                           LOCAL     MACROS                          */
00073    /*=====================================================================*/
00074 #ifndef WIN32
00075     #include <sys/stat.h>       // mkdir
00076 #else
00077 // Win32 specifics
00078     #include <shlobj.h>         // Windows shell technologies
00079     #define PREFIX "C:/Program Files"
00080 #endif
00081 
00082 // Window's settings
00083     #define OC_WINDOW_POS_X         20
00084     #define OC_WINDOW_POS_Y         20
00085     #define OC_WINDOW_WIDTH         750
00086     #define OC_WINDOW_HEIGHT        560
00087     #define OC_WINDOW_BPP_DEFAULT   32              // OC uses this by default
00088     #define OC_WINDOW_BPP_16        16
00089     #define OC_FULLSCREEN_WIDTH     1024
00090     #define OC_FULLSCREEN_HEIGHT    768
00091 
00092 // Exit code
00093     #define OC_CONFIG_NOT_FOUND     -1
00094     #define OC_CONFIG_PARSE_ERROR   -2
00095 
00096 // Settings file
00097     #define OC_CONFIG_FILE_FILENAME "config/opencity.xml"
00098 
00099 // Others macros
00100     #define OC_WINDOW_NAME PACKAGE VERSION
00101 
00102 
00103 
00104    /*=====================================================================*/
00105    /*                         LOCAL    VARIABLES                          */
00106    /*=====================================================================*/
00108     static UI * uipCurrentUI        = NULL;
00109 
00111     static bool boolQuit            = false;
00112 
00114     static int flags                = 0;
00115 
00117     static string sHomeDir          = "";
00118     static string sSaveDir          = "";
00119 
00120 
00121 
00122    /*=====================================================================*/
00123 void ocPerror( const OPENCITY_ERR_CODE & err_code )
00124 {
00125     cout << "Something went wrong. Error code : " << err_code << endl;
00126 }
00127 
00128 
00129    /*=====================================================================*/
00130 void ocKeyboard( const SDL_KeyboardEvent & rcsKeyboardEvent )
00131 {
00132     if (uipCurrentUI != NULL) {
00133         uipCurrentUI->uiKeyboard( rcsKeyboardEvent );
00134     }
00135 }
00136 
00137 
00138    /*=====================================================================*/
00139 void ocMouseButton( const SDL_MouseButtonEvent & rcsMouseButtonEvent )
00140 {
00141     if (uipCurrentUI != NULL) {
00142         uipCurrentUI->uiMouseButton( rcsMouseButtonEvent );
00143     }
00144 }
00145 
00146 
00147    /*=====================================================================*/
00148 void ocMouseMotion( const SDL_MouseMotionEvent & motionEvent )
00149 {
00150     if (uipCurrentUI != NULL) {
00151         uipCurrentUI->uiMouseMotion( motionEvent );
00152     }
00153 }
00154 
00155 
00156    /*=====================================================================*/
00157 void ocResize( const SDL_ResizeEvent & rcsResizeEvent)
00158 {
00159 #ifndef WIN32
00160 // Linux needs this whereas Win32 does not
00161 // Set the new window's size
00162     if( SDL_SetVideoMode(
00163         rcsResizeEvent.w, rcsResizeEvent.h,
00164         gVars.guiVideoBpp, flags ) == 0 ) {
00165         OPENCITY_FATAL( "Video mode reset failed: " << SDL_GetError( ) );
00166         exit( -4 );
00167     }
00168     gVars.gpVideoSrf = SDL_GetVideoSurface();
00169 #endif
00170 
00171 // Save the new screen size
00172     gVars.guiScreenWidth = rcsResizeEvent.w;
00173     gVars.guiScreenHeight = rcsResizeEvent.h;
00174 
00175     if (uipCurrentUI != NULL) {
00176         uipCurrentUI->uiResize( rcsResizeEvent );
00177     }
00178 }
00179 
00180 
00181    /*=====================================================================*/
00182 void ocExpose( const SDL_ExposeEvent & rcsExposeEvent )
00183 {
00184     if (uipCurrentUI != NULL) {
00185         uipCurrentUI->uiExpose( rcsExposeEvent );
00186     }
00187 }
00188 
00189 
00190    /*=====================================================================*/
00191 void ocQuit( const int & quit_code )
00192 {
00193     cout << "Quit requested, quit code is : " << quit_code
00194          << endl
00195          << "Bye bye !"
00196          << endl;
00197     boolQuit = true;
00198 }
00199 
00200 
00201    /*=====================================================================*/
00202 void ocProcessSDLEvents( void )
00203 {
00204     static SDL_Event event;
00205 
00206 // Grab all the events off the queue.
00207     while( SDL_PollEvent( &event ) ) {
00208 
00209         switch( event.type ) {
00210         case SDL_KEYDOWN:
00211         case SDL_KEYUP:
00212             ocKeyboard( event.key );
00213             break;
00214 
00215         case SDL_MOUSEMOTION:
00216             ocMouseMotion( event.motion );
00217             break;
00218 
00219         case SDL_MOUSEBUTTONDOWN:
00220         case SDL_MOUSEBUTTONUP:
00221             ocMouseButton( event.button );
00222             break;
00223 
00224         case SDL_VIDEORESIZE:
00225             ocResize( event.resize );
00226             break;
00227 
00228         case SDL_VIDEOEXPOSE:
00229             ocExpose( event.expose );
00230             break;
00231 
00232         case SDL_QUIT:
00233         // Handle quit requests (like Ctrl-c).
00234             cout << "Quit requested, stoping OpenCity..." << endl;
00235             boolQuit = true;
00236             break;
00237         }
00238     }
00239 }
00240 
00241 
00242    /*=====================================================================*/
00243 void ocSetNewUI( UI * pcNewUI)
00244 {
00245     uipCurrentUI = pcNewUI;
00246 }
00247 
00248 
00249    /*=====================================================================*/
00250 void getFullScreenResolution(uint & w, uint & h)
00251 {
00252     SDL_Rect **modes;
00253     int i;
00254     
00255 // Get available fullscreen/hardware modes
00256     modes = SDL_ListModes(NULL, flags);
00257     
00258 // Check if there are any modes available
00259     if(modes == (SDL_Rect **)0) {
00260         OPENCITY_FATAL( "No fullscreen mode available !" );
00261         exit(-1);
00262     }
00263     
00264 // Check if our resolution is restricted
00265     if(modes == (SDL_Rect **)-1) {
00266     // Use the default fullscreen size
00267         OPENCITY_INFO( "All fullscreen resolutions available. ");
00268         w = OC_FULLSCREEN_WIDTH;
00269         h = OC_FULLSCREEN_HEIGHT;
00270     }
00271     else {
00272     // Print valid modes
00273         //printf("Available Modes\n");
00274         w = 0; h = 0;
00275         for (i = 0; modes[i]; ++i) {
00276             //printf("  %d x %d\n", modes[i]->w, modes[i]->h);
00277             if (modes[i]->w > w) {
00278                 w = modes[i]->w;
00279                 h = modes[i]->h;
00280             }
00281         } // for
00282         OPENCITY_INFO( "The autodetected resolution of " << w << "x" << h << " pixels is used." );
00283     } // else
00284 }
00285 
00286 
00287    /*=====================================================================*/
00288 int initSDL()
00289 {
00290 // Initialization of the SDL library
00291     OPENCITY_DEBUG( "SDL Initialization" );
00292 
00293 // First, initialize SDL's video subsystem.
00294     if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
00295         // Failed, exit.
00296         OPENCITY_FATAL( "SDL video initialization failed: " << SDL_GetError() );
00297         return -2;
00298     }
00299 
00300 // Set the SDL_GL_DoubleBuffer ON for smoother rendering
00301 // in addition, this is required for the implemented selection method
00302     SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
00303 
00304 // Set 8 bits for each color component
00305     SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
00306     SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
00307     SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
00308     SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
00309     SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
00310     flags = SDL_OPENGL | SDL_RESIZABLE | SDL_HWSURFACE;
00311 
00312 // Will we go for fullscreen ?
00313     if (gVars.gboolFullScreen == true) {
00314         flags |= SDL_FULLSCREEN;
00315     // IF autodetect THEN
00316         if (gVars.guiScreenWidth == 0 or gVars.guiScreenHeight == 0)
00317             getFullScreenResolution( gVars.guiScreenWidth, gVars.guiScreenHeight );
00318     }
00319     else {
00320     // Use the default screen size
00321         gVars.guiScreenWidth    = OC_WINDOW_WIDTH;
00322         gVars.guiScreenHeight   = OC_WINDOW_HEIGHT;
00323     }
00324 
00325 // OK, go for the video settings now
00326     gVars.gpVideoSrf = SDL_SetVideoMode( gVars.guiScreenWidth, gVars.guiScreenHeight, gVars.guiVideoBpp, flags );
00327     if ( gVars.gpVideoSrf == NULL ) {
00328     // This could happen for a variety of reasons,
00329     // including DISPLAY not being set, the specified
00330     // resolution not being available, etc.
00331         OPENCITY_ERROR( 
00332             "Initialization of 32 bpp video mode failed: " << SDL_GetError() 
00333         );
00334         OPENCITY_INFO( "Trying 16 bpp... " );
00335         gVars.guiVideoBpp = OC_WINDOW_BPP_16;
00336 
00337     // Set 5 bits for each color component
00338         SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
00339         SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 6 );
00340         SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
00341         SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 0 );
00342         gVars.gpVideoSrf = SDL_SetVideoMode( gVars.guiScreenWidth, gVars.guiScreenHeight, gVars.guiVideoBpp, flags );
00343 
00344         if (gVars.gpVideoSrf == NULL) {
00345             OPENCITY_FATAL( "16 bpp mode has failed: " << SDL_GetError() );
00346             return -4;
00347         }
00348         else {
00349             OPENCITY_INFO( "16 bpp works." );
00350         }
00351     }
00352 
00353 //debug cout << "W: " << gVars.gpVideoSrf->w << " /H: " << gVars.gpVideoSrf->h << endl;
00354 
00355 
00356 // Test for DoubleBuffer
00357     int iDblBuff = 0;
00358     SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &iDblBuff );
00359     if ( iDblBuff == 0 ) {
00360         OPENCITY_INFO( "Checking doublebuffer: failed !" );
00361         OPENCITY_FATAL( "We need doublebuffer" );
00362         return -6;
00363     }
00364     else {
00365         OPENCITY_INFO( "Checking doublebuffer: OK !" );
00366     }
00367 
00368     return 0;
00369 }
00370 
00371 
00372    /*=====================================================================*/
00373 void formatHomeDir()
00374 {
00375     string::size_type pos;
00376 
00377     if (sHomeDir.size() > 0) {
00378     // Delete all quotes "
00379         while ( (pos = sHomeDir.find( '\"' )) != sHomeDir.npos ) {
00380             sHomeDir.erase( pos );
00381         }
00382     // Append the "/" to HOMEDIR    
00383         if (sHomeDir[ sHomeDir.size()-1 ] != '/')
00384             sHomeDir += '/';
00385     }
00386     else {
00387         sHomeDir = "/";
00388     }
00389 }
00390 
00391 
00392    /*=====================================================================*/
00393 void parseArg(int argc, char *argv[])
00394 {
00395     int counter;
00396 
00397     counter = 0;
00398 
00399     while (++counter < argc) {
00400         if (strcmp( argv[counter], "--gl-version" ) == 0) {
00401             cout << "<OPTION> " << argv[counter] << " detected" << endl;
00402             if (gVars.gpVideoSrf == NULL) {
00403                 (void)initSDL();
00404             }
00405             printf("GL Vendor: '%s' \n", glGetString( GL_VENDOR ));
00406             printf("GL Renderer: '%s' \n", glGetString( GL_RENDERER ));
00407             printf("GL Version: '%s' \n", glGetString( GL_VERSION ));
00408             printf("GL Extensions: '%s' \n", glGetString( GL_EXTENSIONS ));
00409         } else
00410         if (strcmp( argv[counter], "--fullscreen" ) == 0) {
00411             cout << "<OPTION> " << argv[counter] << " detected" << endl;
00412             gVars.gboolFullScreen = true;
00413         } else
00414         if (strcmp( argv[counter], "--server" ) == 0) {
00415             cout << "<OPTION> " << argv[counter] << " detected" << endl;
00416             gVars.gboolServerMode = true;
00417         } else
00418         if (strcmp( argv[counter], "--homedir" ) == 0) {
00419             cout << "<OPTION> " << argv[counter] << " detected" << endl;
00420             if (++counter < argc)
00421                 sHomeDir = argv[counter];
00422             else
00423                 sHomeDir = "";
00424             formatHomeDir();
00425             cout << "<OPTION> HomeDir is: \"" << sHomeDir << "\"" << endl;
00426         }
00427         else {
00428             cout << "Unknown option: [" << argv[counter] << "]" << endl;
00429             cout << "Usage: " << argv[0]
00430                  << " [--fullscreen] [--gl-version] [--homedir newHomePath] [--server]"
00431                  << endl << endl;
00432             cout << "Warning: any command line switch will overwrite the config file settings"
00433                  << endl;
00434             exit(-1);
00435         }
00436     } // while
00437 }
00438 
00439 
00440    /*=====================================================================*/
00441 void displaySplash()
00442 {
00443     #define OC_SPLASH_CLEAR_COLOR       .15, .15, .3, 1.0
00444 
00445     glClearColor( OC_SPLASH_CLEAR_COLOR );
00446     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00447     gVars.gpRenderer->DisplaySplash();
00448 }
00449 
00450 
00451    /*=====================================================================*/
00452 void displayStatus( const string & str )
00453 {
00454     uint x, y;
00455 
00456     displaySplash();
00457 
00458 // Center the text on the screen
00459 //  x = (gVars.gpVideoSrf->w - 512)/2 + (512 - str.size()*10)/2;
00460     x = (gVars.gpVideoSrf->w - str.size()*10)/2;
00461     y = (gVars.gpVideoSrf->h - 140) / 2;
00462     gVars.gpRenderer->DisplayText( x, y, OC_BLUE_COLOR, str );
00463     SDL_GL_SwapBuffers();
00464 }
00465 
00466 
00467    /*=====================================================================*/
00468 int serverMode()
00469 {
00470     static SDL_Event event;
00471 
00472 // Initialize the video system in order to capture Ctrl-C !
00473     SDL_Init(SDL_INIT_VIDEO);
00474 
00475 // Start server and listen to the standard port
00476     gVars.gpNetworking = new Networking();
00477     boolQuit = (gVars.gpNetworking->StartServer() == OC_NET_OK) ? false : true;
00478 
00479     while (!boolQuit) {
00480         cout << ".";
00481         (void)gVars.gpNetworking->ProcessServerData();
00482         SDL_Delay( 50 );
00483         cout.flush();
00484 
00485         while( SDL_PollEvent( &event ) ) {
00486             switch( event.type ) {
00487             case SDL_QUIT:
00488             // Handle quit requests (like Ctrl-c).
00489                 cout << endl << "Quit requested, stoping OpenCity ZeN server..." << endl;
00490                 boolQuit = true;
00491                 break;
00492             }
00493         }
00494     }
00495 
00496     (void)gVars.gpNetworking->StopServer();
00497     delete gVars.gpNetworking;
00498 
00499     SDL_Quit();                 // WARNING: Calls free() on an invalid pointer. Detected by glibc
00500 
00501     return 0;
00502 }
00503 
00504 
00505    /*=====================================================================*/
00506 int clientMode()
00507 {
00508     int errCode;
00509 
00510 // Initialize SDL
00511     errCode = initSDL();
00512     if (errCode != 0) {
00513         return errCode;
00514     }
00515 
00516     
00517 // set the window's caption
00518     SDL_WM_SetCaption( PACKAGE " " VERSION, NULL );
00519     SDL_WM_SetIcon( IMG_Load(ocHomeDirPrefix("graphism/icon/OpenCity32.png").c_str()), NULL );
00520 
00521 
00522 // Create the mutex first
00523     gVars.gpmutexSim = SDL_CreateMutex();
00524 
00525 
00526 // Create the global renderer in order to use its text rendering functions
00527     gVars.gpRenderer = new Renderer( gVars.guiCityWidth, gVars.guiCityLength );
00528 
00529 /* debug
00530 // Test font
00531     glClearColor( OC_CLEAR_COLOR );
00532     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00533     gVars.gpRenderer->DisplayText( 10, 50, OC_WHITE_COLOR, "Hello world" );
00534     SDL_GL_SwapBuffers();
00535     SDL_Delay( 3000 );
00536 */
00537 
00538 
00539 // AudioManager's initialization
00540     displayStatus( "Looking for GPU freezing system... ");
00541     gVars.gpAudioMgr = new AudioManager();
00542 
00543     if ( gVars.gpAudioMgr == NULL ) {
00544         OPENCITY_FATAL( "Error while creating the audio manager" );
00545         return -16;
00546     } else
00547     if ( (gVars.gboolUseAudio == true)
00548       && (gVars.gpAudioMgr->OpenAudio() != OC_ERR_FREE))
00549     {
00550     // try to open the audio device IF we have successfully created an audio object
00551         OPENCITY_INFO( "Audio open error ! OpenCity continues happily." );
00552     }
00553 
00554 
00555 // Load musics and sounds
00556     displayStatus( "Warming up central processing unit...");
00557     gVars.gpAudioMgr->LoadMusicList( ocHomeDirPrefix(OC_MUSIC_LIST_FILENAME), ocHomeDirPrefix("") );
00558     OPENCITY_INFO( "Loaded " << gVars.gpAudioMgr->GetNumberMusic() << " musics." );
00559     gVars.gpAudioMgr->LoadSoundList( ocHomeDirPrefix(OC_SOUND_LIST_FILENAME), ocHomeDirPrefix("") );
00560     OPENCITY_INFO( "Loaded " << gVars.gpAudioMgr->GetNumberSound() << " sounds." );
00561 
00562 
00563 // Create the other required global managers
00564     displayStatus( "Activating embedded GPS...");
00565     gVars.gpMapMgr = new Map( gVars.guiCityWidth, gVars.guiCityLength );
00566 
00567     displayStatus( "Calibrating earthquake subsystem...");
00568     gVars.gpGraphicMgr = new GraphicManager();
00569 
00570     displayStatus( "Shaking DNA mixer thread...");
00571     gVars.gpPropertyMgr = new PropertyManager();
00572 
00573     displayStatus( "Mounting intergalactic hyperlink ...");
00574     gVars.gpNetworking = new Networking();
00575 
00576     displayStatus( "Initializing the particle handler ...");
00577     gVars.gpMoveMgr = new MovementManager( gVars.gpGraphicMgr, gVars.gpMapMgr );
00578 
00579 
00580 // the pointer of our new city
00581     City* pNewCity = new City( gVars.guiCityWidth, gVars.guiCityLength );
00582     if (pNewCity == NULL) {
00583         OPENCITY_FATAL( "Error while creating new city" );
00584         return (-15);
00585     }
00586     else {
00587         displayStatus( "Almost done...");
00588 // debug SDL_Delay( 5000 );
00589 
00590     // FIXME: buggy MAS
00591     /*
00592     // Create the necessary classes for the Multi-Agent System
00593         gVars.gpKernel = new Kernel();
00594         gVars.gpEnvironment = new Environment(
00595             gVars.guiCityWidth, gVars.guiCityLength, pNewCity->GetLayer( BUILDING_LAYER ), gVars.gpKernel );
00596 
00597         new AgentPolice(*gVars.gpKernel, *gVars.gpEnvironment, 1, 2);
00598         new AgentPolice(*gVars.gpKernel, *gVars.gpEnvironment, 3, 4);
00599         new AgentDemonstrator(*gVars.gpKernel, *gVars.gpEnvironment, 4, 2);
00600     */
00601 
00602         while (!boolQuit) {
00603         // running the city at the LAST_SPEED (default parameter)
00604             ocProcessSDLEvents();
00605             pNewCity->Run();
00606             //gVars.gpKernel->live();
00607 
00608 
00609 #undef OC_PRINT_FPS
00610 #ifndef OC_PRINT_FPS
00611             SDL_Delay( gVars.guiMsPerFrame );
00612 #else
00613             static Uint32 uiNumberTick = SDL_GetTicks();
00614             static uint uiNumberFrame = 0;
00615 
00616             uiNumberFrame++;
00617             if ((SDL_GetTicks() - uiNumberTick) > 5000) {
00618                 cout << uiNumberFrame << " frames per 5 seconds = "
00619                      << uiNumberFrame / 5 << " FPS" << endl;
00620                 uiNumberTick = SDL_GetTicks();
00621                 uiNumberFrame = 0;
00622             }
00623             SDL_Delay( gVars.guiMsPerFrame );
00624 #endif
00625         }
00626 
00627         //delete gVars.gpEnvironment;
00628         //delete gVars.gpKernel;
00629     }
00630 
00631 
00632 // Close the network connection
00633     gVars.gpNetworking->Close();
00634 
00635 // WARNING: the deleting/creating order is very important !
00636     delete pNewCity;
00637 
00638     delete gVars.gpMoveMgr;
00639     delete gVars.gpNetworking;
00640     delete gVars.gpPropertyMgr;
00641     delete gVars.gpGraphicMgr;
00642     delete gVars.gpMapMgr;
00643 
00644 // close the audio device then delete the audio manager
00645     gVars.gpAudioMgr->CloseAudio();
00646     delete gVars.gpAudioMgr;
00647 
00648     delete gVars.gpRenderer;
00649 
00650 // delete the simulators' mutex now
00651     SDL_DestroyMutex( gVars.gpmutexSim );
00652 
00653 //  SDL_FreeSurface( gVars.gpVideoSrf ); // This is not recommended by SDL documentation
00654     gVars.gpVideoSrf = NULL;
00655 
00656     SDL_Quit();                 // WARNING: Calls free() on an invalid pointer. Detected by glibc
00657     return errCode;
00658 }
00659 
00660 
00661    /*=====================================================================*/
00662 void printCopyright() {
00663 // Output the copyright text
00664     cout << "Welcome to " << PACKAGE << " version " << VERSION << endl;
00665     cout << "Copyright (C) by Duong-Khang NGUYEN. All rights reserved." << endl;
00666     cout << "   web  : http://www.opencity.info" << endl;
00667     cout << "   email: neoneurone @ users sf net" << endl << endl;
00668 
00669     cout << "This program is released under the terms of" << endl;
00670     cout << "GNU General Public License (See the COPYING file for more details)" << endl << endl;
00671 
00672     cout << "Starting ..." << endl << endl;
00673 }
00674 
00675 
00676    /*=====================================================================*/
00681 char* findSaveDir()
00682 {
00683     char* ret = NULL;
00684 
00685 #ifndef WIN32
00686 // Get the home directory from the environment variable
00687     char* env = getenv("HOME");
00688     if (env != NULL) {
00689         ret = (char*)malloc( strlen(env) + 1 );
00690         strcpy( ret, env );
00691     }
00692 #else
00693 // Find the directory: "C:\Documents and Settings\username\Application Data"
00694 // Required shell DLL version: 5.0 or later
00695 // header: shlobj.h
00696 // lib: shell32.lib ?
00697 // dll: shell32.dll
00698 
00699     TCHAR szPath[MAX_PATH];
00700     
00701     if(SUCCEEDED(
00702         SHGetFolderPath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, szPath)
00703         )) {
00704         ret = (char*)malloc( strlen(szPath) + 1 );
00705         strcpy( ret, szPath );
00706     }
00707 #endif
00708 
00709 // The required save directory does not exist, use the current directory
00710     if (ret == NULL) {
00711         ret = (char*)malloc( 2 );
00712         strcpy( ret, "." );
00713     }
00714 
00715     return ret;
00716 }
00717 
00718 
00719    /*=====================================================================*/
00723 /* 1st Nov, 06, kept for reference, old version
00724 int readConfig()
00725 {
00726     int retVal = 0;
00727     BrInitError brError;
00728     char* pTemp = NULL;
00729     Conf* pConf = new Conf();
00730 
00731 
00732 // IF the homedir is not set THEN try to get it from BinReloc routines
00733     if (sHomeDir == "") {
00734     // Init the BinReloc routines
00735         if (br_init(&brError) != 1) {
00736             OPENCITY_INFO(
00737                 "The initialization of BinReloc routines has failed." << endl
00738                  << "The error was: " << brError
00739             );
00740         }
00741         else {
00742         // Construct the datadir from the prefix
00743             pTemp = br_find_prefix( PREFIX );
00744             sHomeDir = pTemp;
00745             sHomeDir += "/share/";
00746             sHomeDir += PACKAGE;
00747             free(pTemp);
00748             formatHomeDir();
00749         }
00750     }
00751 
00752 // IF the save directory is not set the find it
00753     if (sSaveDir == "") {
00754         pTemp = findSaveDir();
00755         sSaveDir = pTemp;
00756         free(pTemp);
00757 #ifndef WIN32
00758         sSaveDir += "/.OpenCity/";
00759         mkdir( sSaveDir.c_str(), 0755 );
00760 #else
00761     // Win32 uses \ as directory separtor
00762         sSaveDir += "\\OpenCity\\";
00763         CreateDirectory( sSaveDir.c_str(), NULL );      
00764     // Replace \ by /
00765         string::size_type pos;
00766         while ( (pos = sSaveDir.find( '\\' )) != sSaveDir.npos ) {
00767             sSaveDir.replace( pos, 1, "/" );
00768         }
00769 #endif
00770     }
00771 
00772 
00773 // Now try to open the config file then read it
00774     OPENCITY_INFO(
00775         "Reading config file: \"" << ocHomeDirPrefix(OC_CONFIG_FILE_FILENAME) << "\""
00776     );
00777     if (pConf->Open(ocHomeDirPrefix(OC_CONFIG_FILE_FILENAME)) == OC_ERR_FREE) {
00778         bool bValue;
00779         OC_LINT liValue;
00780 
00781         // Fullscreen settings
00782         if (pConf->GetBool("FullScreen", bValue) == OC_ERR_FREE)
00783             gVars.gboolFullScreen |= bValue;
00784         if (pConf->GetLint("FullScreenWidth", liValue) == OC_ERR_FREE)
00785             gVars.guiScreenWidth = liValue;
00786         if (pConf->GetLint("FullScreenHeight", liValue) == OC_ERR_FREE)
00787             gVars.guiScreenHeight = liValue;
00788 
00789         if (pConf->GetBool("UseAudio", bValue) == OC_ERR_FREE)
00790             gVars.gboolUseAudio = bValue;
00791         if (pConf->GetLint("CityWidth", liValue) == OC_ERR_FREE)
00792             gVars.guiCityWidth = liValue;
00793         if (pConf->GetLint("CityLength", liValue) == OC_ERR_FREE)
00794             gVars.guiCityLength = liValue;
00795         if (pConf->GetLint("MsPerFrame", liValue) == OC_ERR_FREE)
00796             gVars.guiMsPerFrame = liValue;
00797 
00798         gVars.gsZenServer = pConf->GetValue("ZenServer", "localhost");
00799 
00800         pConf->Close();
00801         retVal = 0;
00802     }
00803     else {
00804         retVal = -1;
00805     }
00806 
00807     delete pConf;
00808     return retVal;
00809 }
00810 */
00811 
00812 
00813    /*=====================================================================*/
00817 void detectProgramPath()
00818 {
00819     char* pTemp = NULL;
00820     BrInitError brError;
00821 
00822 // IF the homedir is not set THEN try to get it from BinReloc routines
00823     if (sHomeDir == "") {
00824     // Init the BinReloc routines
00825         if (br_init(&brError) != 1) {
00826             OPENCITY_INFO(
00827                 "The initialization of BinReloc routines has failed." << endl
00828                  << "The error was: " << brError
00829             );
00830         }
00831         else {
00832         // Construct the datadir from the prefix
00833             pTemp = br_find_prefix( PREFIX );
00834             sHomeDir = pTemp;
00835             sHomeDir += "/share/";
00836             sHomeDir += PACKAGE;
00837             free(pTemp);
00838             formatHomeDir();
00839         }
00840     }
00841 
00842 // IF the save directory is not set the find it
00843     if (sSaveDir == "") {
00844         pTemp = findSaveDir();
00845         sSaveDir = pTemp;
00846         free(pTemp);
00847 #ifndef WIN32
00848         sSaveDir += "/.OpenCity/";
00849         mkdir( sSaveDir.c_str(), 0755 );
00850 #else
00851     // Win32 uses \ as directory separtor
00852         sSaveDir += "\\OpenCity\\";
00853         CreateDirectory( sSaveDir.c_str(), NULL );      
00854     // Replace \ by /
00855         string::size_type pos;
00856         while ( (pos = sSaveDir.find( '\\' )) != sSaveDir.npos ) {
00857             sSaveDir.replace( pos, 1, "/" );
00858         }
00859 #endif
00860     }
00861 }
00862 
00863 
00864    /*=====================================================================*/
00871 string readSettings()
00872 {
00873     string errorString = "";
00874     TiXmlDocument settings;
00875 
00876 // Now try to open the config file then read it
00877     OPENCITY_INFO(
00878         "Reading XML config file: \"" << ocHomeDirPrefix(OC_CONFIG_FILE_FILENAME) << "\""
00879     );
00880 
00881 // Load the settings file
00882     string fn = ocHomeDirPrefix(OC_CONFIG_FILE_FILENAME);
00883     if (!settings.LoadFile(fn)) {
00884         errorString = settings.ErrorDesc();
00885         return errorString;
00886     }
00887 
00888 // Error testing
00889     if (settings.Error()) {
00890         errorString = settings.ErrorDesc();
00891         return errorString;
00892     }
00893 
00894 // Get the root element
00895     TiXmlNode* pRoot = settings.RootElement();
00896     if (pRoot == NULL) {
00897         errorString = settings.ErrorDesc();
00898         return errorString;
00899     }
00900 
00901 // Parse the settings
00902     TiXmlElement* pElement = pRoot->FirstChildElement();
00903     int i = 0;
00904     const char* str = NULL;
00905     while (pElement != NULL)
00906     {
00907 // Debug
00908 //      cout << i++ << "||" << *pElement << std::endl;
00909     // "fullscreen" element
00910         if (pElement->ValueStr() == "fullscreen") {
00911             str = pElement->Attribute("enable");
00912             if (str != NULL && strcmp(str, "true") == 0) {
00913                 gVars.gboolFullScreen |= true;
00914             }
00915             else {
00916                 gVars.gboolFullScreen |= false;
00917             }
00918 
00919             // IF fullscreen mode enabled THEN read size
00920             if (gVars.gboolFullScreen) {
00921                 TiXmlElement* pChild = pElement->FirstChildElement();
00922                 while (pChild != NULL) {
00923                     if (pChild->ValueStr() == "width") {
00924                         pChild->QueryIntAttribute("value", (int*)&gVars.guiScreenWidth);
00925                     }
00926                     else if (pChild->ValueStr() == "height") {
00927                         pChild->QueryIntAttribute("value", (int*)&gVars.guiScreenHeight);
00928                     }
00929                     pChild = pChild->NextSiblingElement();
00930                 }
00931             }
00932         }
00933     // "audio" element
00934         else if (pElement->ValueStr() == "audio") {
00935             str = pElement->Attribute("enable");
00936             if (str != NULL && strcmp(str, "true") == 0) {
00937                 gVars.gboolUseAudio = true;
00938             }
00939         }
00940     // "city" element, read the city's size
00941         if (pElement->ValueStr() == "city") {
00942             TiXmlElement* pChild = pElement->FirstChildElement();
00943             while (pChild != NULL) {
00944                 cout << i++ << "||" << *pChild << std::endl;
00945                 if (pChild->ValueStr() == "width") {
00946                     pChild->QueryIntAttribute("value", (int*)&gVars.guiCityWidth);
00947                 }
00948                 else if (pChild->ValueStr() == "length") {
00949                     pChild->QueryIntAttribute("value", (int*)&gVars.guiCityLength);
00950                 }
00951                 pChild = pChild->NextSiblingElement();
00952             }
00953         }
00954     // "msPerFrame" element
00955         if (pElement->ValueStr() == "msPerFrame") {
00956             pElement->QueryIntAttribute("value", (int*)&gVars.guiMsPerFrame);
00957         }
00958     // "zenServer" element
00959         if (pElement->ValueStr() == "zenServer") {
00960             if (pElement->GetText() != NULL)
00961                 gVars.gsZenServer = pElement->GetText();
00962         }
00963 
00964         pElement = pElement->NextSiblingElement();
00965     }
00966 
00967     return errorString;
00968 }
00969 
00970 
00971    /*=====================================================================*/
00972 void initGlobalVar()
00973 {
00974 // Config file and command line options
00975     gVars.gboolUseAudio             = false;
00976     gVars.gboolFullScreen           = false;
00977     gVars.gboolServerMode           = false;
00978     gVars.guiCityWidth              = OC_CITY_W;
00979     gVars.guiCityLength             = OC_CITY_L;
00980     gVars.guiMsPerFrame             = OC_MS_PER_FRAME;
00981     gVars.guiScreenWidth            = OC_WINDOW_WIDTH;
00982     gVars.guiScreenHeight           = OC_WINDOW_HEIGHT;
00983     gVars.guiVideoBpp               = OC_WINDOW_BPP_DEFAULT;
00984 
00985     gVars.gfMsSimDelayMax           = 0;
00986     gVars.gsZenServer               = "localhost";
00987 
00988 // The mutex that all the simulators depend on
00989     gVars.gpmutexSim                = NULL;
00990 
00991 // The famous renderer
00992     gVars.gpRenderer                = NULL;
00993 
00994 // Datamanagers
00995     gVars.gpAudioMgr                = NULL;     // global Audio Manager
00996     gVars.gpGraphicMgr              = NULL;     // global Graphic Manager
00997     gVars.gpPropertyMgr             = NULL;     // global Property Manager
00998     gVars.gpMapMgr                  = NULL;     // global height Map Manager
00999     gVars.gpNetworking              = NULL;     // global networking support class
01000     gVars.gpPathFinder              = NULL;     // global pathfinder class
01001     gVars.gpMoveMgr                 = NULL;     // global movement manager
01002 
01003 // Multi-Agent System
01004     gVars.gpKernel                  = NULL;     // global MAS Kernel
01005     gVars.gpEnvironment             = NULL;     // global Environement class
01006 
01007 // The SDL video surface
01008     gVars.gpVideoSrf                = NULL;     // global video screen surface
01009 }
01010 
01011 
01012    /*=====================================================================*/
01013 #if defined(WIN32) || defined(_WIN32)
01014 extern "C"
01015 #endif
01016 int main(int argc, char *argv[])
01017 {
01018 // Initialize the global settings variable to the default values
01019     initGlobalVar();
01020 
01021 // Print out the copyright
01022     printCopyright();
01023 
01024 // Parse the command-line options
01025     parseArg( argc, argv );
01026 
01027 // Detect the main path: sHomeDir and sSaveDir
01028     detectProgramPath();
01029 
01030 // TOKILL, old version, .conf config file, 1st Nov, 06
01031 // Read the main config file
01032 //  if (readConfig() != 0)
01033 
01034 // Read the application settings from the XML settings file
01035     string errorDesc = readSettings();
01036     if (errorDesc != "") {
01037         OPENCITY_FATAL(
01038             "The was an error while loading the settings file: \"" << errorDesc << "\"" << endl
01039             << "If the main config file \"" << OC_CONFIG_FILE_FILENAME << "\" has not been found then" << endl
01040             << "try to specify the home directory with ""--homedir""." << endl
01041             << "For example:" << endl
01042             << "    opencity --homedir \"/absolute/path/to/opencity/data\"" << endl
01043             << "or" << endl
01044             << "    opencity --homedir \"../relative/path/to/opencity/data\"" << endl
01045         );
01046         exit(OC_CONFIG_NOT_FOUND);
01047     }
01048 
01049 // Initialization of global variables
01050     uipCurrentUI = NULL;
01051     gVars.gfMsSimDelayMax = log10((OC_FLOAT)gVars.guiCityWidth*gVars.guiCityLength + 1) * OC_MS_GLOBAL_LOG_FACTOR;
01052 
01053 // Initialize the random number generator
01054     srand( time(NULL) );
01055 
01056 // Launch either client or server mode
01057     int returnCode = 0;
01058     if (gVars.gboolServerMode == true)
01059         returnCode = serverMode();
01060     else
01061         returnCode = clientMode();
01062 
01063     return returnCode;
01064 }
01065 
01066 
01067    /*=====================================================================*/
01068    /*                       GLOBAL       FUNCTIONS                        */
01069    /*=====================================================================*/
01070 string
01071 ocHomeDirPrefix( const string & s )
01072 {
01073     return sHomeDir + s;
01074 }
01075 
01076 
01077    /*=====================================================================*/
01078 string
01079 ocSaveDirPrefix( const string & s )
01080 {
01081     return sSaveDir + s;
01082 }
01083 
01084 
01085 
01086 
01087 
01088 
01089 
01090 
01091 
01092 
01093 
01094 
01095 
01096 
01097 
01098 
01099 
01100 
01101 
01102 
01103 
01104 
01105 
01106 

Generated on Sat Nov 11 10:21:10 2006 for OpenCity by  doxygen 1.4.2