1
0
forked from 0ad/0ad

CTerrain, Brushes: made CalcFromPosition static and added float x,y overload

minimap, PatchRData, renderer: fix ELOSState comparison vs & and use
SAFE_DELETE
ia32: add rounding control constants (for FISTP)
premake: set /QIfist compiler setting which causes float->int casts to
go through FISTP instruction instead of _ftol2() (much faster, but
requires CPU state to have been set)
LOSManager.cpp: cache m_TilesPerSize; use MIN/MAX; use
CTerrain::CalcFromPosition; clean up GetUnitState a bit. now runs at
203ns, down from 222

This was SVN commit r3099.
This commit is contained in:
janwas 2005-11-06 01:33:16 +00:00
parent 82bdda29ef
commit 6668ad6e1c
11 changed files with 66 additions and 67 deletions

View File

@ -225,6 +225,8 @@ function setuppackage_engine (projectname)
package.pchHeader = "precompiled.h"
package.pchSource = "precompiled.cpp"
tinsert(package.buildoptions, { "/QIfist" })
else -- Non-Windows, = Unix
tinsert(package.files, sourcesfromdirs(sourceroot, {"lib/sysdep/unix"}))

View File

@ -85,15 +85,6 @@ void CTerrain::CalcPosition(i32 i, i32 j, CVector3D& pos) const
}
///////////////////////////////////////////////////////////////////////////////
// CalcFromPosition: calculate the vertex underneath the world space position
void CTerrain::CalcFromPosition(const CVector3D& pos, i32& i, i32& j) const
{
i = pos.X / CELL_SIZE;
j = pos.Z / CELL_SIZE;
}
///////////////////////////////////////////////////////////////////////////////
// CalcNormal: calculate the world space normal of the vertex at (i,j)
void CTerrain::CalcNormal(u32 i, u32 j, CVector3D& normal) const

View File

@ -60,7 +60,15 @@ public:
// calculate the position of a given vertex
void CalcPosition(i32 i, i32 j, CVector3D& pos) const;
// calculate the vertex under a given position (rounding down coordinates)
void CalcFromPosition(const CVector3D& pos, i32& i, i32& j) const;
static void CalcFromPosition(const CVector3D& pos, i32& i, i32& j)
{
i = pos.X / CELL_SIZE; j = pos.Z / CELL_SIZE;
}
// calculate the vertex under a given position (rounding down coordinates)
static void CalcFromPosition(float x, float y, i32& i, i32& j)
{
i = x / CELL_SIZE; j = y / CELL_SIZE;
}
// calculate the normal at a given vertex
void CalcNormal(u32 i, u32 j, CVector3D& normal) const;

View File

@ -375,7 +375,7 @@ void CMiniMap::RebuildLOSTexture()
{
*dataPtr++ = 0xff;
}
else if(status == LOS_EXPLORED)
else if(status & LOS_EXPLORED)
{
*dataPtr++ = (u8) (0xff * 0.3f);
}
@ -400,17 +400,8 @@ void CMiniMap::Destroy()
if(m_LOSTexture)
glDeleteTextures(1, (GLuint *)&m_LOSTexture);
if(m_TerrainData)
{
delete[] m_TerrainData;
m_TerrainData = 0;
}
if(m_LOSData)
{
delete[] m_LOSData;
m_LOSData = 0;
}
SAFE_DELETE(m_TerrainData);
SAFE_DELETE(m_LOSData);
}
CVector2D CMiniMap::GetMapSpaceCoords(CVector3D worldPos)

View File

@ -165,6 +165,11 @@ void cpu_init()
// note: passing a flag *disables* that exception.
_control87(_EM_INVALID|_EM_DENORMAL|_EM_OVERFLOW|_EM_UNDERFLOW|_EM_INEXACT, _MCW_EM);
// round toward zero (truncate). this is what ANSI C calls for;
// if we set it to this (default is round to nearest), the compiler can
// generate FISTP (much faster) instead of _ftol2 with the same results.
_control87(_RC_CHOP, _MCW_RC);
// If possible, hook up capability-sensitive assembler routines
ia32_hook_capabilities();
#endif

View File

@ -46,13 +46,23 @@ extern u64 rdtsc(void);
// these may have been defined by system headers; we redefine them to
// the real IA-32 values for use with ia32_control87.
// Precision Control:
// .. Precision Control:
#undef _MCW_PC
#define _MCW_PC 0x0300
#undef _PC_24
#define _PC_24 0x0000
// Exception Mask:
// .. Rounding Control:
#undef _MCW_RC
#define _MCW_RC 0x0C00
#undef _RC_NEAR
#define _RC_NEAR 0x0000
#undef _RC_DOWN
#define _RC_DOWN 0x0400
#undef _RC_UP
#define _RC_UP 0x0800
#undef _RC_CHOP
#define _RC_CHOP 0x0C00
// .. Exception Mask:
#undef _MCW_EM
#define _MCW_EM 0x003f
#undef _EM_INVALID

View File

@ -461,7 +461,7 @@ void CPatchRData::Update()
if(tx >= 0 && tz >= 0 && tx <= mapSize-2 && tz <= mapSize-2)
{
ELOSStatus s = losMgr->GetStatus(tx, tz, g_Game->GetLocalPlayer());
if(s==LOS_EXPLORED && losMod > 0.7f)
if(s&LOS_EXPLORED && losMod > 0.7f)
losMod = 0.7f;
else if(s==LOS_UNEXPLORED && losMod > 0.0f)
losMod = 0.0f;

View File

@ -1035,7 +1035,7 @@ void CRenderer::RenderWater()
if(tx >= 0 && tz >= 0 && tx <= mapSize-2 && tz <= mapSize-2)
{
ELOSStatus s = losMgr->GetStatus(tx, tz, g_Game->GetLocalPlayer());
if(s==LOS_EXPLORED && losMod > 0.7f)
if(s&LOS_EXPLORED && losMod > 0.7f)
losMod = 0.7f;
else if(s==LOS_UNEXPLORED && losMod > 0.0f)
losMod = 0.0f;

View File

@ -45,14 +45,16 @@ void CLOSManager::Initialize(uint losSetting)
m_LOSSetting = losSetting;
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
int tilesPerSide = terrain->GetVerticesPerSide() - 1;
m_TilesPerSide = terrain->GetVerticesPerSide() - 1;
m_TilesPerSide_1 = m_TilesPerSide-1;
// Create the LOS data arrays
#ifdef _2_los
m_Explored = (int**)matrix_alloc(tilesPerSide, tilesPerSide, sizeof(int));
m_Visible = (int**)matrix_alloc(tilesPerSide, tilesPerSide, sizeof(int));
m_Explored = (int**)matrix_alloc(m_TilesPerSide, m_TilesPerSide, sizeof(int));
m_Visible = (int**)matrix_alloc(m_TilesPerSide, m_TilesPerSide, sizeof(int));
#else
m_VisibilityMatrix = (u16**)matrix_alloc(tilesPerSide, tilesPerSide, sizeof(u16));
m_VisibilityMatrix = (u16**)matrix_alloc(m_TilesPerSide, m_TilesPerSide, sizeof(u16));
#endif
// TODO: This memory should be freed somewhere when the engine supports
@ -70,14 +72,14 @@ void CLOSManager::Initialize(uint losSetting)
if(m_LOSSetting == ALL_VISIBLE)
for(int i = 0; i < 8; i++) vis_value |= LOS_VISIBLE << (i*2);
#endif
for(int x=0; x<tilesPerSide; x++)
for(uint x=0; x<m_TilesPerSide; x++)
{
#ifdef _2_los
memset(m_Explored[x], explored_value, tilesPerSide*sizeof(int));
memset(m_Visible [x], vis_value , tilesPerSide*sizeof(int));
memset(m_Explored[x], explored_value, m_TilesPerSide*sizeof(int));
memset(m_Visible [x], vis_value , m_TilesPerSide*sizeof(int));
#else
for(int y=0; y<tilesPerSide; y++)
for(int x=0; x<tilesPerSide; x++)
for(uint y=0; y<m_TilesPerSide; y++)
for(uint x=0; x<m_TilesPerSide; x++)
m_VisibilityMatrix[y][x] = vis_value;
#endif
}
@ -93,21 +95,18 @@ void CLOSManager::Update()
if(m_LOSSetting == ALL_VISIBLE)
return;
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
int tilesPerSide = terrain->GetVerticesPerSide() - 1;
// Clear the visible array
#ifdef _2_los
for(int x=0; x<tilesPerSide; x++)
for(int x=0; x<m_TilesPerSide; x++)
{
memset(m_Visible[x], 0, tilesPerSide*sizeof(int));
memset(m_Visible[x], 0, m_TilesPerSide*sizeof(int));
}
#else
u16 not_all_vis = 0xFFFF;
for(int i = 0; i < 8; i++)
not_all_vis &= ~(LOS_VISIBLE << (i*2));
for(int y=0; y<tilesPerSide; y++)
for(int x=0; x<tilesPerSide; x++)
for(uint y=0; y<m_TilesPerSide; y++)
for(uint x=0; x<m_TilesPerSide; x++)
m_VisibilityMatrix[y][x] &= not_all_vis;
#endif
@ -130,13 +129,13 @@ void CLOSManager::Update()
uint shift = e->GetPlayer()->GetPlayerID()*2;
#endif
int cx = min(int(e->m_position.X/CELL_SIZE), tilesPerSide-1);
int cz = min(int(e->m_position.Z/CELL_SIZE), tilesPerSide-1);
int cx, cz;
CTerrain::CalcFromPosition(e->m_position.X, e->m_position.Z, cx, cz);
int minX = max(cx-los, 0);
int minZ = max(cz-los, 0);
int maxX = min(cx+los, tilesPerSide-1);
int maxZ = min(cz+los, tilesPerSide-1);
int minX = MAX(cx-los, 0);
int minZ = MAX(cz-los, 0);
int maxX = MIN(cx+los, (int)m_TilesPerSide_1);
int maxZ = MIN(cz+los, (int)m_TilesPerSide_1);
for(int x=minX; x<=maxX; x++)
{
@ -198,11 +197,8 @@ TIMER_ACCRUE(tc_getstatus);
ELOSStatus CLOSManager::GetStatus(float fx, float fz, CPlayer* player)
{
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
int tilesPerSide = terrain->GetVerticesPerSide() - 1;
int ix = min(int(fx/CELL_SIZE), tilesPerSide-1);
int iz = min(int(fz/CELL_SIZE), tilesPerSide-1);
int ix, iz;
CTerrain::CalcFromPosition(fx, fz, ix, iz);
return GetStatus(ix, iz, player);
}
@ -211,11 +207,11 @@ EUnitLOSStatus CLOSManager::GetUnitStatus(CUnit* unit, CPlayer* player)
CVector3D centre;
unit->GetModel()->GetBounds().GetCentre(centre);
ELOSStatus status = GetStatus(centre.X, centre.Z, player);
if(status & LOS_VISIBLE)
{
return UNIT_VISIBLE;
}
else if(status == LOS_EXPLORED)
if(status & LOS_EXPLORED)
{
if(unit->GetEntity() == 0 || unit->GetEntity()->m_permanent)
{
@ -227,15 +223,9 @@ EUnitLOSStatus CLOSManager::GetUnitStatus(CUnit* unit, CPlayer* player)
// system so that we can't remember units that we haven't seen and so we can
// see permanent units that have died but that we haven't been near lately
}
else
{
return UNIT_HIDDEN;
}
}
else
{
return UNIT_HIDDEN;
}
return UNIT_HIDDEN;
}

View File

@ -54,6 +54,9 @@ class CLOSManager : public Singleton<CLOSManager>
u16** m_VisibilityMatrix;
#endif
uint m_TilesPerSide;
uint m_TilesPerSide_1; // as above, -1
public:
static const int NORMAL = 0;
static const int EXPLORED = 1;

View File

@ -33,9 +33,8 @@ void Brush::GetBottomRight(int& x, int& y) const
CVector3D c = m_Centre;
if (m_W % 2) c.X += CELL_SIZE/2.f;
if (m_H % 2) c.Z += CELL_SIZE/2.f;
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
i32 cx, cy;
terrain->CalcFromPosition(c, cx, cy);
CTerrain::CalcFromPosition(c, cx, cy);
x = cx - (m_W-1)/2;
y = cy - (m_H-1)/2;