1 /*
2  * Seven Kingdoms: Ancient Adversaries
3  *
4  * Copyright 1997,1998 Enlight Software Ltd.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 //Filename	  : OSYS2.CPP
22 //Description : System resource management object
23 
24 #include <OVGA.h>
25 #include <vga_util.h>
26 #include <OMOUSE.h>
27 #include <OFONT.h>
28 #include <OBUTT3D.h>
29 #include <OVBROWSE.h>
30 #include <ONATION.h>
31 #include <OFIRM.h>
32 #include <OTOWN.h>
33 #include <OSITE.h>
34 #include <OUNIT.h>
35 #include <OHELP.h>
36 #include <OTUTOR.h>
37 #include <ONEWS.h>
38 #include <OBULLET.h>
39 #include <OREBEL.h>
40 #include <OREMOTE.h>
41 #include <OSPY.h>
42 #include <OINFO.h>
43 #include <OGAME.h>
44 #include <OWORLD.h>
45 #include <OSYS.h>
46 #include <ORAWRES.h>
47 #include <OTALKRES.h>
48 #include <OWEATHER.h>
49 #include <OANLINE.h>
50 #include <OTORNADO.h>
51 #include <OSE.h>
52 #include <OSNOWG.h>
53 #include <OROCK.h>
54 #include <OEFFECT.h>
55 #include <OLOG.h>
56 #include <OCONFIG.h>
57 #include <OPOWER.h>
58 #include <OSERES.h>
59 #include <OIMGRES.h>
60 #include <OWARPT.h>
61 #include <OMOUSECR.h>
62 #include <OFIRMDIE.h>
63 #include <OOPTMENU.h>
64 #include <OINGMENU.h>
65 #include <CmdLine.h>
66 #include <gettext.h>
67 
68 
69 //---------- define static variables ----------//
70 
71 static int		  report_disp_frame_no;
72 static Button3D  button_menu;
73 
74 //-------- Begin of function Sys::detect --------//
75 //
detect()76 void Sys::detect()
77 {
78 	//--- only detect at the even frames when in report mode ---//
79 
80 	if( view_mode != MODE_NORMAL &&
81 		// ###### begin Gilbert 5/11 ######//
82 		 !report_disp_frame_no )
83 		// ###### end Gilbert 5/11 ######//
84 	{
85 		return;
86 	}
87 
88 	//--------------------------------------//
89 
90 	mouse.get_event();
91 
92 	if( option_menu.is_active() )
93 	{
94 		option_menu.detect();
95 		return;
96 	}
97 
98 	if( in_game_menu.is_active() )
99 	{
100 		in_game_menu.detect();
101 		return;
102 	}
103 
104 	if( mouse.is_key_event() )
105 	{
106 		process_key(mouse.scan_code, mouse.event_skey_state);
107 	}
108 
109 	detect_button();		// detect main buttons on the screen
110 
111 	detect_view();
112 }
113 //--------- End of function Sys::detect ---------//
114 
115 
116 //-------- Begin of function Sys::process --------//
117 //
process()118 void Sys::process()
119 {
120 	//------- update frame count and is_sync_frame --------//
121 
122 	frame_count++;
123 	is_sync_frame = frame_count%3==0;	// check if sychronization should take place at this frame (for handling one sync per n frames)
124 
125 	//--------- process objects -----------//
126 
127 	LOG_MSG(misc.get_random_seed());
128 	LOG_MSG("begin unit_array.process()");
129 	unit_array.process();
130 	seek_path.reset_total_node_avail();	// reset node for seek_path
131 	LOG_MSG("end unit_array.process()");
132 	LOG_MSG(misc.get_random_seed());
133 
134 	LOG_MSG("begin firm_array.process()");
135 	firm_array.process();
136 	LOG_MSG("end firm_array.process()");
137 	LOG_MSG(misc.get_random_seed());
138 
139 	LOG_MSG("begin town_array.process()");
140 	town_array.process();
141 	LOG_MSG("end town_array.process()");
142 	LOG_MSG(misc.get_random_seed());
143 
144 	LOG_MSG("begin nation_array.process()");
145 	nation_array.process();
146 	LOG_MSG("end nation_array.process()");
147 	LOG_MSG(misc.get_random_seed());
148 
149 	LOG_MSG("begin bullet_array.process()");
150 	bullet_array.process();
151 	LOG_MSG("end bullet_array.process()");
152 	LOG_MSG(misc.get_random_seed());
153 
154 	LOG_MSG("begin world.process()");
155 	world.process();
156 	LOG_MSG("end world.process()");
157 	LOG_MSG(misc.get_random_seed());
158 
159 	LOG_MSG("begin tornado_array.process()");
160 	tornado_array.process();
161 	LOG_MSG("begin tornado_array.process()");
162 	LOG_MSG(misc.get_random_seed());
163 
164 	LOG_MSG("begin snow_ground_array.process()");
165 	snow_ground_array.process();
166 	LOG_MSG("end snow_ground_array.process()");
167 	LOG_MSG(misc.get_random_seed());
168 
169 	LOG_MSG("begin rock_array.process()");
170 	rock_array.process();
171 	LOG_MSG("end rock_array.process()");
172 	LOG_MSG(misc.get_random_seed());
173 
174 	LOG_MSG("begin dirt_array.process()");
175 	dirt_array.process();
176 	LOG_MSG("end dirt_array.process()");
177 	LOG_MSG(misc.get_random_seed());
178 
179 	LOG_MSG("begin effect_array.process()");
180 	effect_array.process();
181 	LOG_MSG("end effect_array.process()");
182 	LOG_MSG(misc.get_random_seed());
183 
184 	LOG_MSG("begin war_point_array.process()");
185 	war_point_array.process();
186 	LOG_MSG("end war_point_array.process()");
187 
188 	LOG_MSG("begin firm_die.process()");
189 	firm_die_array.process();
190 	LOG_MSG("end firm_die.process()");
191 
192 	//------ check if it's time for the next day ------//
193 
194 	if( ++day_frame_count > FRAMES_PER_DAY )
195 	{
196 		LOG_MSG("begin info.next_day()");
197 		info.next_day();
198 		LOG_MSG("end info.next_day()");
199 		LOG_MSG(misc.get_random_seed());
200 
201 		LOG_MSG("begin world.next_day()");
202 		world.next_day();
203 		LOG_MSG("end world.next_day()");
204 		LOG_MSG(misc.get_random_seed());
205 
206 		LOG_MSG("begin site_array.next_day()");
207 		site_array.next_day();
208 		LOG_MSG("end site_array.next_day()");
209 		LOG_MSG(misc.get_random_seed());
210 
211 		LOG_MSG("begin rebel_array.next_day()");
212 		rebel_array.next_day();
213 		LOG_MSG("end rebel_array.next_day()");
214 		LOG_MSG(misc.get_random_seed());
215 
216 		LOG_MSG("begin spy_array.next_day()");
217 		spy_array.next_day();
218 		LOG_MSG("end spy_array.next_day()");
219 		LOG_MSG(misc.get_random_seed());
220 
221 		LOG_MSG("begin sprite_res.update_speed()");
222 		if( config.weather_effect)
223 			sprite_res.update_speed();
224 		LOG_MSG("end sprite_res.update_speed()");
225 		LOG_MSG(misc.get_random_seed());
226 
227 		LOG_MSG("begin raw_res.next_day()");
228 		raw_res.next_day();
229 		LOG_MSG("end raw_res.next_day()");
230 		LOG_MSG(misc.get_random_seed());
231 
232 		LOG_MSG("begin talk_res.next_day()");
233 		talk_res.next_day();
234 		LOG_MSG("end talk_res.next_day()");
235 		LOG_MSG(misc.get_random_seed());
236 
237 		LOG_MSG("begin region_array.next_day()");
238 		region_array.next_day();
239 		LOG_MSG("end region_array.next_day()");
240 		LOG_MSG(misc.get_random_seed());
241 
242 		day_frame_count = 0;
243 	}
244 
245 	//------ display the current frame ------//
246 
247 	LOG_MSG("begin sys.disp_frame");
248 	misc.lock_seed();
249 	if( cmd_line.enable_if )
250 		disp_frame();
251 	misc.unlock_seed();
252 	LOG_MSG("end sys.disp_frame");
253 	LOG_MSG(misc.get_random_seed() );
254 
255 	//-----------------------------------------//
256 
257 	/*
258 	#ifdef DEBUG
259 		//------- debug codes used to count town's defender number -------//
260 		Unit *unitPtr;
261 		Town *townPtr;
262 		for(int i=unit_array.size(); i>0; i--)
263 		{
264 			if(unit_array.SpriteArray::is_deleted(i))
265 				continue;
266 
267 			unitPtr = unit_array[i];
268 
269 			if(unitPtr->unit_mode==UNIT_MODE_DEFEND_TOWN)
270 			{
271 				if(town_array.is_deleted(unitPtr->unit_mode_para))
272 					continue;
273 
274 				townPtr = town_array[unitPtr->unit_mode_para];
275 				if(townPtr->nation_recno==unitPtr->nation_recno)
276 					townPtr->debug_defender_count++;
277 			}
278 		}
279 
280 		for(i=town_array.size(); i>0; i--)
281 		{
282 			if(town_array.is_deleted(i))
283 				continue;
284 
285 			townPtr = town_array[i];
286 			err_when(townPtr->debug_defender_count != townPtr->town_defender_count);
287 			townPtr->debug_defender_count = 0;
288 		}
289 	#endif
290 	*/
291 	//-*********** simulate aat ************-//
292 	#ifdef DEBUG
293 		if(debug_sim_game_type==2)
294 		{
295 			//if(misc.random(20)==0)
296 			if(misc.random(50)==0)
297 			{
298 				#define MAX_ATTACKER	30
299 				int arraySize = unit_array.size();
300 				int i, j, i2, j2;
301 				short nationRecno;
302 				Unit *unitPtr, *targetPtr;
303 
304 				short attackerArray[MAX_ATTACKER];
305 				short attackerCount = 0;
306 
307 				//----------- select attackers -----------//
308 				//for(i=misc.random(arraySize)+1, j=1; j<=arraySize; j++, i++)
309 				for(i=int(misc.get_random_seed()%arraySize)+1, j=1; j<=arraySize; j++, i++)
310 				{
311 					if(i>arraySize)
312 						i = 1;
313 
314 					if(unit_array.is_deleted(i))
315 						continue;
316 
317 					unitPtr = (Unit*) unit_array[i];
318 					if(!unitPtr->is_visible())
319 						continue;
320 
321 					if(attackerCount)
322 					{
323 						if(unitPtr->nation_recno!=nationRecno)
324 							continue;
325 					}
326 					else
327 						nationRecno = unitPtr->nation_recno;
328 
329 					err_when(i!=unitPtr->sprite_recno);
330 					err_when(i>arraySize);
331 
332 					if(misc.random(4)==0)
333 						attackerArray[attackerCount++] = i;
334 
335 					if(attackerCount>=MAX_ATTACKER/2)
336 						break; // array full
337 				}
338 
339 				//--------- selecet victim ----------//
340 				//if(day_frame_count==9 && frame_count==6082)
341 				//	int debug  =0;
342 				if(misc.random(10))
343 				{
344 					//for(i2=misc.random(arraySize)+1, j2=1; j2<=arraySize; j2++, i2++)
345 					for(i2=int(misc.get_random_seed()%arraySize)+1, j2=1; j2<=arraySize; j2++, i2++)
346 					{
347 						if(i2>arraySize)
348 							i2 = 1;
349 
350 						if(unit_array.is_deleted(i2))
351 							continue;
352 
353 						targetPtr = (Unit*) unit_array[i2];
354 						if(!targetPtr->is_visible())
355 							continue;
356 
357 						if(targetPtr->nation_recno==unitPtr->nation_recno)
358 							continue;
359 
360 						err_when(i2>arraySize);
361 						unit_array.attack(targetPtr->next_x_loc(), targetPtr->next_y_loc(), 0, attackerArray, attackerCount, 0, 0);
362 						break;
363 					}
364 				}
365 				else
366 					unit_array.move_to(misc.random(MAX_WORLD_X_LOC), misc.random(MAX_WORLD_Y_LOC), 0, attackerArray, attackerCount, 1);
367 			}
368 		}
369 	#endif
370 	//-*********** simulate aat ************-//
371 }
372 //--------- End of function Sys::process ---------//
373 
374 
375 //-------- Begin of function Sys::disp_button --------//
376 //
disp_button()377 void Sys::disp_button()
378 {
379 	vga.use_back();
380 
381 	button_menu.paint( 720, 6, "MENU-U", "MENU-D" );
382 	button_menu.set_help_code( "GAMEMENU" );
383 
384 	vga.use_front();
385 }
386 //--------- End of function Sys::disp_button ---------//
387 
388 
389 //-------- Begin of function Sys::detect_button --------//
390 //
detect_button()391 void Sys::detect_button()
392 {
393 	//--------- detect menu button -------//
394 
395 	if( button_menu.detect() )
396 	{
397 		// ##### begin Gilbert 5/11 #######//
398 		// game.in_game_menu();
399 		in_game_menu.enter(!remote.is_enable());
400 		// ##### end Gilbert 5/11 #######//
401 		return;
402 	}
403 
404 	//------- detect view mode buttons -----//
405 
406 	#define VIEW_MODE_BUTTON_WIDTH   58
407 	#define VIEW_MODE_BUTTON_HEIGHT  16
408 	#define VIEW_MODE_BUTTON_X_SPACE  5
409 
410 	int i, x=6, y=8;
411 
412 	static char viewModeArray[] =
413 	{
414 		MODE_NATION, MODE_TOWN, MODE_ECONOMY, MODE_TRADE, MODE_MILITARY, MODE_TECH, MODE_SPY, MODE_RANK
415 	};
416 
417 	for( i=0 ; i<8 ; i++, x+=VIEW_MODE_BUTTON_WIDTH+VIEW_MODE_BUTTON_X_SPACE )
418 	{
419 		if( i==4 )		// the second row
420 		{
421 			x=12;
422 			y=29;
423 		}
424 
425 		if( nation_array.player_recno==0 && i<7 )		// when the player has lost the game, the only report available is ranking report only
426 			continue;
427 
428 		if( mouse.single_click( x, y, x+VIEW_MODE_BUTTON_WIDTH-1, y+VIEW_MODE_BUTTON_HEIGHT-1 ) )
429 		{
430 			int newMode = viewModeArray[i];
431 
432 			if( view_mode == newMode )       	// when click on the same mode again, go to the normal mode
433 				set_view_mode(MODE_NORMAL);
434 			else
435 				set_view_mode(newMode);
436 
437 			break;
438 		}
439 	}
440 }
441 //--------- End of function Sys::detect_button ---------//
442 
443 
444 //-------- Begin of function Sys::set_view_mode --------//
445 //
446 // <int> viewMode 			 - id. of the view mode.
447 // [int] viewingNationRecno - which nation the player is viewing at with the reports.
448 //										(default: the player nation)
449 // [int] viewingSpyRecno 	 - >0 if the spy is viewing secret reports of other nations
450 //
set_view_mode(int viewMode,int viewingNationRecno,int viewingSpyRecno)451 void Sys::set_view_mode(int viewMode, int viewingNationRecno, int viewingSpyRecno)
452 {
453 	if( view_mode == viewMode )
454 		return;
455 
456 	//---- if the player's kingdom has been destroyed ----//
457 
458 	err_when( viewingNationRecno && nation_array.is_deleted(viewingNationRecno) );
459 
460 	if( nation_array.is_deleted(info.default_viewing_nation_recno) )
461 	{
462 		if( viewMode != MODE_NORMAL && viewMode != MODE_RANK )		// other reports are not available except the normal and rank report
463 			return;
464 	}
465 
466 	//---- a spy is exposed when he has finished viewing the secrets ----//
467 
468 	if( info.viewing_spy_recno )
469 	{
470 		if( !spy_array.is_deleted(info.viewing_spy_recno) )
471 		{
472 			Spy* spyPtr = spy_array[info.viewing_spy_recno];
473 
474 			int needViewSecretSkill = spy_array.needed_view_secret_skill(info.viewing_spy_recno);
475 			int escapeChance = spyPtr->spy_skill - needViewSecretSkill;
476 			int killFlag = 0;
477 
478 			if( escapeChance > 0 )
479 			{
480 				if( misc2.random( escapeChance/15 )==0  )		// use m2 instead of m to maintain mulitplayer sync
481 					killFlag = 1;
482 			}
483 
484 			if( killFlag )
485 				spyPtr->set_exposed(COMMAND_PLAYER);
486 		}
487 
488 		info.viewing_spy_recno = 0;
489 	}
490 
491 	//----------------------------------------------------//
492 
493 	if( viewMode == MODE_NORMAL )
494 	{
495 		info.viewing_nation_recno = info.default_viewing_nation_recno;
496 	}
497 	else
498 	{
499 		if( viewingNationRecno )
500 			info.viewing_nation_recno = viewingNationRecno;
501 		else
502 			info.viewing_nation_recno = info.default_viewing_nation_recno;
503 
504 		info.viewing_spy_recno = viewingSpyRecno;
505 	}
506 	if( viewMode == MODE_NATION && info.nation_report_mode == NATION_REPORT_CHAT )
507 		SDL_StartTextInput();
508 	else
509 		SDL_StopTextInput();
510 
511 	view_mode = viewMode;
512 	disp_view_mode();
513 
514 	disp_view();
515 }
516 //--------- End of function Sys::set_view_mode ---------//
517 
518 
519 //-------- Begin of function Sys::disp_frame --------//
520 
disp_frame()521 void Sys::disp_frame()
522 {
523 	if( sys.signal_exit_flag )
524 		return;
525 
526 	if( option_menu.is_active() )
527 	{
528 		// ##### begin Gilbert 3/11 ######//
529 		option_menu.disp(need_redraw_flag);
530 		// ##### end Gilbert 3/11 ######//
531 		blt_virtual_buf();
532 	}
533 	else
534 	{
535 		// -------- re-draw the whole screen if needed, such as after task switching ---------//
536 
537 		if( need_redraw_flag )
538 		{
539 			info.disp_panel();
540 			world.paint();
541 			disp_button();
542 			world.refresh();
543 			disp_view();
544 
545 			if( in_game_menu.is_active() )
546 			{
547 				vga.use_back();
548 				in_game_menu.disp();
549 				vga.use_front();
550 			}
551 
552 			vga_util.blt_buf(0,0, VGA_WIDTH-1, VGA_HEIGHT-1, 0);
553 			// ###### begin Gilbert 4/11 ######//
554 			disp_view_mode();
555 			// ###### end Gilbert 4/11 ######//
556 
557 			info.disp();
558 		}
559 		else
560 		{
561 			update_view();
562 			info.update();
563 		}
564 
565 		//--------- display the map and info area --------//
566 
567 		disp_map();
568 
569 		blt_virtual_buf();
570 
571 		//---------- display help ----------//
572 
573 		if( !remote.is_enable() )		// help is only available in a single player game as it has to pause the game
574 			help.disp();
575 	}
576 	// ####### end Glbert 24/10 #######//
577 
578 	anim_line.inc_phase();		// originally in Sys::process()
579 
580 	need_redraw_flag = 0;
581 }
582 //-------- End of function Sys::disp_frame --------//
583 
584 
585 //-------- Begin of function Sys::disp_view --------//
586 //
587 // Display the view area.
588 //
disp_view()589 void Sys::disp_view()
590 {
591 	disp_zoom();
592 	// ###### begin Gilbert 5/11 ########//
593 	report_disp_frame_no = 0;		// 0 - mean report can be drawn, clear after disp_zoom, set after display report
594 	// ###### end Gilbert 5/11 ########//
595 
596 	//---- if in report mode, convert the view to gray scale ----//
597 
598 	if( view_mode!=MODE_NORMAL )
599 	{
600 		// ###### begin Gilbert 5/11 ########//
601 		// report_disp_frame_no = frame_count;		// the frame no which this report is first displayed
602 		// ###### end Gilbert 5/11 ########//
603 
604 		//------- blt the zoom area to the front screen --------//
605 
606 		vga.use_back();
607 		Vga::opaque_flag = config.opaque_report;
608 
609 		switch( view_mode )
610 		{
611 			case MODE_TRADE:
612 				info.disp_trade(INFO_REPAINT);
613 				break;
614 
615 			case MODE_MILITARY:
616 				info.disp_military(INFO_REPAINT);
617 				break;
618 
619 			case MODE_ECONOMY:
620 				info.disp_economy(INFO_REPAINT);
621 				break;
622 
623 			case MODE_TOWN:
624 				info.disp_town(INFO_REPAINT);
625 				break;
626 
627 			case MODE_NATION:
628 				info.disp_nation(INFO_REPAINT);
629 				break;
630 
631 			case MODE_TECH:
632 				info.disp_tech(INFO_REPAINT);
633 				break;
634 
635 			case MODE_SPY:
636 				info.disp_spy(INFO_REPAINT);
637 				break;
638 
639 			case MODE_RANK:
640 				info.disp_rank(INFO_REPAINT);
641 				break;
642 
643 			case MODE_NEWS_LOG:
644 				info.disp_news_log(INFO_REPAINT);
645 				break;
646 
647 			case MODE_AI_ACTION:
648 				info.disp_ai_action(INFO_REPAINT);
649 				break;
650 		}
651 
652 		vga.use_front();
653 		Vga::opaque_flag = 0;
654 
655 		// ###### begin Gilbert 5/11 ########//
656 		report_disp_frame_no = 1;
657 		// ###### end Gilbert 5/11 ########//
658 	}
659 }
660 //-------- End of function Sys::disp_view --------//
661 
662 
663 //-------- Begin of function Sys::update_view --------//
664 //
665 // Display the view area.
666 //
update_view()667 void Sys::update_view()
668 {
669 	if( view_mode==MODE_NORMAL )
670 	{
671 		disp_zoom();
672 		// ####### begin Gilbert 5/11 #######//
673 		report_disp_frame_no = 0;
674 		// ####### end Gilbert 5/11 #######//
675 
676 		//------ display tutorial text -------//
677 
678 		if( game.game_mode == GAME_TUTORIAL )
679 			tutor.disp();
680 
681 		//----------- draw profile information -----------//
682 
683 		if( config.show_ai_info )
684 		{
685 			vga.use_back();
686 /*
687 			char* germanStr = "d �    �    �    �    �    �    �";
688 
689 			vga_back.bar( ZOOM_X1, ZOOM_Y1, ZOOM_X1+300, ZOOM_Y1+150, VGA_LIGHT_GREEN );
690 
691 			font_san.put( ZOOM_X1+10, ZOOM_Y1+30, germanStr );
692 			font_news.put( ZOOM_X1+10, ZOOM_Y1+50, germanStr );
693 			font_bible.put( ZOOM_X1+10, ZOOM_Y1+70, germanStr );
694 */
695 			nation_array.draw_profile();
696 			firm_array.draw_profile();
697 			town_array.draw_profile();
698 			unit_array.draw_profile();
699 
700 			vga.use_front();
701 		}
702 
703 		if( in_game_menu.is_active() )
704 		{
705 			vga.use_back();
706 			in_game_menu.disp();
707 			vga.use_front();
708 		}
709 
710 		//------------------------------------//
711 
712 		vga_util.blt_buf(ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2);
713 	}
714 	else
715 	{
716 		//-------------------------------------------//
717 		//
718 		// In report mode, display the background view in odd
719 		// number frames and the report in even number frames.
720 		//
721 		//-------------------------------------------//
722 
723 		// ####### begin Gilbert 5/11 #######//
724 		if( report_disp_frame_no )
725 		{
726 			disp_zoom();
727 			report_disp_frame_no = 0;
728 		}
729 		else
730 		{
731 			vga.use_back();
732 			Vga::opaque_flag = config.opaque_report;
733 
734 			switch( view_mode )
735 			{
736 				case MODE_TRADE:
737 					info.disp_trade(INFO_UPDATE);
738 					break;
739 
740 				case MODE_MILITARY:
741 					info.disp_military(INFO_UPDATE);
742 					break;
743 
744 				case MODE_ECONOMY:
745 					info.disp_economy(INFO_UPDATE);
746 					break;
747 
748 				case MODE_TOWN:
749 					info.disp_town(INFO_UPDATE);
750 					break;
751 
752 				case MODE_NATION:
753 					info.disp_nation(INFO_UPDATE);
754 					break;
755 
756 				case MODE_TECH:
757 					info.disp_tech(INFO_UPDATE);
758 					break;
759 
760 				case MODE_SPY:
761 					info.disp_spy(INFO_UPDATE);
762 					break;
763 
764 				case MODE_RANK:
765 					info.disp_rank(INFO_UPDATE);
766 					break;
767 
768 				case MODE_NEWS_LOG:
769 					info.disp_news_log(INFO_UPDATE);
770 					break;
771 
772 				case MODE_AI_ACTION:
773 					info.disp_ai_action(INFO_UPDATE);
774 					break;
775 			}
776 
777 			if( in_game_menu.is_active() )
778 			{
779 				in_game_menu.disp();
780 			}
781 
782 			vga.use_front();
783 			Vga::opaque_flag = 0;
784 
785 			vga_util.blt_buf(ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2);
786 
787 			// ###### begin Gilbert 5/11 #######//
788 			report_disp_frame_no = 1;
789 			// ###### end Gilbert 5/11 #######//
790 		}
791 	}
792 }
793 //-------- End of function Sys::update_view --------//
794 
795 
796 //-------- Begin of function Sys::detect_view --------//
797 //
detect_view()798 void Sys::detect_view()
799 {
800 	int enableAction;			// some action is not enabled, when paused.
801 	enableAction = config.frame_speed > 0 || !remote.is_enable();	// allow action when paused in single player
802 
803 	if( enableAction )
804 		info.detect();
805 
806 	vga.use_back();
807 
808 	switch( view_mode )
809 	{
810 		case MODE_TRADE:
811 			info.detect_trade();
812 			break;
813 
814 		case MODE_MILITARY:
815 			info.detect_military();
816 			break;
817 
818 		case MODE_ECONOMY:
819 			info.detect_economy();
820 			break;
821 
822 		case MODE_TOWN:
823 			info.detect_town();
824 			break;
825 
826 		case MODE_NATION:
827 			info.detect_nation();
828 			break;
829 
830 		case MODE_TECH:
831 			info.detect_tech();
832 			break;
833 
834 		case MODE_SPY:
835 			info.detect_spy();
836 			break;
837 
838 		case MODE_RANK:
839 			info.detect_rank();
840 			break;
841 
842 		case MODE_NEWS_LOG:
843 			info.detect_news_log();
844 			break;
845 
846 		case MODE_AI_ACTION:
847 			info.detect_ai_action();
848 			break;
849 	}
850 
851 	vga.use_front();
852 
853 	//------ detect tutorial controls -------//
854 
855 	if( view_mode==MODE_NORMAL && game.game_mode==GAME_TUTORIAL )		// tutorial text is only displayed in non-report mode
856 	{
857 		if( tutor.detect() )
858 			return;
859 	}
860 
861 	//---- no normal news when the game is displaying the news log ----//
862 
863 	// ##### patch begin Gilbert 31/3 #####//
864 	if( news_array.detect() )
865 		return;
866 	// ##### patch end Gilbert 31/3 #####//
867 
868 	//---- pressing right button in command mode -> cancel command mode ----//
869 
870 	if( mouse.any_click(RIGHT_BUTTON) && power.command_id )
871 	{
872 		power.command_id = 0;
873 		mouse.reset_click();
874 		info.disp();
875 		return;
876 	}
877 
878 	//------ detect selecting objects and laying tracks ------//
879 
880 	//-------- detect world ----------//
881 
882 	if( world.detect() )
883 		return;
884 
885 	if( view_mode == MODE_NORMAL )
886 	{
887 		if( world.detect_firm_town() )
888 			return;
889 
890 		//------ detect selecting objects and laying tracks ------//
891 
892 		if( power.detect_frame() )
893 			return;
894 	}
895 	else
896 	{
897 		mouse_cursor.set_frame(0);
898 	}
899 
900 	//----------- detect action ------------//
901 
902 	if( enableAction && power.detect_action() )
903 	{
904 		if(unit_array.selected_recno && se_res.mark_command_time() )
905 		{
906 			Unit *unitPtr = unit_array[unit_array.selected_recno];
907 			se_res.far_sound( unitPtr->cur_x_loc(), unitPtr->cur_y_loc(), 1, 'S',
908 				unitPtr->sprite_id, "ACK");
909 		}
910 		return;
911 	}
912 
913 	//----- detect right mouse button to select defined unit groups -----//
914 
915 	if( !(mouse.event_skey_state & SHIFT_KEY_MASK) &&
916 		mouse.any_click(ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2, RIGHT_BUTTON) &&
917 		power.detect_select(mouse.click_x(RIGHT_BUTTON), mouse.click_y(RIGHT_BUTTON),
918 			mouse.click_x(RIGHT_BUTTON),mouse.click_y(RIGHT_BUTTON), 1, 0) )		// 1 - recall group
919 	{
920 		return;
921 	}
922 
923 	//-------- detect world ----------//
924 
925 	// world.detect();
926 }
927 //-------- End of function Sys::detect_view --------//
928 
929 
930 //-------- Begin of function Sys::disp_map --------//
931 
disp_map()932 void Sys::disp_map()
933 {
934 	//------ draw and display the map -------//
935 
936 	if( map_need_redraw )		// requested by other modules to redraw the pre-drawn map background
937 	{
938 		world.map_matrix->draw();
939 		map_need_redraw = 0;
940 	}
941 
942 	world.map_matrix->disp();
943 
944 	//-------- draw dots on the map ---------//
945 
946 	firm_array.draw_dot();
947 	town_array.draw_dot();
948 	site_array.draw_dot();
949 	unit_array.draw_dot();
950 	war_point_array.draw_dot();
951 	tornado_array.draw_dot();
952 
953 	world.map_matrix->draw_square();		// draw a square on the map for current zoomed area
954 
955 	//------- blt the map area to the front screen --------//
956 
957 	vga_util.blt_buf( MAP_X1, MAP_Y1 , MAP_X2 , MAP_Y2);
958 }
959 //-------- End of function Sys::disp_map --------//
960 
961 
962 //-------- Begin of function Sys::disp_zoom --------//
963 
disp_zoom()964 void Sys::disp_zoom()
965 {
966 	//--------- set zoom window ----------//
967 
968 	ZoomMatrix* zoomMatrix = world.zoom_matrix;
969 
970 	err_when(zoomMatrix->top_x_loc<0 || zoomMatrix->top_x_loc>=MAX_WORLD_X_LOC);
971 	err_when(zoomMatrix->top_y_loc<0 || zoomMatrix->top_y_loc>=MAX_WORLD_Y_LOC);
972 
973 	World::view_top_x = zoomMatrix->top_x_loc * ZOOM_LOC_WIDTH;
974 	World::view_top_y = zoomMatrix->top_y_loc * ZOOM_LOC_HEIGHT;
975 
976 	//--------- draw map area ---------//
977 
978 	if( zoom_need_redraw )		// requested by other modules to redraw the pre-drawn zoom background
979 	{
980 		long backupSeed = misc.get_random_seed();
981 
982 		world.zoom_matrix->draw();
983 		zoom_need_redraw = 0;
984 	}
985 
986 	//-------- disp zoom area --------//
987 
988 	world.zoom_matrix->disp();
989 
990 	//---- draw sprite white sites if in debug mode ----//
991 
992 	#ifdef DEBUG
993 	if(debug2_enable_flag)
994 		world.zoom_matrix->draw_white_site();
995 	#endif
996 
997 	//------- draw foreground objects --------//
998 
999 	world.zoom_matrix->draw_frame();
1000 
1001 	//----- draw the frame of the selected firm/town -----//
1002 
1003 	info.draw_selected();
1004 
1005 	//-------- display news messages ---------//
1006 
1007 	news_array.disp();
1008 
1009 	//----- next frame, increase the frame counter -----//
1010 
1011 	sys.frames_in_this_second++;		// no. of frames displayed in this second
1012 
1013 	if( view_mode==MODE_NORMAL )
1014 	{
1015 		disp_frames_per_second();
1016 
1017 		if( (remote.is_enable() || remote.is_replay()) && (remote.sync_test_level & 0x40) )
1018 		{
1019 			// Warn user we are out of sync
1020 			vga.use_back();
1021 
1022 			if( !(remote.sync_test_level & 1) )
1023 				font_news.disp( ZOOM_X1+10, ZOOM_Y1+30, _("Multiplayer Random Seed Sync Error"), MAP_X2 );
1024 			else if( !(remote.sync_test_level & 2) )
1025 				font_news.disp( ZOOM_X1+10, ZOOM_Y1+30, _("Multiplayer Object Sync Error"), MAP_X2 );
1026 
1027 			vga.use_front();
1028 		}
1029 	}
1030 }
1031 //-------- End of function Sys::disp_zoom --------//
1032 
1033 
1034 //-------- Begin of function Sys::blt_virtual_buf --------//
1035 //
blt_virtual_buf()1036 void Sys::blt_virtual_buf()
1037 {
1038 	if( !sys.debug_session )
1039 		return;
1040 
1041 	//--- in a debug sesion, vga_front is not the true front buffer, now copy it to the true one ---//
1042 
1043 	int frontLocked=0;
1044 
1045 	if( vga_front.buf_locked )
1046 	{
1047 		vga_front.unlock_buf();
1048 		frontLocked=1;
1049 	}
1050 
1051 	vga_true_front.blt_virtual_buf( &vga_front );
1052 
1053 	if( frontLocked )
1054 		vga_front.lock_buf();
1055 }
1056 //--------- End of function Sys::blt_virtual_buf ---------//
1057 
1058 
1059 //-------- Begin of function Sys::disp_frames_per_second --------//
1060 //
disp_frames_per_second()1061 void Sys::disp_frames_per_second()
1062 {
1063 	if( !config.show_ai_info && !sys.disp_fps_flag )// only display this in a debug session
1064 		return;
1065 
1066 	if( game.game_mode == GAME_TUTORIAL )		// don't display in tutorial mode as it overlaps with the tutorial text
1067 		return;
1068 
1069 	//------- get the curren system time ---------//
1070 
1071 	unsigned long curTime = misc.get_time();		// in millisecond
1072 
1073 	//----------- first time calling -------------//
1074 
1075 	if( last_second_time==0 )
1076 	{
1077 		last_second_time  = curTime;
1078 		frames_in_this_second = 0;		// no. of frames displayed in this second
1079 		return;
1080 	}
1081 
1082 	//------ when passes to the next second -----//
1083 
1084 	if( curTime >= last_second_time+1000 )  // 1 second = 1000 millisecond
1085 	{
1086 		frames_per_second = frames_in_this_second;
1087 
1088 		//------ update var and reset counter -----//
1089 
1090 		last_second_time += 1000;
1091 		frames_in_this_second = 0;
1092 	}
1093 
1094 	//---------- display frame count -----------//
1095 
1096 	String str;
1097 
1098 	str  = "Frames per second: ";
1099 	str += frames_per_second;
1100 
1101 	if( frames_per_second < config.frame_speed-1 ) // -1 for rounding
1102 	{
1103 		str += " (expecting ";
1104 		str += config.frame_speed;
1105 		str += ")";
1106 	}
1107 
1108 	vga.use_back();
1109 
1110 	font_news.disp( ZOOM_X1+10, ZOOM_Y1+10, str, MAP_X2);
1111 
1112 	vga.use_front();
1113 }
1114 //--------- End of function Sys::disp_frames_per_second ---------//
1115 
1116 
1117 //--------- Begin of funtion Sys::disp_view_mode ---------//
1118 // <int> observeMode		- force observe mode display (darken view mode 1 - 7)
1119 //									needed in Game::game_end, nation_array.player_recno has not yet set to 0
disp_view_mode(int observeMode)1120 void Sys::disp_view_mode(int observeMode)
1121 {
1122 	// ------- display highlight ----------//
1123  	const int MIN_MODE_TO_DISPLAY = 1;
1124 	const int MAX_MODE_TO_DISPLAY = 8;
1125 	const int MODE_TO_DISPLAY_COUNT = MAX_MODE_TO_DISPLAY - MIN_MODE_TO_DISPLAY + 1;
1126 	static short highLightX[MODE_TO_DISPLAY_COUNT] = {  0,  62, 124, 186,  7,  68, 129, 192};
1127 	static short highLightY[MODE_TO_DISPLAY_COUNT] = {  0,   0,   0,   0, 19,  19,  19,  19};
1128 	static short darkenX[MODE_TO_DISPLAY_COUNT] = {  7,  69, 132, 195,  13,  75, 139, 201};
1129 	static short darkenY[MODE_TO_DISPLAY_COUNT] = {  8,   8,   8,   8,  29,  29,  29,  29};
1130 	const int darkenWidth = 58;
1131 	const int darkenHeight = 16;
1132 	char scrollName[] = "SCROLL-0";
1133 
1134 	// disable highlight of the mode before
1135 	scrollName[7] = 'B';
1136 	image_button.put_front( 0,0, scrollName);
1137 
1138 	// highlight of the mode after
1139 	if( view_mode >= MIN_MODE_TO_DISPLAY && view_mode <= MAX_MODE_TO_DISPLAY )
1140 	{
1141 		// find the size of that scroll
1142 		scrollName[7] = '0' + view_mode;
1143 		image_button.put_front( highLightX[view_mode-MIN_MODE_TO_DISPLAY],
1144 			highLightY[view_mode-MIN_MODE_TO_DISPLAY], scrollName);
1145 	}
1146 
1147 	// darken buttons of view mode 1-7 if nation_array.player_recno == 0
1148 	if( observeMode || !nation_array.player_recno )
1149 	{
1150 		for( int j = 1; j <= 7; ++j )
1151 		{
1152 			//if( j == view_mode)
1153 			//	continue;
1154 
1155 			vga_front.adjust_brightness(
1156 				darkenX[j-MIN_MODE_TO_DISPLAY], darkenY[j-MIN_MODE_TO_DISPLAY],
1157 				darkenX[j-MIN_MODE_TO_DISPLAY]+darkenWidth-1,
1158 				darkenY[j-MIN_MODE_TO_DISPLAY]+darkenHeight-1, -8 );
1159 		}
1160 	}
1161 }
1162 //--------- End of funtion Sys::disp_view_mode ---------//
1163