/* * Seven Kingdoms: Ancient Adversaries * * Copyright 1997,1998 Enlight Software Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ // Filename : OFIRMDIE.CPP // Description : destruting firm #include #include #include #include #include #include #include #define FIRM_BUILD_DB "FDBUILD" #define FIRM_FRAME_DB "FDFRAME" #define FIRM_BITMAP_DB "FDBITMAP" struct FirmDieBitmap : public FirmBitmap { int bitmap_offset; // fill bitmap_ptr, width and height before draw() }; FirmDieRes::FirmDieRes() { firm_build_count = 0; firm_bitmap_count = 0; firm_build_array = NULL; firm_bitmap_array = NULL; init_flag = 0; } FirmDieRes::~FirmDieRes() { deinit(); } void FirmDieRes::init() { deinit(); //----- open firm material bitmap resource file -------// String str; str = DIR_RES; str += "I_FIRMDI.RES"; res_bitmap.init_imported(str,0,1); // 0 - do not read all data into buffer //------- load database information --------// load_bitmap_info(); // call load_firm_bitmap() first as load_firm_info() will need info loaded by load_firm_bitmap() load_build_info(); //----------------------------------------// init_flag=1; } void FirmDieRes::deinit() { if(init_flag) { mem_del(firm_build_array); mem_del(firm_bitmap_array); res_bitmap.deinit(); init_flag = 0; } } //------- Begin of function FirmDieRes::load_firm_bitmap -------// // // Read in information of FDBITMAP.DBF into memory array // void FirmDieRes::load_bitmap_info() { FirmBitmapRec *firmBitmapRec; FirmDieBitmap *firmBitmap; int i; uint32_t bitmapOffset; Database *dbFirmBitmap = game_set.open_db(FIRM_BITMAP_DB); firm_bitmap_count = (short) dbFirmBitmap->rec_count(); firm_bitmap_array = (FirmDieBitmap*) mem_add( sizeof(FirmDieBitmap)*firm_bitmap_count ); //------ read in firm bitmap info array -------// memset( firm_bitmap_array, 0, sizeof(FirmDieBitmap) * firm_bitmap_count ); for( i=0 ; iread(i+1); firmBitmap = firm_bitmap_array+i; memcpy( &bitmapOffset, firmBitmapRec->bitmap_ptr, sizeof(uint32_t) ); // BUGHERE : bitmap is not yet loaded into memory, fill them before draw() firmBitmap->bitmap_ptr = NULL; firmBitmap->width = 0; firmBitmap->height = 0; firmBitmap->offset_x = misc.atoi( firmBitmapRec->offset_x, firmBitmapRec->OFFSET_LEN ); firmBitmap->offset_y = misc.atoi( firmBitmapRec->offset_y, firmBitmapRec->OFFSET_LEN ); firmBitmap->loc_width = misc.atoi( firmBitmapRec->loc_width , firmBitmapRec->LOC_LEN ); firmBitmap->loc_height = misc.atoi( firmBitmapRec->loc_height, firmBitmapRec->LOC_LEN ); firmBitmap->display_layer = firmBitmapRec->layer - '0'; firmBitmap->bitmap_offset = bitmapOffset; } } //--------- End of function FirmDieRes::load_firm_bitmap ---------// //------- Begin of function FirmDieRes::load_firm_build -------// // // Read in information of FIRM.DBF into memory array // void FirmDieRes::load_build_info() { FirmBuildRec *firmBuildRec; FirmFrameRec *firmFrameRec; FirmBuild *firmBuild; FirmBitmap *firmBitmap; int i, j, k, frameRecno, bitmapRecno; short *firstFrameArray; //---- read in firm count and initialize firm info array ----// Database *dbFirmBuild = game_set.open_db(FIRM_BUILD_DB); // only one database can be opened at a time, so we read FIRM.DBF first firm_build_count = (short) dbFirmBuild->rec_count(); firm_build_array = (FirmBuild*) mem_add( sizeof(FirmBuild)*firm_build_count ); memset( firm_build_array, 0, sizeof(FirmBuild) * firm_build_count ); //------ allocate an array for storing firstFrameRecno -----// firstFrameArray = (short*) mem_add( sizeof(short) * firm_build_count ); //---------- read in FDBUILD.DBF ---------// for( i=0 ; iread(i+1); firmBuild = firm_build_array+i; misc.rtrim_fld( firmBuild->build_code, firmBuildRec->race_code, firmBuild->BUILD_CODE_LEN ); firmBuild->animate_full_size = firmBuildRec->animate_full_size=='1'; firmBuild->race_id = misc.atoi( firmBuildRec->race_id, firmBuildRec->RACE_ID_LEN ); firmBuild->frame_count = misc.atoi( firmBuildRec->frame_count, firmBuildRec->FRAME_COUNT_LEN ); firmBuild->under_construction_bitmap_recno = misc.atoi(firmBuildRec->under_construction_bitmap_recno, firmBuildRec->BITMAP_RECNO_LEN); firmBuild->idle_bitmap_recno = misc.atoi(firmBuildRec->idle_bitmap_recno, firmBuildRec->BITMAP_RECNO_LEN); firmBuild->ground_bitmap_recno = misc.atoi(firmBuildRec->ground_bitmap_recno, firmBuildRec->BITMAP_RECNO_LEN); err_when( firmBuild->frame_count > MAX_FIRM_FRAME ); firstFrameArray[i] = misc.atoi( firmBuildRec->first_frame, firmBuildRec->FIRST_FRAME_LEN ); // BUGHERE : need to compare same Firm name and build code in firm database } //-------- read in FDFRAME.DBF --------// Database *dbFirmFrame = game_set.open_db(FIRM_FRAME_DB); int minOffsetX, minOffsetY; int maxX2, maxY2; for( i=0 ; iframe_count ; j++, frameRecno++ ) { firmFrameRec = (FirmFrameRec*) dbFirmFrame->read(frameRecno); //------ following animation frames, bitmap sections -----// firmBuild->first_bitmap_array[j] = misc.atoi( firmFrameRec->first_bitmap, firmFrameRec->FIRST_BITMAP_LEN ); firmBuild->bitmap_count_array[j] = misc.atoi( firmFrameRec->bitmap_count, firmFrameRec->BITMAP_COUNT_LEN ); firmBuild->frame_delay_array[j] = misc.atoi( firmFrameRec->delay, firmFrameRec->DELAY_LEN ); //---- get the MIN offset_x, offset_y and MAX width, height ----// // // So we can get the largest area of all the frames in this building // and this will serve as a normal size setting for this building, // with variation from frame to frame // //--------------------------------------------------------------// firmBitmap = firm_bitmap_array + firmBuild->first_bitmap_array[j] - 1; for( k=firmBuild->bitmap_count_array[j] ; k>0 ; k--, firmBitmap++ ) { if( firmBitmap->offset_x < minOffsetX ) minOffsetX = firmBitmap->offset_x; if( firmBitmap->offset_y < minOffsetY ) minOffsetY = firmBitmap->offset_y; if( firmBitmap->offset_x + firmBitmap->width > maxX2 ) maxX2 = firmBitmap->offset_x + firmBitmap->width; if( firmBitmap->offset_y + firmBitmap->height > maxY2 ) maxY2 = firmBitmap->offset_y + firmBitmap->height; } } //------- set FirmBuild Info -------// bitmapRecno = firmBuild->first_bitmap_array[0]; //----- get the info of the first frame bitmap ----// firmBitmap = firm_bitmap_array + bitmapRecno - 1; firmBuild->loc_width = firmBitmap->loc_width; firmBuild->loc_height = firmBitmap->loc_height; firmBuild->min_offset_x = minOffsetX; firmBuild->min_offset_y = minOffsetY; firmBuild->max_bitmap_width = maxX2 - minOffsetX; firmBuild->max_bitmap_height = maxY2 - minOffsetY; //------ set firmBuild's under construction and idle bitmap recno -----// if( firmBuild->under_construction_bitmap_recno==0 ) firmBuild->under_construction_bitmap_recno = bitmapRecno; if( firmBuild->idle_bitmap_recno==0 ) firmBuild->idle_bitmap_recno = bitmapRecno; } //------ free up the temporary array -------// mem_del( firstFrameArray ); } //--------- End of function FirmDieRes::load_firm_build ---------// //--------- Begin of function FirmDieRes::get_build ---------// FirmBuild* FirmDieRes::get_build(int buildId) { err_when( buildId < 1 || buildId > firm_build_count); return firm_build_array+buildId-1; } //--------- End of function FirmDieRes::get_build ---------// //--------- Begin of function FirmDieRes::get_bitmap ---------// FirmDieBitmap* FirmDieRes::get_bitmap(int bitmapId) { err_when( bitmapId < 1 || bitmapId > firm_bitmap_count); return firm_bitmap_array+bitmapId-1; } //--------- End of function FirmDieRes::get_bitmap ---------// //--------- Begin of function FirmDie::init --------// void FirmDie::init(short firmId, short firmBuildId, short nationRecno, short locX1, short locY1, short locX2, short locY2) { firm_id = firmId; firm_build_id = firmBuildId; nation_recno = nationRecno; loc_x1 = locX1; loc_y1 = locY1; loc_x2 = locX2; loc_y2 = locY2; frame = 1; } // add before delete the firm void FirmDie::init(Firm *firmPtr) { firm_id = firmPtr->firm_id; firm_build_id = firmPtr->firm_build_id; nation_recno = firmPtr->nation_recno; loc_x1 = firmPtr->loc_x1; loc_y1 = firmPtr->loc_y1; loc_x2 = firmPtr->loc_x2; loc_y2 = firmPtr->loc_y2; frame = 1; frame_delay_count = 0; } void FirmDie::pre_process() { //nothing } int FirmDie::process() { FirmBuild *firmBuild = firm_die_res.get_build(firm_build_id); if( ++frame_delay_count > firmBuild->frame_delay_array[frame-1]) { frame_delay_count = 0; if( ++frame > firmBuild->frame_count) { return 1; } } return 0; } void FirmDie::draw(int displayLayer) { // get ground dirt from firm_res FirmBuild* firmBuild = firm_res.get_build(firm_build_id); if( firmBuild->ground_bitmap_recno ) { // firm_res.get_bitmap(firmBuild->ground_bitmap_recno) // ->draw_at(loc_x1*ZOOM_LOC_WIDTH, loc_y1*ZOOM_LOC_HEIGHT, NULL, displayLayer); } //---------- draw animation now ------------// firmBuild = firm_die_res.get_build(firm_build_id); FirmDieBitmap* firmBitmap; int bitmapRecno, i; int firstBitmap = firmBuild->first_bitmap(frame); int bitmapCount = firmBuild->bitmap_count(frame); char* colorRemapTable = game.get_color_remap_table(nation_recno, 0); for( i=0, bitmapRecno=firstBitmap ; ibitmap_ptr = bitmapPtr = firm_die_res.res_bitmap.read_imported(firmBitmap->bitmap_offset); firmBitmap->width = *(short *)bitmapPtr; firmBitmap->height= *(1+(short *)bitmapPtr); firmBitmap->draw_at(loc_x1*ZOOM_LOC_WIDTH, loc_y1*ZOOM_LOC_HEIGHT, colorRemapTable, displayLayer); } } } FirmDieArray::FirmDieArray() : DynArrayB(sizeof(FirmDie),10, DEFAULT_REUSE_INTERVAL_DAYS) { // nothing } FirmDieArray::~FirmDieArray() { deinit(); } void FirmDieArray::init() { zap(); } void FirmDieArray::deinit() { // nothing } void FirmDieArray::process() { int i, j; for( i=1, j=size(); j; --j, ++i) { if( is_deleted(i) ) continue; FirmDie *firmDiePtr = this->operator[](i); if( firmDiePtr->process() ) { del(i); continue; } } } int FirmDieArray::add(FirmDie *r) { linkin(r); return recno(); } void FirmDieArray::del(int i) { linkout(i); } FirmDie *FirmDieArray::operator[](int recNo) { FirmDie* firmDiePtr = (FirmDie*) get(recNo); if( !firmDiePtr || is_deleted(recNo) ) err.run( "FirmDieArray[] is deleted" ); return firmDiePtr; } int FirmDieArray::is_deleted(int recNo) { FirmDie* firmDiePtr = (FirmDie*) get(recNo); if( !firmDiePtr || firmDiePtr->firm_id == 0) return 1; return 0; }