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