int _winstart(void) { char *szCmd; STARTUPINFO startinfo; __set_app_type(__GUI_APP); _controlfp(0x10000, 0x30000); szCmd = GetCommandLine(); if (szCmd) { while (' ' == *szCmd) szCmd++; if ('\"' == *szCmd) { while (*++szCmd) if ('\"' == *szCmd) { szCmd++; break; } } else { while (*szCmd && ' ' != *szCmd) szCmd++; } while (' ' == *szCmd) szCmd++; } GetStartupInfo(&startinfo); exit(WinMain(GetModuleHandle(NULL), NULL, szCmd, (startinfo.dwFlags & STARTF_USESHOWWINDOW) ? startinfo.wShowWindow : SW_SHOWDEFAULT)); }
/////////////////////////////////////////////////////////////////////////////// // constructor of any FloatException has to clear exception CFltException::CFltException (const char *_S) : CMathException(_S) { _clearfp(); // turn off exception for _controlfp to succeed UINT uiCW = _controlfp (0, 0); // save current control word _fpreset(); // reset everything _controlfp (uiCW, (UINT)~0); // restore control word }
static void setrounding(TaskData *mdTaskData, Handle args) { switch (get_C_long(mdTaskData, DEREFWORDHANDLE(args))) { case POLY_ROUND_TONEAREST: _controlfp(_RC_NEAR, _MCW_RC); break; // Choose nearest case POLY_ROUND_DOWNWARD: _controlfp(_RC_DOWN, _MCW_RC); break; // Towards negative infinity case POLY_ROUND_UPWARD: _controlfp(_RC_UP, _MCW_RC); break; // Towards positive infinity case POLY_ROUND_TOZERO: _controlfp(_RC_CHOP, _MCW_RC); break; // Truncate towards zero } }
void EnableFPE() { // clear any outstanding exceptions before enabling, otherwise they'll // trip immediately _clearfp(); _controlfp(_EM_INEXACT | _EM_UNDERFLOW, _MCW_EM); }
static DWORD WINAPI TclWinThreadStart( LPVOID lpParameter) /* The WinThread structure pointer passed * from TclpThreadCreate */ { WinThread *winThreadPtr = (WinThread *) lpParameter; LPTHREAD_START_ROUTINE lpOrigStartAddress; LPVOID lpOrigParameter; if (!winThreadPtr) { return TCL_ERROR; } _controlfp(winThreadPtr->fpControl, _MCW_EM | _MCW_RC | 0x03000000 /* _MCW_DN */ #if !defined(_WIN64) | _MCW_PC #endif ); lpOrigStartAddress = winThreadPtr->lpStartAddress; lpOrigParameter = winThreadPtr->lpParameter; ckfree(winThreadPtr); return lpOrigStartAddress(lpOrigParameter); }
void _start(void) { __TRY__ int argc; char **argv; char **env; _startupinfo start_info; // Sets the current application type __set_app_type(_CONSOLE_APP); // Set default FP precision to 53 bits (8-byte double) // _MCW_PC (Precision control) is not supported on // the ARM and x64 architectures #if defined(_X86_) && !defined(__x86_64) _controlfp(_PC_53, _MCW_PC); #endif start_info.newmode = 0; if ( __getmainargs( &argc, &argv, &env, 0, &start_info ) < 0 ) { ExitProcess(-1); } else { exit( main(argc, argv, env) ); } }
int main() { try { _controlfp( _RC_UP, _MCW_RC ); throw 1; } catch ( ... ) { // Sets the rounding mode to 0 and show that it's realy the case. _controlfp( 0, _MCW_RC ); } // After the catch, this value will not be 0 in x64 unsigned int cw = _controlfp( 0, 0 ) & _MCW_RC; return (cw != 0); }
/* From crlibm */ unsigned long long mwFixFPUPrecision(void) { #if MW_IS_X86_32 #if defined(_MSC_VER) || defined(__MINGW32__) unsigned int oldcw, cw; /* CHECKME */ oldcw = _controlfp(0, 0); #ifdef __MINGW32__ _controlfp(_PC_53, _MCW_PC); #else _controlfp(_PC_53, MCW_PC); #endif return (unsigned long long) oldcw; #elif defined(__SUNPRO_C) /* Sun Studio */ unsigned short oldcw, cw; __asm__ ("movw $639, -22(%ebp)"); __asm__ ("fldcw -22(%ebp)"); return (unsigned long long) oldcw; #elif !defined(__APPLE__) /* GCC, clang */ /* x87 FPU never used on OS X */ unsigned short oldcw, cw; /* save old state */ _FPU_GETCW(oldcw); /* Set FPU flags to use double, not double extended, with rounding to nearest */ cw = (_FPU_DEFAULT & ~_FPU_EXTENDED)|_FPU_DOUBLE; _FPU_SETCW(cw); return (unsigned long long) oldcw; #else return 0; #endif /* defined(_MSC_VER) || defined(__MINGW32__) */ #else /* */ return 0; #endif /* MW_IS_X86 */ }
void sigfpe_test() { // Code taken from http://www.devx.com/cplus/Article/34993/1954 //Set the x86 floating-point control word according to what //exceptions you want to trap. _clearfp(); //Always call _clearfp before setting the control //word //Because the second parameter in the following call is 0, it //only returns the floating-point control word unsigned int cw; #if _MSC_VER<1400 cw = _controlfp(0, 0); //Get the default control #else _controlfp_s(&cw, 0, 0); //Get the default control #endif //word //Set the exception masks off for exceptions that you want to //trap. When a mask bit is set, the corresponding floating-point //exception is //blocked from being generating. cw &=~(EM_OVERFLOW|EM_UNDERFLOW|EM_ZERODIVIDE| EM_DENORMAL|EM_INVALID); //For any bit in the second parameter (mask) that is 1, the //corresponding bit in the first parameter is used to update //the control word. unsigned int cwOriginal = 0; #if _MSC_VER<1400 cwOriginal = _controlfp(cw, MCW_EM); //Set it. #else _controlfp_s(&cwOriginal, cw, MCW_EM); //Set it. #endif //MCW_EM is defined in float.h. // Divide by zero float a = 1.0f; float b = 0.0f; float c = a/b; c; //Restore the original value when done: //_controlfp_s(cwOriginal, MCW_EM); }
// Windows version static int getrounding(TaskData *) { switch (_controlfp(0,0) & _MCW_RC) { case _RC_NEAR: return POLY_ROUND_TONEAREST; case _RC_DOWN: return POLY_ROUND_DOWNWARD; case _RC_UP: return POLY_ROUND_UPWARD; case _RC_CHOP: return POLY_ROUND_TOZERO; } return 0; // Keep the compiler happy }
HINSTANCE R_loadLibrary(const char *path, int asLocal, int now, const char *search) { HINSTANCE tdlh; unsigned int dllcw, rcw; int useSearch = search && search[0]; rcw = _controlfp(0,0) & ~_MCW_IC; /* Infinity control is ignored */ _clearfp(); if(useSearch) setDLLSearchPath(search); tdlh = LoadLibrary(path); if(useSearch) setDLLSearchPath(NULL); dllcw = _controlfp(0,0) & ~_MCW_IC; if (dllcw != rcw) { _controlfp(rcw, _MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC); if (LOGICAL(GetOption1(install("warn.FPU")))[0]) warning(_("DLL attempted to change FPU control word from %x to %x"), rcw,dllcw); } return(tdlh); }
ulong FPstatus(ulong fsr, ulong mask) { ulong old = getFPstatus(); fsr = (fsr&mask) | (old&~mask); if(fsr!=old){ _clearfp(); if(fsr){ ulong fcr = _controlfp(0,0); double x = 1., y = 1e200, z = 0.; _controlfp(_MCW_EM,_MCW_EM); if(fsr&INEX) z = x + y; if(fsr&OVFL) z = y*y; if(fsr&UNFL) z = (x/y)/y; if(fsr&ZDIV) z = x/z; if(fsr&INVAL) z = z/z; _controlfp(fcr,_MCW_EM); } } return(old&mask); }
///////////////////////////////////////////////////////////////////////////////// // main function int main(int argc, char* argv[]) { // detect memory leaks in win32 #if (defined(WITH_MEMORYCHECK) && !defined(NDEBUG) && defined (GTCMT_WIN32)) // set memory checking flags int iDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); iDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF; iDbgFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag( iDbgFlag ); //_CrtSetBreakAlloc(245); #endif // enable floating point exceptions in win32 #if (defined(WITH_FLOATEXCEPTIONS) && !defined(NDEBUG) && defined (GTCMT_WIN32)) // enable check for exceptions (don't forget to enable stop in MSVC!) _controlfp(~(_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_DENORMAL), _MCW_EM) ; #endif // #ifndef WITHOUT_EXCEPTIONS // argument 2 contains the working dir if (argc > 2) cTestDataDir.assign(argv[2]); // see http://stackoverflow.com/questions/3546054/how-do-i-run-a-single-test-with-unittest if( argc > 1 ) { //walk list of all tests, add those with a name that //matches one of the arguments to a new TestList const UnitTest::TestList& allTests( UnitTest::Test::GetTestList() ); UnitTest::TestList selectedTests; UnitTest::Test* p = allTests.GetHead(); while( p ) { if( strcmp( p->m_details.suiteName, argv[ 1 ] ) == 0 ) { selectedTests.Add( p ); } p = p->m_nextTest; } selectedTests.Add(0); //run selected test(s) only UnitTest::TestReporterStdout reporter; UnitTest::TestRunner runner( reporter ); return runner.RunTestsIf( selectedTests, 0, UnitTest::True(), 0 ); } else { return UnitTest::RunAllTests(); } }
int TclpThreadCreate( Tcl_ThreadId *idPtr, /* Return, the ID of the thread. */ Tcl_ThreadCreateProc *proc, /* Main() function of the thread. */ ClientData clientData, /* The one argument to Main(). */ int stackSize, /* Size of stack for the new thread. */ int flags) /* Flags controlling behaviour of the new * thread. */ { WinThread *winThreadPtr; /* Per-thread startup info */ HANDLE tHandle; winThreadPtr = (WinThread *)ckalloc(sizeof(WinThread)); winThreadPtr->lpStartAddress = (LPTHREAD_START_ROUTINE) proc; winThreadPtr->lpParameter = clientData; winThreadPtr->fpControl = _controlfp(0, 0); EnterCriticalSection(&joinLock); *idPtr = 0; /* must initialize as Tcl_Thread is a pointer and * on WIN64 sizeof void* != sizeof unsigned */ #if defined(_MSC_VER) || defined(__MSVCRT__) || defined(__BORLANDC__) tHandle = (HANDLE) _beginthreadex(NULL, (unsigned) stackSize, (Tcl_ThreadCreateProc*) TclWinThreadStart, winThreadPtr, 0, (unsigned *)idPtr); #else tHandle = CreateThread(NULL, (DWORD) stackSize, TclWinThreadStart, winThreadPtr, 0, (LPDWORD)idPtr); #endif if (tHandle == NULL) { LeaveCriticalSection(&joinLock); return TCL_ERROR; } else { if (flags & TCL_THREAD_JOINABLE) { TclRememberJoinableThread(*idPtr); } /* * The only purpose of this is to decrement the reference count so the * OS resources will be reaquired when the thread closes. */ CloseHandle(tHandle); LeaveCriticalSection(&joinLock); return TCL_OK; } }
/** * @brief Main game loop */ void Sys_GameLoop(void) { #ifdef LEGACY_DEBUG int startTime, endTime, totalMsec, countMsec; startTime = endTime = totalMsec = countMsec = 0; #endif while (qtrue) { #if defined(_MSC_VER) && defined(LEGACY_DEBUG) && !defined(_WIN64) // set low precision every frame, because some system calls // reset it arbitrarily _controlfp(_PC_24, _MCW_PC); _controlfp(-1, _MCW_EM); // no exceptions, even if some crappy // syscall turns them back on! #endif #ifdef LEGACY_DEBUG startTime = Sys_Milliseconds(); #endif // Improve input responsiveness by moving sampling to other side of framerate limiter - moved to Com_Frame() //IN_Frame(); Com_Frame(); #ifdef LEGACY_DEBUG endTime = Sys_Milliseconds(); totalMsec += endTime - startTime; countMsec++; if (com_speeds->integer) { Com_Printf("frame:%i total used:%i frame time:%i\n", countMsec, totalMsec, endTime - startTime); } #endif } }
bool disableFPExceptions() { bool exceptionsWereEnabled = false; #if defined(WIN32) _clearfp(); uint32_t cw = _controlfp(0, 0); exceptionsWereEnabled = ~cw & (_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW); cw |= _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW; _controlfp(cw, _MCW_EM); #elif defined(__OSX__) #if !defined(MTS_SSE) #warning SSE must be enabled to handle FP exceptions on OSX #else exceptionsWereEnabled = query_fpexcept_sse() != 0; #endif #else exceptionsWereEnabled = fegetexcept() & (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); fedisableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); #endif #if defined(MTS_SSE) disable_fpexcept_sse(); #endif return exceptionsWereEnabled; }
ulong getFPcontrol(void) { ulong fcr, fcr32 = _controlfp(0,0); switch(fcr32&_MCW_RC){ case _RC_NEAR: fcr = RND_NR; break; case _RC_DOWN: fcr = RND_NINF; break; case _RC_UP: fcr = RND_PINF; break; case _RC_CHOP: fcr = RND_Z; break; } if(!(fcr32&_EM_INEXACT)) fcr |= INEX; if(!(fcr32&_EM_OVERFLOW)) fcr |= OVFL; if(!(fcr32&_EM_UNDERFLOW)) fcr |= UNFL; if(!(fcr32&_EM_ZERODIVIDE)) fcr |= ZDIV; if(!(fcr32&_EM_INVALID)) fcr |= INVAL; return fcr; }
ulong FPcontrol(ulong fcr, ulong mask) { ulong old = getFPcontrol(); ulong fcr32 = _MCW_EM, mask32 = _MCW_RC|_MCW_EM; fcr = (fcr&mask) | (old&~mask); if(fcr&INEX) fcr32 ^= _EM_INEXACT; if(fcr&OVFL) fcr32 ^= _EM_OVERFLOW; if(fcr&UNFL) fcr32 ^= _EM_UNDERFLOW; if(fcr&ZDIV) fcr32 ^= _EM_ZERODIVIDE; if(fcr&INVAL) fcr32 ^= _EM_INVALID; switch(fcr&RND_MASK){ case RND_NR: fcr32 |= _RC_NEAR; break; case RND_NINF: fcr32 |= _RC_DOWN; break; case RND_PINF: fcr32 |= _RC_UP; break; case RND_Z: fcr32 |= _RC_CHOP; break; } _controlfp(fcr32,mask32); return(old&mask); }
void restoreFPExceptions(bool oldState) { bool currentState; #if defined(WIN32) uint32_t cw = _controlfp(0, 0); currentState = ~cw & (_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW); #elif defined(__OSX__) #if !defined(MTS_SSE) #warning SSE must be enabled to handle FP exceptions on OSX #else currentState = query_fpexcept_sse() != 0; #endif #else currentState = fegetexcept() & (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); #endif if (oldState != currentState) { if (oldState) enableFPExceptions(); else disableFPExceptions(); } }
int main(int argc, char* argv[]) { #ifdef _WIN32 assert((_controlfp(0,0)&_MCW_RC)==_RC_NEAR); #endif bool result =false; { //test vertex-triangle Vec3d verts_old[4]= {Vec3d(-2,0,1.0000001),Vec3d(0,0,1),Vec3d(-1,0,-1),Vec3d(1,0,-1)}; Vec3d verts_new[4]= {Vec3d(2.1,0,0.999999),Vec3d(0,0,1),Vec3d(-1,0,-1),Vec3d(1,0,-1)}; bool is_edge_edge = false; rootparity::RootParityCollisionTest test( verts_old[0],verts_old[1],verts_old[2],verts_old[3], verts_new[0],verts_new[1],verts_new[2],verts_new[3],is_edge_edge); result = test.run_test(); } { //test edge-edge Vec3d verts_old[4]= {Vec3d(-1,0,0),Vec3d(1,0,0),Vec3d(0,1,-1),Vec3d(0,1,1)}; Vec3d verts_new[4]= {Vec3d(-1,0,0),Vec3d(1,0,0),Vec3d(0,0,-1),Vec3d(0,0,1)}; bool is_edge_edge = true; rootparity::RootParityCollisionTest test( verts_old[0],verts_old[1],verts_old[2],verts_old[3], verts_new[0],verts_new[1],verts_new[2],verts_new[3],is_edge_edge); result = test.run_test(); } return 0; }
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; double time, oldtime, newtime; char *cddir; /* previous instances do not exist in Win32 */ if (hPrevInstance) return 0; global_hInstance = hInstance; ParseCommandLine (lpCmdLine); // if we find the CD, add a +set cddir xxx command line cddir = Sys_ScanForCD (); if (cddir && argc < MAX_NUM_ARGVS - 3) { int i; // don't override a cddir on the command line for (i=0 ; i<argc ; i++) if (!strcmp(argv[i], "cddir")) break; if (i == argc) { argv[argc++] = "+set"; argv[argc++] = "cddir"; argv[argc++] = cddir; } } Detect_WinNT(); Qcommon_Init (argc, argv); oldtime = Sys_Milliseconds (); /* main window message loop */ while (1) { // if at a full screen console, don't update unless needed if (Minimized || (dedicated && dedicated->value) ) { Sleep (1); } while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage (&msg, NULL, 0, 0)) Com_Quit (); sys_msg_time = (double)msg.time; TranslateMessage (&msg); DispatchMessage (&msg); } do { newtime = Sys_Milliseconds (); time = newtime - oldtime; } while (time < 1); // Con_Printf ("time:%5.2f - %5.2f = %5.2f\n", newtime, oldtime, time); // _controlfp( ~( _EM_ZERODIVIDE /*| _EM_INVALID*/ ), _MCW_EM ); _controlfp( _PC_24, _MCW_PC ); Qcommon_Frame (time); oldtime = newtime; } // never gets here return TRUE; }
void DisableFPE() { _controlfp(_MCW_EM, _MCW_EM); }
void _setdefaultprecision() { _controlfp(_PC_53, _MCW_PC); }
static void fpe_reset(Sigfunc *handler) { /* Reset the exception handling machinery, and reset the signal * handler for SIGFPE to the given handler. */ /*-- SunOS and Solaris ----------------------------------------------------*/ #if defined(sun) /* References: ieee_handler, ieee_sun, ieee_functions, and ieee_flags man pages (SunOS or Solaris) cc -c -I/usr/local/python/include fpectlmodule.c ld -G -o fpectlmodule.so -L/opt/SUNWspro/lib fpectlmodule.o -lsunmath -lm */ #include <math.h> #ifndef _SUNMATH_H extern void nonstandard_arithmetic(void); extern int ieee_flags(const char*, const char*, const char*, char **); extern long ieee_handler(const char*, const char*, sigfpe_handler_type); #endif char *mode="exception", *in="all", *out; (void) nonstandard_arithmetic(); (void) ieee_flags("clearall",mode,in,&out); (void) ieee_handler("set","common",(sigfpe_handler_type)handler); PyOS_setsig(SIGFPE, handler); /*-- HPUX -----------------------------------------------------------------*/ #elif defined(__hppa) || defined(hppa) /* References: fpsetmask man page */ /* cc -Aa +z -c -I/usr/local/python/include fpectlmodule.c */ /* ld -b -o fpectlmodule.sl fpectlmodule.o -lm */ #include <math.h> fpsetdefaults(); PyOS_setsig(SIGFPE, handler); /*-- IBM AIX --------------------------------------------------------------*/ #elif defined(__AIX) || defined(_AIX) /* References: fp_trap, fp_enable man pages */ #include <fptrap.h> fp_trap(FP_TRAP_SYNC); fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW); PyOS_setsig(SIGFPE, handler); /*-- DEC ALPHA LINUX ------------------------------------------------------*/ #elif defined(__alpha) && defined(linux) #include <asm/fpu.h> unsigned long fp_control = IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF; ieee_set_fp_control(fp_control); PyOS_setsig(SIGFPE, handler); /*-- Cray Unicos ----------------------------------------------------------*/ #elif defined(cray) /* UNICOS delivers SIGFPE by default, but no matherr */ #ifdef HAS_LIBMSET libmset(-1); #endif PyOS_setsig(SIGFPE, handler); /*-- FreeBSD ----------------------------------------------------------------*/ #elif defined(__FreeBSD__) fpresetsticky(fpgetsticky()); fpsetmask(FP_X_INV | FP_X_DZ | FP_X_OFL); PyOS_setsig(SIGFPE, handler); /*-- Linux ----------------------------------------------------------------*/ #elif defined(linux) #ifdef __GLIBC__ #include <fpu_control.h> #else #include <i386/fpu_control.h> #endif #ifdef _FPU_SETCW { fpu_control_t cw = 0x1372; _FPU_SETCW(cw); } #else __setfpucw(0x1372); #endif PyOS_setsig(SIGFPE, handler); /*-- Microsoft Windows, NT ------------------------------------------------*/ #elif defined(_MSC_VER) /* Reference: Visual C++ Books Online 4.2, Run-Time Library Reference, _control87, _controlfp */ #include <float.h> unsigned int cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW; (void)_controlfp(0, cw); PyOS_setsig(SIGFPE, handler); /*-- Give Up --------------------------------------------------------------*/ #else fputs("Operation not implemented\n", stderr); #endif }
// float point 에러가 exception을 내게 한다. void EnableFloatException() { int cw = _controlfp( 0, 0 ); cw &= ~(EM_OVERFLOW|EM_UNDERFLOW|EM_ZERODIVIDE|EM_DENORMAL); _controlfp( cw, MCW_EM ); }
// Address range: 0x401bb0 - 0x401bcf int32_t function_401bb0(void) { // 0x401bb0 return _controlfp(0x10000, 0x30000); }
static int setup_fpu(int doINV, int doOFL) { #if defined(WIN32) /* Win32 uses _controlfp() */ unsigned int mask = _controlfp(0,0); fpe_inv = doINV; fpe_ofl = doOFL; if (doINV) mask&=(~_EM_INVALID); else mask|=(_EM_INVALID); if (doOFL) mask&=(~_EM_OVERFLOW); else mask|=(_EM_OVERFLOW); if (doOFL) mask&=(~_EM_ZERODIVIDE); else mask|=(_EM_ZERODIVIDE); _controlfp(mask, _MCW_EM); return 1; #elif defined(HAVE_FPSETMASK) /* SysVr4 defines fpsetmask() */ int mask = 0; fpe_inv = doINV; fpe_ofl = doOFL; #ifdef FP_X_INV if (doINV) mask |= FP_X_INV; #endif #ifdef FP_X_OFL if (doOFL) mask |= FP_X_OFL; #endif #ifdef FP_X_DZ if (doOFL) mask |= FP_X_DZ; #endif fpsetmask( mask ); return 1; #elif defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT) /* GLIBC-2.2 model */ int mask1 = 0; int mask2 = 0; fpe_inv = doINV; fpe_ofl = doOFL; #ifdef FE_INVALID if (doINV) mask1 |= FE_INVALID; else mask2 |= FE_INVALID; #endif #ifdef FE_DIVBYZERO if (doOFL) mask1 |= FE_DIVBYZERO; else mask2 |= FE_DIVBYZERO; #endif #ifdef FE_OVERFLOW if (doOFL) mask1 |= FE_OVERFLOW; else mask2 |= FE_OVERFLOW; #endif feenableexcept(mask1); fedisableexcept(mask2); return 1; #elif defined(HAVE_FPU_CONTROL_H) /* Older GLIBC */ int mask = 0; fpe_inv = doINV; fpe_ofl = doOFL; #ifdef _FPU_DEFAULT mask = _FPU_DEFAULT; #endif #define DO(c,f) mask=((c)?(mask|(f)):(mask&~(f))); #if defined(__i386__) || defined(__alpha__) #ifdef _FPU_MASK_IM DO(!doINV, _FPU_MASK_IM); #endif #ifdef _FPU_MASK_OM DO(!doOFL, _FPU_MASK_OM); #endif #ifdef _FPU_MASK_ZM DO(!doOFL, _FPU_MASK_ZM); #endif #else #ifdef _FPU_MASK_IM DO(doINV, _FPU_MASK_IM); #endif #ifdef _FPU_MASK_OM DO(doOFL, _FPU_MASK_OM); #endif #ifdef _FPU_MASK_ZM DO(doOFL, _FPU_MASK_ZM); #endif #ifdef _FPU_MASK_V DO(doINV, _FPU_MASK_V); #endif #ifdef _FPU_MASK_O DO(doOFL, _FPU_MASK_O); #endif #ifdef _FPU_MASK_Z DO(doOFL, _FPU_MASK_Z); #endif #ifdef _FPU_MASK_OPERR DO(doINV, _FPU_MASK_OPERR); #endif #ifdef _FPU_MASK_OVFL DO(doOFL, _FPU_MASK_OPERR); #endif #ifdef _FPU_MASK_DZ DO(doOFL, _FPU_MASK_DZ); #endif #endif /* continue */ #if defined(HAVE___SETFPUCW) __setfpucw( mask ); return 1; #elif defined(_FPU_SETCW) _FPU_SETCW( mask ); return 1; #undef DO #endif #endif /* Default */ return 0; }
void fn00401BB0() { _controlfp(); return; }
void Sys_SetFloatEnv(void) { _controlfp(FPUCW, FPUCWMASK); }
ALUAPI ALvoid ALUAPIENTRY aluMixData(ALvoid *context,ALvoid *buffer,ALsizei size,ALenum format) { ALfloat Pitch,DrySend[OUTPUTCHANNELS],WetSend[OUTPUTCHANNELS]; static float DryBuffer[BUFFERSIZE][OUTPUTCHANNELS]; static float WetBuffer[BUFFERSIZE][OUTPUTCHANNELS]; ALuint BlockAlign,BytesPerSample,BufferSize; ALuint DataSize,DataPosInt,DataPosFrac; ALuint Channels,Bits,Frequency,ulExtraSamples; ALint Looping,increment,State; ALuint Buffer,fraction; ALCcontext *ALContext; ALuint SamplesToDo; ALsource *ALSource; ALbuffer *ALBuffer; ALfloat value; ALshort *Data; ALuint i,j,k; ALenum Error; ALbufferlistitem *BufferListItem; ALuint loop; __int64 DataSize64,DataPos64; unsigned int fpuState; if (context) { ALContext=((ALCcontext *)context); SuspendContext(ALContext); //Save FPU state fpuState=_controlfp(0,0); //Change FPU rounding mode _controlfp(_RC_CHOP,_MCW_RC); if ((buffer)&&(size)) { //Figure output format variables switch (format) { case AL_FORMAT_MONO8: BlockAlign=1; BytesPerSample=1; break; case AL_FORMAT_STEREO8: BlockAlign=2; BytesPerSample=1; break; case AL_FORMAT_MONO16: BlockAlign=2; BytesPerSample=2; break; case AL_FORMAT_STEREO16: default: BlockAlign=4; BytesPerSample=2; break; } //Setup variables ALSource=ALContext->Source; SamplesToDo=((size/BlockAlign)<BUFFERSIZE?(size/BlockAlign):BUFFERSIZE); //Clear mixing buffer memset(DryBuffer,0,SamplesToDo*OUTPUTCHANNELS*sizeof(ALfloat)); memset(WetBuffer,0,SamplesToDo*OUTPUTCHANNELS*sizeof(ALfloat)); //Actual mixing loop for (i=0;i<ALContext->SourceCount;i++) { j=0; State = ALSource->state; while ((State==AL_PLAYING)&&(j<SamplesToDo)) { aluCalculateSourceParameters((ALuint)ALSource->source,ALContext->Frequency,ALContext->Channels,DrySend,WetSend,&Pitch); //Get buffer info if (Buffer = ALSource->ulBufferID) { ALBuffer = (ALbuffer*)ALTHUNK_LOOKUPENTRY(Buffer); Data = ALBuffer->data; Bits = (((ALBuffer->format==AL_FORMAT_MONO8)||(ALBuffer->format==AL_FORMAT_STEREO8))?8:16); DataSize = ALBuffer->size; Channels = (((ALBuffer->format==AL_FORMAT_MONO8)||(ALBuffer->format==AL_FORMAT_MONO16))?1:2); Frequency = ALBuffer->frequency; Pitch=((Pitch*Frequency)/ALContext->Frequency); DataSize=(DataSize/(Bits*Channels/8)); //Get source info DataPosInt=ALSource->position; DataPosFrac=ALSource->position_fraction; //Compute 18.14 fixed point step increment=aluF2L(Pitch*(1L<<FRACTIONBITS)); if (increment > (MAX_PITCH<<FRACTIONBITS)) increment=(MAX_PITCH<<FRACTIONBITS); //Figure out how many samples we can mix. //Pitch must be <= 4 (the number below !) DataSize64=DataSize+MAX_PITCH; DataSize64<<=FRACTIONBITS; DataPos64=DataPosInt; DataPos64<<=FRACTIONBITS; DataPos64+=DataPosFrac; //FIX DEVIDE BY ZERO (NUMMER) if (increment == 0) increment = 1; BufferSize=(ALuint)((DataSize64-DataPos64)/increment); BufferListItem = ALSource->queue; for (loop = 0; loop < ALSource->BuffersAddedToDSBuffer; loop++) if (BufferListItem) BufferListItem = BufferListItem->next; if (BufferListItem) { if (BufferListItem->next) { if (Channels==2) { if (((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->data) { ulExtraSamples = min(((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->size, 32); memcpy(&Data[DataSize*2], ((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->data, ulExtraSamples); } } else { if (((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->data) { ulExtraSamples = min(((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->size, 16); memcpy(&Data[DataSize], ((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->data, ulExtraSamples); } } } else if (ALSource->bLooping) { if (ALSource->queue->buffer) { if (Channels==2) { if (((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->data) { ulExtraSamples = min(((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->size, 32); memcpy(&Data[DataSize*2], ((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->data, ulExtraSamples); } } else { if (((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->data) { ulExtraSamples = min(((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->size, 16); memcpy(&Data[DataSize], ((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->data, ulExtraSamples); } } } } } BufferSize=(BufferSize<(SamplesToDo-j)?BufferSize:(SamplesToDo-j)); //Actual sample mixing loop Data+=DataPosInt*Channels; while (BufferSize--) { k=DataPosFrac>>FRACTIONBITS; fraction=DataPosFrac&FRACTIONMASK; if (Channels==1) { //First order interpolator value=(ALfloat)((ALshort)(((Data[k]*((1L<<FRACTIONBITS)-fraction))+(Data[k+1]*(fraction)))>>FRACTIONBITS)); //Direct path final mix buffer and panning DryBuffer[j][0]+=value*DrySend[0]; DryBuffer[j][1]+=value*DrySend[1]; //Room path final mix buffer and panning WetBuffer[j][0]+=value*WetSend[0]; WetBuffer[j][1]+=value*WetSend[1]; } else { //First order interpolator (left) value=(ALfloat)((ALshort)(((Data[k*2 ]*((1L<<FRACTIONBITS)-fraction))+(Data[k*2+2]*(fraction)))>>FRACTIONBITS)); //Direct path final mix buffer and panning (left) DryBuffer[j][0]+=value*DrySend[0]; //Room path final mix buffer and panning (left) WetBuffer[j][0]+=value*WetSend[0]; //First order interpolator (right) value=(ALfloat)((ALshort)(((Data[k*2+1]*((1L<<FRACTIONBITS)-fraction))+(Data[k*2+3]*(fraction)))>>FRACTIONBITS)); //Direct path final mix buffer and panning (right) DryBuffer[j][1]+=value*DrySend[1]; //Room path final mix buffer and panning (right) WetBuffer[j][1]+=value*WetSend[1]; } DataPosFrac+=increment; j++; } DataPosInt+=(DataPosFrac>>FRACTIONBITS); DataPosFrac=(DataPosFrac&FRACTIONMASK); //Update source info ALSource->position=DataPosInt; ALSource->position_fraction=DataPosFrac; } //Handle looping sources if ((!Buffer)||(DataPosInt>=DataSize)) { //queueing if (ALSource->queue) { Looping = ALSource->bLooping; if (ALSource->BuffersAddedToDSBuffer < (ALSource->BuffersInQueue-1)) { BufferListItem = ALSource->queue; for (loop = 0; loop <= ALSource->BuffersAddedToDSBuffer; loop++) { if (BufferListItem) { if (!Looping) BufferListItem->bufferstate=PROCESSED; BufferListItem = BufferListItem->next; } } if (!Looping) ALSource->BuffersProcessed++; if (BufferListItem) ALSource->ulBufferID=BufferListItem->buffer; ALSource->position=DataPosInt-DataSize; ALSource->position_fraction=DataPosFrac; ALSource->BuffersAddedToDSBuffer++; } else { alSourceStop((ALuint)ALSource->source); if (Looping) { alSourceRewind((ALuint)ALSource->source); alSourcePlay((ALuint)ALSource->source); ALSource->position=DataPosInt-DataSize; ALSource->position_fraction=DataPosFrac; } } } } //Get source state State = ALSource->state; } ALSource=ALSource->next; }