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 : OFIRMDIE.CPP
22 // Description : destruting firm
23
24
25 #include <OSTR.h>
26 #include <OFIRMRES.h>
27 #include <OFIRMDIE.h>
28 #include <OGAMESET.h>
29 #include <OGAME.h>
30 #include <ORESDB.h>
31 #include <ALL.h>
32
33
34 #define FIRM_BUILD_DB "FDBUILD"
35 #define FIRM_FRAME_DB "FDFRAME"
36 #define FIRM_BITMAP_DB "FDBITMAP"
37
38
39 struct FirmDieBitmap : public FirmBitmap
40 {
41 int bitmap_offset; // fill bitmap_ptr, width and height before draw()
42 };
43
FirmDieRes()44 FirmDieRes::FirmDieRes()
45 {
46 firm_build_count = 0;
47 firm_bitmap_count = 0;
48 firm_build_array = NULL;
49 firm_bitmap_array = NULL;
50 init_flag = 0;
51 }
52
~FirmDieRes()53 FirmDieRes::~FirmDieRes()
54 {
55 deinit();
56 }
57
init()58 void FirmDieRes::init()
59 {
60 deinit();
61
62 //----- open firm material bitmap resource file -------//
63
64 String str;
65
66 str = DIR_RES;
67 str += "I_FIRMDI.RES";
68
69 res_bitmap.init_imported(str,0,1); // 0 - do not read all data into buffer
70
71 //------- load database information --------//
72
73 load_bitmap_info(); // call load_firm_bitmap() first as load_firm_info() will need info loaded by load_firm_bitmap()
74 load_build_info();
75
76 //----------------------------------------//
77
78 init_flag=1;
79 }
80
deinit()81 void FirmDieRes::deinit()
82 {
83 if(init_flag)
84 {
85 mem_del(firm_build_array);
86 mem_del(firm_bitmap_array);
87
88 res_bitmap.deinit();
89
90 init_flag = 0;
91 }
92 }
93
94
95 //------- Begin of function FirmDieRes::load_firm_bitmap -------//
96 //
97 // Read in information of FDBITMAP.DBF into memory array
98 //
load_bitmap_info()99 void FirmDieRes::load_bitmap_info()
100 {
101 FirmBitmapRec *firmBitmapRec;
102 FirmDieBitmap *firmBitmap;
103 int i;
104 uint32_t bitmapOffset;
105 Database *dbFirmBitmap = game_set.open_db(FIRM_BITMAP_DB);
106
107 firm_bitmap_count = (short) dbFirmBitmap->rec_count();
108 firm_bitmap_array = (FirmDieBitmap*) mem_add( sizeof(FirmDieBitmap)*firm_bitmap_count );
109
110 //------ read in firm bitmap info array -------//
111
112 memset( firm_bitmap_array, 0, sizeof(FirmDieBitmap) * firm_bitmap_count );
113
114 for( i=0 ; i<firm_bitmap_count ; i++ )
115 {
116 firmBitmapRec = (FirmBitmapRec*) dbFirmBitmap->read(i+1);
117 firmBitmap = firm_bitmap_array+i;
118
119 memcpy( &bitmapOffset, firmBitmapRec->bitmap_ptr, sizeof(uint32_t) );
120
121 // BUGHERE : bitmap is not yet loaded into memory, fill them before draw()
122 firmBitmap->bitmap_ptr = NULL;
123 firmBitmap->width = 0;
124 firmBitmap->height = 0;
125
126 firmBitmap->offset_x = misc.atoi( firmBitmapRec->offset_x, firmBitmapRec->OFFSET_LEN );
127 firmBitmap->offset_y = misc.atoi( firmBitmapRec->offset_y, firmBitmapRec->OFFSET_LEN );
128
129 firmBitmap->loc_width = misc.atoi( firmBitmapRec->loc_width , firmBitmapRec->LOC_LEN );
130 firmBitmap->loc_height = misc.atoi( firmBitmapRec->loc_height, firmBitmapRec->LOC_LEN );
131 firmBitmap->display_layer = firmBitmapRec->layer - '0';
132
133 firmBitmap->bitmap_offset = bitmapOffset;
134 }
135 }
136 //--------- End of function FirmDieRes::load_firm_bitmap ---------//
137
138
139 //------- Begin of function FirmDieRes::load_firm_build -------//
140 //
141 // Read in information of FIRM.DBF into memory array
142 //
load_build_info()143 void FirmDieRes::load_build_info()
144 {
145 FirmBuildRec *firmBuildRec;
146 FirmFrameRec *firmFrameRec;
147 FirmBuild *firmBuild;
148 FirmBitmap *firmBitmap;
149 int i, j, k, frameRecno, bitmapRecno;
150 short *firstFrameArray;
151
152 //---- read in firm count and initialize firm info array ----//
153
154 Database *dbFirmBuild = game_set.open_db(FIRM_BUILD_DB); // only one database can be opened at a time, so we read FIRM.DBF first
155
156 firm_build_count = (short) dbFirmBuild->rec_count();
157 firm_build_array = (FirmBuild*) mem_add( sizeof(FirmBuild)*firm_build_count );
158
159 memset( firm_build_array, 0, sizeof(FirmBuild) * firm_build_count );
160
161 //------ allocate an array for storing firstFrameRecno -----//
162
163 firstFrameArray = (short*) mem_add( sizeof(short) * firm_build_count );
164
165 //---------- read in FDBUILD.DBF ---------//
166
167 for( i=0 ; i<firm_build_count ; i++ )
168 {
169 firmBuildRec = (FirmBuildRec*) dbFirmBuild->read(i+1);
170 firmBuild = firm_build_array+i;
171
172 misc.rtrim_fld( firmBuild->build_code, firmBuildRec->race_code, firmBuild->BUILD_CODE_LEN );
173
174 firmBuild->animate_full_size = firmBuildRec->animate_full_size=='1';
175
176 firmBuild->race_id = misc.atoi( firmBuildRec->race_id, firmBuildRec->RACE_ID_LEN );
177 firmBuild->frame_count = misc.atoi( firmBuildRec->frame_count, firmBuildRec->FRAME_COUNT_LEN );
178
179 firmBuild->under_construction_bitmap_recno = misc.atoi(firmBuildRec->under_construction_bitmap_recno, firmBuildRec->BITMAP_RECNO_LEN);
180 firmBuild->idle_bitmap_recno = misc.atoi(firmBuildRec->idle_bitmap_recno, firmBuildRec->BITMAP_RECNO_LEN);
181 firmBuild->ground_bitmap_recno = misc.atoi(firmBuildRec->ground_bitmap_recno, firmBuildRec->BITMAP_RECNO_LEN);
182
183 err_when( firmBuild->frame_count > MAX_FIRM_FRAME );
184
185 firstFrameArray[i] = misc.atoi( firmBuildRec->first_frame, firmBuildRec->FIRST_FRAME_LEN );
186
187 // BUGHERE : need to compare same Firm name and build code in firm database
188 }
189
190 //-------- read in FDFRAME.DBF --------//
191
192 Database *dbFirmFrame = game_set.open_db(FIRM_FRAME_DB);
193 int minOffsetX, minOffsetY;
194 int maxX2, maxY2;
195
196 for( i=0 ; i<firm_build_count ; i++ )
197 {
198 firmBuild = firm_build_array+i;
199 frameRecno = firstFrameArray[i];
200
201 minOffsetX = minOffsetY = 0xFFFF;
202 maxX2 = maxY2 = 0;
203
204 for( j=0 ; j<firmBuild->frame_count ; j++, frameRecno++ )
205 {
206 firmFrameRec = (FirmFrameRec*) dbFirmFrame->read(frameRecno);
207
208 //------ following animation frames, bitmap sections -----//
209
210 firmBuild->first_bitmap_array[j] = misc.atoi( firmFrameRec->first_bitmap, firmFrameRec->FIRST_BITMAP_LEN );
211 firmBuild->bitmap_count_array[j] = misc.atoi( firmFrameRec->bitmap_count, firmFrameRec->BITMAP_COUNT_LEN );
212
213 firmBuild->frame_delay_array[j] = misc.atoi( firmFrameRec->delay, firmFrameRec->DELAY_LEN );
214
215 //---- get the MIN offset_x, offset_y and MAX width, height ----//
216 //
217 // So we can get the largest area of all the frames in this building
218 // and this will serve as a normal size setting for this building,
219 // with variation from frame to frame
220 //
221 //--------------------------------------------------------------//
222
223 firmBitmap = firm_bitmap_array + firmBuild->first_bitmap_array[j] - 1;
224
225 for( k=firmBuild->bitmap_count_array[j] ; k>0 ; k--, firmBitmap++ )
226 {
227 if( firmBitmap->offset_x < minOffsetX )
228 minOffsetX = firmBitmap->offset_x;
229
230 if( firmBitmap->offset_y < minOffsetY )
231 minOffsetY = firmBitmap->offset_y;
232
233 if( firmBitmap->offset_x + firmBitmap->width > maxX2 )
234 maxX2 = firmBitmap->offset_x + firmBitmap->width;
235
236 if( firmBitmap->offset_y + firmBitmap->height > maxY2 )
237 maxY2 = firmBitmap->offset_y + firmBitmap->height;
238 }
239 }
240
241 //------- set FirmBuild Info -------//
242
243 bitmapRecno = firmBuild->first_bitmap_array[0];
244
245 //----- get the info of the first frame bitmap ----//
246
247 firmBitmap = firm_bitmap_array + bitmapRecno - 1;
248
249 firmBuild->loc_width = firmBitmap->loc_width;
250 firmBuild->loc_height = firmBitmap->loc_height;
251
252 firmBuild->min_offset_x = minOffsetX;
253 firmBuild->min_offset_y = minOffsetY;
254
255 firmBuild->max_bitmap_width = maxX2 - minOffsetX;
256 firmBuild->max_bitmap_height = maxY2 - minOffsetY;
257
258 //------ set firmBuild's under construction and idle bitmap recno -----//
259
260 if( firmBuild->under_construction_bitmap_recno==0 )
261 firmBuild->under_construction_bitmap_recno = bitmapRecno;
262
263 if( firmBuild->idle_bitmap_recno==0 )
264 firmBuild->idle_bitmap_recno = bitmapRecno;
265 }
266
267 //------ free up the temporary array -------//
268
269 mem_del( firstFrameArray );
270 }
271 //--------- End of function FirmDieRes::load_firm_build ---------//
272
273
274 //--------- Begin of function FirmDieRes::get_build ---------//
get_build(int buildId)275 FirmBuild* FirmDieRes::get_build(int buildId)
276 {
277 err_when( buildId < 1 || buildId > firm_build_count);
278 return firm_build_array+buildId-1;
279 }
280 //--------- End of function FirmDieRes::get_build ---------//
281
282
283 //--------- Begin of function FirmDieRes::get_bitmap ---------//
get_bitmap(int bitmapId)284 FirmDieBitmap* FirmDieRes::get_bitmap(int bitmapId)
285 {
286 err_when( bitmapId < 1 || bitmapId > firm_bitmap_count);
287 return firm_bitmap_array+bitmapId-1;
288 }
289 //--------- End of function FirmDieRes::get_bitmap ---------//
290
291
292 //--------- Begin of function FirmDie::init --------//
init(short firmId,short firmBuildId,short nationRecno,short locX1,short locY1,short locX2,short locY2)293 void FirmDie::init(short firmId, short firmBuildId, short nationRecno,
294 short locX1, short locY1, short locX2, short locY2)
295 {
296 firm_id = firmId;
297 firm_build_id = firmBuildId;
298 nation_recno = nationRecno;
299 loc_x1 = locX1;
300 loc_y1 = locY1;
301 loc_x2 = locX2;
302 loc_y2 = locY2;
303 frame = 1;
304 }
305
306 // add before delete the firm
init(Firm * firmPtr)307 void FirmDie::init(Firm *firmPtr)
308 {
309 firm_id = firmPtr->firm_id;
310 firm_build_id = firmPtr->firm_build_id;
311 nation_recno = firmPtr->nation_recno;
312 loc_x1 = firmPtr->loc_x1;
313 loc_y1 = firmPtr->loc_y1;
314 loc_x2 = firmPtr->loc_x2;
315 loc_y2 = firmPtr->loc_y2;
316 frame = 1;
317 frame_delay_count = 0;
318 }
319
320
321
pre_process()322 void FirmDie::pre_process()
323 {
324 //nothing
325 }
326
process()327 int FirmDie::process()
328 {
329 FirmBuild *firmBuild = firm_die_res.get_build(firm_build_id);
330 if( ++frame_delay_count > firmBuild->frame_delay_array[frame-1])
331 {
332 frame_delay_count = 0;
333 if( ++frame > firmBuild->frame_count)
334 {
335 return 1;
336 }
337 }
338 return 0;
339 }
340
341
draw(int displayLayer)342 void FirmDie::draw(int displayLayer)
343 {
344 // get ground dirt from firm_res
345 FirmBuild* firmBuild = firm_res.get_build(firm_build_id);
346
347 if( firmBuild->ground_bitmap_recno )
348 {
349 // firm_res.get_bitmap(firmBuild->ground_bitmap_recno)
350 // ->draw_at(loc_x1*ZOOM_LOC_WIDTH, loc_y1*ZOOM_LOC_HEIGHT, NULL, displayLayer);
351 }
352
353 //---------- draw animation now ------------//
354
355 firmBuild = firm_die_res.get_build(firm_build_id);
356 FirmDieBitmap* firmBitmap;
357
358 int bitmapRecno, i;
359 int firstBitmap = firmBuild->first_bitmap(frame);
360 int bitmapCount = firmBuild->bitmap_count(frame);
361
362 char* colorRemapTable = game.get_color_remap_table(nation_recno, 0);
363
364 for( i=0, bitmapRecno=firstBitmap ; i<bitmapCount ; i++, bitmapRecno++ )
365 {
366 firmBitmap = firm_die_res.get_bitmap(bitmapRecno);
367
368 // BUGHERE : need to load bitmap into memory
369 if( firmBitmap )
370 {
371 char *bitmapPtr;
372 firmBitmap->bitmap_ptr = bitmapPtr = firm_die_res.res_bitmap.read_imported(firmBitmap->bitmap_offset);
373 firmBitmap->width = *(short *)bitmapPtr;
374 firmBitmap->height= *(1+(short *)bitmapPtr);
375 firmBitmap->draw_at(loc_x1*ZOOM_LOC_WIDTH, loc_y1*ZOOM_LOC_HEIGHT, colorRemapTable, displayLayer);
376 }
377 }
378 }
379
380
FirmDieArray()381 FirmDieArray::FirmDieArray() : DynArrayB(sizeof(FirmDie),10, DEFAULT_REUSE_INTERVAL_DAYS)
382 {
383 // nothing
384 }
385
~FirmDieArray()386 FirmDieArray::~FirmDieArray()
387 {
388 deinit();
389 }
390
init()391 void FirmDieArray::init()
392 {
393 zap();
394 }
395
deinit()396 void FirmDieArray::deinit()
397 {
398 // nothing
399 }
400
process()401 void FirmDieArray::process()
402 {
403 int i, j;
404
405 for( i=1, j=size(); j; --j, ++i)
406 {
407 if( is_deleted(i) )
408 continue;
409
410 FirmDie *firmDiePtr = this->operator[](i);
411
412 if( firmDiePtr->process() )
413 {
414 del(i);
415 continue;
416 }
417 }
418 }
419
420
421
add(FirmDie * r)422 int FirmDieArray::add(FirmDie *r)
423 {
424 linkin(r);
425 return recno();
426 }
427
del(int i)428 void FirmDieArray::del(int i)
429 {
430 linkout(i);
431 }
432
433
operator [](int recNo)434 FirmDie *FirmDieArray::operator[](int recNo)
435 {
436 FirmDie* firmDiePtr = (FirmDie*) get(recNo);
437
438 if( !firmDiePtr || is_deleted(recNo) )
439 err.run( "FirmDieArray[] is deleted" );
440
441 return firmDiePtr;
442 }
443
is_deleted(int recNo)444 int FirmDieArray::is_deleted(int recNo)
445 {
446 FirmDie* firmDiePtr = (FirmDie*) get(recNo);
447 if( !firmDiePtr || firmDiePtr->firm_id == 0)
448 return 1;
449 return 0;
450 }
451
452