00001
00002
00003
00004
00005
00006
00007
00008
00014
00015
00016
00017
00018
00019
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
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 }
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 {
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 );
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 );
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
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
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
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
00945
00946
00947
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
01001
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
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
01091
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
01122
01123
01124
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
01412 catch ( ... ) {
01413 fatalError ( "caught undefined exception" );
01414 }
01415 #endif
01416
01417
01418
01419
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
01442
01443
01444
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 }
01482 catch ( NoMapLoaded ) {
01483 delete actmap;
01484 actmap = NULL;
01485 }
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
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() )
01590 fullscreen = false;
01591
01592 int xr = -1;
01593 int yr = -1;
01594
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
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
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() );
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
01754 returncode = initializeEventHandling ( gamethread, >p );
01755 }
01756 catch ( bad_alloc ) {
01757 fatalError ("Out of memory");
01758 }
01759
01760 writegameoptions ( );
01761
01762 return( returncode );
01763 }