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    : OWORLD_M.CPP
22 //Description : Object MapMatrix
23 
24 #include <OVGA.h>
25 #include <OMOUSE.h>
26 #include <OIMGRES.h>
27 #include <OBUTTON.h>
28 #include <OPLANT.h>
29 #include <OTOWN.h>
30 #include <ONATION.h>
31 #include <OFIRM.h>
32 #include <OSYS.h>
33 #include <OPOWER.h>
34 #include <OGAME.h>
35 #include <OWORLD.h>
36 #include <OTERRAIN.h>
37 
38 //-------- Begin of function MapMatrix::MapMatrix ----------//
39 
MapMatrix()40 MapMatrix::MapMatrix()
41 {
42 	init( MAP_X1, MAP_Y1, MAP_X2, MAP_Y2,
43 			MAP_WIDTH, MAP_HEIGHT,
44 			MAP_LOC_WIDTH, MAP_LOC_HEIGHT, 1 );    // 1-create a background buffer
45 }
46 //---------- End of function MapMatrix::MapMatrix ----------//
47 
48 
49 //-------- Begin of function MapMatrix::~MapMatrix ----------//
50 
~MapMatrix()51 MapMatrix::~MapMatrix()
52 {
53 }
54 //---------- End of function MapMatrix::~MapMatrix ----------//
55 
56 
57 //---------- Begin of function MapMatrix::init_para ------------//
init_para()58 void MapMatrix::init_para()
59 {
60 	last_map_mode = MAP_NORMAL;
61 
62 	map_mode   = MAP_MODE_TERRAIN;
63 	power_mode = 0;
64 }
65 //---------- End of function MapMatrix::init_para ----------//
66 
67 
68 //--------- Begin of function MapMatrix::paint -----------//
69 
paint()70 void MapMatrix::paint()
71 {
72 	disp_mode_button();
73 }
74 //----------- End of function MapMatrix::paint ------------//
75 
76 
77 //------- Begin of function MapMatrix::disp_mode_button ---------//
78 //
79 // Display map mode buttons.
80 //
81 // [int] putFront - 1-display the buttons on the front buffer
82 //						  0-display the buttons on the back buffer
83 //						  (default: 0)
84 //
disp_mode_button(int putFront)85 void MapMatrix::disp_mode_button(int putFront)
86 {
87 	const char* iconName;
88 
89 	switch(map_mode)
90 	{
91 		case MAP_MODE_TERRAIN:
92 			iconName = "MAP-1";
93 			break;
94 
95 		case MAP_MODE_POWER:
96 			if( power_mode )
97 				iconName = "MAP-2B";
98 			else
99 				iconName = "MAP-2A";
100 			break;
101 
102 		case MAP_MODE_SPOT:
103 			iconName = "MAP-3";
104 			break;
105 
106 		default:
107 			err_here();
108 	}
109 
110 	if( putFront )
111 		image_button.put_front( 579, 2, iconName, 1 );
112 	else
113 		image_button.put_back( 579, 2, iconName, 1 );
114 }
115 //----------- End of function MapMatrix::disp_mode_button ------------//
116 
117 
118 //--------- Begin of function MapMatrix::detect ------------//
119 
detect()120 int MapMatrix::detect()
121 {
122 	int x=586;
123 
124 	#define MAP_MODE_BUTTON_WIDTH 40
125 
126 	for( int i=0 ; i<MAP_MODE_COUNT ; i++, x+=MAP_MODE_BUTTON_WIDTH )
127 	{
128 		if( mouse.single_click(	x, 7, x+MAP_MODE_BUTTON_WIDTH-1, 46 ) )
129 		{
130 			toggle_map_mode(i);
131 			return 1;
132 		}
133 	}
134 
135 	//----- detect clicking on the map -------//
136 
137 	return detect_area();
138 }
139 //---------- End of function MapMatrix::detect ------------//
140 
141 
142 //---------- Begin of function MapMatrix::draw ------------//
143 //
144 // Draw world map
145 //
draw()146 void MapMatrix::draw()
147 {
148 	draw_map();
149 
150 	//------- save it to the buffer for later reuse ------//
151 
152 	if( save_image_buf )
153 	{
154 		vga_back.read_bitmap( image_x1, image_y1, image_x2, image_y2, save_image_buf );
155 		just_drawn_flag = 1;
156 	}
157 }
158 //------------ End of function MapMatrix::draw ------------//
159 
160 
161 //---------- Begin of function MapMatrix::draw_map ------------//
162 // see also World::explore
163 //
draw_map()164 void MapMatrix::draw_map()
165 {
166 	char* 	 writePtr  = vga_back.buf_ptr() + vga_back.buf_pitch() * image_y1 + image_x1;
167 	int   	 lineRemain = vga_back.buf_pitch() - image_width;
168 	int 		 x, y;
169 	Location* locPtr = world.loc_matrix;
170 	char*     nationColorArray = nation_array.nation_power_color_array;
171 
172 	//----------- draw map now ------------//
173 
174 	sys.yield();
175 
176 	int		 shadowMapDist = max_x_loc + 1;
177 	int		 tileYOffset;
178 	char		 tilePixel;
179 	Location* northWestPtr;
180 
181 	switch(map_mode)
182 	{
183 	case MAP_MODE_TERRAIN:
184 		for( y=image_y1 ; y<=image_y2 ; y++, writePtr+=lineRemain )
185 		{
186 			tileYOffset = (y & TERRAIN_TILE_Y_MASK) * TERRAIN_TILE_WIDTH;
187 
188 			for( x=image_x1 ; x<=image_x2 ; x++, writePtr++, locPtr++ )
189 			{
190 				if( locPtr->explored() )
191 				{
192 					if( locPtr->fire_str() > 0)
193 						*writePtr = (char) FIRE_COLOR;
194 
195 					else if( locPtr->is_plant() )
196 						*writePtr = plant_res.plant_map_color;
197 
198 					else
199 					{
200 						tilePixel = terrain_res.get_map_tile(locPtr->terrain_id)[tileYOffset + (x & TERRAIN_TILE_X_MASK)];
201 
202 						if( y == image_y1 || x == image_x1)
203 						{
204 							*writePtr = tilePixel;
205 						}
206 						else
207 						{
208 							northWestPtr = locPtr - shadowMapDist;
209 
210 							if( terrain_res[locPtr->terrain_id]->average_type >=
211 								terrain_res[northWestPtr->terrain_id]->average_type)
212 							{
213 								*writePtr = tilePixel;
214 							}
215 							else
216 							{
217 								*writePtr = (char) VGA_GRAY;
218 							}
219 						}
220 					}
221 				}
222 				else
223 				{
224 					*writePtr = UNEXPLORED_COLOR;
225 				}
226 			}
227 		}
228 		break;
229 
230 	case MAP_MODE_SPOT:
231 		for( y=image_y1 ; y<=image_y2 ; y++, writePtr+=lineRemain )
232 		{
233 			for( x=image_x1 ; x<=image_x2 ; x++, writePtr++, locPtr++ )
234 			{
235 				if( locPtr->explored() )
236 				{
237 					if( locPtr->sailable() )
238 						*writePtr = (char) 0x32;
239 
240 					else if( locPtr->has_hill() )
241 						*writePtr = (char) V_BROWN;
242 
243 //					else if( locPtr->is_plant() )
244 //						*writePtr = (char) V_DARK_GREEN;
245 
246 					else
247 						*writePtr = (char) VGA_GRAY+10;
248 				}
249 				else
250 				{
251 					*writePtr = UNEXPLORED_COLOR;
252 				}
253 			}
254 		}
255 		break;
256 
257 	case MAP_MODE_POWER:
258 		for( y=image_y1 ; y<=image_y2 ; y++, writePtr+=lineRemain )
259 		{
260 			for( x=image_x1 ; x<=image_x2 ; x++, writePtr++, locPtr++ )
261 			{
262 				if( locPtr->explored() )
263 				{
264 					if( locPtr->sailable() )
265 						*writePtr = (char) 0x32;
266 
267 					else if( locPtr->has_hill() )
268 						*writePtr = (char) V_BROWN;
269 
270 					else if( locPtr->is_plant() )
271 						*writePtr = (char) V_DARK_GREEN;
272 
273 					else
274 						*writePtr = nationColorArray[locPtr->power_nation_recno];
275 				}
276 				else
277 				{
278 					*writePtr = UNEXPLORED_COLOR;
279 				}
280 			}
281 		}
282 		break;
283 	}
284 
285 	sys.yield();
286 }
287 //------------ End of function MapMatrix::draw_map ------------//
288 
289 
290 //----------- Begin of function MapMatrix::disp ------------//
291 //
292 // Display the drawn world map on screen, update the location
293 // of the map-to-zoom area box.
294 //
disp()295 void MapMatrix::disp()
296 {
297 	if( !just_drawn_flag )		// if the map has just been drawn in draw()
298 	{
299 		if( save_image_buf && map_mode==last_map_mode )
300 			vga_back.put_bitmap( image_x1, image_y1, save_image_buf );
301 		else
302 		{
303 			draw();
304 			last_map_mode = map_mode;
305 		}
306 	}
307 
308 	just_drawn_flag=0;
309 }
310 //----------- End of function MapMatrix::disp ------------//
311 
312 
313 //----------- Begin of function MapMatrix::draw_square ------------//
314 //
315 // Calling sequences:
316 //
317 // 1. MapMatrix::disp()
318 // 2. SpriteArray::draw()
319 // 3. MapMatrix::draw_square()
320 //
draw_square()321 void MapMatrix::draw_square()
322 {
323 	//-------- draw the map-to-zoom highlight box --------//
324 
325 	static int squareFrameCount=0, squareFrameStep=1;
326 
327 	int x1=image_x1+(cur_x_loc-top_x_loc)*loc_width;
328 	int y1=image_y1+(cur_y_loc-top_y_loc)*loc_height;
329 	int x2=x1+cur_cargo_width *loc_width-1;
330 	int y2=y1+cur_cargo_height*loc_height-1;
331 
332 	vga_back.rect( x1, y1, x2, y2, 1, VGA_YELLOW + squareFrameCount );
333 
334 	squareFrameCount += squareFrameStep;
335 
336 	if( squareFrameCount==0 )  // color with smaller number is brighter
337 		squareFrameStep  = 1;
338 
339 	if( squareFrameCount==6 ) // bi-directional color shift
340 		squareFrameStep  = -1;
341 }
342 //----------- End of function MapMatrix::draw_square ------------//
343 
344 
345 //-------- Begin of function MapMatrix::toggle_map_mode ------------//
346 
toggle_map_mode(int modeId)347 void MapMatrix::toggle_map_mode(int modeId)
348 {
349 	if( map_mode == modeId )
350 	{
351 		if( map_mode == MAP_MODE_POWER )		// clicking on a pressed button unclick the button
352 			power_mode = !power_mode;
353 	}
354 	else
355 	{
356 		map_mode = modeId;
357 	}
358 
359 	disp_mode_button(1);		// 1-display the buttons on the front buffer.
360 
361 	refresh();
362 }
363 //---------- End of function MapMatrix::toggle_map_mode ------------//
364 
365 
366 //-------- Begin of function MapMatrix::cycle_map_mode ------------//
367 
cycle_map_mode()368 void MapMatrix::cycle_map_mode()
369 {
370 	//--- Cycle through all available map modes ---//
371 
372 	if( map_mode == MAP_MODE_POWER && !power_mode)
373 		power_mode = !power_mode;
374 	else
375 	{
376 		map_mode = (map_mode + 1) % 3;
377 		if (map_mode == MAP_MODE_POWER)
378 			power_mode = 0;
379 	}
380 
381 	disp_mode_button(1);		// 1-display the buttons on the front buffer.
382 
383 	refresh();
384 }
385 //---------- End of function MapMatrix::cycle_map_mode ------------//
386 
387 
388 //----------- Begin of function MapMatrix::detect_area -----------//
389 //
390 // Detect for click on a new zoom area, update the zoom window as well
391 //
392 // return : 0 - no action
393 //          1 - pressed on new cargo
394 //          2 - pressed on new cargo and also scrolled window
395 //
detect_area()396 int MapMatrix::detect_area()
397 {
398 	if( !mouse.press_area( image_x1,image_y1,image_x2,image_y2, 2 ) &&
399 		 !mouse.any_click( image_x1,image_y1,image_x2,image_y2, 2 ) )
400 	{
401 		return 0;
402 	}
403 
404 	int rc = 0;
405 
406 	int lastXLoc = cur_x_loc;
407 	int lastYLoc = cur_y_loc;
408 
409 	//--- if press left button, select zoom area ----//
410 
411 	if( mouse.single_click( image_x1,image_y1,image_x2,image_y2 ) ||
412 		 mouse.press_area( image_x1,image_y1,image_x2,image_y2, LEFT_BUTTON ) )
413 	{
414 		int xLoc = top_x_loc + (mouse.cur_x-image_x1)/loc_width;
415 		int yLoc = top_y_loc + (mouse.cur_y-image_y1)/loc_height;
416 
417 		//-- if only single click, don't highlight new firm, only new area --//
418 
419 		cur_x_loc = xLoc - world.zoom_matrix->disp_x_loc/2;
420 		cur_y_loc = yLoc - world.zoom_matrix->disp_y_loc/2;
421 
422 		if( !valid_cur_box() )    // valid_cur_box() return 1 if it has refreshed, 0 if didn't
423 			disp();
424 
425 		rc=1;
426 	}
427 
428 	//------- if the view area has been changed -------//
429 
430 	if( cur_x_loc != lastXLoc || cur_y_loc != lastYLoc )
431 	{
432 		world.zoom_matrix->top_x_loc = cur_x_loc;
433 		world.zoom_matrix->top_y_loc = cur_y_loc;
434 
435 		sys.zoom_need_redraw = 1;
436 	}
437 
438 	return rc;
439 }
440 //------------ End of function MapMatrix::detect_area ----------//
441 
442 
443