Merge pull request #11 from ptitSeb/master

Portable C is useable now, plus a (beggining of) OpenPandora (arm processor) port
This commit is contained in:
Ryan C. Gordon 2016-04-06 13:03:10 -04:00
commit 22fb22ab27
21 changed files with 430 additions and 98 deletions

View File

@ -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")

View File

@ -28,9 +28,15 @@ template class CStaticArray<CProfileTimer>;
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;

View File

@ -1,6 +1,6 @@
%{
#include "ParsingSymbols.h"
#include "Parser.h"
#include "parser.h"
#include <Engine/Base/FileName.h>
#include <Engine/Base/CTString.h>

View File

@ -24,7 +24,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <Engine/Templates/DynamicArray.h>
#include <Engine/Base/Shell_internal.h>
#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 {

View File

@ -28,9 +28,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <Engine/Base/ListIterator.inl>
#include <Engine/Base/Priority.inl>
//#if ( (USE_PORTABLE_C) || (PLATFORM_UNIX) )
//#define USE_GETTIMEOFDAY 1
//#endif
#if (USE_PORTABLE_C)
#define USE_GETTIMEOFDAY 1
#endif
#if USE_GETTIMEOFDAY
#include <sys/time.h>
@ -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

View File

@ -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<ct; i++) {
ULONG tmp = pulSrc[i];
pulDst[i] = (tmp&0xff00ff00) | ((tmp&0x00ff0000)>>16) | ((tmp&0x000000ff)<<16);
}
#elif (defined __MSVC_INLINE__)
__asm {

5
Sources/Engine/Graphics/DrawPort.cpp Normal file → Executable file
View File

@ -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) );

View File

@ -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--;
}
}

View File

@ -25,7 +25,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <Engine/Graphics/Fog_internal.h>
#include <Engine/Graphics/GfxProfile.h>
#include <Engine/Graphics/ImageInfo.h>
#ifdef USE_PORTABLE_C
# include <byteswap.h>
#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<pixTextureSize; i++) {
DWORD tmp = *src | 0xFFFFFF00;
*dst = bswap_32(tmp);
src++;
dst++;
}
#elif (defined __MSVC_INLINE__)
__asm {

View File

@ -168,18 +168,29 @@ void UploadTexture_OGL( ULONG *pulTexture, PIX pixSizeU, PIX pixSizeV,
#if (defined USE_PORTABLE_C)
// Basically average every other pixel...
pixSize *= 4;
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__)
__asm {
pxor mm0,mm0

View File

@ -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<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__)
__asm {
@ -894,7 +928,31 @@ ditherError:
// slModulo+=4;
// now, dither destination
#if (defined USE_PORTABLE_C)
STUBBED("error diffusion dithering routine");
#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__)
__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);

View File

@ -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<FTOX) {
SLONG sl1oL = (slL2Point>>SHIFTX)&(SQRTTABLESIZE-1); // and is just for degenerate cases
sl1oL = auw1oSqrt[sl1oL];
SLONG slIntensity = _slLightMax;
if( sl1oL<slMax1oL) slIntensity = ((sl1oL-256)*_slLightStep)>>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<slMax1oL) slIntensity = ((sl1oL-256)*_slLightStep)>>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

View File

@ -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;

View File

@ -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));
}

View File

@ -96,7 +96,11 @@ public:
// ------------------------------------ Ogg Vorbis
#ifdef USE_TREMOR
#include <tremor/ivorbisfile.h> // we define needed stuff ourselves, and ignore the rest
#else
#include <vorbis/vorbisfile.h> // 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 (ctDecoded<ctBytesToDecode) {
#ifdef USE_TREMOR
long iRes = pov_read(sdc_pogg->ogg_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;
}

View File

@ -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 {

View File

@ -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);
#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

View File

@ -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;

View File

@ -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 <Engine/StdH.h>
#pragma GCC optimize 0
#include <Engine/World/World.h>
#include <Engine/World/PhysicsProfile.h>
#include <Engine/Templates/StaticStackArray.cpp>
@ -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;
}

View File

@ -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);

View File

@ -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)