/*************************************************************************** sg.cpp - description ------------------- begin : a long time ago... copyright : (C) 1994-2003 by Martin Bickel email : bickel@asc-hq.org ***************************************************************************/ /*! \file sg.cpp \brief THE main program: ASC */ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /*! \mainpage \section a short walk through the source THE central class of ASC is tmap in gamemap.h . It is the anchor where nearly all elements of ASC are chained to. The global variable #actmap is a pointer to the active map. There can be a maximum of 8 players on a map, plus neutral units (which are handled like a 9th player). Hence the array of 9 tmap::Player classes in tmap. Each player has units and buildings, which are stored in the lists tmap::Player::vehicleList and tmap::Player::buildingList . The terms units and vehicles are used synonymously in ASC. Since unit was a reserved word in Borland Pascal, we decided to use the term vehicle instead. But now, with ASC written in C++, 'unit' is also used. Every building and unit is of a certain 'type': Vehicletype and BuildingType . These are stored in the data files which are loaded on startup and are globally available. They are not modified during runtime in any way and are referenced by the instances of Vehicle and Building. The Vehicletype has information that are shared by all vehicles of this 'type', like speed, weapon systems, accessable terrain etc, while the vehicle stores things like remaining movement for this turn, ammo, fuel and cargo. The primary contents of a map are its fields ( tfield). Each field has again a pointer to a certain weather of a TerrainType. Each TerrainType has up to 5 different weathers ("dry (standard)","light rain", "heavy rain", "few snow", "lot of snow"). If there is a unit or a building standing on a field, the field has a pointer to it: tfield::vehicle and tfield::building . On the field can be several instances of Object. Objects are another central class of ASC. Roads, pipleines, trenches and woods are examples of objects. */ #include "global.h" #include #include #include #include #include #include #include #include #include #include #ifndef NO_PARAGUI # include # include # include #endif #include "SDL_mixer.h" #include "SDL_getenv.h" #include "paradialog.h" #include "vehicletype.h" #include "buildingtype.h" #include "ai/ai.h" #include "basegfx.h" #include "misc.h" #include "loadpcx.h" #include "newfont.h" #include "events.h" #include "typen.h" #include "spfst.h" #include "loaders.h" #include "dlg_box.h" #include "stack.h" #include "controls.h" #include "dlg_box.h" #include "dialog.h" #include "gui.h" #include "pd.h" #include "strtmesg.h" #include "gamedlg.h" #include "network.h" #include "building.h" #include "sg.h" #include "soundList.h" #include "gameoptions.h" #include "loadimage.h" #include "astar2.h" #include "errors.h" #include "password.h" #include "password_dialog.h" #include "viewcalculation.h" #include "replay.h" #include "dashboard.h" #include "graphicset.h" #include "loadbi3.h" #include "itemrepository.h" #include "music.h" #include "messagedlg.h" #include "statisticdialog.h" #include "clipboard.h" #include "paradialog.h" // #define MEMCHK #include "memorycheck.cpp" #ifdef WIN32 #include "win32/msvc/mdump.h" MiniDumper miniDumper( "main" ); #endif class tsgonlinemousehelp : public tonlinemousehelp { public: tsgonlinemousehelp ( void ); }; tsgonlinemousehelp :: tsgonlinemousehelp ( void ) { helplist.num = 12; static tonlinehelpitem sghelpitems[12] = {{{ 498, 26, 576, 36}, 20001 }, {{ 498, 41, 576, 51}, 20002 }, {{ 586, 26, 612, 51}, 20003 }, {{ 499, 57, 575, 69}, 20004 }, {{ 499, 70, 575, 81}, 20005 }, {{ 577, 58, 610, 68}, 20006 }, {{ 577, 70, 610, 80}, 20007 }, {{ 502, 92, 531,193}, 20008 }, {{ 465, 92, 485,194}, 20009 }, {{ 551, 92, 572,193}, 20010 }, {{ 586, 90, 612,195}, 20011 }, {{ 473,agmp->resolutiony - ( 480 - 449 ), 601,agmp->resolutiony - ( 480 - 460 )}, 20016 }}; for ( int i = 0; i< helplist.num; i++ ) { sghelpitems[i].rect.x1 = agmp->resolutionx - ( 640 - sghelpitems[i].rect.x1 ); sghelpitems[i].rect.x2 = agmp->resolutionx - ( 640 - sghelpitems[i].rect.x2 ); } helplist.item = sghelpitems; } tsgonlinemousehelp* onlinehelp = NULL; class tsgonlinemousehelpwind : public tonlinemousehelp { public: tsgonlinemousehelpwind ( void ); } ; tsgonlinemousehelpwind :: tsgonlinemousehelpwind ( void ) { helplist.num = 3; static tonlinehelpitem sghelpitemswind[3] = { {{ 501,224, 569,290}, 20013 }, {{ 589,228, 609,289}, 20014 }, {{ 489,284, 509,294}, 20015 }}; for ( int i = 0; i< helplist.num; i++ ) { sghelpitemswind[i].rect.x1 = agmp->resolutionx - ( 640 - sghelpitemswind[i].rect.x1 ); sghelpitemswind[i].rect.x2 = agmp->resolutionx - ( 640 - sghelpitemswind[i].rect.x2 ); } helplist.item = sghelpitemswind; } tsgonlinemousehelpwind* onlinehelpwind = NULL; int abortgame; pprogressbar actprogressbar = NULL; cmousecontrol* mousecontrol = NULL; #define messagedisplaytime 300 #define mmaintainence bool maintainencecheck( void ) { int res = 0; if ( res ) return true; #ifdef maintainence int num = 0; for ( int i = 0; i < 8; i++ ) if ( actmap->player[i].stat == Player::human && actmap->player[i].exist()) num++; if ( actmap->campaign ) num++; if ( actmap->network ) num++; if ( num <= 1 ) return 1; else return 0; #else return false; #endif } void* loadpcx2raw( const ASCString& file ) { int pcxwidth,imgwidth; int pcxheight,imgheight; int depth = pcxGetColorDepth ( file, &pcxwidth, &pcxheight ); if ( depth > 8 ) fatalError(file + " could not be loaded: only 8 bit images supported"); tvirtualdisplay vdp ( pcxwidth, pcxheight, 255, 8 ); loadpcxxy ( file, 0, 0, 0, &imgwidth, &imgheight ); void* img = new char[imagesize (0, 0, imgheight-1, imgwidth-1)]; getimage ( 0, 0, imgwidth-1, imgheight-1, img ); return img; } void loadMoreData(void) { int w; char i; { tnfilestream stream ( "height2.raw", tnstream::reading ); for (i=0;i<3 ;i++ ) for ( int j=0; j<8; j++) stream.readrlepict( &icons.height2[i][j], false, &w ); } { tnfilestream stream ("windp.raw", tnstream::reading); for (i=0;i<9 ;i++ ) stream.readrlepict( &icons.wind[i], false, &w ); } { tnfilestream stream ("windpfei.raw",tnstream::reading); stream.readrlepict( &icons.windarrow, false, &w ); } { tnfilestream stream ("farbe.raw",tnstream::reading); for (i=0;i<8 ;i++ ) stream.readrlepict( &icons.player[i], false, &w ); } { tnfilestream stream ("allianc.raw",tnstream::reading); for (i=0;i<8 ;i++ ) { stream.readrlepict( &icons.allianz[i][0], false, &w ); stream.readrlepict( &icons.allianz[i][1], false, &w ); stream.readrlepict( &icons.allianz[i][2], false, &w ); } /* endfor */ } { tnfilestream stream ("weapicon.raw",tnstream::reading); for (i=0; i<14 ;i++ ) stream.readrlepict( &icons.unitinfoguiweapons[i], false, &w ); } { tnfilestream stream ("expicons.raw",tnstream::reading); for (i=0; i<=maxunitexperience ;i++ ) stream.readrlepict( &icons.experience[i], false, &w ); } { tnfilestream stream ("hexinvi2.raw",tnstream::reading); stream.readrlepict( &icons.view.va8, false, &w); } { tnfilestream stream ("hexinvis.raw",tnstream::reading); stream.readrlepict( &icons.view.nv8, false, &w); void* u = uncompress_rlepict ( icons.view.nv8 ); if ( u ) { asc_free( icons.view.nv8 ); icons.view.nv8 = u; } } { tnfilestream stream ("fg8.raw",tnstream::reading); stream.readrlepict( &icons.view.fog8, false, &w); } { tnfilestream stream ("windrose.raw",tnstream::reading); stream.readrlepict( &icons.windbackground, false, &w); } if ( actprogressbar ) actprogressbar->point(); { tnfilestream stream ("hexfld_a.raw",tnstream::reading); stream.readrlepict( &icons.container.mark.active, false, &w); } if ( actprogressbar ) actprogressbar->point(); { tnfilestream stream ("hexfld.raw",tnstream::reading); stream.readrlepict( &icons.container.mark.inactive, false, &w); } { tnfilestream stream ("in_ach.raw",tnstream::reading); stream.readrlepict( &icons.container.mark.movein_active, false, &w); } { tnfilestream stream ("in_h.raw",tnstream::reading); stream.readrlepict( &icons.container.mark.movein_inactive, false, &w); } { tnfilestream stream ("build_ah.raw",tnstream::reading); stream.readrlepict( &icons.container.mark.repairactive, false, &w); } { tnfilestream stream ("build_h.raw",tnstream::reading); stream.readrlepict( &icons.container.mark.repairinactive, false, &w); } { tnfilestream stream ("hexbuild.raw",tnstream::reading); stream.readrlepict( &icons.container.container_window, false, &w); } if ( actprogressbar ) actprogressbar->point(); if ( !asc_paletteloaded ) loadpalette(); for (w=0;w<256 ;w++ ) { palette16[w][0] = pal[w][0]; palette16[w][1] = pal[w][1]; palette16[w][2] = pal[w][2]; xlattables.nochange[w] = w; } /* endfor */ if ( actprogressbar ) actprogressbar->point(); loadicons(); if ( actprogressbar ) actprogressbar->point(); loadmessages(); if ( actprogressbar ) actprogressbar->point(); { tnfilestream stream ("waffen.raw",tnstream::reading); int num = stream.readInt(); static int xlatselectweaponguiicons[12] = { 2, 7, 6, 3, 4, 9, 0, 5, 10, 11, 11, 11 }; for ( i = 0; i < num; i++ ) stream.readrlepict( &icons.selectweapongui[xlatselectweaponguiicons[i]], false, &w ); stream.readrlepict( &icons.selectweaponguicancel, false, &w ); stream.readrlepict( &icons.selectweapongui[12], false, &w ); } { tnfilestream stream ("knorein.raw",tnstream::reading); stream.readrlepict( &icons.guiknopf, false, &w ); } { tnfilestream stream ("compi2.raw",tnstream::reading); stream.readrlepict( &icons.computer, false, &w ); } { tnfilestream stream ("pfeil-a0.raw",tnstream::reading); for (i=0; i<8 ;i++ ) { stream.readrlepict( &icons.pfeil2[i], false, &w ); } /* endfor */ } { tnfilestream stream ("gebasym2.raw",tnstream::reading); for ( i = 0; i < 12; i++ ) for ( int j = 0; j < 2; j++ ) stream.readrlepict( &icons.container.lasche.sym[i][j], false, &w ); } { tnfilestream stream ("netcontr.raw",tnstream::reading); stream.readrlepict( &icons.container.subwin.netcontrol.start, false, &w ); stream.readrlepict( &icons.container.subwin.netcontrol.inactive, false, &w ); stream.readrlepict( &icons.container.subwin.netcontrol.active, false, &w ); } { tnfilestream stream ("ammoprod.raw",tnstream::reading); stream.readrlepict( &icons.container.subwin.ammoproduction.start, false, &w ); stream.readrlepict( &icons.container.subwin.ammoproduction.button, false, &w ); stream.readrlepict( &icons.container.subwin.ammoproduction.buttonpressed, false, &w ); for ( i = 0; i < 4; i++ ) stream.readrlepict( &icons.container.subwin.ammoproduction.schieber[i], false, &w ); stream.readrlepict( &icons.container.subwin.ammoproduction.schiene, false, &w ); } if ( actprogressbar ) actprogressbar->point(); { tnfilestream stream ("resorinf.raw",tnstream::reading); stream.readrlepict( &icons.container.subwin.resourceinfo.start, false, &w ); } { tnfilestream stream ("windpowr.raw",tnstream::reading); stream.readrlepict( &icons.container.subwin.windpower.start, false, &w ); } { tnfilestream stream ("solarpwr.raw",tnstream::reading); stream.readrlepict( &icons.container.subwin.solarpower.start, false, &w ); } { tnfilestream stream ("ammotran.raw", tnstream::reading); stream.readrlepict( &icons.container.subwin.ammotransfer.start, false, &w ); stream.readrlepict( &icons.container.subwin.ammotransfer.button, false, &w ); stream.readrlepict( &icons.container.subwin.ammotransfer.buttonpressed, false, &w ); for ( i = 0; i < 4; i++ ) stream.readrlepict( &icons.container.subwin.ammotransfer.schieber[i], false, &w ); stream.readrlepict( &icons.container.subwin.ammotransfer.schieneinactive, false, &w ); stream.readrlepict( &icons.container.subwin.ammotransfer.schiene, false, &w ); if ( dataVersion >= 2 ) { stream.readrlepict( &icons.container.subwin.ammotransfer.singlepage[0], false, &w ); stream.readrlepict( &icons.container.subwin.ammotransfer.singlepage[1], false, &w ); stream.readrlepict( &icons.container.subwin.ammotransfer.plus[0], false, &w ); stream.readrlepict( &icons.container.subwin.ammotransfer.plus[1], false, &w ); stream.readrlepict( &icons.container.subwin.ammotransfer.minus[0], false, &w ); stream.readrlepict( &icons.container.subwin.ammotransfer.minus[1], false, &w ); } } { tnfilestream stream ("research.raw",tnstream::reading); stream.readrlepict( &icons.container.subwin.research.start, false, &w ); stream.readrlepict( &icons.container.subwin.research.button[0], false, &w ); stream.readrlepict( &icons.container.subwin.research.button[1], false, &w ); stream.readrlepict( &icons.container.subwin.research.schieber, false, &w ); } { tnfilestream stream ("pwrplnt2.raw",tnstream::reading); stream.readrlepict( &icons.container.subwin.conventionelpowerplant.start, false, &w ); stream.readrlepict( &icons.container.subwin.conventionelpowerplant.schieber, false, &w ); //stream.readrlepict( &icons.container.subwin.conventionelpowerplant.button[1], false, &w ); } int m; { tnfilestream stream ( "bldinfo.raw", tnstream::reading ); stream.readrlepict( &icons.container.subwin.buildinginfo.start, false, &m ); for ( i = 0; i < 8; i++ ) stream.readrlepict( &icons.container.subwin.buildinginfo.height1[i], false, &m ); for ( i = 0; i < 8; i++ ) stream.readrlepict( &icons.container.subwin.buildinginfo.height2[i], false, &m ); stream.readrlepict( &icons.container.subwin.buildinginfo.repair, false, &m ); stream.readrlepict( &icons.container.subwin.buildinginfo.repairpressed, false, &m ); stream.readrlepict( &icons.container.subwin.buildinginfo.block, false, &m ); } { tnfilestream stream ("mining2.raw", tnstream::reading); stream.readrlepict( &icons.container.subwin.miningstation.start, false, &w ); stream.readrlepict( &icons.container.subwin.miningstation.zeiger, false, &w ); /* for ( i = 0; i < 2; i++ ) stream.readrlepict( &icons.container.subwin.miningstation.button[i], false, &w ); for ( i = 0; i < 2; i++ ) stream.readrlepict( &icons.container.subwin.miningstation.resource[i], false, &w ); for ( i = 0; i < 3; i++ ) stream.readrlepict( &icons.container.subwin.miningstation.axis[i], false, &w ); for ( i = 0; i < 2; i++ ) stream.readrlepict( &icons.container.subwin.miningstation.pageturn[i], false, &w ); stream.readrlepict( &icons.container.subwin.miningstation.graph, false, &w ); */ } { tnfilestream stream ("mineral.raw", tnstream::reading); stream.readrlepict( &icons.container.subwin.mineralresources.start, false, &w ); stream.readrlepict( &icons.container.subwin.mineralresources.zeiger, false, &w ); } { tnfilestream stream ("tabmark.raw", tnstream::reading); stream.readrlepict ( &icons.container.tabmark[0], false, &w ); stream.readrlepict ( &icons.container.tabmark[1], false, &w ); } { tnfilestream stream ("traninfo.raw", tnstream::reading); stream.readrlepict( &icons.container.subwin.transportinfo.start, false, &w ); for ( i = 0; i < 8; i++ ) stream.readrlepict( &icons.container.subwin.transportinfo.height1[i], false, &w ); for ( i = 0; i < 8; i++ ) stream.readrlepict( &icons.container.subwin.transportinfo.height2[i], false, &w ); stream.readrlepict( &icons.container.subwin.transportinfo.sum, false, &w ); } if ( actprogressbar ) actprogressbar->point(); { tnfilestream stream ("attack.raw", tnstream::reading); stream.readrlepict ( &icons.attack.bkgr, false, &w ); icons.attack.orgbkgr = NULL; } { tnfilestream stream ("hexfeld.raw", tnstream::reading); stream.readrlepict ( &icons.fieldshape, false, &w ); } { tnfilestream stream ("mapbkgr.raw", tnstream::reading); stream.readrlepict ( &icons.mapbackground, false, &w ); } { tnfilestream stream ("hex2oct.raw", tnstream::reading); stream.readrlepict ( &icons.hex2octmask, false, &w ); } { tnfilestream stream ("weapinfo.raw", tnstream::reading); for ( int i = 0; i < 5; i++ ) stream.readrlepict ( &icons.weaponinfo[i], false, &w ); } backgroundpict.load(); } enum tuseractions { ua_repainthard, ua_repaint, ua_help, ua_showpalette, ua_dispvehicleimprovement, ua_mainmenu, ua_mntnc_morefog, ua_mntnc_lessfog, ua_mntnc_morewind, ua_mntnc_lesswind, ua_mntnc_rotatewind, ua_changeresourceview, ua_benchgamewv, ua_benchgamewov, ua_viewterraininfo, ua_unitweightinfo, ua_writemaptopcx, ua_writescreentopcx, ua_startnewsinglelevel, ua_changepassword, ua_gamepreferences, ua_bi3preferences, ua_exitgame, ua_newcampaign, ua_loadgame, ua_savegame, ua_setupalliances, ua_settribute, ua_giveunitaway, ua_vehicleinfo, ua_researchinfo, ua_unitstatistics, ua_buildingstatistics, ua_newmessage, ua_viewqueuedmessages, ua_viewsentmessages, ua_viewreceivedmessages, ua_viewjournal, ua_editjournal, ua_viewaboutmessage, ua_continuenetworkgame, ua_toggleunitshading, ua_computerturn, ua_setupnetwork, ua_howtostartpbem, ua_howtocontinuepbem, ua_mousepreferences, ua_selectgraphicset, ua_UnitSetInfo, ua_GameParameterInfo, ua_GameStatus, ua_viewunitweaponrange, ua_viewunitmovementrange, ua_aibench, ua_networksupervisor, ua_selectPlayList, ua_soundDialog, ua_reloadDlgTheme, ua_showPlayerSpeed, ua_renameunit, ua_statisticdialog, ua_viewPipeNet, ua_cancelResearch, ua_showResearchStatus, ua_exportUnitToFile, ua_cargosummary, ua_showsearchdirs, ua_unitsummary, ua_togglesound }; class tsgpulldown : public tpulldown { public: void init ( void ); } pd; void tsgpulldown :: init ( void ) { addfield ( "Glo~b~al" ); addbutton ( "toggle ~R~esourceviewõ1", ua_changeresourceview ); addbutton ( "toggle unit shadingõ2", ua_toggleunitshading ); addbutton ( "seperator", -1); addbutton ( "~O~ptions", ua_gamepreferences ); addbutton ( "~M~ouse options", ua_mousepreferences ); #ifndef NO_PARAGUI addbutton ( "~S~ound options", ua_soundDialog ); #else addbutton ( "sound on/off", ua_togglesound ); #endif addbutton ( "seperator", -1); addbutton ( "E~x~itõctrl-x", ua_exitgame ); addfield ("~G~ame"); addbutton ( "New ~C~ampaign", ua_newcampaign); addbutton ( "~N~ew single Levelõctrl-n", ua_startnewsinglelevel ); addbutton ( "seperator", -1); addbutton ( "~L~oad gameõctrl-l", ua_loadgame ); addbutton ( "~S~ave gameõctrl-s", ua_savegame ); addbutton ( "seperator", -1 ); addbutton ( "Continue network gameõF3", ua_continuenetworkgame); addbutton ( "setup Net~w~ork", ua_setupnetwork ); addbutton ( "Change Passw~o~rd", ua_changepassword ); addbutton ( "supervise network game", ua_networksupervisor ); addbutton ( "seperator", -1 ); addbutton ( "~P~layers + Alliances", ua_setupalliances); addbutton ( "transfer ~U~nit control", ua_giveunitaway ); addbutton ( "~r~ename unit/building", ua_renameunit ); addbutton ( "~T~ransfer resources", ua_settribute); addbutton ( "~C~ancel Research", ua_cancelResearch ); addfield ( "~I~nfo" ); addbutton ( "~V~ehicle types", ua_vehicleinfo ); addbutton ( "Unit ~w~eapon rangeõ3", ua_viewunitweaponrange ); addbutton ( "Unit ~m~ovement rangeõ4", ua_viewunitmovementrange ); addbutton ( "~G~ame Timeõ5", ua_GameStatus ); addbutton ( "unit ~S~et informationõ6", ua_UnitSetInfo ); addbutton ( "~T~errainõ7", ua_viewterraininfo ); addbutton ( "~U~nit weightõ8", ua_unitweightinfo ); addbutton ( "show ~P~ipeline netõ9", ua_viewPipeNet ); addbutton ( "seperator", -1 ); addbutton ( "~R~esearch", ua_researchinfo ); addbutton ( "~P~lay time", ua_showPlayerSpeed ); addbutton ( "~C~argo Summary", ua_cargosummary ); addbutton ( "Unit Summary", ua_unitsummary ); // addbutton ( "~R~esearch status", ua_showResearchStatus ); // addbutton ( "vehicle ~I~mprovementõF7", ua_dispvehicleimprovement); // addbutton ( "show game ~P~arameters", ua_GameParameterInfo ); addfield ( "~S~tatistics" ); addbutton ( "~U~nits", ua_unitstatistics ); addbutton ( "~B~uildings", ua_buildingstatistics ); // addbutton ( "~R~esources ", ua_statisticdialog ); // addbutton ( "seperator"); // addbutton ( "~H~istory"); addfield ( "~M~essage"); addbutton ( "~n~ew message", ua_newmessage ); addbutton ( "view ~q~ueued messages", ua_viewqueuedmessages ); addbutton ( "view ~s~end messages", ua_viewsentmessages ); addbutton ( "view ~r~eceived messages", ua_viewreceivedmessages); addbutton ( "seperator", -1 ); addbutton ( "view ~j~ournal", ua_viewjournal ); addbutton ( "~a~ppend to journal", ua_editjournal ); addfield ( "~T~ools" ); addbutton ( "save ~M~ap as PCXõ9", ua_writemaptopcx ); addbutton ( "save ~S~creen as PCX", ua_writescreentopcx ); addbutton ( "benchmark without view calc", ua_benchgamewov ); addbutton ( "benchmark with view calc", ua_benchgamewv); addbutton ( "compiler benchmark (AI)", ua_aibench ); // addbutton ( "test memory integrity", ua_heapcheck ); addbutton ( "seperator", -1 ); addbutton ( "select graphic set", ua_selectgraphicset ); addbutton ( "reload dialog theme", ua_reloadDlgTheme ); addfield ( "~H~elp" ); addbutton ( "HowTo ~S~tart email games", ua_howtostartpbem ); addbutton ( "HowTo ~C~ontinue email games", ua_howtocontinuepbem ); addbutton ( "seperator", -1); addbutton ( "Show ASC search ~P~ath", ua_showsearchdirs ); addbutton ( "seperator", -1); addbutton ( "~K~eys", ua_help ); addbutton ( "~A~bout", ua_viewaboutmessage ); tpulldown :: init(); setshortkeys(); } class MainMenuPullDown : public tpulldown { public: void init ( void ); } ; void MainMenuPullDown :: init ( void ) { alwaysOpen = true; addfield ( "Glo~b~al" ); addbutton ( "~O~ptions", ua_gamepreferences ); addbutton ( "~M~ouse options", ua_mousepreferences ); // addbutton ( "Select Music Play ~L~ist ", ua_selectPlayList ); addbutton ( "~S~ound options", ua_soundDialog ); addbutton ( "seperator", -1); addbutton ( "E~x~itõctrl-x", ua_exitgame ); addfield ("~G~ame"); addbutton ( "New ~C~ampaign", ua_newcampaign); addbutton ( "~N~ew single Levelõctrl-n", ua_startnewsinglelevel ); addbutton ( "~L~oad gameõctrl-l", ua_loadgame ); addbutton ( "Continue network gameõF3", ua_continuenetworkgame); addbutton ( "supervise network game", ua_networksupervisor ); addfield ( "~H~elp" ); addbutton ( "HowTo ~S~tart email games", ua_howtostartpbem ); addbutton ( "HowTo ~C~ontinue email games", ua_howtocontinuepbem ); addbutton ( "seperator", -1); addbutton ( "~K~eys", ua_help ); addbutton ( "~A~bout", ua_viewaboutmessage ); tpulldown :: init(); setshortkeys(); } void repaintdisplay(void) { collategraphicoperations cgo; int mapexist = actmap && (actmap->xsize > 0) && (actmap->ysize > 0); int ms = getmousestatus(); if ( ms == 2 ) mousevisible ( false ); int cv = cursor.an; if ( mapexist && cv ) cursor.hide(); backgroundpict.paint(); setvgapalette256(pal); if ( mapexist ) { displaymap(); if ( cv ) cursor.show(); } pd.barstatus = false; if ( ms == 2 ) mousevisible ( true ); dashboard.x = 0xffff; dashboard.repainthard = 1; if ( actmap && actmap->ellipse ) actmap->ellipse->paint(); if ( actgui && actmap && actmap->xsize>0 ) { if ( !getactfield() ) cursor.gotoxy( 0, 0, 0 ); actgui->painticons(); } } void loadMap() { ASCString s1; mousevisible(false); fileselectsvga(mapextension, s1, true ); if ( !s1.empty() ) { mousevisible(false); cursor.hide(); displaymessage("loading map %s",0, s1.c_str() ); loadmap(s1.c_str()); actmap->startGame(); next_turn(); removemessage(); if (actmap->campaign != NULL) { delete ( actmap->campaign ); actmap->campaign = NULL; } displaymap(); dashboard.x = 0xffff; moveparams.movestatus = 0; } mousevisible(true); } void loadGame() { mousevisible(false); ASCString s1; fileselectsvga(savegameextension, s1, true ); if ( !s1.empty() ) { mousevisible(false); cursor.hide(); displaymessage("loading %s ",0, s1.c_str()); loadgame(s1.c_str() ); removemessage(); if ( !actmap || actmap->xsize == 0 || actmap->ysize == 0 ) throw NoMapLoaded(); if ( actmap->network ) setallnetworkpointers ( actmap->network ); computeview( actmap ); displaymap(); dashboard.x = 0xffff; moveparams.movestatus = 0; } mousevisible(true); } void saveGame( bool as ) { ASCString s1; int nameavail = 0; if ( !actmap->preferredFileNames.savegame[actmap->actplayer].empty() ) nameavail = 1; if ( as || !nameavail ) { mousevisible(false); fileselectsvga(savegameextension, s1, false ); } else s1 = actmap->preferredFileNames.savegame[actmap->actplayer]; if ( !s1.empty() ) { actmap->preferredFileNames.savegame[actmap->actplayer] = s1; mousevisible(false); cursor.hide(); displaymessage("saving %s", 0, s1.c_str()); savegame(s1.c_str()); removemessage(); displaymap(); cursor.show(); } mousevisible(true); } void showpalette(void) { bar ( 0, 0, 639, 479, black ); int x=7; for ( char a = 0; a <= 15; a++) for ( char b = 0; b <= 15; b++) { bar( a * 40, b * 20,a * 40 + x,b * 20 + 20, xlattables.a.light [a * 16 + b]); bar( x + a * 40, b * 20,a * 40 + 2*x,b * 20 + 20, xlattables.nochange [a * 16 + b]); bar(2*x + a * 40, b * 20,a * 40 + 3*x,b * 20 + 20, xlattables.a.dark1 [a * 16 + b]); bar(3*x + a * 40, b * 20,a * 40 + 4*x,b * 20 + 20, xlattables.a.dark2 [a * 16 + b]); bar(4*x + a * 40, b * 20,a * 40 + 5*x,b * 20 + 20, xlattables.a.dark3 [a * 16 + b]); } wait(); repaintdisplay(); } void newcampaign(void) { tchoosenewcampaign tnc; tnc.init(); tnc.run(); tnc.done(); } void newsinglelevel(void) { tchoosenewsinglelevel tnc; tnc.init(); tnc.run(); tnc.done(); // actmap->player[0].exist(); } void startnewsinglelevelfromgame(void) { cursor.hide(); newsinglelevel(); if ( !actmap ) throw NoMapLoaded(); computeview( actmap ); displaymap(); cursor.show(); } void loadStartupMap ( const char *gameToLoad=NULL ) { if ( gameToLoad && gameToLoad[0] ) { try { if ( patimat ( tournamentextension, gameToLoad )) { if( validateemlfile( gameToLoad ) == 0 ) fatalError( "Email gamefile %s is invalid. Aborting.", gameToLoad ); try { tnfilestream gamefile ( gameToLoad, tnstream::reading ); tnetworkloaders nwl; nwl.loadnwgame( &gamefile ); if ( actmap->network ) setallnetworkpointers ( actmap->network ); } catch ( tfileerror ) { fatalError ( "%s is not a legal email game.", gameToLoad ); } } else if( patimat ( savegameextension, gameToLoad )) { if( validatesavfile( gameToLoad ) == 0 ) fatalError ( "The savegame %s is invalid. Aborting.", gameToLoad ); try { loadgame( gameToLoad ); computeview( actmap ); } catch ( tfileerror ) { fatalError ( "%s is not a legal savegame. ", gameToLoad ); } } else if( patimat ( mapextension, gameToLoad )) { if( validatemapfile( gameToLoad ) == 0 ) fatalError ( "Mapfile %s is invalid. Aborting.", gameToLoad ); try { loadmap( gameToLoad ); if ( actmap->network ) setallnetworkpointers ( actmap->network ); actmap->startGame(); } catch ( tfileerror ) { fatalError ( "%s is not a legal map. ", gameToLoad ); } } else fatalError ( "Don't know how to handle the file %s ", gameToLoad ); } catch ( InvalidID err ) { displaymessage( err.getMessage().c_str(), 2 ); } /* endcatch */ catch ( tinvalidversion err ) { if ( err.expected < err.found ) 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 ); else 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 ); } } else { // resort to loading defaults ASCString s; if ( CGameOptions::Instance()->startupMap.getName() ) { if ( ASCString ( CGameOptions::Instance()->startupMap.getName() ) == "asc000.map" ) CGameOptions::Instance()->startupMap.setName( "asc001.map"); s= CGameOptions::Instance()->startupMap.getName(); } if ( s.empty() ) s = "asc001.map"; int maploadable; { tfindfile ff ( s ); string filename = ff.getnextname(); maploadable = validatemapfile ( filename.c_str() ); } if ( !maploadable ) { tfindfile ff ( mapextension ); string filename = ff.getnextname(); if ( filename.empty() ) displaymessage( "unable to load startup-map",2); while ( !validatemapfile ( filename.c_str() ) ) { filename = ff.getnextname(); if ( filename.empty() ) displaymessage( "unable to load startup-map",2); } s = filename; } loadmap(s.c_str()); displayLogMessage ( 6, "initializing map..." ); actmap->startGame(); displayLogMessage ( 6, "done\n Setting up Resources..." ); actmap->setupResources(); displayLogMessage ( 6, "done\n" ); } } void startnextcampaignmap( int id) { tcontinuecampaign ncm; ncm.init(); ncm.setid(id); ncm.run(); ncm.done(); } void benchgame ( int mode ) { int t2; int t = ticker; int n = 0; do { if ( mode <= 1 ) { if ( mode == 1 ) computeview( actmap ); displaymap(); } else copy2screen(); n++; t2 = ticker; } while ( t + 1000 > t2 ); /* enddo */ double d = 100 * n; d /= (t2-t); char buf[100]; sprintf ( buf, "%3.1f", d ); displaymessage2 ( " %s fps ", buf ); } class WeaponRange : public SearchFields { public: int run ( const pvehicle veh ); void testfield ( const MapCoordinate& mc ) { gamemap->getField( mc )->tempw = 1; }; WeaponRange ( pmap _gamemap ) : SearchFields ( _gamemap ) {} ; }; int WeaponRange :: run ( const pvehicle veh ) { int found = 0; if ( fieldvisiblenow ( getfield ( veh->xpos, veh->ypos ))) for ( int i = 0; i < veh->typ->weapons.count; i++ ) { if ( veh->typ->weapons.weapon[i].shootable() ) { initsearch ( veh->getPosition(), veh->typ->weapons.weapon[i].maxdistance/minmalq, (veh->typ->weapons.weapon[i].mindistance+maxmalq-1)/maxmalq ); startsearch(); found++; } } return found; } void viewunitweaponrange ( const pvehicle veh, tkey taste ) { if ( veh && !moveparams.movestatus ) { actmap->cleartemps ( 7 ); WeaponRange wr ( actmap ); int res = wr.run ( veh ); if ( res ) { displaymap(); if ( taste != ct_invvalue ) { while ( skeypress ( taste )) { while ( keypress() ) r_key(); releasetimeslice(); } } else { int mb = mouseparams.taste; while ( mouseparams.taste == mb && !keypress() ) releasetimeslice(); while ( keypress() ) r_key(); } actmap->cleartemps ( 7 ); displaymap(); } } } void viewPipeNet( tkey taste ) { if ( !moveparams.movestatus ) { actmap->cleartemps ( 7 ); TerrainBits tb = getTerrainBitType(cbpipeline); for ( int x = 0; x < actmap->xsize; ++x ) for ( int y = 0; y < actmap->ysize; ++y ) { pfield fld = actmap->getField ( x, y ); if ( fieldvisiblenow( fld )) if ( (fld->bdt & tb).any() || fld->building ) fld->a.temp = 1; } displaymap(); if ( taste != ct_invvalue ) { while ( skeypress ( taste )) { while ( keypress() ) r_key(); releasetimeslice(); } } else { int mb = mouseparams.taste; while ( mouseparams.taste == mb && !keypress() ) releasetimeslice(); while ( keypress() ) r_key(); } actmap->cleartemps ( 7 ); displaymap(); } } void viewunitmovementrange ( pvehicle veh, tkey taste ) { if ( veh && !moveparams.movestatus && fieldvisiblenow ( getfield ( veh->xpos, veh->ypos ))) { actmap->cleartemps ( 7 ); TemporaryContainerStorage tcs ( veh, false ); veh->reactionfire.disable(); veh->setMovement ( veh->typ->movement[log2(veh->height)]); int oldcolor = veh->color; veh->color = actmap->actplayer*8; VehicleMovement vm ( NULL, NULL ); if ( vm.available ( veh )) { vm.execute ( veh, -1, -1, 0, -1, -1 ); veh->color = oldcolor; if ( vm.reachableFields.getFieldNum()) { for ( int i = 0; i < vm.reachableFields.getFieldNum(); i++ ) if ( fieldvisiblenow ( vm.reachableFields.getField ( i ) )) vm.reachableFields.getField ( i )->a.temp = 1; for ( int j = 0; j < vm.reachableFieldsIndirect.getFieldNum(); j++ ) if ( fieldvisiblenow ( vm.reachableFieldsIndirect.getField ( j ))) vm.reachableFieldsIndirect.getField ( j )->a.temp = 1; displaymap(); if ( taste != ct_invvalue ) { while ( skeypress ( taste )) { while ( keypress() ) r_key(); releasetimeslice(); } } else { int mb = mouseparams.taste; while ( mouseparams.taste == mb && !keypress() ) releasetimeslice(); while ( keypress() ) r_key(); } actmap->cleartemps ( 7 ); displaymap(); } } veh->color = oldcolor; tcs.restore(); } } void renameUnit() { if ( actmap ) { pfield fld = getactfield(); if ( fld && fld->vehicle && fld->vehicle->getOwner() == actmap->actplayer ) fld->vehicle->name = editString ( "unit name", fld->vehicle->name ); if ( fld && fld->building && fld->building->getOwner() == actmap->actplayer ) fld->building->name = editString ( "building name", fld->building->name ); } } void calcCargoSummary( ContainerBase* cb, map& summary ) { for ( int i = 0; i < 32; ++i ) if ( cb->loading[i] ) { calcCargoSummary( cb->loading[i], summary ); summary[cb->loading[i]->typ->id] += 1; } } typedef map Summary; void showSummary ( map& summary ) { ASCString s; map sorter; for ( Summary::iterator i = summary.begin(); i != summary.end(); ++i ) sorter[vehicleTypeRepository.getObject_byID( i->first )->name] = i->second; for ( map::iterator i = sorter.begin(); i != sorter.end(); ++i ) s += i->first + ": " + strrr(i->second) + "\n"; tviewanytext vat ; vat.init ( "Unit summary", s.c_str(), 20, -1 , 450, 480 ); vat.run(); vat.done(); } void showCargoSummary() { Summary summary; pfield fld = getactfield(); if ( fld && fld->vehicle && fld->vehicle->getOwner() == actmap->actplayer ) { calcCargoSummary( fld->vehicle, summary ); showSummary( summary ); } } void showUnitSummary() { Summary summary; for ( int y = 0; y < actmap->ysize; ++y ) for ( int x = 0; x < actmap->xsize; ++x ) { pfield fld = actmap->getField(x,y); if ( fld ) { if ( fld->vehicle && fld->vehicle->getOwner() == actmap->actplayer ) { calcCargoSummary( fld->vehicle, summary ); summary[ fld->vehicle->typ->id] += 1; } if ( fld->building && fld->building->getOwner() == actmap->actplayer && (fld->bdt & getTerrainBitType(cbbuildingentry)).any() ) calcCargoSummary( fld->getContainer(), summary ); } } showSummary( summary ); } void showSearchPath() { ASCString s; for ( int i = 0; i < getSearchPathNum(); ++i ) s += getSearchPath ( i ) + "\n"; s += "\n"; s += "Configuration file used: \n"; s += getConfigFileName(); tviewanytext vat ; vat.init ( "Search Path", s.c_str(), 20, -1 , 450, 480 ); vat.run(); vat.done(); } void execuseraction ( tuseractions action ) { switch ( action ) { case ua_repainthard : case ua_repaint : repaintdisplay(); break; case ua_help : help(20); break; case ua_howtostartpbem : help(21); break; case ua_howtocontinuepbem : help(22); break; case ua_showpalette : showpalette(); break; case ua_dispvehicleimprovement : /* displaymessage("Research:\n%s %d \n%s %d \n%s %d \n" "%s %d \n%s %d \n%s %d \n" "%s %d \n%s %d \n%s %d \n" "%s %d",1, cwaffentypen[0], (actmap->player[actmap->actplayer].research.unitimprovement.weapons[0]), cwaffentypen[1], (actmap->player[actmap->actplayer].research.unitimprovement.weapons[1]), cwaffentypen[2], (actmap->player[actmap->actplayer].research.unitimprovement.weapons[2]), cwaffentypen[3], (actmap->player[actmap->actplayer].research.unitimprovement.weapons[3]), cwaffentypen[4], (actmap->player[actmap->actplayer].research.unitimprovement.weapons[4]), cwaffentypen[5], (actmap->player[actmap->actplayer].research.unitimprovement.weapons[5]), cwaffentypen[6], (actmap->player[actmap->actplayer].research.unitimprovement.weapons[6]) , cwaffentypen[7], (actmap->player[actmap->actplayer].research.unitimprovement.weapons[7]) , cwaffentypen[10], (actmap->player[actmap->actplayer].research.unitimprovement.weapons[10]) , "armor", (actmap->player[actmap->actplayer].research.unitimprovement.armor)); */ break; case ua_mainmenu: if (choice_dlg("do you really want to close the current game ?","~y~es","~n~o") == 1) { delete actmap; actmap = NULL; throw NoMapLoaded(); } break; case ua_mntnc_morefog: if (actmap->weather.fog < 255 && maintainencecheck() ) { actmap->weather.fog++; computeview( actmap ); displaymessage2("fog intensity set to %d ", actmap->weather.fog); displaymap(); } break; case ua_mntnc_lessfog: if (actmap->weather.fog && maintainencecheck()) { actmap->weather.fog--; computeview( actmap ); displaymessage2("fog intensity set to %d ", actmap->weather.fog); displaymap(); } break; case ua_mntnc_morewind: if ((actmap->weather.windSpeed < 254) && maintainencecheck()) { actmap->weather.windSpeed+=2; displaywindspeed ( ); dashboard.x = 0xffff; } break; case ua_mntnc_lesswind: if ((actmap->weather.windSpeed > 1) && maintainencecheck() ) { actmap->weather.windSpeed-=2; displaywindspeed ( ); dashboard.x = 0xffff; } break; case ua_mntnc_rotatewind: if ( maintainencecheck() ) { if (actmap->weather.windDirection < sidenum-1 ) actmap->weather.windDirection++; else actmap->weather.windDirection = 0; displaymessage2("wind dir set to %d ", actmap->weather.windDirection); dashboard.x = 0xffff; resetallbuildingpicturepointers(); displaymap(); } break; case ua_changeresourceview: showresources++; if ( showresources >= 3 ) showresources = 0; displaymap(); break; case ua_benchgamewov: benchgame( 0 ); break; case ua_benchgamewv : benchgame( 1 ); break; case ua_viewterraininfo: viewterraininfo(); break; case ua_unitweightinfo: if ( fieldvisiblenow ( getactfield() )) { pvehicle eht = getactfield()->vehicle; if ( eht && getdiplomaticstatus ( eht->color ) == capeace ) displaymessage(" weight of unit: \n basic: %d\n+cargo:%d\n= %d",1 ,eht->typ->weight, eht->cargo(), eht->weight() ); } break; case ua_writemaptopcx : writemaptopcx (); break; case ua_writescreentopcx: { char* nm = getnextfilenumname ( "screen", "pcx", 0 ); writepcx ( nm, 0, 0, agmp->resolutionx-1, agmp->resolutiony-1, pal ); displaymessage2( "screen saved to %s", nm ); } break; case ua_startnewsinglelevel: startnewsinglelevelfromgame(); break; case ua_changepassword: { bool success; do { Password oldpwd = actmap->player[actmap->actplayer].passwordcrc; actmap->player[actmap->actplayer].passwordcrc.reset(); success = enterpassword ( actmap->player[actmap->actplayer].passwordcrc, true, true ); if ( !success ) actmap->player[actmap->actplayer].passwordcrc = oldpwd; } while ( actmap->player[actmap->actplayer].passwordcrc.empty() && success && viewtextquery ( 910, "warning", "~e~nter password", "~c~ontinue without password" ) == 0 ); /* enddo */ } break; case ua_gamepreferences: gamepreferences(); break; case ua_mousepreferences: mousepreferences(); break; case ua_bi3preferences: bi3preferences(); break; case ua_exitgame: if (choice_dlg("do you really want to quit ?","~y~es","~n~o") == 1) abortgame = 1; else exitprogram = 0; break; case ua_newcampaign: cursor.hide(); newcampaign(); if ( !actmap ) throw NoMapLoaded(); computeview( actmap ); displaymap(); cursor.show(); break; case ua_loadgame: loadGame(); break; case ua_savegame: saveGame( true ); break; case ua_setupalliances: setupalliances(); logtoreplayinfo ( rpl_alliancechange ); logtoreplayinfo ( rpl_shareviewchange ); if ( actmap->shareview && actmap->shareview->recalculateview ) { logtoreplayinfo ( rpl_shareviewchange ); computeview( actmap ); actmap->shareview->recalculateview = 0; displaymap(); } dashboard.x = 0xffff; break; case ua_settribute : settributepayments (); break; case ua_giveunitaway: if ( actmap && actmap->getgameparameter( cgp_disableUnitTransfer ) == 0 ) giveunitaway (); else displaymessage("Sorry, this function has been disabled when starting the map!", 1 ); break; case ua_renameunit: renameUnit(); break; case ua_vehicleinfo: activefontsettings.font = schriften.smallarial; vehicle_information(); break; case ua_researchinfo: researchinfo (); break; case ua_unitstatistics: statisticarmies(); break; case ua_buildingstatistics: statisticbuildings(); break; case ua_newmessage: newmessage(); break; case ua_viewqueuedmessages: viewmessages( "queued messages", actmap->unsentmessage, 1, 0 ); break; case ua_viewsentmessages: viewmessages( "sent messages", actmap->player[ actmap->actplayer ].sentmessage, 0, 0 ); break; case ua_viewreceivedmessages: viewmessages( "received messages", actmap->player[ actmap->actplayer ].oldmessage, 0, 1 ); break; case ua_viewjournal: viewjournal(); break; case ua_editjournal: editjournal(); break; case ua_viewaboutmessage: { help(30); tviewanytext vat; ASCString s = getstartupmessage(); #ifdef _SDL_ char buf[1000]; SDL_version compiled; SDL_VERSION(&compiled); sprintf(buf, "\nCompiled with SDL version: %d.%d.%d\n", compiled.major, compiled.minor, compiled.patch); s += buf; sprintf(buf, "Linked with SDL version: %d.%d.%d\n", SDL_Linked_Version()->major, SDL_Linked_Version()->minor, SDL_Linked_Version()->patch); s += buf; #endif vat.init ( "about", s.c_str() ); vat.run(); vat.done(); } break; case ua_continuenetworkgame: continuenetworkgame(); displaymap(); break; case ua_toggleunitshading: CGameOptions::Instance()->units_gray_after_move = !CGameOptions::Instance()->units_gray_after_move; CGameOptions::Instance()->setChanged(); displaymap(); while ( mouseparams.taste ) releasetimeslice(); if ( CGameOptions::Instance()->units_gray_after_move ) displaymessage("units that can not move will now be displayed gray", 3); else displaymessage("units that can not move and cannot shoot will now be displayed gray", 3); break; case ua_computerturn: if ( maintainencecheck() || 1) { displaymessage("This function is under development and for programmers only\n" "unpredictable things may happen ...",3 ) ; if (choice_dlg("do you really want to start the AI?","~y~es","~n~o") == 1) { if ( !actmap->player[ actmap->actplayer ].ai ) actmap->player[ actmap->actplayer ].ai = new AI ( actmap, actmap->actplayer ); savegame ( "aistart.sav" ); actmap->player[ actmap->actplayer ].ai->run(); } } break; case ua_setupnetwork: if ( actmap->network ) setupnetwork ( actmap->network ); else displaymessage("This map is not played across a network",3 ); break; case ua_selectgraphicset: selectgraphicset(); break; case ua_UnitSetInfo: viewUnitSetinfo(); break; case ua_GameParameterInfo: showGameParameters(); break; case ua_GameStatus: displaymessage ( "Current game time is:\n turn %d , move %d ", 3, actmap->time.turn(), actmap->time.move() ); break; case ua_viewunitweaponrange: viewunitweaponrange ( getactfield()->vehicle, ct_invvalue ); break; case ua_viewunitmovementrange: viewunitmovementrange ( getactfield()->vehicle, ct_invvalue ); break; case ua_aibench: if ( maintainencecheck() && 0 ) { if ( !actmap->player[ actmap->actplayer ].ai ) actmap->player[ actmap->actplayer ].ai = new AI ( actmap, actmap->actplayer ); if ( AI* ai = dynamic_cast( actmap->player[ actmap->actplayer ].ai )) { savegame ( "ai-bench-start.sav" ); ai->run( true ); } } break; case ua_networksupervisor: networksupervisor(); displaymap(); break; case ua_selectPlayList: selectPlayList(); break; case ua_statisticdialog: statisticDialog(); break; case ua_soundDialog: soundSettings(); break; case ua_togglesound: if ( !SoundSystem::getInstance()->isOff() ) { bool on = !SoundSystem::getInstance()->areEffectsMuted(); SoundSystem::getInstance()->setEffectsMute( on ); if ( on ) SoundSystem::getInstance()->pauseMusic(); else SoundSystem::getInstance()->resumeMusic(); } break; case ua_showPlayerSpeed: showPlayerTime(); break; case ua_cancelResearch: if ( actmap->player[actmap->actplayer].research.activetechnology ) { ASCString s = "do you really want to cancel the current research project ?\n"; // s += strrr ( actmap->player[actmap->actplayer].research.progress ); // s += " research points will be lost."; if (choice_dlg(s.c_str(),"~y~es","~n~o") == 1) { actmap->player[actmap->actplayer].research.progress = 0; actmap->player[actmap->actplayer].research.activetechnology = NULL; } } else displaymessage("you are not researching anything", 3); break; case ua_showResearchStatus: { ASCString s; s += "Current technology:\n"; if ( actmap->player[actmap->actplayer].research.activetechnology ) s += actmap->player[actmap->actplayer].research.activetechnology->name; else s += " - none - "; s += "\n\n"; s += "Research Points: \n"; s += strrr( actmap->player[actmap->actplayer].research.progress ); if ( actmap->player[actmap->actplayer].research.activetechnology ) s += ASCString(" / ") + strrr ( actmap->player[actmap->actplayer].research.activetechnology->researchpoints ); s += "\n\n"; s+= "Research Points Plus \n"; int p = 0; for ( Player::BuildingList::iterator i = actmap->player[actmap->actplayer].buildingList.begin(); i != actmap->player[actmap->actplayer].buildingList.end(); ++i ) p += (*i)->researchpoints; s += strrr ( p ); s += "\n\n"; s+= "Developed Technologies: \n"; for ( vector::iterator i = actmap->player[actmap->actplayer].research.developedTechnologies.begin(); i != actmap->player[actmap->actplayer].research.developedTechnologies.end(); ++i ) { Technology* t = technologyRepository.getObject_byID( *i ); if ( t ) s += t->name + "\n"; } tviewanytext vat ; vat.init ( "Research Status", s.c_str(), 20, -1 , 450, 480 ); vat.run(); vat.done(); } break; case ua_exportUnitToFile: if ( getactfield()->vehicle && getactfield()->vehicle->getOwner() == actmap->actplayer ){ ASCString s = "do you really want to cut this unit from the game?"; if (choice_dlg(s.c_str(),"~y~es","~n~o") == 1) { Vehicle* veh = getactfield()->vehicle; ClipBoard::Instance().clear(); ClipBoard::Instance().addUnit( veh ); ASCString filename; fileselectsvga(clipboardFileExtension, filename, false); if ( !filename.empty() ) { tnfilestream stream ( filename, tnstream::writing ); ClipBoard::Instance().write( stream ); logtoreplayinfo ( rpl_cutFromGame, veh->networkid ); veh->prepareForCleanRemove(); delete veh; computeview( actmap ); displaymap(); } } } break; case ua_cargosummary: showCargoSummary(); break; case ua_unitsummary: showUnitSummary(); break; case ua_showsearchdirs: showSearchPath(); break; #ifndef NO_PARAGUI case ua_reloadDlgTheme: if ( pgApp ) { pgApp->reloadTheme(); soundSettings(); } break; #endif } } void checkpulldown( tkey ch ) { pd.key = ch; pd.checkpulldown(); if (pd.action2execute >= 0 ) { tuseractions ua = (tuseractions) pd.action2execute; pd.action2execute = -1; execuseraction ( ua ); } } void mainloopgeneralkeycheck ( tkey& ch ) { int keyprn; getkeysyms ( &ch, &keyprn ); checkpulldown( ch ); movecursor(ch); actgui->checkforkey ( ch, keyprn ); } void mainloopgeneralmousecheck ( void ) { if ( exitprogram ) execuseraction ( ua_exitgame ); actgui->checkformouse(); dashboard.checkformouse(); if ((dashboard.x != getxpos()) || (dashboard.y != getypos())) { dashboard.paint ( getactfield(), actmap->playerView ); actgui->painticons(); } if ( lastdisplayedmessageticker + messagedisplaytime < ticker ) displaymessage2(""); if ( mousecontrol ) mousecontrol->chkmouse(); { int oldx = actmap->xpos; int oldy = actmap->ypos; checkformousescrolling(); if ( oldx != actmap->xpos || oldy != actmap->ypos ) dashboard.x = 0xffff; } if ( onlinehelp ) onlinehelp->checkforhelp(); if ( onlinehelpwind && !CGameOptions::Instance()->smallmapactive ) onlinehelpwind->checkforhelp(); } void mainloop ( void ) { tkey ch; abortgame = 0; do { viewunreadmessages(); activefontsettings.background=0; activefontsettings.length=50; activefontsettings.color=14; if (keypress()) { mainloopgeneralkeycheck ( ch ); switch (ch) { #ifndef NEWKEYB case 'R': execuseraction ( ua_repainthard ); break; #else case ct_shp + ct_r: execuseraction ( ua_repainthard ); break; #endif case ct_stp + ct_l: execuseraction ( ua_loadgame ); break; case ct_stp + ct_s: execuseraction ( ua_savegame ); break; case ct_stp + ct_n: execuseraction ( ua_startnewsinglelevel ); break; case ct_stp + ct_f12: execuseraction ( ua_exportUnitToFile ); break; case ct_r: execuseraction ( ua_repaint ); break; case ct_f1: execuseraction ( ua_help ); break; case ct_f2: execuseraction ( ua_mainmenu ); break; case ct_f3: execuseraction ( ua_continuenetworkgame ); break; case ct_f4: execuseraction ( ua_computerturn ); break; case ct_f8: { int color = actmap->actplayer; for ( int p = 0; p < 8; p++ ) if ( actmap->player[p].stat == Player::computer && actmap->player[p].exist() ) color = p; if ( actmap->player[color].ai ) { AI* ai = (AI*) actmap->player[color].ai; ai->showFieldInformation ( getxpos(), getypos() ); } } break; case ct_f11: { int counter = 0; for ( int i = 0; i < vehicleTypeRepository.getNum(); ++i ) if ( vehicleTypeRepository.getObject_byPos(i)->movemalustyp == 0 ) { printf( "%s \n", vehicleTypeRepository.getObject_byPos(i)->name.c_str() ); ++counter; } displaymessage("%d / %d", 1, counter, vehicleTypeRepository.getNum() ); // delete getactfield()->vehicle->aiparam[1]; // getactfield()->vehicle->aiparam[1] = NULL; // displaymap(); } break; case ct_1: execuseraction ( ua_changeresourceview ); break; case ct_2: execuseraction ( ua_toggleunitshading ); break; case ct_3: viewunitweaponrange ( getactfield()->vehicle, ct_3 ); break; case ct_4: viewunitmovementrange ( getactfield()->vehicle, ct_4 ); break; case ct_5: execuseraction ( ua_GameStatus ); break; case ct_6: execuseraction ( ua_UnitSetInfo ); break; case ct_7: execuseraction ( ua_viewterraininfo ); break; case ct_8: execuseraction ( ua_unitweightinfo ); break; case ct_9: viewPipeNet ( ct_9 ); break; case ct_0: execuseraction( ua_writescreentopcx ); break; case ct_x + ct_stp: execuseraction ( ua_exitgame ); break; } } else ch = ct_invvalue; mainloopgeneralmousecheck ( ); /************************************************************************************************/ /* Pulldown Men? . */ /************************************************************************************************/ checkpulldown( ch ); while ( actmap->player[ actmap->actplayer ].queuedEvents ) checkevents( &defaultMapDisplay ); checktimedevents( &defaultMapDisplay ); checkforvictory(); releasetimeslice(); } while ( !abortgame ); } pfont load_font ( const char* name ) { tnfilestream stream ( name , tnstream::reading ); return loadfont ( &stream ); } const char* progressbarfilename = "progress.6mn"; void loaddata( int resolx, int resoly, const char *gameToLoad=NULL ) { actprogressbar = new tprogressbar; if ( actprogressbar ) { tfindfile ff ( progressbarfilename ); if ( !ff.getnextname().empty() ) { tnfilestream strm ( progressbarfilename, tnstream::reading ); actprogressbar->start ( 255, 0, agmp->resolutiony-3, agmp->resolutionx-1, agmp->resolutiony-1, &strm ); } else { actprogressbar->start ( 255, 0, agmp->resolutiony-3, agmp->resolutionx-1, agmp->resolutiony-1, NULL ); } } schriften.smallarial = load_font("smalaril.fnt"); schriften.large = load_font("usablack.fnt"); schriften.arial8 = load_font("arial8.fnt"); schriften.smallsystem = load_font("msystem.fnt"); schriften.guifont = load_font("gui.fnt"); schriften.guicolfont = load_font("guicol.fnt"); schriften.monogui = load_font("monogui.fnt"); activefontsettings.markfont = schriften.guicolfont; shrinkfont ( schriften.guifont, -1 ); shrinkfont ( schriften.guicolfont, -1 ); shrinkfont ( schriften.monogui, -1 ); pulldownfont = schriften.smallarial ; if ( actprogressbar ) actprogressbar->startgroup(); SoundList::init(); if ( actprogressbar ) actprogressbar->startgroup(); loadMoreData(); if ( actprogressbar ) actprogressbar->startgroup(); registerDataLoader ( new PlayListLoader() ); registerDataLoader ( new BI3TranslationTableLoader() ); loadguipictures(); if ( actprogressbar ) actprogressbar->startgroup(); loadAllData(); if ( actprogressbar ) actprogressbar->startgroup(); loadUnitSets(); if ( actprogressbar ) actprogressbar->startgroup(); cursor.init(); selectbuildinggui.init( resolx, resoly ); selectobjectcontainergui.init( resolx, resoly ); selectvehiclecontainergui.init( resolx, resoly ); if ( actprogressbar ) actprogressbar->startgroup(); loadStartupMap( gameToLoad ); if ( actprogressbar ) actprogressbar->startgroup(); displayLogMessage ( 6, "loading gui icons..." ); gui.starticonload(); displayLogMessage ( 6, "done\n" ); if ( actprogressbar ) actprogressbar->startgroup(); dashboard.allocmem (); mousecontrol = new cmousecontrol; if ( actprogressbar ) { actprogressbar->end(); try { tnfilestream strm ( progressbarfilename, tnstream::writing ); actprogressbar->writetostream( &strm ); } /* endtry */ catch ( tfileerror ) { } /* endcatch */ delete actprogressbar; actprogressbar = NULL; } } void runmainmenu ( void ) { MainMenuPullDown pd; pd.init(); backgroundpict.paint(); pd.baron(); // loadFullscreenImage ( "title.jpg" ); do { tkey ch = ct_invvalue; if (keypress()) { ch = r_key(); switch (ch) { case ct_f3: execuseraction ( ua_continuenetworkgame ); break; case 'R': execuseraction ( ua_repainthard ); break; case ct_stp + ct_l: execuseraction ( ua_loadgame ); break; case ct_stp + ct_n: execuseraction ( ua_startnewsinglelevel ); break; case ct_x + ct_stp: execuseraction ( ua_exitgame ); break; }; } pd.key = ch; pd.checkpulldown(); if (pd.action2execute >= 0 ) { tuseractions ua = (tuseractions) pd.action2execute; pd.action2execute = -1; execuseraction ( ua ); pd.redraw(); } releasetimeslice(); } while ( !actmap && !abortgame ); /* enddo */ } struct GameThreadParams { ASCString filename; }; int gamethread ( void* data ) { GameThreadParams* gtp = (GameThreadParams*) data; initMapDisplay( ); int resolx = agmp->resolutionx; int resoly = agmp->resolutiony; gui.init ( resolx, resoly ); virtualscreenbuf.init(); try { int fs = loadFullscreenImage ( "title.jpg" ); if ( !fs ) { tnfilestream stream ( "logo640.pcx", tnstream::reading ); loadpcxxy( &stream, (hgmp->resolutionx - 640)/2, (hgmp->resolutiony-35)/2, 1 ); } loaddata( resolx, resoly, gtp->filename.c_str() ); if ( fs ) closeFullscreenImage (); } catch ( ParsingError err ) { displaymessage ( "Error parsing text file " + err.getMessage(), 2 ); } catch ( tfileerror err ) { displaymessage ( "Error loading file " + err.getFileName(), 2 ); } catch ( ASCexception ) { displaymessage ( "loading of game failed", 2 ); } #ifndef WIN32 catch ( ... ) { displaymessage ( "caught undefined exception", 2 ); } #endif displayLogMessage ( 5, "loaddata completed successfully.\n" ); setvgapalette256(pal); addmouseproc ( &mousescrollproc ); displayLogMessage ( 5, "starting music..." ); startMusic(); displayLogMessage ( 5, " done \n" ); onlinehelp = new tsgonlinemousehelp; onlinehelpwind = new tsgonlinemousehelpwind; pd.init(); abortgame = 0; gameStartupComplete = true; displayLogMessage ( 5, "entering outer main loop.\n" ); do { try { if ( !actmap || actmap->xsize <= 0 || actmap->ysize <= 0 ) { displayLogMessage ( 8, "gamethread :: starting main menu.\n" ); runmainmenu(); } else { if ( actmap->actplayer == -1 ) { displayLogMessage ( 8, "gamethread :: performing next_turn..." ); next_turn(); displayLogMessage ( 8, "done.\n" ); } displayLogMessage ( 8, "gamethread :: Painting background pict..." ); backgroundpict.paint(); displayLogMessage ( 8, "done\n" ); if ( !gtp->filename.empty() && patimat ( tournamentextension, gtp->filename.c_str() ) ) { displayLogMessage ( 5, "Initializing network game..." ); initNetworkGame ( ); displayLogMessage ( 5, "done\n" ); } displayLogMessage ( 8, "gamethread :: displaying map..." ); displaymap(); displayLogMessage ( 8, "done.\n" ); cursor.show(); moveparams.movestatus = 0; displayLogMessage ( 8, "gamethread :: painting gui icons..." ); actgui->painticons(); displayLogMessage ( 8, "done.\n" ); mousevisible(true); dashboard.x = 0xffff; dashboard.y = 0xffff; setupMainScreenWidget(); displayLogMessage ( 5, "entering inner main loop.\n" ); mainloop(); mousevisible ( false ); } } /* endtry */ catch ( NoMapLoaded ) { } /* endcatch */ catch ( ShutDownMap ) { delete actmap; actmap = NULL; } catch ( LoadNextMap lnm ) { if ( actmap->campaign ) { startnextcampaignmap( lnm.id ); } else { viewtext2(904); if (choice_dlg("Do you want to continue playing ?","~y~es","~n~o") == 2) { delete actmap; actmap = NULL; } else { actmap->continueplaying = 1; if ( actmap->replayinfo ) { delete actmap->replayinfo; actmap->replayinfo = NULL; } } } } } while ( abortgame == 0); return 0; } // including the command line parser, which is generated by genparse #include "clparser/asc.cpp" int main(int argc, char *argv[] ) { putenv("SDL_VIDEO_CENTERED=1") ; assert ( sizeof(PointerSizedInt) == sizeof(int*)); Cmdline* cl = NULL; auto_ptr apcl ( cl ); try { cl = new Cmdline ( argc, argv ); } catch ( string s ) { cerr << s.c_str(); exit(1); } /* if ( cl->next_param() < argc ) { cerr << "invalid command line parameter\n"; exit(1); }*/ if ( cl->v() ) { ASCString msg = getstartupmessage(); printf( msg.c_str() ); exit(0); } if ( cl->w() ) fullscreen = SDL_FALSE; if ( cl->f() ) fullscreen = SDL_TRUE; verbosity = cl->r(); displayLogMessage( 1, getstartupmessage() ); mapborderpainter = &backgroundpict; initFileIO( cl->c().c_str() ); // passing the filename from the command line options try { checkDataVersion(); check_bi3_dir (); } catch ( tfileerror err ) { displaymessage ( "unable to access file %s \n", 2, err.getFileName().c_str() ); } catch ( ... ) { displaymessage ( "loading of game failed during pre graphic initializing", 2 ); } if ( CGameOptions::Instance()->forceWindowedMode && !cl->f() ) // cl->f == force fullscreen command line param fullscreen = SDL_FALSE; #ifdef NO_PARAGUI SDL_Init ( SDL_INIT_VIDEO ); #endif SDLmm::Surface* icon = NULL; try { tnfilestream iconl ( "icon_asc.gif", tnstream::reading ); SDL_Surface *icn = IMG_LoadGIF_RW( SDL_RWFromStream ( &iconl )); SDL_SetColorKey(icn, SDL_SRCCOLORKEY, *((Uint8 *)icn->pixels)); icon = new SDLmm::Surface ( icn ); } catch ( ... ) {} int xr = 800; int yr = 600; // determining the graphics resolution if ( CGameOptions::Instance()->xresolution != 800 ) xr = CGameOptions::Instance()->xresolution; if ( cl->x() != 800 ) xr = cl->x(); if ( CGameOptions::Instance()->yresolution != 600 ) yr = CGameOptions::Instance()->yresolution; if ( cl->y() != 600 ) yr = cl->y(); SoundSystem soundSystem ( CGameOptions::Instance()->sound.muteEffects, CGameOptions::Instance()->sound.muteMusic, cl->q() || CGameOptions::Instance()->sound.off ); soundSystem.setMusicVolume ( CGameOptions::Instance()->sound.musicVolume ); soundSystem.setEffectVolume ( CGameOptions::Instance()->sound.soundVolume ); #ifndef NO_PARAGUI ASC_PG_App app ( "asc_dlg" ); pgApp = &app; int flags = SDL_SWSURFACE; if ( fullscreen ) flags |= SDL_FULLSCREEN; SDL_WM_SetIcon( icon->GetSurface(), NULL ); app.InitScreen( xr, yr, 8, flags); initASCGraphicSubsystem ( app.GetScreen(), icon ); #else SDL_WM_SetIcon( icon->GetSurface(), NULL ); initgraphics ( xr, yr, 8, icon ); #endif setWindowCaption ( "Advanced Strategic Command" ); GameThreadParams gtp; gtp.filename = cl->l(); if ( cl->next_param() < argc ) for ( int i = cl->next_param(); i < argc; i++ ) gtp.filename = argv[i]; { int w; tnfilestream stream ("mausi.raw", tnstream::reading); stream.readrlepict( &icons.mousepointer, false, &w ); } try { // this starts the gamethread procedure, whichs will run the entire game initializeEventHandling ( gamethread, >p, icons.mousepointer ); } catch ( bad_alloc ) { fatalError ("Out of memory"); } closegraphics(); writegameoptions ( ); delete onlinehelp; onlinehelp = NULL; delete onlinehelpwind; onlinehelpwind = NULL; #ifdef MEMCHK verifyallblocks(); #endif #ifdef NO_PARAGUI SDL_Quit(); #endif return(0); }