mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-22 02:20:25 +01:00
rework asm to always fall back to portable C code
with this there is no need to worry about x86 asm switch for other platforms.
This commit is contained in:
parent
78b26698ac
commit
1f70d4e242
|
@ -65,9 +65,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#else
|
||||
#warning "UNKNOWN PLATFORM IDENTIFIED!!!!"
|
||||
#define PLATFORM_UNKNOWN 1
|
||||
#warning "USING PORTABLE C!!!"
|
||||
#define USE_PORTABLE_C
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if PLATFORM_LINUX || PLATFORM_MACOSX
|
||||
#ifndef PLATFORM_UNIX
|
||||
|
|
|
@ -21,24 +21,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
template class CStaticArray<CProfileCounter>;
|
||||
template class CStaticArray<CProfileTimer>;
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
#if (defined PLATFORM_UNIX) && !defined(__GNU_INLINE_X86_32__)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
static inline __int64 ReadTSC_profile(void)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C)
|
||||
#ifdef __arm__
|
||||
struct timespec tv;
|
||||
clock_gettime(CLOCK_MONOTONIC, &tv);
|
||||
return( (((__int64) tv.tv_sec) * 1000) + (((__int64) tv.tv_nsec) / 1000000) );
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return( (((__int64) tv.tv_sec) * 1000) + (((__int64) tv.tv_usec) / 1000) );
|
||||
#endif
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__int64 mmRet;
|
||||
__asm {
|
||||
rdtsc
|
||||
|
@ -60,7 +49,16 @@ static inline __int64 ReadTSC_profile(void)
|
|||
return(mmRet);
|
||||
|
||||
#else
|
||||
#error Please implement for your platform/compiler.
|
||||
#ifdef __arm__
|
||||
struct timespec tv;
|
||||
clock_gettime(CLOCK_MONOTONIC, &tv);
|
||||
return( (((__int64) tv.tv_sec) * 1000) + (((__int64) tv.tv_nsec) / 1000000) );
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return( (((__int64) tv.tv_sec) * 1000) + (((__int64) tv.tv_usec) / 1000) );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include <Engine/Base/Priority.inl>
|
||||
|
||||
// !!! FIXME: use SDL timer code instead and rdtsc never?
|
||||
#if (USE_PORTABLE_C)
|
||||
#if (defined PLATFORM_UNIX) && !defined(__GNU_INLINE_X86_32__)
|
||||
#define USE_GETTIMEOFDAY 1
|
||||
#endif
|
||||
|
||||
|
|
|
@ -229,10 +229,7 @@ MY_STATIC_ASSERT(size_tSize, sizeof(size_t) == sizeof(void*));
|
|||
|
||||
inline ULONG _rotl(ULONG ul, int bits)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C)
|
||||
// DG: according to http://blog.regehr.org/archives/1063 this is fast
|
||||
return (ul<<bits) | (ul>>(-bits&31));
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#if (defined __GNU_INLINE_X86_32__)
|
||||
// This, on the other hand, is wicked fast. :)
|
||||
__asm__ __volatile__ (
|
||||
"roll %%cl, %%eax \n\t"
|
||||
|
@ -254,7 +251,8 @@ MY_STATIC_ASSERT(size_tSize, sizeof(size_t) == sizeof(void*));
|
|||
return(ul);
|
||||
|
||||
#else
|
||||
#error need inline asm for your platform.
|
||||
// DG: according to http://blog.regehr.org/archives/1063 this is fast
|
||||
return (ul<<bits) | (ul>>(-bits&31));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -125,14 +125,10 @@ BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReser
|
|||
|
||||
static void DetectCPU(void)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C) // rcg10072001
|
||||
CPrintF(TRANSV(" (No CPU detection in this binary.)\n"));
|
||||
|
||||
#else
|
||||
char strVendor[12+1];
|
||||
char strVendor[12+1] = { 0 };
|
||||
strVendor[12] = 0;
|
||||
ULONG ulTFMS;
|
||||
ULONG ulFeatures;
|
||||
ULONG ulTFMS = 0;
|
||||
ULONG ulFeatures = 0;
|
||||
|
||||
#if (defined __MSVC_INLINE__)
|
||||
// test MMX presence and update flag
|
||||
|
@ -181,10 +177,13 @@ static void DetectCPU(void)
|
|||
: "eax", "ecx", "edx", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Please implement for your platform or define USE_PORTABLE_C.
|
||||
#endif
|
||||
|
||||
if (ulTFMS == 0) {
|
||||
CPrintF(TRANSV(" (No CPU detection in this binary.)\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
INDEX iType = (ulTFMS>>12)&0x3;
|
||||
INDEX iFamily = (ulTFMS>> 8)&0xF;
|
||||
INDEX iModel = (ulTFMS>> 4)&0xF;
|
||||
|
@ -215,8 +214,6 @@ static void DetectCPU(void)
|
|||
sys_iCPUMHz = INDEX(_pTimer->tm_llCPUSpeedHZ/1E6);
|
||||
|
||||
if( !bMMX) FatalError( TRANS("MMX support required but not present!"));
|
||||
|
||||
#endif // defined USE_PORTABLE_C
|
||||
}
|
||||
|
||||
static void DetectCPUWrapper(void)
|
||||
|
|
|
@ -247,30 +247,7 @@ COLOR MulColors( COLOR col1, COLOR col2)
|
|||
if( col2==0xFFFFFFFF) return col1;
|
||||
if( col1==0 || col2==0) return 0;
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
// !!! FIXME: This...is not fast.
|
||||
union
|
||||
{
|
||||
COLOR col;
|
||||
UBYTE bytes[4];
|
||||
} conv1;
|
||||
|
||||
union
|
||||
{
|
||||
COLOR col;
|
||||
UBYTE bytes[4];
|
||||
} conv2;
|
||||
|
||||
conv1.col = col1;
|
||||
conv2.col = col2;
|
||||
conv1.bytes[0] = (UBYTE) ((((DWORD) conv1.bytes[0]) * ((DWORD) conv2.bytes[0])) / 255);
|
||||
conv1.bytes[1] = (UBYTE) ((((DWORD) conv1.bytes[1]) * ((DWORD) conv2.bytes[1])) / 255);
|
||||
conv1.bytes[2] = (UBYTE) ((((DWORD) conv1.bytes[2]) * ((DWORD) conv2.bytes[2])) / 255);
|
||||
conv1.bytes[3] = (UBYTE) ((((DWORD) conv1.bytes[3]) * ((DWORD) conv2.bytes[3])) / 255);
|
||||
|
||||
return(conv1.col);
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
COLOR colRet;
|
||||
__asm {
|
||||
xor ebx,ebx
|
||||
|
@ -433,20 +410,6 @@ COLOR MulColors( COLOR col1, COLOR col2)
|
|||
|
||||
return colRet;
|
||||
#else
|
||||
#error please fill in inline assembly for your platform.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// fast color additon function - RES = clamp (1ST + 2ND)
|
||||
COLOR AddColors( COLOR col1, COLOR col2)
|
||||
{
|
||||
if( col1==0) return col2;
|
||||
if( col2==0) return col1;
|
||||
if( col1==0xFFFFFFFF || col2==0xFFFFFFFF) return 0xFFFFFFFF;
|
||||
COLOR colRet;
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
// !!! FIXME: This...is not fast.
|
||||
union
|
||||
{
|
||||
|
@ -459,19 +422,28 @@ COLOR AddColors( COLOR col1, COLOR col2)
|
|||
COLOR col;
|
||||
UBYTE bytes[4];
|
||||
} conv2;
|
||||
#define MINVAL(a, b) ((a)>(b))?(b):(a)
|
||||
|
||||
conv1.col = col1;
|
||||
conv2.col = col2;
|
||||
conv1.bytes[0] = (UBYTE) MINVAL((((WORD) conv1.bytes[0]) + ((WORD) conv2.bytes[0])) , 255);
|
||||
conv1.bytes[1] = (UBYTE) MINVAL((((WORD) conv1.bytes[1]) + ((WORD) conv2.bytes[1])) , 255);
|
||||
conv1.bytes[2] = (UBYTE) MINVAL((((WORD) conv1.bytes[2]) + ((WORD) conv2.bytes[2])) , 255);
|
||||
conv1.bytes[3] = (UBYTE) MINVAL((((WORD) conv1.bytes[3]) + ((WORD) conv2.bytes[3])) , 255);
|
||||
#undef MINVAL
|
||||
conv1.bytes[0] = (UBYTE) ((((DWORD) conv1.bytes[0]) * ((DWORD) conv2.bytes[0])) / 255);
|
||||
conv1.bytes[1] = (UBYTE) ((((DWORD) conv1.bytes[1]) * ((DWORD) conv2.bytes[1])) / 255);
|
||||
conv1.bytes[2] = (UBYTE) ((((DWORD) conv1.bytes[2]) * ((DWORD) conv2.bytes[2])) / 255);
|
||||
conv1.bytes[3] = (UBYTE) ((((DWORD) conv1.bytes[3]) * ((DWORD) conv2.bytes[3])) / 255);
|
||||
|
||||
colRet = conv1.col;
|
||||
return(conv1.col);
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
|
||||
// fast color additon function - RES = clamp (1ST + 2ND)
|
||||
COLOR AddColors( COLOR col1, COLOR col2)
|
||||
{
|
||||
if( col1==0) return col2;
|
||||
if( col2==0) return col1;
|
||||
if( col1==0xFFFFFFFF || col2==0xFFFFFFFF) return 0xFFFFFFFF;
|
||||
COLOR colRet;
|
||||
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
xor ebx,ebx
|
||||
mov esi,255
|
||||
|
@ -608,7 +580,29 @@ COLOR AddColors( COLOR col1, COLOR col2)
|
|||
);
|
||||
|
||||
#else
|
||||
#error please fill in inline assembly for your platform.
|
||||
// !!! FIXME: This...is not fast.
|
||||
union
|
||||
{
|
||||
COLOR col;
|
||||
UBYTE bytes[4];
|
||||
} conv1;
|
||||
|
||||
union
|
||||
{
|
||||
COLOR col;
|
||||
UBYTE bytes[4];
|
||||
} conv2;
|
||||
#define MINVAL(a, b) ((a)>(b))?(b):(a)
|
||||
|
||||
conv1.col = col1;
|
||||
conv2.col = col2;
|
||||
conv1.bytes[0] = (UBYTE) MINVAL((((WORD) conv1.bytes[0]) + ((WORD) conv2.bytes[0])) , 255);
|
||||
conv1.bytes[1] = (UBYTE) MINVAL((((WORD) conv1.bytes[1]) + ((WORD) conv2.bytes[1])) , 255);
|
||||
conv1.bytes[2] = (UBYTE) MINVAL((((WORD) conv1.bytes[2]) + ((WORD) conv2.bytes[2])) , 255);
|
||||
conv1.bytes[3] = (UBYTE) MINVAL((((WORD) conv1.bytes[3]) + ((WORD) conv2.bytes[3])) , 255);
|
||||
#undef MINVAL
|
||||
|
||||
colRet = conv1.col;
|
||||
#endif
|
||||
|
||||
return colRet;
|
||||
|
@ -619,14 +613,7 @@ COLOR AddColors( COLOR col1, COLOR col2)
|
|||
// multiple conversion from OpenGL color to DirectX color
|
||||
extern void abgr2argb( ULONG *pulSrc, ULONG *pulDst, INDEX ct)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C)
|
||||
//#error write me.
|
||||
for (int i=0; i<ct; i++) {
|
||||
ULONG tmp = pulSrc[i];
|
||||
pulDst[i] = (tmp&0xff00ff00) | ((tmp&0x00ff0000)>>16) | ((tmp&0x000000ff)<<16);
|
||||
}
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
mov esi,dword ptr [pulSrc]
|
||||
mov edi,dword ptr [pulDst]
|
||||
|
@ -678,12 +665,12 @@ colSkip2:
|
|||
mov dword ptr [edi],eax
|
||||
colSkip1:
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
STUBBED("convert to inline asm.");
|
||||
|
||||
#else
|
||||
#error please fill in inline assembly for your platform.
|
||||
for (int i=0; i<ct; i++) {
|
||||
ULONG tmp = pulSrc[i];
|
||||
pulDst[i] = (tmp&0xff00ff00) | ((tmp&0x00ff0000)>>16) | ((tmp&0x000000ff)<<16);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -204,19 +204,7 @@ ENGINE_API extern COLOR AddColors( COLOR col1, COLOR col2); // fast color addito
|
|||
__forceinline ULONG ByteSwap( ULONG ul)
|
||||
{
|
||||
/* rcg10052001 Platform-wrappers. */
|
||||
#if (defined USE_PORTABLE_C)
|
||||
ul = ( ((ul << 24) ) |
|
||||
((ul << 8) & 0x00FF0000) |
|
||||
((ul >> 8) & 0x0000FF00) |
|
||||
((ul >> 24) ) );
|
||||
|
||||
#if (defined PLATFORM_BIGENDIAN)
|
||||
BYTESWAP(ul); // !!! FIXME: May not be right!
|
||||
#endif
|
||||
|
||||
return(ul);
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
ULONG ulRet;
|
||||
__asm {
|
||||
mov eax,dword ptr [ul]
|
||||
|
@ -234,16 +222,22 @@ __forceinline ULONG ByteSwap( ULONG ul)
|
|||
return(ul);
|
||||
|
||||
#else
|
||||
#error please define for your platform.
|
||||
ul = ( ((ul << 24) ) |
|
||||
((ul << 8) & 0x00FF0000) |
|
||||
((ul >> 8) & 0x0000FF00) |
|
||||
((ul >> 24) ) );
|
||||
|
||||
#if (defined PLATFORM_BIGENDIAN)
|
||||
BYTESWAP(ul); // !!! FIXME: May not be right!
|
||||
#endif
|
||||
|
||||
return(ul);
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline ULONG rgba2argb( ULONG ul)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C)
|
||||
return( (ul << 24) | (ul >> 8) );
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
ULONG ulRet;
|
||||
__asm {
|
||||
mov eax,dword ptr [ul]
|
||||
|
@ -263,21 +257,14 @@ __forceinline ULONG rgba2argb( ULONG ul)
|
|||
return ulRet;
|
||||
|
||||
#else
|
||||
#error please define for your platform.
|
||||
return (ul << 24) | (ul >> 8);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline ULONG abgr2argb( COLOR col)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C)
|
||||
// this could be simplified, this is just a safe conversion from asm code
|
||||
col = ( ((col << 24) ) |
|
||||
((col << 8) & 0x00FF0000) |
|
||||
((col >> 8) & 0x0000FF00) |
|
||||
((col >> 24) ) );
|
||||
return( (col << 24) | (col >> 8) );
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
ULONG ulRet;
|
||||
__asm {
|
||||
mov eax,dword ptr [col]
|
||||
|
@ -299,7 +286,13 @@ __forceinline ULONG abgr2argb( COLOR col)
|
|||
return ulRet;
|
||||
|
||||
#else
|
||||
#error please define for your platform.
|
||||
// this could be simplified, this is just a safe conversion from asm code
|
||||
col = ( ((col << 24) ) |
|
||||
((col << 8) & 0x00FF0000) |
|
||||
((col >> 8) & 0x0000FF00) |
|
||||
((col >> 24) ) );
|
||||
return( (col << 24) | (col >> 8) );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -311,10 +304,7 @@ extern void abgr2argb( ULONG *pulSrc, ULONG *pulDst, INDEX ct);
|
|||
// fast memory copy of ULONGs
|
||||
inline void CopyLongs( ULONG *pulSrc, ULONG *pulDst, INDEX ctLongs)
|
||||
{
|
||||
#if ((defined USE_PORTABLE_C) || (PLATFORM_MACOSX))
|
||||
memcpy( pulDst, pulSrc, ctLongs*4);
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
cld
|
||||
mov esi,dword ptr [pulSrc]
|
||||
|
@ -322,23 +312,8 @@ inline void CopyLongs( ULONG *pulSrc, ULONG *pulDst, INDEX ctLongs)
|
|||
mov ecx,dword ptr [ctLongs]
|
||||
rep movsd
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
// I haven't benchmarked it, but in many cases, memcpy() becomes an
|
||||
// inline (asm?) macro on GNU platforms, so this might not be a
|
||||
// speed gain at all over the USE_PORTABLE_C version.
|
||||
// You Have Been Warned. --ryan.
|
||||
__asm__ __volatile__ (
|
||||
"cld \n\t"
|
||||
"rep \n\t"
|
||||
"movsd \n\t"
|
||||
: "=S" (pulSrc), "=D" (pulDst), "=c" (ctLongs)
|
||||
: "S" (pulSrc), "D" (pulDst), "c" (ctLongs)
|
||||
: "cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
# error Please fill this in for your platform.
|
||||
memcpy( pulDst, pulSrc, ctLongs*4);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -346,11 +321,7 @@ inline void CopyLongs( ULONG *pulSrc, ULONG *pulDst, INDEX ctLongs)
|
|||
// fast memory set of ULONGs
|
||||
inline void StoreLongs( ULONG ulVal, ULONG *pulDst, INDEX ctLongs)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C)
|
||||
for( INDEX i=0; i<ctLongs; i++)
|
||||
pulDst[i] = ulVal;
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
cld
|
||||
mov eax,dword ptr [ulVal]
|
||||
|
@ -370,7 +341,9 @@ inline void StoreLongs( ULONG ulVal, ULONG *pulDst, INDEX ctLongs)
|
|||
);
|
||||
|
||||
#else
|
||||
# error Please fill this in for your platform.
|
||||
for( INDEX i=0; i<ctLongs; i++)
|
||||
pulDst[i] = ulVal;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -38,16 +38,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define W word ptr
|
||||
#define B byte ptr
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
#define ASMOPT 0
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#define ASMOPT 1
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#define ASMOPT 1
|
||||
#else
|
||||
#define ASMOPT 0
|
||||
#endif
|
||||
|
||||
#define MAXTEXUNITS 4
|
||||
#define SHADOWTEXTURE 3
|
||||
|
||||
|
@ -153,8 +143,7 @@ void AddElements( ScenePolygon *pspo)
|
|||
const INDEX ctElems = pspo->spo_ctElements;
|
||||
INDEX *piDst = _aiElements.Push(ctElems);
|
||||
|
||||
#if (ASMOPT == 1)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
mov eax,D [pspo]
|
||||
mov ecx,D [ctElems]
|
||||
|
@ -184,7 +173,7 @@ elemRest:
|
|||
mov D [edi],eax
|
||||
elemDone:
|
||||
}
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
__asm__ __volatile__ (
|
||||
"movl %[ctElems], %%ecx \n\t"
|
||||
"movl %[piDst], %%edi \n\t"
|
||||
|
@ -219,11 +208,6 @@ elemDone:
|
|||
"cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Please write inline ASM for your platform.
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
const INDEX iVtx0Pass = pspo->spo_iVtx0Pass;
|
||||
const INDEX *piSrc = pspo->spo_piElements;
|
||||
|
@ -495,9 +479,7 @@ static void RSBinToGroups( ScenePolygon *pspoFirst)
|
|||
// determine maximum used groups
|
||||
ASSERT( _ctGroupsCount);
|
||||
|
||||
#if ASMOPT == 1
|
||||
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
mov eax,2
|
||||
bsr ecx,D [_ctGroupsCount]
|
||||
|
@ -505,7 +487,7 @@ static void RSBinToGroups( ScenePolygon *pspoFirst)
|
|||
mov D [_ctGroupsCount],eax
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
__asm__ __volatile__ (
|
||||
"movl $2, %%eax \n\t"
|
||||
"bsrl (%%esi), %%ecx \n\t"
|
||||
|
@ -516,11 +498,6 @@ static void RSBinToGroups( ScenePolygon *pspoFirst)
|
|||
: "eax", "ecx", "cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Please write inline ASM for your platform.
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
// emulate x86's bsr opcode...not fast. :/
|
||||
register DWORD val = _ctGroupsCount;
|
||||
|
@ -858,10 +835,7 @@ static void RSSetTextureCoords( ScenePolygon *pspoGroup, INDEX iLayer, INDEX iUn
|
|||
continue;
|
||||
}
|
||||
|
||||
// !!! FIXME: rcg11232001 This inline conversion is broken. Use the
|
||||
// !!! FIXME: rcg11232001 C version for now with GCC.
|
||||
#if ((ASMOPT == 1) && (!defined __GNU_INLINE_X86_32__) && (!defined __INTEL_COMPILER))
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
mov esi,D [pspo]
|
||||
mov edi,D [iMappingOffset]
|
||||
|
@ -915,7 +889,7 @@ vtxLoop:
|
|||
/*
|
||||
// !!! FIXME: rcg11232001 This inline conversion is broken. Use the
|
||||
// !!! FIXME: rcg11232001 C version for now on Linux.
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
STUBBED("debug this");
|
||||
__asm__ __volatile__ (
|
||||
"0: \n\t" // vtxLoop
|
||||
|
@ -956,11 +930,6 @@ vtxLoop:
|
|||
);
|
||||
*/
|
||||
|
||||
#else
|
||||
#error Please write inline ASM for your platform.
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// diffuse mapping
|
||||
|
|
|
@ -67,18 +67,7 @@ ULONG PrepareTexture( UBYTE *pubTexture, PIX pixSizeI, PIX pixSizeJ)
|
|||
// need to upload from RGBA format
|
||||
const PIX pixTextureSize = pixSizeI*pixSizeJ;
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
const UBYTE* src = pubTexture;
|
||||
DWORD* dst = (DWORD*)(pubTexture+pixTextureSize);
|
||||
for (int i=0; i<pixTextureSize; i++) {
|
||||
const DWORD tmp = ((DWORD)*src) | 0xFFFFFF00;
|
||||
*dst = ((tmp << 24) & 0xff000000 ) | ((tmp << 8) & 0x00ff0000 ) |
|
||||
((tmp >> 8) & 0x0000ff00 ) | ((tmp >> 24) & 0x000000ff );
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
mov esi,D [pubTexture]
|
||||
mov edi,D [pubTexture]
|
||||
|
@ -95,7 +84,7 @@ pixLoop:
|
|||
jnz pixLoop
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
__asm__ __volatile__ (
|
||||
"movl %[pubTexture], %%esi \n\t"
|
||||
"movl %[pixTextureSize], %%ecx \n\t"
|
||||
|
@ -115,10 +104,18 @@ pixLoop:
|
|||
: "eax", "ecx", "esi", "edi", "cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Write inline ASM for your platform.
|
||||
#else
|
||||
const UBYTE* src = pubTexture;
|
||||
DWORD* dst = (DWORD*)(pubTexture+pixTextureSize);
|
||||
for (int i=0; i<pixTextureSize; i++) {
|
||||
const DWORD tmp = ((DWORD)*src) | 0xFFFFFF00;
|
||||
*dst = ((tmp << 24) & 0xff000000 ) | ((tmp << 8) & 0x00ff0000 ) |
|
||||
((tmp >> 8) & 0x0000ff00 ) | ((tmp >> 24) & 0x000000ff );
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// determine internal format
|
||||
extern INDEX gap_bAllowGrayTextures;
|
||||
|
|
|
@ -169,32 +169,7 @@ void UploadTexture_OGL( ULONG *pulTexture, PIX pixSizeU, PIX pixSizeV,
|
|||
if( pixSizeV==0) pixSizeV=1;
|
||||
pixSize = pixSizeU*pixSizeV;
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
// Basically average every other pixel...
|
||||
UWORD w = 0;
|
||||
UBYTE *dptr = (UBYTE *) pulDst;
|
||||
UBYTE *sptr = (UBYTE *) pulSrc;
|
||||
#if 0
|
||||
pixSize *= 4;
|
||||
for (PIX i = 0; i < pixSize; i++)
|
||||
{
|
||||
*dptr = (UBYTE) ( (((UWORD) sptr[0]) + ((UWORD) sptr[1])) >> 1 );
|
||||
dptr++;
|
||||
sptr += 2;
|
||||
}
|
||||
#else
|
||||
for (PIX i = 0; i < pixSize; i++)
|
||||
{
|
||||
for (PIX j = 0; j < 4; j++)
|
||||
{
|
||||
*dptr = (UBYTE) ( (((UWORD) sptr[0]) + ((UWORD) sptr[4])) >> 1 );
|
||||
dptr++;
|
||||
sptr++;
|
||||
}
|
||||
sptr += 4;
|
||||
}
|
||||
#endif
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
pxor mm0,mm0
|
||||
mov esi,D [pulSrc]
|
||||
|
@ -244,7 +219,30 @@ void UploadTexture_OGL( ULONG *pulTexture, PIX pixSizeU, PIX pixSizeV,
|
|||
);
|
||||
|
||||
#else
|
||||
#error Please write inline ASM for your platform.
|
||||
// Basically average every other pixel...
|
||||
UWORD w = 0;
|
||||
UBYTE *dptr = (UBYTE *) pulDst;
|
||||
UBYTE *sptr = (UBYTE *) pulSrc;
|
||||
#if 0
|
||||
pixSize *= 4;
|
||||
for (PIX i = 0; i < pixSize; i++)
|
||||
{
|
||||
*dptr = (UBYTE) ( (((UWORD) sptr[0]) + ((UWORD) sptr[1])) >> 1 );
|
||||
dptr++;
|
||||
sptr += 2;
|
||||
}
|
||||
#else
|
||||
for (PIX i = 0; i < pixSize; i++)
|
||||
{
|
||||
for (PIX j = 0; j < 4; j++)
|
||||
{
|
||||
*dptr = (UBYTE) ( (((UWORD) sptr[0]) + ((UWORD) sptr[4])) >> 1 );
|
||||
dptr++;
|
||||
sptr++;
|
||||
}
|
||||
sptr += 4;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// upload mipmap
|
||||
|
|
|
@ -209,58 +209,7 @@ static void MakeOneMipmap( ULONG *pulSrcMipmap, ULONG *pulDstMipmap, PIX pixWidt
|
|||
if( bBilinear) // type of filtering?
|
||||
{ // BILINEAR
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
UBYTE *src = (UBYTE *) pulSrcMipmap;
|
||||
UBYTE *dest = (UBYTE *) pulDstMipmap;
|
||||
for (int i = 0 ; i < pixHeight; i++)
|
||||
{
|
||||
for (int j = 0; j < pixWidth; j++)
|
||||
{
|
||||
// Grab pixels from image
|
||||
UWORD upleft[4];
|
||||
UWORD upright[4];
|
||||
UWORD downleft[4];
|
||||
UWORD downright[4];
|
||||
upleft[0] = *(src + 0);
|
||||
upleft[1] = *(src + 1);
|
||||
upleft[2] = *(src + 2);
|
||||
upleft[3] = *(src + 3);
|
||||
upright[0] = *(src + 4);
|
||||
upright[1] = *(src + 5);
|
||||
upright[2] = *(src + 6);
|
||||
upright[3] = *(src + 7);
|
||||
|
||||
downleft[0] = *(src + pixWidth*8 + 0);
|
||||
downleft[1] = *(src + pixWidth*8 + 1);
|
||||
downleft[2] = *(src + pixWidth*8 + 2);
|
||||
downleft[3] = *(src + pixWidth*8 + 3);
|
||||
downright[0] = *(src + pixWidth*8 + 4);
|
||||
downright[1] = *(src + pixWidth*8 + 5);
|
||||
downright[2] = *(src + pixWidth*8 + 6);
|
||||
downright[3] = *(src + pixWidth*8 + 7);
|
||||
|
||||
UWORD answer[4];
|
||||
answer[0] = upleft[0] + upright[0] + downleft[0] + downright[0] + 2;
|
||||
answer[1] = upleft[1] + upright[1] + downleft[1] + downright[1] + 2;
|
||||
answer[2] = upleft[2] + upright[2] + downleft[2] + downright[2] + 2;
|
||||
answer[3] = upleft[3] + upright[3] + downleft[3] + downright[3] + 2;
|
||||
answer[0] /= 4;
|
||||
answer[1] /= 4;
|
||||
answer[2] /= 4;
|
||||
answer[3] /= 4;
|
||||
|
||||
*(dest + 0) = answer[0];
|
||||
*(dest + 1) = answer[1];
|
||||
*(dest + 2) = answer[2];
|
||||
*(dest + 3) = answer[3];
|
||||
|
||||
src += 8;
|
||||
dest += 4;
|
||||
}
|
||||
src += 8*pixWidth;
|
||||
}
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
pxor mm0,mm0
|
||||
mov ebx,D [pixWidth]
|
||||
|
@ -346,43 +295,63 @@ pixLoopN:
|
|||
);
|
||||
|
||||
#else
|
||||
#error Write inline asm for your platform.
|
||||
UBYTE *src = (UBYTE *) pulSrcMipmap;
|
||||
UBYTE *dest = (UBYTE *) pulDstMipmap;
|
||||
for (int i = 0 ; i < pixHeight; i++)
|
||||
{
|
||||
for (int j = 0; j < pixWidth; j++)
|
||||
{
|
||||
// Grab pixels from image
|
||||
UWORD upleft[4];
|
||||
UWORD upright[4];
|
||||
UWORD downleft[4];
|
||||
UWORD downright[4];
|
||||
upleft[0] = *(src + 0);
|
||||
upleft[1] = *(src + 1);
|
||||
upleft[2] = *(src + 2);
|
||||
upleft[3] = *(src + 3);
|
||||
upright[0] = *(src + 4);
|
||||
upright[1] = *(src + 5);
|
||||
upright[2] = *(src + 6);
|
||||
upright[3] = *(src + 7);
|
||||
|
||||
downleft[0] = *(src + pixWidth*8 + 0);
|
||||
downleft[1] = *(src + pixWidth*8 + 1);
|
||||
downleft[2] = *(src + pixWidth*8 + 2);
|
||||
downleft[3] = *(src + pixWidth*8 + 3);
|
||||
downright[0] = *(src + pixWidth*8 + 4);
|
||||
downright[1] = *(src + pixWidth*8 + 5);
|
||||
downright[2] = *(src + pixWidth*8 + 6);
|
||||
downright[3] = *(src + pixWidth*8 + 7);
|
||||
|
||||
UWORD answer[4];
|
||||
answer[0] = upleft[0] + upright[0] + downleft[0] + downright[0] + 2;
|
||||
answer[1] = upleft[1] + upright[1] + downleft[1] + downright[1] + 2;
|
||||
answer[2] = upleft[2] + upright[2] + downleft[2] + downright[2] + 2;
|
||||
answer[3] = upleft[3] + upright[3] + downleft[3] + downright[3] + 2;
|
||||
answer[0] /= 4;
|
||||
answer[1] /= 4;
|
||||
answer[2] /= 4;
|
||||
answer[3] /= 4;
|
||||
|
||||
*(dest + 0) = answer[0];
|
||||
*(dest + 1) = answer[1];
|
||||
*(dest + 2) = answer[2];
|
||||
*(dest + 3) = answer[3];
|
||||
|
||||
src += 8;
|
||||
dest += 4;
|
||||
}
|
||||
src += 8*pixWidth;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{ // NEAREST-NEIGHBOUR but with border preserving
|
||||
ULONG ulRowModulo = pixWidth*2 *BYTES_PER_TEXEL;
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
|
||||
PIX offset = 0;
|
||||
ulRowModulo /= 4;
|
||||
|
||||
for (int q = 0; q < 2; q++)
|
||||
{
|
||||
for (PIX i = pixHeight / 2; i > 0; i--)
|
||||
{
|
||||
for (PIX j = pixWidth / 2; j > 0; j--)
|
||||
{
|
||||
*pulDstMipmap = *(pulSrcMipmap + offset);
|
||||
pulSrcMipmap += 2;
|
||||
pulDstMipmap++;
|
||||
}
|
||||
|
||||
for (PIX j = pixWidth / 2; j > 0; j--)
|
||||
{
|
||||
*pulDstMipmap = *(pulSrcMipmap + offset + 1);
|
||||
pulSrcMipmap += 2;
|
||||
pulDstMipmap++;
|
||||
}
|
||||
|
||||
pulSrcMipmap += ulRowModulo;
|
||||
}
|
||||
|
||||
offset = pixWidth * 2;
|
||||
}
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
xor ebx,ebx
|
||||
mov esi,D [pulSrcMipmap]
|
||||
|
@ -493,7 +462,33 @@ fullEnd:
|
|||
);
|
||||
|
||||
#else
|
||||
#error Write inline asm for your platform.
|
||||
PIX offset = 0;
|
||||
ulRowModulo /= 4;
|
||||
|
||||
for (int q = 0; q < 2; q++)
|
||||
{
|
||||
for (PIX i = pixHeight / 2; i > 0; i--)
|
||||
{
|
||||
for (PIX j = pixWidth / 2; j > 0; j--)
|
||||
{
|
||||
*pulDstMipmap = *(pulSrcMipmap + offset);
|
||||
pulSrcMipmap += 2;
|
||||
pulDstMipmap++;
|
||||
}
|
||||
|
||||
for (PIX j = pixWidth / 2; j > 0; j--)
|
||||
{
|
||||
*pulDstMipmap = *(pulSrcMipmap + offset + 1);
|
||||
pulSrcMipmap += 2;
|
||||
pulDstMipmap++;
|
||||
}
|
||||
|
||||
pulSrcMipmap += ulRowModulo;
|
||||
}
|
||||
|
||||
offset = pixWidth * 2;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -649,7 +644,7 @@ __int64 mmShifter = 0;
|
|||
__int64 mmMask = 0;
|
||||
ULONG *pulDitherTable;
|
||||
|
||||
#ifdef USE_PORTABLE_C
|
||||
#if !(defined __MSVC_INLINE__) && !(defined __GNU_INLINE_X86_32__)
|
||||
extern const UBYTE *pubClipByte;
|
||||
// increment a byte without overflowing it
|
||||
static inline void IncrementByteWithClip( UBYTE &ub, SLONG slAdd)
|
||||
|
@ -778,35 +773,7 @@ void DitherBitmap( INDEX iDitherType, ULONG *pulSrc, ULONG *pulDst, PIX pixWidth
|
|||
// ------------------------------- ordered matrix dithering routine
|
||||
|
||||
ditherOrder:
|
||||
#if (defined USE_PORTABLE_C)
|
||||
union uConv
|
||||
{
|
||||
ULONG val;
|
||||
DWORD dwords[2];
|
||||
UWORD words[4];
|
||||
WORD iwords[4];
|
||||
UBYTE bytes[8];
|
||||
};
|
||||
for (int i=0; i<pixHeight; i++) {
|
||||
int idx = i&3;
|
||||
uConv dith;
|
||||
dith.val = pulDitherTable[idx];
|
||||
for (int j=0; j<4; j++) { dith.words[j] >>= mmShifter; }
|
||||
dith.val &= mmMask;
|
||||
uConv* src = (uConv*)(pulSrc+i*pixWidth);
|
||||
uConv* dst = (uConv*)(pulDst+i*pixWidth);
|
||||
for (int j=0; j<pixWidth; j+=2) {
|
||||
uConv p=src[0];
|
||||
for (int k=0; k<8; k++) {
|
||||
IncrementByteWithClip(p.bytes[k], dith.bytes[k]);
|
||||
}
|
||||
dst[0] = p;
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
mov esi,D [pulSrc]
|
||||
mov edi,D [pulDst]
|
||||
|
@ -912,7 +879,33 @@ nextRowO:
|
|||
);
|
||||
|
||||
#else
|
||||
#error Write inline asm for your platform.
|
||||
union uConv
|
||||
{
|
||||
ULONG val;
|
||||
DWORD dwords[2];
|
||||
UWORD words[4];
|
||||
WORD iwords[4];
|
||||
UBYTE bytes[8];
|
||||
};
|
||||
for (int i=0; i<pixHeight; i++) {
|
||||
int idx = i&3;
|
||||
uConv dith;
|
||||
dith.val = pulDitherTable[idx];
|
||||
for (int j=0; j<4; j++) { dith.words[j] >>= mmShifter; }
|
||||
dith.val &= mmMask;
|
||||
uConv* src = (uConv*)(pulSrc+i*pixWidth);
|
||||
uConv* dst = (uConv*)(pulDst+i*pixWidth);
|
||||
for (int j=0; j<pixWidth; j+=2) {
|
||||
uConv p=src[0];
|
||||
for (int k=0; k<8; k++) {
|
||||
IncrementByteWithClip(p.bytes[k], dith.bytes[k]);
|
||||
}
|
||||
dst[0] = p;
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
goto theEnd;
|
||||
|
@ -924,34 +917,7 @@ ditherError:
|
|||
if( pulDst!=pulSrc) memcpy( pulDst, pulSrc, pixCanvasWidth*pixCanvasHeight *BYTES_PER_TEXEL);
|
||||
// slModulo+=4;
|
||||
// now, dither destination
|
||||
#if (defined USE_PORTABLE_C)
|
||||
#if 1 //SEB doesn't works....
|
||||
for (int i=0; i<pixHeight-1; i++) {
|
||||
int step = (i&1)?-4:+4;
|
||||
const UBYTE ubMask = (mmErrDiffMask&0xff);
|
||||
UBYTE *src = ((UBYTE*)pulDst)+i*pixCanvasWidth*4;
|
||||
if(i&1) src+=pixWidth*4;
|
||||
// left to right or right to left
|
||||
for (int j=0; j<pixWidth-1; j++) {
|
||||
uConv p1, p3, p5, p7;
|
||||
src+=step;
|
||||
for (int k=0; k<4; k++) { p1.words[k] = src[k]&ubMask; }
|
||||
//p1.val &= mmErrDiffMask;
|
||||
for (int k=0; k<4; k++) { p3.words[k] = (p1.words[k]*3)>>4;
|
||||
p5.words[k] = (p1.words[k]*5)>>4;
|
||||
p7.words[k] = (p1.words[k]*7)>>4; }
|
||||
for (int k=0; k<4; k++) { p1.words[k] -= (p3.words[k] + p5.words[k] + p7.words[k]);}
|
||||
for (int k=0; k<4; k++) {
|
||||
IncrementByteWithClip( src[k + step] , p7.words[k]);
|
||||
IncrementByteWithClip( src[pixCanvasWidth*4 -step +k], p5.words[k]);
|
||||
IncrementByteWithClip( src[pixCanvasWidth*4 +0 +k], p3.words[k]);
|
||||
IncrementByteWithClip( src[pixCanvasWidth*4 +step +k], p1.words[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
pxor mm0,mm0
|
||||
mov esi,D [pulDst]
|
||||
|
@ -1157,7 +1123,32 @@ allDoneE:
|
|||
);
|
||||
|
||||
#else
|
||||
#error Write inline asm for your platform.
|
||||
#if 1 //SEB doesn't works....
|
||||
for (int i=0; i<pixHeight-1; i++) {
|
||||
int step = (i&1)?-4:+4;
|
||||
const UBYTE ubMask = (mmErrDiffMask&0xff);
|
||||
UBYTE *src = ((UBYTE*)pulDst)+i*pixCanvasWidth*4;
|
||||
if(i&1) src+=pixWidth*4;
|
||||
// left to right or right to left
|
||||
for (int j=0; j<pixWidth-1; j++) {
|
||||
uConv p1, p3, p5, p7;
|
||||
src+=step;
|
||||
for (int k=0; k<4; k++) { p1.words[k] = src[k]&ubMask; }
|
||||
//p1.val &= mmErrDiffMask;
|
||||
for (int k=0; k<4; k++) { p3.words[k] = (p1.words[k]*3)>>4;
|
||||
p5.words[k] = (p1.words[k]*5)>>4;
|
||||
p7.words[k] = (p1.words[k]*7)>>4; }
|
||||
for (int k=0; k<4; k++) { p1.words[k] -= (p3.words[k] + p5.words[k] + p7.words[k]);}
|
||||
for (int k=0; k<4; k++) {
|
||||
IncrementByteWithClip( src[k + step] , p7.words[k]);
|
||||
IncrementByteWithClip( src[pixCanvasWidth*4 -step +k], p5.words[k]);
|
||||
IncrementByteWithClip( src[pixCanvasWidth*4 +0 +k], p3.words[k]);
|
||||
IncrementByteWithClip( src[pixCanvasWidth*4 +step +k], p1.words[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
goto theEnd;
|
||||
|
@ -1265,7 +1256,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
#ifdef USE_PORTABLE_C
|
||||
#if !(defined USE_MMX_INTRINSICS) && !(defined __MSVC_INLINE__) && !(defined __GNU_INLINE_X86_32__)
|
||||
typedef SWORD ExtPix[4];
|
||||
|
||||
static inline void extpix_fromi64(ExtPix &pix, const __int64 i64)
|
||||
|
@ -1632,265 +1623,6 @@ void FilterBitmap( INDEX iFilter, ULONG *pulSrc, ULONG *pulDst, PIX pixWidth, PI
|
|||
_mm_empty(); // we're done, clear out the MMX registers!
|
||||
|
||||
|
||||
#elif (defined USE_PORTABLE_C)
|
||||
slModulo1 /= BYTES_PER_TEXEL; // C++ handles incrementing by sizeof type
|
||||
slCanvasWidth /= BYTES_PER_TEXEL; // C++ handles incrementing by sizeof type
|
||||
|
||||
ULONG *src = pulSrc;
|
||||
ULONG *dst = pulDst;
|
||||
ULONG *rowptr = aulRows;
|
||||
|
||||
ExtPix rmm1={0}, rmm2={0}, rmm3={0}, rmm4={0}, rmm5={0}, rmm6={0}, rmm7={0};
|
||||
#define EXTPIXFROMINT64(x) ExtPix r##x; extpix_fromi64(r##x, x);
|
||||
EXTPIXFROMINT64(mmCm);
|
||||
EXTPIXFROMINT64(mmCe);
|
||||
EXTPIXFROMINT64(mmCc);
|
||||
EXTPIXFROMINT64(mmEch);
|
||||
EXTPIXFROMINT64(mmEcl);
|
||||
EXTPIXFROMINT64(mmEe);
|
||||
EXTPIXFROMINT64(mmEm);
|
||||
EXTPIXFROMINT64(mmMm);
|
||||
EXTPIXFROMINT64(mmMe);
|
||||
EXTPIXFROMINT64(mmMc);
|
||||
EXTPIXFROMINT64(mmAdd);
|
||||
EXTPIXFROMINT64(mmInvDiv);
|
||||
#undef EXTPIXFROMINT64
|
||||
|
||||
// ----------------------- process upper left corner
|
||||
extend_pixel(src[0], rmm1);
|
||||
extend_pixel(src[1], rmm2);
|
||||
extend_pixel(src[pixCanvasWidth], rmm3);
|
||||
extend_pixel(src[pixCanvasWidth+1], rmm4);
|
||||
|
||||
extpix_add(rmm2, rmm3);
|
||||
extpix_mul(rmm1, rmmCm);
|
||||
extpix_mul(rmm2, rmmCe);
|
||||
extpix_mul(rmm4, rmmCc);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
*(rowptr++) = unextend_pixel(rmm1);
|
||||
|
||||
src++;
|
||||
|
||||
// ----------------------- process upper edge pixels
|
||||
for (PIX i = pixWidth - 2; i != 0; i--)
|
||||
{
|
||||
extend_pixel(src[-1], rmm1);
|
||||
extend_pixel(src[0], rmm2);
|
||||
extend_pixel(src[1], rmm3);
|
||||
extend_pixel(src[pixCanvasWidth-1], rmm4);
|
||||
extend_pixel(src[pixCanvasWidth], rmm5);
|
||||
extend_pixel(src[pixCanvasWidth+1], rmm6);
|
||||
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm4, rmm6);
|
||||
extpix_mul(rmm1, rmmEch);
|
||||
extpix_mul(rmm2, rmmEm);
|
||||
extpix_mul(rmm4, rmmEcl);
|
||||
extpix_mul(rmm5, rmmEe);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_add(rmm1, rmm5);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
*(rowptr++) = unextend_pixel(rmm1);
|
||||
src++;
|
||||
}
|
||||
|
||||
// ----------------------- process upper right corner
|
||||
|
||||
extend_pixel(src[-1], rmm1);
|
||||
extend_pixel(src[0], rmm2);
|
||||
extend_pixel(src[pixCanvasWidth-1], rmm3);
|
||||
extend_pixel(src[pixCanvasWidth], rmm4);
|
||||
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_mul(rmm1, rmmCe);
|
||||
extpix_mul(rmm2, rmmCm);
|
||||
extpix_mul(rmm3, rmmCc);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
*rowptr = unextend_pixel(rmm1);
|
||||
|
||||
// ----------------------- process bitmap middle pixels
|
||||
|
||||
dst += slCanvasWidth;
|
||||
src += slModulo1;
|
||||
|
||||
// for each row
|
||||
for (size_t i = pixHeight-2; i != 0; i--) // rowLoop
|
||||
{
|
||||
rowptr = aulRows;
|
||||
|
||||
// process left edge pixel
|
||||
extend_pixel(src[-pixCanvasWidth], rmm1);
|
||||
extend_pixel(src[(-pixCanvasWidth)+1], rmm2);
|
||||
extend_pixel(src[0], rmm3);
|
||||
extend_pixel(src[1], rmm4);
|
||||
extend_pixel(src[pixCanvasWidth], rmm5);
|
||||
extend_pixel(src[pixCanvasWidth+1], rmm6);
|
||||
|
||||
extpix_add(rmm1, rmm5);
|
||||
extpix_add(rmm2, rmm6);
|
||||
extpix_mul(rmm1, rmmEch);
|
||||
extpix_mul(rmm2, rmmEcl);
|
||||
extpix_mul(rmm3, rmmEm);
|
||||
extpix_mul(rmm4, rmmEe);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
*(rowptr++) = unextend_pixel(rmm1);
|
||||
src++;
|
||||
dst++;
|
||||
|
||||
// for each pixel in current row
|
||||
for (size_t j = pixWidth-2; j != 0; j--) // pixLoop
|
||||
{
|
||||
// prepare upper convolution row
|
||||
extend_pixel(src[(-pixCanvasWidth)-1], rmm1);
|
||||
extend_pixel(src[-pixCanvasWidth], rmm2);
|
||||
extend_pixel(src[(-pixCanvasWidth)+1], rmm3);
|
||||
|
||||
// prepare middle convolution row
|
||||
extend_pixel(src[-1], rmm4);
|
||||
extend_pixel(src[0], rmm5);
|
||||
extend_pixel(src[1], rmm6);
|
||||
|
||||
// free some registers
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm2, rmm4);
|
||||
extpix_mul(rmm5, rmmMm);
|
||||
|
||||
// prepare lower convolution row
|
||||
extend_pixel(src[pixCanvasWidth-1], rmm3);
|
||||
extend_pixel(src[pixCanvasWidth], rmm4);
|
||||
extend_pixel(src[pixCanvasWidth+1], rmm7);
|
||||
|
||||
// calc weightened value
|
||||
extpix_add(rmm2, rmm6);
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm2, rmm4);
|
||||
extpix_add(rmm1, rmm7);
|
||||
extpix_mul(rmm2, rmmMe);
|
||||
extpix_mul(rmm1, rmmMc);
|
||||
extpix_add(rmm2, rmm5);
|
||||
extpix_add(rmm1, rmm2);
|
||||
|
||||
// calc and store wightened value
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
*(rowptr++) = unextend_pixel(rmm1);
|
||||
|
||||
// advance to next pixel
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
|
||||
// process right edge pixel
|
||||
extend_pixel(src[(-pixCanvasWidth)-1], rmm1);
|
||||
extend_pixel(src[-pixCanvasWidth], rmm2);
|
||||
extend_pixel(src[-1], rmm3);
|
||||
extend_pixel(src[0], rmm4);
|
||||
extend_pixel(src[pixCanvasWidth-1], rmm5);
|
||||
extend_pixel(src[pixCanvasWidth], rmm6);
|
||||
|
||||
extpix_add(rmm1, rmm5);
|
||||
extpix_add(rmm2, rmm6);
|
||||
extpix_mul(rmm1, rmmEcl);
|
||||
extpix_mul(rmm2, rmmEch);
|
||||
extpix_mul(rmm3, rmmEe);
|
||||
extpix_mul(rmm4, rmmEm);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
*rowptr = unextend_pixel(rmm1);
|
||||
|
||||
// advance to next row
|
||||
src += slModulo1;
|
||||
dst += slModulo1;
|
||||
}
|
||||
|
||||
// ----------------------- process lower left corner
|
||||
rowptr = aulRows;
|
||||
extend_pixel(src[-pixCanvasWidth], rmm1);
|
||||
extend_pixel(src[(-pixCanvasWidth)+1], rmm2);
|
||||
extend_pixel(src[0], rmm3);
|
||||
extend_pixel(src[1], rmm4);
|
||||
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_mul(rmm1, rmmCe);
|
||||
extpix_mul(rmm2, rmmCc);
|
||||
extpix_mul(rmm3, rmmCm);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
dst[0] = unextend_pixel(rmm1);
|
||||
|
||||
src++;
|
||||
dst++;
|
||||
rowptr++;
|
||||
|
||||
// ----------------------- process lower edge pixels
|
||||
for (size_t i = pixWidth-2; i != 0; i--) // lowerLoop
|
||||
{
|
||||
// for each pixel
|
||||
extend_pixel(src[(-pixCanvasWidth)-1], rmm1);
|
||||
extend_pixel(src[-pixCanvasWidth], rmm2);
|
||||
extend_pixel(src[(-pixCanvasWidth)+1], rmm3);
|
||||
extend_pixel(src[-1], rmm4);
|
||||
extend_pixel(src[0], rmm5);
|
||||
extend_pixel(src[1], rmm6);
|
||||
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm4, rmm6);
|
||||
extpix_mul(rmm1, rmmEcl);
|
||||
extpix_mul(rmm2, rmmEe);
|
||||
extpix_mul(rmm4, rmmEch);
|
||||
extpix_mul(rmm5, rmmEm);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_add(rmm1, rmm5);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
dst[0] = unextend_pixel(rmm1);
|
||||
|
||||
// advance to next pixel
|
||||
src++;
|
||||
dst++;
|
||||
rowptr++;
|
||||
}
|
||||
|
||||
// ----------------------- lower right corners
|
||||
extend_pixel(src[(-pixCanvasWidth)-1], rmm1);
|
||||
extend_pixel(src[-pixCanvasWidth], rmm2);
|
||||
extend_pixel(src[-1], rmm3);
|
||||
extend_pixel(src[0], rmm4);
|
||||
|
||||
extpix_add(rmm2, rmm3);
|
||||
extpix_mul(rmm1, rmmCc);
|
||||
extpix_mul(rmm2, rmmCe);
|
||||
extpix_mul(rmm4, rmmCm);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
dst[0] = unextend_pixel(rmm1);
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
cld
|
||||
|
@ -2537,7 +2269,264 @@ lowerLoop:
|
|||
);
|
||||
|
||||
#else
|
||||
#error Write inline asm for your platform.
|
||||
slModulo1 /= BYTES_PER_TEXEL; // C++ handles incrementing by sizeof type
|
||||
slCanvasWidth /= BYTES_PER_TEXEL; // C++ handles incrementing by sizeof type
|
||||
|
||||
ULONG *src = pulSrc;
|
||||
ULONG *dst = pulDst;
|
||||
ULONG *rowptr = aulRows;
|
||||
|
||||
ExtPix rmm1={0}, rmm2={0}, rmm3={0}, rmm4={0}, rmm5={0}, rmm6={0}, rmm7={0};
|
||||
#define EXTPIXFROMINT64(x) ExtPix r##x; extpix_fromi64(r##x, x);
|
||||
EXTPIXFROMINT64(mmCm);
|
||||
EXTPIXFROMINT64(mmCe);
|
||||
EXTPIXFROMINT64(mmCc);
|
||||
EXTPIXFROMINT64(mmEch);
|
||||
EXTPIXFROMINT64(mmEcl);
|
||||
EXTPIXFROMINT64(mmEe);
|
||||
EXTPIXFROMINT64(mmEm);
|
||||
EXTPIXFROMINT64(mmMm);
|
||||
EXTPIXFROMINT64(mmMe);
|
||||
EXTPIXFROMINT64(mmMc);
|
||||
EXTPIXFROMINT64(mmAdd);
|
||||
EXTPIXFROMINT64(mmInvDiv);
|
||||
#undef EXTPIXFROMINT64
|
||||
|
||||
// ----------------------- process upper left corner
|
||||
extend_pixel(src[0], rmm1);
|
||||
extend_pixel(src[1], rmm2);
|
||||
extend_pixel(src[pixCanvasWidth], rmm3);
|
||||
extend_pixel(src[pixCanvasWidth+1], rmm4);
|
||||
|
||||
extpix_add(rmm2, rmm3);
|
||||
extpix_mul(rmm1, rmmCm);
|
||||
extpix_mul(rmm2, rmmCe);
|
||||
extpix_mul(rmm4, rmmCc);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
*(rowptr++) = unextend_pixel(rmm1);
|
||||
|
||||
src++;
|
||||
|
||||
// ----------------------- process upper edge pixels
|
||||
for (PIX i = pixWidth - 2; i != 0; i--)
|
||||
{
|
||||
extend_pixel(src[-1], rmm1);
|
||||
extend_pixel(src[0], rmm2);
|
||||
extend_pixel(src[1], rmm3);
|
||||
extend_pixel(src[pixCanvasWidth-1], rmm4);
|
||||
extend_pixel(src[pixCanvasWidth], rmm5);
|
||||
extend_pixel(src[pixCanvasWidth+1], rmm6);
|
||||
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm4, rmm6);
|
||||
extpix_mul(rmm1, rmmEch);
|
||||
extpix_mul(rmm2, rmmEm);
|
||||
extpix_mul(rmm4, rmmEcl);
|
||||
extpix_mul(rmm5, rmmEe);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_add(rmm1, rmm5);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
*(rowptr++) = unextend_pixel(rmm1);
|
||||
src++;
|
||||
}
|
||||
|
||||
// ----------------------- process upper right corner
|
||||
|
||||
extend_pixel(src[-1], rmm1);
|
||||
extend_pixel(src[0], rmm2);
|
||||
extend_pixel(src[pixCanvasWidth-1], rmm3);
|
||||
extend_pixel(src[pixCanvasWidth], rmm4);
|
||||
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_mul(rmm1, rmmCe);
|
||||
extpix_mul(rmm2, rmmCm);
|
||||
extpix_mul(rmm3, rmmCc);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
*rowptr = unextend_pixel(rmm1);
|
||||
|
||||
// ----------------------- process bitmap middle pixels
|
||||
|
||||
dst += slCanvasWidth;
|
||||
src += slModulo1;
|
||||
|
||||
// for each row
|
||||
for (size_t i = pixHeight-2; i != 0; i--) // rowLoop
|
||||
{
|
||||
rowptr = aulRows;
|
||||
|
||||
// process left edge pixel
|
||||
extend_pixel(src[-pixCanvasWidth], rmm1);
|
||||
extend_pixel(src[(-pixCanvasWidth)+1], rmm2);
|
||||
extend_pixel(src[0], rmm3);
|
||||
extend_pixel(src[1], rmm4);
|
||||
extend_pixel(src[pixCanvasWidth], rmm5);
|
||||
extend_pixel(src[pixCanvasWidth+1], rmm6);
|
||||
|
||||
extpix_add(rmm1, rmm5);
|
||||
extpix_add(rmm2, rmm6);
|
||||
extpix_mul(rmm1, rmmEch);
|
||||
extpix_mul(rmm2, rmmEcl);
|
||||
extpix_mul(rmm3, rmmEm);
|
||||
extpix_mul(rmm4, rmmEe);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
*(rowptr++) = unextend_pixel(rmm1);
|
||||
src++;
|
||||
dst++;
|
||||
|
||||
// for each pixel in current row
|
||||
for (size_t j = pixWidth-2; j != 0; j--) // pixLoop
|
||||
{
|
||||
// prepare upper convolution row
|
||||
extend_pixel(src[(-pixCanvasWidth)-1], rmm1);
|
||||
extend_pixel(src[-pixCanvasWidth], rmm2);
|
||||
extend_pixel(src[(-pixCanvasWidth)+1], rmm3);
|
||||
|
||||
// prepare middle convolution row
|
||||
extend_pixel(src[-1], rmm4);
|
||||
extend_pixel(src[0], rmm5);
|
||||
extend_pixel(src[1], rmm6);
|
||||
|
||||
// free some registers
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm2, rmm4);
|
||||
extpix_mul(rmm5, rmmMm);
|
||||
|
||||
// prepare lower convolution row
|
||||
extend_pixel(src[pixCanvasWidth-1], rmm3);
|
||||
extend_pixel(src[pixCanvasWidth], rmm4);
|
||||
extend_pixel(src[pixCanvasWidth+1], rmm7);
|
||||
|
||||
// calc weightened value
|
||||
extpix_add(rmm2, rmm6);
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm2, rmm4);
|
||||
extpix_add(rmm1, rmm7);
|
||||
extpix_mul(rmm2, rmmMe);
|
||||
extpix_mul(rmm1, rmmMc);
|
||||
extpix_add(rmm2, rmm5);
|
||||
extpix_add(rmm1, rmm2);
|
||||
|
||||
// calc and store wightened value
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
*(rowptr++) = unextend_pixel(rmm1);
|
||||
|
||||
// advance to next pixel
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
|
||||
// process right edge pixel
|
||||
extend_pixel(src[(-pixCanvasWidth)-1], rmm1);
|
||||
extend_pixel(src[-pixCanvasWidth], rmm2);
|
||||
extend_pixel(src[-1], rmm3);
|
||||
extend_pixel(src[0], rmm4);
|
||||
extend_pixel(src[pixCanvasWidth-1], rmm5);
|
||||
extend_pixel(src[pixCanvasWidth], rmm6);
|
||||
|
||||
extpix_add(rmm1, rmm5);
|
||||
extpix_add(rmm2, rmm6);
|
||||
extpix_mul(rmm1, rmmEcl);
|
||||
extpix_mul(rmm2, rmmEch);
|
||||
extpix_mul(rmm3, rmmEe);
|
||||
extpix_mul(rmm4, rmmEm);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
*rowptr = unextend_pixel(rmm1);
|
||||
|
||||
// advance to next row
|
||||
src += slModulo1;
|
||||
dst += slModulo1;
|
||||
}
|
||||
|
||||
// ----------------------- process lower left corner
|
||||
rowptr = aulRows;
|
||||
extend_pixel(src[-pixCanvasWidth], rmm1);
|
||||
extend_pixel(src[(-pixCanvasWidth)+1], rmm2);
|
||||
extend_pixel(src[0], rmm3);
|
||||
extend_pixel(src[1], rmm4);
|
||||
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_mul(rmm1, rmmCe);
|
||||
extpix_mul(rmm2, rmmCc);
|
||||
extpix_mul(rmm3, rmmCm);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
dst[0] = unextend_pixel(rmm1);
|
||||
|
||||
src++;
|
||||
dst++;
|
||||
rowptr++;
|
||||
|
||||
// ----------------------- process lower edge pixels
|
||||
for (size_t i = pixWidth-2; i != 0; i--) // lowerLoop
|
||||
{
|
||||
// for each pixel
|
||||
extend_pixel(src[(-pixCanvasWidth)-1], rmm1);
|
||||
extend_pixel(src[-pixCanvasWidth], rmm2);
|
||||
extend_pixel(src[(-pixCanvasWidth)+1], rmm3);
|
||||
extend_pixel(src[-1], rmm4);
|
||||
extend_pixel(src[0], rmm5);
|
||||
extend_pixel(src[1], rmm6);
|
||||
|
||||
extpix_add(rmm1, rmm3);
|
||||
extpix_add(rmm4, rmm6);
|
||||
extpix_mul(rmm1, rmmEcl);
|
||||
extpix_mul(rmm2, rmmEe);
|
||||
extpix_mul(rmm4, rmmEch);
|
||||
extpix_mul(rmm5, rmmEm);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_add(rmm1, rmm5);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
dst[0] = unextend_pixel(rmm1);
|
||||
|
||||
// advance to next pixel
|
||||
src++;
|
||||
dst++;
|
||||
rowptr++;
|
||||
}
|
||||
|
||||
// ----------------------- lower right corners
|
||||
extend_pixel(src[(-pixCanvasWidth)-1], rmm1);
|
||||
extend_pixel(src[-pixCanvasWidth], rmm2);
|
||||
extend_pixel(src[-1], rmm3);
|
||||
extend_pixel(src[0], rmm4);
|
||||
|
||||
extpix_add(rmm2, rmm3);
|
||||
extpix_mul(rmm1, rmmCc);
|
||||
extpix_mul(rmm2, rmmCe);
|
||||
extpix_mul(rmm4, rmmCm);
|
||||
extpix_add(rmm1, rmm2);
|
||||
extpix_add(rmm1, rmm4);
|
||||
extpix_adds(rmm1, rmmAdd);
|
||||
extpix_mulhi(rmm1, rmmInvDiv);
|
||||
dst[-pixCanvasWidth] = *rowptr;
|
||||
dst[0] = unextend_pixel(rmm1);
|
||||
|
||||
#endif
|
||||
|
||||
// all done (finally)
|
||||
|
|
|
@ -89,13 +89,7 @@ extern void (__stdcall *pglPNTrianglesfATI)( GLenum pname, GLfloat param);
|
|||
inline void glCOLOR( COLOR col)
|
||||
{
|
||||
/* rcg10052001 Platform-wrappers. */
|
||||
#if (defined USE_PORTABLE_C)
|
||||
col = ( ((col << 24) ) |
|
||||
((col << 8) & 0x00FF0000) |
|
||||
((col >> 8) & 0x0000FF00) |
|
||||
((col >> 24) ) );
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
mov eax,dword ptr [col]
|
||||
bswap eax
|
||||
|
@ -110,7 +104,11 @@ inline void glCOLOR( COLOR col)
|
|||
);
|
||||
|
||||
#else
|
||||
#error please define for your platform.
|
||||
col = ( ((col << 24) ) |
|
||||
((col << 8) & 0x00FF0000) |
|
||||
((col >> 8) & 0x0000FF00) |
|
||||
((col >> 24) ) );
|
||||
|
||||
#endif
|
||||
|
||||
pglColor4ubv((GLubyte*)&col);
|
||||
|
|
|
@ -32,9 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define W word ptr
|
||||
#define B byte ptr
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
#define ASMOPT 0
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#define ASMOPT 1
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#define ASMOPT 1
|
||||
|
@ -1285,8 +1283,7 @@ static void RenderWater(void)
|
|||
{ // SUB-SAMPLING
|
||||
SLONG slHeightMapStep, slHeightRowStep;
|
||||
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
push ebx
|
||||
bsf ecx,D [_pixTexWidth]
|
||||
|
@ -1357,7 +1354,7 @@ pixLoop:
|
|||
pop ebx
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
// rcg12152001 needed extra registers. :(
|
||||
_slHeightMapStep_renderWater = slHeightMapStep;
|
||||
_pixBaseWidth_renderWater = pixBaseWidth;
|
||||
|
@ -1460,10 +1457,6 @@ pixLoop:
|
|||
"cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error fill in for your platform.
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
PIX pixPos, pixDU, pixDV;
|
||||
|
|
|
@ -40,16 +40,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define W word ptr
|
||||
#define B byte ptr
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
#define ASMOPT 0
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#define ASMOPT 1
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#define ASMOPT 1
|
||||
#else
|
||||
#define ASMOPT 0
|
||||
#endif
|
||||
|
||||
extern INDEX shd_bFineQuality;
|
||||
extern INDEX shd_iFiltering;
|
||||
extern INDEX shd_iDithering;
|
||||
|
@ -290,8 +280,7 @@ void CLayerMixer::AddAmbientPoint(void)
|
|||
_slLightMax<<=7;
|
||||
_slLightStep>>=1;
|
||||
|
||||
#if (ASMOPT == 1)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
// prepare interpolants
|
||||
movd mm0,D [_slL2Row]
|
||||
|
@ -364,7 +353,7 @@ skipPixel:
|
|||
emms
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
ULONG tmp1, tmp2;
|
||||
__asm__ __volatile__ (
|
||||
// prepare interpolants
|
||||
|
@ -439,10 +428,6 @@ skipPixel:
|
|||
: FPU_REGS, MMX_REGS, "eax", "ecx", "edi", "cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Write inline asm for your platform.
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// !!! FIXME WARNING: I have not checked this code, and it could be
|
||||
|
@ -496,8 +481,7 @@ void CLayerMixer::AddAmbientMaskPoint( UBYTE *pubMask, UBYTE ubMask)
|
|||
_slLightStep>>=1;
|
||||
|
||||
|
||||
#if (ASMOPT == 1)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
// prepare interpolants
|
||||
movd mm0,D [_slL2Row]
|
||||
|
@ -576,7 +560,7 @@ skipPixel:
|
|||
emms
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
ULONG tmp1, tmp2;
|
||||
__asm__ __volatile__ (
|
||||
// prepare interpolants
|
||||
|
@ -660,10 +644,6 @@ skipPixel:
|
|||
"cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Please write inline assembly for your platform.
|
||||
#endif
|
||||
|
||||
#else // Portable C version...
|
||||
|
||||
UBYTE* pubLayer = (UBYTE*)_pulLayer;
|
||||
|
@ -723,8 +703,7 @@ void CLayerMixer::AddDiffusionPoint(void)
|
|||
_slLightMax<<=7;
|
||||
_slLightStep>>=1;
|
||||
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
// prepare interpolants
|
||||
movd mm0,D [_slL2Row]
|
||||
|
@ -796,7 +775,7 @@ skipPixel:
|
|||
emms
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
ULONG tmp1, tmp2;
|
||||
__asm__ __volatile__ (
|
||||
// prepare interpolants
|
||||
|
@ -871,10 +850,6 @@ skipPixel:
|
|||
: FPU_REGS, MMX_REGS, "eax", "ecx", "edi", "cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Write inline assembly for your platform.
|
||||
#endif
|
||||
|
||||
#else
|
||||
// for each pixel in the shadow map
|
||||
UBYTE* pubLayer = (UBYTE*)_pulLayer;
|
||||
|
@ -929,8 +904,7 @@ void CLayerMixer::AddDiffusionMaskPoint( UBYTE *pubMask, UBYTE ubMask)
|
|||
_slLightMax<<=7;
|
||||
_slLightStep>>=1;
|
||||
|
||||
#if (ASMOPT == 1)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
// prepare interpolants
|
||||
movd mm0,D [_slL2Row]
|
||||
|
@ -1008,7 +982,7 @@ skipPixel:
|
|||
emms
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
ULONG tmp1, tmp2;
|
||||
__asm__ __volatile__ (
|
||||
// prepare interpolants
|
||||
|
@ -1091,11 +1065,6 @@ skipPixel:
|
|||
"cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Write inline ASM for your platform.
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// for each pixel in the shadow map
|
||||
|
@ -1201,8 +1170,7 @@ BOOL CLayerMixer::PrepareOneLayerPoint( CBrushShadowLayer *pbsl, BOOL bNoMask)
|
|||
FLOAT fDL2oDV = fDDL2oDV + 2*(lm_vStepV%v00);
|
||||
//_v00 = v00;
|
||||
|
||||
#if ((ASMOPT == 1) && (!defined __GNU_INLINE_X86_32__))
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
fld D [fDDL2oDU]
|
||||
fadd D [fDDL2oDU]
|
||||
|
@ -1230,12 +1198,6 @@ BOOL CLayerMixer::PrepareOneLayerPoint( CBrushShadowLayer *pbsl, BOOL bNoMask)
|
|||
fistp D [_slDDL2oDV]
|
||||
fistp D [_slDDL2oDU]
|
||||
}
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
STUBBED("inline asm.");
|
||||
#else
|
||||
#error Please write inline assembly for your platform.
|
||||
#endif
|
||||
|
||||
#else
|
||||
fDDL2oDU *= 2;
|
||||
fDDL2oDV *= 2;
|
||||
|
@ -1321,8 +1283,7 @@ void CLayerMixer::AddOneLayerGradient( CGradientParameters &gp)
|
|||
_pulLayer = lm_pulShadowMap;
|
||||
FLOAT fStart = Clamp( fGr00-(fDGroDJ+fDGroDI)*0.5f, 0.0f, 1.0f);
|
||||
|
||||
#if ((ASMOPT == 1) && (!defined __GNU_INLINE_X86_32__))
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__int64 mmRowAdv;
|
||||
SLONG fixGRow = (fGr00-(fDGroDJ+fDGroDI)*0.5f)*32767.0f; // 16:15
|
||||
SLONG slModulo = (lm_pixCanvasSizeU-lm_pixPolygonSizeU) *BYTES_PER_TEXEL;
|
||||
|
@ -1436,14 +1397,6 @@ rowNext:
|
|||
rowDone:
|
||||
emms
|
||||
}
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
|
||||
STUBBED("WRITE ME. Argh.");
|
||||
|
||||
#else
|
||||
#error Need inline assembly for your platform.
|
||||
#endif
|
||||
|
||||
#else
|
||||
// well, make gradient ...
|
||||
SLONG slR0=0,slG0=0,slB0=0;
|
||||
|
@ -1528,9 +1481,8 @@ rowDone:
|
|||
// apply directional light or ambient to layer
|
||||
void CLayerMixer::AddDirectional(void)
|
||||
{
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
ULONG ulLight = ByteSwap( lm_colLight);
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
// prepare pointers and variables
|
||||
mov edi,D [_pulLayer]
|
||||
|
@ -1565,7 +1517,8 @@ rowNext:
|
|||
emms
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
ULONG ulLight = ByteSwap( lm_colLight);
|
||||
ULONG tmp;
|
||||
__asm__ __volatile__ (
|
||||
// prepare pointers and variables
|
||||
|
@ -1608,10 +1561,6 @@ rowNext:
|
|||
: FPU_REGS, "mm5", "mm6", "ecx", "edi", "cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Write inline assembly for your platform.
|
||||
#endif
|
||||
|
||||
#else
|
||||
UBYTE* pubLayer = (UBYTE*)_pulLayer;
|
||||
// for each pixel in the shadow map
|
||||
|
@ -1631,9 +1580,8 @@ rowNext:
|
|||
// apply directional light thru mask to layer
|
||||
void CLayerMixer::AddMaskDirectional( UBYTE *pubMask, UBYTE ubMask)
|
||||
{
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
ULONG ulLight = ByteSwap( lm_colLight);
|
||||
#if (defined __MSVC_INLINE__)
|
||||
// prepare some local variables
|
||||
__asm {
|
||||
// prepare pointers and variables
|
||||
|
@ -1665,7 +1613,8 @@ skipLight:
|
|||
emms
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
ULONG ulLight = ByteSwap( lm_colLight);
|
||||
ULONG tmp;
|
||||
__asm__ __volatile__ (
|
||||
// prepare pointers and variables
|
||||
|
@ -1706,10 +1655,6 @@ skipLight:
|
|||
"cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Please write inline assembly for your platform.
|
||||
#endif
|
||||
|
||||
#else
|
||||
UBYTE* pubLayer = (UBYTE*)_pulLayer;
|
||||
// for each pixel in the shadow map
|
||||
|
@ -1832,7 +1777,33 @@ void CLayerMixer::MixOneMipmap(CBrushShadowMap *pbsm, INDEX iMipmap)
|
|||
}
|
||||
} // set initial color
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
cld
|
||||
mov ebx,D [this]
|
||||
mov ecx,D [ebx].lm_pixCanvasSizeU
|
||||
imul ecx,D [ebx].lm_pixCanvasSizeV
|
||||
mov edi,D [ebx].lm_pulShadowMap
|
||||
mov eax,D [colAmbient]
|
||||
bswap eax
|
||||
rep stosd
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
ULONG clob1, clob2, clob3;
|
||||
__asm__ __volatile__ (
|
||||
"cld \n\t"
|
||||
"imull %%esi, %%ecx \n\t"
|
||||
"bswapl %%eax \n\t"
|
||||
"rep \n\t"
|
||||
"stosl \n\t"
|
||||
: "=a" (clob1), "=c" (clob2), "=D" (clob3)
|
||||
: "c" (this->lm_pixCanvasSizeU), "S" (this->lm_pixCanvasSizeV),
|
||||
"a" (colAmbient), "D" (this->lm_pulShadowMap)
|
||||
: "cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
register ULONG count = this->lm_pixCanvasSizeU * this->lm_pixCanvasSizeV;
|
||||
#if PLATFORM_LITTLEENDIAN
|
||||
// Forces C fallback; BYTESWAP itself is a no-op on little endian.
|
||||
|
@ -1850,35 +1821,7 @@ void CLayerMixer::MixOneMipmap(CBrushShadowMap *pbsm, INDEX iMipmap)
|
|||
ptr++;
|
||||
}
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
cld
|
||||
mov ebx,D [this]
|
||||
mov ecx,D [ebx].lm_pixCanvasSizeU
|
||||
imul ecx,D [ebx].lm_pixCanvasSizeV
|
||||
mov edi,D [ebx].lm_pulShadowMap
|
||||
mov eax,D [colAmbient]
|
||||
bswap eax
|
||||
rep stosd
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
ULONG clob1, clob2, clob3;
|
||||
__asm__ __volatile__ (
|
||||
"cld \n\t"
|
||||
"imull %%esi, %%ecx \n\t"
|
||||
"bswapl %%eax \n\t"
|
||||
"rep \n\t"
|
||||
"stosl \n\t"
|
||||
: "=a" (clob1), "=c" (clob2), "=D" (clob3)
|
||||
: "c" (this->lm_pixCanvasSizeU), "S" (this->lm_pixCanvasSizeV),
|
||||
"a" (colAmbient), "D" (this->lm_pulShadowMap)
|
||||
: "cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Please write inline assembly for your platform.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_AMBIENTFILL);
|
||||
|
||||
|
@ -1955,9 +1898,7 @@ void CLayerMixer::MixOneMipmap(CBrushShadowMap *pbsm, INDEX iMipmap)
|
|||
// copy from static shadow map to dynamic layer
|
||||
__forceinline void CLayerMixer::CopyShadowLayer(void)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C)
|
||||
memcpy(lm_pulShadowMap, lm_pulStaticShadowMap, lm_pixCanvasSizeU*lm_pixCanvasSizeV*4);
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
cld
|
||||
mov ebx,D [this]
|
||||
|
@ -1967,7 +1908,7 @@ __forceinline void CLayerMixer::CopyShadowLayer(void)
|
|||
mov edi,D [ebx].lm_pulShadowMap
|
||||
rep movsd
|
||||
}
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
ULONG clob1, clob2, clob3;
|
||||
__asm__ __volatile__ (
|
||||
"cld \n\t"
|
||||
|
@ -1980,21 +1921,16 @@ __forceinline void CLayerMixer::CopyShadowLayer(void)
|
|||
: "cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Please write inline assembly for your platform.
|
||||
#endif
|
||||
#else
|
||||
memcpy(lm_pulShadowMap, lm_pulStaticShadowMap, lm_pixCanvasSizeU*lm_pixCanvasSizeV*4);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// copy from static shadow map to dynamic layer
|
||||
__forceinline void CLayerMixer::FillShadowLayer( COLOR col)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C)
|
||||
DWORD* dst = (DWORD*)lm_pulShadowMap;
|
||||
int n = lm_pixCanvasSizeU*lm_pixCanvasSizeV;
|
||||
DWORD color = __builtin_bswap32(col);
|
||||
while(n--) {*(dst++)=color;}
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
cld
|
||||
mov ebx,D [this]
|
||||
|
@ -2006,7 +1942,7 @@ __forceinline void CLayerMixer::FillShadowLayer( COLOR col)
|
|||
rep stosd
|
||||
}
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
ULONG clob1, clob2, clob3;
|
||||
__asm__ __volatile__ (
|
||||
"cld \n\t"
|
||||
|
@ -2020,9 +1956,12 @@ __forceinline void CLayerMixer::FillShadowLayer( COLOR col)
|
|||
: "cc", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
#error Please write inline assembly for your platform.
|
||||
#endif
|
||||
#else
|
||||
DWORD* dst = (DWORD*)lm_pulShadowMap;
|
||||
int n = lm_pixCanvasSizeU*lm_pixCanvasSizeV;
|
||||
DWORD color = __builtin_bswap32(col);
|
||||
while(n--) {*(dst++)=color;}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,18 +24,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define _PC_64 0x0300
|
||||
|
||||
// !!! FIXME: I'd like to remove any dependency on the FPU control word from the game, asap. --ryan.
|
||||
#ifdef USE_PORTABLE_C
|
||||
// Fake control87 for USE_PORTABLE_C version
|
||||
inline ULONG _control87(WORD newcw, WORD mask)
|
||||
{
|
||||
static WORD fpw=_PC_64;
|
||||
if (mask != 0)
|
||||
{
|
||||
fpw &= ~mask;
|
||||
fpw |= (newcw & mask);
|
||||
}
|
||||
return(fpw);
|
||||
}
|
||||
#if (defined _MSC_VER)
|
||||
|
||||
// _control87 is provided by the compiler
|
||||
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
|
||||
|
@ -74,8 +65,20 @@ inline ULONG _control87(WORD newcw, WORD mask)
|
|||
return(fpw);
|
||||
}
|
||||
|
||||
#elif (!defined _MSC_VER)
|
||||
#error Implement for your platform, or add a stub conditional here.
|
||||
#else
|
||||
|
||||
// Fake control87 for USE_PORTABLE_C version
|
||||
inline ULONG _control87(WORD newcw, WORD mask)
|
||||
{
|
||||
static WORD fpw=_PC_64;
|
||||
if (mask != 0)
|
||||
{
|
||||
fpw &= ~mask;
|
||||
fpw |= (newcw & mask);
|
||||
}
|
||||
return(fpw);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Get current precision setting of FPU. */
|
||||
|
|
|
@ -312,12 +312,7 @@ inline FLOAT NormByteToFloat( const ULONG ul)
|
|||
// fast float to int conversion
|
||||
inline SLONG FloatToInt( FLOAT f)
|
||||
{
|
||||
#if defined(__arm__) || defined(USE_PORTABLE_C)
|
||||
// round to nearest by adding/subtracting 0.5 (depending on f pos/neg) before converting to SLONG
|
||||
float addToRound = copysignf(0.5f, f); // copy f's signbit to 0.5 => if f<0 then addToRound = -0.5, else 0.5
|
||||
return((SLONG) (f + addToRound));
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
SLONG slRet;
|
||||
__asm {
|
||||
fld D [f]
|
||||
|
@ -336,16 +331,16 @@ inline SLONG FloatToInt( FLOAT f)
|
|||
);
|
||||
return(slRet);
|
||||
#else
|
||||
#error Fill this in for your platform.
|
||||
// round to nearest by adding/subtracting 0.5 (depending on f pos/neg) before converting to SLONG
|
||||
float addToRound = copysignf(0.5f, f); // copy f's signbit to 0.5 => if f<0 then addToRound = -0.5, else 0.5
|
||||
return((SLONG) (f + addToRound));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// log base 2 of any float numero
|
||||
inline FLOAT Log2( FLOAT f) {
|
||||
#if (defined USE_PORTABLE_C) || defined(__arm__)
|
||||
return log2f(f);
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
FLOAT fRet;
|
||||
_asm {
|
||||
fld1
|
||||
|
@ -368,7 +363,8 @@ inline FLOAT Log2( FLOAT f) {
|
|||
);
|
||||
return(fRet);
|
||||
#else
|
||||
#error Fill this in for your platform.
|
||||
return log2f(f);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -376,25 +372,7 @@ inline FLOAT Log2( FLOAT f) {
|
|||
// returns accurate values only for integers that are power of 2
|
||||
inline SLONG FastLog2( SLONG x)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C)
|
||||
#ifdef __GNUC__
|
||||
if(x == 0) return 0; // __builtin_clz() is undefined for 0
|
||||
int numLeadingZeros = __builtin_clz(x);
|
||||
return 31 - numLeadingZeros;
|
||||
#else
|
||||
register SLONG val = x;
|
||||
register SLONG retval = 31;
|
||||
while (retval > 0)
|
||||
{
|
||||
if (val & (1 << retval))
|
||||
return retval;
|
||||
retval--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
SLONG slRet;
|
||||
__asm {
|
||||
bsr eax,D [x]
|
||||
|
@ -411,8 +389,21 @@ inline SLONG FastLog2( SLONG x)
|
|||
: "memory"
|
||||
);
|
||||
return(slRet);
|
||||
#elif (defined __GNUC__)
|
||||
if(x == 0) return 0; // __builtin_clz() is undefined for 0
|
||||
int numLeadingZeros = __builtin_clz(x);
|
||||
return 31 - numLeadingZeros;
|
||||
#else
|
||||
#error Fill this in for your platform.
|
||||
register SLONG val = x;
|
||||
register SLONG retval = 31;
|
||||
while (retval > 0)
|
||||
{
|
||||
if (val & (1 << retval))
|
||||
return retval;
|
||||
retval--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -420,11 +411,7 @@ inline SLONG FastLog2( SLONG x)
|
|||
// returns log2 of first larger value that is a power of 2
|
||||
inline SLONG FastMaxLog2( SLONG x)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C)
|
||||
printf("CHECK THIS: %s:%d\n", __FILE__, __LINE__);
|
||||
return((SLONG) log2((double) x));
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
SLONG slRet;
|
||||
__asm {
|
||||
bsr eax,D [x]
|
||||
|
@ -448,7 +435,9 @@ printf("CHECK THIS: %s:%d\n", __FILE__, __LINE__);
|
|||
);
|
||||
return(slRet);
|
||||
#else
|
||||
#error Fill this in for your platform.
|
||||
printf("CHECK THIS: %s:%d\n", __FILE__, __LINE__);
|
||||
return((SLONG) log2((double) x));
|
||||
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -40,14 +40,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define W word ptr
|
||||
#define B byte ptr
|
||||
|
||||
#if (defined __MSVC_INLINE__)
|
||||
#define ASMOPT 1
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
#define ASMOPT 0 // !!! FIXME: rcg10112001 Write GCC inline asm versions...
|
||||
#else
|
||||
#define ASMOPT 0
|
||||
#endif
|
||||
|
||||
|
||||
extern BOOL CVA_bModels;
|
||||
extern BOOL GFX_bTruform;
|
||||
|
@ -663,7 +655,7 @@ static FLOAT _fHazeAdd;
|
|||
// check vertex against fog
|
||||
static void GetFogMapInVertex( GFXVertex3 &vtx, GFXTexCoord &tex)
|
||||
{
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
mov esi,D [vtx]
|
||||
mov edi,D [tex]
|
||||
|
@ -708,7 +700,7 @@ static void GetFogMapInVertex( GFXVertex3 &vtx, GFXTexCoord &tex)
|
|||
// check vertex against haze
|
||||
static void GetHazeMapInVertex( GFXVertex3 &vtx, FLOAT &tx1)
|
||||
{
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
mov esi,D [vtx]
|
||||
mov edi,D [tx1]
|
||||
|
@ -1080,7 +1072,7 @@ static void UnpackFrame( CRenderModel &rm, BOOL bKeepNormals)
|
|||
const ModelFrameVertex16 *pFrame1 = rm.rm_pFrame16_1;
|
||||
if( pFrame0==pFrame1)
|
||||
{
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
// for each vertex in mip
|
||||
const SLONG fixLerpRatio = FloatToInt(fLerpRatio*256.0f); // fix 8:8
|
||||
SLONG slTmp1, slTmp2, slTmp3;
|
||||
|
@ -1196,7 +1188,7 @@ vtxNext16:
|
|||
// if lerping
|
||||
else
|
||||
{
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
// for each vertex in mip
|
||||
const SLONG fixLerpRatio = FloatToInt(fLerpRatio*256.0f); // fix 8:8
|
||||
SLONG slTmp1, slTmp2, slTmp3;
|
||||
|
@ -1365,7 +1357,7 @@ vtxNext16L:
|
|||
// if no lerping
|
||||
if( pFrame0==pFrame1)
|
||||
{
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
// for each vertex in mip
|
||||
const SLONG fixLerpRatio = FloatToInt(fLerpRatio*256.0f); // fix 8:8
|
||||
SLONG slTmp1, slTmp2, slTmp3;
|
||||
|
@ -1464,7 +1456,7 @@ vtxNext8:
|
|||
// if lerping
|
||||
else
|
||||
{
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
const SLONG fixLerpRatio = FloatToInt(fLerpRatio*256.0f); // fix 8:8
|
||||
SLONG slTmp1, slTmp2, slTmp3;
|
||||
// re-adjust stretching factors because of fixint lerping (divide by 256)
|
||||
|
@ -1610,7 +1602,7 @@ vtxNext8L:
|
|||
}
|
||||
|
||||
// generate colors from shades
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
pxor mm0,mm0
|
||||
// construct 64-bit RGBA light
|
||||
|
@ -1974,7 +1966,7 @@ void CModelObject::RenderModel_View( CRenderModel &rm)
|
|||
pvtxSrfBase = &_avtxSrfBase[iSrfVx0];
|
||||
INDEX iSrfVx;
|
||||
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
push ebx
|
||||
mov ebx,D [puwSrfToMip]
|
||||
|
@ -2074,7 +2066,7 @@ srfVtxLoop:
|
|||
const COLOR colD = AdjustColor( ms.ms_colDiffuse, _slTexHueShift, _slTexSaturation);
|
||||
colSrfDiff.MultiplyRGBA( colD, colMdlDiff);
|
||||
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
// setup texcoord array
|
||||
__asm {
|
||||
push ebx
|
||||
|
@ -2134,7 +2126,7 @@ vtxEnd:
|
|||
for( INDEX iSrfVx=0; iSrfVx<ctSrfVx; iSrfVx++) pcolSrfBase[iSrfVx] = colSrfDiffAdj;
|
||||
}
|
||||
else {
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
// setup color array
|
||||
const COLOR colS = colSrfDiff.ul.abgr;
|
||||
__asm {
|
||||
|
@ -2335,7 +2327,7 @@ diffColLoop:
|
|||
// cache rotation
|
||||
const FLOATmatrix3D &m = rm.rm_mObjectRotation;
|
||||
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
push ebx
|
||||
mov ebx,D [m]
|
||||
|
@ -2530,7 +2522,7 @@ reflMipLoop:
|
|||
// cache object view rotation
|
||||
const FLOATmatrix3D &m = rm.rm_mObjectToView;
|
||||
|
||||
#if ASMOPT == 1
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
push ebx
|
||||
mov ebx,D [m]
|
||||
|
|
|
@ -105,10 +105,7 @@ static SLONG slTmp;
|
|||
|
||||
static inline PIX PIXCoord(FLOAT f) // (f+0.9999f) or (ceil(f))
|
||||
{
|
||||
#if (defined USE_PORTABLE_C)
|
||||
return((PIX) (f+0.9999f));
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
PIX pixRet;
|
||||
__asm {
|
||||
fld dword ptr [f]
|
||||
|
@ -142,7 +139,8 @@ static inline PIX PIXCoord(FLOAT f) // (f+0.9999f) or (ceil(f))
|
|||
return pixRet;
|
||||
|
||||
#else
|
||||
#error Please write inline ASM for your platform.
|
||||
return((PIX) (f+0.9999f));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -43,17 +43,15 @@ static CSoundData *psd;
|
|||
|
||||
// nasm on MacOS X is getting wrong addresses of external globals, so I have
|
||||
// to define them in the .asm file...lame.
|
||||
#ifdef __GNU_INLINE_X86_32__
|
||||
#ifdef USE_PORTABLE_C
|
||||
#define INASM
|
||||
#else
|
||||
#if (defined __GNU_INLINE_X86_32__)
|
||||
#define INASM extern
|
||||
#endif
|
||||
#else
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#define INASM static
|
||||
static __int64 mmInvFactor = 0x00007FFF00007FFF;
|
||||
static FLOAT f65536 = 65536.0f;
|
||||
static FLOAT f4G = 4294967296.0f;
|
||||
#else
|
||||
#define INASM static
|
||||
#endif
|
||||
|
||||
INASM SLONG slMixerBufferSize; // size in samples per channel of the destination buffers
|
||||
|
@ -81,11 +79,7 @@ void ResetMixer( const SLONG *pslBuffer, const SLONG slBufferSize)
|
|||
slMixerBufferSampleRate = _pSound->sl_SwfeFormat.nSamplesPerSec;
|
||||
|
||||
// wipe destination mixer buffer
|
||||
// (Mac OS X uses this path because Apple's memset() is customized for each CPU they support and way faster than this inline asm. --ryan.)
|
||||
#if ((defined USE_PORTABLE_C) || (PLATFORM_MACOSX))
|
||||
memset(pvMixerBuffer, 0, slMixerBufferSize * 8);
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
cld
|
||||
xor eax,eax
|
||||
|
@ -94,19 +88,8 @@ void ResetMixer( const SLONG *pslBuffer, const SLONG slBufferSize)
|
|||
shl ecx,1 // *2 because of 32-bit src format
|
||||
rep stosd
|
||||
}
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
// !!! FIXME : rcg12172001 Is this REALLY any faster than memset()?
|
||||
ULONG clob1, clob2;
|
||||
__asm__ __volatile__ (
|
||||
"cld \n\t"
|
||||
"rep \n\t"
|
||||
"stosl \n\t"
|
||||
: "=D" (clob1), "=c" (clob2)
|
||||
: "a" (0), "D" (pvMixerBuffer), "c" (slMixerBufferSize*2)
|
||||
: "cc", "memory"
|
||||
);
|
||||
#else
|
||||
#error please write inline asm for your platform.
|
||||
memset(pvMixerBuffer, 0, slMixerBufferSize * 8);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -118,10 +101,7 @@ void CopyMixerBuffer_stereo( const SLONG slSrcOffset, void *pDstBuffer, const SL
|
|||
ASSERT( slBytes%4==0);
|
||||
if( slBytes<4) return;
|
||||
|
||||
#if ((defined USE_PORTABLE_C) || (PLATFORM_MACOSX))
|
||||
// (Mac OS X uses this path because Apple's memset() is customized for each CPU they support and way faster than this inline asm. --ryan.)
|
||||
memcpy(pDstBuffer, ((const char *)pvMixerBuffer) + slSrcOffset, slBytes);
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
cld
|
||||
mov esi,D [slSrcOffset]
|
||||
|
@ -131,21 +111,8 @@ void CopyMixerBuffer_stereo( const SLONG slSrcOffset, void *pDstBuffer, const SL
|
|||
shr ecx,2 // bytes to samples per channel
|
||||
rep movsd
|
||||
}
|
||||
#elif (defined __GNU_INLINE_X86_32__)
|
||||
// !!! FIXME : rcg12172001 Is this REALLY any faster than memcpy()?
|
||||
ULONG clob1, clob2, clob3;
|
||||
__asm__ __volatile__ (
|
||||
"cld \n\t"
|
||||
"rep \n\t"
|
||||
"movsl \n\t"
|
||||
: "=S" (clob1), "=D" (clob2), "=c" (clob3)
|
||||
: "S" (((char *)pvMixerBuffer) + slSrcOffset),
|
||||
"D" (pDstBuffer),
|
||||
"c" (slBytes >> 2)
|
||||
: "cc", "memory"
|
||||
);
|
||||
#else
|
||||
#error please write inline asm for your platform.
|
||||
memcpy(pDstBuffer, ((const char *)pvMixerBuffer) + slSrcOffset, slBytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -157,18 +124,7 @@ void CopyMixerBuffer_mono( const SLONG slSrcOffset, void *pDstBuffer, const SLON
|
|||
ASSERT( slBytes%2==0);
|
||||
if( slBytes<4) return;
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
// (This is untested, currently. --ryan.)
|
||||
WORD *dest = (WORD *) pDstBuffer;
|
||||
WORD *src = (WORD *) ( ((char *) pvMixerBuffer) + slSrcOffset );
|
||||
SLONG max = slBytes / 4;
|
||||
for (SLONG i = 0; i < max; i++) {
|
||||
*dest = *src;
|
||||
dest++; // move 16 bits.
|
||||
src+=2; // move 32 bits.
|
||||
}
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
mov esi,D [slSrcOffset]
|
||||
add esi,D [pvMixerBuffer]
|
||||
|
@ -204,7 +160,15 @@ copyLoop:
|
|||
);
|
||||
|
||||
#else
|
||||
#error please write inline asm for your platform.
|
||||
// (This is untested, currently. --ryan.)
|
||||
WORD *dest = (WORD *) pDstBuffer;
|
||||
WORD *src = (WORD *) ( ((char *) pvMixerBuffer) + slSrcOffset );
|
||||
SLONG max = slBytes / 4;
|
||||
for (SLONG i = 0; i < max; i++) {
|
||||
*dest = *src;
|
||||
dest++; // move 16 bits.
|
||||
src+=2; // move 32 bits.
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -215,24 +179,7 @@ static void ConvertMixerBuffer( const SLONG slBytes)
|
|||
ASSERT( slBytes%4==0);
|
||||
if( slBytes<4) return;
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
//STUBBED("ConvertMixerBuffer");
|
||||
SWORD *dest = (SWORD *) pvMixerBuffer;
|
||||
SLONG *src = (SLONG *) pvMixerBuffer;
|
||||
SLONG max = slBytes / 2;
|
||||
int tmp;
|
||||
for (SLONG i = 0; i < max; i++) {
|
||||
tmp = *src;
|
||||
if (tmp>32767) tmp=32767;
|
||||
if (tmp<-32767) tmp=-32767;
|
||||
*dest=tmp;
|
||||
dest++; // move 16 bits.
|
||||
src++; // move 32 bits.
|
||||
}
|
||||
|
||||
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
cld
|
||||
mov esi,D [pvMixerBuffer]
|
||||
|
@ -271,7 +218,20 @@ copyLoop:
|
|||
);
|
||||
|
||||
#else
|
||||
#error please write inline asm for your platform.
|
||||
|
||||
SWORD *dest = (SWORD *) pvMixerBuffer;
|
||||
SLONG *src = (SLONG *) pvMixerBuffer;
|
||||
SLONG max = slBytes / 2;
|
||||
int tmp;
|
||||
for (SLONG i = 0; i < max; i++) {
|
||||
tmp = *src;
|
||||
if (tmp>32767) tmp=32767;
|
||||
if (tmp<-32767) tmp=-32767;
|
||||
*dest=tmp;
|
||||
dest++; // move 16 bits.
|
||||
src++; // move 32 bits.
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -337,85 +297,7 @@ inline void MixMono( CSoundObject *pso)
|
|||
{
|
||||
_pfSoundProfile.StartTimer(CSoundProfile::PTI_RAWMIXER);
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
// initialize some local vars
|
||||
SLONG slLeftSample, slRightSample, slNextSample;
|
||||
SLONG *pslDstBuffer = (SLONG*)pvMixerBuffer;
|
||||
fixLeftOfs = (__int64)(fLeftOfs * 65536.0);
|
||||
fixRightOfs = (__int64)(fRightOfs * 65536.0);
|
||||
__int64 fixLeftStep = (__int64)(fLeftStep * 65536.0);
|
||||
__int64 fixRightStep = (__int64)(fRightStep * 65536.0);
|
||||
__int64 fixSoundBufferSize = ((__int64)slSoundBufferSize)<<16;
|
||||
mmSurroundFactor = (__int64)(SWORD)mmSurroundFactor;
|
||||
|
||||
SLONG slLeftVolume_ = slLeftVolume >> 16;
|
||||
SLONG slRightVolume_ = slRightVolume >> 16;
|
||||
|
||||
// loop thru source buffer
|
||||
INDEX iCt = slMixerBufferSize;
|
||||
FOREVER
|
||||
{
|
||||
// if left channel source sample came to end of sample buffer
|
||||
if( fixLeftOfs >= fixSoundBufferSize) {
|
||||
fixLeftOfs -= fixSoundBufferSize;
|
||||
// if has no loop, end it
|
||||
bEndOfSound = bNotLoop;
|
||||
}
|
||||
// if right channel source sample came to end of sample buffer
|
||||
if( fixRightOfs >= fixSoundBufferSize) {
|
||||
fixRightOfs -= fixSoundBufferSize;
|
||||
// if has no loop, end it
|
||||
bEndOfSound = bNotLoop;
|
||||
}
|
||||
// end of buffer?
|
||||
if( iCt<=0 || bEndOfSound) break;
|
||||
|
||||
// fetch one lineary interpolated sample on left channel
|
||||
slLeftSample = pswSrcBuffer[(fixLeftOfs>>16)+0];
|
||||
slNextSample = pswSrcBuffer[(fixLeftOfs>>16)+1];
|
||||
slLeftSample = (slLeftSample*(65535-(fixLeftOfs&65535)) + slNextSample*(fixLeftOfs&65535)) >>16;
|
||||
// fetch one lineary interpolated sample on right channel
|
||||
slRightSample = pswSrcBuffer[(fixRightOfs>>16)+0];
|
||||
slNextSample = pswSrcBuffer[(fixRightOfs>>16)+1];
|
||||
slRightSample = (slRightSample*(65535-(fixRightOfs&65535)) + slNextSample*(fixRightOfs&65535)) >>16;
|
||||
|
||||
// filter samples
|
||||
slLastLeftSample += ((slLeftSample -slLastLeftSample) *slLeftFilter) >>15;
|
||||
slLastRightSample += ((slRightSample-slLastRightSample)*slRightFilter)>>15;
|
||||
|
||||
// apply stereo volume to current sample
|
||||
slLeftSample = (slLastLeftSample * slLeftVolume_) >>15;
|
||||
slRightSample = (slLastRightSample * slRightVolume_)>>15;
|
||||
|
||||
slLeftSample ^= (SLONG)((mmSurroundFactor>> 0)&0xFFFFFFFF);
|
||||
slRightSample ^= (SLONG)((mmSurroundFactor>>32)&0xFFFFFFFF);
|
||||
|
||||
// mix in current sample
|
||||
slLeftSample += pslDstBuffer[0];
|
||||
slRightSample += pslDstBuffer[1];
|
||||
// upper clamp
|
||||
if( slLeftSample > MAX_SWORD) slLeftSample = MAX_SWORD;
|
||||
if( slRightSample > MAX_SWORD) slRightSample = MAX_SWORD;
|
||||
// lower clamp
|
||||
if( slLeftSample < MIN_SWORD) slLeftSample = MIN_SWORD;
|
||||
if( slRightSample < MIN_SWORD) slRightSample = MIN_SWORD;
|
||||
|
||||
// store samples (both channels)
|
||||
pslDstBuffer[0] = slLeftSample;
|
||||
pslDstBuffer[1] = slRightSample;
|
||||
|
||||
// modify volume `
|
||||
slLeftVolume += (SWORD)((mmVolumeGain>> 0)&0xFFFF);
|
||||
slRightVolume += (SWORD)((mmVolumeGain>>16)&0xFFFF);
|
||||
|
||||
// advance to next sample
|
||||
fixLeftOfs += fixLeftStep;
|
||||
fixRightOfs += fixRightStep;
|
||||
pslDstBuffer += 2;
|
||||
iCt--;
|
||||
}
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
// convert from floats to fixints 32:16
|
||||
fld D [fLeftOfs]
|
||||
|
@ -553,19 +435,6 @@ loopEnd:
|
|||
MixMono_asm(pso);
|
||||
|
||||
#else
|
||||
#error please write inline asm for your platform.
|
||||
#endif
|
||||
|
||||
_pfSoundProfile.StopTimer(CSoundProfile::PTI_RAWMIXER);
|
||||
}
|
||||
|
||||
|
||||
// mixes one stereo 16-bit signed sound to destination buffer
|
||||
inline void MixStereo( CSoundObject *pso)
|
||||
{
|
||||
_pfSoundProfile.StartTimer(CSoundProfile::PTI_RAWMIXER);
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
// initialize some local vars
|
||||
SLONG slLeftSample, slRightSample, slNextSample;
|
||||
SLONG *pslDstBuffer = (SLONG*)pvMixerBuffer;
|
||||
|
@ -599,12 +468,12 @@ inline void MixStereo( CSoundObject *pso)
|
|||
if( iCt<=0 || bEndOfSound) break;
|
||||
|
||||
// fetch one lineary interpolated sample on left channel
|
||||
slLeftSample = pswSrcBuffer[(fixLeftOfs>>15)+0];
|
||||
slNextSample = pswSrcBuffer[(fixLeftOfs>>15)+2];
|
||||
slLeftSample = pswSrcBuffer[(fixLeftOfs>>16)+0];
|
||||
slNextSample = pswSrcBuffer[(fixLeftOfs>>16)+1];
|
||||
slLeftSample = (slLeftSample*(65535-(fixLeftOfs&65535)) + slNextSample*(fixLeftOfs&65535)) >>16;
|
||||
// fetch one lineary interpolated sample on right channel
|
||||
slRightSample = pswSrcBuffer[(fixRightOfs>>15)+0];
|
||||
slNextSample = pswSrcBuffer[(fixRightOfs>>15)+2];
|
||||
slRightSample = pswSrcBuffer[(fixRightOfs>>16)+0];
|
||||
slNextSample = pswSrcBuffer[(fixRightOfs>>16)+1];
|
||||
slRightSample = (slRightSample*(65535-(fixRightOfs&65535)) + slNextSample*(fixRightOfs&65535)) >>16;
|
||||
|
||||
// filter samples
|
||||
|
@ -643,7 +512,18 @@ inline void MixStereo( CSoundObject *pso)
|
|||
iCt--;
|
||||
}
|
||||
|
||||
#elif (defined __MSVC_INLINE__)
|
||||
#endif
|
||||
|
||||
_pfSoundProfile.StopTimer(CSoundProfile::PTI_RAWMIXER);
|
||||
}
|
||||
|
||||
|
||||
// mixes one stereo 16-bit signed sound to destination buffer
|
||||
inline void MixStereo( CSoundObject *pso)
|
||||
{
|
||||
_pfSoundProfile.StartTimer(CSoundProfile::PTI_RAWMIXER);
|
||||
|
||||
#if (defined __MSVC_INLINE__)
|
||||
__asm {
|
||||
// convert from floats to fixints 32:16
|
||||
fld D [fLeftOfs]
|
||||
|
@ -783,7 +663,83 @@ loopEnd:
|
|||
MixStereo_asm(pso);
|
||||
|
||||
#else
|
||||
#error please write inline asm for your platform.
|
||||
// initialize some local vars
|
||||
SLONG slLeftSample, slRightSample, slNextSample;
|
||||
SLONG *pslDstBuffer = (SLONG*)pvMixerBuffer;
|
||||
fixLeftOfs = (__int64)(fLeftOfs * 65536.0);
|
||||
fixRightOfs = (__int64)(fRightOfs * 65536.0);
|
||||
__int64 fixLeftStep = (__int64)(fLeftStep * 65536.0);
|
||||
__int64 fixRightStep = (__int64)(fRightStep * 65536.0);
|
||||
__int64 fixSoundBufferSize = ((__int64)slSoundBufferSize)<<16;
|
||||
mmSurroundFactor = (__int64)(SWORD)mmSurroundFactor;
|
||||
|
||||
SLONG slLeftVolume_ = slLeftVolume >> 16;
|
||||
SLONG slRightVolume_ = slRightVolume >> 16;
|
||||
|
||||
// loop thru source buffer
|
||||
INDEX iCt = slMixerBufferSize;
|
||||
FOREVER
|
||||
{
|
||||
// if left channel source sample came to end of sample buffer
|
||||
if( fixLeftOfs >= fixSoundBufferSize) {
|
||||
fixLeftOfs -= fixSoundBufferSize;
|
||||
// if has no loop, end it
|
||||
bEndOfSound = bNotLoop;
|
||||
}
|
||||
// if right channel source sample came to end of sample buffer
|
||||
if( fixRightOfs >= fixSoundBufferSize) {
|
||||
fixRightOfs -= fixSoundBufferSize;
|
||||
// if has no loop, end it
|
||||
bEndOfSound = bNotLoop;
|
||||
}
|
||||
// end of buffer?
|
||||
if( iCt<=0 || bEndOfSound) break;
|
||||
|
||||
// fetch one lineary interpolated sample on left channel
|
||||
slLeftSample = pswSrcBuffer[(fixLeftOfs>>15)+0];
|
||||
slNextSample = pswSrcBuffer[(fixLeftOfs>>15)+2];
|
||||
slLeftSample = (slLeftSample*(65535-(fixLeftOfs&65535)) + slNextSample*(fixLeftOfs&65535)) >>16;
|
||||
// fetch one lineary interpolated sample on right channel
|
||||
slRightSample = pswSrcBuffer[(fixRightOfs>>15)+0];
|
||||
slNextSample = pswSrcBuffer[(fixRightOfs>>15)+2];
|
||||
slRightSample = (slRightSample*(65535-(fixRightOfs&65535)) + slNextSample*(fixRightOfs&65535)) >>16;
|
||||
|
||||
// filter samples
|
||||
slLastLeftSample += ((slLeftSample -slLastLeftSample) *slLeftFilter) >>15;
|
||||
slLastRightSample += ((slRightSample-slLastRightSample)*slRightFilter)>>15;
|
||||
|
||||
// apply stereo volume to current sample
|
||||
slLeftSample = (slLastLeftSample * slLeftVolume_) >>15;
|
||||
slRightSample = (slLastRightSample * slRightVolume_)>>15;
|
||||
|
||||
slLeftSample ^= (SLONG)((mmSurroundFactor>> 0)&0xFFFFFFFF);
|
||||
slRightSample ^= (SLONG)((mmSurroundFactor>>32)&0xFFFFFFFF);
|
||||
|
||||
// mix in current sample
|
||||
slLeftSample += pslDstBuffer[0];
|
||||
slRightSample += pslDstBuffer[1];
|
||||
// upper clamp
|
||||
if( slLeftSample > MAX_SWORD) slLeftSample = MAX_SWORD;
|
||||
if( slRightSample > MAX_SWORD) slRightSample = MAX_SWORD;
|
||||
// lower clamp
|
||||
if( slLeftSample < MIN_SWORD) slLeftSample = MIN_SWORD;
|
||||
if( slRightSample < MIN_SWORD) slRightSample = MIN_SWORD;
|
||||
|
||||
// store samples (both channels)
|
||||
pslDstBuffer[0] = slLeftSample;
|
||||
pslDstBuffer[1] = slRightSample;
|
||||
|
||||
// modify volume `
|
||||
slLeftVolume += (SWORD)((mmVolumeGain>> 0)&0xFFFF);
|
||||
slRightVolume += (SWORD)((mmVolumeGain>>16)&0xFFFF);
|
||||
|
||||
// advance to next sample
|
||||
fixLeftOfs += fixLeftStep;
|
||||
fixRightOfs += fixRightStep;
|
||||
pslDstBuffer += 2;
|
||||
iCt--;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
_pfSoundProfile.StopTimer(CSoundProfile::PTI_RAWMIXER);
|
||||
|
|
Loading…
Reference in New Issue
Block a user