1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247 |
- /*
- * Seven Kingdoms: Ancient Adversaries
- *
- * Copyright 1997,1998 Enlight Software Ltd.
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- //Filename : OSYS.CPP
- //Description : System resource management object
- #include <RESOURCE.h>
- #include <stdio.h>
- #include <ALL.h>
- #include <OAUDIO.h>
- #include <ODATE.h>
- #include <OBOX.h>
- #include <OFONT.h>
- #include <OSTR.h>
- #include <OVGA.h>
- #include <OGAME.h>
- #include <ONEWS.h>
- #include <OTRANSL.h>
- #include <OGAMESET.h>
- #include <OGFILE.h>
- #include <OINFO.h>
- #include <OVBROWSE.h>
- #include <OIMGRES.h>
- #include <OMOUSE.h>
- #include <OMOUSE2.h>
- #include <KEY.h>
- #include <OMOUSECR.h>
- #include <OUNIT.h>
- #include <OSITE.h>
- #include <OSPATH.h>
- #include <OSPATHS2.h>
- #include <OSPREUSE.h>
- #include <OSPY.h>
- #include <OSYS.h>
- #include <OREMOTE.h>
- #include <OTECHRES.h>
- #include <OTALKRES.h>
- #include <OGODRES.h>
- #include <OHELP.h>
- #include <OTUTOR.h>
- #include <OF_BASE.h>
- #include <OTOWN.h>
- #include <OBULLET.h>
- #include <ONATION.h>
- #include <OFLAME.h>
- #include <OPOWER.h>
- #include <OTERRAIN.h>
- #include <OWORLD.h>
- #include <OANLINE.h>
- #include <OSE.h>
- #include <OLOG.h>
- #include <OERRCTRL.h>
- #include <OMUSIC.h>
- #include <OLZW.h>
- #include <OLONGLOG.h>
- #include <OVGALOCK.h>
- #include <OGRPSEL.h>
- #include <OCRC_STO.h>
- #include <OF_HARB.h>
- // ##### begin Gilbert 23/10 ######//
- #include <OOPTMENU.h>
- #include <OINGMENU.h>
- // ##### end Gilbert 23/10 ######//
- //----------- Declare static functions -----------//
- static long FAR PASCAL static_main_win_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
- //------- Define static functions -----------//
- LRESULT CALLBACK win_hook_proc(int nCode, WORD wParam, LONG lParam);
- static void test_lzw();
- static void locate_king_general(int rankId);
- static void locate_spy();
- static void locate_ship();
- static void locate_camp();
- static int locate_ship_in_harbor();
- static int locate_visible_ship();
- static int detect_scenario_cheat_key(unsigned scanCode, unsigned skeyState);
- static int get_mouse_loc_in_zoom_map(int &x, int &y);
- //----------- Define static variables ------------//
- static unsigned long last_frame_time=0, last_resend_time=0;
- static char remote_send_success_flag=1;
- static HHOOK win_hook_handle=NULL;
- static char scenario_cheat_flag=0;
- //----------- Begin of function Sys::Sys -----------//
- Sys::Sys()
- {
- memset(this, 0, sizeof(Sys) );
- common_data_buf = mem_add( COMMON_DATA_BUF_SIZE );
- view_mode = MODE_NORMAL; // the animation mode
- }
- //----------- End of function Sys::Sys -----------//
- //----------- Begin of function Sys::~Sys -----------//
- Sys::~Sys()
- {
- mem_del(common_data_buf);
- deinit();
- }
- //----------- End of function Sys::~Sys -----------//
- //------------ Begin of function Sys::init ----------//
- //
- int Sys::init( HINSTANCE hInstance )
- {
- err_when( init_flag );
- //------- initialize basic vars --------//
- app_hinstance = hInstance;
- #ifdef BETA
- debug_session = m.is_file_exist("DEBUG.SYS");
- testing_session = m.is_file_exist("TESTING.SYS");
- scenario_cheat_flag = m.is_file_exist("CHEAT.SYS");
- #endif
- #ifdef DEBUG
- debug_session = m.is_file_exist("DEBUG.SYS");
- testing_session = m.is_file_exist("TESTING.SYS");
- scenario_cheat_flag = m.is_file_exist("CHEAT.SYS");
- #endif
- // debug_session = m.is_file_exist("DEBUG.SYS");
- set_game_dir(); // set game directories names and game version
- //------- initialize more stuff ---------//
- if( !init_win() )
- return FALSE;
- if( !init_directx() )
- return FALSE;
- if( !init_objects() ) // initialize system objects which do not change from games to games.
- return FALSE;
- init_flag = 1;
- return TRUE;
- }
- //------------ End of function Sys::init ----------//
- //-------- Begin of function Sys::deinit --------//
- //
- // Finished with all objects we use; release them
- //
- void Sys::deinit()
- {
- if( !init_flag )
- return;
- game.deinit(); // actually game.deinit() will be called by main_win_proc() and calling it here will have no effect
- deinit_objects();
- //-------------------------------------//
- if( vga_back.buf_locked )
- vga_back.unlock_buf();
- if( vga_front.buf_locked )
- vga_front.unlock_buf();
- //-------------------------------------//
- /*
- extern char low_video_memory_flag;
- if( low_video_memory_flag )
- {
- ShowWindow(sys.main_hwnd, SW_MINIMIZE );
- unsigned curTime = m.get_time();
- while( m.get_time() < curTime + 4000 );
- }
- */
- //---------------------------------------//
- PostMessage(main_hwnd, WM_CLOSE, 0, 0);
- init_flag = 0;
- MSG msg;
- while( GetMessage(&msg, NULL, 0, 0) )
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- //--------- End of function Sys::deinit ---------//
- //-------- Begin of function Sys::init_win --------//
- //
- int Sys::init_win()
- {
- //--------- register window class --------//
- WNDCLASS wc;
- BOOL rc;
- wc.style = CS_DBLCLKS;
- wc.lpfnWndProc = static_main_win_proc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = app_hinstance;
- wc.hIcon = LoadIcon( app_hinstance, MAKEINTATOM(IDI_ICON1));
- wc.hCursor = LoadCursor( NULL, IDC_ARROW );
- wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = WIN_CLASS_NAME;
- rc = RegisterClass( &wc );
- if( !rc )
- return FALSE;
- //------ install keyboard hook ---------//
- /*
- win_hook_handle = SetWindowsHookEx(WH_CBT, (HOOKPROC) win_hook_proc, sys.app_hinstance, NULL);
- if( !win_hook_handle )
- err.run( "Failed installing keyboard hook." );
- */
- //--------- create window -----------//
- main_hwnd = CreateWindowEx(
- WS_EX_APPWINDOW | WS_EX_TOPMOST,
- WIN_CLASS_NAME,
- WIN_TITLE,
- WS_VISIBLE | // so we dont have to call ShowWindow
- WS_POPUP,
- 0,
- 0,
- GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN),
- NULL,
- NULL,
- app_hinstance,
- NULL );
- if( !main_hwnd )
- return FALSE;
- UpdateWindow( main_hwnd );
- SetFocus( main_hwnd );
- return TRUE;
- }
- //-------- End of function Sys::init_win --------//
- //------- Begin of function win_hook_proc --------//
- LRESULT CALLBACK win_hook_proc(int nCode, WORD wParam, LONG lParam)
- {
- static int lastnCode;
- int a=0;
- if( vga_true_front.dd_buf && vga_true_front.dd_buf->IsLost() )
- a = 1;
- lastnCode = nCode;
- if( sys.init_flag && nCode == HCBT_SETFOCUS )
- sys.pause();
- return CallNextHookEx(win_hook_handle, nCode, wParam, lParam);
- }
- //-------- End of function win_hook_proc --------//
- //-------- Begin of function Sys::init_directx --------//
- //
- int Sys::init_directx()
- {
- DEBUG_LOG("Attempt audio.init()");
- audio.init();
- DEBUG_LOG(audio.wav_init_flag);
- music.init();
- se_ctrl.init();
- //---------------------------------------//
- ShowCursor(FALSE);
- //-------- initialize DirectDraw --------//
- DEBUG_LOG("Attempt vga.init()");
- if( !vga.init() )
- return FALSE;
- DEBUG_LOG("vga.init() ok");
- DEBUG_LOG("Attempt vga.load_pal()");
- vga.load_pal(DIR_RES"PAL_STD.RES");
- DEBUG_LOG("vga.load_pal() finish");
- if( sys.debug_session ) // if we are currently in a debug session, don't lock the front buffer otherwise the system will hang up
- {
- DEBUG_LOG("Attempt vga_front.init_back()");
- vga_front.init_back( vga.dd_obj );
- vga_front.is_front = 1; // set it to 1, overriding the setting in init_back()
- DEBUG_LOG("Attempt vga_true_front.init_front()");
- vga_true_front.init_front( vga.dd_obj );
- DEBUG_LOG("Attempt vga.activate_pal()");
- vga.activate_pal(&vga_true_front);
- DEBUG_LOG("vga.activate_pal() finish");
- }
- else
- {
- vga_front.init_front( vga.dd_obj );
- vga.activate_pal(&vga_front);
- }
- DEBUG_LOG("Attempt vga_back.init_back()");
- vga_back.init_back( vga.dd_obj );
- DEBUG_LOG("vga_back.init_back() finish");
- DEBUG_LOG("Attempt vga_front.lock_buf()");
- vga_front.lock_buf();
- DEBUG_LOG("vga_front.lock_buf() finish");
- DEBUG_LOG("Attempt vga_back.lock_buf()");
- vga_back.lock_buf();
- DEBUG_LOG("vga_back.lock_buf() finish");
- return TRUE;
- }
- //-------- End of function Sys::init_directx --------//
- //-------- Begin of function Sys::deinit_directx --------//
- //
- void Sys::deinit_directx()
- {
- if( vga_back.dd_buf && vga_back.buf_locked )
- {
- DEBUG_LOG("Attempt vga_back.unlock_buf()");
- vga_back.unlock_buf();
- DEBUG_LOG("vga_back.unlock_buf() finish");
- }
- if( vga_front.dd_buf && vga_front.buf_locked )
- {
- DEBUG_LOG("Attempt vga_front.unlock_buf()");
- vga_front.unlock_buf();
- DEBUG_LOG("vga_front.unlock_buf() finish");
- }
- DEBUG_LOG("Attempt vga_back.deinit()");
- vga_back.deinit();
- DEBUG_LOG("vga_back.deinit() finish");
- if( sys.debug_session )
- {
- DEBUG_LOG("Attempt vga_true_front.deinit()");
- vga_true_front.deinit();
- DEBUG_LOG("vga_true_front.deinit() finish");
- }
- DEBUG_LOG("Attempt vga_front.deinit()");
- vga_front.deinit();
- DEBUG_LOG("Attempt vga_front.deinit() finish");
- DEBUG_LOG("Attempt vga.deinit()");
- vga.deinit();
- DEBUG_LOG("vga.deinit() finish");
- //------------------------------//
- se_ctrl.deinit();
- music.deinit();
- DEBUG_LOG("Attempt audio.deinit()");
- audio.deinit();
- DEBUG_LOG("audio.deinit() finish");
- }
- //--------- End of function Sys::deinit_directx ---------//
- //------- Begin of function Sys::init_objects -----------//
- //
- // Initialize system objects which do not change from games to games.
- //
- int Sys::init_objects()
- {
- //--------- init system class ----------//
- mouse_cursor.init();
- mouse_cursor.set_frame_border(ZOOM_X1,ZOOM_Y1,ZOOM_X2,ZOOM_Y2);
- mouse.init(app_hinstance, main_hwnd, NULL);
- //------- init resource class ----------//
- #if( defined(GERMAN) || defined(FRENCH) || defined(SPANISH) )
- font_std.init("SAN", 1);
- font_hall.init("HALL", 1);
- #else
- font_std.init("STD", 2);
- #endif
- font_san.init("SAN", 0); // 0-zero inter-character space
- font_mid.init("MID");
- font_small.init("SMAL");
- font_news.init("NEWS");
- font_hitpoint.init("HITP");
- font_bible.init("CASA", 1, 3);
- font_bard.init("CASA", 0);
- image_icon.init(DIR_RES"I_ICON.RES",1,0); // 1-read into buffer
- image_interface.init(DIR_RES"I_IF.RES",0,0); // 0-don't read into the buffer, don't use common buffer
- #ifndef DEMO // do not load these in the demo verison
- image_menu.init(DIR_RES"I_MENU.RES",0,0); // 0-don't read into the buffer, don't use common buffer
- image_encyc.init(DIR_RES"I_ENCYC.RES",0,0); // 0-don't read into the buffer, don't use common buffer
- #endif
- image_button.init(DIR_RES"I_BUTTON.RES",1,0);
- image_spict.init(DIR_RES"I_SPICT.RES",1,0);
- image_tutorial.init(DIR_RES"TUT_PICT.RES",0,0);
- #ifdef AMPLUS
- #ifndef DEMO // do not load these in the demo verison
- image_menu_plus.init(DIR_RES"I_MENU2.RES",0,0); // 0-don't read into the buffer, don't use common buffer
- #endif
- #endif
- seek_path.init(MAX_BACKGROUND_NODE);
- seek_path_s2.init(1);//seek_path_s2.init(MAX_BACKGROUND_NODE);
- seek_path_reuse.init(MAX_BACKGROUND_NODE);
- group_select.init();
- //------------ init flame ------------//
- for(int i = 0; i < FLAME_GROW_STEP; ++i)
- flame[i].init(Flame::default_width(i), Flame::default_height(i), Flame::base_width(i), FLAME_WIDE);
- //------------ init animated line drawer -------//
- anim_line.init(ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2);
- //---------- init other objects ----------//
- game_set.init(); // this must be called before game.init() as game.init() assume game_set has been initialized
- help.init("HELP.RES");
- #if( defined(GERMAN) || defined(FRENCH) || defined(SPANISH) )
- translate.init();
- #endif
- tutor.init();
- game_file_array.init("*.SAV");
- //---------- init game_set -----------//
- DEBUG_LOG("Sys::init_objects finish");
- return TRUE;
- }
- //------- End of function Sys::init_objects -----------//
- //------- Begin of function Sys::deinit_objects -----------//
- void Sys::deinit_objects()
- {
- //--------- deinit system class ----------//
- mouse.deinit(); // mouse must be deinitialized first
- mouse_cursor.deinit();
- //------- deinit resource class ----------//
- font_std.deinit();
- font_san.deinit();
- font_mid.deinit();
- font_small.deinit();
- font_news.deinit();
- font_hitpoint.deinit();
- font_bible.deinit();
- font_bard.deinit();
- #if( defined(GERMAN) || defined(FRENCH) || defined(SPANISH) )
- font_hall.deinit();
- #endif
- image_icon.deinit();
- image_interface.deinit();
- image_menu.deinit();
- image_button.deinit();
- image_spict.deinit();
- image_encyc.deinit();
- image_tutorial.deinit();
- seek_path.deinit();
- seek_path_s2.deinit();
- seek_path_reuse.deinit();
- group_select.deinit();
- for(int i = 0; i < FLAME_GROW_STEP; ++i)
- flame[i].deinit();
- //--------- deinit other objects ----------//
- game_set.deinit();
- help.deinit();
- #if( defined(GERMAN) || defined(FRENCH) || defined(SPANISH) )
- translate.deinit();
- #endif
- tutor.deinit();
- config.deinit();
- game_file_array.deinit();
- }
- //------- End of function Sys::deinit_objects -----------//
- //-------- Begin of function Sys::run --------//
- //
- void Sys::run(int isLoadedGame)
- {
- //-*********** simulate aat ************-//
- #ifdef DEBUG
- //--------- enable only when simulation -------//
- debug_sim_game_type = (m.is_file_exist("sim.sys")) ? 2 : 0;
- #endif
- //-*********** simulate aat ************-//
- sys_flag = SYS_RUN;
- view_mode = MODE_NORMAL;
- //------- test LZW compression ---------//
- #ifdef DEBUG_LZW
- test_lzw();
- #endif
- //------ reset mouse ---------//
- mouse.reset_click();
- mouse_cursor.set_frame(0);
- //-- enable power after the game objets has been initialized --//
- power.enable(); // enable power, which handle mouse inputs
- //----- sys::disp_frame() will redraw everything when this flag is set to 1 ----//
- sys.need_redraw_flag = 1;
- option_menu.active_flag = 0;
- in_game_menu.active_flag = 0;
- sys.disp_frame();
- disp_view_mode();
- //----------- run the main loop -----------//
- main_loop(isLoadedGame);
- //-----------------------------------------//
- m.unlock_seed();
- }
- //--------- End of function Sys::run --------//
- //-------- Begin of static function test_lzw --------//
- //
- static void test_lzw()
- {
- // test lzw compress
- if( m.is_file_exist("NORMAL.SAV"))
- {
- File f,g;
- Lzw lzw_c, lzw_d; // one for compress, the other for decompress
- f.file_open("NORMAL.SAV");
- // read into buffer
- long fileSize = f.file_size();
- unsigned char *srcPtr = (unsigned char *) mem_add(fileSize);
- f.file_read(srcPtr, fileSize);
- // find compressed size to allocate space
- long compSize = lzw_c.compress(srcPtr, fileSize);
- unsigned char *destPtr = (unsigned char *) mem_add( compSize/8+ 4 ); // alloc 4 bytes more
- if( compSize != lzw_c.compress(srcPtr, fileSize, destPtr) )
- {
- err_here();
- }
- // decompress again
- long backSize = lzw_d.expand(destPtr, compSize, NULL);
- err_when(backSize != fileSize);
- unsigned char *backPtr = (unsigned char *) mem_add( backSize+4 );
- if( backSize != lzw_d.expand(destPtr, compSize, backPtr) )
- {
- err_here();
- }
- // finally compare srcPtr and backPtr
- err_when( memcmp(srcPtr, backPtr, fileSize) );
- f.file_close();
- // write it to a file
- {
- unsigned char *writePtr = destPtr;
- long writeSize = (compSize +7) / 8;
- g.file_create("NORMAL.LZ1");
- for( ; writeSize > 0; writeSize -= 0x4000)
- {
- g.file_write(writePtr, writeSize > 0x4000 ? 0x4000 : writeSize);
- writePtr += 0x4000;
- }
- g.file_close();
- }
- // test two, compress to a file
- g.file_create("NORMAL.LZW");
- compSize = lzw_c.compress(srcPtr, fileSize, &g);
- g.file_close();
- g.file_open("NORMAL.LZW");
- backSize = lzw_d.expand(&g, NULL);
- err_when(backSize != fileSize);
- backPtr = (unsigned char *) mem_resize(backPtr, backSize+4 );
- g.file_close();
- g.file_open("NORMAL.LZW");
- if( backSize != lzw_d.expand(&g, backPtr))
- {
- err_here();
- }
- err_when( memcmp(srcPtr,backPtr, fileSize) );
- mem_del(destPtr);
- mem_del(backPtr);
- mem_del(srcPtr);
- }
- }
- //--------- End of static function test_lzw --------//
- //-------- Begin of function Sys::main_loop --------//
- //
- void Sys::main_loop(int isLoadedGame)
- {
- MSG msg;
- // #### begin Gilbert 31/10 #####//
- // int rc;
- // #### end Gilbert 31/10 #####//
- //-------- reset day_frame_count -------//
- if( !isLoadedGame )
- {
- day_frame_count = 0; // for determining when the day counter should be increased.
- frame_count = 1;
- }
- //----- initialize these vars for every game -----//
- for( int i=nation_array.size() ; i>0 ; i-- )
- {
- if( !nation_array.is_deleted(i) )
- nation_array[i]->next_frame_ready = 0;
- }
- remote.packet_send_count = 0;
- remote.packet_receive_count = 0;
- last_frame_time = m.get_time()+60000; // plus 60 seconds buffer for game loading/starting time
- //frame_count = 1;
- is_sync_frame = 0;
- //----------------------------------------------//
- mp_clear_request_save();
- remote.enable_poll_msg();
- remote.enable_process_queue();
- remote_send_success_flag = 1;
- #ifdef DEBUG
- char longLogSuffix = 'A';
- if( remote.is_enable() )
- {
- if(long_log)
- delete long_log;
- long_log = new LongLog(longLogSuffix);
- }
- #endif
- //-*********** syn game test ***********-//
- #ifdef DEBUG
- if(debug_seed_status_flag==DEBUG_SYN_LOAD_AND_COMPARE_ONCE)
- sp_load_seed_file();
- #endif
- //-*********** syn game test ***********-//
- vga_front.unlock_buf();
- // ------- establish_contact again --------//
- // if the game saved after NationRelation::contact_msg_flag set, but
- // remote players may have not receive MSG_NATION_CONTACT
- //
- // send MSG_NATION_CONTACT now
- if( !config.explore_whole_map && nation_array.player_recno &&
- !nation_array.is_deleted(nation_array.player_recno) )
- {
- for(short nationRecno = 1; nationRecno <= nation_array.size(); ++nationRecno )
- {
- if( nationRecno == nation_array.player_recno ||
- nation_array.is_deleted(nationRecno) )
- continue;
- NationRelation *relation = (~nation_array)->get_relation(nationRecno);
- if( relation->contact_msg_flag && !relation->has_contact)
- {
- // packet structure : <player nation> <explored nation>
- short *shortPtr = (short *)remote.new_send_queue_msg(MSG_NATION_CONTACT, 2*sizeof(short));
- *shortPtr = nation_array.player_recno;
- shortPtr[1] = nationRecno;
- }
- }
- }
- // #### begin Gilbert 23/10 #######//
- option_menu.active_flag = 0;
- in_game_menu.active_flag = 0;
- // #### end Gilbert 23/10 #######//
- // ##### begin Gilbert 4/11 ######//
- DWORD lastDispFrameTime = m.get_time();
- // ##### end Gilbert 4/11 ######//
- // ##### patch begin Gilbert 17/11 #######//
- DWORD firstUnreadyTime = 0;
- // ##### patch end Gilbert 17/11 #######//
- while( 1 )
- {
- if (PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE))
- {
- if (!GetMessage( &msg, NULL, 0, 0))
- break;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else if ( !paused_flag && active_flag )
- {
- // #### begin Gilbert 31/10 ######//
- int rc = 0;
- // #### end Gilbert 31/10 ######//
- if( sys.signal_exit_flag )
- break;
- vga_front.lock_buf();
- yield(); // could be improved, give back the control to Windows, so it can do some OS management. Maybe call WaitMessage() here and set up a timer to get messages regularly.
- detect();
- //--------------------------------//
- // ###### begin Gilbert 4/11 ######//
- DWORD markTime = m.get_time(); // a time taken earlier than should_next_frame takes
- // ###### end Gilbert 4/11 ######//
- // ##### patch begin Gilbert 17/11 #######//
- int unreadyPlayerFlag = 0;
- // ##### patch end Gilbert 17/11 #######//
- if( config.frame_speed>0 ) // 0-frozen
- {
- if( remote.is_enable() ) // && is_sync_frame )
- {
- remote.poll_msg();
- m.unlock_seed();
- rc = is_mp_sync(&unreadyPlayerFlag); // if all players are synchronized
- m.lock_seed();
- }
- else
- rc = should_next_frame();
- if( rc )
- {
- LOG_BEGIN;
- m.unlock_seed();
- #ifdef DEBUG
- if( remote.is_enable() )
- {
- long_log->printf("begin process frame %d\n", frame_count);
- }
- #endif
- process();
- if(remote.is_enable() )
- m.lock_seed(); // such that random seed is unchanged outside sys::process()
- LOG_END;
- // -------- compare objects' crc --------- //
- // ###### patch begin Gilbert 20/1 ######//
- if( remote.is_enable() && (remote.sync_test_level & 2) &&(frame_count % (remote.get_process_frame_delay()+3)) == 0)
- {
- // cannot compare every frame, as PROCESS_FRAME_DELAY >= 1
- crc_store.record_all();
- crc_store.send_all();
- }
- // ###### patch end Gilbert 20/1 ######//
- }
- }
- // ###### begin Gilbert 4/11 #######//
- // ------- display graduately, keep on displaying --------- //
- if( rc )
- {
- lastDispFrameTime = m.get_time();
- // ####### patch begin Gilbert 17/11 ######//
- // reset firstUnreadyTime
- firstUnreadyTime = 0;
- // ####### patch end Gilbert 17/11 ######//
- }
- else
- {
- // ####### patch begin Gilbert 17/11 ######//
- // set firstUnreadyTime, begin of a delay
- if( !firstUnreadyTime )
- firstUnreadyTime = m.get_time();
- // ####### patch end Gilbert 17/11 ######//
- if( config.frame_speed == 0 || markTime-lastDispFrameTime >= DWORD(1000/config.frame_speed)
- #ifdef AMPLUS
- || zoom_need_redraw || map_need_redraw
- #endif
- )
- {
- // on second condition, it should be happened when
- // in multiplayer, where should_next_frame passed
- // but is_mp_sync not passed
- disp_frame();
- lastDispFrameTime = markTime;
- // ####### patch begin Gilbert 17/11 ######//
- // display player not ready
- if( firstUnreadyTime && m.get_time() - firstUnreadyTime > 5000 )
- {
- int y = ZOOM_Y1 + 10;
- int x = ZOOM_X1 + 10;
- for( int nationRecno = 1; nationRecno <= MAX_NATION; ++nationRecno )
- {
- if( unreadyPlayerFlag & (1 << (nationRecno-1)) )
- {
- if( !nation_array.is_deleted(nationRecno) )
- {
- int x2 = font_news.put( x, y, "Waiting for ");
- x2 = font_news.put( x2, y, nation_array[nationRecno]->nation_name() );
- y += font_news.height() + 5;
- }
- }
- }
- }
- // ####### patch end Gilbert 17/11 ######//
- }
- }
- // ###### end Gilbert 4/11 #######//
- // ----------- detect sond is ended, play another -----------//
- if( config.frame_speed == 0 || day_frame_count == 0)
- music.yield();
- #ifdef DEBUG
- if( rc && remote.is_enable() && day_frame_count == 0 )
- {
- if( long_log)
- delete long_log;
- if( ++longLogSuffix > 'Z' )
- {
- longLogSuffix = 'A';
- }
- long_log = new LongLog(longLogSuffix);
- long_log->printf("Game Date : %d/%d/%d\n", info.game_month, info.game_day, info.game_year);
- }
- #endif
- if(rc)
- {
- //-*********** syn game test ***********-//
- //-------------------------------------------------------------//
- // record random seed for comparison
- //-------------------------------------------------------------//
- #ifdef DEBUG
- if(debug_seed_status_flag==DEBUG_SYN_LOAD_AND_COMPARE_ONCE ||
- debug_seed_status_flag==DEBUG_SYN_AUTO_LOAD)
- sp_compare_seed();
- else if(debug_seed_status_flag==DEBUG_SYN_AUTO_SAVE)
- sp_record_seed();
- #endif
- //-*********** syn game test ***********-//
- //------ auto save -------//
- auto_save();
- }
- //------ detect save game triggered by remote player ------//
- if( mp_save_flag && mp_save_frame == frame_count )
- {
- mp_clear_request_save(); // clear request first before save game
- if( nation_array.player_recno ) // only save then the player is still in the game
- {
- game_file.save_game( remote.save_file_name );
- // ####### begin Gilbert 24/10 ######//
- //static String str;
- //str = "The current game has been saved to ";
- //str += remote.save_file_name;
- //str += ".";
- //box.msg( str );
- news_array.multi_save_game();
- // ####### end Gilbert 24/10 ######//
- }
- }
- vga_front.unlock_buf();
- if( sys.signal_exit_flag )
- break;
- }
- else
- {
- WaitMessage();
- }
- }
- // #### begin Gilbert 23/10 #######//
- in_game_menu.active_flag = 0;
- option_menu.active_flag = 0;
- // #### end Gilbert 23/10 #######//
- vga_front.lock_buf();
- #ifdef DEBUG
- if(remote.is_enable())
- {
- if(long_log)
- delete long_log;
- long_log = NULL;
- }
- #endif
- music.stop();
- remote.disable_process_queue();
- remote.disable_poll_msg();
- mp_clear_request_save();
- }
- //--------- End of function Sys::main_loop --------//
- //-------- Begin of function Sys::auto_save --------//
- //
- void Sys::auto_save()
- {
- if( nation_array.player_recno == 0 )
- return;
- //---------- single player auto save ----------//
- if( !remote.is_enable() && // no auto save in a multiplayer game
- info.game_month%2==0 && info.game_day==1 && day_frame_count==0)
- {
- #ifdef DEBUG2
- if(1)
- #else
- if( sys.debug_session || sys.testing_session )
- #endif
- {
- static int saveCount = 0;
- switch(saveCount)
- {
- case 0: game_file.save_game( "AUTO1.SAV" );
- break;
- case 1: game_file.save_game( "AUTO2.SAV" );
- break;
- case 2: game_file.save_game( "AUTO3.SAV" );
- break;
- }
- if( ++saveCount>3 )
- saveCount = 0;
- }
- else
- {
- //--- rename the existing AUTO.SAV to AUTO2.SAV and save a new game ---//
- if( m.is_file_exist( "AUTO.SAV" ) )
- {
- if( m.is_file_exist( "AUTO2.SAV" ) ) // if there is already an AUTO2.SAV, delete it
- remove( "AUTO2.SAV" );
- rename( "AUTO.SAV", "AUTO2.SAV" );
- }
- }
- game_file.save_game( "AUTO.SAV" );
- //-*********** syn game test ***********-//
- #ifdef DEBUG
- if(debug_seed_status_flag==DEBUG_SYN_AUTO_SAVE)
- {
- sp_write_seed();
- sp_close_seed_file();
- //if(info.game_date-info.game_start_date<=365)
- if(0)
- {
- sp_open_seed_file("nseed.rs");
- debug_seed_status_flag = DEBUG_SYN_AUTO_SAVE; // continue recording
- }
- else
- {
- debug_seed_status_flag = NO_DEBUG_SYN;
- //sp_load_seed_file();
- //SendMessage(main_hwnd, WM_KEYDOWN, 'L', 0);
- mouse.add_key_event(DIK_BACKSLASH, m.get_time()); // load file for comparison
- }
- }
- //debug_seed_status_flag = 2;
- //sp_seed_pos_reset();
- //sp_record_match_seed();
- #endif
- //-*********** syn game test ***********-//
- }
- // --------- multiplayer autosave game --------//
- // ###### patch begin Gilbert 23/1 #######//
- if( remote.is_enable() && remote.sync_test_level >= 0 && // disable autosave after un-sync
- day_frame_count==0 && info.game_day==1 && info.game_month%2==0 )
- // ###### patch end Gilbert 23/1 #######//
- {
- //--- rename the existing AUTO.SVM to AUTO2.SVM and save a new game ---//
- if( m.is_file_exist( "AUTO.SVM" ) )
- {
- if( m.is_file_exist( "AUTO2.SVM" ) ) // if there is already an AUTO2.SVM, delete it
- remove( "AUTO2.SVM" );
- rename( "AUTO.SVM", "AUTO2.SVM" );
- }
- game_file.save_game( "AUTO.SVM" );
- }
- }
- //-------- End of function Sys::auto_save --------//
- //-------- Begin of function Sys::pause --------//
- //
- void Sys::pause()
- {
- if( paused_flag )
- return;
- InvalidateRect(main_hwnd, NULL, TRUE);
- paused_flag = TRUE;
- }
- //--------- End of function Sys::pause ---------//
- //-------- Begin of function Sys::unpause --------//
- //
- void Sys::unpause()
- {
- if( !paused_flag )
- return;
- // ####### begin Gilbert 3/11 #######//
- //if( GetForegroundWindow() != main_hwnd )
- // return;
- // ####### end Gilbert 3/11 #######//
- if( !restore() )
- {
- //-----------------------------------------------------//
- // we are unable to restore, this can happen when
- // the screen resolution or bitdepth has changed
- // we just reload all the art again and re-create
- // the front and back buffers. this is a little
- // overkill we could handle a screen res change by
- // just recreating the front and back buffers we dont
- // need to redo the art, but this is way easier.
- //-----------------------------------------------------//
- if (init_directx())
- {
- if( !restore() ) // if still not successful, quit
- return;
- }
- }
- // ####### begin Gilbert 31/10 #######//
- mouse.update_skey_state(); // update ctrl/shift/alt key state after switch task
- // ####### end Gilbert 31/10 #######//
- //---- restore the saved screen before killing the focus ----//
- paused_flag = FALSE;
- }
- //--------- End of function Sys::unpause ---------//
- //-------- Begin of function Sys::restore --------//
- //
- int Sys::restore()
- {
- if( !vga_front.restore_buf() )
- return 0;
- if( !vga_back.restore_buf() )
- return 0;
- if( sys.debug_session )
- {
- if( !vga_true_front.restore_buf() )
- return 0;
- }
- // ####### begin Gilbert 16/9 ########//
- //else
- // vga_front.lock_buf();
- // ####### end Gilbert 16/9 ########//
- return 1;
- }
- //--------- End of function Sys::restore ---------//
- //-------- Begin of function Sys::yield --------//
- //
- void Sys::yield()
- {
- static int isYielding=0;
- if( isYielding )
- return;
- isYielding=1;
- handle_window_messages();
- mouse.poll_event();
- audio.yield();
- if( remote.is_enable() )
- {
- //yield_wsock_msg();
- remote.poll_msg();
- remote.process_specific_msg(MSG_SET_SPEED); // need to test it here for restoring the speed from frozen to normal
- if( config.frame_speed > 0 )
- {
- remote.process_specific_msg(MSG_TELL_SEND_TIME);
- remote.process_specific_msg(MSG_REQUEST_RESEND);
- }
- //-------- display debug info -----------//
- if( power.enable_flag && (testing_session || debug_session) )
- {
- String str;
- str = "Player: ";
- str += nation_array.player_recno;
- str += "/";
- str += nation_array.size();
- str += " Send:";
- str += remote.packet_send_count;
- str += " Recv:";
- str += remote.packet_receive_count;
- str += " Frame:";
- str += frame_count;
- font_san.disp( ZOOM_X1, 4, str, ZOOM_X1+300);
- }
- }
- isYielding=0;
- }
- //--------- End of function Sys::yield ---------//
- //-------- Begin of function Sys::yield_wsock_msg --------//
- //
- void Sys::yield_wsock_msg()
- {
- // MSG msg;
- //------ only get WinSock messages (WSA_ACCEPT & WSA_READ) ------//
- // if( PeekMessage(&msg, NULL, WSA_ACCEPT, WSA_READ, PM_NOREMOVE) )
- // {
- // if (!GetMessage( &msg, NULL, WSA_ACCEPT, WSA_READ))
- // return;
- // TranslateMessage(&msg);
- // DispatchMessage(&msg);
- //}
- }
- //--------- End of function Sys::yield_wsock_msg ---------//
- //-------- Begin of function Sys::is_mp_sync --------//
- //
- // Multiplayer synchronization.
- //
- // Check all players are ready to proceed to the next frame.
- //
- int Sys::is_mp_sync(int *unreadyPlayerFlag)
- {
- #define RESEND_TIME_OUT 2000 // if the other machines still aren't ready after 2 seconds, send the notification again
- #define RESEND_AGAIN_TIME_OUT 1000 // keep resending if no responses
- #define CONNECTION_LOST_TIME_OUT 20000 // ask for connection lost handling aftering waiting for 5 seconds.
- //---- if we haven't been ready for the next frame yet ----//
- #ifdef DEBUG
- int n;
- DEBUG_LOG("begin nation's next_frame_ready");
- for (n = 1; n <= nation_array.size(); ++n)
- {
- DEBUG_LOG(nation_array[n]->next_frame_ready);
- }
- DEBUG_LOG("end nation's next_frame_ready");
- #endif
- // ####### patch begin Gilbert 17/11 ######//
- if( unreadyPlayerFlag )
- *unreadyPlayerFlag = 0;
- // ####### end begin Gilbert 17/11 ######//
- // if last remote.send was fail, attempt to send it again
- if( !nation_array.player_recno )
- {
- // observation mode
- if( !should_next_frame() )
- return 0;
- remote_send_success_flag = 1;
- }
- else if( remote_send_success_flag
- && remote.has_send_frame(nation_array.player_recno, frame_count)
- && (~nation_array)->next_frame_ready==0 )
- {
- DEBUG_LOG("Local player not ready");
- if( !should_next_frame() ) // not ready to proceed yet
- return 0;
- //------------ queue MSG_NEXT_FRAME ----------//
- short* shortPtr = (short*) remote.new_send_queue_msg(MSG_NEXT_FRAME, sizeof(short));
- shortPtr[0] = nation_array.player_recno; // short_para1 is the nation recno of the current player
- //------------ queue MSG_QUEUE_TRAILER ----------//
- shortPtr = (short*) remote.new_send_queue_msg(MSG_QUEUE_TRAILER, sizeof(short));
- shortPtr[0] = nation_array.player_recno; // short_para1 is the nation recno of the current player
- //------ copy all queued action to our own receive buffer to merge with other player's action ----//
- remote.append_send_to_receive();
- //--- copy the whole queue to a buffer in case of resend request from other players ---//
- remote.copy_send_to_backup();
- //----------- queue MSG_TELL_SEND_TIME ----------//
- /*
- unsigned long* longPtr = (unsigned long*) remote.new_send_queue_msg(MSG_TELL_SEND_TIME, sizeof(unsigned long));
- longPtr[0] = m.get_time();
- */
- //---------- send out all messages in the queue ---------//
- remote_send_success_flag = remote.send_queue_now(); // if not sent successfully, try again next time
- if( remote_send_success_flag ) // still failed, try again next time
- {
- DEBUG_LOG("first send sucess" );
- remote.init_send_queue(frame_count+1, nation_array.player_recno); // frame_count, initialize for next frame's send queue
- // sent random seed
- char *p = (char *)remote.new_send_queue_msg(MSG_TELL_RANDOM_SEED, sizeof(short)+sizeof(long));
- *(short *)p = nation_array.player_recno;
- p += sizeof(short);
- *(long *)p = m.get_random_seed();
- }
- else
- {
- // re_transmit as quickly as possible
- ec_remote.re_transmit(5);
- }
- }
- else
- {
- DEBUG_LOG("Local player nation ready");
- }
- //----- if previous sending was not successful, send again now -----//
- if( !remote_send_success_flag )
- {
- remote_send_success_flag = remote.send_queue_now(); // if not sent successfully, try again next time
- if( remote_send_success_flag ) // still failed, try again next time
- {
- DEBUG_LOG("resending ok");
- remote.init_send_queue(frame_count+1, nation_array.player_recno); // frame_count, initialize for next frame's send queue
- // sent random seed
- char *p = (char *)remote.new_send_queue_msg(MSG_TELL_RANDOM_SEED, sizeof(short)+sizeof(long));
- *(short *)p = nation_array.player_recno;
- p += sizeof(short);
- *(long *)p = m.get_random_seed();
- }
- else
- {
- // re_transmit as quickly as possible
- ec_remote.re_transmit(5);
- DEBUG_LOG("resending not ok");
- return 0;
- }
- }
- //------ pre_process MSG_NEXT_FRAME in the queue -----//
- remote.process_specific_msg(MSG_NEXT_FRAME);
- #ifdef DEBUG
- DEBUG_LOG("begin nation's next_frame_ready");
- for (n = 1; n <= nation_array.size(); ++n)
- {
- DEBUG_LOG(nation_array[n]->next_frame_ready);
- }
- DEBUG_LOG("end nation's next_frame_ready");
- #endif
- //------ check if all remote players are ready to proceed -----//
- int nationRecno;
- Nation* nationPtr;
- for( nationRecno=nation_array.size() ; nationRecno>0 ; nationRecno-- )
- {
- if( nation_array.is_deleted(nationRecno) )
- continue;
- nationPtr = nation_array[nationRecno];
- //------- if some remote machines are not ready yet -------//
- // ###### patch begin Gilbert 17/11 ######//
- if( nationPtr->is_remote() &&
- (remote.has_send_frame(nationRecno, frame_count) && !nationPtr->next_frame_ready) )
- {
- if( unreadyPlayerFlag )
- *unreadyPlayerFlag |= ( 1 << (nationRecno-1) );
- break;
- }
- // ###### end begin Gilbert 17/11 ######//
- }
- //------- if some remote machines are not ready yet -------//
- if( nationRecno>0 )
- {
- DEBUG_LOG("a nation not ready");
- DEBUG_LOG(nationRecno);
- if( m.get_time() >= last_frame_time+RESEND_TIME_OUT )
- {
- //---- if it has been time out for too long, carry out connection lost handling ---//
- if( // m.get_time() >= last_frame_time+CONNECTION_LOST_TIME_OUT ||
- !ec_remote.is_player_valid(nationRecno))
- {
- DEBUG_LOG( "Connection Lost" );
- // ###### begin Gilbert 24/10 ######//
- // box.msg( "Connection Lost!" ); //**BUGHERE, should have a function to set all units, structures of this nation to AI
- news_array.multi_connection_lost(nationRecno);
- // may allow save game here, ask user whether to save the game
- // ###### end Gilbert 24/10 ######//
- nationPtr->nation_type = NATION_AI; // let computer take over the nation
- nation_array.ai_nation_count++;
- }
- //------- re-send the message -------//
- /* re-send is now done by ec_remote
- else if( m.get_time() >= last_resend_time + RESEND_AGAIN_TIME_OUT ) // resent once per half second
- {
- DEBUG_LOG( "send retransmit request" );
- RemoteMsg* remoteMsg = remote.new_msg(MSG_REQUEST_RESEND, sizeof(int) + sizeof(DWORD) );
- DWORD* dwordPtr = (DWORD*) remoteMsg->data_buf;
- dwordPtr[0] = (~nation_array)->player_id; // send to us
- dwordPtr[1] = frame_count; // request it to send us queue of this frame
- remote.send_free_msg( remoteMsg, nation_array[nationRecno]->player_id ); // send to that nationRecno only
- last_resend_time = m.get_time();
- }
- */
- }
- return 0;
- }
- //--------------------------------------------------------//
- //
- // When all players are ready to proceed to the next frame
- //
- // As we have already know all players are ready, we can
- // reset the next_frame_ready flag for all nations.
- //
- //--------------------------------------------------------//
- DEBUG_LOG("all nation ready");
- for( int i=nation_array.size() ; i>0 ; i-- )
- {
- if( nation_array.is_deleted(i) )
- continue;
- nation_array[i]->next_frame_ready=0; // -- instead of set to 0, set it may be 2 if it has just received an notifying signal for the further next frame from a player as it also sent out a next frame ready msg to all other players
- }
- //--------- process msgs in the receive queue ----------//
- remote.process_receive_queue();
- #ifdef DEBUG
- DEBUG_LOG("begin nation's next_frame_ready");
- for (n = 1; n <= nation_array.size(); ++n)
- {
- DEBUG_LOG(nation_array[n]->next_frame_ready);
- }
- DEBUG_LOG("end nation's next_frame_ready");
- #endif
- //-------- record this frame's time -------//
- last_frame_time = m.get_time();
- last_resend_time = 0;
- return 1;
- }
- //---------- End of function Sys::is_mp_sync --------//
- //-------- Begin of function Sys::should_next_frame --------//
- //
- // Check if it's now the time for processing the next frame.
- //
- int Sys::should_next_frame()
- {
- //----- special modes: 0-frozen, 9-fastest possible -----//
- if( config.frame_speed==99 )
- return 1;
- if( config.frame_speed==0 )
- return 0;
- //---- check if it's now the time for processing the next frame ----//
- DWORD curTime = m.get_time();
- if( next_frame_time ) // if next_frame_time==0, it's the first frame of the game
- {
- if( next_frame_time < 1000 ) // the DWORD variable has been overflow
- {
- if( curTime < next_frame_time || curTime >= 1000 ) // >= 1000 if the curTime has been overflow yet, wait for it to overflow so we can compare it when next_frame_time
- return 0;
- }
- else // normal non-overflow case
- {
- if( curTime < next_frame_time )
- return 0;
- }
- }
- //--- Time between frames = 1000 milliseconds / frames per second ---//
- next_frame_time = curTime + 1000 / config.frame_speed;
- return 1;
- }
- //--------- End of function Sys::should_next_frame ---------//
- //-------- Begin of function Sys::main_win_proc --------//
- //
- long Sys::main_win_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch( message )
- {
- case WM_CREATE:
- sys.main_hwnd = hWnd;
- break;
- case WM_ACTIVATEAPP:
- // ####### begin Gilbert 3/11 #######//
- // active_flag = (BOOL)wParam && GetForegroundWindow() == hWnd && !IsIconic(hWnd);
- active_flag = (BOOL)wParam && !IsIconic(hWnd);
- // ####### end Gilbert 3/11 #######//
- //--------------------------------------------------------------//
- // while we were not-active something bad happened that caused us
- // to pause, like a surface restore failing or we got a palette
- // changed, now that we are active try to fix things
- //--------------------------------------------------------------//
- if( active_flag )
- {
- unpause();
- need_redraw_flag = 1; // for Sys::disp_frame to redraw the screen
- }
- else
- pause();
- break;
- case WM_DESTROY:
- main_hwnd = NULL;
- // game.deinit(); // end of game
- deinit_directx();
- PostQuitMessage( 0 );
- break;
- case WM_ERASEBKGND:
- // do not erase the background
- return 1;
- case WM_PALETTECHANGED:
- // if we changed the palette, do nothing
- if ((HWND)wParam == hWnd) break;
- // we can't restore if dd_pal is not initialized
- if (!vga.dd_pal) break;
- // if we are temporarily overriding, then we should be okay
- if (vga.back_up_pal) break;
- // restore palette
- vga.dd_pal->SetEntries(0, 0, 256, vga.pal_entry_buf);
- break;
- default:
- break;
- }
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- //--------- End of function Sys::main_win_proc ---------//
- //-------- Begin of function Sys::handle_window_messages --------//
- void Sys::handle_window_messages()
- {
- static int lastTick;
- int tick = GetTickCount();
- if (lastTick == tick)
- return;
- lastTick = tick;
- MSG msg;
- while (PeekMessage(&msg, sys.main_hwnd, 0, 0, PM_NOREMOVE))
- {
- BOOL r;
- r = GetMessage(&msg, sys.main_hwnd, 0, 0);
- if (r == -1)
- {
- // not handled
- return;
- }
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- //-------- End of function Sys::handle_window_messages --------//
- //-------- Begin of function Sys::process_key --------//
- //
- void Sys::process_key(unsigned scanCode, unsigned skeyState)
- {
- detect_function_key(scanCode, skeyState);
- //----- don't detect letter keys when in chat mode ----//
- if( !(view_mode == MODE_NATION &&
- info.nation_report_mode == NATION_REPORT_CHAT) )
- {
- if( sys.debug_session || sys.testing_session || scenario_cheat_flag )
- {
- detect_cheat_key(scanCode, skeyState);
- detect_debug_cheat_key(scanCode, skeyState);
- if( detect_scenario_cheat_key(scanCode, skeyState) )
- return;
- }
- else
- {
- if( nation_array.player_recno && !remote.is_enable() ) // not allowed in multiplayer mode
- {
- if( (~nation_array)->cheat_enabled_flag )
- {
- detect_cheat_key(scanCode, skeyState);
- }
- else
- {
- #ifdef GERMAN
- if( detect_key_str(1, "!!!###") )
- #else
- if( detect_key_str(1, "!!!@@@###") )
- #endif
- {
- box.msg( "Cheat Mode Enabled." );
- (~nation_array)->cheat_enabled_flag = 1;
- }
- }
- }
- }
- detect_letter_key(scanCode, skeyState);
- detect_set_speed(scanCode, skeyState); // set the speed of the game
- }
- }
- //--------- End of function Sys::process_key ---------//
- //-------- Begin of function Sys::detect_letter_key --------//
- //
- void Sys::detect_letter_key(unsigned scanCode, unsigned skeyState)
- {
- int keyCode;
- if((keyCode = mouse.is_key(scanCode, skeyState, (WORD) 0, K_IS_CTRL)))
- {
- int groupId;
- switch(keyCode)
- {
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- groupId = keyCode-'0';
- group_select.group_units(groupId);
- break;
- }
- }
- if((keyCode = mouse.is_key(scanCode, skeyState, (WORD) 0, K_IS_ALT)))
- {
- int groupId;
- switch(keyCode)
- {
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- groupId = keyCode-'0';
- group_select.select_grouped_units(groupId);
- break;
- }
- }
- if( (keyCode = mouse.is_key(scanCode, skeyState, (WORD) 0, K_UNIQUE_KEY)) )
- {
- keyCode = m.lower(keyCode);
- switch(keyCode)
- {
- case KEY_ESC:
- set_view_mode(MODE_NORMAL);
- break;
- //---- keys for toggling map mode ----//
- case 'q':
- world.map_matrix->toggle_map_mode(0);
- break;
- case 'w':
- world.map_matrix->toggle_map_mode(1);
- break;
- case 'e':
- world.map_matrix->toggle_map_mode(2);
- break;
- //--------- opaque report mode --------//
- case 'p':
- config.opaque_report = !config.opaque_report;
- if( config.opaque_report )
- box.msg( "Opaque report mode." );
- else
- box.msg( "Transparent report mode." );
- break;
- //------ clear news messages ------//
- case 'x':
- news_array.clear_news_disp();
- break;
- //------ jump to a location with natural resource ---//
- case 'j':
- site_array.go_to_a_raw_site();
- break;
- //--------- bring up the option menu ----------//
- case 'o':
- // ##### begin Gilbert 5/11 #######//
- // game.in_game_option_menu();
- option_menu.enter(!remote.is_enable());
- // ##### end Gilbert 5/11 #######//
- break;
- //--------- forward/backward tutorial text block --------//
- case ',':
- if( game.game_mode == GAME_TUTORIAL )
- tutor.prev_text_block();
- break;
- case '.':
- if( game.game_mode == GAME_TUTORIAL )
- tutor.next_text_block();
- break;
- //---- keys for saving and loading game -----//
- case 's':
- save_game();
- break;
- case 'l':
- load_game();
- break;
- case KEY_UP:
- world.disp_next(-1, 0); // previous same object type of any nation
- break;
- case KEY_DOWN:
- world.disp_next(1, 0); // next same object type of any nation
- break;
- case KEY_LEFT:
- world.disp_next(-1, 1); // prevous same object type of the same nation
- break;
- case KEY_RIGHT:
- world.disp_next(1, 1); // next same object type of the same nation
- break;
- //---- key for quick locate -----//
- case 'k':
- locate_king_general(RANK_KING);
- break;
- case 'g':
- locate_king_general(RANK_GENERAL);
- break;
- case 'y':
- locate_spy();
- break;
- case 'h':
- locate_ship();
- break;
- case 'f':
- locate_camp();
- break;
- }
- }
- }
- //--------- End of function Sys::detect_letter_key ---------//
- //-------- Begin of function Sys::detect_function_key --------//
- //
- void Sys::detect_function_key(unsigned scanCode, unsigned skeyState)
- {
- int keyCode;
- if( (keyCode = mouse.is_key(scanCode, skeyState, (WORD) 0, K_UNIQUE_KEY)) )
- {
- switch(keyCode)
- {
- case KEY_ESC:
- set_view_mode(MODE_NORMAL);
- break;
- case KEY_F1:
- if( view_mode==MODE_NATION )
- set_view_mode(MODE_NORMAL);
- else
- set_view_mode(MODE_NATION);
- break;
- case KEY_F2:
- if( view_mode==MODE_TOWN )
- set_view_mode(MODE_NORMAL);
- else
- set_view_mode(MODE_TOWN);
- break;
- case KEY_F3:
- if( view_mode==MODE_ECONOMY )
- set_view_mode(MODE_NORMAL);
- else
- set_view_mode(MODE_ECONOMY);
- break;
- case KEY_F4:
- if( view_mode==MODE_TRADE )
- set_view_mode(MODE_NORMAL);
- else
- set_view_mode(MODE_TRADE);
- break;
- case KEY_F5:
- if( view_mode==MODE_MILITARY )
- set_view_mode(MODE_NORMAL);
- else
- set_view_mode(MODE_MILITARY);
- break;
- case KEY_F6:
- if( view_mode==MODE_TECH )
- set_view_mode(MODE_NORMAL);
- else
- set_view_mode(MODE_TECH);
- break;
- case KEY_F7:
- if( view_mode==MODE_SPY )
- set_view_mode(MODE_NORMAL);
- else
- set_view_mode(MODE_SPY);
- break;
- case KEY_F8:
- if( view_mode==MODE_RANK )
- set_view_mode(MODE_NORMAL);
- else
- set_view_mode(MODE_RANK);
- break;
- case KEY_F9:
- if( view_mode==MODE_NEWS_LOG )
- set_view_mode(MODE_NORMAL);
- else
- set_view_mode(MODE_NEWS_LOG);
- break;
- case KEY_F10:
- // ##### begin Gilbert 5/11 ######//
- //game.in_game_menu();
- in_game_menu.enter(!remote.is_enable());
- // ##### end Gilbert 5/11 ######//
- break;
- case KEY_F11:
- capture_screen();
- break;
- case KEY_F12:
- capture_minimap();
- break;
- }
- }
- }
- //--------- End of function Sys::detect_function_key ---------//
- //-------- Begin of function Sys::detect_cheat_key --------//
- //
- void Sys::detect_cheat_key(unsigned scanCode, unsigned skeyState)
- {
- if( remote.is_enable() ) // no cheat keys in multiplayer games
- return;
- int keyCode = mouse.is_key( scanCode, skeyState, (WORD) 0, K_CHAR_KEY );
- if( !keyCode ) // since all keys concern are printable
- return;
- keyCode = m.lower(keyCode);
- switch( keyCode )
- {
- //-------- cheat keys ---------//
- case 'c': // add cash
- if( nation_array.player_recno )
- (~nation_array)->add_cheat((float)1000);
- break;
- case '\\': // add food
- if( nation_array.player_recno )
- (~nation_array)->add_food((float)1000);
- break;
- case 't':
- tech_res.inc_all_tech_level(nation_array.player_recno);
- god_res.enable_know_all(nation_array.player_recno);
- box.msg( "Your technology has advanced.\nYou can now invoke all Greater Beings." );
- break;
- case 'm':
- world.unveil(0, 0, MAX_WORLD_X_LOC-1, MAX_WORLD_Y_LOC-1);
- world.visit(0, 0, MAX_WORLD_X_LOC-1, MAX_WORLD_Y_LOC-1, 0, 0);
- break;
- case ';': // increase town population
- if( town_array.selected_recno )
- {
- Town* townPtr = town_array[town_array.selected_recno];
- #ifdef DEBUG2
- for(int di=0; di<MAX_RACE; di++)
- {
- if(townPtr->race_pop_array[di])
- {
- townPtr->init_pop(di+1, 10, 100);
- break;
- }
- }
- #else
- townPtr->init_pop( m.random(MAX_RACE)+1, 10, 100 );
- #endif
- townPtr->auto_set_layout();
- }
- break;
- case 'u':
- config.king_undie_flag = !config.king_undie_flag;
- if( config.king_undie_flag )
- box.msg( "Your king is now immortal." );
- else
- box.msg( "King immortal mode is now disabled." );
- break;
- case '=':
- if( firm_array.selected_recno )
- {
- Firm* firmPtr = firm_array[firm_array.selected_recno];
- if( firmPtr->firm_id == FIRM_BASE )
- {
- ((FirmBase*)firmPtr)->pray_points = (float) MAX_PRAY_POINTS;
- info.disp();
- }
- }
- break;
- case 'b': // finish building a firm instantly or increase the hit points of a firm to its max
- if( firm_array.selected_recno )
- {
- Firm* firmPtr = firm_array[firm_array.selected_recno];
- firmPtr->hit_points = firmPtr->max_hit_points;
- }
- break;
- case 'z': // toggle fast_build
- config.fast_build = !config.fast_build;
- if( !config.fast_build )
- box.msg( "Fast build is now disabled" );
- else
- box.msg( "Fast build is now enabled" );
- break;
- //----- increase the combat level -------//
- case '[':
- if( unit_array.selected_recno )
- {
- Unit* unitPtr = unit_array[unit_array.selected_recno];
- unitPtr->set_combat_level( min(100, unitPtr->skill.combat_level+20) );
- }
- break;
- //----- increase the skill level of the unit -------//
- case ']':
- if( unit_array.selected_recno )
- {
- Unit* unitPtr = unit_array[unit_array.selected_recno];
- if( unitPtr->skill.skill_id )
- unitPtr->skill.skill_level = min(100, unitPtr->skill.skill_level+20);
- }
- break;
- //----- increase the spying skill -------//
- case '\'':
- if( unit_array.selected_recno )
- {
- Unit* unitPtr = unit_array[unit_array.selected_recno];
- if( unitPtr->spy_recno )
- {
- Spy* spyPtr = spy_array[unitPtr->spy_recno];
- spyPtr->spy_skill = min(100, spyPtr->spy_skill+20);
- }
- }
- break;
- }
- }
- //--------- End of function Sys::detect_cheat_key ---------//
- //-------- Begin of function Sys::detect_debug_cheat_key --------//
- //
- void Sys::detect_debug_cheat_key(unsigned scanCode, unsigned skeyState)
- {
- if( remote.is_enable() ) // no cheat keys in multiplayer games
- return;
- int keyCode = mouse.is_key( scanCode, skeyState, (WORD) 0, K_UNIQUE_KEY );
- if( !keyCode ) // since all keys concern are printable
- return;
- keyCode = m.lower(keyCode);
- switch( keyCode )
- {
- /*
- case 'j': // allow all nations to have all god creatures
- for( i=1; i<=nation_array.size() ; i++ )
- {
- if( !nation_array.is_deleted(i) )
- god_res.enable_know_all(i);
- }
- box.msg( "Now knowledge of seat of power is available to all nations." );
- break;
- */
- case 'n':
- config.blacken_map = !config.blacken_map;
- config.fog_of_war = config.blacken_map;
- break;
- case 'r': // set default report nation
- if( firm_array.selected_recno )
- {
- info.default_viewing_nation_recno = firm_array[firm_array.selected_recno]->nation_recno;
- }
- else if( town_array.selected_recno )
- {
- int nationRecno = town_array[town_array.selected_recno]->nation_recno;
- if( nationRecno )
- info.default_viewing_nation_recno = nationRecno;
- }
- else if( unit_array.selected_recno )
- {
- int nationRecno = unit_array[unit_array.selected_recno]->nation_recno;
- if( nationRecno )
- info.default_viewing_nation_recno = nationRecno;
- }
- break;
- case 'a':
- if( view_mode==MODE_AI_ACTION )
- set_view_mode(MODE_NORMAL);
- else
- set_view_mode(MODE_AI_ACTION);
- break;
- //-----------------------------------//
- /*
- case 't': // next town layout
- if( town_array.selected_recno )
- town_array[town_array.selected_recno]->auto_set_layout();
- break;
- */
- //-------------------------------//
- case 'i':
- config.disable_ai_flag = !config.disable_ai_flag;
- if( config.disable_ai_flag )
- box.msg( "AI is now disabled" );
- else
- box.msg( "AI is now enabled" );
- break;
- case 'd':
- config.show_ai_info = !config.show_ai_info;
- info.disp();
- if( config.show_ai_info )
- box.msg( "Now AI info will be displayed." );
- else
- box.msg( "Now AI info will not be displayed." );
- break;
- case '/':
- config.show_all_unit_icon = !config.show_all_unit_icon;
- if( config.show_all_unit_icon )
- box.msg( "Now all unit icons will be displayed." );
- else
- box.msg( "Now all unit icons will not be displayed." );
- break;
- #ifdef DEBUG
- case '~':
- sys.testing_session = !sys.testing_session;
- if( sys.testing_session )
- box.msg( "sys.testing_session is now 1." );
- else
- box.msg( "sys.testing_session is now 0." );
- break;
- case '\r':
- if(debug2_enable_flag)
- debug2_enable_flag = 0;
- else
- debug2_enable_flag = 1;
- break;
- /* //-*********** syn game test ***********-//
- case '\'':
- //if(debug2_enable_flag && debug_sim_game_type)
- //game_file_array[0]->load_game("syn.sav");
- game_file.load_game("syn.sav");
- sp_load_seed_file();
- debug_seed_status_flag = DEBUG_SYN_AUTO_LOAD;
- break;
- case '[':
- if(m.is_file_exist("SYN.SYS"))
- {
- debug_seed_status_flag = DEBUG_SYN_AUTO_SAVE;
- sp_seed_pos_reset();
- sp_record_match_seed();
- sp_create_seed_file("nseed.rs");
- game_file.save_game("syn.sav");
- }
- break;
- case ']':
- if(debug_seed_status_flag==NO_DEBUG_SYN)
- {
- if(m.is_file_exist("SYN.SYS"))
- {
- debug_seed_status_flag = DEBUG_SYN_LOAD_AND_COMPARE_ONCE;
- game_file.load_game("syn.sav");
- sp_load_seed_file();
- }
- else
- debug_seed_status_flag = NO_DEBUG_SYN;
- }
- break;
- */ //-*********** syn game test ***********-//
- #endif
- }
- }
- //--------- End of function Sys::detect_debug_cheat_key ---------//
- //-------- Start of function detect_scenario_cheat_key -------------//
- static int detect_scenario_cheat_key(unsigned scanCode, unsigned skeyState)
- {
- if( remote.is_enable() ) // no cheat keys in multiplayer games
- return 0;
- int keyCode = mouse.is_key(scanCode, skeyState, (WORD) 0, K_IS_CTRL);
- if( !keyCode )
- return 0;
- //------------------------------------------//
- int keyProcessed = 0;
- Firm *firmPtr;
- Unit *unitPtr;
- Town *townPtr;
- Nation *nationPtr;
- Site *sitePtr;
- Spy *spyPtr;
- Location *locPtr;
- int i, j, curXLoc, curYLoc;
- switch(keyCode)
- {
- case 'p': //-------- get scroll of power for the race of selected unit --------//
- if(unit_array.selected_recno)
- {
- unitPtr = unit_array[unit_array.selected_recno];
- if(unitPtr->nation_recno==nation_array.player_recno && unitPtr->race_id)
- {
- god_res[unitPtr->race_id]->enable_know(unitPtr->nation_recno);
- //box.msg( "Get Scroll of Power of selected unit for his race" );
- keyProcessed++;
- }
- }
- keyProcessed++;
- break;
- case 't': //-------- get all technology except scrolls of power -------//
- tech_res.inc_all_tech_level(nation_array.player_recno);
- //box.msg( "Your technology has advanced." );
- keyProcessed++;
- break;
- case 'g': //------- get galleon and cannon technologies -------//
- err_when(tech_res[4]->unit_id != UNIT_CANNON);
- err_when(tech_res[7]->unit_id != UNIT_GALLEON);
- i = tech_res[4]->get_nation_tech_level(nation_array.player_recno);
- if(i < tech_res[4]->max_tech_level)
- tech_res[4]->set_nation_tech_level(nation_array.player_recno, i+1);
- i = tech_res[7]->get_nation_tech_level(nation_array.player_recno);
- if(i < tech_res[7]->max_tech_level)
- tech_res[7]->set_nation_tech_level(nation_array.player_recno, i+1);
- //box.msg( "Get technologies of Galleon and Cannon." );
- keyProcessed++;
- break;
- case 'q': //-- decrease population of a selected race in a selected village by 10 --//
- if(town_array.selected_recno)
- {
- townPtr = town_array[town_array.selected_recno];
- if(townPtr->nation_recno == nation_array.player_recno)
- {
- i = townPtr->get_selected_race();
- if(i && townPtr->race_pop_array[i-1])
- {
- for(j=10; j>0 && !town_array.is_deleted(townPtr->town_recno); --j)
- townPtr->kill_town_people(i);
- //box.msg( "Population decrease by 10." );
- keyProcessed++;
- }
- townPtr->auto_set_layout();
- }
- }
- keyProcessed++;
- break;
- case 'w': //-- increase population of a selected race in a selected village by 10 --//
- if(town_array.selected_recno)
- {
- townPtr = town_array[town_array.selected_recno];
- if(townPtr->nation_recno == nation_array.player_recno)
- {
- i = townPtr->get_selected_race();
- if(i && townPtr->race_pop_array[i-1])
- {
- townPtr->init_pop(i, 10, 100);
- //box.msg( "Population increase by 10." );
- keyProcessed++;
- }
- townPtr->auto_set_layout();
- }
- }
- keyProcessed++;
- break;
- case 'e': //-------- decrease the reputation by 10 -----------//
- nationPtr = nation_array[nation_array.player_recno];
- nationPtr->reputation -= 10;
- if(nationPtr->reputation < -100)
- nationPtr->reputation = (float) -100;
- //box.msg( "Reputation decrease by 10." );
- keyProcessed++;
- break;
- case 'r': //-------- increase the reputation by 10 -----------//
- nationPtr = nation_array[nation_array.player_recno];
- nationPtr->reputation += 10;
- if(nationPtr->reputation > 100)
- nationPtr->reputation = (float) 100;
- //box.msg( "Reputation increase by 10." );
- keyProcessed++;
- break;
- case 'j': //--------- damage a building by 20 pt -----------//
- if(firm_array.selected_recno)
- {
- firmPtr = firm_array[firm_array.selected_recno];
- if(firmPtr->nation_recno==nation_array.player_recno)
- {
- firmPtr->hit_points -= 20;
- if(firmPtr->hit_points < 1)
- firmPtr->hit_points = (float) 1;
- //box.msg( "damage firm by 20 points." );
- keyProcessed++;
- }
- }
- keyProcessed++;
- break;
- case 'k': //--------- repair a building by 20 pt -----------//
- if(firm_array.selected_recno)
- {
- firmPtr = firm_array[firm_array.selected_recno];
- if(firmPtr->nation_recno==nation_array.player_recno)
- {
- firmPtr->hit_points += 20;
- if(firmPtr->hit_points > firmPtr->max_hit_points)
- firmPtr->hit_points = firmPtr->max_hit_points;
- //box.msg( "Repair firm by 20 points." );
- keyProcessed++;
- }
- }
- keyProcessed++;
- break;
- case 'x': //------ decrease cash by 1000 --------//
- nationPtr = nation_array[nation_array.player_recno];
- nationPtr->cash -= 1000;
- if(nationPtr->cash < 0)
- nationPtr->cash = (float) 0;
- //box.msg( "Decrease cash by 1000." );
- keyProcessed++;
- break;
- case 'c': //------ decrease food by 1000 --------//
- nationPtr = nation_array[nation_array.player_recno];
- nationPtr->food -= 1000;
- if(nationPtr->food < 0)
- nationPtr->food = (float) 0;
- //box.msg( "Decrease food by 1000." );
- keyProcessed++;
- break;
- case 'm': //----- add natural resource to cursor pos / remove existing resource ------//
- if(get_mouse_loc_in_zoom_map(curXLoc, curYLoc))
- {
- locPtr = world.get_loc(curXLoc, curYLoc);
- if(locPtr->has_site()) // remove site
- {
- i = locPtr->site_recno();
- sitePtr = site_array[i];
- if(!sitePtr->has_mine)
- {
- site_array.del_site(i);
- //box.msg( "Site deleted." );
- keyProcessed++;
- }
- }
- else if(locPtr->can_build_site(1) && !locPtr->is_power_off()) // add site
- {
- i = MAX_RAW_RESERVE_QTY * (50 + m.random(50)) / 100;
- site_array.add_site(curXLoc, curYLoc, SITE_RAW, m.random(MAX_RAW)+1, i);
- //box.msg( "Site added." );
- keyProcessed++;
- }
- }
- keyProcessed++;
- break;
- case 'b': //------------ add reserve of natural resource by 100 ----------//
- if(get_mouse_loc_in_zoom_map(curXLoc, curYLoc))
- {
- locPtr = world.get_loc(curXLoc, curYLoc);
- if(locPtr->has_site())
- {
- i = locPtr->site_recno();
- sitePtr = site_array[i];
- if(!sitePtr->has_mine)
- {
- sitePtr->reserve_qty += 100;
- //box.msg( "increase reserve by 100." );
- keyProcessed++;
- info.disp();
- }
- }
- }
- keyProcessed++;
- break;
- case 'v': //------------ reduce reserve of natural resource by 100 ----------//
- if(get_mouse_loc_in_zoom_map(curXLoc, curYLoc))
- {
- locPtr = world.get_loc(curXLoc, curYLoc);
- if(locPtr->has_site())
- {
- i = locPtr->site_recno();
- sitePtr = site_array[i];
- if(!sitePtr->has_mine && sitePtr->reserve_qty>100)
- {
- sitePtr->reserve_qty -= 100;
- //box.msg( "reduce reserve by 100." );
- keyProcessed++;
- info.disp();
- }
- }
- }
- keyProcessed++;
- break;
- case 'h': //-------- hide map except for areas around your village, people --------//
- if( config.explore_whole_map ) // no action if the setting of the map is explored
- break;
- vga_back.bar(MAP_X1, MAP_Y1, MAP_X2, MAP_Y2, UNEXPLORED_COLOR);
- for(j=0; j<MAX_WORLD_Y_LOC; ++j)
- {
- locPtr = world.get_loc(0, j);
- for(i=0; i<MAX_WORLD_X_LOC; ++i, locPtr++)
- locPtr->explored_off();
- }
- for(i=town_array.size(); i>0; --i)
- {
- if(town_array.is_deleted(i))
- continue;
- townPtr = town_array[i];
- if(townPtr->nation_recno == nation_array.player_recno)
- world.unveil(townPtr->loc_x1, townPtr->loc_y1, townPtr->loc_x2, townPtr->loc_y2);
- }
- for(i=firm_array.size(); i>0; --i)
- {
- if(firm_array.is_deleted(i))
- continue;
- firmPtr = firm_array[i];
- if(firmPtr->nation_recno == nation_array.player_recno)
- world.unveil(firmPtr->loc_x1, firmPtr->loc_y1, firmPtr->loc_x2, firmPtr->loc_y2);
- }
- for(i=unit_array.size(); i>0; --i)
- {
- if(unit_array.is_deleted(i))
- continue;
- unitPtr = unit_array[i];
- if(unitPtr->nation_recno == nation_array.player_recno)
- world.unveil(unitPtr->next_x_loc(), unitPtr->next_y_loc(), unitPtr->next_x_loc(), unitPtr->next_y_loc());
- }
- for(i=spy_array.size(); i>0; --i)
- {
- if(spy_array.is_deleted(i))
- continue;
- spyPtr = spy_array[i];
- if(spyPtr->true_nation_recno!=nation_array.player_recno)
- continue;
- if(spyPtr->spy_place == SPY_FIRM)
- {
- if(!firm_array.is_deleted(spyPtr->spy_place_para))
- {
- firmPtr = firm_array[spyPtr->spy_place_para];
- world.unveil(firmPtr->loc_x1, firmPtr->loc_y1, firmPtr->loc_x2, firmPtr->loc_y2);
- }
- }
- else if(spyPtr->spy_place == SPY_TOWN)
- {
- if(!town_array.is_deleted(spyPtr->spy_place_para))
- {
- townPtr = town_array[spyPtr->spy_place_para];
- world.unveil(townPtr->loc_x1, townPtr->loc_y1, townPtr->loc_x2, townPtr->loc_y2);
- }
- }
- }
- for(i=2; i<=nation_array.size(); ++i) // assume player_nation_recno = 1
- {
- if( nation_array.is_deleted(i) )
- continue;
- (~nation_array)->init_relation(i);
- nation_array[i]->init_relation(1);
- }
- keyProcessed++;
- break;
- case 'z': //------------ put the selected unit to the cursor position ------------//
- if(unit_array.selected_recno)
- {
- unitPtr = unit_array[unit_array.selected_recno];
- if(get_mouse_loc_in_zoom_map(curXLoc, curYLoc))
- {
- if(unitPtr->mobile_type!=UNIT_LAND)
- {
- curXLoc = (curXLoc/2) * 2;
- curYLoc = (curYLoc/2) * 2;
- }
- locPtr = world.get_loc(curXLoc, curYLoc);
- if(locPtr->can_move(unitPtr->mobile_type))
- {
- world.set_unit_recno(unitPtr->next_x_loc(), unitPtr->next_y_loc(), unitPtr->mobile_type, 0);
- unitPtr->stop2();
- unitPtr->next_x = curXLoc << ZOOM_X_SHIFT_COUNT;
- unitPtr->next_y = curYLoc << ZOOM_Y_SHIFT_COUNT;
- unitPtr->cur_x = unitPtr->go_x = unitPtr->next_x;
- unitPtr->cur_y = unitPtr->go_y = unitPtr->next_y;
- unitPtr->move_to_x_loc = curXLoc;
- unitPtr->move_to_y_loc = curYLoc;
- world.set_unit_recno(curXLoc, curYLoc, unitPtr->mobile_type, unitPtr->sprite_recno);
- //box.msg( "move unit." );
- keyProcessed++;
- }
- }
- }
- keyProcessed++;
- break;
- case 's':
- if( info.default_viewing_nation_recno &&
- nation_array.player_recno &&
- nation_array[info.default_viewing_nation_recno]->is_ai() )
- {
- nation_array[info.default_viewing_nation_recno]->surrender(nation_array.player_recno);
- }
- keyProcessed++;
- break;
- }
- return keyProcessed;
- }
- //--------- End of function detect_scenario_cheat_key ---------------//
- //-------- Begin of function Sys::detect_set_speed --------//
- //
- int Sys::detect_set_speed(unsigned scanCode, unsigned skeyState)
- {
- int keyCode = mouse.is_key( scanCode, skeyState, (WORD) 0, K_CHAR_KEY );
- if( !keyCode ) // since all keys concern are printable
- return 0;
- //------- determine the speed to set of the key pressed -------//
- if( keyCode >= '0' && keyCode <= '8' )
- {
- set_speed( (keyCode-'0') * 3 );
- return 1;
- }
- else if( keyCode == '9' )
- {
- set_speed( 99 ); // highest possible speed
- return 1;
- }
- return 0;
- }
- //--------- End of function Sys::detect_set_speed ---------//
- //--------- Begin of function Sys::detect_key_str --------//
- //
- // Detect for continous input of a string from the keyboard
- //
- // <int> keyStrId = the id. of the key string
- // each id has its individual key_str_pos
- // <char*> keyStr = the string to detect
- //
- // return : <int> 1 - complete string detected
- // 0 - not detected
- //
- int Sys::detect_key_str(int keyStrId, char* keyStr)
- {
- err_when( keyStrId < 0 || keyStrId >= MAX_KEY_STR );
- unsigned char* keyStr2 = (unsigned char*) keyStr;
- if( mouse.key_code == keyStr2[key_str_pos[keyStrId]] )
- key_str_pos[keyStrId]++;
- else
- key_str_pos[keyStrId]=0; // when one key unmatched, reset the counter
- if( key_str_pos[keyStrId] >= (int) strlen(keyStr) )
- {
- key_str_pos[keyStrId]=0; // the full string has been entered successfully without any mistakes
- return 1;
- }
- else
- return 0;
- }
- //----------- End of function Sys::detect_key_str --------//
- //-------- Begin of function Sys::set_speed --------//
- //
- void Sys::set_speed(int frameSpeed, int remoteCall)
- {
- //--------- if multiplayer, update remote players setting -------//
- if( remote.is_enable() && !remoteCall )
- {
- RemoteMsg *remoteMsg = remote.new_msg(MSG_SET_SPEED, sizeof(short));
- *((short*)remoteMsg->data_buf) = frameSpeed;
- remote.send_free_msg( remoteMsg ); // send out the message and free it after finishing sending
- }
- //---------- set the speed now ----------//
- if( config.frame_speed==0 ) // if it's currently frozen, set last_frame_time to avoid incorrect timeout
- last_frame_time = m.get_time();
- config.frame_speed = frameSpeed;
- }
- //--------- End of function Sys::set_speed ---------//
- //-------- Begin of function Sys::capture_screen --------//
- //
- void Sys::capture_screen()
- {
- String str;
- int i;
- for (i = 0; i <= 999; i++)
- {
- str = m.format(info.random_seed, 1);
- str += "_";
- if (i < 100) str += "0";
- if (i < 10) str += "0";
- str += i;
- str += ".BMP";
- if( !m.is_file_exist(str) )
- break;
- }
- if (i > 999) // all file names from DWORLD000 to DWORLD999 have been occupied
- return;
- if( sys.debug_session ) // in debug session, the buffer is not locked, we need to lock it for capturing the screen
- {
- vga_true_front.lock_buf();
- vga_true_front.write_bmp_file(str);
- vga_true_front.unlock_buf();
- }
- else
- {
- vga_front.write_bmp_file(str);
- }
- //------ display msg --------//
- String str2;
- #if(defined(SPANISH))
- str2 = "Pantalla actual guardada en el archivo ";
- str2 += str;
- str2 += ".";
- #elif(defined(FRENCH))
- str2 = "Cet écran a été sauvegardé dans le fichier ";
- str2 += str;
- str2 += ".";
- #else
- str2 = "The current screen has been written to file ";
- str2 += str;
- str2 += ".";
- #endif
- box.msg( str2 );
- }
- //--------- End of function Sys::capture_screen ---------//
- //-------- Begin of function Sys::capture_minimap --------//
- //
- void Sys::capture_minimap()
- {
- String str;
- int i;
- for (i = 0; i <= 999; i++)
- {
- str = m.format(info.random_seed, 1);
- str += "_";
- if (i < 100) str += "0";
- if (i < 10) str += "0";
- str += i;
- str += ".BMP";
- if( !m.is_file_exist(str) )
- break;
- }
- if (i > 999) // all file names from DWORLD000 to DWORLD999 have been occupied
- return;
- if( sys.debug_session ) // in debug session, the buffer is not locked, we need to lock it for capturing the screen
- {
- vga_true_front.lock_buf();
- vga_true_front.write_bmp_file(str, 588, 56, 200, 200);
- vga_true_front.unlock_buf();
- }
- else
- {
- vga_front.write_bmp_file(str, 588, 56, 200, 200);
- }
- //------ display msg --------//
- String str2;
- str2 = "The current minimap has been written to file ";
- str2 += str;
- str2 += ".";
- box.msg( str2 );
- }
- //--------- End of function Sys::capture_minimap ---------//
- //--------- Begin of static function static_main_win_proc --------//
- //
- // Callback for all Windows messages
- //
- static long FAR PASCAL static_main_win_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- return sys.main_win_proc(hWnd, message, wParam, lParam);
- }
- //--------- End of static function static_main_win_proc --------//
- //-------- Begin of function Sys::load_game --------//
- //
- void Sys::load_game()
- {
- //--- load game not enabled in multiplayer game ---//
- if( remote.is_enable() )
- return;
- signal_exit_flag=1; // for deinit functions to recognize that this is an end game deinitialization instead of a normal deinitialization
- int rc=0;
- game_file_array.init("*.SAV"); // reload any save game file
- game_file_array.menu(-2); // save screen area to back buffer
- switch( game_file_array.menu(2) )
- {
- case 1:
- rc = 1; // fall through to case 0
- case 0:
- signal_exit_flag = 0;
- break;
- // case -1 and otherwise, left sys.signal_exit_flag 1 to exit the game
- }
- game_file_array.menu(-1); // restore screen area from back buffer
- //-----------------------------------//
- if( rc == -1)
- {
- box.msg( "Fail Loading Game" );
- return;
- }
- if( rc ) // if rc==0, leave signal_exit_flag 1, which the game will then quit
- {
- need_redraw_flag = 1;
- disp_frame();
- // #### begin Gilbert 22/10 ######//
- disp_view_mode();
- // #### end Gilbert 22/10 ######//
- box.msg( "Game Loaded Successfully" );
- signal_exit_flag=0;
- info.disp();
- }
- }
- //--------- End of function Sys::load_game ---------//
- //-------- Begin of function Sys::save_game --------//
- //
- void Sys::save_game()
- {
- if( nation_array.player_recno==0 ) // cannot save game when the player's kingdom has been destroyed
- return;
- if( remote.is_enable() )
- {
- DWORD *dwordPtr = (DWORD *)remote.new_send_queue_msg( MSG_REQUEST_SAVE, sizeof(DWORD) );
- *dwordPtr = remote.next_send_frame(nation_array.player_recno, sys.frame_count+remote.process_frame_delay)+2;
- return;
- }
- game_file_array.init("*.SAV"); // reload any save game file
- game_file_array.menu(-2); // save screen area to back buffer
- if( game_file_array.menu(1) == 1 )
- {
- if( GameFile::last_read_success_flag )
- box.msg( "Game Saved Successfully" );
- }
- game_file_array.menu(-1); // restore screen area from back buffer
- // ##### patch begin Gilbert 16/3 #######//
- info.disp();
- // ##### patch end Gilbert 16/3 #######//
- }
- //-------- End of function Sys::save_game --------//
- // --------- begin of function Sys::mp_request_save ----------//
- void Sys::mp_request_save(DWORD frame)
- {
- if( !mp_save_flag )
- {
- mp_save_flag = 1;
- mp_save_frame = frame;
- }
- }
- // --------- end of function Sys::mp_request_save ----------//
- // --------- begin of function Sys::mp_clear_request_save ----------//
- void Sys::mp_clear_request_save()
- {
- mp_save_flag = 0;
- mp_save_frame = 0;
- }
- // --------- end of function Sys::mp_clear_request_save ----------//
- //-------- Begin of function Sys::set_game_dir ----------//
- //
- // Set all game directories.
- //
- void Sys::set_game_dir()
- {
- //------- If it should run from the CDROM ------//
- get_cdrom_drive();
- set_one_dir( "IMAGE\\HALLFAME.ICN" , "IMAGE\\", dir_image );
- set_one_dir( "ENCYC\\SEAT\\NORMAN.ICN", "ENCYC\\", dir_encyc );
- #ifdef AMPLUS
- set_one_dir( "ENCYC2\\SEAT\\EGYPTIAN.ICN", "ENCYC2\\", dir_encyc2 );
- #endif
- set_one_dir( "MOVIE\\INTRO.AVI" , "MOVIE\\", dir_movie );
- #ifdef DEMO
- set_one_dir( "MUSIC\\DEMO.WAV" , "MUSIC\\", dir_music );
- set_one_dir( "TUTORIAL\\STANDARD.TUT" , "TUTORIAL\\", dir_tutorial );
- set_one_dir( "SCENARIO\\DEMO.SCN" , "SCENARIO\\", dir_scenario );
- #else
- set_one_dir( "MUSIC\\NORMAN.WAV" , "MUSIC\\", dir_music );
- set_one_dir( "TUTORIAL\\1BAS_MIL.TUT" , "TUTORIAL\\", dir_tutorial );
- set_one_dir( "SCENARIO\\7FOR7.SCN" , "SCENARIO\\", dir_scenario );
- #endif
- #if(MAX_SCENARIO_PATH >= 2)
- set_one_dir( "SCENARI2\\SCN_01.SCN" , "SCENARI2\\", dir_scenario_path[1] );
- #endif
- //-------- set game version ---------//
- #ifdef BETA
- game_version = VERSION_FULL;
- #else
- #ifdef DEMO
- game_version = VERSION_DEMO;
- #else
- if( 1 ) // no longer checkcd if( cdrom_drive )
- game_version = VERSION_FULL; // single player game is not available when game_version == VERSION_FULL
- else
- game_version = VERSION_MULTIPLAYER_ONLY;
- #endif
- #endif
- }
- //----------- End of function Sys::set_game_dir ----------//
- //-------- Begin of function Sys::set_one_dir ----------//
- //
- int Sys::set_one_dir( char* checkFileName, char* defaultDir, char* trueDir )
- {
- if( m.is_file_exist( checkFileName ) )
- {
- strcpy( trueDir, defaultDir );
- }
- else
- {
- if( cdrom_drive )
- {
- strcpy( trueDir, "D:\\" );
- strcat( trueDir, defaultDir );
- trueDir[0] = cdrom_drive;
- }
- else
- {
- strcpy( trueDir, "" );
- return 0;
- }
- }
- return 1;
- }
- //----------- End of function Sys::set_one_dir ----------//
- //-------- Start of function Sys::get_cdrom_drive -------------//
- //
- // Get the drive letter of the CDROM and restore the result in cdrom_drive.
- //
- void Sys::get_cdrom_drive()
- {
- unsigned char i;
- char driveStr[4];
- static char checkFileName[30] = "D:\\7K.EXE"; // check this file to identify the disc
- cdrom_drive = 0;
- driveStr[1] = ':';
- driveStr[2] = '\\';
- driveStr[3] = 0;
- // ##### patch begin Gilbert 14/10 ######//
- for(i='C'; i<='Z'; i++)
- // ##### patch end Gilbert 14/10 ######//
- {
- checkFileName[0] = i;
- driveStr[0] = i;
- if(GetDriveType(driveStr) == DRIVE_CDROM)
- {
- if( m.is_file_exist(checkFileName) )
- {
- cdrom_drive = i;
- break;
- }
- }
- }
- }
- //--------- End of function Sys::get_cdrom_drive ---------------//
- //-------- Start of function locate_king_general -------------//
- //
- static void locate_king_general(int rankId)
- {
- if( !nation_array.player_recno )
- return;
- int unitRecno = 0;
- if(unit_array.selected_recno)
- unitRecno = unit_array.selected_recno;
- else if(rankId!=RANK_KING && firm_array.selected_recno)
- {
- Firm *firmPtr = firm_array[firm_array.selected_recno];
- if((firmPtr->firm_id==FIRM_CAMP || firmPtr->firm_id==FIRM_BASE) && firmPtr->overseer_recno)
- unitRecno = firmPtr->overseer_recno;
- }
- for( int i=unit_array.size() ; i>0 ; i-- )
- {
- if( ++unitRecno > unit_array.size() )
- unitRecno = 1;
- if( unit_array.is_deleted(unitRecno) )
- continue;
- Unit* unitPtr = unit_array[unitRecno];
- if( unitPtr->nation_recno == nation_array.player_recno &&
- unitPtr->rank_id == rankId )
- {
- short xLoc, yLoc;
- if( unitPtr->get_cur_loc(xLoc, yLoc) )
- {
- world.go_loc(xLoc, yLoc, 1);
- return;
- }
- }
- }
- }
- //--------- End of function locate_king_general ---------------//
- //-------- Start of function locate_spy -------------//
- //
- static void locate_spy()
- {
- if( !nation_array.player_recno )
- return;
- int unitRecno = unit_array.selected_recno;
- for( int i=unit_array.size() ; i>0 ; i-- )
- {
- if( ++unitRecno > unit_array.size() )
- unitRecno = 1;
- if( unit_array.is_deleted(unitRecno) )
- continue;
- Unit* unitPtr = unit_array[unitRecno];
- if( unitPtr->true_nation_recno() == nation_array.player_recno &&
- unitPtr->spy_recno && unitPtr->is_visible() )
- {
- short xLoc, yLoc;
- if( unitPtr->get_cur_loc(xLoc, yLoc) )
- {
- world.go_loc(xLoc, yLoc, 1);
- return;
- }
- }
- }
- }
- //--------- End of function locate_spy ---------------//
- //-------- Start of function locate_ship -------------//
- //
- static void locate_ship()
- {
- if( !nation_array.player_recno )
- return;
- //----------------------------------------------------------------------------//
- // The order is
- // 1) visible ships by their sprite_recno in ascending order
- // 2) FirmHarbors with ships (num of ships >= 1) by their firm_recno in ascending
- // order
- //
- // Start the scaning in one of the following cases
- // 1) a unit is selected
- // 2) a firm is selected
- // 3) neither unit or firm is selected
- //----------------------------------------------------------------------------//
- if(firm_array.selected_recno)
- {
- if(!locate_ship_in_harbor()) // harbor first, then unit
- locate_visible_ship();
- }
- else // if(unit_array.selected_recno) or neither of them is selected
- {
- if(!locate_visible_ship()) // unit first, then harbor
- locate_ship_in_harbor();
- }
- }
- //--------- End of function locate_ship ---------------//
- //-------- Start of function locate_ship_in_harbor -------------//
- // return 1 if found
- // return 0 otherwise
- //
- static int locate_ship_in_harbor()
- {
- int firmRecno = firm_array.selected_recno;
- int checkSize = firm_array.size();
- if(firmRecno)
- checkSize--; // not include the selected firm
- for( int i=checkSize ; i>0 ; i-- )
- {
- if( ++firmRecno > firm_array.size() )
- firmRecno = 1;
- if( firm_array.is_deleted(firmRecno) )
- continue;
- Firm* firmPtr = firm_array[firmRecno];
- if(firmPtr->firm_id!=FIRM_HARBOR ||
- firmPtr->nation_recno != nation_array.player_recno)
- continue;
- if(((FirmHarbor*)firmPtr)->ship_count==0)
- continue; // not interested
- world.go_loc(firmPtr->center_x, firmPtr->center_y, 1);
- return 1;
- }
- return 0;
- }
- //--------- End of function locate_ship_in_harbor ---------------//
- //-------- Start of function locate_visible_ship -------------//
- // return 1 if found
- // return 0 otherwise
- //
- static int locate_visible_ship()
- {
- int unitRecno = unit_array.selected_recno;
- int checkSize = unit_array.size();
- if(unitRecno)
- checkSize--; // not include the selected unit
- for( int i=checkSize ; i>0 ; i-- )
- {
- if( ++unitRecno > unit_array.size() )
- unitRecno = 1;
- if( unit_array.is_deleted(unitRecno) )
- continue;
- Unit* unitPtr = unit_array[unitRecno];
- if(!unitPtr->is_visible()) // skip the case unit_mode==UNIT_MODE_IN_HARBOR in calling Unit::get_cur_loc()
- continue;
- if( unitPtr->nation_recno == nation_array.player_recno &&
- unit_res[unitPtr->unit_id]->unit_class == UNIT_CLASS_SHIP )
- {
- short xLoc, yLoc;
- if( unitPtr->get_cur_loc(xLoc, yLoc) )
- {
- world.go_loc(xLoc, yLoc, 1);
- return 1;
- }
- }
- }
- return 0;
- }
- //--------- End of function locate_visible_ship ---------------//
- //-------- Start of function locate_camp -------------//
- //
- static void locate_camp()
- {
- if( !nation_array.player_recno )
- return;
- int firmRecno = firm_array.selected_recno;
- for( int i=firm_array.size() ; i>0 ; i-- )
- {
- if( ++firmRecno > firm_array.size() )
- firmRecno = 1;
- if( firm_array.is_deleted(firmRecno) )
- continue;
- Firm* firmPtr = firm_array[firmRecno];
- if( firmPtr->nation_recno == nation_array.player_recno &&
- firmPtr->firm_id == FIRM_CAMP )
- {
- world.go_loc(firmPtr->center_x, firmPtr->center_y, 1);
- return;
- }
- }
- }
- //--------- End of function locate_camp ---------------//
- //-------- Start of function get_mouse_loc_in_zoom_map -------------//
- static int get_mouse_loc_in_zoom_map(int &x, int &y)
- {
- int mouseX = mouse.cur_x;
- int mouseY = mouse.cur_y;
- if(mouseX >= ZOOM_X1 && mouseX <= ZOOM_X2 && mouseY >= ZOOM_Y1 && mouseY <= ZOOM_Y2)
- {
- x = world.zoom_matrix->top_x_loc + (mouseX-ZOOM_X1)/ZOOM_LOC_WIDTH;
- y = world.zoom_matrix->top_y_loc + (mouseY-ZOOM_Y1)/ZOOM_LOC_HEIGHT;
- return 1;
- }
- return 0; // out of zoom map boundary
- }
- //--------- End of function get_mouse_loc_in_zoom_map ---------------//
|