sg.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                            sg.cpp  -  description
00003                              -------------------
00004     begin                : a long time ago...
00005     copyright            : (C) 1994-2010 by Martin Bickel
00006     email                : bickel@asc-hq.org
00007  ***************************************************************************/
00008 
00014 /***************************************************************************
00015  *                                                                         *
00016  *   This program is free software; you can redistribute it and/or modify  *
00017  *   it under the terms of the GNU General Public License as published by  *
00018  *   the Free Software Foundation; either version 2 of the License, or     *
00019  *   (at your option) any later version.                                   *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00075 #include "global.h"
00076 
00077 #include <stdio.h>
00078 #include <stdlib.h>
00079 #include <new>
00080 #include <cstdlib>
00081 #include <ctype.h>
00082 #include <algorithm>
00083 #include <memory>
00084 #include <fstream>
00085 
00086 #include <boost/regex.hpp>
00087 #include <boost/algorithm/string/split.hpp>
00088 #include <boost/algorithm/string/classification.hpp>
00089 
00090 #include "paradialog.h"
00091 
00092 #include "vehicletype.h"
00093 #include "buildingtype.h"
00094 #include "ai/ai.h"
00095 #include "misc.h"
00096 #include "events.h"
00097 #include "typen.h"
00098 #include "spfst.h"
00099 #include "loaders.h"
00100 #include "dlg_box.h"
00101 #include "controls.h"
00102 #include "dlg_box.h"
00103 #include "dialog.h"
00104 #include "strtmesg.h"
00105 #include "gamedlg.h"
00106 #include "sg.h"
00107 #include "gameoptions.h"
00108 #include "loadimage.h"
00109 #include "astar2.h"
00110 #include "errors.h"
00111 #include "dialogs/pwd_dlg.h"
00112 #include "viewcalculation.h"
00113 #include "replay.h"
00114 #include "graphicset.h"
00115 #include "loadbi3.h"
00116 #include "itemrepository.h"
00117 #include "music.h"
00118 #include "messagedlg.h"
00119 #include "statisticdialog.h"
00120 #include "clipboard.h"
00121 #include "guifunctions.h"
00122 #include "iconrepository.h"
00123 #include "dashboard.h"
00124 #include "gamedialog.h"
00125 #include "unitset.h"
00126 #include "applicationstarter.h"
00127 #include "replaymapdisplay.h"
00128 
00129 #ifdef WEATHERGENERATOR
00130 # include "weathercast.h"
00131 #endif
00132 
00133 #include "asc-mainscreen.h"
00134 #include "dialogs/unitinfodialog.h"
00135 #include "util/messaginghub.h"
00136 #include "cannedmessages.h"
00137 #include "memorycheck.cpp"
00138 #include "networkinterface.h"
00139 #include "resourcenet.h"
00140 #include "mapimageexport.h"
00141 #include "loadpcx.h"
00142 #include "gameeventsystem.h"
00143 #include "sdl/sound.h"
00144 #include "soundList.h"
00145 #include "turncontrol.h"
00146 #include "networksupervisor.h"
00147 
00148 #include "dialogs/newgame.h"
00149 #include "dialogs/soundsettings.h"
00150 #include "dialogs/alliancesetup.h"
00151 #include "dialogs/unitcounting.h"
00152 #include "dialogs/editgameoptions.h"
00153 #include "dialogs/nextcampaignmap.h"
00154 #include "dialogs/terraininfo.h"
00155 #include "dialogs/editplayerdata.h"
00156 #include "dialogs/locatefile.h"
00157 #include "dialogs/infodialogs.h"
00158 #include "stdio-errorhandler.h"
00159 #include "widgets/textrenderer.h"
00160 #include "dialogs/productionanalysis.h"
00161 #include "dialogs/fileselector.h"
00162 #include "containerbase-functions.h"
00163 #include "memory-measurement.h"
00164 #include "dialogs/mailoptionseditor.h"
00165 #include "dialogs/unitguidedialog.h"
00166 #include "actions/cancelresearchcommand.h"
00167 #include "actions/diplomacycommand.h"
00168 #include "gameevent_dialogs.h"
00169 #include "actions/commandwriter.h"
00170 #include "dialogs/actionmanager.h"
00171 #include "dialogs/gotoposition.h"
00172 #include "loggingoutput.h"
00173 #include "contextutils.h"
00174 #include "actions/taskinterface.h"
00175 #include "tasks/taskcontainer.h"
00176 #include "dialogs/taskmanager.h"
00177 #include "autotraining.h"
00178 #include "spfst-legacy.h"
00179 
00180 #include "lua/luarunner.h"
00181 #include "lua/luastate.h"
00182 #include "luacommandwriter.h"
00183 #include "campaignactionrecorder.h"
00184 #include "textfiletags.h"
00185 #include "dataversioncheck.h"
00186 #include "packagemanager.h"
00187 #include "i18n.h"
00188 
00189 #ifdef WIN32
00190 # include "win32/win32-errormsg.h"
00191 # include  "win32/msvc/mdump.h"
00192  MiniDumper miniDumper( "main" );
00193 # include <direct.h>
00194 # include <stdlib.h>
00195 # include <stdio.h>
00196 #endif
00197 
00198 MapField*        getSelectedField(void)
00199 {
00200    return actmap->getField( actmap->getCursor() ); 
00201 } 
00202 
00203 
00204 #define mmaintainence
00205 
00206 bool maintainencecheck( void )
00207 {
00208    int res = 0;
00209    if ( res )
00210       return true;
00211 
00212 #ifdef maintainence
00213    int num = 0;
00214 
00215    for ( int i = 0; i < 8; i++ )
00216       if ( actmap->player[i].stat == Player::human  && actmap->player[i].exist())
00217          num++;
00218 
00219    if ( actmap->campaign )
00220       num++;
00221 
00222    if ( actmap->network )
00223       num++;
00224 
00225    if ( num <= 1 )
00226       return 1;
00227    else
00228       return 0;
00229 
00230 #else
00231    return false;
00232 #endif
00233 }
00234 
00235 
00236 void positionCursor( Player& player )
00237 {
00238    getDefaultMapDisplay().displayPosition( player.getParentMap()->getCursor() );
00239 }
00240 
00241 void viewcomp( Player& player )
00242 {
00243    computeview( player.getParentMap() );
00244 }
00245 
00246 
00247 void runOpenTasks()
00248 {
00249    GameMap* map = actmap;
00250    
00251    if ( map->tasks ) {
00252       TaskContainer* tc = dynamic_cast<TaskContainer*>( map->tasks );
00253       if ( tc ) {
00254          while ( tc->pendingCommands.begin() != tc->pendingCommands.end() ) {
00255             Command* c = tc->pendingCommands.front();
00256             TaskInterface* ti = dynamic_cast<TaskInterface*>( c );
00257             
00258             if ( ti->operatable() ) {
00259                ActionResult res = c->execute( createFollowerContext( map ));
00260                if ( !res.successful() )
00261                   dispmessage2(res);
00262             }
00263             
00264             tc->pendingCommands.erase( tc->pendingCommands.begin() );
00265          }
00266       }
00267    }
00268 }
00269 
00270 
00271 void runPendingTasks( Player& player )
00272 {
00273    GameMap* map = player.getParentMap();
00274    if ( map->tasks ) {
00275       TaskContainer* tc = dynamic_cast<TaskContainer*>( map->tasks );
00276       if ( tc ) 
00277          if( tc->pendingCommands.begin() != tc->pendingCommands.end() ) 
00278             if (choice_dlg("run pending tasks ?","~y~es","~n~o") == 1)
00279                runOpenTasks(); 
00280    }
00281 }
00282 
00283 
00284 
00285 void hookGuiToMap( GameMap* map )
00286 {
00287    if ( !map->getGuiHooked() ) {
00288 
00289       map->sigPlayerUserInteractionBegins.connect( SigC::slot( &viewcomp ) );
00290       map->sigPlayerUserInteractionBegins.connect( SigC::hide<Player&>( repaintMap.slot() ));
00291       
00292       map->sigPlayerUserInteractionBegins.connect( SigC::slot( &positionCursor ));
00293       map->sigPlayerUserInteractionBegins.connect( SigC::hide<Player&>( SigC::slot( &checkforreplay )));
00294       map->sigPlayerUserInteractionBegins.connect( SigC::slot( &checkForNewResearch ));
00295       map->sigPlayerUserInteractionBegins.connect( SigC::slot( &viewunreadmessages ));
00296       map->sigPlayerUserInteractionBegins.connect( SigC::slot( &checkJournal ));
00297       map->sigPlayerUserInteractionBegins.connect( SigC::slot( &checkUsedASCVersions ));
00298       map->sigPlayerUserInteractionBegins.connect( SigC::hide<Player&>( updateFieldInfo.slot() ));
00299 
00300       map->sigPlayerUserInteractionEnds.connect( SigC::slot( &runPendingTasks ));
00301 
00302       map->sigPlayerTurnHasEnded.connect( SigC::slot( viewOwnReplay));
00303       map->guiHooked();
00304    }
00305 }
00306 
00307 bool loadGameFromFile( const ASCString& filename )
00308 {
00309    GameMap* m = mapLoadingExceptionChecker( filename, MapLoadingFunction( tsavegameloaders::loadGameFromFile ));
00310    if ( !m )
00311       return false;
00312 
00313    delete actmap;
00314    actmap = m;
00315    actmap->levelfinished = false;
00316 
00317    if ( actmap->replayinfo ) {
00318       if ( actmap->replayinfo->actmemstream )
00319          displaymessage2( "actmemstream already open at begin of turn ",2 );
00320 
00321       if ( actmap->replayinfo->guidata[actmap->actplayer] )
00322          actmap->replayinfo->actmemstream = new MemoryStream ( actmap->replayinfo->guidata[actmap->actplayer], tnstream::appending );
00323       else {
00324          actmap->replayinfo->guidata[actmap->actplayer] = new MemoryStreamStorage;
00325          actmap->replayinfo->actmemstream = new MemoryStream ( actmap->replayinfo->guidata[actmap->actplayer], tnstream::writing );
00326       }
00327    }
00328    
00329    computeview( actmap );
00330    hookGuiToMap ( actmap );
00331    return true;
00332 }
00333 
00334 
00335 
00336 
00337 bool loadGame( bool mostRecent )
00338 {
00339    ASCString s1;
00340    if ( mostRecent ) {
00341       int datefound = 0;
00342 
00343       tfindfile ff ( savegameextension );
00344       tfindfile::FileInfo fi;
00345       while ( ff.getnextname( fi ))
00346          if ( fi.date > datefound ) {
00347             datefound = fi.date;
00348             s1 = fi.name;
00349          }
00350    } else {
00351      // s1 = selectFile( savegameextension, true );
00352            s1 = selectSavegame( savegameextension, true );
00353    }
00354 
00355    if ( !s1.empty() ) {
00356       StatusMessageWindowHolder smw = MessagingHub::Instance().infoMessageWindow( "loading " + s1 );
00357 
00358       loadGameFromFile( s1 );
00359       
00360       updateFieldInfo();
00361       positionCursor( actmap->getCurrentPlayer() );
00362       getDefaultMapDisplay().displayPosition( actmap->getCursor() );
00363       displaymap();
00364 
00365       return true;
00366    } else
00367       return false;
00368 }
00369 
00370 
00371 void saveGame( bool as )
00372 {
00373    if ( !actmap )
00374       return;
00375 
00376    ASCString s1;
00377 
00378    int nameavail = 0;
00379    if ( !actmap->preferredFileNames.savegame[actmap->actplayer].empty() )
00380       nameavail = 1;
00381 
00382    if ( as || !nameavail ) {
00383       s1 = selectSavegame( savegameextension, false);
00384    } else
00385       s1 = actmap->preferredFileNames.savegame[actmap->actplayer];
00386 
00387    if ( !s1.empty() ) {
00388       actmap->preferredFileNames.savegame[actmap->actplayer] = s1;
00389 
00390       StatusMessageWindowHolder smw = MessagingHub::Instance().infoMessageWindow( "saving " + s1 );
00391       savegame( s1, actmap );
00392    }
00393 }
00394 
00395 
00396 
00397 
00398 void loadmap( const ASCString& name, bool campaign )
00399 {
00400    GameMap* m = mapLoadingExceptionChecker( name, MapLoadingFunction( tmaploaders::loadmap ));
00401    delete actmap;
00402    actmap = m;
00403    computeview( actmap );
00404    hookGuiToMap( actmap );
00405    if ( !campaign )
00406       actmap->campaign.avail = false;
00407 }
00408 
00409 
00410 enum MapTypeLoaded { None, Map, Savegame, Mailfile };
00411 
00412 MapTypeLoaded loadStartupMap ( const char *gameToLoad=NULL )
00413 {
00414    if ( gameToLoad && gameToLoad[0] ) {
00415       try {
00416          if ( patimat ( ASCString("*")+tournamentextension, gameToLoad )) {
00417 
00418             if( validateemlfile( gameToLoad ) == 0 )
00419                fatalError( "Email gamefile %s is invalid. Aborting.", gameToLoad );
00420 
00421             try {
00422                GameMap* map = continueNetworkGame( ASCString(gameToLoad) );
00423                if ( map ) {
00424                   delete actmap;
00425                   actmap = map; 
00426                   hookGuiToMap(actmap);
00427                }
00428 
00429                return Mailfile;
00430             } catch ( tfileerror ) {
00431                fatalError ( "%s is not a legal email game.", gameToLoad );
00432             }
00433          } else if( patimat ( savegameextension, gameToLoad )) {
00434             if( validatesavfile( gameToLoad ) == 0 )
00435                fatalError ( "The savegame %s is invalid. Aborting.", gameToLoad );
00436 
00437             try {
00438                loadGameFromFile( gameToLoad );
00439                computeview( actmap );
00440                return Savegame;
00441             } catch ( tfileerror ) {
00442                fatalError ( "%s is not a legal savegame. ", gameToLoad );
00443             }
00444 
00445          } else if( patimat ( mapextension, gameToLoad )) {
00446             if( validatemapfile( gameToLoad ) == 0 )
00447                fatalError ( "Mapfile %s is invalid. Aborting.", gameToLoad );
00448 
00449             try {
00450                loadmap( gameToLoad, false );
00451             } catch ( tfileerror ) {
00452                fatalError ( "%s is not a legal map. ", gameToLoad );
00453             }
00454          } else
00455             fatalError ( "Don't know how to handle the file %s ", gameToLoad );
00456 
00457       }
00458       catch ( InvalidID err ) {
00459          displaymessage( err.getMessage(), 2 );
00460       } /* endcatch */
00461       catch ( tinvalidversion err ) {
00462          if ( err.expected < err.found )
00463             displaymessage( "File/module %s has invalid version.\nExpected version %d\nFound version %d\nPlease install the latest version from www.asc-hq.org", 2, err.getFileName().c_str(), err.expected, err.found );
00464          else
00465             displaymessage( "File/module %s has invalid version.\nExpected version %d\nFound version %d\nThis is a bug, please report it!", 2, err.getFileName().c_str(), err.expected, err.found );
00466       }
00467    } else {  // resort to loading defaults
00468 
00469       ASCString s = CGameOptions::Instance()->startupMap; 
00470 
00471       if ( s.empty() )
00472          s = "asc001.map";
00473 
00474 
00475       int maploadable;
00476       {
00477          tfindfile ff ( s );
00478          string filename = ff.getnextname();
00479          maploadable = validatemapfile ( filename );
00480       }
00481 
00482       if ( !maploadable ) {
00483 
00484          tfindfile ff ( mapextension );
00485          string filename = ff.getnextname();
00486 
00487          if ( filename.empty() )
00488             displaymessage( "unable to load startup-map",2);
00489 
00490          while ( !validatemapfile ( filename ) ) {
00491             filename = ff.getnextname();
00492             if ( filename.empty() )
00493                displaymessage( "unable to load startup-map",2);
00494 
00495          }
00496          s = filename;
00497       }
00498 
00499       loadmap( s, true );
00500       return Map;
00501       displayLogMessage ( 6, "done\n" );
00502    }
00503 
00504    return None;
00505 }
00506 
00507 
00508 void         startnextcampaignmap( int id)
00509 {
00510    GameMap* map = nextCampaignMap( id );
00511    delete actmap;
00512    actmap = map;
00513 
00514    if ( actmap ) {
00515       computeview( actmap );
00516       hookGuiToMap( actmap );
00517       repaintMap();
00518       
00519       if ( CGameOptions::Instance()->recordCampaignMaps ) 
00520          actmap->actionRecorder = new  CampaignActionLogger( actmap );
00521       
00522    }
00523 }
00524 
00525 
00526 void benchgame ( bool withViewCalc )
00527 {
00528    int t2;
00529    int t = ticker;
00530    int n = 0;
00531    do {
00532       if ( withViewCalc ) 
00533          computeview( actmap );
00534 
00535       repaintMap();
00536             
00537       n++;
00538       t2 = ticker;
00539    } while ( t + 1000 > t2 ); /* enddo */
00540    double d = 100 * n;
00541    d /= (t2-t);
00542    char buf[100];
00543    sprintf ( buf, "%3.1f fps", d );
00544    infoMessage ( buf );
00545 }
00546 
00547 
00548 
00549 
00550 
00551 void changePassword( GameMap* gamemap )
00552 {
00553    if ( Player::getHumanPlayerNum( gamemap) < 2 ) {
00554       infoMessage ("Passwords are only used for multiplayer games");
00555       return;
00556    }
00557 
00558    bool success;
00559    do {
00560       Password oldpwd = gamemap->player[gamemap->actplayer].passwordcrc;
00561       gamemap->player[gamemap->actplayer].passwordcrc.reset();
00562       success = enterpassword ( gamemap->player[gamemap->actplayer].passwordcrc, true, true );
00563       if ( !success )
00564          gamemap->player[gamemap->actplayer].passwordcrc = oldpwd;
00565    } while ( gamemap->player[gamemap->actplayer].passwordcrc.empty() && success && viewtextquery ( 910, "warning", "~e~nter password", "~c~ontinue without password" ) == 0 ); /* enddo */
00566 }
00567 
00568 
00569 void helpAbout()
00570 {
00571    ASCString s = "#fontsize=22#Advanced Strategic Command#fontsize=14#\n";
00572    s += getVersionAndCompilation();
00573 
00574    s += "\n#fontsize=18#Credits#fontsize=14#\n";
00575 
00576    s += readtextmessage( 30 );
00577                      
00578    ViewFormattedText vft( "About", s, PG_Rect(-1,-1,450,550));
00579    vft.Show();
00580    vft.RunModal();
00581 }
00582 
00583 
00584 
00585 void undo()
00586 {
00587    if ( actmap ) {
00588       resetActiveGuiAction( actmap );
00589       actmap->actions.undo( createContext( actmap ) );  
00590       displaymap();
00591       mapChanged(actmap);
00592       updateFieldInfo();
00593    }
00594 }
00595 
00596 void redo()
00597 {
00598    if ( actmap ) {
00599       resetActiveGuiAction( actmap );
00600       actmap->actions.redo( createContext( actmap ) );  
00601       displaymap();
00602       mapChanged(actmap);
00603       updateFieldInfo();
00604    }
00605 }
00606 
00607 
00608 bool continueAndStartMultiplayerGame( bool mostRecent = false )
00609 {
00610    GameMap* map = continueNetworkGame( mostRecent );
00611    if ( map ) {
00612       delete actmap;
00613       actmap = map;
00614       hookGuiToMap(actmap);
00615       actmap->sigPlayerUserInteractionBegins( actmap->player[actmap->actplayer] );
00616       displaymap();
00617       return true;
00618    } else
00619       return false;
00620 }
00621 
00622 
00623 
00624 
00625 void writeLuaCommands()
00626 {
00627    ASCString filename =  selectFile("*.lua", false );
00628    if ( !filename.empty() ) {
00629       LuaCommandFileWriter writer ( filename );
00630       actmap->actions.getCommands( writer );
00631    }
00632 }
00633 
00634 void selectAndRunLuaScript()
00635 {
00636    ASCString file = selectFile( "*.lua", true );
00637    if ( file.size() ) {
00638       LuaState state;
00639       LuaRunner runner( state );
00640       runner.runFile( file );
00641       if ( !runner.getErrors().empty() )
00642          errorMessage( runner.getErrors() );
00643       updateFieldInfo();
00644    }
00645 }
00646 
00647 
00648 void showUnitAiProperties()
00649 {
00650    MapField* fld = getSelectedField();
00651    if ( fld->vehicle && fieldvisiblenow(fld ) ) {
00652       Vehicle* v = fld->vehicle;
00653       ASCString s;
00654       s += "Unit nwid = " + ASCString::toString( v->networkid ) + "\n";
00655 
00656       AiParameter* a = NULL;
00657 
00658       for ( int i = 0; i < 8; ++i )
00659          if ( v->aiparam[i] ) {
00660          a = v->aiparam[i];
00661          break;
00662          }
00663 
00664          s += "Task = " + ASCString(AItasks[(int)a->getTask() ]) + "\n";
00665          s += "Job = " + ASCString(AIjobs[(int)a->getJob() ]) + "\n";
00666 
00667 
00668          s += "Destination: ";
00669          if ( a->dest.valid() )
00670             s += a->dest.toString();
00671          s += "\n";
00672 
00673          ViewFormattedText vat ( "AI properties", s, PG_Rect( 20, -1 , 450, 480 ));
00674          vat.Show();
00675          vat.RunModal();
00676    }
00677 }
00678 
00679 
00680 void showUsedPackages()
00681 {
00682    PackageManager::storeData( actmap );
00683    if ( actmap->packageData ) {
00684       ASCString s;
00685       for ( PackageData::Packages::const_iterator i  = actmap->packageData->packages.begin(); i != actmap->packageData->packages.end(); ++i ) {
00686          s += "#fontsize=14#" + i->second->name + "#fontsize=11#\n";
00687          s += i->second->description;
00688          s += "\n\n";
00689       }
00690 
00691       ViewFormattedText vat ( "Used Packages", s, PG_Rect( 20, -1 , 450, 480 ));
00692       vat.Show();
00693       vat.RunModal();
00694    }
00695 }
00696 
00697 
00698 class CommandAllianceSetupStrategy : public AllianceSetupWidget::ApplyStrategy {
00699    virtual void sneakAttack ( GameMap* map, int actingPlayer, int towardsPlayer )
00700    {
00701       auto_ptr<DiplomacyCommand> dc ( new DiplomacyCommand( map->player[actingPlayer]));
00702       dc->sneakAttack( map->getPlayer( towardsPlayer ));
00703       ActionResult res = dc->execute( createContext(actmap) );
00704       if ( res.successful() )
00705          dc.release();
00706       else
00707          displayActionError( res );
00708    }
00709 
00710    virtual void setState ( GameMap* map, int actingPlayer, int towardsPlayer, DiplomaticStates newState )
00711    {
00712       auto_ptr<DiplomacyCommand> dc ( new DiplomacyCommand( map->player[actingPlayer]));
00713       dc->newstate( newState, map->getPlayer( towardsPlayer ));
00714       ActionResult res = dc->execute( createContext(actmap) );
00715       if ( res.successful() )
00716          dc.release();
00717       else
00718          displayActionError( res );
00719    }
00720 };
00721 
00722 
00723 void editAlliances()
00724 {
00725    CommandAllianceSetupStrategy cass;
00726    if ( setupalliances( actmap, &cass, actmap->getCurrentPlayer().stat == Player::supervisor ) ) {
00727       if ( computeview( actmap ))
00728          displaymap();
00729    }
00730 }
00731 
00732 
00737 void chooseTechnologyIfAvail( Player& player )
00738 {
00739    if ( player.research.activetechnology ) {
00740       infoMessage("You are already researching " + player.research.activetechnology->name);
00741    } else {
00742       if ( !player.research.progress )
00743          infoMessage("You don't have any research points to spend");
00744       else {
00745          checkForNewResearch( player );
00746       }
00747    }
00748 }
00749 
00750 
00751 
00752 
00753 
00754 // user actions using the old event system
00755 void executeUserAction ( tuseractions action )
00756 {
00757    switch ( action ) {
00758       case ua_repainthard  :
00759       case ua_repaint      :
00760          repaintDisplay();
00761          break;
00762 
00763       case ua_help         :
00764          help(20);
00765          break;
00766 
00767       case ua_howtostartpbem :
00768          help(21);
00769          break;
00770 
00771       case ua_howtocontinuepbem :
00772          help(22);
00773          break;
00774 
00775 /*
00776       case ua_mntnc_morefog:
00777          if (actmap->weather.fog < 255   && maintainencecheck() ) {
00778             actmap->weather.fog++;
00779             computeview( actmap );
00780             displaymessage2("fog intensity set to %d ", actmap->weather.fog);
00781             displaymap();
00782          }
00783          break;
00784 
00785       case ua_mntnc_lessfog:
00786          if (actmap->weather.fog  && maintainencecheck()) {
00787             actmap->weather.fog--;
00788             computeview( actmap );
00789             displaymessage2("fog intensity set to %d ", actmap->weather.fog);
00790             displaymap();
00791          }
00792          break;
00793 
00794       case ua_mntnc_morewind:
00795          if ((actmap->weather.windSpeed < 254) &&  maintainencecheck()) {
00796             actmap->weather.windSpeed+=2;
00797             displaywindspeed (  );
00798             updateFieldInfo();
00799          }
00800          break;
00801 
00802       case ua_mntnc_lesswind:
00803          if ((actmap->weather.windSpeed > 1)  && maintainencecheck() ) {
00804             actmap->weather.windSpeed-=2;
00805             displaywindspeed (  );
00806             updateFieldInfo();
00807          }
00808          break;
00809 
00810       case ua_mntnc_rotatewind:
00811          if ( maintainencecheck() ) {
00812             if (actmap->weather.windDirection < sidenum-1 )
00813                actmap->weather.windDirection++;
00814             else
00815                actmap->weather.windDirection = 0;
00816             displaymessage2("wind dir set to %d ", actmap->weather.windDirection);
00817             updateFieldInfo();
00818             displaymap();
00819          }
00820          break;
00821 */
00822       case ua_changeresourceview:
00823          if ( mainScreenWidget ) 
00824             mainScreenWidget->toggleMapLayer( "resources");
00825          displaymap();
00826          break;
00827 
00828       case ua_visibilityInfo:
00829          if ( mainScreenWidget ) 
00830             mainScreenWidget->toggleMapLayer( "visibilityvalue");
00831          displaymap();
00832          break;
00833 
00834       case ua_showCargoLayer:
00835          if ( mainScreenWidget ) 
00836             mainScreenWidget->toggleMapLayer( "container");
00837          displaymap();
00838          break;
00839 
00840       case ua_benchgamewov:
00841          benchgame( false );
00842          break;
00843 
00844       case ua_benchgamewv :
00845          benchgame( true );
00846          break;
00847 
00848       case ua_writescreentopcx:
00849          {
00850             ASCString name = getnextfilenumname ( "screen", "pcx", 0 );
00851             Surface s ( PG_Application::GetScreen() );
00852             writepcx ( name, s);
00853             displaymessage2( "screen saved to %s", name.c_str() );
00854          }
00855          break;
00856 
00857       case ua_bi3preferences:
00858          bi3preferences();
00859          break;
00860 
00861       case ua_settribute :
00862          settributepayments ();
00863          break;
00864 
00865       case ua_giveunitaway:
00866          if ( actmap && actmap->getgameparameter( cgp_disableUnitTransfer ) == 0 )
00867             giveunitaway ( actmap->getField( actmap->getCursor() ), createContext( actmap ));
00868          else
00869             infoMessage("Sorry, this function has been disabled when starting the map!");
00870          break;
00871 
00872       case ua_newmessage:
00873          newmessage();
00874          break;
00875 
00876       case ua_viewqueuedmessages:
00877          viewmessages( "queued messages", actmap->unsentmessage, 1 );
00878          break;
00879 
00880       case ua_viewsentmessages:
00881          viewmessages( "sent messages", actmap->player[ actmap->actplayer ].sentmessage, 0);
00882          break;
00883 
00884       case ua_viewreceivedmessages:
00885          viewmessages( "received messages", actmap->player[ actmap->actplayer ].oldmessage, 0 );
00886          break;
00887 
00888       case ua_viewjournal:
00889          viewjournal( true );
00890          break;
00891 
00892       case ua_editjournal:
00893          editjournal();
00894          break;
00895 
00896       case ua_viewaboutmessage:
00897          helpAbout();
00898          break;
00899 
00900       case ua_viewlayerhelp:
00901          help(49);
00902          break;
00903 
00904       case ua_SDLinfo:
00905          showSDLInfo();
00906          break;
00907 
00908       case ua_toggleunitshading: 
00909          {
00910             CGameOptions::Instance()->units_gray_after_move = !CGameOptions::Instance()->units_gray_after_move;
00911             CGameOptions::Instance()->setChanged();
00912             displaymap();
00913             while ( mouseparams.taste )
00914                releasetimeslice();
00915 
00916             ASCString condition;
00917             if ( CGameOptions::Instance()->units_gray_after_move )
00918                condition = "- thay can't move";
00919             else
00920                condition = "- thay can't move AND\n- thay can't shoot";
00921 
00922             infoMessage ("units that now displayed shaded when:\n" + condition);
00923          }
00924 
00925          break;
00926 
00927       case ua_computerturn:
00928          if ( maintainencecheck() ) {
00929             displaymessage("This function is under development and for programmers only\n"
00930                            "unpredictable things may happen ...",3 ) ;
00931 
00932             if (choice_dlg("do you really want to start the AI?","~y~es","~n~o") == 1) {
00933 
00934                if ( !actmap->player[ actmap->actplayer ].ai )
00935                   actmap->player[ actmap->actplayer ].ai = new AI ( actmap, actmap->actplayer );
00936 
00937                savegame ( "aistart.sav", actmap);
00938                actmap->player[ actmap->actplayer ].ai->run( &getDefaultMapDisplay() );
00939             }
00940          }
00941          break;
00942       case ua_setupnetwork:
00943       /*
00944          if ( actmap->network )
00945             setupnetwork ( actmap->network );
00946          else
00947             displaymessage("This map is not played across a network",3 );
00948             */
00949             displaymessage("Not implemented yet",3 );
00950          break;
00951       case ua_UnitSetInfo:
00952          viewUnitSetinfo();
00953          break;
00954       case ua_GameParameterInfo:
00955          showGameParameters();
00956          break;
00957       case ua_viewunitweaponrange:
00958          mainScreenWidget->showWeaponRange( actmap, actmap->getCursor() );
00959          break;
00960 
00961       case ua_viewunitmovementrange:
00962          mainScreenWidget->showMovementRange( actmap, actmap->getCursor() );
00963          break;
00964 
00965       case ua_aibench:
00966          if ( maintainencecheck() && 0 ) {
00967             if ( !actmap->player[ actmap->actplayer ].ai )
00968                actmap->player[ actmap->actplayer ].ai = new AI ( actmap, actmap->actplayer );
00969 
00970             if ( AI* ai = dynamic_cast<AI*>( actmap->player[ actmap->actplayer ].ai )) {
00971                savegame ( "ai-bench-start.sav", actmap);
00972                ai->run( true, &getDefaultMapDisplay() );
00973             }
00974          }
00975          break;
00976 
00977       case ua_selectPlayList:
00978          selectPlayList();
00979          break;
00980       case ua_statisticdialog:
00981          statisticDialog();
00982          break;
00983 
00984       case ua_togglesound:
00985          if ( !SoundSystem::getInstance()->isOff() ) {
00986             bool on = !SoundSystem::getInstance()->areEffectsMuted();
00987             SoundSystem::getInstance()->setEffectsMute( on );
00988             if ( on )
00989                SoundSystem::getInstance()->pauseMusic();
00990             else
00991                SoundSystem::getInstance()->resumeMusic();
00992          }
00993          break;
00994       case ua_showPlayerSpeed:
00995          showPlayerTime();
00996          break;
00997       case  ua_cancelResearch:
00998          if ( actmap->player[actmap->actplayer].research.activetechnology ) {
00999             ASCString s = "do you really want to cancel the current research project ?\n";
01000             // s += strrr ( actmap->player[actmap->actplayer].research.progress );
01001             // s += " research points will be lost.";
01002             if (choice_dlg(s.c_str(),"~y~es","~n~o") == 1) {
01003                auto_ptr<CancelResearchCommand> crc ( new CancelResearchCommand( actmap ));
01004                crc->setPlayer( actmap->player[actmap->actplayer] );
01005                ActionResult res = crc->execute( createContext( actmap ));
01006                if ( res.successful() )
01007                   crc.release();
01008                else
01009                   displayActionError( res );
01010             }
01011             
01012          } else
01013             displaymessage("you are not researching anything", 3);
01014          break;
01015       case ua_showResearchStatus: {
01016             ASCString s;
01017             s += "Current technology:\n";
01018             if ( actmap->player[actmap->actplayer].research.activetechnology )
01019                s += actmap->player[actmap->actplayer].research.activetechnology->name;
01020             else
01021                s += " - none - ";
01022             s += "\n\n";
01023 
01024             s += "Research Points: \n";
01025             s += strrr( actmap->player[actmap->actplayer].research.progress );
01026             if ( actmap->player[actmap->actplayer].research.activetechnology )
01027                s += ASCString(" / ") + strrr ( actmap->player[actmap->actplayer].research.activetechnology->researchpoints );
01028             s += "\n\n";
01029 
01030             s+= "Research Points Plus \n";
01031 
01032             s += strrr ( actmap->player[actmap->actplayer].research.getResearchPerTurn() );
01033 
01034             s += "\n\n";
01035 
01036             s+= "Developed Technologies: \n";
01037             for ( vector<int>::iterator i = actmap->player[actmap->actplayer].research.developedTechnologies.begin(); i != actmap->player[actmap->actplayer].research.developedTechnologies.end(); ++i ) {
01038                Technology* t = technologyRepository.getObject_byID( *i );
01039                if ( t )
01040                   s += t->name + "\n";
01041             }
01042 
01043             tviewanytext vat ;
01044             vat.init ( "Research Status", s.c_str(), 20, -1 , 450, 480 );
01045             vat.run();
01046             vat.done();
01047          }
01048          break;
01049       case ua_exportUnitToFile:
01050          warningMessage("this function is not supported any longer");
01051          break;
01052       case ua_undo:
01053          undo();
01054          break;
01055       case ua_redo:
01056          redo();
01057          break;
01058 
01059          
01060       case ua_unitweightinfo:
01061          if ( fieldvisiblenow  ( getSelectedField() )) {
01062             Vehicle* eht = getSelectedField()->vehicle;
01063             if ( eht && actmap->player[actmap->actplayer].diplomacy.getState( eht->getOwner()) >= PEACE_SV )
01064                infoMessage(" weight of unit: \n basic: " + ASCString::toString(eht->typ->weight) + "\n+cargo: " + ASCString::toString(eht->cargoWeight()) + "\n= " + ASCString::toString( eht->weight() ));
01065          }
01066          break;
01067       case ua_GameStatus:
01068          infoMessage ( "Current game time is:\n turn " + ASCString::toString( actmap->time.turn() ) + " , move " + ASCString::toString( actmap->time.move() ));
01069          break;
01070       case ua_soundDialog:
01071           soundSettings( NULL );
01072          break;
01073       case ua_reloadDlgTheme:
01074              getPGApplication().reloadTheme();
01075              MessagingHub::Instance().message( MessagingHubBase::InfoMessage, "Theme reloaded" );
01076              // soundSettings( NULL );
01077          break;
01078       case ua_viewButtonPanel:  mainScreenWidget->spawnPanel( ASC_MainScreenWidget::ButtonPanel );
01079          break;
01080       case ua_viewWindPanel:     mainScreenWidget->spawnPanel( ASC_MainScreenWidget::WindInfo );
01081          break;
01082       case ua_clearImageCache:  IconRepository::clear();
01083          break;
01084       case ua_viewUnitInfoPanel: mainScreenWidget->spawnPanel( ASC_MainScreenWidget::UnitInfo );
01085          break;
01086       case ua_viewOverviewMapPanel: mainScreenWidget->spawnPanel( ASC_MainScreenWidget::OverviewMap );
01087          break;
01088       case ua_viewMapControlPanel: mainScreenWidget->spawnPanel( ASC_MainScreenWidget::MapControl );
01089          break;
01090 //      case ua_viewActionPanel: mainScreenWidget->spawnPanel( ASC_MainScreenWidget::ActionInfo );
01091 //         break;
01092       case ua_vehicleinfo: unitInfoDialog();
01093          break;
01094 #ifdef WEATHERGENERATOR
01095       case ua_weathercast: weathercast();
01096          break;
01097 #endif
01098       case ua_newGame: 
01099          startMultiplayerGame();
01100          break;
01101 
01102       case ua_continuerecentnetworkgame:
01103          continueAndStartMultiplayerGame( true );
01104          break;
01105 
01106       case ua_continuenetworkgame:
01107          continueAndStartMultiplayerGame();
01108          break;
01109       case ua_loadgame: loadGame( false);
01110          break;
01111       case ua_loadrecentgame: loadGame ( true );
01112          break;
01113       case ua_savegame: saveGame( true );
01114          break;
01115       case ua_setupalliances:
01116          editAlliances();
01117          updateFieldInfo();
01118          break;
01119       case ua_mainmenu:
01120          /*
01121          if (choice_dlg("do you really want to close the current game ?","~y~es","~n~o") == 1) {
01122             delete actmap;
01123             actmap = NULL;
01124             throw NoMapLoaded();
01125          }
01126          */
01127          GameDialog::gameDialog();
01128          break;
01129       case ua_viewterraininfo:
01130          if ( fieldvisiblenow( actmap->getField( actmap->getCursor())))
01131             viewterraininfo( actmap, actmap->getCursor(), fieldVisibility( actmap->getField( actmap->getCursor())) == visible_all );
01132          break;
01133       case ua_testMessages:
01134          MessagingHub::Instance().message( MessagingHubBase::InfoMessage, "This is an informational message" );
01135          MessagingHub::Instance().message( MessagingHubBase::Warning,     "This is an warning message" );
01136          MessagingHub::Instance().message( MessagingHubBase::Error,       "This is an error message" );
01137          MessagingHub::Instance().message( MessagingHubBase::FatalError,  "This is an fatal error message. Game will be exited." );
01138          break;
01139       case ua_writemaptopcx :
01140          writemaptopcx ( actmap, choice_dlg("Include View ?","~y~es","~n~o")==1  );
01141          break;
01142       case ua_exitgame:
01143          if (choiceDialog("do you really want to quit ?","~y~es","~n~o", "quitasc") == 1)
01144             getPGApplication().Quit();
01145          break;
01146       case ua_cargosummary: 
01147          showCargoSummary( getSelectedField() );
01148          break;
01149       case ua_unitsummary: showUnitSummary( actmap );
01150          break;
01151       case ua_gamepreferences:
01152          editGameOptions();
01153          break;
01154       case ua_increase_zoom:
01155          if ( mainScreenWidget && mainScreenWidget->getMapDisplay() ) {
01156             mainScreenWidget->getMapDisplay()->changeZoom( 10 );
01157             viewChanged();
01158             repaintMap();
01159          }
01160          break;
01161       case ua_decrease_zoom:
01162          if ( mainScreenWidget && mainScreenWidget->getMapDisplay() ) {
01163             mainScreenWidget->getMapDisplay()->changeZoom( -10 );
01164             viewChanged();
01165             repaintMap();
01166          }
01167          break;
01168       case ua_selectgraphicset:
01169          selectgraphicset();
01170          break;
01171       case ua_networksupervisor:
01172          networksupervisor();
01173          displaymap();
01174          break;
01175       case ua_researchinfo:
01176          researchinfo ();
01177          break;
01178       case ua_viewPipeNet:
01179          mainScreenWidget->getMapDisplay()->toggleMapLayer("pipes");
01180          repaintMap();
01181          break;
01182       case ua_viewReactionfireOverlay:
01183          mainScreenWidget->getMapDisplay()->toggleMapLayer("reactionfire");
01184          repaintMap();
01185          break;
01186       case ua_viewUnitinfoOverlay:
01187          mainScreenWidget->getMapDisplay()->toggleMapLayer("unitinfo");
01188          repaintMap();
01189          break;
01190       case ua_viewUnitexperienceOverlay:
01191          mainScreenWidget->getMapDisplay()->toggleMapLayer("unittraining");
01192          repaintMap();
01193          break;
01194       case ua_showsearchdirs: showSearchPath();
01195          break;
01196       case ua_changepassword:
01197          changePassword( actmap );
01198          break;
01199       case ua_editPlayerData:
01200          editPlayerData( actmap );
01201          break;
01202       case ua_locatefile:
01203          locateFile();
01204          break;
01205       case ua_viewfont:
01206          viewFont();
01207          break;
01208       case ua_resourceAnalysis:
01209          resourceAnalysis();
01210          break;
01211       case ua_unitproductionanalysis:
01212          unitProductionAnalysis( actmap );
01213          break;
01214       case ua_gotoPosition: { 
01215          GotoPosition gp( actmap );
01216          gp.Show();
01217          gp.RunModal();
01218           break;
01219       };
01220       case ua_showTechAdapter: {
01221                ViewFormattedText vft("TechAdapter", actmap->getCurrentPlayer().research.listTriggeredTechAdapter(), PG_Rect( -1,-1,300,500));
01222                vft.Show();
01223                vft.RunModal();
01224                                };
01225          break;
01226       case ua_showUnitEndurance:  showUnitEndurance(); 
01227          break;
01228          
01229       case ua_getMemoryFootprint: showMemoryFootprint();
01230          break;
01231 
01232       case ua_showMiningPower: viewMiningPower();
01233          break;
01234 
01235       case ua_emailOptions: editEmailOptions();
01236          break;
01237       
01238       case ua_createReminder: newreminder(); 
01239          break;
01240 
01241       case ua_recompteview: 
01242          computeview(actmap);
01243          displaymap();
01244          break;
01245          
01246       case ua_unitGuideDialog:
01247          unitGuideWindow( 2);
01248          break;
01249          
01250       case ua_writeLuaCommands: writeLuaCommands();
01251          break;
01252          
01253       case ua_chooseTechnology: chooseTechnologyIfAvail( actmap->getCurrentPlayer() );
01254          break;
01255       
01256       case ua_actionManager: actionManager( actmap );
01257          break;
01258          
01259       case ua_runLuaCommands: selectAndRunLuaScript();
01260          break;
01261                   
01262       case ua_unitAiOptions: showUnitAiProperties();
01263          break;
01264       
01265       case ua_showUsedPackages: showUsedPackages();
01266          break;
01267          
01268       case ua_runOpenTasks: runOpenTasks();
01269          break;
01270          
01271       case ua_taskManager: taskManager( actmap );
01272          break;
01273          
01274       case ua_createUnitCostList: createUnitCostList();
01275          break;
01276          
01277       default:;
01278       };
01279 }
01280 
01281 
01282 
01283 
01284 bool mainloopidle( PG_MessageObject* msgObj )
01285 {
01286    if ( msgObj != PG_Application::GetApp())
01287       return false;
01288 
01289    if ( actmap ) {
01290       while ( actmap->player[ actmap->actplayer ].queuedEvents )
01291          if ( !checkevents( actmap, &getDefaultMapDisplay() ))
01292             return false;
01293 
01294       checktimedevents( actmap, &getDefaultMapDisplay() );
01295 
01296       checkforvictory( actmap, true );
01297    }
01298    return false;
01299 }
01300 
01301 
01302 void resetActions( GameMap& map )
01303 {
01304    if ( NewGuiHost::pendingCommand ) {
01305       delete NewGuiHost::pendingCommand;
01306       NewGuiHost::pendingCommand = NULL;
01307    }
01308 }
01309 
01310 void resetActmap( GameMap& map )
01311 {
01312    if ( &map == actmap ) 
01313       actmap = NULL;  
01314 }
01315 
01316 
01317 pfont load_font ( const char* name )
01318 {
01319    tnfilestream stream ( name , tnstream::reading );
01320    return loadfont ( &stream );
01321 }
01322 
01323 void loadLegacyFonts()
01324 {
01325    schriften.smallarial = load_font("smalaril.fnt");
01326    schriften.large = load_font("usablack.fnt");
01327    schriften.arial8 = load_font("arial8.fnt");
01328    schriften.smallsystem = load_font("msystem.fnt");
01329    schriften.guifont = load_font("gui.fnt");
01330    schriften.guicolfont = load_font("guicol.fnt");
01331    schriften.monogui = load_font("monogui.fnt");
01332    
01333    activefontsettings.markfont = schriften.guicolfont;
01334    shrinkfont ( schriften.guifont, -1 );
01335    shrinkfont ( schriften.guicolfont, -1 );
01336    shrinkfont ( schriften.monogui, -1 );
01337    
01338 }
01339 
01340 
01341 
01342 
01343 
01344 class GameThreadParams: public SigC::Object
01345 {
01346    private:
01347       bool exit() { exitMainloop = true; return true; };
01348    public:   
01349       ASCString filename;
01350       ASC_PG_App& application;
01351       bool exitMainloop;
01352       GameThreadParams( ASC_PG_App& app ) : application ( app ), exitMainloop(false) 
01353       {
01354          app.sigQuit.connect( SigC::slot( *this, &GameThreadParams::exit ));
01355       };
01356 };
01357 
01358 
01359 void checkGameEvents( GameMap* map,const Command& command )
01360 {
01361    checktimedevents( map, &getDefaultMapDisplay() );
01362    checkevents( map, &getDefaultMapDisplay() );
01363 }
01364 
01365 int gamethread ( void* data )
01366 {
01367    GameMap::sigMapDeletion.connect( SigC::slot( &resetActions ));
01368    GameMap::sigMapDeletion.connect( SigC::slot( &resetActmap ));
01369    GameMap::sigPlayerTurnEndsStatic.connect( SigC::slot( automaticTrainig ));
01370    
01371    TaskContainer::registerHooks();
01372    
01373    GameThreadParams* gtp = (GameThreadParams*) data;
01374 
01375    std::auto_ptr<StartupScreen> startupScreen;
01376 
01377    MapTypeLoaded mtl = None;
01378 
01379    try {
01380       loadpalette();
01381       virtualscreenbuf.init();
01382 
01383       startupScreen.reset( new StartupScreen( "title.jpg", dataLoaderTicker ));
01384       loadLegacyFonts();
01385       loaddata();
01386       
01387       mtl = loadStartupMap( gtp->filename.c_str() );
01388    }
01389    catch ( ParsingError err ) {
01390       errorMessage ( "Error parsing text file " + err.getMessage() );
01391       return -1;
01392    }
01393    catch ( tfileerror err ) {
01394       errorMessage ( "Error loading file " + err.getFileName() );
01395       return -1;
01396    }
01397    catch ( ASCmsgException msg ) {
01398       errorMessage ( msg.getMessage() );
01399       return -1;
01400    }
01401    catch ( ASCexception ) {
01402       errorMessage ( "loading of game failed" );
01403       return -1;
01404    }
01405    catch ( ThreadExitException ) {
01406       displayLogMessage(0, "caught thread exiting exception, shutting down");
01407       return -1;
01408    }
01409 
01410 #ifndef _WIN32_
01411    // Windows/MSVC will catch access violations with this, which we don't want to, because it makes our dump files useless.
01412    catch ( ... ) {
01413       fatalError ( "caught undefined exception" );
01414    }
01415 #endif
01416 
01417 
01418 
01419 //   ActionContainer::postActionExecution.connect( SigC::slot( &checkGameEvents ));
01420             
01421    suppressMapTriggerExecution = false;
01422    
01423    static ShowNewTechnology showNewTechs;
01424    setResearchPresenter( &showNewTechs );
01425 
01426    displayLogMessage ( 5, "loaddata completed successfully.\n" );
01427    dataLoaderTicker();
01428    
01429    displayLogMessage ( 5, "starting music..." );
01430    startMusic();
01431    displayLogMessage ( 5, " done\n" );
01432    dataLoaderTicker();
01433    
01434    repaintDisplay.connect( repaintMap );
01435 
01436    mainScreenWidget = new ASC_MainScreenWidget( getPGApplication());
01437    dataLoaderTicker();
01438 
01439    /*
01441    if ( actmap && actmap->actplayer == -1 ) {
01442       displayLogMessage ( 8, "Startup :: performing first next_turn..." );
01443       next_turn( actmap, NextTurnStrategy_AskUser(), &getDefaultMapDisplay() );
01444       displayLogMessage ( 8, "done.\n" );
01445    }
01446    */
01447 
01448    displayLogMessage ( 5, "entering outer main loop.\n" );
01449    do {
01450       try {
01451          if ( !actmap || actmap->xsize <= 0 || actmap->ysize <= 0 ) {
01452             displayLogMessage ( 8, "gamethread :: starting main menu.\n" );
01453             startupScreen.reset();
01454             GameDialog::gameDialog();
01455             mtl = None;
01456          } else {
01457             mainScreenWidget->Show();
01458             startupScreen.reset();
01459             
01460             if ( actmap->actplayer == -1 ) {
01461                displayLogMessage ( 8, "gamethread :: performing next_turn..." );
01462                next_turn( actmap, NextTurnStrategy_AskUser(), &getDefaultMapDisplay() );
01463                displayLogMessage ( 8, "done.\n" );
01464             } 
01465 
01466             updateFieldInfo();
01467 
01468             displayLogMessage ( 4, "Spawning MainScreenWidget\n ");
01469 
01470 
01471             displayLogMessage ( 7, "Entering main event loop\n");
01472    
01473             if ( mtl == Mailfile ) 
01474                actmap->sigPlayerUserInteractionBegins( actmap->player[actmap->actplayer] );
01475 
01476             mtl = None;
01477 
01478             getPGApplication().Run();
01479             displayLogMessage ( 7, "mainloop exited\n");
01480          }
01481       } /* endtry */
01482       catch ( NoMapLoaded ) { 
01483          delete actmap;
01484          actmap = NULL;
01485       } /* endcatch */
01486       catch ( ShutDownMap ) { 
01487          delete actmap;
01488          actmap = NULL;
01489       }
01490       catch ( LoadNextMap lnm ) {
01491          if ( actmap->campaign.avail ) {
01492             delete actmap;
01493             actmap = NULL;
01494             startnextcampaignmap( lnm.id );
01495          } else {
01496            viewtext2(904);
01497            if (choice_dlg("Do you want to continue playing ?","~y~es","~n~o") == 2) {
01498               delete actmap;
01499               actmap = NULL;
01500            } else {
01501               actmap->continueplaying = 1;
01502               if ( actmap->replayinfo ) {
01503                  delete actmap->replayinfo;
01504                  actmap->replayinfo = NULL;
01505               }
01506            }
01507          }
01508       }
01509    } while ( !gtp->exitMainloop );
01510    
01511    delete actmap;
01512    actmap = NULL;
01513    
01514    return 0;
01515 }
01516 
01517 
01518 static void __runResearch( Player& player ){
01519    runResearch( player, NULL, NULL );  
01520 }
01521 
01522 void deployMapPlayingHooks ( GameMap* map )
01523 {
01524    map->sigPlayerTurnBegins.connect( SigC::slot( initReplayLogging ));
01525    map->sigPlayerTurnBegins.connect( SigC::slot( transfer_all_outstanding_tribute ));   
01526    map->sigPlayerTurnBegins.connect( SigC::slot( __runResearch ));
01527 }
01528 
01529 
01530 
01531 
01532 
01533 
01534 
01535 // including the command line parser, which is generated by genparse
01536 #include "clparser/asc.cpp"
01537 
01538 
01539 class ResourceLogger: public SigC::Object {
01540       ofstream s;
01541    public:
01542       ResourceLogger() {
01543          s.open("resource-log", ios_base::out | ios_base::trunc );
01544          MessagingHub::Instance().logCategorizedMessage.connect( SigC::slot( *this, &ResourceLogger::message ));
01545          MessagingHub::Instance().setLoggingCategory("ResourceWork", true);
01546       };
01547 
01548       void message( const ASCString& category, const ASCString& msg )
01549       {
01550          if ( category == "ResourceWork" )
01551             s << msg << "\n";
01552       }
01553 
01554       ~ResourceLogger() {
01555          s.close();
01556       }
01557 
01558 };
01559 
01560 
01561 class ScreenResolutionSetup {
01562       Cmdline& cli;
01563       int x,y;
01564       bool fullscreen;
01565    public:
01566       ScreenResolutionSetup( Cmdline& commandLine );
01567       
01568       int getWidth() { return x; };
01569       int getHeight() { return y; };
01570       bool isFullscreen() { return fullscreen; };
01571    
01572 };
01573 
01574 ScreenResolutionSetup::ScreenResolutionSetup( Cmdline& commandLine ) : cli( commandLine )
01575 {
01576    if ( SDL_Init( SDL_INIT_VIDEO ) ) 
01577       fatalError( ASCString("Unable to init SDL: ") +  SDL_GetError());
01578   
01579    putenv(const_cast<char*>("SDL_VIDEO_CENTERED=1")) ;
01580    
01581    fullscreen = true;
01582    
01583    if ( cli.w() )
01584       fullscreen = false;
01585 
01586    if ( cli.f() )
01587       fullscreen = true;
01588    
01589    if ( CGameOptions::Instance()->forceWindowedMode && !cli.f() )  // cl->f == force fullscreen command line param
01590       fullscreen = false;
01591 
01592    int xr = -1;
01593    int yr = -1;
01594    // determining the graphics resolution
01595    
01596    if ( CGameOptions::Instance()->xresolution != -1 )
01597       xr = CGameOptions::Instance()->xresolution;
01598    if ( cli.x() != -1 )
01599       xr = cli.x();
01600 
01601    if ( CGameOptions::Instance()->yresolution != -1 )
01602       yr = CGameOptions::Instance()->yresolution;
01603    if ( cli.y() != -1 )
01604       yr = cli.y();
01605 
01606    
01607    GetVideoModes gvm;
01608    
01609    GetVideoModes::ModeRes best = gvm.getBest();
01610    if ( xr == -1 ) {
01611       if ( fullscreen )
01612          xr = best.first;
01613       else
01614          xr = best.first - 100;
01615    }
01616    
01617    if ( yr == -1 ) {
01618       if ( fullscreen ) 
01619          yr = best.second;
01620       else
01621          yr = best.second - 100;
01622    }
01623    
01624    
01625    if ( CGameOptions::Instance()->graphicsDriver.compare_ci("default") != 0 ) {
01626       static char buf[100];
01627       strcpy(buf, "SDL_VIDEODRIVER=" );
01628       strncat( buf, CGameOptions::Instance()->graphicsDriver.c_str(), 100 - strlen(buf));
01629       buf[99] = 0;
01630       putenv( buf );
01631    }
01632 
01633    if ( xr == -1 )
01634       xr = 1024;
01635    
01636    if ( yr == -1 )
01637       yr = 768;
01638    
01639    x = xr;
01640    y = yr;
01641 }
01642 
01643 
01644 int main(int argc, char *argv[] )
01645 { 
01646    assert ( sizeof(PointerSizedInt) == sizeof(int*));
01647 
01648    // we should think about replacing clparser with libpopt
01649    Cmdline* cl = NULL;
01650    try {
01651       cl = new Cmdline ( argc, argv );
01652    } catch ( string s ) {
01653       cerr << s;
01654       exit(1);
01655    }
01656    auto_ptr<Cmdline> apcl ( cl );
01657 
01658    if ( cl->v() ) {
01659       ASCString msg = getstartupmessage();
01660       printf( "%s", msg.c_str() );
01661       exit(0);
01662    }
01663 
01664    MessagingHub::Instance().setVerbosity( cl->r() );
01665    StdIoErrorHandler stdIoErrorHandler(false);
01666    MessagingHub::Instance().exitHandler.connect( SigC::bind( SigC::slot( exit_asc ), -1 ));
01667 
01668    // ResourceLogger rl;
01669 
01670 #ifdef WIN32
01671    Win32IoErrorHandler* win32ErrorDialogGenerator = new Win32IoErrorHandler;
01672 #endif
01673 
01674 
01675    displayLogMessage( 1, getstartupmessage() );
01676 
01677    ConfigurationFileLocator::Instance().setExecutableLocation( argv[0] );
01678 
01679    try {
01680       initFileIO( cl->c() );  // passing the filename from the command line options
01681       checkDataVersion();
01682    } catch ( tfileerror err ) {
01683       displaymessage ( "unable to access file %s \n", 2, err.getFileName().c_str() );
01684    }
01685    catch ( ... ) {
01686       displaymessage ( "loading of game failed during pre graphic initializing", 2 );
01687    }
01688 
01689    LoggingOutputHandler logger( getSearchPath( 0 ));
01690    
01691 
01692    
01693    SoundSystem soundSystem ( CGameOptions::Instance()->sound.muteEffects, CGameOptions::Instance()->sound.muteMusic, cl->q() || CGameOptions::Instance()->sound.off );
01694    soundSystem.setMusicVolume ( CGameOptions::Instance()->sound.musicVolume );
01695    soundSystem.setEffectVolume ( CGameOptions::Instance()->sound.soundVolume );
01696 
01697    
01698    tspfldloaders::mapLoaded.connect( SigC::slot( deployMapPlayingHooks ));
01699 
01700    PG_FileArchive archive( argv[0] );
01701 
01702    ASC_PG_App app ( "asc2_dlg" );
01703 
01704    app.sigAppIdle.connect ( SigC::slot( mainloopidle ));
01705 
01706    cursorMoved.connect( updateFieldInfo );
01707 
01708    
01709    ScreenResolutionSetup screenResolutionSetup ( *cl );
01710    int flags = 0;
01711 
01712    if ( CGameOptions::Instance()->hardwareSurface )
01713       flags |= SDL_HWSURFACE;
01714    else
01715       flags |= SDL_SWSURFACE;
01716 
01717    if ( screenResolutionSetup.isFullscreen() )
01718       flags |= SDL_FULLSCREEN;
01719 
01720    app.setIcon( "program-icon.png" );
01721    bool initialized = false;
01722    if ( !app.InitScreen( screenResolutionSetup.getWidth(), screenResolutionSetup.getHeight(), 32, flags)) {
01723       if ( flags & SDL_FULLSCREEN ) {
01724          GetVideoModes gvm;
01725          if ( gvm.getList().size() > 0 ) {
01726             if ( app.InitScreen( gvm.getx(0), gvm.gety(0), 32, flags)) 
01727                initialized = true;
01728          }
01729       }
01730    } else
01731       initialized = true;
01732 
01733    if ( !initialized )
01734      fatalError( "Could not initialize video mode");
01735 
01736 
01737 #ifdef WIN32
01738    delete win32ErrorDialogGenerator;
01739 #endif
01740 
01741    setWindowCaption ( "Advanced Strategic Command" );
01742       
01743    GameThreadParams gtp ( app );
01744    gtp.filename = cl->l();
01745 
01746    if ( cl->next_param() < argc )
01747       for ( int i = cl->next_param(); i < argc; i++ )
01748          gtp.filename = argv[i];
01749 
01750 
01751    int returncode = 0;
01752    try {
01753       // this starts the gamethread procedure, whichs will run the entire game
01754       returncode = initializeEventHandling ( gamethread, &gtp );
01755    }
01756    catch ( bad_alloc ) {
01757       fatalError ("Out of memory");
01758    }
01759 
01760    writegameoptions ( );
01761 
01762    return( returncode );
01763 }

Generated on Mon May 21 01:26:37 2012 for Advanced Strategic Command by  doxygen 1.5.1