Merged with the master repo

Merged with the master repo

diff --git a/src/engine/GPURenderer/r_bsp_tech3.cpp b/src/engine/GPURenderer/r_bsp_tech3.cpp
index c335cae..f8bb8cd 100644
--- a/src/engine/GPURenderer/r_bsp_tech3.cpp
+++ b/src/engine/GPURenderer/r_bsp_tech3.cpp
@@ -2279,10 +2279,19 @@ static	void R_LoadFogs( lump_t* l, lump_t* brushesLump, lump_t* sidesLump )
         }
         else
         {
-            out->hasSurface = true;
-            planeNum = LittleLong( sides[ firstSide + sideNum ].planeNum );
-            VectorSubtract( vec3_origin, s_worldData.planes[ planeNum ].normal, out->surface );
-            out->surface[3] = -s_worldData.planes[ planeNum ].dist;
+            sint sideOffset = firstSide + sideNum;
+            if( ( sint )sideOffset >= sidesCount )
+            {
+                CL_RefPrintf( PRINT_WARNING, "bad fog side offset %i\n", sideOffset );
+                out->hasSurface = false;
+            }
+            else
+            {
+                out->hasSurface = true;
+                planeNum = LittleLong( sides[sideOffset].planeNum );
+                VectorSubtract( vec3_origin, s_worldData.planes[planeNum].normal, out->surface );
+                out->surface[3] = -s_worldData.planes[planeNum].dist;
+            }
         }
         
         out++;
@@ -2997,13 +3006,12 @@ void idRenderSystemLocal::LoadWorld( pointer name )
     fileBase = ( uchar8* )header;
     
     i = LittleLong( header->version );
-#if 0
+    
     if( i != BSP_VERSION )
     {
         Com_Error( ERR_DROP, "idRenderSystemLocal::LoadWorldMap: %s has wrong version number (%i should be %i)",
                    name, i, BSP_VERSION );
     }
-#endif
     
     // swap all the lumps
     for( i = 0 ; i < sizeof( dheader_t ) / 4 ; i++ )
diff --git a/src/engine/audio/s_dma.cpp b/src/engine/audio/s_dma.cpp
index c905b51..5e70a9f 100644
--- a/src/engine/audio/s_dma.cpp
+++ b/src/engine/audio/s_dma.cpp
@@ -1699,8 +1699,10 @@ void S_Base_Shutdown( void )
     }
     
     SNDDMA_Shutdown();
+    SND_shutdown();
     
     s_soundStarted = 0;
+    s_numSfx = 0;
     
     cmdSystem->RemoveCommand( "s_info" );
 }
diff --git a/src/engine/audio/s_local.h b/src/engine/audio/s_local.h
index 4c1f628..74dd39b 100644
--- a/src/engine/audio/s_local.h
+++ b/src/engine/audio/s_local.h
@@ -220,6 +220,7 @@ extern convar_t* s_testsound;
 
 bool S_LoadSound( sfx_t* sfx );
 
+void SND_shutdown( void );
 void SND_free( sndBuffer* v );
 sndBuffer* SND_malloc( void );
 void SND_setup( void );
diff --git a/src/engine/audio/s_mem.cpp b/src/engine/audio/s_mem.cpp
index 7985ebc..cbc07b1 100644
--- a/src/engine/audio/s_mem.cpp
+++ b/src/engine/audio/s_mem.cpp
@@ -48,6 +48,12 @@ schar16* sfxScratchBuffer = nullptr;
 sfx_t* sfxScratchPointer = nullptr;
 sint	sfxScratchIndex = 0;
 
+void SND_shutdown( void )
+{
+    free( sfxScratchBuffer );
+    free( buffer );
+}
+
 void SND_free( sndBuffer* v )
 {
     *( sndBuffer** )v = freelist;
diff --git a/src/engine/client/clientParse.cpp b/src/engine/client/clientParse.cpp
index 3f9b53b..76149b7 100644
--- a/src/engine/client/clientParse.cpp
+++ b/src/engine/client/clientParse.cpp
@@ -516,7 +516,7 @@ void idClientParseSystemLocal::ParseSnapshot( msg_t* msg )
     else
     {
         old = &cl.snapshots[newSnap.deltaNum & PACKET_MASK];
-
+        
         if( !old->valid )
         {
             // should never happen
@@ -533,7 +533,7 @@ void idClientParseSystemLocal::ParseSnapshot( msg_t* msg )
                 Com_Printf( "Found more recent frame to delta from.\n" );
             }
         }
-
+        
         if( !old->valid )
         {
             Com_Printf( "Failed to find more recent frame to delta from.\n" );
diff --git a/src/engine/cm/cm_load_tech3.cpp b/src/engine/cm/cm_load_tech3.cpp
index a0fe634..d1fde1f 100644
--- a/src/engine/cm/cm_load_tech3.cpp
+++ b/src/engine/cm/cm_load_tech3.cpp
@@ -679,6 +679,25 @@ void CMod_LoadLeafSurfaces( lump_t* l )
 
 /*
 =================
+CMod_CheckLeafBrushes
+=================
+*/
+void CMod_CheckLeafBrushes( void )
+{
+    sint	i;
+    
+    for( i = 0; i < cm.numLeafBrushes; i++ )
+    {
+        if( cm.leafbrushes[i] < 0 || cm.leafbrushes[i] >= cm.numBrushes )
+        {
+            Com_DPrintf( S_COLOR_YELLOW "[%i] invalid leaf brush %08x\n", i, cm.leafbrushes[i] );
+            cm.leafbrushes[i] = 0;
+        }
+    }
+}
+
+/*
+=================
 CMod_LoadBrushSides
 =================
 */
@@ -1194,12 +1213,11 @@ void idCollisionModelManagerLocal::LoadMap( pointer name, bool clientload, sint*
         ( ( sint* )&header )[i] = LittleLong( ( ( sint* )&header )[i] );
     }
     
-#if 0
     if( header.version != BSP_VERSION )
     {
         Com_Error( ERR_DROP, "idCollisionModelManagerLocal::LoadMap: %s has wrong version number (%i should be %i)", name, header.version, BSP_VERSION );
     }
-#endif
+
     cmod_base = ( uchar8* ) buf;
     
     // load into heap
@@ -1216,6 +1234,8 @@ void idCollisionModelManagerLocal::LoadMap( pointer name, bool clientload, sint*
     CMod_LoadVisibility( &header.lumps[LUMP_VISIBILITY] );
     CMod_LoadSurfaces( &header.lumps[LUMP_SURFACES], &header.lumps[LUMP_DRAWVERTS], &header.lumps[LUMP_DRAWINDEXES] );
     
+    CMod_CheckLeafBrushes();
+    
     CMod_CreateBrushSideWindings();
     
     // we are NOT freeing the file, because it is cached for the ref
diff --git a/src/engine/framework/Network.cpp b/src/engine/framework/Network.cpp
index 1b89ca4..9de0e72 100644
--- a/src/engine/framework/Network.cpp
+++ b/src/engine/framework/Network.cpp
@@ -455,19 +455,36 @@ idNetworkSystemLocal::AdrToString
 */
 pointer	idNetworkSystemLocal::AdrToString( netadr_t a )
 {
-    static	valueType	s[NET_ADDRSTRMAXLEN];
+    static valueType s[NET_ADDRSTRMAXLEN];
     
-    if( a.type == NA_LOOPBACK )
-        Com_sprintf( s, sizeof( s ), "loopback" );
-    else if( a.type == NA_BOT )
-        Com_sprintf( s, sizeof( s ), "bot" );
-    else if( a.type == NA_IP || a.type == NA_IP6 )
+    switch( a.type )
     {
-        struct sockaddr_storage sadr;
-        
-        memset( &sadr, 0, sizeof( sadr ) );
-        NetadrToSockadr( &a, ( struct sockaddr* ) &sadr );
-        SockaddrToString( s, sizeof( s ), ( struct sockaddr* ) &sadr );
+        case NA_LOOPBACK:
+            Com_sprintf( s, sizeof( s ), "loopback" );
+            break;
+        case NA_BOT:
+            Com_sprintf( s, sizeof( s ), "bot" );
+            break;
+        case NA_IP:
+            Com_sprintf( s, sizeof( s ), "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3] );
+            break;
+        case NA_IP6:
+        {
+            struct sockaddr_storage sadr;
+            
+            memset( &sadr, 0, sizeof( sadr ) );
+            NetadrToSockadr( &a, ( struct sockaddr* )&sadr );
+            SockaddrToString( s, sizeof( s ), ( struct sockaddr* )&sadr );
+            break;
+        }
+        break;
+        case NA_BAD:
+            Com_sprintf( s, sizeof( s ), "invalid" );
+            break;
+        default:
+            Com_Printf( "idNetworkSystemLocal::AdrToString: Unknown address type: %i\n", a.type );
+            Com_sprintf( s, sizeof( s ), "unknown" );
+            break;
     }
     
     return s;
@@ -480,16 +497,31 @@ idNetworkSystemLocal::AdrToStringwPort
 */
 pointer	idNetworkSystemLocal::AdrToStringwPort( netadr_t a )
 {
-    static	valueType	s[NET_ADDRSTRMAXLEN];
+    static valueType s[NET_ADDRSTRMAXLEN];
+    
+    switch( a.type )
+    {
+        case NA_LOOPBACK:
+            Com_sprintf( s, sizeof( s ), "loopback" );
+            break;
+        case NA_BOT:
+            Com_sprintf( s, sizeof( s ), "bot" );
+            break;
+        case NA_IP:
+            Com_sprintf( s, sizeof( s ), "%i.%i.%i.%i:%hu", a.ip[0], a.ip[1], a.ip[2], a.ip[3], BigShort( a.port ) );
+            break;
+        case NA_IP6:
+            Com_sprintf( s, sizeof( s ), "[%s]:%hu", AdrToString( a ), ntohs( a.port ) );
+            break;
+        case NA_BAD:
+            Com_sprintf( s, sizeof( s ), "invalid" );

[... diff too long, it was truncated ...]

GitHub
sha: 447726bc