#include "ssDefs.hpp"

#undef NDEBUG					// we need to get the real assertion routines...

#include <cassert>
#include <cstdio>

using namespace SS;

/*****************************************************************************
 *
 * Function:		SS::assertFail()
 *
 * Description:		Assertion failure function -- calls either user-defined
 *					error handler or native assert() function.
 *
 *****************************************************************************/

void SS::assertFail (const char* expr, const char* file, int line, const char* /*message*/)
{
	#if defined (SS_BUILD_ACC)
		__assert((const char*)expr,(const char*)file,line);
	#elif defined (SS_BUILD_GCC) && defined (SS_OS_LINUX)
		__assert_fail(expr,file,line,"unknown function");
	#elif defined (SS_BUILD_GCC) && defined (SS_OS_MAC)
		__assert((const char*)expr,file,line);
	#elif defined (SS_BUILD_GCC)
		__assert((const char*)expr,line,file);
	#elif defined (SS_BUILD_CW)
		__assertion_failed((char*)expr,(const char*)file,line);
	#elif defined (SS_BUILD_BC)
		_assert((const char*)expr,(const char*)file,line);
	#elif defined (SS_BUILD_IVA)
		_assert(expr,file,line);
	#else
//		_assert((void*)expr,(void*)file,line);
	#endif
}


/*****************************************************************************
 *
 * Function:		SS::intChop()
 *
 * Description:		
 *
 *****************************************************************************/

int SS::intChop (const float& f) 
{ 
	INT32 a			= *reinterpret_cast<const INT32*>(&f);			// take bit pattern of float into a register
	INT32 sign		= (a>>31);										// sign = 0xFFFFFFFF if original value is negative, 0 if positive
	INT32 mantissa	= (a&((1<<23)-1))|(1<<23);						// extract mantissa and add the hidden bit
	INT32 exponent	= ((a&0x7fffffff)>>23)-127;						// extract the exponent
	INT32 r			= ((UINT32)(mantissa)<<8)>>(31-exponent);		// ((1<<exponent)*mantissa)>>24 -- (we know that mantissa > (1<<24))
	return ((r ^ (sign)) - sign ) &~ (exponent>>31);				// add original sign. If exponent was negative, make return value 0.
}

/*****************************************************************************
 *
 * Function:		SS::intFloor()
 *
 * Description:		
 *
 *****************************************************************************/

int SS::intFloor (const float& f) 
{ 
	INT32 a			= *reinterpret_cast<const INT32*>(&f);									// take bit pattern of float into a register
	INT32 sign		= (a>>31);																// sign = 0xFFFFFFFF if original value is negative, 0 if positive
	a&=0x7fffffff;																			// we don't need the sign any more
	INT32 exponent	= (a>>23)-127;															// extract the exponent
	INT32 expsign   = ~(exponent>>31);														// 0xFFFFFFFF if exponent is positive, 0 otherwise
	INT32 imask		= ( (1<<(31-(exponent))))-1;											// mask for true integer values
	INT32 mantissa	= (a&((1<<23)-1));														// extract mantissa (without the hidden bit)
	INT32 r			= ((UINT32)(mantissa|(1<<23))<<8)>>(31-exponent);						// ((1<<exponent)*(mantissa|hidden bit))>>24 -- (we know that mantissa > (1<<24))
	r = ((r & expsign) ^ (sign)) + ((!((mantissa<<8)&imask)&(expsign^((a-1)>>31)))&sign);	// if (fabs(value)<1.0) value = 0; copy sign; if (value < 0 && value==(int)(value)) value++; 
	return r;
}

/*****************************************************************************
 *
 * Function:		SS::intCeil()
 *
 * Description:		
 *
 *****************************************************************************/

int SS::intCeil (const float& f) 
{ 
	INT32 a			= *reinterpret_cast<const INT32*>(&f) ^ 0x80000000;						// take bit pattern of float into a register
	INT32 sign		= (a>>31);																// sign = 0xFFFFFFFF if original value is negative, 0 if positive
	a&=0x7fffffff;																			// we don't need the sign any more
	INT32 exponent	= (a>>23)-127;															// extract the exponent
	INT32 expsign   = ~(exponent>>31);														// 0xFFFFFFFF if exponent is positive, 0 otherwise
	INT32 imask		= ( (1<<(31-(exponent))))-1;											// mask for true integer values
	INT32 mantissa	= (a&((1<<23)-1));														// extract mantissa (without the hidden bit)
	INT32 r			= ((UINT32)(mantissa|(1<<23))<<8)>>(31-exponent);						// ((1<<exponent)*(mantissa|hidden bit))>>24 -- (we know that mantissa > (1<<24))
	r = ((r & expsign) ^ (sign)) + ((!((mantissa<<8)&imask)&(expsign^((a-1)>>31)))&sign);	// if (fabs(value)<1.0) value = 0; copy sign; if (value < 0 && value==(int)(value)) value++; 
	return -r;
}

//------------------------------------------------------------------------
