diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt index 287d7c7..213a22b 100644 --- a/Sources/CMakeLists.txt +++ b/Sources/CMakeLists.txt @@ -84,7 +84,7 @@ endif() # !!! FIXME: you currently need this, but I'd like to flip this to not use # !!! FIXME: assembly language. And maybe delete the asm code too. -set(USE_I386_ASM TRUE) +option(USE_I386_ASM "Use X86 ASM" TRUE) if (USE_I386_ASM) # You need the Netwide Assembler (NASM) to build this on Intel systems. @@ -102,7 +102,15 @@ else() add_definitions(-DUSE_PORTABLE_C=1) endif() +option(PANDORA "Compile for Pandora" FALSE) +if (PANDORA) + add_definitions(-DPANDORA=1) +endif() +option(USE_TREMOR "Use Tremor instead of Vorbis" FALSE) +if (USE_TREMOR) + add_definitions(-DUSE_TREMOR=1) +endif() # !!! FIXME: I currently force this, but you shouldn't _have_ to. add_definitions(-DSINGLE_THREADED=1) @@ -111,8 +119,16 @@ include_directories( . External/SDL12 External/libogg/include - External/libvorbis/include ) +if(USE_TREMOR) +if(PANDORA) + include_directories(/mnt/utmp/codeblocks/usr/include/tremor) +else() + # !!!Do something here! +endif() +else() + include_directories(External/libvorbis/include) +endif() # We build ECC, then use it to generate C++ code for the game entities... macro(add_parser_and_scanner _PARSER _SCANNER) @@ -594,7 +610,7 @@ set(ENGINE_SRCS ${ADDITIONAL_ENGINE_SRCS} ) -add_executable(SeriousSam +add_executable(ssam ${ENGINE_SRCS} SeriousSam/LevelInfo.cpp SeriousSam/CmdLine.cpp @@ -609,7 +625,7 @@ add_executable(SeriousSam SeriousSam/MenuGadgets.cpp SeriousSam/MenuPrinting.cpp ) -add_dependencies(SeriousSam ParseEntities) +add_dependencies(ssam ParseEntities) # !!! FIXME: this is an option because you have to recompile the entire engine twice. # !!! FIXME: If we can put the engine in a static library and not lose symbols, @@ -622,9 +638,9 @@ endif() if(MACOSX) find_library(COCOA_FRAMEWORK Cocoa) - target_link_libraries(SeriousSam "${COCOA_FRAMEWORK}") - target_link_libraries(SeriousSam "${CMAKE_CURRENT_SOURCE_DIR}/lib/macosx/libSDL-1.2.0.dylib") - target_link_libraries(SeriousSam "${CMAKE_CURRENT_SOURCE_DIR}/lib/macosx/libSDLmain.a") + target_link_libraries(ssam "${COCOA_FRAMEWORK}") + target_link_libraries(ssam "${CMAKE_CURRENT_SOURCE_DIR}/lib/macosx/libSDL-1.2.0.dylib") + target_link_libraries(ssam "${CMAKE_CURRENT_SOURCE_DIR}/lib/macosx/libSDLmain.a") if(BUILD_DEDICATED_SERVER) target_link_libraries(SeriousSamDedicated "${COCOA_FRAMEWORK}") target_link_libraries(SeriousSamDedicated "${CMAKE_CURRENT_SOURCE_DIR}/lib/macosx/libSDL-1.2.0.dylib") @@ -633,12 +649,14 @@ if(MACOSX) endif() if(LINUX) - set_target_properties(SeriousSam PROPERTIES LINK_FLAGS "-Wl,-rpath,$ORIGIN") - target_link_libraries(SeriousSam "m") - target_link_libraries(SeriousSam "dl") - target_link_libraries(SeriousSam "pthread") - target_link_libraries(SeriousSam ${SDL_LIBRARY}) - + set_target_properties(ssam PROPERTIES LINK_FLAGS "-Wl,-rpath,$ORIGIN") + target_link_libraries(ssam "m") + target_link_libraries(ssam "dl") + if(PANDORA) + target_link_libraries(ssam "rt") + endif() + target_link_libraries(ssam "pthread") + target_link_libraries(ssam ${SDL_LIBRARY}) if(BUILD_DEDICATED_SERVER) set_target_properties(SeriousSamDedicated PROPERTIES LINK_FLAGS "-Wl,-rpath,$ORIGIN") target_link_libraries(SeriousSamDedicated "m") diff --git a/Sources/Engine/Base/Profiling.cpp b/Sources/Engine/Base/Profiling.cpp index d37d42e..bd23ba2 100644 --- a/Sources/Engine/Base/Profiling.cpp +++ b/Sources/Engine/Base/Profiling.cpp @@ -28,9 +28,15 @@ template class CStaticArray; 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__) __int64 mmRet; diff --git a/Sources/Engine/Base/Scanner.l b/Sources/Engine/Base/Scanner.l index 5db324f..6111887 100644 --- a/Sources/Engine/Base/Scanner.l +++ b/Sources/Engine/Base/Scanner.l @@ -1,6 +1,6 @@ %{ #include "ParsingSymbols.h" -#include "Parser.h" +#include "parser.h" #include #include diff --git a/Sources/Engine/Base/Shell.h b/Sources/Engine/Base/Shell.h index 09b8ca6..a11571f 100644 --- a/Sources/Engine/Base/Shell.h +++ b/Sources/Engine/Base/Shell.h @@ -24,7 +24,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +#if 0 #define NEXTARGUMENT(type) ( *((type*&)pArgs)++ ) +#else +#define NEXTARGUMENT(type) ( *((type*)&pArgs) ); pArgs+=sizeof(void*); +#endif // Object that takes care of shell functions, variables, macros etc. class ENGINE_API CShell { diff --git a/Sources/Engine/Base/Timer.cpp b/Sources/Engine/Base/Timer.cpp index 5f0fe0f..fb6dfe6 100644 --- a/Sources/Engine/Base/Timer.cpp +++ b/Sources/Engine/Base/Timer.cpp @@ -28,9 +28,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include -//#if ( (USE_PORTABLE_C) || (PLATFORM_UNIX) ) -//#define USE_GETTIMEOFDAY 1 -//#endif +#if (USE_PORTABLE_C) +#define USE_GETTIMEOFDAY 1 +#endif #if USE_GETTIMEOFDAY #include @@ -40,10 +40,15 @@ with this program; if not, write to the Free Software Foundation, Inc., static inline __int64 ReadTSC(void) { #if USE_GETTIMEOFDAY +#ifdef PANDORA + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC, &tp); + return( (((__int64) tp.tv_sec) * 1000000000LL) + ((__int64) tp.tv_nsec)); +#else struct timeval tv; gettimeofday(&tv, NULL); return( (((__int64) tv.tv_sec) * 1000000) + ((__int64) tv.tv_usec) ); - +#endif #elif (defined __MSVC_INLINE__) __int64 mmRet; __asm { @@ -315,7 +320,11 @@ CTimer::CTimer(BOOL bInterrupt /*=TRUE*/) #if USE_GETTIMEOFDAY // just use gettimeofday. + #ifdef PANDORA + tm_llCPUSpeedHZ = tm_llPerformanceCounterFrequency = 1000000000LL; + #else tm_llCPUSpeedHZ = tm_llPerformanceCounterFrequency = 1000000; + #endif #elif PLATFORM_WIN32 { // this part of code must be executed as precisely as possible diff --git a/Sources/Engine/Graphics/Color.cpp b/Sources/Engine/Graphics/Color.cpp index 7085aa7..c117ea8 100644 --- a/Sources/Engine/Graphics/Color.cpp +++ b/Sources/Engine/Graphics/Color.cpp @@ -447,8 +447,29 @@ COLOR AddColors( COLOR col1, COLOR col2) COLOR colRet; #if (defined USE_PORTABLE_C) - STUBBED("AddColors"); - colRet = 0; + // !!! FIXME: This...is not fast. + union + { + COLOR col; + UBYTE bytes[4]; + } conv1; + + union + { + COLOR col; + UBYTE bytes[4]; + } conv2; + #define MIN(a, b) ((a)>(b))?(b):(a) + + conv1.col = col1; + conv2.col = col2; + conv1.bytes[0] = (UBYTE) MIN((((WORD) conv1.bytes[0]) + ((WORD) conv2.bytes[0])) , 255); + conv1.bytes[1] = (UBYTE) MIN((((WORD) conv1.bytes[1]) + ((WORD) conv2.bytes[1])) , 255); + conv1.bytes[2] = (UBYTE) MIN((((WORD) conv1.bytes[2]) + ((WORD) conv2.bytes[2])) , 255); + conv1.bytes[3] = (UBYTE) MIN((((WORD) conv1.bytes[3]) + ((WORD) conv2.bytes[3])) , 255); + #undef MIN + + colRet = conv1.col; #elif (defined __MSVC_INLINE__) __asm { @@ -605,7 +626,10 @@ extern void abgr2argb( ULONG *pulSrc, ULONG *pulDst, INDEX ct) { #if (defined USE_PORTABLE_C) //#error write me. - STUBBED("abgr2argb"); + for (int i=0; i>16) | ((tmp&0x000000ff)<<16); + } #elif (defined __MSVC_INLINE__) __asm { diff --git a/Sources/Engine/Graphics/DrawPort.cpp b/Sources/Engine/Graphics/DrawPort.cpp old mode 100644 new mode 100755 index 8af58ab..b53468d --- a/Sources/Engine/Graphics/DrawPort.cpp +++ b/Sources/Engine/Graphics/DrawPort.cpp @@ -1028,6 +1028,11 @@ BOOL CDrawPort::IsPointVisible( PIX pixI, PIX pixJ, FLOAT fOoK, INDEX iID, INDEX // if the point is out or at the edge of drawport, it is not visible by default if( pixI<1 || pixI>dp_Width-2 || pixJ<1 || pixJ>dp_Height-2) return FALSE; + #ifdef __arm__ + // Assuming here that all ARM machine use GLES based GPU, were DEPTH reading is probably not available (or super slow) + return FALSE; + #endif + // check API const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI; ASSERT( GfxValidApi(eAPI) ); diff --git a/Sources/Engine/Graphics/DrawPort_RenderScene.cpp b/Sources/Engine/Graphics/DrawPort_RenderScene.cpp index a972d43..70b0bc6 100644 --- a/Sources/Engine/Graphics/DrawPort_RenderScene.cpp +++ b/Sources/Engine/Graphics/DrawPort_RenderScene.cpp @@ -521,15 +521,15 @@ static void RSBinToGroups( ScenePolygon *pspoFirst) #else // emulate x86's bsr opcode...not fast. :/ - register INDEX val = _ctGroupsCount; - register INDEX bsr = 0; + register DWORD val = _ctGroupsCount; + register INDEX bsr = 31; if (val != 0) { - while (bsr < 32) + while (bsr > 0) { - if (val & (1 << bsr)) + if (val & (1l << bsr)) break; - bsr++; + bsr--; } } diff --git a/Sources/Engine/Graphics/Fog.cpp b/Sources/Engine/Graphics/Fog.cpp index 84b82d1..503f743 100644 --- a/Sources/Engine/Graphics/Fog.cpp +++ b/Sources/Engine/Graphics/Fog.cpp @@ -25,7 +25,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include - +#ifdef USE_PORTABLE_C +# include +#endif // asm shortcuts #define O offset @@ -69,7 +71,14 @@ ULONG PrepareTexture( UBYTE *pubTexture, PIX pixSizeI, PIX pixSizeJ) const PIX pixTextureSize = pixSizeI*pixSizeJ; #if (defined USE_PORTABLE_C) - STUBBED("PrepareTexture"); + UBYTE* src = pubTexture; + DWORD* dst = (DWORD*)(pubTexture+pixTextureSize); + for (int i=0; i> 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__) __asm { pxor mm0,mm0 diff --git a/Sources/Engine/Graphics/Graphics.cpp b/Sources/Engine/Graphics/Graphics.cpp index 7114770..feadd99 100644 --- a/Sources/Engine/Graphics/Graphics.cpp +++ b/Sources/Engine/Graphics/Graphics.cpp @@ -653,6 +653,15 @@ __int64 mmShifter = 0; __int64 mmMask = 0; ULONG *pulDitherTable; +#ifdef USE_PORTABLE_C +extern const UBYTE *pubClipByte; +// increment a byte without overflowing it +static inline void IncrementByteWithClip( UBYTE &ub, SLONG slAdd) +{ + ub = pubClipByte[(SLONG)ub+slAdd]; +} +#endif + // performs dithering of a 32-bit bipmap (can be in-place) void DitherBitmap( INDEX iDitherType, ULONG *pulSrc, ULONG *pulDst, PIX pixWidth, PIX pixHeight, PIX pixCanvasWidth, PIX pixCanvasHeight) @@ -774,7 +783,32 @@ void DitherBitmap( INDEX iDitherType, ULONG *pulSrc, ULONG *pulDst, PIX pixWidth ditherOrder: #if (defined USE_PORTABLE_C) - STUBBED("ordered matrix dithering routine"); + union uConv + { + ULONG val; + DWORD dwords[2]; + UWORD words[4]; + WORD iwords[4]; + UBYTE bytes[8]; + }; + for (int i=0; i>= mmShifter; } + dith.val &= mmMask; + uConv* src = (uConv*)(pulSrc+i*pixWidth); + uConv* dst = (uConv*)(pulDst+i*pixWidth); + for (int j=0; j>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__) __asm { @@ -1585,7 +1643,7 @@ void FilterBitmap( INDEX iFilter, ULONG *pulSrc, ULONG *pulDst, PIX pixWidth, PI ULONG *dst = pulDst; ULONG *rowptr = aulRows; - ExtPix rmm1, rmm2, rmm3, rmm4, rmm5, rmm6, rmm7; + 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); diff --git a/Sources/Engine/Light/LayerMixer.cpp b/Sources/Engine/Light/LayerMixer.cpp index 6f15789..d8d5ecf 100644 --- a/Sources/Engine/Light/LayerMixer.cpp +++ b/Sources/Engine/Light/LayerMixer.cpp @@ -451,8 +451,8 @@ skipPixel: // !!! FIXME WARNING: I have not checked this code, and it could be // !!! FIXME totally and utterly wrong. --ryan. - STUBBED("may not work"); - +// STUBBED("may not work"); + UBYTE* pubLayer = (UBYTE*)_pulLayer; for( PIX pixV=0; pixV<_iRowCt; pixV++) { SLONG slL2Point = _slL2Row; @@ -466,15 +466,15 @@ skipPixel: slL = aubSqrt[slL]; if( slL>_slHotSpot) slIntensity = ((255-slL)*_slLightStep)>>8; // add the intensity to the pixel - AddToCluster( (UBYTE*)_pulLayer, slIntensity/255.0f); + AddToCluster( pubLayer, slIntensity/255.0f); } // go to the next pixel - _pulLayer++; + pubLayer+=4; slL2Point += slDL2oDU; slDL2oDU += _slDDL2oDU; } // go to the next row - _pulLayer += _slModulo/BYTES_PER_TEXEL; + pubLayer += _slModulo; _slL2Row += _slDL2oDV; _slDL2oDV += _slDDL2oDV; _slDL2oDURow += _slDDL2oDUoDV; @@ -670,6 +670,7 @@ skipPixel: #else // Portable C version... + UBYTE* pubLayer = (UBYTE*)_pulLayer; for( PIX pixV=0; pixV<_iRowCt; pixV++) { SLONG slL2Point = _slL2Row; @@ -683,10 +684,10 @@ skipPixel: slL = aubSqrt[slL]; if( slL>_slHotSpot) slIntensity = ((255-slL)*_slLightStep)>>8; // add the intensity to the pixel - AddToCluster( (UBYTE*)_pulLayer, slIntensity/255.0f); + AddToCluster( pubLayer, slIntensity/255.0f); } // go to the next pixel - _pulLayer++; + pubLayer+=4; slL2Point += slDL2oDU; slDL2oDU += _slDDL2oDU; ubMask<<=1; @@ -696,7 +697,7 @@ skipPixel: } } // go to the next row - _pulLayer += _slModulo/BYTES_PER_TEXEL; + pubLayer += _slModulo; _slL2Row += _slDL2oDV; _slDL2oDV += _slDDL2oDV; _slDL2oDURow += _slDDL2oDUoDV; @@ -885,7 +886,34 @@ skipPixel: #endif #else - STUBBED("Some layer junk"); + // for each pixel in the shadow map + UBYTE* pubLayer = (UBYTE*)_pulLayer; + for( PIX pixV=0; pixV<_iRowCt; pixV++) + { + SLONG slL2Point = _slL2Row; + SLONG slDL2oDU = _slDL2oDURow; + for( PIX pixU=0; pixU<_iPixCt; pixU++) + { + // if the point is not masked + if(slL2Point>SHIFTX)&(SQRTTABLESIZE-1); // and is just for degenerate cases + sl1oL = auw1oSqrt[sl1oL]; + SLONG slIntensity = _slLightMax; + if( sl1oL>16; + // add the intensity to the pixel + AddToCluster( pubLayer, slIntensity/255.0f); + } + // advance to next pixel + pubLayer+=4; + slL2Point += slDL2oDU; + slDL2oDU += _slDDL2oDU; + } + // advance to next row + pubLayer += _slModulo; + _slL2Row += _slDL2oDV; + _slDL2oDV += _slDDL2oDV; + _slDL2oDURow += _slDDL2oDUoDV; + } #endif } @@ -1079,6 +1107,7 @@ skipPixel: #else // for each pixel in the shadow map + UBYTE* pubLayer = (UBYTE*)_pulLayer; for( PIX pixV=0; pixV<_iRowCt; pixV++) { SLONG slL2Point = _slL2Row; @@ -1092,10 +1121,10 @@ skipPixel: SLONG slIntensity = _slLightMax; if( sl1oL>16; // add the intensity to the pixel - AddToCluster( (UBYTE*)_pulLayer, slIntensity/255.0f); + AddToCluster( pubLayer, slIntensity/255.0f); } // advance to next pixel - _pulLayer++; + pubLayer+=4; slL2Point += slDL2oDU; slDL2oDU += _slDDL2oDU; ubMask<<=1; @@ -1105,7 +1134,7 @@ skipPixel: } } // advance to next row - _pulLayer += _slModulo/BYTES_PER_TEXEL; + pubLayer += _slModulo; _slL2Row += _slDL2oDV; _slDL2oDV += _slDDL2oDV; _slDL2oDURow += _slDDL2oDUoDV; @@ -1593,15 +1622,15 @@ rowNext: #endif #else - + UBYTE* pubLayer = (UBYTE*)_pulLayer; // for each pixel in the shadow map for( PIX pixV=0; pixV<_iRowCt; pixV++) { for( PIX pixU=0; pixU<_iPixCt; pixU++) { // add the intensity to the pixel - AddToCluster( (UBYTE*)_pulLayer); - _pulLayer++; // go to the next pixel + AddToCluster( pubLayer ); + pubLayer+=4; // go to the next pixel } // go to the next row - _pulLayer += _slModulo; + pubLayer += _slModulo; } #endif @@ -1691,23 +1720,23 @@ skipLight: #endif #else - + UBYTE* pubLayer = (UBYTE*)_pulLayer; // for each pixel in the shadow map for( PIX pixV=0; pixV<_iRowCt; pixV++) { for( PIX pixU=0; pixU<_iPixCt; pixU++) { // if the point is not masked if( *pubMask&ubMask) { // add the intensity to the pixel - AddToCluster( (UBYTE*)_pulLayer); + AddToCluster( pubLayer); } // go to the next pixel - _pulLayer++; + pubLayer+=4; ubMask<<=1; if( ubMask==0) { pubMask ++; ubMask = 1; } } // go to the next row - _pulLayer += _slModulo; + pubLayer += _slModulo; } #endif @@ -1935,8 +1964,7 @@ void CLayerMixer::MixOneMipmap(CBrushShadowMap *pbsm, INDEX iMipmap) __forceinline void CLayerMixer::CopyShadowLayer(void) { #if (defined USE_PORTABLE_C) - STUBBED("shadow layer stuff"); - + memcpy(lm_pulShadowMap, lm_pulStaticShadowMap, lm_pixCanvasSizeU*lm_pixCanvasSizeV*4); #elif (defined __MSVC_INLINE__) __asm { cld @@ -1969,8 +1997,10 @@ __forceinline void CLayerMixer::CopyShadowLayer(void) __forceinline void CLayerMixer::FillShadowLayer( COLOR col) { #if (defined USE_PORTABLE_C) - STUBBED("FillShadowLayer"); - + DWORD* dst = (DWORD*)lm_pulShadowMap; + int n = lm_pixCanvasSizeV*lm_pixCanvasSizeV; + DWORD color = __builtin_bswap32(col); + while(n--) {*(dst++)=color;} #elif (defined __MSVC_INLINE__) __asm { cld diff --git a/Sources/Engine/Math/Float.cpp b/Sources/Engine/Math/Float.cpp index 980eb8a..1466160 100644 --- a/Sources/Engine/Math/Float.cpp +++ b/Sources/Engine/Math/Float.cpp @@ -34,6 +34,14 @@ inline ULONG _control87(WORD newcw, WORD mask) fpw |= (newcw & mask); } return(fpw); +#elif defined(__arm__) + static WORD fpw=_PC_64; + if (mask != 0) + { + fpw &= ~mask; + fpw |= (newcw & mask); + } + return(fpw); #else WORD fpw = 0; diff --git a/Sources/Engine/Math/Functions.h b/Sources/Engine/Math/Functions.h index 93deaaa..3b388d0 100644 --- a/Sources/Engine/Math/Functions.h +++ b/Sources/Engine/Math/Functions.h @@ -312,7 +312,7 @@ inline FLOAT NormByteToFloat( const ULONG ul) // fast float to int conversion inline SLONG FloatToInt( FLOAT f) { -#if (defined USE_PORTABLE_C) +#if defined(__arm__) || defined(USE_PORTABLE_C) return((SLONG) (f + 0.5f)); /* best of luck to you. */ #elif (defined __MSVC_INLINE__) @@ -340,7 +340,7 @@ inline SLONG FloatToInt( FLOAT f) // log base 2 of any float numero inline FLOAT Log2( FLOAT f) { -#if (defined USE_PORTABLE_C) +#if (defined USE_PORTABLE_C) || defined(__arm__) // !!! FIXME: What's wrong with log2()? return (FLOAT)(log10(f)*3.321928094887); // log10(x)/log10(2) @@ -377,12 +377,12 @@ inline SLONG FastLog2( SLONG x) { #if (defined USE_PORTABLE_C) register SLONG val = x; - register SLONG retval = 0; - while (retval < 32) + register SLONG retval = 31; + while (retval > 0) { if (val & (1 << retval)) return retval; - retval++; + retval--; } return 0; @@ -497,31 +497,50 @@ ENGINE_API FLOAT Sin(ANGLE a); ENGINE_API FLOAT Cos(ANGLE a); ENGINE_API FLOAT Tan(ANGLE a); +#ifdef __arm__ +inline ENGINE_API FLOAT SinFast(ANGLE a) { return sinf(a*(PI/ANGLE_180)); }; +inline ENGINE_API FLOAT CosFast(ANGLE a) { return cosf(a*(PI/ANGLE_180)); }; +inline ENGINE_API FLOAT TanFast(ANGLE a) { return tanf(a*(PI/ANGLE_180)); }; +inline ANGLE ASin(FLOAT y) { + return AngleRad (asinf(Clamp(y, -1.0f, 1.0f))); +} +inline ANGLE ACos(FLOAT x) { + return AngleRad (acosf(Clamp(x, -1.0f, 1.0f))); + +} +inline ANGLE ATan(FLOAT z) { + return AngleRad (atanf(z)); +} +inline ANGLE ATan2(FLOAT y, FLOAT x) { + return AngleRad (atan2f(y, x)); +} +#else inline ENGINE_API FLOAT SinFast(ANGLE a) { return (FLOAT)sin(a*(PI/ANGLE_180)); }; inline ENGINE_API FLOAT CosFast(ANGLE a) { return (FLOAT)cos(a*(PI/ANGLE_180)); }; inline ENGINE_API FLOAT TanFast(ANGLE a) { return (FLOAT)tan(a*(PI/ANGLE_180)); }; - inline ANGLE ASin(FLOAT y) { return AngleRad (asin(Clamp(y, -1.0f, 1.0f))); } -inline ANGLE ASin(DOUBLE y) { - return AngleRad (asin(Clamp(y, -1.0, 1.0))); -} inline ANGLE ACos(FLOAT x) { return AngleRad (acos(Clamp(x, -1.0f, 1.0f))); } -inline ANGLE ACos(DOUBLE x) { - return AngleRad (acos(Clamp(x, -1.0, 1.0))); -} inline ANGLE ATan(FLOAT z) { return AngleRad (atan(z)); } -inline ANGLE ATan(DOUBLE z) { - return AngleRad (atan(z)); -} inline ANGLE ATan2(FLOAT y, FLOAT x) { return AngleRad (atan2(y, x)); } +#endif + +inline ANGLE ASin(DOUBLE y) { + return AngleRad (asin(Clamp(y, -1.0, 1.0))); +} +inline ANGLE ACos(DOUBLE x) { + return AngleRad (acos(Clamp(x, -1.0, 1.0))); +} +inline ANGLE ATan(DOUBLE z) { + return AngleRad (atan(z)); +} inline ANGLE ATan2(DOUBLE y, DOUBLE x) { return AngleRad (atan2(y, x)); } diff --git a/Sources/Engine/Sound/SoundDecoder.cpp b/Sources/Engine/Sound/SoundDecoder.cpp index 74ebf0d..ee61191 100644 --- a/Sources/Engine/Sound/SoundDecoder.cpp +++ b/Sources/Engine/Sound/SoundDecoder.cpp @@ -96,7 +96,11 @@ public: // ------------------------------------ Ogg Vorbis +#ifdef USE_TREMOR +#include // we define needed stuff ourselves, and ignore the rest +#else #include // we define needed stuff ourselves, and ignore the rest +#endif // vorbis vars BOOL _bOVEnabled = FALSE; @@ -208,7 +212,11 @@ void CSoundDecoder::InitPlugins(void) #if ((defined PLATFORM_WIN32) && (defined NDEBUG)) #define VORBISLIB "vorbisfile_d" #else - #define VORBISLIB "vorbisfile" + #ifdef USE_TREMOR + #define VORBISLIB "vorbisidec" + #else + #define VORBISLIB "vorbisfile" + #endif #endif _hOV = CDynamicLoader::GetInstance(VORBISLIB); if( _hOV->GetError() != NULL) { @@ -571,8 +579,12 @@ INDEX CSoundDecoder::Decode(void *pvDestBuffer, INDEX ctBytesToDecode) char *pch = (char *)pvDestBuffer; INDEX ctDecoded = 0; while (ctDecodedogg_vfVorbisFile, pch, ctBytesToDecode-ctDecoded, &iCurrrentSection); + #else long iRes = pov_read(sdc_pogg->ogg_vfVorbisFile, pch, ctBytesToDecode-ctDecoded, 0, 2, 1, &iCurrrentSection); + #endif if (iRes<=0) { return ctDecoded; } diff --git a/Sources/Engine/Sound/SoundMixer.cpp b/Sources/Engine/Sound/SoundMixer.cpp index 8aa8a82..1a81457 100644 --- a/Sources/Engine/Sound/SoundMixer.cpp +++ b/Sources/Engine/Sound/SoundMixer.cpp @@ -44,7 +44,11 @@ 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__ +#ifdef USE_PORTABLE_C +#define INASM +#else #define INASM extern +#endif #else #define INASM static static __int64 mmInvFactor = 0x00007FFF00007FFF; @@ -79,7 +83,7 @@ void ResetMixer( const SLONG *pslBuffer, const SLONG slBufferSize) // 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); + memset(pvMixerBuffer, 0, slMixerBufferSize * 8); #elif (defined __MSVC_INLINE__) __asm { @@ -154,12 +158,12 @@ void CopyMixerBuffer_mono( const SLONG slSrcOffset, void *pDstBuffer, const SLON #if (defined USE_PORTABLE_C) // (This is untested, currently. --ryan.) WORD *dest = (WORD *) pDstBuffer; - DWORD *src = (DWORD *) ( ((char *) pvMixerBuffer) + slSrcOffset ); + WORD *src = (WORD *) ( ((char *) pvMixerBuffer) + slSrcOffset ); SLONG max = slBytes / 4; for (SLONG i = 0; i < max; i++) { - *dest = *((WORD *) src); + *dest = *src; dest++; // move 16 bits. - src++; // move 32 bits. + src+=2; // move 32 bits. } #elif (defined __MSVC_INLINE__) @@ -207,7 +211,21 @@ static void ConvertMixerBuffer( const SLONG slBytes) if( slBytes<4) return; #if (defined USE_PORTABLE_C) - STUBBED("ConvertMixerBuffer"); + //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__) __asm { @@ -322,6 +340,9 @@ inline void MixMono( CSoundObject *pso) __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 @@ -355,10 +376,11 @@ inline void MixMono( CSoundObject *pso) slLastRightSample += ((slRightSample-slLastRightSample)*slRightFilter)>>15; // apply stereo volume to current sample - slLeftSample = (slLastLeftSample * slLeftVolume) >>15; - slRightSample = (slLastRightSample * slRightVolume)>>15; + slLeftSample = (slLastLeftSample * slLeftVolume_) >>15; + slRightSample = (slLastRightSample * slRightVolume_)>>15; - slRightSample = slRightSample ^ mmSurroundFactor; + slLeftSample ^= (SLONG)((mmSurroundFactor>> 0)&0xFFFFFFFF); + slRightSample ^= (SLONG)((mmSurroundFactor>>32)&0xFFFFFFFF); // mix in current sample slLeftSample += pslDstBuffer[0]; @@ -381,7 +403,7 @@ inline void MixMono( CSoundObject *pso) // advance to next sample fixLeftOfs += fixLeftStep; fixRightOfs += fixRightStep; - pslDstBuffer += 4; + pslDstBuffer += 2; iCt--; } @@ -536,7 +558,82 @@ inline void MixStereo( CSoundObject *pso) _pfSoundProfile.StartTimer(CSoundProfile::PTI_RAWMIXER); #if (defined USE_PORTABLE_C) - STUBBED("MixStereo"); + // 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--; + } #elif (defined __MSVC_INLINE__) __asm { diff --git a/Sources/Engine/Sound/ov_functions.h b/Sources/Engine/Sound/ov_functions.h index 0188a83..703cefb 100644 --- a/Sources/Engine/Sound/ov_functions.h +++ b/Sources/Engine/Sound/ov_functions.h @@ -19,6 +19,14 @@ with this program; if not, write to the Free Software Foundation, Inc., DLLFUNCTION( OVF, int, ov_clear, (OggVorbis_File *vf), 4, 0) DLLFUNCTION( OVF, int, ov_open, (FILE *f, OggVorbis_File *vf, char *initial, long ibytes), 16,0); DLLFUNCTION( OVF, int, ov_open_callbacks, (void *datasource, OggVorbis_File *vf, char *initial, long ibytes, ov_callbacks callbacks), 32,0); +#ifdef USE_TREMOR +DLLFUNCTION( OVF, long, ov_read, (OggVorbis_File *vf,char *buffer,int length, int *bitstream), 16,0); +#else DLLFUNCTION( OVF, long, ov_read, (OggVorbis_File *vf,char *buffer,int length, int bigendianp,int word,int sgned,int *bitstream), 28,0); +#endif DLLFUNCTION( OVF, vorbis_info *, ov_info, (OggVorbis_File *vf,int link), 8,0); -DLLFUNCTION( OVF, int, ov_time_seek, (OggVorbis_File *vf, double pos), 12,0); \ No newline at end of file +#ifdef USE_TREMOR +DLLFUNCTION( OVF, int, ov_time_seek, (OggVorbis_File *vf, int64_t pos), 12,0); +#else +DLLFUNCTION( OVF, int, ov_time_seek, (OggVorbis_File *vf, double pos), 12,0); +#endif \ No newline at end of file diff --git a/Sources/Engine/Terrain/TerrainMisc.cpp b/Sources/Engine/Terrain/TerrainMisc.cpp index 3f894fe..8a46245 100644 --- a/Sources/Engine/Terrain/TerrainMisc.cpp +++ b/Sources/Engine/Terrain/TerrainMisc.cpp @@ -308,16 +308,30 @@ Rect ExtractPolygonsInBox(CTerrain *ptrTerrain, const FLOATaabbox3D &bboxExtract Rect rc; if(!bFixSize) { // max vector of bbox in incremented for one, because first vertex is at 0,0,0 in world and in heightmap is at 1,1 +#ifdef __arm__ + rc.rc_iLeft = (isinf(bbox.minvect(1)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(1)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); + rc.rc_iTop = (isinf(bbox.minvect(3)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(3)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); + rc.rc_iRight = (isinf(bbox.maxvect(1)))?(INDEX)0:Clamp((INDEX)ceil(bbox.maxvect(1)+1),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); + rc.rc_iBottom = (isinf(bbox.maxvect(3)))?(INDEX)0:Clamp((INDEX)ceil(bbox.maxvect(3)+1),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); +#else rc.rc_iLeft = Clamp((INDEX)(bbox.minvect(1)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); rc.rc_iTop = Clamp((INDEX)(bbox.minvect(3)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); rc.rc_iRight = Clamp((INDEX)ceil(bbox.maxvect(1)+1),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); rc.rc_iBottom = Clamp((INDEX)ceil(bbox.maxvect(3)+1),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); +#endif } else { // max vector of bbox in incremented for one, because first vertex is at 0,0,0 in world and in heightmap is at 1,1 +#ifdef __arm__ + rc.rc_iLeft = (isinf(bbox.minvect(1)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(1)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); + rc.rc_iTop = (isinf(bbox.minvect(3)))?(INDEX)0:Clamp((INDEX)(bbox.minvect(3)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); + rc.rc_iRight = (isinf(bbox.maxvect(1)))?(INDEX)0:Clamp((INDEX)(bbox.maxvect(1)+0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); + rc.rc_iBottom = (isinf(bbox.maxvect(3)))?(INDEX)0:Clamp((INDEX)(bbox.maxvect(3)+0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); +#else rc.rc_iLeft = Clamp((INDEX)(bbox.minvect(1)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); rc.rc_iTop = Clamp((INDEX)(bbox.minvect(3)-0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); rc.rc_iRight = Clamp((INDEX)(bbox.maxvect(1)+0),(INDEX)0,ptrTerrain->tr_pixHeightMapWidth); rc.rc_iBottom = Clamp((INDEX)(bbox.maxvect(3)+0),(INDEX)0,ptrTerrain->tr_pixHeightMapHeight); +#endif } INDEX iStartX = rc.rc_iLeft; diff --git a/Sources/Engine/World/WorldCollisionGrid.cpp b/Sources/Engine/World/WorldCollisionGrid.cpp index 8677933..1b94f21 100644 --- a/Sources/Engine/World/WorldCollisionGrid.cpp +++ b/Sources/Engine/World/WorldCollisionGrid.cpp @@ -14,7 +14,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include - +#pragma GCC optimize 0 #include #include #include @@ -47,10 +47,10 @@ static inline void BoxToGrid( FLOAT fMinZ = boxEntity.Min()(3); FLOAT fMaxX = boxEntity.Max()(1); FLOAT fMaxZ = boxEntity.Max()(3); - iMinX = INDEX(floor(fMinX/GRID_CELLSIZE)); - iMinZ = INDEX(floor(fMinZ/GRID_CELLSIZE)); - iMaxX = INDEX(ceil(fMaxX/GRID_CELLSIZE)); - iMaxZ = INDEX(ceil(fMaxZ/GRID_CELLSIZE)); + iMinX = (isinf(fMinX))?INDEX(GRID_MIN):INDEX(floor(fMinX/GRID_CELLSIZE)); + iMinZ = (isinf(fMinZ))?INDEX(GRID_MIN):INDEX(floor(fMinZ/GRID_CELLSIZE)); + iMaxX = (isinf(fMaxX))?INDEX(GRID_MIN):INDEX(ceil(fMaxX/GRID_CELLSIZE)); + iMaxZ = (isinf(fMaxZ))?INDEX(GRID_MIN):INDEX(ceil(fMaxZ/GRID_CELLSIZE)); iMinX = Clamp(iMinX, (INDEX)GRID_MIN, (INDEX)GRID_MAX); iMinZ = Clamp(iMinZ, (INDEX)GRID_MIN, (INDEX)GRID_MAX); @@ -69,10 +69,10 @@ static inline INDEX MakeKey(INDEX iX, INDEX iZ) //INDEX iKey = (iX+iZ)&(GRID_HASHTABLESIZE-1); // x+z // use absolute x and z, swap upper and lower bits in z, xor x and z INDEX iZ2 = abs(iZ); - INDEX iKey = (iZ2>>(GRID_HASHTABLESIZE_LOG2/2)) | ( - (iZ2&(GRID_HASHTABLESIZE/2-1))<<(GRID_HASHTABLESIZE_LOG2/2)); - iKey = iKey^abs(iX); - iKey = iKey&(GRID_HASHTABLESIZE-1); + INDEX iKey = (iZ2>>(GRID_HASHTABLESIZE_LOG2/2)); + iKey |= ((iZ2&(GRID_HASHTABLESIZE/2-1))<<(GRID_HASHTABLESIZE_LOG2/2)); + iKey ^= abs(iX); + iKey &= (GRID_HASHTABLESIZE-1); return iKey; } diff --git a/Sources/GameMP/Game.cpp b/Sources/GameMP/Game.cpp index 5d7a5e7..52a328e 100644 --- a/Sources/GameMP/Game.cpp +++ b/Sources/GameMP/Game.cpp @@ -1023,7 +1023,7 @@ void CGame::InitInternal( void) extern CTString GetCurrentGameTypeName(void); extern ULONG GetSpawnFlagsForGameType(INDEX); extern ULONG GetSpawnFlagsForGameTypeCfunc(void* pArgs); - extern BOOL IsMenuEnabled(const CTString &); + extern BOOL IsMenuEnabled_(const CTString &); extern BOOL IsMenuEnabledCfunc(void* pArgs); _pShell->DeclareSymbol("user CTString GetGameAgentRulesInfo(void);", (void *)&GetGameAgentRulesInfo); _pShell->DeclareSymbol("user CTString GetGameTypeName(INDEX);", (void *)&GetGameTypeNameCfunc); @@ -1035,7 +1035,7 @@ void CGame::InitInternal( void) _pShell->DeclareSymbol("CTString GetGameTypeNameSS(INDEX);", (void *)&GetGameTypeName); _pShell->DeclareSymbol("INDEX GetSpawnFlagsForGameTypeSS(INDEX);", (void *)&GetSpawnFlagsForGameType); - _pShell->DeclareSymbol("INDEX IsMenuEnabledSS(CTString);", (void *)&IsMenuEnabled); + _pShell->DeclareSymbol("INDEX IsMenuEnabledSS(CTString);", (void *)&IsMenuEnabled_); _pShell->DeclareSymbol("user const INDEX ctl_iCurrentPlayerLocal;", (void *)&ctl_iCurrentPlayerLocal); _pShell->DeclareSymbol("user const INDEX ctl_iCurrentPlayer;", (void *)&ctl_iCurrentPlayer); diff --git a/Sources/GameMP/SessionProperties.cpp b/Sources/GameMP/SessionProperties.cpp index b6377ff..7a72abb 100644 --- a/Sources/GameMP/SessionProperties.cpp +++ b/Sources/GameMP/SessionProperties.cpp @@ -251,7 +251,7 @@ void CGame::SetMultiPlayerSession(CSessionProperties &sp) } } -BOOL IsMenuEnabled(const CTString &strMenuName) +BOOL IsMenuEnabled_(const CTString &strMenuName) { if (strMenuName=="Single Player") { return TRUE; @@ -272,7 +272,7 @@ BOOL IsMenuEnabled(const CTString &strMenuName) BOOL IsMenuEnabledCfunc(void* pArgs) { CTString strMenuName = *NEXTARGUMENT(CTString*); - return IsMenuEnabled(strMenuName); + return IsMenuEnabled_(strMenuName); } CTString GetGameTypeName(INDEX iMode)