From 5c08cb01400ac8d957ac95d319e2b6375aede5fd 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. --- d3xp/Pvs.cpp | 36 ++++++++++++++++++------------------ d3xp/Pvs.h | 4 ++-- game/Pvs.cpp | 36 ++++++++++++++++++------------------ game/Pvs.h | 4 ++-- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/d3xp/Pvs.cpp b/d3xp/Pvs.cpp index 61e1fa1..8ff144f 100644 --- a/d3xp/Pvs.cpp +++ b/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/d3xp/Pvs.h b/d3xp/Pvs.h index 64251dd..a85e2bb 100644 --- a/d3xp/Pvs.h +++ b/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/game/Pvs.cpp b/game/Pvs.cpp index c86fe87..c8a86a1 100644 --- a/game/Pvs.cpp +++ b/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/game/Pvs.h b/game/Pvs.h index 6063c2f..65b3a01 100644 --- a/game/Pvs.h +++ b/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;