From 4244436d7d7b0f5d937edf36636448271c7954fc Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Fri, 22 Jun 2012 15:33:21 +0200 Subject: [PATCH] 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. --- neo/d3xp/Pvs.cpp | 36 ++++++++++++++++++------------------ neo/d3xp/Pvs.h | 4 ++-- neo/game/Pvs.cpp | 36 ++++++++++++++++++------------------ neo/game/Pvs.h | 4 ++-- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/neo/d3xp/Pvs.cpp b/neo/d3xp/Pvs.cpp index 61e1fa14..8ff144fb 100644 --- a/neo/d3xp/Pvs.cpp +++ b/neo/d3xp/Pvs.cpp @@ -330,7 +330,7 @@ pvsStack_t *idPVS::FloodPassagePVS_r( pvsPortal_t *source, const pvsPortal_t *po pvsArea_t *area; pvsStack_t *stack; pvsPassage_t *passage; - long *sourceVis, *passageVis, *portalVis, *mightSee, *prevMightSee, more; + int *sourceVis, *passageVis, *portalVis, *mightSee, *prevMightSee, more; 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)); // get pointers to vis data - prevMightSee = reinterpret_cast(prevStack->mightSee); - passageVis = reinterpret_cast(passage->canSee); - sourceVis = reinterpret_cast(source->vis); - mightSee = reinterpret_cast(stack->mightSee); + prevMightSee = reinterpret_cast(prevStack->mightSee); + passageVis = reinterpret_cast(passage->canSee); + sourceVis = reinterpret_cast(source->vis); + mightSee = reinterpret_cast(stack->mightSee); more = 0; // use the portal PVS if it has been calculated if ( p->done ) { - portalVis = reinterpret_cast(p->vis); + portalVis = reinterpret_cast(p->vis); for ( j = 0; j < portalVisLongs; j++ ) { // get new PVS which is decreased by going through this passage m = *prevMightSee++ & *passageVis++ & *portalVis++; @@ -731,7 +731,7 @@ idPVS::AreaPVSFromPortalPVS */ int idPVS::AreaPVSFromPortalPVS( void ) const { int i, j, k, areaNum, totalVisibleAreas; - long *p1, *p2; + int *p1, *p2; byte *pvs, *portalPVS; 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 for ( j = 1; j < area->numPortals; j++ ) { - p1 = reinterpret_cast(area->portals[0]->vis); - p2 = reinterpret_cast(area->portals[j]->vis); + p1 = reinterpret_cast(area->portals[0]->vis); + p2 = reinterpret_cast(area->portals[j]->vis); for ( k = 0; k < portalVisLongs; k++ ) { *p1++ |= *p2++; } @@ -808,7 +808,7 @@ void idPVS::Init( void ) { areaQueue = new int[numAreas]; areaVisBytes = ( ((numAreas+31)&~31) >> 3); - areaVisLongs = areaVisBytes/sizeof(long); + areaVisLongs = areaVisBytes/sizeof(int); areaPVS = new byte[numAreas * areaVisBytes]; memset( areaPVS, 0xFF, numAreas * areaVisBytes ); @@ -816,7 +816,7 @@ void idPVS::Init( void ) { numPortals = GetPortalCount(); portalVisBytes = ( ((numPortals+31)&~31) >> 3); - portalVisLongs = portalVisBytes/sizeof(long); + portalVisLongs = portalVisBytes/sizeof(int); for ( int i = 0; i < MAX_CURRENT_PVS; i++ ) { 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 { int i, j; unsigned int h; - long *vis, *pvs; + int *vis, *pvs; pvsHandle_t handle; h = 0; @@ -1035,8 +1035,8 @@ pvsHandle_t idPVS::SetupCurrentPVS( const int *sourceAreas, const int numSourceA assert( sourceAreas[i] >= 0 && sourceAreas[i] < numAreas ); - vis = reinterpret_cast(areaPVS + sourceAreas[i] * areaVisBytes); - pvs = reinterpret_cast(currentPVS[handle.i].pvs); + vis = reinterpret_cast(areaPVS + sourceAreas[i] * areaVisBytes); + pvs = reinterpret_cast(currentPVS[handle.i].pvs); for ( j = 0; j < areaVisLongs; j++ ) { *pvs++ |= *vis++; } @@ -1075,7 +1075,7 @@ idPVS::MergeCurrentPVS */ pvsHandle_t idPVS::MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const { int i; - long *pvs1Ptr, *pvs2Ptr, *ptr; + int *pvs1Ptr, *pvs2Ptr, *ptr; pvsHandle_t handle; 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 ); - ptr = reinterpret_cast(currentPVS[handle.i].pvs); - pvs1Ptr = reinterpret_cast(currentPVS[pvs1.i].pvs); - pvs2Ptr = reinterpret_cast(currentPVS[pvs2.i].pvs); + ptr = reinterpret_cast(currentPVS[handle.i].pvs); + pvs1Ptr = reinterpret_cast(currentPVS[pvs1.i].pvs); + pvs2Ptr = reinterpret_cast(currentPVS[pvs2.i].pvs); for ( i = 0; i < areaVisLongs; i++ ) { *ptr++ = *pvs1Ptr++ | *pvs2Ptr++; diff --git a/neo/d3xp/Pvs.h b/neo/d3xp/Pvs.h index 64251ddf..a85e2bba 100644 --- a/neo/d3xp/Pvs.h +++ b/neo/d3xp/Pvs.h @@ -111,9 +111,9 @@ private: mutable pvsCurrent_t currentPVS[MAX_CURRENT_PVS]; // used to create PVS int portalVisBytes; - int portalVisLongs; + int portalVisLongs; // Note: these are really ints now.. int areaVisBytes; - int areaVisLongs; + int areaVisLongs; // Note: these are really ints now.. struct pvsPortal_s *pvsPortals; struct pvsArea_s * pvsAreas; diff --git a/neo/game/Pvs.cpp b/neo/game/Pvs.cpp index c86fe870..c8a86a1f 100644 --- a/neo/game/Pvs.cpp +++ b/neo/game/Pvs.cpp @@ -330,7 +330,7 @@ pvsStack_t *idPVS::FloodPassagePVS_r( pvsPortal_t *source, const pvsPortal_t *po pvsArea_t *area; pvsStack_t *stack; pvsPassage_t *passage; - long *sourceVis, *passageVis, *portalVis, *mightSee, *prevMightSee, more; + int *sourceVis, *passageVis, *portalVis, *mightSee, *prevMightSee, more; 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)); // get pointers to vis data - prevMightSee = reinterpret_cast(prevStack->mightSee); - passageVis = reinterpret_cast(passage->canSee); - sourceVis = reinterpret_cast(source->vis); - mightSee = reinterpret_cast(stack->mightSee); + prevMightSee = reinterpret_cast(prevStack->mightSee); + passageVis = reinterpret_cast(passage->canSee); + sourceVis = reinterpret_cast(source->vis); + mightSee = reinterpret_cast(stack->mightSee); more = 0; // use the portal PVS if it has been calculated if ( p->done ) { - portalVis = reinterpret_cast(p->vis); + portalVis = reinterpret_cast(p->vis); for ( j = 0; j < portalVisLongs; j++ ) { // get new PVS which is decreased by going through this passage m = *prevMightSee++ & *passageVis++ & *portalVis++; @@ -731,7 +731,7 @@ idPVS::AreaPVSFromPortalPVS */ int idPVS::AreaPVSFromPortalPVS( void ) const { int i, j, k, areaNum, totalVisibleAreas; - long *p1, *p2; + int *p1, *p2; byte *pvs, *portalPVS; 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 for ( j = 1; j < area->numPortals; j++ ) { - p1 = reinterpret_cast(area->portals[0]->vis); - p2 = reinterpret_cast(area->portals[j]->vis); + p1 = reinterpret_cast(area->portals[0]->vis); + p2 = reinterpret_cast(area->portals[j]->vis); for ( k = 0; k < portalVisLongs; k++ ) { *p1++ |= *p2++; } @@ -808,7 +808,7 @@ void idPVS::Init( void ) { areaQueue = new int[numAreas]; areaVisBytes = ( ((numAreas+31)&~31) >> 3); - areaVisLongs = areaVisBytes/sizeof(long); + areaVisLongs = areaVisBytes/sizeof(int); areaPVS = new byte[numAreas * areaVisBytes]; memset( areaPVS, 0xFF, numAreas * areaVisBytes ); @@ -816,7 +816,7 @@ void idPVS::Init( void ) { numPortals = GetPortalCount(); portalVisBytes = ( ((numPortals+31)&~31) >> 3); - portalVisLongs = portalVisBytes/sizeof(long); + portalVisLongs = portalVisBytes/sizeof(int); for ( int i = 0; i < MAX_CURRENT_PVS; i++ ) { 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 { int i, j; unsigned int h; - long *vis, *pvs; + int *vis, *pvs; pvsHandle_t handle; h = 0; @@ -1035,8 +1035,8 @@ pvsHandle_t idPVS::SetupCurrentPVS( const int *sourceAreas, const int numSourceA assert( sourceAreas[i] >= 0 && sourceAreas[i] < numAreas ); - vis = reinterpret_cast(areaPVS + sourceAreas[i] * areaVisBytes); - pvs = reinterpret_cast(currentPVS[handle.i].pvs); + vis = reinterpret_cast(areaPVS + sourceAreas[i] * areaVisBytes); + pvs = reinterpret_cast(currentPVS[handle.i].pvs); for ( j = 0; j < areaVisLongs; j++ ) { *pvs++ |= *vis++; } @@ -1075,7 +1075,7 @@ idPVS::MergeCurrentPVS */ pvsHandle_t idPVS::MergeCurrentPVS( pvsHandle_t pvs1, pvsHandle_t pvs2 ) const { int i; - long *pvs1Ptr, *pvs2Ptr, *ptr; + int *pvs1Ptr, *pvs2Ptr, *ptr; pvsHandle_t handle; 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 ); - ptr = reinterpret_cast(currentPVS[handle.i].pvs); - pvs1Ptr = reinterpret_cast(currentPVS[pvs1.i].pvs); - pvs2Ptr = reinterpret_cast(currentPVS[pvs2.i].pvs); + ptr = reinterpret_cast(currentPVS[handle.i].pvs); + pvs1Ptr = reinterpret_cast(currentPVS[pvs1.i].pvs); + pvs2Ptr = reinterpret_cast(currentPVS[pvs2.i].pvs); for ( i = 0; i < areaVisLongs; i++ ) { *ptr++ = *pvs1Ptr++ | *pvs2Ptr++; diff --git a/neo/game/Pvs.h b/neo/game/Pvs.h index 6063c2f2..65b3a01f 100644 --- a/neo/game/Pvs.h +++ b/neo/game/Pvs.h @@ -107,9 +107,9 @@ private: mutable pvsCurrent_t currentPVS[MAX_CURRENT_PVS]; // used to create PVS int portalVisBytes; - int portalVisLongs; + int portalVisLongs; // Note: these are really ints now.. int areaVisBytes; - int areaVisLongs; + int areaVisLongs; // Note: these are really ints now.. struct pvsPortal_s *pvsPortals; struct pvsArea_s * pvsAreas;