//--------- Begin of function Unit::init_sprite ---------// // // <int> startXLoc, startYLoc - the starting location of the unit // void Unit::init_sprite(int startXLoc, int startYLoc) { Sprite::init( unit_res[unit_id]->sprite_id, startXLoc, startYLoc ); // BUGHERE use unit_id temporarily //-------- set loc_width and loc_height ------// loc_width = (char) sprite_info->loc_width; loc_height = (char) sprite_info->loc_height; // copy the vars for fast access // ###### begin Gilbert 30/4 ##########// move_to_loc_x = startXLoc; // * LOCATE_WIDTH; move_to_loc_y = startYLoc; // * LOCATE_HEIGHT; // ###### end Gilbert 30/4 ##########// //-------- set the cargo_recno -------------// int w, h, x, y; err_if(!sprite_recno) // sprite_recno must be initialized first before calling UnitB::init() err_here(); for(h=0, y=startYLoc; h<loc_height; h++, y++) { for(w=0, x=startXLoc; w<loc_width; w++, x++) { err_if( !world.get_loc(x, y)->can_move(mobile_type) ) // it must be 0 to put the sprite in this location err_here(); world.get_loc(x, y)->set_unit(sprite_recno, mobile_type); } } explore_area(); }
HillBlockInfo* HillRes::operator[](int hillBlockId) { err_if( hillBlockId<1 || hillBlockId>hill_block_count ) err_now( "HillRes::operator[]" ); return hill_block_info_array+(hillBlockId-1); }
int eb_serial_recv(unsigned char *buf, int *buflen) { int ret; /* flush deactivated - brings us an error */ /* tcflush(sfd, TCIOFLUSH); */ /* read msg from ebus device */ *buflen = read(sfd, buf, *buflen); err_if(*buflen < 0); if (*buflen < 0) { log_print(L_WAR, "error read serial device"); return -1; } if (*buflen > SERIAL_BUFSIZE) { log_print(L_WAR, "read data len > %d", SERIAL_BUFSIZE); return -3; } /* print bus */ if (showraw == YES) eb_print_hex(buf, *buflen); /* dump raw data*/ if (rawdump == YES) { ret = eb_raw_file_write(buf, *buflen); if (ret < 0) log_print(L_WAR, "can't write rawdata"); } return 0; }
TerrainInfo* TerrainRes::operator[](int terrainId) { err_if( terrainId<1 || terrainId>terrain_count ) err_now( "TerrainRes::operator[]" ); return terrain_info_array+terrainId-1; }
//--------- Begin of function SiteArray::del_site ----------// // // Delete a specified site. // // <int> siteRecno = the record no. of the site to be deleted // void SiteArray::del_site(int siteRecno) { err_if( siteRecno == 0 ) err_now( "SiteArray::del_site" ); Site* sitePtr = site_array[siteRecno]; switch( sitePtr->site_type ) { case SITE_RAW: untapped_raw_count--; break; case SITE_SCROLL: scroll_count--; break; case SITE_GOLD_COIN: gold_coin_count--; break; } //-------------------------------// sitePtr->deinit(); linkout(siteRecno); if( siteRecno == site_array.selected_recno ) site_array.selected_recno = 0; }
MonsterInfo* MonsterRes::operator[](int monsterId) { err_if( monsterId<1 || monsterId>monster_count ) err_now( "MonsterRes::operator[]" ); return monster_info_array+monsterId-1; }
TownBuildType* TownRes::get_build_type(int recNo) { err_if( recNo<1 || recNo>town_build_type_count ) err_now( "TownRes::get_build_type()" ); return town_build_type_array+recNo-1; }
RawInfo* RawRes::operator[](int rawId) { err_if( rawId<1 || rawId>raw_count ) err_now( "RawRes::operator[]" ); return raw_info_array+rawId-1; }
TownBuild* TownRes::get_build(int recNo) { err_if( recNo<1 || recNo>town_build_count ) err_now( "TownRes::get_build()" ); return town_build_array+recNo-1; }
WallInfo* WallRes::operator[](int wallId) { err_if( wallId<1 || wallId>max_wall_id ) err_now( "WallRes::operator[]" ); return wall_index[wallId-1]; }
char* TownRes::get_name(int recNo) { err_if( recNo<1 || recNo>town_name_count ) err_now( "TownRes::get_name()" ); return town_name_array[recNo-1].name; }
FirmInfo* FirmRes::operator[](int firmId) { err_if( firmId<1 || firmId>firm_count ) err_now( "FirmRes::operator[]" ); return firm_info_array+firmId-1; }
TownSlot* TownRes::get_slot(int recNo) { err_if( recNo<1 || recNo>town_slot_count ) err_now( "TownRes::get_slot()" ); return town_slot_array+recNo-1; }
TownLayout* TownRes::get_layout(int recNo) { err_if( recNo<1 || recNo>town_layout_count ) err_now( "TownRes::get_layout()" ); return town_layout_array+recNo-1; }
Firm* FirmArray::operator()() { Firm* firmPtr = (Firm*) get_ptr(); // if recno()==0, get_ptr() returns NULL err_if( !firmPtr ) err_now( "FirmArray[recno()] is deleted" ); return firmPtr; }
/// add two sparse vectors (*this = a + b) inline void add( sparse_vector_t<T> &a, sparse_vector_t<T> &b ) { T value; unsigned i; err_if(a.length()!=b.length(), "Cannot add sparse vectors with different sizes"); copy(a); b.reset_next(); while ( b.get_next(i,value) ) { data_[i] += value; } }
//---------- Begin of function TownRes::scan_build -----------// // // Set the given slot with a building that fits the given criteria // // <int> slotId - the slot id. of the current town section to be set. // <int> raceId - one of the building selection criteria // (0-any race) // // return : <int> townBuildId - the id. of the town building // int TownRes::scan_build(int slotId, int raceId) { enum { MAX_SCAN_ID = 100 }; TownSlot* townSlot = town_res.get_slot(slotId); TownBuildType* buildType; TownBuild* townBuild; int i, buildRecno, matchCount=0; int scanIdArray[MAX_SCAN_ID]; //---- get the building type of the slot ------// buildType = town_res.get_build_type(townSlot->build_type); err_if( buildType->build_count==0 ) err_here(); //------ scan_build buildings of the specified type ------// buildRecno = buildType->first_build_recno; townBuild = town_res.get_build(buildRecno); // the pointer to the first building of the specified type for( i=buildType->build_count ; i>0 ; i--, townBuild++, buildRecno++ ) { if( townBuild->build_code == townSlot->build_code ) { if( !raceId || townBuild->race_id == raceId ) { scanIdArray[matchCount] = buildRecno; if( ++matchCount >= MAX_SCAN_ID ) break; } } } //--- pick one from those plants that match the criteria ---// if( matchCount > 0 ) { int buildId = scanIdArray[misc.random(matchCount)]; #ifdef DEBUG town_res.get_build( buildId ); // get_build() will error if buildId is not valid #endif return buildId; } else return 0; }
//------- Begin of function Misc::random ---------// // // <int> maxNum = maximum random number, it must <= 0x7FFF // in 32 bit compiler <int> = <long> // // return : <int> the random number // int Misc::random(int maxNum) { err_if( maxNum < 0 || maxNum > 0x7FFF ) err_now( "Misc::random()" ); // ###### begin Gilbert 19/6 ######// err_when( is_seed_locked() ); // ###### end Gilbert 19/6 ######// #define MULTIPLIER 0x015a4e35L #define INCREMENT 1 #define RANDOM_MAX 0x7FFFU random_seed = MULTIPLIER * random_seed + INCREMENT; return maxNum * ((random_seed >> 16) & RANDOM_MAX) / (RANDOM_MAX+1); }
//------- BEGIN OF FUNCTION Misc::fix_str ------// // // format the word to the fixed length // // e.g. Misc::fix_str("ABC",10) -> "ABC " // // <char*> str = the string to be formated // <int> len = the deserved length after formatted // [char] endChar = the end character of the string ( default : NULL terminator ) // void Misc::fix_str(char* str,int len,char endChar) { int oldLen; if ( endChar == '\0' ) oldLen = strlen(str); else { oldLen = Misc::str_chr(str,endChar)-1; err_if ( oldLen == -1 ) // the end character not found err_now("Misc::fix_str"); } if ( len > oldLen ) memset( str+oldLen, ' ', len-oldLen ); str[len] = '\0'; }
//--------- Begin of GameSet::open_set -------------// // // Open the specific set. // Only one set can be activiated at a time in GameSet. // // <int> setId = the id. of the set // void GameSet::open_set(int setId) { err_if( setId<0 || setId>set_count ) err_here(); cur_set_id = setId; String str; str = DIR_RES; str += set_info_array[setId-1].code; str += ".SET"; set_res.init( str, 0 ); // 0-don't read all into the buffer //-----------------------------------------------// set_opened_flag=1; }
//------- Begin of function TownRes::load_town_layout -------// // // Read in information from TOWNLAY.DBF. // void TownRes::load_town_layout() { TownLayoutRec *townLayoutRec; TownLayout *townLayout; TownSlot *townSlot; int i, j; Database *dbTownLayout = game_set.open_db(TOWN_LAYOUT_DB); town_layout_count = (short) dbTownLayout->rec_count(); town_layout_array = (TownLayout*) mem_add( sizeof(TownLayout)*town_layout_count ); //------ read in town layout info array -------// memset( town_layout_array, 0, sizeof(TownLayout) * town_layout_count ); for( i=0 ; i<town_layout_count ; i++ ) { townLayoutRec = (TownLayoutRec*) dbTownLayout->read(i+1); townLayout = town_layout_array+i; townLayout->first_slot_recno = misc.atoi(townLayoutRec->first_slot, TownLayoutRec::FIRST_SLOT_LEN); townLayout->slot_count = misc.atoi(townLayoutRec->slot_count, TownLayoutRec::SLOT_COUNT_LEN); // ###### begin Gilbert 9/9 ########// // townLayout->ground_bitmap_ptr = image_spict.get_ptr( misc.nullify(townLayoutRec->ground_name, TownLayoutRec::GROUND_NAME_LEN) ); townLayout->ground_bitmap_ptr = image_tpict.get_ptr( misc.nullify(townLayoutRec->ground_name, TownLayoutRec::GROUND_NAME_LEN) ); // ###### end Gilbert 9/9 ########// err_if( townLayout->slot_count > MAX_TOWN_LAYOUT_SLOT ) err_now( "Error: MAX_TOWN_LAYOUT_SLOT limit exceeded." ); //----- calculate min_population & max_population -----// townSlot = town_slot_array+townLayout->first_slot_recno-1; for( j=0 ; j<townLayout->slot_count ; j++, townSlot++ ) { if( townSlot->build_type==TOWN_OBJECT_HOUSE ) // if there is a building in this slot townLayout->build_count++; } } }
News* NewsArray::operator[](int recNo) { #ifdef DEBUG News* msgPtr; if( recNo ) msgPtr = (News*) get(recNo); else msgPtr = NULL; // NULL will then cause error err_if( !msgPtr || msgPtr->news_date==0 ) err_now( "NewsArray[] is deleted" ); return msgPtr; #else return (News*) get(recNo); #endif }
//---------- Begin of function ResourceDb::init ---------// // // <char*> resName = name of the resource file (e.g. "GIF.RES") // <Database*> dbObj = name of the database (e.g. Database db("PFILE.DBF")) // <int> indexOffset = offset of the index field // [int] useCommonBuf = whether use the vga common buffer to store the data or not // (default:0) // void ResourceDb::init(char* resName, Database* dbObj, int indexOffset, int useCommonBuf) { deinit(); file_open( resName ); db_obj = dbObj; index_field_offset = indexOffset; use_common_buf = useCommonBuf; if( use_common_buf ) data_buf = sys.common_data_buf; else data_buf = NULL; err_if( db_obj == NULL ) err_now("db_obj is NULL"); init_flag = 1; }
//--------- Begin of function Sprite::sprite_move --------// // // <int> desX, desY - the destination coordination // void Sprite::sprite_move(int desX, int desY) { if( cur_action != SPRITE_MOVE ) { cur_action = SPRITE_MOVE; cur_frame = 1; } err_when(desX<0 || desY<0 || desX>=MAX_WORLD_X_LOC*LOCATE_WIDTH || desY>=MAX_WORLD_Y_LOC*LOCATE_HEIGHT); #ifdef DEBUG short vectorX=desX-next_x; short vectorY=desY-next_y; if(vectorX && vectorY) // both are non-zero { err_if(abs(vectorX) != abs(vectorY)) err_here(); } #endif go_x = desX; go_y = desY; //----------- determine the movement direction ---------// set_dir(cur_x, cur_y, go_x, go_y); //------ set the next tile to move towards -------// /* next_x = cur_x; next_y = cur_y; */ int stepMagn = move_step_magn(); set_next(cur_x+stepMagn*move_x_pixel_array[final_dir], cur_y+stepMagn*move_y_pixel_array[final_dir], -stepMagn); err_when(cur_action==SPRITE_MOVE && (cur_x!=next_x || cur_y!=next_y) && final_dir!=(check_dir1=get_dir(cur_x, cur_y, next_x, next_y))); }
/// operator( index ) - returns a constant reference to an element with the given index const T& operator()( unsigned index ) const { err_if(index>=length_,"sparse_vector, out of bounds"); return get(index); };
PlantInfo* PlantRes::operator[](int plantId) { err_if( plantId<1 || plantId>plant_count ) err_now( "PlantRes::operator[]" ); return info_array+plantId-1; }
/// operator( index ) - returns a reference to an element with the given index T& operator()( unsigned index ) { err_if(index>=length_,"sparse_vector, out of bounds"); return data_[index]; };
void Sprite::process_move() { #ifdef DEBUG int debugStepMagn1 = move_step_magn(); err_when(abs(cur_x-next_x)>LOCATE_WIDTH*debugStepMagn1 || abs(cur_y-next_y)>LOCATE_HEIGHT*debugStepMagn1); #endif //---- for some sprite (e.g. elephant), move one step per a few frames ----// if( --remain_frames_per_step > 0 ) return; else remain_frames_per_step = sprite_info->frames_per_step; err_when(cur_x < 0 || cur_y < 0 || cur_x >= MAX_WORLD_X_LOC * LOCATE_WIDTH || cur_y >= MAX_WORLD_Y_LOC * LOCATE_HEIGHT); err_when(cur_x-next_x!=0 && cur_y-next_y!=0 && abs(next_x-cur_x)!=abs(next_y-cur_y)); //----- if the sprite has reach the destintion ----// if( cur_x==go_x && cur_y==go_y) { cur_action = SPRITE_IDLE; int rc = set_next(cur_x, cur_y); //********* BUGHERE err_when( !rc ); #ifdef DEBUG char h, w, blocked=0; short x, y; for(h=0, y=next_y_loc(); h<sprite_info->loc_height&&!blocked; h++, y++) { for(w=0, x=next_x_loc(); w<sprite_info->loc_width&&!blocked; w++, x++) blocked = world.get_loc(x, y)->unit_recno(mobile_type) != sprite_recno; } err_if(blocked) err_here(); #endif cur_frame = 1; return; } err_when(cur_x-next_x!=0 && cur_y-next_y!=0 && abs(next_x-cur_x)!=abs(next_y-cur_y)); //---- set the next tile the sprite will be moving towards ---// static short vector_x_array[] = { 0, 1, 1, 1, 0, -1, -1, -1 }; // default vectors, temporary only static short vector_y_array[] = { -1, -1, 0, 1, 1, 1, 0, -1 }; // short stepX = sprite_info->speed; // short stepY = sprite_info->speed; short stepX, stepY; stepX = stepY = sprite_speed(); if( final_dir & 1 ) // diagonal direction slower { if( stepX >=8 ) { stepY = (stepX -= (unsigned)stepX /4 ); // slightly fast for unsigned division } else if( stepX >= 3 ) { --stepX; --stepY; } } //------------------------------------------// if( next_x != go_x || next_y != go_y ) // if next_x==go_x & next_y==go_y, reach destination already, don't move further. { if( abs(cur_x-next_x) <= stepX && abs(cur_y-next_y) <= stepY ) { int stepMagn = move_step_magn(); if( !set_next(next_x+stepMagn*move_x_pixel_array[final_dir], next_y+stepMagn*move_y_pixel_array[final_dir], -stepMagn) ) return; } } err_when(cur_x-next_x!=0 && cur_y-next_y!=0 && abs(next_x-cur_x)!=abs(next_y-cur_y)); //---- if the is blocked, cur_action is changed to SPRITE_WAIT, return now ----// if( cur_action != SPRITE_MOVE ) return; //-------------- update position -----------------// // // If it gets very close to the destination, fit it // to the destination ingoring the normal vector. // //------------------------------------------------// short vectorX = vector_x_array[final_dir] * stepX; // cur_dir may be changed in the above set_next() call short vectorY = vector_y_array[final_dir] * stepY; if( abs(cur_x-go_x) <= stepX ) cur_x = go_x; else cur_x += vectorX; if( abs(cur_y-go_y) <= stepY ) cur_y = go_y; else cur_y += vectorY; err_when(cur_x-next_x!=0 && cur_y-next_y!=0 && abs(next_x-cur_x)!=abs(next_y-cur_y)); // is a better checking if speed in all direction is equal #ifdef DEBUG int debugStepMagn2 = move_step_magn(); err_when(abs(cur_x-next_x)>LOCATE_WIDTH*debugStepMagn1 || abs(cur_y-next_y)>LOCATE_HEIGHT*debugStepMagn1); #endif //-------- check boundary ---------// err_when(cur_x < 0 || cur_y < 0 || cur_x >= MAX_WORLD_X_LOC * LOCATE_WIDTH || cur_y >= MAX_WORLD_Y_LOC * LOCATE_HEIGHT); //------- update frame id. --------// if( ++cur_frame > cur_sprite_move()->frame_count ) cur_frame = 1; }
void main_loop(void) { int maxfd, sfd_closed, timeout_reached; fd_set listenfds; struct timeval timeout; sfd_closed = NO; timeout_reached = NO; FD_ZERO(&listenfds); FD_SET(serialfd, &listenfds); FD_SET(socketfd, &listenfds); maxfd = socketfd; /* serialfd should be always lower then socketfd */ if (serialfd > socketfd) { log_print(L_ERR, "serialfd %d > %d socketfd", serialfd, socketfd); cleanup(EXIT_FAILURE); } for (;;) { fd_set readfds; int readfd; int ret; /* set select timeout 10 secs */ timeout.tv_sec = 10; timeout.tv_usec = 0; /* set readfds to inital listenfds */ readfds = listenfds; /* check if the usb device is working */ if (eb_serial_valid() < 0 || timeout_reached == YES) { timeout_reached = NO; if (serialfd > 0 && sfd_closed == NO) { log_print(L_ERR, "serial device is invalid"); sfd_closed = YES; /* close listing tcp socket */ if (socketfd > 0) { if (sock_close(socketfd) == -1) log_print(L_ERR, "can't close port: %d", port); else log_print(L_INF, "port %d closed", port); } /* close serial device */ if (eb_serial_close() == -1) log_print(L_ERR, "can't close device: %s", device); else log_print(L_INF, "%s closed", device); } /* need sleep to prevent high cpu consumption */ sleep(1); /* open serial device */ if (eb_serial_open(device, &serialfd) == 0) { log_print(L_INF, "%s opened", device); sfd_closed = NO; } /* open listing tcp socket */ if (sfd_closed == NO && sock_open(&socketfd, port, localhost) == 0) log_print(L_INF, "port %d opened", port); continue; } ret = select(maxfd + 1, &readfds, NULL, NULL, &timeout); /* timeout after 10 secs means that ebus is probably disconnected or USB device is dead */ if (ret == 0) { log_print(L_WAR, "select timeout (%d) reached", timeout.tv_sec); timeout_reached = YES; continue; /* ignore signals */ } else if ((ret < 0) && (errno == EINTR)) { /* log_print(L_NOT, "get signal at select: %s", strerror(errno)); */ continue; /* on other errors */ } else if (ret < 0) { err_if(1); cleanup(EXIT_FAILURE); } /* new data from serial port? */ if (FD_ISSET(serialfd, &readfds)) { /* get cycle message from bus */ ret = eb_cyc_data_recv(); /* send msg to bus - only when cyc buf is empty */ if (ret == 0 && msg_queue_entries() > 0) { char tcpbuf[SOCKET_BUFSIZE]; char data[MSG_QUEUE_MSG_SIZE]; int tcpbuflen, id, clientfd; memset(tcpbuf, '\0', sizeof(tcpbuf)); tcpbuflen = sizeof(tcpbuf); memset(data, '\0', sizeof(data)); /* get next entry from msg queue */ msg_queue_msg_del(&id, data, &clientfd); /* just do it */ eb_execute(id, data, tcpbuf, &tcpbuflen); /* send answer */ sock_client_write(clientfd, tcpbuf, tcpbuflen); } } /* new incoming connection at TCP port arrived? */ if (FD_ISSET(socketfd, &readfds)) { /* get new TCP client fd*/ ret = sock_client_accept(socketfd, &readfd); if (readfd >= 0) { /* add new TCP client fd to listenfds */ FD_SET(readfd, &listenfds); (readfd > maxfd) ? (maxfd = readfd) : (1); } } /* run through connected sockets for new data */ for (readfd = socketfd + 1; readfd <= maxfd; ++readfd) { /* check all connected clients */ if (FD_ISSET(readfd, &readfds)) { char tcpbuf[SOCKET_BUFSIZE]; char data[MSG_QUEUE_MSG_SIZE]; int tcpbuflen; memset(tcpbuf, '\0', sizeof(tcpbuf)); tcpbuflen = sizeof(tcpbuf); memset(data, '\0', sizeof(data)); /* get message from client */ ret = sock_client_read(readfd, tcpbuf, &tcpbuflen); /* remove dead TCP client */ if (ret < 0) { FD_CLR(readfd, &listenfds); continue; } /* handle different commands */ if (strncasecmp("shutdown", tcpbuf, 8) == 0) cleanup(EXIT_SUCCESS); if (strncasecmp("loglevel", tcpbuf, 8) == 0) { strncpy(loglevel, tcpbuf, strlen(tcpbuf)); log_level(loglevel); continue; } /* search ebus command */ if (tcpbuflen > 0) ret = eb_cmd_search_com(tcpbuf, data); else ret = -1; /* command not found */ if (ret < 0) { memset(tcpbuf, '\0', sizeof(tcpbuf)); strcpy(tcpbuf, "command not found\n"); tcpbuflen = strlen(tcpbuf); /* send answer */ sock_client_write(readfd, tcpbuf, tcpbuflen); } else { msg_queue_msg_add(ret, data, readfd); } } } } }
void daemonize(void) { pid_t pid; /* fork off the parent process */ pid = fork(); if (pid < 0) { err_if(1); cleanup(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process */ if (pid > 0) { /* printf("Child process created: %d\n", pid); */ exit(EXIT_SUCCESS); } /* At this point we are executing as the child process */ /* Set file permissions 750 */ umask(027); /* Create a new SID for the child process and */ /* detach the process from the parent (normally a shell) */ if (setsid() < 0) { err_if(1); cleanup(EXIT_FAILURE); } /* Change the current working directory. This prevents the current directory from being locked; hence not being able to remove it. */ if (chdir(DAEMON_WORKDIR) < 0) { /* Log any failure here */ err_if(1); cleanup(EXIT_FAILURE); } /* Route I/O connections */ close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); /* write pidfile and try to lock it */ if (pid_file_open(pidfile, &pidfd) == -1) { log_print(L_ERR, "can't open pidfile: %s\n", pidfile); cleanup(EXIT_FAILURE); } else { pidfile_locked = YES; log_print(L_INF, "%s created.", pidfile); } /* Cancel certain signals */ signal(SIGCHLD, SIG_DFL); /* A child process dies */ signal(SIGTSTP, SIG_IGN); /* Various TTY signals */ signal(SIGTTOU, SIG_IGN); /* Ignore TTY background writes */ signal(SIGTTIN, SIG_IGN); /* Ignore TTY background reads */ /* Trap signals that we expect to receive */ signal(SIGHUP, signal_handler); signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); }