/***************************************************************************** ** ** ** Neversoft Entertainment ** ** ** ** Copyright (C) 1999 - All Rights Reserved ** ** ** ****************************************************************************** ** ** ** Project: Core Library ** ** ** ** Module: Math (MTH) ** ** ** ** File name: math.cpp ** ** ** ** Created by: 11/24/99 - mjb ** ** ** ** Description: Math Library code ** ** ** *****************************************************************************/ /***************************************************************************** ** Includes ** *****************************************************************************/ #include #ifdef __PLAT_WN32__ #include #endif #ifdef __PLAT_XBOX__ #include #endif /***************************************************************************** ** DBG Information ** *****************************************************************************/ #include #if DEBUGGING_REPLAY_RND #include #include extern int *gReplayTestRndLine; extern uint64 *gReplayTestRndFunc; static int gRndIndex = 0; static int gTestMode = 0; #define MAX_RND_TEST_INDEX 3666 #endif namespace Mth { /***************************************************************************** ** Externals ** *****************************************************************************/ /***************************************************************************** ** Defines ** *****************************************************************************/ /***************************************************************************** ** Private Types ** *****************************************************************************/ /***************************************************************************** ** Private Data ** *****************************************************************************/ /***************************************************************************** ** Public Data ** *****************************************************************************/ /***************************************************************************** ** Private Prototypes ** *****************************************************************************/ /***************************************************************************** ** Private Functions ** *****************************************************************************/ /***************************************************************************** ** Public Functions ** *****************************************************************************/ static int RandSeed; static int RandA; static int RandB; static int RandSeed2; static int RandC; static int RandD; void InitialRand(int a) { RandSeed = a; RandA = 314159265; RandB = 178453311; RandSeed2 = a; RandC = 314159265; RandD = 178453311; } #if DEBUGGING_REPLAY_RND static bool gFuckedUp = false; bool RndFuckedUp( void ) { if ( gTestMode != 2 ) return ( false ); return ( gFuckedUp ); } int Rnd_DbgVersion(int n, int line, char *file) { if ( gRndIndex < MAX_RND_TEST_INDEX ) { if ( gTestMode == 1 ) { // record: gReplayTestRndLine[ gRndIndex ] = line; strncpy( ( char * )( &gReplayTestRndFunc[ gRndIndex ] ), file, 8 ); gRndIndex++; } else if ( gTestMode == 2 ) { // compare: if ( line != gReplayTestRndLine[ gRndIndex ] ) { char temp[ 9 ]; strncpy( temp, ( char * )( &gReplayTestRndFunc[ gRndIndex ] ), 8 ); temp[ 8 ] = '\0'; Dbg_Message( "********Rnd Fuckup!********* num %d time %d\ncurrent line %d file %s conflicts with prev line %d file %s", Tmr::GetTime( ), gRndIndex, line, file, gReplayTestRndLine[ gRndIndex ], temp ); gFuckedUp = true; } else { gFuckedUp = false; } gRndIndex++; } } RandSeed=RandSeed*RandA+RandB; RandA = (RandA ^ RandSeed) + (RandSeed>>4); RandB += (RandSeed>>3) - 0x10101010L; return (int)((RandSeed&0xffff) * n)>>16; } void SetRndTestMode( int mode ) { gTestMode = mode; gRndIndex = 0; } #else int Rnd(int n) { RandSeed=RandSeed*RandA+RandB; RandA = (RandA ^ RandSeed) + (RandSeed>>4); RandB += (RandSeed>>3) - 0x10101010L; return (int)((RandSeed&0xffff) * n)>>16; } #endif int Rnd2(int n) { RandSeed2=RandSeed2*RandC+RandD; RandC = (RandC ^ RandSeed2) + (RandSeed2>>4); RandD += (RandSeed2>>3) - 0x10101010L; return (int)((RandSeed2&0xffff) * n)>>16; } // Return a random number in the range +/- n float PlusOrMinus(float n) { float range = (float)(Rnd(10000)); range -= 5000.0f; return n * range / 5000.0f; } #if 0 // 8192 makes Kensinf and sinf match to all 6 decimal places, (when x is in the range -2pi to 2pi) // apart from very occassionally where there might be a .000001 difference. // The table size must be a power of two. #define SINF_NUM_DIVISIONS 8192 static float pSinLookup[SINF_NUM_DIVISIONS+5]; // +5 for good measure, since sometimes we look one beyond the end. void InitSinLookupTable() { // The lookup table covers a whole period (0 to 2pi) of the sin function. // This saves a few if's in the sin function. for (int i=0; i fabsf( delta ) ) { return ( current - fabsf( delta ) ); } return ( target ); } if ( ( target - current ) > fabsf( delta ) ) { return ( current + fabsf( delta ) ); } return ( target ); } int RunFilter( int target, int current, int delta ) { if ( target < current ) { if ( current - target > abs( delta ) ) return ( target ); return ( current - abs( delta ) ); } if ( target - current > abs( delta ) ) return ( target ); return ( current + abs( delta ) ); } // returns atan(y/x) with appropiate sign determinations // although it does not work, as we cant; find atan ..... /* float Atan2 (float y, float x) { if (x == 0.0f) { if (y < 0.0f) return(-PI/2.0f); else return( PI/2.0f); } else { if (x < 0.0f) { if (y < 0.0f) return(atan(y/x)-PI); else return(atan(y/x)+PI); } else { return(atan(y/x)); } } } */ } // namespace Mth