From: Garux <garux@mail.ru>
Date: Tue, 1 Aug 2017 10:58:52 +0000 (+0300)
Subject: Q3map2:
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=fe73dd74d0e40a33c090993390e4d5721a1f9e05;p=xonotic%2Fnetradiant.git

Q3map2:
	* fix: number of problems, found by Visual Studio's static code analyser
		(https://github.com/TTimo/GtkRadiant/commit/76ea7385dd94aac435a858b05f87820e1cfadfd6)

Radiant:

misc...
	* fix of: convert group entity to diff one = entity w/o objects
	* asking for game path at 1st start, even if one, specified in .game exists (auto picking could make confused)
	* disabled game autodetecting: (~2min awaiting on w7 in non admin mode was confusing)
---

diff --git a/radiant/environment.cpp b/radiant/environment.cpp
index 9583b90f..74de78b6 100644
--- a/radiant/environment.cpp
+++ b/radiant/environment.cpp
@@ -104,7 +104,8 @@ bool gamedetect_check_game( char *gamefile, const char *checkfile1, const char *
 void gamedetect(){
 	// if we're inside a Nexuiz install
 	// default to nexuiz.game (unless the user used an option to inhibit this)
-	bool nogamedetect = false;
+	//bool nogamedetect = false;
+	bool nogamedetect = true;
 	int i;
 	for ( i = 1; i < g_argc - 1; ++i )
 		if ( g_argv[i][0] == '-' ) {
diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp
index 4f0bfef0..310e7d97 100644
--- a/radiant/mainframe.cpp
+++ b/radiant/mainframe.cpp
@@ -447,8 +447,10 @@ GtkWindow* BuildDialog(){
 
 PathsDialog g_PathsDialog;
 
+bool g_strEnginePath_was_empty_1st_start = false;
+
 void EnginePath_verify(){
-	if ( !file_exists( g_strEnginePath.c_str() ) ) {
+	if ( !file_exists( g_strEnginePath.c_str() ) || g_strEnginePath_was_empty_1st_start ) {
 		g_PathsDialog.Create();
 		g_PathsDialog.DoModal();
 		g_PathsDialog.Destroy();
@@ -3365,7 +3367,10 @@ void MainFrame_Construct(){
 	GlobalPreferenceSystem().registerPreference( "YZWnd", WindowPositionTrackerImportStringCaller( g_posYZWnd ), WindowPositionTrackerExportStringCaller( g_posYZWnd ) );
 	GlobalPreferenceSystem().registerPreference( "XZWnd", WindowPositionTrackerImportStringCaller( g_posXZWnd ), WindowPositionTrackerExportStringCaller( g_posXZWnd ) );
 
+	GlobalPreferenceSystem().registerPreference( "EnginePath", CopiedStringImportStringCaller( g_strEnginePath ), CopiedStringExportStringCaller( g_strEnginePath ) );
+	if ( g_strEnginePath.empty() )
 	{
+		g_strEnginePath_was_empty_1st_start = true;
 		const char* ENGINEPATH_ATTRIBUTE =
 #if defined( WIN32 )
 			"enginepath_win32"
@@ -3380,9 +3385,10 @@ void MainFrame_Construct(){
 		StringOutputStream path( 256 );
 		path << DirectoryCleaned( g_pGameDescription->getRequiredKeyValue( ENGINEPATH_ATTRIBUTE ) );
 		g_strEnginePath = path.c_str();
+		GlobalPreferenceSystem().registerPreference( "EnginePath", CopiedStringImportStringCaller( g_strEnginePath ), CopiedStringExportStringCaller( g_strEnginePath ) );
 	}
 
-	GlobalPreferenceSystem().registerPreference( "EnginePath", CopiedStringImportStringCaller( g_strEnginePath ), CopiedStringExportStringCaller( g_strEnginePath ) );
+
 
 	g_Layout_viewStyle.useLatched();
 	g_Layout_enableDetachableMenus.useLatched();
diff --git a/radiant/map.cpp b/radiant/map.cpp
index fae78de3..4706a0c6 100644
--- a/radiant/map.cpp
+++ b/radiant/map.cpp
@@ -1595,40 +1595,51 @@ bool Map_SaveSelected( const char* filename ){
 	return MapResource_saveFile( MapFormat_forFile( filename ), GlobalSceneGraph().root(), Map_Traverse_Selected, filename );
 }
 
-
 class ParentSelectedBrushesToEntityWalker : public scene::Graph::Walker
 {
-scene::Node& m_parent;
+	scene::Node& m_parent;
+	mutable bool m_emptyOldParent;
+
 public:
-ParentSelectedBrushesToEntityWalker( scene::Node& parent ) : m_parent( parent ){
+ParentSelectedBrushesToEntityWalker( scene::Node& parent ) : m_parent( parent ), m_emptyOldParent( false ){
 }
 bool pre( const scene::Path& path, scene::Instance& instance ) const {
-	if ( path.top().get_pointer() != &m_parent
-		 && Node_isPrimitive( path.top() ) ) {
+	if ( path.top().get_pointer() != &m_parent && ( Node_isPrimitive( path.top() ) || m_emptyOldParent ) ) {
 		Selectable* selectable = Instance_getSelectable( instance );
-		if ( selectable != 0
-			 && selectable->isSelected()
-			 && path.size() > 1 ) {
+		if ( selectable && selectable->isSelected() && path.size() > 1 ) {
 			return false;
 		}
 	}
 	return true;
 }
 void post( const scene::Path& path, scene::Instance& instance ) const {
-	if ( path.top().get_pointer() != &m_parent
-		 && Node_isPrimitive( path.top() ) ) {
+	if ( path.top().get_pointer() == &m_parent )
+		return;
+
+	if ( Node_isPrimitive( path.top() ) ){
+		m_emptyOldParent = false;
 		Selectable* selectable = Instance_getSelectable( instance );
-		if ( selectable != 0
-			 && selectable->isSelected()
-			 && path.size() > 1 ) {
+
+		if ( selectable && selectable->isSelected() && path.size() > 1 ){
 			scene::Node& parent = path.parent();
-			if ( &parent != &m_parent ) {
+			if ( &parent != &m_parent ){
 				NodeSmartReference node( path.top().get() );
-				Node_getTraversable( parent )->erase( node );
+				scene::Traversable* traversable_parent = Node_getTraversable( parent );
+				traversable_parent->erase( node );
 				Node_getTraversable( m_parent )->insert( node );
+				if ( traversable_parent->empty() )
+					m_emptyOldParent = true;
 			}
 		}
 	}
+	else if ( m_emptyOldParent ){
+		m_emptyOldParent = false;
+		// delete empty entities
+		Entity* entity = Node_getEntity( path.top() );
+		if ( entity != 0 && path.top().get_pointer() != Map_FindWorldspawn( g_map )	&& Node_getTraversable( path.top() )->empty() ) {
+			Path_deleteTop( path );
+		}
+	}
 }
 };
 
diff --git a/radiant/texwindow.cpp b/radiant/texwindow.cpp
index c7e02c11..14dfab42 100644
--- a/radiant/texwindow.cpp
+++ b/radiant/texwindow.cpp
@@ -305,34 +305,32 @@ int m_uniformTextureMinSize;
 	}
 }
 */
-void getTextureWH( qtexture_t* tex, int *width, int *height ){
+void getTextureWH( qtexture_t* tex, int &W, int &H ){
 		// Don't use uniform size
-		*width = (int)( tex->width * ( (float)m_textureScale / 100 ) );
-		*height = (int)( tex->height * ( (float)m_textureScale / 100 ) );
+		W = (int)( tex->width * ( (float)m_textureScale / 100 ) );
+		H = (int)( tex->height * ( (float)m_textureScale / 100 ) );
 
 	if ( g_TextureBrowser_fixedSize ){
-		int W = *width;
-		int H = *height;
 		if	( W >= H ) {
 			// Texture is square, or wider than it is tall
 			if ( W >= m_uniformTextureSize ){
-				*width = m_uniformTextureSize;
-				*height = m_uniformTextureSize * H / W;
+				H = m_uniformTextureSize * H / W;
+				W = m_uniformTextureSize;
 			}
 			else if ( W <= m_uniformTextureMinSize ){
-				*width = m_uniformTextureMinSize;
-				*height = m_uniformTextureMinSize * H / W;
+				H = m_uniformTextureMinSize * H / W;
+				W = m_uniformTextureMinSize;
 			}
 		}
 		else {
 			// Texture taller than it is wide
 			if ( H >= m_uniformTextureSize ){
-				*height = m_uniformTextureSize;
-				*width = m_uniformTextureSize * W / H;
+				W = m_uniformTextureSize * W / H;
+				H = m_uniformTextureSize;
 			}
 			else if ( H <= m_uniformTextureMinSize ){
-				*height = m_uniformTextureMinSize;
-				*width = m_uniformTextureMinSize * W / H;
+				W = m_uniformTextureMinSize * W / H;
+				H = m_uniformTextureMinSize;
 			}
 		}
 	}
@@ -461,7 +459,7 @@ void Texture_NextPos( TextureBrowser& textureBrowser, TextureLayout& layout, qte
 	qtexture_t* q = current_texture;
 
 	int nWidth, nHeight;
-	textureBrowser.getTextureWH( q, &nWidth, &nHeight );
+	textureBrowser.getTextureWH( q, nWidth, nHeight );
 	if ( layout.current_x + nWidth > textureBrowser.width - 8 && layout.current_row ) { // go to the next row unless the texture is the first on the row
 		layout.current_x = 8;
 		layout.current_y -= layout.current_row + TextureBrowser_fontHeight( textureBrowser ) + 4;
@@ -574,7 +572,7 @@ void TextureBrowser_evaluateHeight( TextureBrowser& textureBrowser ){
 			int x, y;
 			Texture_NextPos( textureBrowser, layout, shader->getTexture(), &x, &y );
 			int nWidth, nHeight;
-			textureBrowser.getTextureWH( shader->getTexture(), &nWidth, &nHeight );
+			textureBrowser.getTextureWH( shader->getTexture(), nWidth, nHeight );
 			textureBrowser.m_nTotalHeight = std::max( textureBrowser.m_nTotalHeight, abs( layout.current_y ) + TextureBrowser_fontHeight( textureBrowser ) + nHeight + 4 );
 		}
 	}
@@ -960,7 +958,7 @@ IShader* Texture_At( TextureBrowser& textureBrowser, int mx, int my ){
 		}
 
 		int nWidth, nHeight;
-		textureBrowser.getTextureWH( q, &nWidth, &nHeight );
+		textureBrowser.getTextureWH( q, nWidth, nHeight );
 		if ( mx > x && mx - x < nWidth
 			 && my < y && y - my < nHeight + TextureBrowser_fontHeight( textureBrowser ) ) {
 			return shader;
@@ -1091,7 +1089,7 @@ void Texture_Draw( TextureBrowser& textureBrowser ){
 		}
 
 		int nWidth, nHeight;
-		textureBrowser.getTextureWH( q, &nWidth, &nHeight );
+		textureBrowser.getTextureWH( q, nWidth, nHeight );
 
 		if ( y != last_y ) {
 			last_y = y;
diff --git a/tools/quake3/q3map2/bspfile_abstract.c b/tools/quake3/q3map2/bspfile_abstract.c
index b842c69c..27ea7c15 100644
--- a/tools/quake3/q3map2/bspfile_abstract.c
+++ b/tools/quake3/q3map2/bspfile_abstract.c
@@ -68,14 +68,19 @@ void IncDrawVerts(){
 
 	}
 	else if ( numBSPDrawVerts > numBSPDrawVertsBuffer ) {
+		bspDrawVert_t *newBspDrawVerts;
+
 		numBSPDrawVertsBuffer *= 3; // multiply by 1.5
 		numBSPDrawVertsBuffer /= 2;
 
-		bspDrawVerts = realloc( bspDrawVerts, sizeof( bspDrawVert_t ) * numBSPDrawVertsBuffer );
+		newBspDrawVerts = realloc( bspDrawVerts, sizeof( bspDrawVert_t ) * numBSPDrawVertsBuffer );
 
-		if ( !bspDrawVerts ) {
+		if ( !newBspDrawVerts ) {
+			free (bspDrawVerts);
 			Error( "realloc() failed (IncDrawVerts)" );
 		}
+
+		bspDrawVerts = newBspDrawVerts;
 	}
 
 	memset( bspDrawVerts + ( numBSPDrawVerts - 1 ), 0, sizeof( bspDrawVert_t ) );
diff --git a/tools/quake3/q3map2/light_bounce.c b/tools/quake3/q3map2/light_bounce.c
index 82aacdb5..b9cb8242 100644
--- a/tools/quake3/q3map2/light_bounce.c
+++ b/tools/quake3/q3map2/light_bounce.c
@@ -185,10 +185,10 @@ static void RadClipWindingEpsilon( radWinding_t *in, vec3_t normal, vec_t dist,
 	}
 
 	/* error check */
-	if ( front->numVerts > maxPoints || front->numVerts > maxPoints ) {
+	if ( front->numVerts > maxPoints ) {
 		Error( "RadClipWindingEpsilon: points exceeded estimate" );
 	}
-	if ( front->numVerts > MAX_POINTS_ON_WINDING || front->numVerts > MAX_POINTS_ON_WINDING ) {
+	if ( front->numVerts > MAX_POINTS_ON_WINDING ) {
 		Error( "RadClipWindingEpsilon: MAX_POINTS_ON_WINDING" );
 	}
 }
@@ -288,7 +288,7 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm,
 			/* multiply by texture color */
 			if ( !RadSampleImage( si->lightImage->pixels, si->lightImage->width, si->lightImage->height, rw->verts[ samples ].st, textureColor ) ) {
 				VectorCopy( si->averageColor, textureColor );
-				textureColor[ 4 ] = 255.0f;
+				textureColor[ 3 ] = 255.0f;
 			}
 			avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3;
 			for ( i = 0; i < 3; i++ )
@@ -374,7 +374,7 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm,
 						/* multiply by texture color */
 						if ( !RadSampleImage( si->lightImage->pixels, si->lightImage->width, si->lightImage->height, st, textureColor ) ) {
 							VectorCopy( si->averageColor, textureColor );
-							textureColor[ 4 ] = 255;
+							textureColor[ 3 ] = 255;
 						}
 						avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3;
 						for ( l = 0; l < 3; l++ ){
diff --git a/tools/quake3/q3map2/lightmaps_ydnar.c b/tools/quake3/q3map2/lightmaps_ydnar.c
index 28ccab57..82de2474 100644
--- a/tools/quake3/q3map2/lightmaps_ydnar.c
+++ b/tools/quake3/q3map2/lightmaps_ydnar.c
@@ -2166,6 +2166,10 @@ static void FindOutLightmaps( rawLightmap_t *lm ){
 			/* allocate LIGHTMAP_RESERVE_COUNT new output lightmaps */
 			numOutLightmaps += LIGHTMAP_RESERVE_COUNT;
 			olm = safe_malloc( numOutLightmaps * sizeof( outLightmap_t ) );
+			if ( !olm ){
+				Error( "FindOutLightmaps: Failed to allocate memory.\n" );
+			}
+
 			if ( outLightmaps != NULL && numOutLightmaps > LIGHTMAP_RESERVE_COUNT ) {
 				memcpy( olm, outLightmaps, ( numOutLightmaps - LIGHTMAP_RESERVE_COUNT ) * sizeof( outLightmap_t ) );
 				free( outLightmaps );
diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h
index df44fc84..e0c7a0cb 100644
--- a/tools/quake3/q3map2/q3map2.h
+++ b/tools/quake3/q3map2/q3map2.h
@@ -789,7 +789,7 @@ typedef struct shaderInfo_s
 	sun_t               *sun;                           /* ydnar */
 
 	vec3_t color;                                       /* normalized color */
-	vec3_t averageColor;
+	vec4_t averageColor;
 	byte lightStyle;
 
 	/* vortex: per-surface floodlight */
diff --git a/tools/quake3/q3map2/shaders.c b/tools/quake3/q3map2/shaders.c
index 07322fa6..c771d89b 100644
--- a/tools/quake3/q3map2/shaders.c
+++ b/tools/quake3/q3map2/shaders.c
@@ -811,10 +811,12 @@ static void LoadShaderImages( shaderInfo_t *si ){
 	if ( VectorLength( si->color ) <= 0.0f ) {
 		ColorNormalize( color, si->color );
 		VectorScale( color, ( 1.0f / count ), si->averageColor );
+		si->averageColor[ 3 ] = color[ 3 ] / count;
 	}
 	else
 	{
 		VectorCopy( si->color, si->averageColor );
+		si->averageColor[ 3 ] = 1.0f;
 	}
 }
 
diff --git a/tools/quake3/q3map2/surface_meta.c b/tools/quake3/q3map2/surface_meta.c
index 8d4f3c36..453b7531 100644
--- a/tools/quake3/q3map2/surface_meta.c
+++ b/tools/quake3/q3map2/surface_meta.c
@@ -952,7 +952,8 @@ void MakeEntityMetaTriangles( entity_t *e ){
 
 typedef struct edge_s
 {
-	vec3_t origin, edge;
+	vec3_t origin;
+	vec4_t edge;
 	vec_t length, kingpinLength;
 	int kingpin;
 	vec4_t plane;