/* * 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 : OMISC.CPP //Description : Object of Misc useful functions #include #include #include #include #include #include #include #include #include #include #define MOVE_AROUND_TABLE_SIZE 900 static char move_around_table_x[MOVE_AROUND_TABLE_SIZE] = {0}; static char move_around_table_y[MOVE_AROUND_TABLE_SIZE] = {0}; static short move_around_table_size = 0; #if(defined(SPANISH)) #define THOUSAND_SEPARATOR '.' #define DECIMAL_SEPARATOR ',' #else #define THOUSAND_SEPARATOR ',' #define DECIMAL_SEPARATOR '.' #endif //-------- Start of function Misc::delay -------------// // // Misc::delay for specified seconds // // float wait = the no. of second to wait // void Misc::delay(float wait) { clock_t stopTime; stopTime = (long) (clock() + (wait * CLOCKS_PER_SEC)); while( clock() < stopTime ); } //--------- End of function Misc::delay ---------------// //-------- BEGIN OF FUNCTION Misc::str_shorten --------// // // Shorten the string with words exceed the dest. length cut. // // = destination string // = source string (source should be longer than dest) // = max. no. of characters in the dest. string. // ( destStr should be allocated as destStr[destLen+1] ) // void Misc::str_shorten(char* destStr, char* srcStr, int destLen) { strncpy( destStr, srcStr, destLen ); destStr[destLen]=NULL; //------ no need to cut characters if it fit preciously ----// // // e.g. "One Two Three" ---> "One Two" // (srcStr) (destStr, return it as the result) //----------------------------------------------------------// if( (int)strlen(srcStr) < destLen || srcStr[destLen] == ' ' ) return; //--- if there is only one word in the string, don't cut it ----// // // e.g. "VeryLongWord" --> "VeryLongWo" // //--------------------------------------------------------------// if( !str_chr( destStr, ' ' ) ) return; //------ if there is more than one word, cut it ------// // // e.g. "One Two Three" ----> "One Two Thr" ---> "One Two" // (srcStr) (destStr before) (destStr after) // //----------------------------------------------------// int i; for( i=destLen-1 ; i>0 && destStr[i] != ' ' ; i-- ) destStr[i] = NULL; destStr[i] = NULL; // trim the space also } //------------ END OF FUNCTIN Misc::str_shorten -----------------// //-------- BEGIN OF FUNCTION Misc::str_cut --------// // // Syntax : Misc::str_cut( ,,, ) // // Description : cut up string1 and place the resuit in string 2 // // = destination string // = source string // = the start position of the new string // = the no. of characters to copied. (default:to the end of the string) // int Misc::str_cut(char* dstr, char* sstr, int schar, int charnum ) { int si,di,forever; forever = (charnum < 0); for (si=schar-1,di=0 ; ( di, = the string to the scanned. // = the key character // [int] = the start position of the string to be scanned (1) // [int] = the end position of the string to be scanned (-1) // // return : a positive number indicating the position of the first occurance // FAIL / NULL if not found // int Misc::str_chr( char* str, char chr, int spos, int epos ) { int i; epos--; for (i=spos-1 ; str[i] && ( i<=epos || epos==-2 ) ; i++) { if ( str[i] == chr ) return(i+1); } return 0; } //----------- END OF FUNCTION Misc::str_chr -------------// //---------- BEGIN OF FUNCTION Misc::str_str ----------------// // // Description : return the position of the first occurance of the character // in the string // // Syntax : Misc::str_str( , , [int], [int] ) // // = the string to the scanned. // = the key string // [int] = the start position of the string to be scanned (1) // [int] = the end position of the string to be scanned (-1) // // return : a positive number indicating the position of the first occurance // FAIL / NULL if not found // int Misc::str_str( char* str, char* fstr, int spos, int epos ) { int i,j,flen; if (epos == -1) epos = strlen(str); flen = strlen(fstr); epos -= flen ; for (i=spos-1 ; str[i] && i<=epos ; i++) { for (j= 0; j < flen && str[i+j] ; j++ ) { if ( str[i+j] != fstr[j] ) // exactly equal break; } if ( j==flen ) // all equal return (i+1) ; } return 0; } //----------- END OF FUNCTION Misc::str_str -------------// //------ BEGIN OF FUNCTION Misc::upper ---------// // // Description : Convert the character to upper case // // Syntax : Misc::upper() // // return : the converted character // // int Misc::upper(int inchar) { if ( inchar >= 'a' && inchar <= 'z' ) inchar -= 32; return( inchar ); } //----- END OF FUNCTION Misc::upper ------------// //------ BEGIN OF FUNCTION Misc::lower ---------// // // Description : Convert the character to lower case // // Syntax : Misc::lower() // // return : the converted character // // int Misc::lower(int inchar) { if ( inchar >= 'A' && inchar <= 'Z' ) inchar += 32; return( inchar ); } //----- END OF FUNCTION Misc::lower ------------// //--------- BEGIN OF FUNCTION Misc::ltrim_len ---------// // // Description : return the number of character in the string // with left space cut // int Misc::ltrim_len(char* inStr,int spos,int len) { int i,j; if ( len == -1 ) len = strlen(inStr); for( i = spos-1,j=0 ; j inStr = the pointer to the string // [int] spos = start position of the string from the pointer // (default : 1) // [int] len = length of the string // (default : until NULL) // int Misc::rtrim_len(char* inStr,int spos,int len) { int i,j; if ( len == -1 ) len = strlen(inStr); for( i = spos+len-2,j=0 ; j = the destination // = the source // // Note : the destination memory must be allocated // void Misc::rtrim( char* des, char* src ) { int i; for ( i=strlen(src)-1 ; src[i]==' ' && i>=0 ; i-- ) des[i] = src[i]; des[i+1] = NULL; } //------- END OF FUNCTION Misc::rtrim --------// //------ BEGIN OF FUNCTION Misc::ltrim ---------// // // = the destination // = the source // // Note : the destination memory must be allocated // void Misc::ltrim( char* des, char* src ) { int i,j; for ( i=0 ; src[i]==' ' && src[i] ; ) i++ ; for ( j=0 ; src[i] ; i++,j++ ) des[j] = src[i]; des[j] = NULL; } //------- END OF FUNCTION Misc::ltrim --------// //------ BEGIN OF FUNCTION Misc::alltrim ---------// // // = the destination // = the source // // Note : the destination memory must be allocated // void Misc::alltrim( char* des, char* src) { int i,j; for ( i=0 ; src[i]==' ' && src[i] ; ) i++ ; for ( j=0 ; src[i] && src[i]!=' ' ; i++,j++ ) des[j] = src[i]; des[j] = NULL; } //------- END OF FUNCTION Misc::alltrim --------// //------ BEGIN OF FUNCTION Misc::rtrim ---------// // // = the string, the result is put back into the original string pointer // char* Misc::rtrim( char* str ) { int i; for ( i=strlen(str)-1 ; str[i]==' ' && i>=0 ; i-- ); str[i+1] = NULL; return str; } //------- END OF FUNCTION Misc::rtrim --------// //------ BEGIN OF FUNCTION Misc::ltrim ---------// // // = the string // char* Misc::ltrim( char* str ) { int i,j; for ( i=0 ; str[i]==' ' && str[i] ; i++ ); for ( j=0 ; str[i] ; i++,j++ ) str[j] = str[i]; str[j] = NULL; return str; } //------- END OF FUNCTION Misc::ltrim --------// //------ BEGIN OF FUNCTION Misc::alltrim ---------// // // = the string // char* Misc::alltrim( char* str ) { int i,j; for ( i=0 ; str[i]==' ' && str[i] ; i++ ); for ( j=0 ; str[i] && str[i]!=' ' ; i++,j++ ) str[j] = str[i]; str[j] = NULL; return str; } //------- END OF FUNCTION Misc::alltrim --------// //------- BEGIN OF FUNCTION Misc::empty ------------// // // Description : empty a string // // Syntax : Misc::empty(<*char>,) // // <*char> = the pointer of the string // = the length of the string (not include the null string ) // void Misc::empty(char *inStr, int strLen ) { memset( inStr,' ',strLen); inStr[strLen] = NULL; } //-------- END OF FUNCTION Misc::empty ---------// //------- BEGIN OF FUNCTION Misc::is_empty ------------// // // Description : empty a string // // Syntax : Misc::is_empty(<*char>,[int],[int]) // // <*char> = the pointer of the string // [int] = the length of the string (not include the null string ) // int Misc::is_empty(char *inStr, int strLen) { int i; if( !strLen ) strLen = strlen(inStr); for( i=0 ; i "ABC " // // str = the string to be formated // 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 == NULL ) 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] = NULL; } //--------- END OF FUNCTION Misc::fix_str ---------// //------- BEGIN OF FUNCTION Misc::valid_char --------// // // Description : test if the character is valid for field and file name // // Syntax : Misc::valid_char() // // = the character to be validify // // return : SUCCEED or FAIL // int Misc::valid_char( char ch ) { return ( ch>='a' && ch<='z' || ch>='A' && ch<='Z' || ch>='0' && ch<='9' || ch=='\\' || ch=='.' || ch=='_' || ch==':' ) ; } //--------- END OF FUNCTION Misc::valid_char ----------// //------- BEGIN OF FUNCTION Misc::str_cmp -----------// // // Description : compare string // // Return : SUCCEED if the same // FAIL if different // // e.g "ABCDE" <> "ABC" // "ABCDE " = "ABCDE" // "ABCDE" <> "ABCDEF" // "ABCDE" <> "ABCDE " int Misc::str_cmp( char* str1, char* str2 ) { err_when( !str1 || !str2 ); int i; for (i=0 ; str1[i] && str2[i] ; i++) if ( str1[i] != str2[i] ) return 0; return ( str2[i] == NULL && (str1[i]==NULL || str1[i]==' ') ); } //--------- END OF FUNCTION Misc::str_cmp -----------// //------- BEGIN OF FUNCTION Misc::str_cmpx -----------// // // Description : String Inexact comparsion // // Return : SUCCEED if the same // FAIL if different // // e.g "ABCDE" = "ABC" // "ABCDE " = "ABCDE" // "ABCDE" <> "ABCDEF" // "ABCDE" <> "ABCDE " // int Misc::str_cmpx( char* str1, char* str2 ) { err_when( !str1 || !str2 ); int i; for (i=0 ; str1[i] && str2[i] ; i++) if ( str1[i] != str2[i] ) return 0; return ( str2[i] == NULL ); } //--------- END OF FUNCTION Misc::str_cmpx -----------// //------- BEGIN OF FUNCTION Misc::str_icmpx -----------// // // Description : String Inexact comparsion without case sensitive // // Return : SUCCEED if the same // FAIL if different // // e.g "ABCDE" = "ABC" // "abcde " = "ABCDE" // "ABCDE" <> "ABCDEF" // "ABCDE" <> "ABCDE " int Misc::str_icmpx( char* str1, char* str2 ) { err_when( !str1 || !str2 ); int i; register int a,b; for (i=0 ; (a=str1[i]) != NULL && (b=str2[i]) != NULL ; i++) { if ( a >= 'a' && a <= 'z' ) a -= 32; if ( b >= 'a' && b <= 'z' ) b -= 32; if ( a != b ) return 0; } return ( str2[i] == NULL ); } //--------- END OF FUNCTION Misc::str_icmpx -----------// //-------- BEGIN OF FUNCTION Misc::check_sum ----------// // // Return the checksum of the string // // = the string // [int] = length of the string int Misc::check_sum(char* str, int len) { int i,checksum; if ( len == -1 ) len = strlen( str ); for( checksum=0,i=0 ; i the pointer to the converted string, the string // is stored in static variable which will be overwritten // in next call. // char* Misc::format( int inNum, int formatType ) { static char outBuf[35]; static char longBuf[25]; char *outPtr=outBuf; char *longStr; int i, intDigit, sign; if( inNum < 0 ) { sign = -1; inNum = -inNum; } else sign = 0; longStr = ltoa( inNum, longBuf, 10 ); intDigit = strlen(longStr); // no. of integer digits //--------- negetive bracket ------------// if( sign < 0 ) *outPtr++ = '('; //--------- dollar sign ------------// if( formatType == 2 ) *outPtr++ = '$'; //-------- integer number -----------// for( i=intDigit ; i>0 ; i-- ) { if( formatType != 4 ) // no thousand separators for format 4 { if( i%3 == 0 && i < intDigit ) *outPtr++ = THOUSAND_SEPARATOR; } *outPtr++ = *longStr++; } //--------- percent sign (%) ------------// if( formatType == 3 ) *outPtr++ = '%'; //--------- negetive bracket ----------// if( sign < 0 ) *outPtr++ = ')'; *outPtr++ = NULL; return outBuf; } //---------- End of function Misc::format ---------// //---------- Begin of function Misc::format --------// // // Format a number to a float number to format string // Note : the formated string is right justified // // inNum = the number to be formated // use instead of because // fcvt() only accept // // [int] formatType = 1 - 1,000,000 add thousand seperator // 2 - $1,000,000 add thousand seperator and dollar sign // 3 - 56% add percentage sign % at the end of the number // // return the pointer to the converted string, the string // is stored in static variable which will be overwritten // in next call. // char* Misc::format(double inNum, int formatType) { enum { MONEY_DEC_PLACE = 2 }; static char outBuf[35]; char *outPtr=outBuf; char *floatStr; int i, intDigit, sign; // intDigit = no. of integer digits floatStr = fcvt( inNum, MONEY_DEC_PLACE, &intDigit, &sign ); #ifdef DEBUG if( intDigit > 29 ) // integer digits can't exceed 29 err.run( "Misc::format(), inNum : %e, formatType : %d", inNum, formatType ); #endif //--------- negetive bracket ------------// if( inNum < 0 ) *outPtr++ = '('; //--------- dollar sign ($) ------------// if( formatType == 2 ) *outPtr++ = '$'; //------- integer number -----------// for( i=intDigit ; i>0 ; i-- ) { if( i%3 == 0 && i < intDigit ) *outPtr++ = THOUSAND_SEPARATOR; *outPtr++ = *floatStr++; } if( intDigit <= 0 ) *outPtr++ = '0'; //------- dec. place number -----------// if( inNum > -1000 && inNum < 1000 ) // if the number is less than 1000, add dec. places { // if the number is greater than 1000, truncate any dec. places *outPtr++ = DECIMAL_SEPARATOR; if( *floatStr && intDigit >= 0 ) // e.g. 0.03 --> str:"3", intDight:-1 *outPtr++ = *floatStr++; // 1st dec. place else *outPtr++ = '0'; // add a '0' when intDigit < 0 if( *floatStr ) // 2nd dec. place *outPtr++ = *floatStr++; else *outPtr++ = '0'; } //--------- percent sign (%) ------------// if( formatType == 3 ) *outPtr++ = '%'; //--------- negetive bracket ------------// if( inNum < 0 ) *outPtr++ = ')'; *outPtr++ = NULL; return outBuf; } //---------- End of function Misc::format ---------// //---------- Begin of function Misc::num_to_str --------// // // Convert a number into string. // // int inNum = the number to be converted // // return : the converted string. // char* Misc::num_to_str(int inNum) { static char strBuf[25]; return ltoa( inNum, strBuf, 10 ); } //---------- End of function Misc::format ---------// //---------- Begin of function Misc::nullify -------// // // Nullify and right trim a string field in the record // // strPtr = string pointer // strLen = string length // // Return : the nullied string which only stored in static // buffer temporary until next call to nullify() // // note : if the string is longer than the buffer space, the string // will be truncated // char* Misc::nullify(char* strPtr, int strLen) { int i; if( strLen > STR_BUF_LEN ) strLen = STR_BUF_LEN; memcpy( str_buf, strPtr, strLen ); for( i=strLen-1 ; i>=0 ; i-- ) // Right Trim { if( str_buf[i] != ' ' ) { str_buf[i+1] = NULL; break; } } if( i<0 ) // Empty value str_buf[0] = NULL; return str_buf; } //----------- End of function Misc::nullify ----------// //-------- Begin of function Misc::rtrim_fld ---------// // // Rtrim a text field and copy it to variable // // varPtr = pointer to the variable // fldPtr = pointer to the field // fldLen = length of the field // // Note must be pre-allocated with a len > fldLen+1 // void Misc::rtrim_fld(char* varPtr, char* fldPtr, int fldLen) { int rtrimLen = rtrim_len( fldPtr, 1, fldLen ); memcpy( varPtr, fldPtr, rtrimLen ); varPtr[rtrimLen] = NULL; } //---------- End of function Misc::rtrim_fld ---------// //------- Begin of function Misc::atoi ---------// // // Same as atoi() in stdlib.h instead it allows you to specify the // length of the string // // str = the string to be converted to integer // strLen = length of the string int Misc::atoi( char *str, int strLen ) { if ( strLen >= sizeof( str_buf ) ) strLen = sizeof( str_buf ) - 1 ; memcpy( str_buf, str, (size_t)strLen ) ; str_buf[strLen] = '\0' ; return ::atoi( str_buf ) ; } //---------- End of function Misc::atoi ---------// //------- Begin of function Misc::sqrt ---------// // // Find the square root of an long integer // // x = the value for calculating its square root // int Misc::sqrt(long x) { err_when( x < 0 ); long OddInt, OldArg, FirstSqrt; OddInt=1; OldArg=x; while(x>=0) { x-=OddInt; OddInt+=2; } FirstSqrt=OddInt >> 1; if( FirstSqrt*FirstSqrt - FirstSqrt + 1 > OldArg) return(FirstSqrt-1); else return(FirstSqrt); } //---------- End of function Misc::sqrt ---------// //------- Begin of function Misc::diagonal_distance ---------// // // Given two lengths in x and y coordination, then find the diagonal // distance between them // result = the square root of X*X + Y*Y // // x1, y1 = the starting point of the diagonal line // x2, y2 = the ending point of the diagonal line // int Misc::diagonal_distance(int x1, int y1, int x2, int y2) { int x = abs(x1-x2); int y = abs(y1-y2); return Misc::sqrt( x*x + y*y ); } //---------- End of function Misc::diagonal_distance ---------// //------- Begin of function Misc::points_distance ---------// // // Given two lengths in x and y coordination, then find the // distance between two points, taking diagonal distance // the same as the horizontal and vertical distances. // // x1, y1 = the starting point of the diagonal line // x2, y2 = the ending point of the diagonal line // int Misc::points_distance(int x1, int y1, int x2, int y2) { int x = abs(x1-x2); int y = abs(y1-y2); return max(x, y); } //---------- End of function Misc::points_distance ---------// //------- Begin of function Misc::get_random_seed --------// // long Misc::get_random_seed() { return random_seed; } //---------- End of function Misc::get_random_seed ---------// //------- Begin of function Misc::randomize --------// // void Misc::randomize() { set_random_seed(time(NULL)); } //---------- End of function Misc::randomize ---------// //------- Begin of function Misc::set_random_seed --------// // void Misc::set_random_seed(long randomSeed) { // ###### begin Gilbert 19/6 ######// err_when( is_seed_locked() ); // ###### end Gilbert 19/6 ######// random_seed = randomSeed; } //---------- End of function Misc::set_random_seed ---------// //------- Begin of function Misc::random ---------// // // maxNum = maximum random number, it must <= 0x7FFF // in 32 bit compiler = // // return : 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); } //---------- End of function Misc::random ---------// //------- Begin of function Misc::rand ---------// // // Return a random number from 0 to 0x7FFF // // return : a random number from from 0 to 0x7FFF // int Misc::rand() { #define MULTIPLIER 0x015a4e35L #define INCREMENT 1 #define RANDOM_MAX 0x7FFFU // ###### begin Gilbert 19/6 ######// err_when( is_seed_locked() ); // ###### end Gilbert 19/6 ######// random_seed = MULTIPLIER * random_seed + INCREMENT; return ((random_seed >> 16) & RANDOM_MAX); } //---------- End of function Misc::rand ---------// //------- Begin of function Misc::round ---------// // // Round the float no. to the 2 signicant values : // // Since this function is not called frequently, we can afford // to use a slower algorithm. // // inValue = the number to be rounded. // signPlace = round to no. of signicant places. // [int] roundDirection = 0-if <= 4, round to a smaller, if >=5 round to a bigger // 1-round to a smaller number // 2-round to a bigger number // (default : 0) // // return : the rounded number // float Misc::round(float inValue, int signPlace, int roundDirection) { int i; float baseValue = (float) 1; float minValue = (float) 10; for( i=2 ; i<=signPlace ; i++ ) minValue *= 10; while( inValue > minValue ) { inValue /= 10; baseValue *= 10; } float outValue = (float)((int)inValue) * baseValue; //-----------------------------------------------// // // If the result number is smaller than the given number // and the roundDirection is rounding to a bigger number, // than increase result number. // //-----------------------------------------------// if( outValue!=inValue ) { if( (roundDirection==0 && ((int)inValue)%10 >= 5) || roundDirection==2 ) { outValue = (float)((int)inValue+1) * baseValue; } } return outValue; } //---------- End of function Misc::round ---------// //------- Begin of function Misc::round_dec ---------// // // Round the number to its nearest 2 decimal places. // // inNum - the input number. // // Return : the output number // float Misc::round_dec(float inNum) { return (float)((int)(inNum * 100)) / 100; } //---------- End of function Misc::round_dec ---------// //------- Begin of function Misc::is_file_exist ---------// // // Check whether the given file exists in the current directory or not // // fileName = the name of the file // // return : 1 - the file exists // 0 - doesn't exist // int Misc::is_file_exist(char* fileName) { WIN32_FIND_DATA findData; HANDLE findHandle = FindFirstFile( fileName, &findData ); return findHandle!=INVALID_HANDLE_VALUE; } //---------- End of function Misc::is_file_exist ---------// //------- Begin of function Misc::change_file_ext ---------// // // Change file extension. // // desFileName = the destination file name to be written // srcFileName = the source file name // newExt = the new extension. // void Misc::change_file_ext(char* desFileName, char* srcFileName, char* newExt) { int nameLen = m.str_chr(srcFileName, '.'); // include the '.' in the nameLen err_when( nameLen<1 || nameLen>9 || strlen(newExt)>3 ); memcpy( desFileName, srcFileName, nameLen ); strcpy( desFileName+nameLen, newExt ); // extension for scenarion text file } //---------- End of function Misc::change_file_ext ---------// //------- Begin of function Misc::extract_file_name ---------// // // Extract the file name from a full file path. // // desFileName = the destination buffer to be written // srcFileName = the source file name // void Misc::extract_file_name(char* desFileName, char* srcFileName) { int i; for( i=strlen(srcFileName) ; i>=0 ; i-- ) { if( srcFileName[i]=='\\' ) // get last '\' before the file name break; } strncpy(desFileName, srcFileName+i+1, MAX_PATH); desFileName[MAX_PATH]=NULL; } //---------- End of function Misc::extract_file_name ---------// //------- Begin of function Misc::num_th ---------// // // Convert the number into 99th format. // // inNum = the input number // // return : the result string // char* Misc::num_th(int inNum) { static String str; str = format(inNum); if( inNum >=11 && inNum <= 13 ) { str += "th"; } else { switch( inNum%10 ) { case 1: str += "st"; break; case 2: str += "nd"; break; case 3: str += "rd"; break; default: str += "th"; break; } } return str; } //---------- End of function Misc::num_th ---------// //------- Begin of function Misc::get_time ---------// // unsigned long Misc::get_time() { return timeGetTime(); } //---------- End of function Misc::get_time ---------// //------- Begin of function Misc::del_array_rec ---------// // // Delete a record in an array. // // arrayBody - the array pointer // arraySize - size of the array // recSize - record size // delRecno - recno to be deleted. // void Misc::del_array_rec(void* arrayBody, int arraySize, int recSize, int delRecno) { err_when( arraySize<1 ); err_when( delRecno<1 || delRecno>arraySize); int t = delRecno-1; char* arrayPtr = (char*) arrayBody; memmove( arrayPtr+recSize*t, arrayPtr+recSize*(t+1), recSize * (arraySize-t-1) ); } //---------- End of function Misc::del_array_rec ---------// //-------- Begin of function Misc::cal_move_around_a_point -------// // This function is used to return the x_Offset and y_Offset from the // center of the square. The detail is shown in the following figure. // // // 21 20 19 18 17 // 22 7 6 5 16 // 23 8 1 4 15 // 24 9 2 3 14 // 25 10 11 12 13 // // Assume the square is 5x5, 1 is the center of the square. The input // value of num determine which point is processed. For instance, 9 is // processed if num=9. // // using the center as the reference point, (xShift, yShift) = (-1, -1) // for num=7, (xShift, yShift) = (0,2) for num=11. // // For num>25 in this case, multiply of 25 will be cut out until num<=25. // void Misc::cal_move_around_a_point(short num, short width, short height, int& xShift, int& yShift) { short maxSqtSize = (width>height) ? height+1 : width+1; //short num2 = num%(maxSqtSize*maxSqtSize) + 1; short num2 = (num-1)%(maxSqtSize*maxSqtSize) + 1; if(num2<=MOVE_AROUND_TABLE_SIZE) { xShift = int(*(move_around_table_x+num2-1)); yShift = int(*(move_around_table_y+num2-1)); /*#ifdef DEBUG2 int xShift2, yShift2; cal_move_around_a_point_v2(num, width, height, xShift2, yShift2); err_when(xShift!=xShift2); err_when(yShift!=yShift2); #endif*/ return; } else cal_move_around_a_point_v2(num, width, height, xShift, yShift); } //------ End of function Misc::cal_move_around_a_point ---------// //-------- Begin of function Misc::cal_move_around_a_point_v2 -------// void Misc::cal_move_around_a_point_v2(short num, short width, short height, int& xShift, int& yShift) { short maxSqtSize = (width>height) ? height+1 : width+1; //short num2 = num%(maxSqtSize*maxSqtSize) + 1; short num2 = (num-1)%(maxSqtSize*maxSqtSize) + 1; if(num2<=1) { xShift = yShift = 0; return; } int sqtCount = 1; while(sqtCount<210) // the max. size of the map is 200x200 { if(num2<=sqtCount*sqtCount) break; else sqtCount += 2; } int filter = (sqtCount-1)/2; // is an integer int refNum = num2 - (sqtCount-2)*(sqtCount-2); //=====================================// // some adjustment to the refNum can // generate different mode of result //=====================================// // note: sqtCount>=3 for this mode refNum = (refNum-1-(sqtCount-3)/2)%(4*(sqtCount-1)) + 1; //-------------------------------------------------// // determine xMag //-------------------------------------------------// int xMag; if(refNum < sqtCount) xMag = refNum - 1; else { if(refNum>=sqtCount && refNum<=3*(sqtCount-1)) xMag = (sqtCount<<1) - 1 - refNum; //(sqtCount-1) - (refNum-sqtCount); else if(refNum >= sqtCount+2*(sqtCount-1)) xMag = refNum + 3 - (sqtCount<<2); //(refNum-sqtCount-2*(sqtCount-1)) - (sqtCount-1); else err_here(); } //-------------------------------------------------// // calculate xShift //-------------------------------------------------// if(xMag>0) // +ve xShift = (xMag>filter) ? filter : xMag; else // -ve xShift = (-xMag>filter) ? -filter : xMag; //-------------------------------------------------// // calculate yShift //-------------------------------------------------// //ySign = (refNum>sqtCount && refNum<=3*sqtCount-3) ? -1 : 1; int yMag = (sqtCount-1) - abs(xMag); // abs(xMag) + abs(yMag) always = (sqtCount-1) if(refNum>sqtCount && refNum<=3*sqtCount-3) // -ve yShift = (yMag>filter) ? -filter : -yMag; else // +ve yShift = (yMag>filter) ? filter : yMag; } //------ End of function Misc::cal_move_around_a_point_v2 ---------// //-------- Begin of function Misc::construct_move_around_table -------// void Misc::construct_move_around_table() { if(move_around_table_size==MOVE_AROUND_TABLE_SIZE) return; // table already created int xShift, yShift; char *xPtr = move_around_table_x; char *yPtr = move_around_table_y; for(int i=1; i<=MOVE_AROUND_TABLE_SIZE; ++i, xPtr++, yPtr++) { cal_move_around_a_point_v2(i, MOVE_AROUND_TABLE_SIZE, MOVE_AROUND_TABLE_SIZE, xShift, yShift); *xPtr = char(xShift); *yPtr = char(yShift); } move_around_table_size = MOVE_AROUND_TABLE_SIZE; } //------ End of function Misc::construct_move_around_table ---------// //-------- Begin of function Misc::set_surround_bit -------// void Misc::set_surround_bit(long int& flag, int bitNo) { static long int bitFlag[20] = {0x000001, 0x000002, 0x000004, 0x000008, 0x000010, 0x000020, 0x000040, 0x000080, 0x000100, 0x000200, 0x000400, 0x000800, 0x001000, 0x002000, 0x004000, 0x008000, 0x010000, 0x020000, 0x040000, 0x080000}; err_when(bitNo<0 || bitNo>=20); flag |= bitFlag[bitNo]; } //------ End of function Misc::set_surround_bit ---------// //------- Begin of function Misc::roman_number -------// char* Misc::roman_number(int inNum) { err_when( inNum<1 || inNum >= 1000 ); static char* roman_number_array[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X" }; static String str; str = ""; if( inNum > 100 ) { str += roman_number_array[inNum/100-1]; inNum = inNum - inNum/100*100; } if( inNum > 10 ) { str += roman_number_array[(inNum-1)/10-1]; inNum = inNum - (inNum-1)/10*10; } err_when( inNum<1 || inNum>10 ); str += roman_number_array[inNum-1]; return str; } //------ End of function Misc::roman_number ---------// // ###### begin Gilbert 19/6 ########// Misc::Misc() { freeze_seed = 0; construct_move_around_table(); } void Misc::lock_seed() { freeze_seed = 1; } void Misc::unlock_seed() { freeze_seed = 0; } int Misc::is_seed_locked() { return freeze_seed > 0; } // ###### end Gilbert 19/6 ########//