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 : OWALLRES.CPP
22 //Description : Wall resource object
23 //Ownership : Gilbert
24
25 #include <OSYS.h>
26 #include <OVGA.h>
27 #include <OFONT.h>
28 #include <OGAMESET.h>
29 #include <OWORLD.h>
30 #include <ONATION.h>
31 #include <WALLTILE.h>
32 #include <OWALLRES.h>
33
34 //---------- #define constant ------------//
35
36 #define WALL_DB "WALL"
37
38 //------- Begin of function WallRes::WallRes -----------//
39
WallRes()40 WallRes::WallRes()
41 {
42 init_flag=0;
43
44 selected_x_loc = -1;
45 selected_y_loc = -1;
46 }
47 //--------- End of function WallRes::WallRes -----------//
48
49
50 //---------- Begin of function WallRes::init -----------//
51 //
52 // This function must be called after a map is generated.
53 //
init()54 void WallRes::init()
55 {
56 deinit();
57
58 //----- open wall material bitmap resource file -------//
59
60 String str;
61
62 str = DIR_RES;
63 str += "I_WALL.RES";
64
65 res_bitmap.init_imported(str,1); // 1-read all into buffer
66
67 //------- load database information --------//
68
69 load_wall_info();
70
71 init_flag=1;
72 }
73 //---------- End of function WallRes::init -----------//
74
75
76 //---------- Begin of function WallRes::deinit -----------//
77
deinit()78 void WallRes::deinit()
79 {
80 if( init_flag )
81 {
82 mem_del(wall_info_array);
83 mem_del(wall_index);
84 init_flag=0;
85 }
86 }
87 //---------- End of function WallRes::deinit -----------//
88
89
90 //------- Begin of function WallRes::load_wall_info -------//
91 //
load_wall_info()92 void WallRes::load_wall_info()
93 {
94 WallRec *wallRec;
95 WallInfo *wallInfo;
96 int i;
97 uint32_t bitmapOffset;
98
99 max_wall_id = 0;
100
101 //---- read in wall count and initialize wall info array ----//
102
103 Database *dbWall = game_set.open_db(WALL_DB); // only one database can be opened at a time, so we read FIRM.DBF first
104
105 wall_count = (short) dbWall->rec_count();
106 wall_info_array = (WallInfo*) mem_add( sizeof(WallInfo)*wall_count );
107
108 memset( wall_info_array, 0, sizeof(WallInfo) * wall_count );
109
110 //---------- read in WALL.DBF ---------//
111
112 for( i=0 ; i<wall_count ; i++ )
113 {
114 wallRec = (WallRec*) dbWall->read(i+1);
115 wallInfo = wall_info_array+i;
116
117 wallInfo->wall_id = misc.atoi(wallRec->wall_id, wallRec->WALL_ID_LEN);
118 wallInfo->flags = 0;
119 if( wallRec->gate_flag == 'Y' || wallRec->gate_flag == 'y')
120 wallInfo->set_gate();
121 if( wallRec->trans_flag == 'Y' || wallRec->trans_flag == 'y')
122 wallInfo->set_trans();
123 wallInfo->offset_x = misc.atoi(wallRec->offset_x, wallRec->OFFSET_LEN);
124 wallInfo->offset_y = misc.atoi(wallRec->offset_y, wallRec->OFFSET_LEN);
125 wallInfo->loc_off_x = misc.atoi(wallRec->loc_off_x, wallRec->LOC_OFF_LEN);
126 wallInfo->loc_off_y = misc.atoi(wallRec->loc_off_y, wallRec->LOC_OFF_LEN);
127
128 wallInfo->draw_wall_id = misc.atoi(wallRec->draw_wall, wallRec->WALL_ID_LEN);
129
130 memcpy( &bitmapOffset, wallRec->bitmap_ptr, sizeof(uint32_t) );
131 wallInfo->bitmap_ptr = res_bitmap.read_imported(bitmapOffset);
132
133 if( wallInfo->wall_id > max_wall_id)
134 max_wall_id = wallInfo->wall_id;
135 }
136
137 // --------- build wall_index ---------//
138 if( max_wall_id > 0)
139 {
140 wall_index = (WallInfo **) mem_add(sizeof(WallInfo *) * max_wall_id);
141 memset( wall_index, 0, sizeof(WallInfo *) * max_wall_id);
142 for( i=0 ; i<wall_count ; i++ )
143 {
144 wall_index[wall_info_array[i].wall_id -1] = &wall_info_array[i];
145 }
146 }
147 else
148 {
149 err.run("No wall database found");
150 }
151 }
152 //--------- End of function WallRes::load_wall_info ---------//
153
154
155 //------- Begin of function WallRes::draw_selected -------//
156 //
draw_selected()157 void WallRes::draw_selected()
158 {
159 if( selected_x_loc < 0 )
160 return;
161
162 int x = selected_x_loc * ZOOM_LOC_WIDTH;
163 int y = selected_y_loc * ZOOM_LOC_HEIGHT;
164
165 x = x - World::view_top_x + ZOOM_X1;
166 y = y - World::view_top_y + ZOOM_Y1;
167
168 //------------ draw the square frame now ------------//
169
170 if( misc.is_touch( x, y, x, x, ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2 ) )
171 {
172 vga_back.rect( x, y, x+ZOOM_LOC_WIDTH-1, y+ZOOM_LOC_HEIGHT-1, 1, OWN_SELECT_FRAME_COLOR );
173 }
174 }
175 //--------- End of function WallRes::draw_selected ---------//
176
177
178 //------- Begin of function WallRes::disp_info -------//
179 //
disp_info(int refreshFlag)180 void WallRes::disp_info(int refreshFlag)
181 {
182 if( selected_x_loc < 0 )
183 return;
184
185 if( refreshFlag == INFO_REPAINT )
186 {
187 font_san.d3_put( INFO_X1, INFO_Y1, INFO_X2, INFO_Y1+17, "Defense Wall" );
188 vga_front.d3_panel_up( INFO_X1, INFO_Y1+20, INFO_X2, INFO_Y1+40, 1 );
189 }
190
191 int x=INFO_X1+3, y=INFO_Y1+23;
192 Location* locPtr = world.get_loc( selected_x_loc, selected_y_loc );
193
194 String str;
195
196 str = locPtr->wall_abs_hit_point();
197 str += " / 100";
198
199 font_san.field( x, y, "Hit Points", x+80, str, INFO_X2-4, refreshFlag );
200 }
201 //--------- End of function WallRes::disp_info ---------//
202
203
204 //---------- Begin of function WallRes::operator[] -----------//
205
operator [](int wallId)206 WallInfo* WallRes::operator[](int wallId)
207 {
208 err_if( wallId<1 || wallId>max_wall_id )
209 err_now( "WallRes::operator[]" );
210
211 return wall_index[wallId-1];
212 }
213 //------------ End of function WallRes::operator[] -----------//
214
215 //------- Begin of function WallInfo::draw -----------//
216 //
217 // Draw the current wall on the map
218 //
draw(int xLoc,int yLoc,char * remapTbl)219 void WallInfo::draw(int xLoc, int yLoc, char *remapTbl)
220 {
221 //----------- calculate absolute positions ------------//
222 //-------- check if the wall is within the view area --------//
223
224 int x1 = xLoc*ZOOM_LOC_WIDTH + offset_x - World::view_top_x;
225 int x2 = x1 + bitmap_width() -1;
226 if( x2 < 0 || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
227 return;
228
229 int y1 = yLoc*ZOOM_LOC_HEIGHT +offset_y - World::view_top_y;
230 int y2 = y1 + bitmap_height() -1;
231 if( y2 < 0 || y1 >= ZOOM_HEIGHT )
232 return;
233
234 //------- decide which approach to use for displaying -----//
235 //---- only portion of the sprite is inside the view area ------//
236
237 if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
238 {
239 if(is_trans())
240 {
241 if( remapTbl)
242 vga_back.put_bitmap_area_trans_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
243 MAX(0,x1)-x1, MAX(0,y1)-y1, MIN(ZOOM_WIDTH-1,x2)-x1, MIN(ZOOM_HEIGHT-1,y2)-y1,
244 remapTbl);
245 else
246 vga_back.put_bitmap_area_trans( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
247 MAX(0,x1)-x1, MAX(0,y1)-y1, MIN(ZOOM_WIDTH-1,x2)-x1, MIN(ZOOM_HEIGHT-1,y2)-y1);
248 }
249 else
250 {
251 if( remapTbl)
252 vga_back.put_bitmap_area_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
253 MAX(0,x1)-x1, MAX(0,y1)-y1, MIN(ZOOM_WIDTH-1,x2)-x1, MIN(ZOOM_HEIGHT-1,y2)-y1,
254 remapTbl);
255 else
256 vga_back.put_bitmap_area( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
257 MAX(0,x1)-x1, MAX(0,y1)-y1, MIN(ZOOM_WIDTH-1,x2)-x1, MIN(ZOOM_HEIGHT-1,y2)-y1);
258 }
259 }
260
261 //---- the whole sprite is inside the view area ------//
262 else
263 {
264 if(is_trans() )
265 {
266 if( remapTbl)
267 vga_back.put_bitmap_trans_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr, remapTbl);
268 else
269 vga_back.put_bitmap_trans( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr);
270 }
271 else
272 {
273 if( remapTbl)
274 vga_back.put_bitmap_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr, remapTbl );
275 else
276 vga_back.put_bitmap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr);
277 }
278 }
279 }
280 //--------- End of function WallInfo::draw -----------//
281
282
283 //------- Begin of function WallInfo::draw_at -----------//
284 //
285 // Draw the wall on the zoom map, given the exact pixel position to put
286 // the bitmap.
287 //
288 // <int> absBaseX, absBaseY - the absolute base (center-bottom) coordination
289 // of the building.
290 //
291 // Draw the current plant on the map
292 //
draw_at(int absBaseX,int absBaseY,char * remapTbl)293 void WallInfo::draw_at(int absBaseX, int absBaseY, char *remapTbl)
294 {
295 //-------- check if the wall is within the view area --------//
296
297 int x1 = absBaseX - World::view_top_x;
298 int x2 = x1 + bitmap_width() -1;
299 if( x2 < 0 || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
300 return;
301
302 int y1 = absBaseY - World::view_top_y;
303 int y2 = y1 + bitmap_height() -1;
304 if( y2 < 0 || y1 >= ZOOM_HEIGHT )
305 return;
306
307 //------- decide which approach to use for displaying -----//
308 //---- only portion of the sprite is inside the view area ------//
309
310 if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
311 {
312 // no put_bitmap_area_remap
313 if(is_trans())
314 {
315 if( remapTbl)
316 vga_back.put_bitmap_area_trans_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
317 MAX(0,x1)-x1, MAX(0,y1)-y1, MIN(ZOOM_WIDTH-1,x2)-x1, MIN(ZOOM_HEIGHT-1,y2)-y1,
318 remapTbl);
319 else
320 vga_back.put_bitmap_area_trans( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
321 MAX(0,x1)-x1, MAX(0,y1)-y1, MIN(ZOOM_WIDTH-1,x2)-x1, MIN(ZOOM_HEIGHT-1,y2)-y1);
322 }
323 else
324 {
325 if( remapTbl)
326 vga_back.put_bitmap_area_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
327 MAX(0,x1)-x1, MAX(0,y1)-y1, MIN(ZOOM_WIDTH-1,x2)-x1, MIN(ZOOM_HEIGHT-1,y2)-y1,
328 remapTbl);
329 else
330 vga_back.put_bitmap_area( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
331 MAX(0,x1)-x1, MAX(0,y1)-y1, MIN(ZOOM_WIDTH-1,x2)-x1, MIN(ZOOM_HEIGHT-1,y2)-y1);
332
333 }
334 }
335
336 //---- the whole sprite is inside the view area ------//
337 else
338 {
339 if(is_trans() )
340 {
341 if( remapTbl)
342 vga_back.put_bitmap_trans_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr, remapTbl);
343 else
344 vga_back.put_bitmap_trans( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr);
345 }
346 else
347 {
348 if( remapTbl)
349 vga_back.put_bitmap_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr, remapTbl );
350 else
351 vga_back.put_bitmap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr);
352 }
353 }
354 }
355 //--------- End of function WallInfo::draw_at -----------//
356
357