Fix PVS calculations on 64bit systems

Monsters got stuck in same places of d3xp because PVS calculations
returned that they were not in the players PVS.
This only happened on LP64 systems like Unix/Linux amd64 where
sizeof(long) == 8 - it did not happen on Win64 because it's LLP64, i.e.
sizeof(long) == 4 (like on x86 32bit).

Bit fiddling code in Pvs.cpp seemed to assume that sizeof(long) == 4
like on win32.

Fixes #7.
This commit is contained in:
Daniel Gibson 2012-06-22 15:33:21 +02:00
parent ca4b20eb08
commit 5c08cb0140
4 changed files with 40 additions and 40 deletions

View file

@ -330,7 +330,7 @@ pvsStack_t *idPVS::FloodPassagePVS_r( pvsPortal_t *source, const pvsPortal_t *po
pvsArea_t *area; pvsArea_t *area;
pvsStack_t *stack; pvsStack_t *stack;
pvsPassage_t *passage; pvsPassage_t *passage;
long *sourceVis, *passageVis, *portalVis, *mightSee, *prevMightSee, more; int *sourceVis, *passageVis, *portalVis, *mightSee, *prevMightSee, more;
area = &pvsAreas[portal->areaNum]; area = &pvsAreas[portal->areaNum];
@ -365,15 +365,15 @@ pvsStack_t *idPVS::FloodPassagePVS_r( pvsPortal_t *source, const pvsPortal_t *po
source->vis[n >> 3] |= (1 << (n & 7)); source->vis[n >> 3] |= (1 << (n & 7));
// get pointers to vis data // get pointers to vis data
prevMightSee = reinterpret_cast<long *>(prevStack->mightSee); prevMightSee = reinterpret_cast<int *>(prevStack->mightSee);
passageVis = reinterpret_cast<long *>(passage->canSee); passageVis = reinterpret_cast<int *>(passage->canSee);
sourceVis = reinterpret_cast<long *>(source->vis); sourceVis = reinterpret_cast<int *>(source->vis);
mightSee = reinterpret_cast<long *>(stack->mightSee); mightSee = reinterpret_cast<int *>(stack->mightSee);
more = 0; more = 0;
// use the portal PVS if it has been calculated // use the portal PVS if it has been calculated
if ( p->done ) { if ( p->done ) {
portalVis = reinterpret_cast<long *>(p->vis); portalVis = reinterpret_cast<int *>(p->vis);
for ( j = 0; j < portalVisLongs; j++ ) { for ( j = 0; j < portalVisLongs; j++ ) {
// get new PVS which is decreased by going through this passage // get new PVS which is decreased by going through this passage
m = *prevMightSee++ & *passageVis++ & *portalVis++; m = *prevMightSee++ & *passageVis++ & *portalVis++;
@ -731,7 +731,7 @@ idPVS::AreaPVSFromPortalPVS
*/ */
int idPVS::AreaPVSFromPortalPVS( void ) const { int idPVS::AreaPVSFromPortalPVS( void ) const {
int i, j, k, areaNum, totalVisibleAreas; int i, j, k, areaNum, totalVisibleAreas;
long *p1, *p2; int *p1, *p2;
byte *pvs, *portalPVS; byte *pvs, *portalPVS;
pvsArea_t *area; pvsArea_t *area;
@ -756,8 +756,8 @@ int idPVS::AreaPVSFromPortalPVS( void ) const {
// store the PVS of all portals in this area at the first portal // store the PVS of all portals in this area at the first portal
for ( j = 1; j < area->numPortals; j++ ) { for ( j = 1; j < area->numPortals; j++ ) {
p1 = reinterpret_cast<long *>(area->portals[0]->vis); p1 = reinterpret_cast<int *>(area->portals[0]->vis);
p2 = reinterpret_cast<long *>(area->portals[j]->vis); p2 = reinterpret_cast<int *>(area->portals[j]->vis);
for ( k = 0; k < portalVisLongs; k++ ) { for ( k = 0; k < portalVisLongs; k++ ) {
*p1++ |= *p2++; *p1++ |= *p2++;
} }
@ -808,7 +808,7 @@ void idPVS::Init( void ) {
areaQueue = new int[numAreas]; areaQueue = new int[numAreas];
areaVisBytes = ( ((numAreas+31)&~31) >> 3); areaVisBytes = ( ((numAreas+31)&~31) >> 3);
areaVisLongs = areaVisBytes/sizeof(long); areaVisLongs = areaVisBytes/sizeof(int);
areaPVS = new byte[numAreas * areaVisBytes]; areaPVS = new byte[numAreas * areaVisBytes];
memset( areaPVS, 0xFF, numAreas * areaVisBytes ); memset( areaPVS, 0xFF, numAreas * areaVisBytes );
@ -816,7 +816,7 @@ void idPVS::Init( void ) {
numPortals = GetPortalCount(); numPortals = GetPortalCount();
portalVisBytes = ( ((numPortals+31)&~31) >> 3); portalVisBytes = ( ((numPortals+31)&~31) >> 3);
portalVisLongs = portalVisBytes/sizeof(long); portalVisLongs = portalVisBytes/sizeof(int);
for ( int i = 0; i < MAX_CURRENT_PVS; i++ ) { for ( int i = 0; i < MAX_CURRENT_PVS; i++ ) {
currentPVS[i].handle.i = -1; currentPVS[i].handle.i = -1;
@ -1014,7 +1014,7 @@ idPVS::SetupCurrentPVS
pvsHandle_t idPVS::SetupCurrentPVS( const int *sourceAreas, const int numSourceAreas, const pvsType_t type ) const { pvsHandle_t idPVS::SetupCurrentPVS( const int *sourceAreas, const int numSourceAreas, const pvsType_t type ) const {
int i, j; int i, j;
unsigned int h; unsigned int h;
long *vis, *pvs; int *vis, *pvs;
pvsHandle_t handle; pvsHandle_t handle;
h = 0; h = 0;
@ -1035,8 +1035,8 @@ pvsHandle_t idPVS::SetupCurrentPVS( const int *sourceAreas, const int numSourceA
assert( sourceAreas[i] >= 0 && sourceAreas[i] < numAreas ); assert( sourceAreas[i] >= 0 && sourceAreas[i] < numAreas );
vis = reinterpret_cast<long*>(areaPVS + sourceAreas[i] * areaVisBytes); vis = reinterpret_cast<int *>(areaPVS + sourceAreas[i] * areaVisBytes);
pvs = reinterpret_cast<long*>(currentPVS[handle.i].pvs); pvs = reinterpret_cast<int *>(currentPVS[handle.i].pvs);
for ( j = 0; j < areaVisLongs; j++ ) { for ( j = 0; j < areaVisLongs; j++ ) {
*pvs++ |= *vis++; *pvs++ |= *vis++;
} }
@ -1075,7 +1075,7 @@ idPVS::MergeCurrentPVS
*/ */
pvsHandle_t idPVS::MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const { pvsHandle_t idPVS::MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const {
int i; int i;
long *pvs1Ptr, *pvs2Ptr, *ptr; int *pvs1Ptr, *pvs2Ptr, *ptr;
pvsHandle_t handle; pvsHandle_t handle;
if ( pvs1.i < 0 || pvs1.i >= MAX_CURRENT_PVS || pvs1.h != currentPVS[pvs1.i].handle.h || if ( pvs1.i < 0 || pvs1.i >= MAX_CURRENT_PVS || pvs1.h != currentPVS[pvs1.i].handle.h ||
@ -1085,9 +1085,9 @@ pvsHandle_t idPVS::MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const {
handle = AllocCurrentPVS( pvs1.h ^ pvs2.h ); handle = AllocCurrentPVS( pvs1.h ^ pvs2.h );
ptr = reinterpret_cast<long*>(currentPVS[handle.i].pvs); ptr = reinterpret_cast<int *>(currentPVS[handle.i].pvs);
pvs1Ptr = reinterpret_cast<long*>(currentPVS[pvs1.i].pvs); pvs1Ptr = reinterpret_cast<int *>(currentPVS[pvs1.i].pvs);
pvs2Ptr = reinterpret_cast<long*>(currentPVS[pvs2.i].pvs); pvs2Ptr = reinterpret_cast<int *>(currentPVS[pvs2.i].pvs);
for ( i = 0; i < areaVisLongs; i++ ) { for ( i = 0; i < areaVisLongs; i++ ) {
*ptr++ = *pvs1Ptr++ | *pvs2Ptr++; *ptr++ = *pvs1Ptr++ | *pvs2Ptr++;

View file

@ -111,9 +111,9 @@ private:
mutable pvsCurrent_t currentPVS[MAX_CURRENT_PVS]; mutable pvsCurrent_t currentPVS[MAX_CURRENT_PVS];
// used to create PVS // used to create PVS
int portalVisBytes; int portalVisBytes;
int portalVisLongs; int portalVisLongs; // Note: these are really ints now..
int areaVisBytes; int areaVisBytes;
int areaVisLongs; int areaVisLongs; // Note: these are really ints now..
struct pvsPortal_s *pvsPortals; struct pvsPortal_s *pvsPortals;
struct pvsArea_s * pvsAreas; struct pvsArea_s * pvsAreas;

View file

@ -330,7 +330,7 @@ pvsStack_t *idPVS::FloodPassagePVS_r( pvsPortal_t *source, const pvsPortal_t *po
pvsArea_t *area; pvsArea_t *area;
pvsStack_t *stack; pvsStack_t *stack;
pvsPassage_t *passage; pvsPassage_t *passage;
long *sourceVis, *passageVis, *portalVis, *mightSee, *prevMightSee, more; int *sourceVis, *passageVis, *portalVis, *mightSee, *prevMightSee, more;
area = &pvsAreas[portal->areaNum]; area = &pvsAreas[portal->areaNum];
@ -365,15 +365,15 @@ pvsStack_t *idPVS::FloodPassagePVS_r( pvsPortal_t *source, const pvsPortal_t *po
source->vis[n >> 3] |= (1 << (n & 7)); source->vis[n >> 3] |= (1 << (n & 7));
// get pointers to vis data // get pointers to vis data
prevMightSee = reinterpret_cast<long *>(prevStack->mightSee); prevMightSee = reinterpret_cast<int *>(prevStack->mightSee);
passageVis = reinterpret_cast<long *>(passage->canSee); passageVis = reinterpret_cast<int *>(passage->canSee);
sourceVis = reinterpret_cast<long *>(source->vis); sourceVis = reinterpret_cast<int *>(source->vis);
mightSee = reinterpret_cast<long *>(stack->mightSee); mightSee = reinterpret_cast<int *>(stack->mightSee);
more = 0; more = 0;
// use the portal PVS if it has been calculated // use the portal PVS if it has been calculated
if ( p->done ) { if ( p->done ) {
portalVis = reinterpret_cast<long *>(p->vis); portalVis = reinterpret_cast<int *>(p->vis);
for ( j = 0; j < portalVisLongs; j++ ) { for ( j = 0; j < portalVisLongs; j++ ) {
// get new PVS which is decreased by going through this passage // get new PVS which is decreased by going through this passage
m = *prevMightSee++ & *passageVis++ & *portalVis++; m = *prevMightSee++ & *passageVis++ & *portalVis++;
@ -731,7 +731,7 @@ idPVS::AreaPVSFromPortalPVS
*/ */
int idPVS::AreaPVSFromPortalPVS( void ) const { int idPVS::AreaPVSFromPortalPVS( void ) const {
int i, j, k, areaNum, totalVisibleAreas; int i, j, k, areaNum, totalVisibleAreas;
long *p1, *p2; int *p1, *p2;
byte *pvs, *portalPVS; byte *pvs, *portalPVS;
pvsArea_t *area; pvsArea_t *area;
@ -756,8 +756,8 @@ int idPVS::AreaPVSFromPortalPVS( void ) const {
// store the PVS of all portals in this area at the first portal // store the PVS of all portals in this area at the first portal
for ( j = 1; j < area->numPortals; j++ ) { for ( j = 1; j < area->numPortals; j++ ) {
p1 = reinterpret_cast<long *>(area->portals[0]->vis); p1 = reinterpret_cast<int *>(area->portals[0]->vis);
p2 = reinterpret_cast<long *>(area->portals[j]->vis); p2 = reinterpret_cast<int *>(area->portals[j]->vis);
for ( k = 0; k < portalVisLongs; k++ ) { for ( k = 0; k < portalVisLongs; k++ ) {
*p1++ |= *p2++; *p1++ |= *p2++;
} }
@ -808,7 +808,7 @@ void idPVS::Init( void ) {
areaQueue = new int[numAreas]; areaQueue = new int[numAreas];
areaVisBytes = ( ((numAreas+31)&~31) >> 3); areaVisBytes = ( ((numAreas+31)&~31) >> 3);
areaVisLongs = areaVisBytes/sizeof(long); areaVisLongs = areaVisBytes/sizeof(int);
areaPVS = new byte[numAreas * areaVisBytes]; areaPVS = new byte[numAreas * areaVisBytes];
memset( areaPVS, 0xFF, numAreas * areaVisBytes ); memset( areaPVS, 0xFF, numAreas * areaVisBytes );
@ -816,7 +816,7 @@ void idPVS::Init( void ) {
numPortals = GetPortalCount(); numPortals = GetPortalCount();
portalVisBytes = ( ((numPortals+31)&~31) >> 3); portalVisBytes = ( ((numPortals+31)&~31) >> 3);
portalVisLongs = portalVisBytes/sizeof(long); portalVisLongs = portalVisBytes/sizeof(int);
for ( int i = 0; i < MAX_CURRENT_PVS; i++ ) { for ( int i = 0; i < MAX_CURRENT_PVS; i++ ) {
currentPVS[i].handle.i = -1; currentPVS[i].handle.i = -1;
@ -1014,7 +1014,7 @@ idPVS::SetupCurrentPVS
pvsHandle_t idPVS::SetupCurrentPVS( const int *sourceAreas, const int numSourceAreas, const pvsType_t type ) const { pvsHandle_t idPVS::SetupCurrentPVS( const int *sourceAreas, const int numSourceAreas, const pvsType_t type ) const {
int i, j; int i, j;
unsigned int h; unsigned int h;
long *vis, *pvs; int *vis, *pvs;
pvsHandle_t handle; pvsHandle_t handle;
h = 0; h = 0;
@ -1035,8 +1035,8 @@ pvsHandle_t idPVS::SetupCurrentPVS( const int *sourceAreas, const int numSourceA
assert( sourceAreas[i] >= 0 && sourceAreas[i] < numAreas ); assert( sourceAreas[i] >= 0 && sourceAreas[i] < numAreas );
vis = reinterpret_cast<long*>(areaPVS + sourceAreas[i] * areaVisBytes); vis = reinterpret_cast<int *>(areaPVS + sourceAreas[i] * areaVisBytes);
pvs = reinterpret_cast<long*>(currentPVS[handle.i].pvs); pvs = reinterpret_cast<int *>(currentPVS[handle.i].pvs);
for ( j = 0; j < areaVisLongs; j++ ) { for ( j = 0; j < areaVisLongs; j++ ) {
*pvs++ |= *vis++; *pvs++ |= *vis++;
} }
@ -1075,7 +1075,7 @@ idPVS::MergeCurrentPVS
*/ */
pvsHandle_t idPVS::MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const { pvsHandle_t idPVS::MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const {
int i; int i;
long *pvs1Ptr, *pvs2Ptr, *ptr; int *pvs1Ptr, *pvs2Ptr, *ptr;
pvsHandle_t handle; pvsHandle_t handle;
if ( pvs1.i < 0 || pvs1.i >= MAX_CURRENT_PVS || pvs1.h != currentPVS[pvs1.i].handle.h || if ( pvs1.i < 0 || pvs1.i >= MAX_CURRENT_PVS || pvs1.h != currentPVS[pvs1.i].handle.h ||
@ -1085,9 +1085,9 @@ pvsHandle_t idPVS::MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const {
handle = AllocCurrentPVS( pvs1.h ^ pvs2.h ); handle = AllocCurrentPVS( pvs1.h ^ pvs2.h );
ptr = reinterpret_cast<long*>(currentPVS[handle.i].pvs); ptr = reinterpret_cast<int *>(currentPVS[handle.i].pvs);
pvs1Ptr = reinterpret_cast<long*>(currentPVS[pvs1.i].pvs); pvs1Ptr = reinterpret_cast<int *>(currentPVS[pvs1.i].pvs);
pvs2Ptr = reinterpret_cast<long*>(currentPVS[pvs2.i].pvs); pvs2Ptr = reinterpret_cast<int *>(currentPVS[pvs2.i].pvs);
for ( i = 0; i < areaVisLongs; i++ ) { for ( i = 0; i < areaVisLongs; i++ ) {
*ptr++ = *pvs1Ptr++ | *pvs2Ptr++; *ptr++ = *pvs1Ptr++ | *pvs2Ptr++;

View file

@ -107,9 +107,9 @@ private:
mutable pvsCurrent_t currentPVS[MAX_CURRENT_PVS]; mutable pvsCurrent_t currentPVS[MAX_CURRENT_PVS];
// used to create PVS // used to create PVS
int portalVisBytes; int portalVisBytes;
int portalVisLongs; int portalVisLongs; // Note: these are really ints now..
int areaVisBytes; int areaVisBytes;
int areaVisLongs; int areaVisLongs; // Note: these are really ints now..
struct pvsPortal_s *pvsPortals; struct pvsPortal_s *pvsPortals;
struct pvsArea_s * pvsAreas; struct pvsArea_s * pvsAreas;