forked from 0ad/0ad
# add strict VSrc validation in OpenAL interface to track down bug
- required adding C99 insnan() implementation, along with fpclassify This was SVN commit r3850.
This commit is contained in:
parent
6a4816a512
commit
a35ee9894d
@ -1827,11 +1827,22 @@ static void vsrc_latch(VSrc* vs)
|
||||
if(!vs->al_src)
|
||||
return;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// paranoid value checking; helps determine which parameter is
|
||||
// the problem when the below AL_CHECK fails.
|
||||
debug_assert(!isnan(vs->pos[0]) && !isnan(vs->pos[1]) && !isnan(vs->pos[2]));
|
||||
debug_assert(vs->relative == AL_TRUE || vs->relative == AL_FALSE);
|
||||
debug_assert(!isnan(vs->gain));
|
||||
debug_assert(!isnan(vs->pitch) && vs->pitch > 0.0f);
|
||||
debug_assert(vs->loop == AL_TRUE || vs->loop == AL_FALSE);
|
||||
#endif
|
||||
|
||||
alSourcefv(vs->al_src, AL_POSITION, vs->pos);
|
||||
alSourcei (vs->al_src, AL_SOURCE_RELATIVE, vs->relative);
|
||||
alSourcef (vs->al_src, AL_GAIN, vs->gain);
|
||||
alSourcef (vs->al_src, AL_PITCH, vs->pitch);
|
||||
alSourcei (vs->al_src, AL_LOOPING, vs->loop);
|
||||
|
||||
AL_CHECK;
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,16 @@ extern i32 ia32_i32_from_float(float f);
|
||||
extern i32 ia32_i32_from_double(double d);
|
||||
extern i64 ia32_i64_from_double(double d);
|
||||
|
||||
// fpclassify return values
|
||||
#define IA32_FP_NAN 0x0100
|
||||
#define IA32_FP_NORMAL 0x0400
|
||||
#define IA32_FP_INFINITE (IA32_FP_NAN | IA32_FP_NORMAL)
|
||||
#define IA32_FP_ZERO 0x4000
|
||||
#define IA32_FP_SUBNORMAL (IA32_FP_NORMAL | IA32_FP_ZERO)
|
||||
|
||||
extern uint ia32_fpclassify(double d);
|
||||
extern uint ia32_fpclassifyf(float f);
|
||||
|
||||
extern void* ia32_memcpy(void* dst, const void* src, size_t nbytes); // asm
|
||||
|
||||
|
||||
|
@ -503,10 +503,10 @@ db 0xf0 ; LOCK prefix
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; misc
|
||||
; FPU
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; extern "C" uint __cdecl ia32_control87(uint new_cw, uint mask)
|
||||
; extern "C" uint __cdecl ia32_control87(uint new_cw, uint mask);
|
||||
global sym(ia32_control87)
|
||||
sym(ia32_control87):
|
||||
push eax
|
||||
@ -525,6 +525,32 @@ sym(ia32_control87):
|
||||
ret
|
||||
|
||||
|
||||
; possible IA-32 FPU control word flags after FXAM: NAN|NORMAL|ZERO
|
||||
FP_CLASSIFY_MASK equ 0x4500
|
||||
|
||||
; extern "C" uint __cdecl ia32_fpclassify(double d);
|
||||
global sym(ia32_fpclassify)
|
||||
sym(ia32_fpclassify):
|
||||
fld qword [esp+4]
|
||||
fxam
|
||||
fnstsw ax
|
||||
and eax, FP_CLASSIFY_MASK
|
||||
ret
|
||||
|
||||
; extern "C" uint __cdecl ia32_fpclassifyf(float f);
|
||||
global sym(ia32_fpclassifyf)
|
||||
sym(ia32_fpclassifyf):
|
||||
fld dword [esp+4]
|
||||
fxam
|
||||
fnstsw ax
|
||||
and eax, FP_CLASSIFY_MASK
|
||||
ret
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; misc
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; write the current execution state (e.g. all register values) into
|
||||
; (Win32::CONTEXT*)pcontext (defined as void* to avoid dependency).
|
||||
; optimized for size; this must be straight asm because __declspec(naked)
|
||||
|
@ -51,6 +51,21 @@ float fmaxf(float a, float b)
|
||||
return (a > b)? a : b;
|
||||
}
|
||||
|
||||
uint fpclassify(double d)
|
||||
{
|
||||
// really sucky stub implementation; doesn't attempt to cover all cases.
|
||||
|
||||
if(d != d)
|
||||
return IA32_FP_NAN;
|
||||
else
|
||||
return IA32_FP_NORMAL;
|
||||
}
|
||||
|
||||
uint fpclassifyf(float f)
|
||||
{
|
||||
return fpclassify((double)f);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #if !HAVE_C99
|
||||
|
@ -101,13 +101,29 @@ extern void* alloca(size_t size);
|
||||
# define rint ia32_rint
|
||||
# define fminf ia32_fminf
|
||||
# define fmaxf ia32_fmaxf
|
||||
|
||||
# define FP_NAN IA32_FP_NAN
|
||||
# define FP_NORMAL IA32_FP_NORMAL
|
||||
# define FP_INFINITE (FP_NAN | FP_NORMAL)
|
||||
# define FP_ZERO IA32_FP_ZERO
|
||||
# define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
|
||||
# define fpclassify ia32_fpclassify
|
||||
// .. portable C emulation
|
||||
# else
|
||||
extern float rintf(float f);
|
||||
extern double rint(double d);
|
||||
extern float fminf(float a, float b);
|
||||
extern float fmaxf(float a, float b);
|
||||
|
||||
# define FP_NAN 1
|
||||
# define FP_NORMAL 2
|
||||
# define FP_INFINITE (FP_NAN | FP_NORMAL)
|
||||
# define FP_ZERO 4
|
||||
# define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
|
||||
extern uint fpclassify(double d);
|
||||
# endif
|
||||
|
||||
# define isnan(d) (fpclassify(d) == FP_NAN)
|
||||
#endif
|
||||
|
||||
// finite: return 0 iff the given double is infinite or NaN.
|
||||
|
Loading…
Reference in New Issue
Block a user