From: Rudolf Polzer Date: Tue, 27 Mar 2012 10:11:37 +0000 (+0200) Subject: Merge remote-tracking branch 'github/master' X-Git-Tag: xonotic-v0.7.0~16^2~6 X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=commitdiff_plain;h=b7e36c120eb1546a6c6f97f30e42ab7f9a559c61;hp=-c Merge remote-tracking branch 'github/master' Conflicts: .gitignore config.py libs/synapse/synapse.cpp plugins/imagehl/lbmlib.cpp plugins/surface_heretic2/surfacedialog.cpp plugins/surface_ufoai/surfacedialog.cpp radiant/brushscript.cpp radiant/main.cpp radiant/preferences.cpp tools/quake3/common/cmdlib.c tools/quake3/common/cmdlib.h tools/quake3/q3map2/path_init.c windows_compile_guide/index.html --- b7e36c120eb1546a6c6f97f30e42ab7f9a559c61 diff --combined contrib/bobtoolz/DBrush.cpp index 7c24cd0f,3e54e797..4a2b9c09 --- a/contrib/bobtoolz/DBrush.cpp +++ b/contrib/bobtoolz/DBrush.cpp @@@ -21,40 -21,25 +21,40 @@@ // ////////////////////////////////////////////////////////////////////// -#include "StdAfx.h" +#include "DBrush.h" -#ifdef _WIN32 +#ifdef WIN32 #pragma warning(disable : 4786) #endif -#include "DBrush.h" +#include +#include "str.h" + +#include "DPoint.h" +#include "DPlane.h" +#include "DEPair.h" +#include "DPatch.h" +#include "DEntity.h" #include "DWinding.h" + #include "dialogs/dialogs-gtk.h" #include "misc.h" +#include "iundo.h" + +#include "generic/referencecounted.h" + +#include "scenelib.h" + ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// DBrush::DBrush( int ID ){ m_nBrushID = ID; - bBoundsBuilt = FALSE; + bBoundsBuilt = false; + QER_entity = NULL; QER_brush = NULL; } @@@ -67,11 -52,11 +67,11 @@@ DBrush::~DBrush() // Implementation ////////////////////////////////////////////////////////////////////// -DPlane* DBrush::AddFace( vec3_t va, vec3_t vb, vec3_t vc, _QERFaceData* texData ){ +DPlane* DBrush::AddFace( const vec3_t va, const vec3_t vb, const vec3_t vc, const _QERFaceData* texData ){ #ifdef _DEBUG // Sys_Printf("(%f %f %f) (%f %f %f) (%f %f %f)\n", va[0], va[1], va[2], vb[0], vb[1], vb[2], vc[0], vc[1], vc[2]); #endif - bBoundsBuilt = FALSE; + bBoundsBuilt = false; DPlane* newFace = new DPlane( va, vb, vc, texData ); faceList.push_back( newFace ); @@@ -85,12 -70,12 +85,12 @@@ int DBrush::BuildPoints() return 0; // with only 3 faces u can't have a bounded soild } - for ( list::const_iterator p1 = faceList.begin(); p1 != faceList.end(); p1++ ) + for ( std::list::const_iterator p1 = faceList.begin(); p1 != faceList.end(); p1++ ) { - list::const_iterator p2 = p1; + std::list::const_iterator p2 = p1; for ( p2++; p2 != faceList.end(); p2++ ) { - list::const_iterator p3 = p2; + std::list::const_iterator p3 = p2; for ( p3++; p3 != faceList.end(); p3++ ) { vec3_t pnt; @@@ -98,7 -83,7 +98,7 @@@ int pos = PointPosition( pnt ); if ( pos == POINT_IN_BRUSH ) { // ???? shouldn't happen here - Sys_Printf( "ERROR:: Build Brush Points: Point IN brush!!!\n" ); + globalErrorStream() << "ERROR:: Build Brush Points: Point IN brush!!!\n"; } else if ( pos == POINT_ON_BRUSH ) { // normal point if ( !HasPoint( pnt ) ) { @@@ -121,33 -106,36 +121,33 @@@ // Sys_Printf("%i points on brush\n", pointList.size()); #endif - return pointList.size(); + return static_cast( pointList.size() ); } -void DBrush::LoadFromBrush_t( brush_t* brush, bool textured ){ - ClearFaces(); - ClearPoints(); +void DBrush_addFace( DBrush& brush, const _QERFaceData& faceData ){ + brush.AddFace( vector3_to_array( faceData.m_p0 ), vector3_to_array( faceData.m_p1 ), vector3_to_array( faceData.m_p2 ), 0 ); +} +typedef ReferenceCaller1 DBrushAddFaceCaller; - for ( int i = g_FuncTable.m_pfnGetFaceCount( brush ) - 1; i >= 0 ; i-- ) - { // running backwards so i dont have to use the count function each time (OPT) - _QERFaceData* faceData = g_FuncTable.m_pfnGetFaceData( brush, i ); +void DBrush_addFaceTextured( DBrush& brush, const _QERFaceData& faceData ){ + brush.AddFace( vector3_to_array( faceData.m_p0 ), vector3_to_array( faceData.m_p1 ), vector3_to_array( faceData.m_p2 ), &faceData ); +} +typedef ReferenceCaller1 DBrushAddFaceTexturedCaller; - if ( faceData == NULL ) { - DoMessageBox( "Null pointer returned", "WARNING!", MB_OK ); - } +void DBrush::LoadFromBrush( scene::Instance& brush, bool textured ){ + ClearFaces(); + ClearPoints(); - if ( textured ) { - AddFace( faceData->m_v1, faceData->m_v2, faceData->m_v3, faceData ); - } - else{ - AddFace( faceData->m_v1, faceData->m_v2, faceData->m_v3, NULL ); - } - } + GlobalBrushCreator().Brush_forEachFace( brush.path().top(), textured ? BrushFaceDataCallback( DBrushAddFaceTexturedCaller( *this ) ) : BrushFaceDataCallback( DBrushAddFaceCaller( *this ) ) ); - QER_brush = brush; + QER_entity = brush.path().parent().get_pointer(); + QER_brush = brush.path().top().get_pointer(); } int DBrush::PointPosition( vec3_t pnt ){ int state = POINT_IN_BRUSH; // if nothing happens point is inside brush - for ( list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) + for ( std::list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) { float dist = ( *chkPlane )->DistanceToPoint( pnt ); @@@ -164,15 -152,15 +164,15 @@@ } void DBrush::ClearPoints(){ - for ( list::const_iterator deadPoint = pointList.begin(); deadPoint != pointList.end(); deadPoint++ ) { + for ( std::list::const_iterator deadPoint = pointList.begin(); deadPoint != pointList.end(); deadPoint++ ) { delete *deadPoint; } pointList.clear(); } void DBrush::ClearFaces(){ - bBoundsBuilt = FALSE; - for ( list::const_iterator deadPlane = faceList.begin(); deadPlane != faceList.end(); deadPlane++ ) + bBoundsBuilt = false; + for ( std::list::const_iterator deadPlane = faceList.begin(); deadPlane != faceList.end(); deadPlane++ ) { delete *deadPlane; } @@@ -186,31 -174,31 +186,31 @@@ void DBrush::AddPoint( vec3_t pnt ) } bool DBrush::HasPoint( vec3_t pnt ){ - for ( list::const_iterator chkPoint = pointList.begin(); chkPoint != pointList.end(); chkPoint++ ) + for ( std::list::const_iterator chkPoint = pointList.begin(); chkPoint != pointList.end(); chkPoint++ ) { if ( **chkPoint == pnt ) { - return TRUE; + return true; } } - return FALSE; + return false; } int DBrush::RemoveRedundantPlanes(){ int cnt = 0; - list::iterator chkPlane; + std::list::iterator chkPlane; // find duplicate planes - list::iterator p1 = faceList.begin(); + std::list::iterator p1 = faceList.begin(); while ( p1 != faceList.end() ) { - list::iterator p2 = p1; + std::list::iterator p2 = p1; for ( p2++; p2 != faceList.end(); p2++ ) { if ( **p1 == **p2 ) { - if ( !strcmp( ( *p1 )->texInfo.m_TextureName, "textures/common/caulk" ) ) { + if ( !strcmp( ( *p1 )->m_shader.c_str(), "textures/common/caulk" ) ) { delete *p1; p1 = faceList.erase( p1 ); // duplicate plane } @@@ -271,13 -259,13 +271,13 @@@ bool DBrush::GetBounds( vec3_t min, vec BuildBounds(); if ( !bBoundsBuilt ) { - return FALSE; + return false; } VectorCopy( bbox_min, min ); VectorCopy( bbox_max, max ); - return TRUE; + return true; } bool DBrush::BBoxCollision( DBrush* chkBrush ){ @@@ -288,30 -276,30 +288,30 @@@ chkBrush->GetBounds( min2, max2 ); if ( min1[0] >= max2[0] ) { - return FALSE; + return false; } if ( min1[1] >= max2[1] ) { - return FALSE; + return false; } if ( min1[2] >= max2[2] ) { - return FALSE; + return false; } if ( max1[0] <= min2[0] ) { - return FALSE; + return false; } if ( max1[1] <= min2[1] ) { - return FALSE; + return false; } if ( max1[2] <= min2[2] ) { - return FALSE; + return false; } - return TRUE; + return true; } DPlane* DBrush::HasPlane( DPlane* chkPlane ){ - for ( list::const_iterator brushPlane = faceList.begin(); brushPlane != faceList.end(); brushPlane++ ) + for ( std::list::const_iterator brushPlane = faceList.begin(); brushPlane != faceList.end(); brushPlane++ ) { if ( **brushPlane == *chkPlane ) { return *brushPlane; @@@ -325,26 -313,26 +325,26 @@@ bool DBrush::IsCutByPlane( DPlane *cutt if ( pointList.size() == 0 ) { if ( BuildPoints() == 0 ) { - return FALSE; + return false; } } - list::const_iterator chkPnt = pointList.begin(); + std::list::const_iterator chkPnt = pointList.begin(); if ( chkPnt == pointList.end() ) { - return FALSE; + return false; } float dist = cuttingPlane->DistanceToPoint( ( *chkPnt )->_pnt ); if ( dist > MAX_ROUND_ERROR ) { - isInFront = FALSE; + isInFront = false; } else if ( dist < MAX_ROUND_ERROR ) { - isInFront = TRUE; + isInFront = true; } else{ - return TRUE; + return true; } for ( chkPnt++ = pointList.begin(); chkPnt != pointList.end(); chkPnt++ ) @@@ -353,31 -341,30 +353,31 @@@ if ( dist > MAX_ROUND_ERROR ) { if ( isInFront ) { - return TRUE; + return true; } } else if ( dist < MAX_ROUND_ERROR ) { if ( !isInFront ) { - return TRUE; + return true; } } else{ - return TRUE; + return true; } } - return FALSE; + return false; } -brush_t* DBrush::BuildInRadiant( bool allowDestruction, int* changeCnt, entity_t* entity ){ + +scene::Node* DBrush::BuildInRadiant( bool allowDestruction, int* changeCnt, scene::Node* entity ){ if ( allowDestruction ) { - bool kill = TRUE; + bool kill = true; - for ( list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) + for ( std::list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) { if ( ( *chkPlane )->m_bChkOk ) { - kill = FALSE; + kill = false; break; } } @@@ -388,30 -375,29 +388,30 @@@ //+djbob: fixed bug when brush had no faces "phantom brush" in radiant. if ( faceList.size() < 4 ) { - Sys_Printf( "Possible Phantom Brush Found, will not rebuild\n" ); + globalErrorStream() << "Possible Phantom Brush Found, will not rebuild\n"; return NULL; } //-djbob - QER_brush = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle(); + NodeSmartReference node( GlobalBrushCreator().createBrush() ); - for ( list::const_iterator buildPlane = faceList.begin(); buildPlane != faceList.end(); buildPlane++ ) { - if ( ( *buildPlane )->AddToBrush_t( QER_brush ) && changeCnt ) { + for ( std::list::const_iterator buildPlane = faceList.begin(); buildPlane != faceList.end(); buildPlane++ ) { + if ( ( *buildPlane )->AddToBrush( node ) && changeCnt ) { ( *changeCnt )++; } } if ( entity ) { - g_FuncTable.m_pfnCommitBrushHandleToEntity( QER_brush, entity ); - g_BrushTable.m_pfnBrush_Build( QER_brush, false, false, false, false ); - g_BrushTable.m_pfnBrush_AddToList( QER_brush, g_AppDataTable.m_pfnSelectedBrushes() ); + Node_getTraversable( *entity )->insert( node ); } else { - g_FuncTable.m_pfnCommitBrushHandle( QER_brush ); + Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( node ); } - return QER_brush; + QER_entity = entity; + QER_brush = node.get_pointer(); + + return node.get_pointer(); } void DBrush::CutByPlane( DPlane *cutPlane, DBrush **newBrush1, DBrush **newBrush2 ){ @@@ -424,7 -410,7 +424,7 @@@ DBrush* b1 = new DBrush; DBrush* b2 = new DBrush; - for ( list::const_iterator parsePlane = faceList.begin(); parsePlane != faceList.end(); parsePlane++ ) + for ( std::list::const_iterator parsePlane = faceList.begin(); parsePlane != faceList.end(); parsePlane++ ) { b1->AddFace( ( *parsePlane )->points[0], ( *parsePlane )->points[1], ( *parsePlane )->points[2], NULL ); b2->AddFace( ( *parsePlane )->points[0], ( *parsePlane )->points[1], ( *parsePlane )->points[2], NULL ); @@@ -443,60 -429,60 +443,60 @@@ bool DBrush::IntersectsWith( DBrush *chkBrush ){ if ( pointList.size() == 0 ) { if ( BuildPoints() == 0 ) { - return FALSE; // invalid brush!!!! + return false; // invalid brush!!!! } } if ( chkBrush->pointList.size() == 0 ) { if ( chkBrush->BuildPoints() == 0 ) { - return FALSE; // invalid brush!!!! + return false; // invalid brush!!!! } } if ( !BBoxCollision( chkBrush ) ) { - return FALSE; + return false; } - list::const_iterator iplPlane; + std::list::const_iterator iplPlane; for ( iplPlane = faceList.begin(); iplPlane != faceList.end(); iplPlane++ ) { - bool allInFront = TRUE; - for ( list::const_iterator iPoint = chkBrush->pointList.begin(); iPoint != chkBrush->pointList.end(); iPoint++ ) + bool allInFront = true; + for ( std::list::const_iterator iPoint = chkBrush->pointList.begin(); iPoint != chkBrush->pointList.end(); iPoint++ ) { if ( ( *iplPlane )->DistanceToPoint( ( *iPoint )->_pnt ) < -MAX_ROUND_ERROR ) { - allInFront = FALSE; + allInFront = false; break; } } if ( allInFront ) { - return FALSE; + return false; } } for ( iplPlane = chkBrush->faceList.begin(); iplPlane != chkBrush->faceList.end(); iplPlane++ ) { - bool allInFront = TRUE; - for ( list::const_iterator iPoint = pointList.begin(); iPoint != pointList.end(); iPoint++ ) + bool allInFront = true; + for ( std::list::const_iterator iPoint = pointList.begin(); iPoint != pointList.end(); iPoint++ ) { if ( ( *iplPlane )->DistanceToPoint( ( *iPoint )->_pnt ) < -MAX_ROUND_ERROR ) { - allInFront = FALSE; + allInFront = false; break; } } if ( allInFront ) { - return FALSE; + return false; } } - return TRUE; + return true; } bool DBrush::IntersectsWith( DPlane* p1, DPlane* p2, vec3_t v ) { vec3_t vDown = { 0, 0, -1 }; - list::const_iterator iplPlane; + std::list::const_iterator iplPlane; for ( iplPlane = faceList.begin(); iplPlane != faceList.end(); iplPlane++ ) { DPlane* p = ( *iplPlane ); @@@ -506,12 -492,12 +506,12 @@@ } if ( p->PlaneIntersection( p1, p2, v ) ) { if ( PointPosition( v ) != POINT_OUT_BRUSH ) { - return TRUE; + return true; } } } - return FALSE; + return false; } void DBrush::BuildBounds(){ @@@ -522,11 -508,11 +522,11 @@@ } } - list::const_iterator first = pointList.begin(); + std::list::const_iterator first = pointList.begin(); VectorCopy( ( *first )->_pnt, bbox_min ); VectorCopy( ( *first )->_pnt, bbox_max ); - list::const_iterator point = pointList.begin(); + std::list::const_iterator point = pointList.begin(); for ( point++; point != pointList.end(); point++ ) { if ( ( *point )->_pnt[0] > bbox_max[0] ) { @@@ -550,7 -536,7 +550,7 @@@ } } - bBoundsBuilt = TRUE; + bBoundsBuilt = true; } } @@@ -562,23 -548,23 +562,23 @@@ bool DBrush::BBoxTouch( DBrush *chkBrus chkBrush->GetBounds( min2, max2 ); if ( ( min1[0] - max2[0] ) > MAX_ROUND_ERROR ) { - return FALSE; + return false; } if ( ( min1[1] - max2[1] ) > MAX_ROUND_ERROR ) { - return FALSE; + return false; } if ( ( min1[2] - max2[2] ) > MAX_ROUND_ERROR ) { - return FALSE; + return false; } if ( ( min2[0] - max1[0] ) > MAX_ROUND_ERROR ) { - return FALSE; + return false; } if ( ( min2[1] - max1[1] ) > MAX_ROUND_ERROR ) { - return FALSE; + return false; } if ( ( min2[2] - max1[2] ) > MAX_ROUND_ERROR ) { - return FALSE; + return false; } int cnt = 0; @@@ -608,22 -594,22 +608,22 @@@ } if ( cnt > 1 ) { - return FALSE; + return false; } - return TRUE; + return true; } -void DBrush::ResetChecks( list* exclusionList ){ - for ( list::const_iterator resetPlane = faceList.begin(); resetPlane != faceList.end(); resetPlane++ ) +void DBrush::ResetChecks( std::list* exclusionList ){ + for ( std::list::const_iterator resetPlane = faceList.begin(); resetPlane != faceList.end(); resetPlane++ ) { - bool set = FALSE; + bool set = false; if ( exclusionList ) { - for ( list::iterator eTexture = exclusionList->begin(); eTexture != exclusionList->end(); eTexture++ ) + for ( std::list::iterator eTexture = exclusionList->begin(); eTexture != exclusionList->end(); eTexture++ ) { - if ( strstr( ( *resetPlane )->texInfo.m_TextureName, eTexture->GetBuffer() ) ) { - set = TRUE; + if ( strstr( ( *resetPlane )->m_shader.c_str(), eTexture->GetBuffer() ) ) { + set = true; break; } } @@@ -634,7 -620,7 +634,7 @@@ } DPlane* DBrush::HasPlaneInverted( DPlane *chkPlane ){ - for ( list::const_iterator brushPlane = faceList.begin(); brushPlane != faceList.end(); brushPlane++ ) + for ( std::list::const_iterator brushPlane = faceList.begin(); brushPlane != faceList.end(); brushPlane++ ) { if ( **brushPlane != *chkPlane ) { if ( fabs( ( *brushPlane )->_d + chkPlane->_d ) < 0.1 ) { @@@ -646,30 -632,30 +646,30 @@@ } bool DBrush::HasTexture( const char *textureName ){ - for ( list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) + for ( std::list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) { - if ( strstr( ( *chkPlane )->texInfo.m_TextureName, textureName ) ) { - return TRUE; + if ( strstr( ( *chkPlane )->m_shader.c_str(), textureName ) ) { + return true; } } - return FALSE; + return false; } bool DBrush::IsDetail(){ - for ( list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) + for ( std::list::const_iterator chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) { - if ( ( *chkPlane )->texInfo.m_nContents & FACE_DETAIL ) { - return TRUE; + if ( ( *chkPlane )->texInfo.contents & FACE_DETAIL ) { + return true; } } - return FALSE; + return false; } void DBrush::BuildFromWinding( DWinding *w ){ if ( w->numpoints < 3 ) { - Sys_ERROR( "Winding has invalid number of points" ); + globalErrorStream() << "Winding has invalid number of points"; return; } @@@ -695,7 -681,7 +695,7 @@@ void DBrush::SaveToFile( FILE *pFile ){ fprintf( pFile, "{\n" ); - for ( list::const_iterator pp = faceList.begin(); pp != faceList.end(); pp++ ) + for ( std::list::const_iterator pp = faceList.begin(); pp != faceList.end(); pp++ ) { char buffer[512]; @@@ -703,19 -689,19 +703,19 @@@ ( *pp )->points[0][0], ( *pp )->points[0][1], ( *pp )->points[0][2], ( *pp )->points[1][0], ( *pp )->points[1][1], ( *pp )->points[1][2], ( *pp )->points[2][0], ( *pp )->points[2][1], ( *pp )->points[2][2], - ( *pp )->texInfo.m_TextureName, - ( *pp )->texInfo.m_fShift[0], ( *pp )->texInfo.m_fShift[1], - ( *pp )->texInfo.m_fScale[0], ( *pp )->texInfo.m_fScale[0], - ( *pp )->texInfo.m_fRotate ); + ( *pp )->m_shader.c_str(), + ( *pp )->texInfo.m_texdef.shift[0], ( *pp )->texInfo.m_texdef.shift[1], + ( *pp )->texInfo.m_texdef.scale[0], ( *pp )->texInfo.m_texdef.scale[0], + ( *pp )->texInfo.m_texdef.rotate ); - fprintf( pFile, buffer ); + fprintf( pFile, "%s", buffer ); } fprintf( pFile, "}\n" ); } void DBrush::Rotate( vec3_t vOrigin, vec3_t vRotation ){ - for ( list::const_iterator rotPlane = faceList.begin(); rotPlane != faceList.end(); rotPlane++ ) + for ( std::list::const_iterator rotPlane = faceList.begin(); rotPlane != faceList.end(); rotPlane++ ) { for ( int i = 0; i < 3; i++ ) VectorRotate( ( *rotPlane )->points[i], vRotation, vOrigin ); @@@ -736,89 -722,89 +736,89 @@@ void DBrush::RotateAboutCentre( vec3_t bool DBrush::ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, int bResetTextureName, int bResetScale[2], int bResetShift[2], int bResetRotation ){ if ( textureName ) { - bool changed = FALSE; - for ( list::const_iterator resetPlane = faceList.begin(); resetPlane != faceList.end(); resetPlane++ ) + bool changed = false; + for ( std::list::const_iterator resetPlane = faceList.begin(); resetPlane != faceList.end(); resetPlane++ ) { - if ( !strcmp( ( *resetPlane )->texInfo.m_TextureName, textureName ) ) { + if ( !strcmp( ( *resetPlane )->m_shader.c_str(), textureName ) ) { if ( bResetTextureName ) { - strcpy( ( *resetPlane )->texInfo.m_TextureName, newTextureName ); + ( *resetPlane )->m_shader = newTextureName; } if ( bResetScale[0] ) { - ( *resetPlane )->texInfo.m_fScale[0] = fScale[0]; + ( *resetPlane )->texInfo.m_texdef.scale[0] = fScale[0]; } if ( bResetScale[1] ) { - ( *resetPlane )->texInfo.m_fScale[1] = fScale[1]; + ( *resetPlane )->texInfo.m_texdef.scale[1] = fScale[1]; } if ( bResetShift[0] ) { - ( *resetPlane )->texInfo.m_fShift[0] = fShift[0]; + ( *resetPlane )->texInfo.m_texdef.shift[0] = fShift[0]; } if ( bResetShift[1] ) { - ( *resetPlane )->texInfo.m_fShift[1] = fShift[1]; + ( *resetPlane )->texInfo.m_texdef.shift[1] = fShift[1]; } if ( bResetRotation ) { - ( *resetPlane )->texInfo.m_fRotate = (float)rotation; + ( *resetPlane )->texInfo.m_texdef.rotate = (float)rotation; } - changed = TRUE; + changed = true; } } return changed; // no point rebuilding unless we need to, only slows things down } else { - for ( list::const_iterator resetPlane = faceList.begin(); resetPlane != faceList.end(); resetPlane++ ) + for ( std::list::const_iterator resetPlane = faceList.begin(); resetPlane != faceList.end(); resetPlane++ ) { if ( bResetTextureName ) { - strcpy( ( *resetPlane )->texInfo.m_TextureName, newTextureName ); + ( *resetPlane )->m_shader = newTextureName; } if ( bResetScale[0] ) { - ( *resetPlane )->texInfo.m_fScale[0] = fScale[0]; + ( *resetPlane )->texInfo.m_texdef.scale[0] = fScale[0]; } if ( bResetScale[1] ) { - ( *resetPlane )->texInfo.m_fScale[1] = fScale[1]; + ( *resetPlane )->texInfo.m_texdef.scale[1] = fScale[1]; } if ( bResetShift[0] ) { - ( *resetPlane )->texInfo.m_fShift[0] = fShift[0]; + ( *resetPlane )->texInfo.m_texdef.shift[0] = fShift[0]; } if ( bResetShift[1] ) { - ( *resetPlane )->texInfo.m_fShift[1] = fShift[1]; + ( *resetPlane )->texInfo.m_texdef.shift[1] = fShift[1]; } if ( bResetRotation ) { - ( *resetPlane )->texInfo.m_fRotate = (float)rotation; + ( *resetPlane )->texInfo.m_texdef.rotate = (float)rotation; } } - return TRUE; + return true; } } bool DBrush::operator ==( DBrush* other ){ - list::const_iterator chkPlane; + std::list::const_iterator chkPlane; for ( chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) { if ( !other->HasPlane( ( *chkPlane ) ) ) { - return FALSE; + return false; } } for ( chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) { if ( !HasPlane( ( *chkPlane ) ) ) { - return FALSE; + return false; } } - return TRUE; + return true; } -DPlane* DBrush::AddFace( vec3_t va, vec3_t vb, vec3_t vc, const char *textureName, bool bDetail ){ - bBoundsBuilt = FALSE; +DPlane* DBrush::AddFace( const vec3_t va, const vec3_t vb, const vec3_t vc, const char *textureName, bool bDetail ){ + bBoundsBuilt = false; DPlane* newFace = new DPlane( va, vb, vc, textureName, bDetail ); faceList.push_back( newFace ); @@@ -828,7 -814,7 +828,7 @@@ DPlane* DBrush::FindPlaneWithClosestNormal( vec_t* normal ) { vec_t bestDot = -2; DPlane* bestDotPlane = NULL; - list::const_iterator chkPlane; + std::list::const_iterator chkPlane; for ( chkPlane = faceList.begin(); chkPlane != faceList.end(); chkPlane++ ) { DPlane* pPlane = ( *chkPlane ); @@@ -851,7 -837,7 +851,7 @@@ int DBrush::FindPointsForPlane( DPlane BuildPoints(); - for ( list::const_iterator points = pointList.begin(); points != pointList.end(); points++ ) { + for ( std::list::const_iterator points = pointList.begin(); points != pointList.end(); points++ ) { DPoint* point = ( *points ); if ( fabs( plane->DistanceToPoint( point->_pnt ) ) < MAX_ROUND_ERROR ) { @@@ -869,11 -855,17 +869,11 @@@ } void DBrush::RemovePlane( DPlane* plane ) { - bBoundsBuilt = FALSE; - for ( list::const_iterator deadPlane = faceList.begin(); deadPlane != faceList.end(); deadPlane++ ) { + bBoundsBuilt = false; + for ( std::list::const_iterator deadPlane = faceList.begin(); deadPlane != faceList.end(); deadPlane++ ) { if ( *deadPlane == plane ) { delete *deadPlane; faceList.remove( plane ); } } } - -void DBrush::RemoveFromRadiant( void ) { - if ( QER_brush ) { - g_FuncTable.m_pfnDeleteBrushHandle( QER_brush ); - } -} diff --combined libs/splines/splines.cpp index 42c34939,b9b7c0c9..05cb3bf9 --- a/libs/splines/splines.cpp +++ b/libs/splines/splines.cpp @@@ -1,5 -1,5 +1,5 @@@ /* - Copyright (C) 1999-2007 id Software, Inc. and contributors. + Copyright (C) 1999-2006 Id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. @@@ -96,17 -96,17 +96,17 @@@ idCameraDef *g_splineList = &splineList idVec3 idSplineList::zero( 0,0,0 ); void glLabeledPoint( idVec3 &color, idVec3 &point, float size, const char *label ) { - qglColor3fv( color ); - qglPointSize( size ); - qglBegin( GL_POINTS ); - qglVertex3fv( point ); - qglEnd(); + glColor3fv( color ); + glPointSize( size ); + glBegin( GL_POINTS ); + glVertex3fv( point ); + glEnd(); idVec3 v = point; v.x += 1; v.y += 1; v.z += 1; - qglRasterPos3fv( v ); - qglCallLists( strlen( label ), GL_UNSIGNED_BYTE, label ); + glRasterPos3fv( v ); + glCallLists( strlen( label ), GL_UNSIGNED_BYTE, label ); } @@@ -119,30 -119,30 +119,30 @@@ void glBox( idVec3 &color, idVec3 &poin maxs[0] += size; maxs[1] -= size; maxs[2] += size; - qglColor3fv( color ); - qglBegin( GL_LINE_LOOP ); - qglVertex3f( mins[0],mins[1],mins[2] ); - qglVertex3f( maxs[0],mins[1],mins[2] ); - qglVertex3f( maxs[0],maxs[1],mins[2] ); - qglVertex3f( mins[0],maxs[1],mins[2] ); - qglEnd(); - qglBegin( GL_LINE_LOOP ); - qglVertex3f( mins[0],mins[1],maxs[2] ); - qglVertex3f( maxs[0],mins[1],maxs[2] ); - qglVertex3f( maxs[0],maxs[1],maxs[2] ); - qglVertex3f( mins[0],maxs[1],maxs[2] ); - qglEnd(); - - qglBegin( GL_LINES ); - qglVertex3f( mins[0],mins[1],mins[2] ); - qglVertex3f( mins[0],mins[1],maxs[2] ); - qglVertex3f( mins[0],maxs[1],maxs[2] ); - qglVertex3f( mins[0],maxs[1],mins[2] ); - qglVertex3f( maxs[0],mins[1],mins[2] ); - qglVertex3f( maxs[0],mins[1],maxs[2] ); - qglVertex3f( maxs[0],maxs[1],maxs[2] ); - qglVertex3f( maxs[0],maxs[1],mins[2] ); - qglEnd(); + glColor3fv( color ); + glBegin( GL_LINE_LOOP ); + glVertex3f( mins[0],mins[1],mins[2] ); + glVertex3f( maxs[0],mins[1],mins[2] ); + glVertex3f( maxs[0],maxs[1],mins[2] ); + glVertex3f( mins[0],maxs[1],mins[2] ); + glEnd(); + glBegin( GL_LINE_LOOP ); + glVertex3f( mins[0],mins[1],maxs[2] ); + glVertex3f( maxs[0],mins[1],maxs[2] ); + glVertex3f( maxs[0],maxs[1],maxs[2] ); + glVertex3f( mins[0],maxs[1],maxs[2] ); + glEnd(); + + glBegin( GL_LINES ); + glVertex3f( mins[0],mins[1],mins[2] ); + glVertex3f( mins[0],mins[1],maxs[2] ); + glVertex3f( mins[0],maxs[1],maxs[2] ); + glVertex3f( mins[0],maxs[1],mins[2] ); + glVertex3f( maxs[0],mins[1],mins[2] ); + glVertex3f( maxs[0],mins[1],maxs[2] ); + glVertex3f( maxs[0],maxs[1],maxs[2] ); + glVertex3f( maxs[0],maxs[1],mins[2] ); + glEnd(); } @@@ -256,14 -256,14 +256,14 @@@ void idSplineList::draw( bool editMode } - qglColor3fv( controlColor ); - qglPointSize( 5 ); + glColor3fv( controlColor ); + glPointSize( 5 ); - qglBegin( GL_POINTS ); + glBegin( GL_POINTS ); for ( i = 0; i < controlPoints.Num(); i++ ) { - qglVertex3fv( *controlPoints[i] ); + glVertex3fv( *controlPoints[i] ); } - qglEnd(); + glEnd(); if ( editMode ) { for ( i = 0; i < controlPoints.Num(); i++ ) { @@@ -272,22 -272,22 +272,22 @@@ } //Draw the curve - qglColor3fv( pathColor ); - qglBegin( GL_LINE_STRIP ); + glColor3fv( pathColor ); + glBegin( GL_LINE_STRIP ); int count = splinePoints.Num(); for ( i = 0; i < count; i++ ) { - qglVertex3fv( *splinePoints[i] ); + glVertex3fv( *splinePoints[i] ); } - qglEnd(); + glEnd(); if ( editMode ) { - qglColor3fv( segmentColor ); - qglPointSize( 3 ); - qglBegin( GL_POINTS ); + glColor3fv( segmentColor ); + glPointSize( 3 ); + glBegin( GL_POINTS ); for ( i = 0; i < count; i++ ) { - qglVertex3fv( *splinePoints[i] ); + glVertex3fv( *splinePoints[i] ); } - qglEnd(); + glEnd(); } if ( count > 0 ) { //assert(activeSegment >=0 && activeSegment < count); @@@ -393,7 -393,6 +393,6 @@@ void idSplineList::setSelectedPoint( id const idVec3 *idSplineList::getPosition( long t ) { static idVec3 interpolatedPos; - static long lastTime = -1; int count = splineTime.Num(); if ( count == 0 ) { @@@ -644,7 -643,6 +643,6 @@@ bool idCameraDef::waitEvent( int index void idCameraDef::buildCamera() { int i; - int lastSwitch = 0; idList waits; idList targets; @@@ -653,7 -651,6 +651,6 @@@ // we have a base time layout for the path and the target path // now we need to layer on any wait or speed changes for ( i = 0; i < events.Num(); i++ ) { - idCameraEvent *ev = events[i]; events[i]->setTriggered( false ); switch ( events[i]->getType() ) { case idCameraEvent::EVENT_TARGET: { @@@ -864,7 -861,8 +861,8 @@@ void idCameraDef::parse( const char *( bool idCameraDef::load( const char *filename ) { char *buf; const char *buf_p; - int length = FS_ReadFile( filename, (void **)&buf ); + + FS_ReadFile( filename, (void **)&buf ); if ( !buf ) { return false; } @@@ -1363,7 -1361,6 +1361,6 @@@ void idSplinePosition::write( fileHandl } void idCameraDef::addTarget( const char *name, idCameraPosition::positionType type ) { - const char *text = ( name == NULL ) ? va( "target0%d", numTargets() + 1 ) : name; idCameraPosition *pos = newFromType( type ); if ( pos ) { pos->setName( name ); diff --combined libs/splines/util_str.cpp index 8ac9dea3,52a01a36..62fdaedc --- a/libs/splines/util_str.cpp +++ b/libs/splines/util_str.cpp @@@ -1,5 -1,5 +1,5 @@@ /* - Copyright (C) 1999-2007 id Software, Inc. and contributors. + Copyright (C) 1999-2006 Id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. @@@ -487,9 -487,6 +487,6 @@@ void TestStringClas i = a.length(); // i == 0 i = c.length(); // i == 4 - const char *s1 = a.c_str(); // s1 == "\0" - const char *s2 = c.c_str(); // s2 == "test\0" - t = new idStr(); // t->len == 0, t->data == "\0" delete t; // t == ? diff --combined tools/quake3/common/cmdlib.c index 5164001c,35f4d75b..41fd1ca1 --- a/tools/quake3/common/cmdlib.c +++ b/tools/quake3/common/cmdlib.c @@@ -1,5 -1,5 +1,5 @@@ /* - Copyright (C) 1999-2007 id Software, Inc. and contributors. + Copyright (C) 1999-2006 Id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. @@@ -34,7 -34,7 +34,7 @@@ #include #include -#ifdef _WIN32 +#ifdef WIN32 #include #include #endif @@@ -188,7 -188,7 +188,7 @@@ void SetQdirFromPath( const char *path } strncpy( qdir, path, c + len + count - path ); Sys_Printf( "qdir: %s\n", qdir ); - for ( i = 0; i < strlen( qdir ); i++ ) + for ( i = 0; i < (int) strlen( qdir ); i++ ) { if ( qdir[i] == '\\' ) { qdir[i] = '/'; @@@ -201,7 -201,7 +201,7 @@@ if ( *c == '/' || *c == '\\' ) { strncpy( gamedir, path, c + 1 - path ); - for ( i = 0; i < strlen( gamedir ); i++ ) + for ( i = 0; i < (int) strlen( gamedir ); i++ ) { if ( gamedir[i] == '\\' ) { gamedir[i] = '/'; @@@ -244,7 -244,10 +244,10 @@@ char *ExpandArg( const char *path ) char *ExpandPath( const char *path ){ static char full[1024]; - if ( !*qdir || path[0] == '/' || path[0] == '\\' || path[1] == ':' ) { - if ( !qdir[0] ) { ++ if ( !qdir ) { + Error( "ExpandPath called without qdir set" ); + } + if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) { strcpy( full, path ); return full; } @@@ -254,8 -257,8 +257,8 @@@ char *ExpandGamePath( const char *path ){ static char full[1024]; - if ( !*gamedir ) { - if ( !qdir[0] ) { - Error( "ExpandGamePath called without qdir set" ); ++ if ( !gamedir[0] ) { + Error( "ExpandGamePath called without gamedir set" ); } if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) { strcpy( full, path ); @@@ -324,9 -327,7 +327,9 @@@ void Q_getwd( char *out ) strcat( out, "\\" ); #else // Gef: Changed from getwd() to getcwd() to avoid potential buffer overflow - getcwd( out, 256 ); + if ( !getcwd( out, 256 ) ) { + *out = 0; + } strcat( out, "/" ); #endif while ( out[i] != 0 ) @@@ -340,42 -341,15 +343,42 @@@ void Q_mkdir( const char *path ){ + char parentbuf[256]; + const char *p = NULL; + int retry = 2; + while ( retry-- ) + { #ifdef WIN32 - if ( _mkdir( path ) != -1 ) { - return; - } + const char *q = NULL; + if ( _mkdir( path ) != -1 ) { + return; + } + if ( errno == ENOENT ) { + p = strrchr( path, '/' ); + q = strrchr( path, '\\' ); + if ( q && ( !p || q < p ) ) { + p = q; + } + } #else - if ( mkdir( path, 0777 ) != -1 ) { - return; - } + if ( mkdir( path, 0777 ) != -1 ) { + return; + } + if ( errno == ENOENT ) { + p = strrchr( path, '/' ); + } #endif + if ( p ) { + strncpy( parentbuf, path, sizeof( parentbuf ) ); + if ( (int) ( p - path ) < (int) sizeof( parentbuf ) ) { + parentbuf[p - path] = 0; + Sys_Printf( "mkdir: %s: creating parent %s first\n", path, parentbuf ); + Q_mkdir( parentbuf ); + continue; + } + } + break; + } if ( errno != EEXIST ) { Error( "mkdir %s: %s",path, strerror( errno ) ); } diff --combined tools/quake3/common/cmdlib.h index 3c9b5a54,3fb98feb..f6f5e4d1 --- a/tools/quake3/common/cmdlib.h +++ b/tools/quake3/common/cmdlib.h @@@ -1,5 -1,5 +1,5 @@@ /* - Copyright (C) 1999-2007 id Software, Inc. and contributors. + Copyright (C) 1999-2006 Id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. @@@ -53,11 -53,7 +53,11 @@@ #endif +#ifdef PATH_MAX +#define MAX_OS_PATH PATH_MAX +#else - #define MAX_OS_PATH 1024 + #define MAX_OS_PATH 4096 +#endif #define MEM_BLOCKSIZE 4096 // the dec offsetof macro doesnt work very well... @@@ -99,11 -95,7 +99,11 @@@ void ExpandWildcards( int *argc, char * double I_FloatTime( void ); -void Error( const char *error, ... ); +void Error( const char *error, ... ) +#ifdef __GNUC__ +__attribute__( ( noreturn ) ) +#endif +; int CheckParm( const char *check ); FILE *SafeOpenWrite( const char *filename ); diff --combined tools/quake3/common/inout.c index 6920995f,7adbf23e..2c1758a7 --- a/tools/quake3/common/inout.c +++ b/tools/quake3/common/inout.c @@@ -1,5 -1,5 +1,5 @@@ /* - Copyright (C) 1999-2007 id Software, Inc. and contributors. + Copyright (C) 1999-2006 Id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. @@@ -43,6 -43,7 +43,7 @@@ #include "libxml/tree.h" // utf8 conversion + #include #include #include @@@ -70,8 -71,8 +71,8 @@@ xmlNodePtr xml_NodeForVec( vec3_t v ) char buf[1024]; sprintf( buf, "%f %f %f", v[0], v[1], v[2] ); - ret = xmlNewNode( NULL, "point" ); - xmlNodeSetContent( ret, buf ); + ret = xmlNewNode( NULL, (xmlChar*)"point" ); + xmlNodeSetContent( ret, (xmlChar*)buf ); return ret; } @@@ -93,7 -94,7 +94,7 @@@ void xml_SendNode( xmlNodePtr node ) // l_net library defines an upper limit of MAX_NETMESSAGE // there are some size check errors, so we use MAX_NETMESSAGE-10 to be safe // if the size of the buffer exceeds MAX_NETMESSAGE-10 we'll send in several network messages - while ( pos < xml_buf->use ) + while ( pos < (int)xml_buf->use ) { // what size are we gonna send now? ( xml_buf->use - pos < MAX_NETMESSAGE - 10 ) ? ( size = xml_buf->use - pos ) : ( size = MAX_NETMESSAGE - 10 ); @@@ -148,15 -149,15 +149,15 @@@ void xml_Select( char *msg, int entityn // now build a proper "select" XML node sprintf( buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg ); - node = xmlNewNode( NULL, "select" ); - xmlNodeSetContent( node, buf ); + node = xmlNewNode( NULL, (xmlChar*)"select" ); + xmlNodeSetContent( node, (xmlChar*)buf ); level[0] = (int)'0' + ( bError ? SYS_ERR : SYS_WRN ) ; level[1] = 0; - xmlSetProp( node, "level", (char *)&level ); + xmlSetProp( node, (xmlChar*)"level", (xmlChar *)&level ); // a 'select' information sprintf( buf, "%i %i", entitynum, brushnum ); - select = xmlNewNode( NULL, "brush" ); - xmlNodeSetContent( select, buf ); + select = xmlNewNode( NULL, (xmlChar*)"brush" ); + xmlNodeSetContent( select, (xmlChar*)buf ); xmlAddChild( node, select ); xml_SendNode( node ); @@@ -175,15 -176,15 +176,15 @@@ void xml_Point( char *msg, vec3_t pt ) char buf[1024]; char level[2]; - node = xmlNewNode( NULL, "pointmsg" ); - xmlNodeSetContent( node, msg ); + node = xmlNewNode( NULL, (xmlChar*)"pointmsg" ); + xmlNodeSetContent( node, (xmlChar*)msg ); level[0] = (int)'0' + SYS_ERR; level[1] = 0; - xmlSetProp( node, "level", (char *)&level ); + xmlSetProp( node, (xmlChar*)"level", (xmlChar *)&level ); // a 'point' node sprintf( buf, "%g %g %g", pt[0], pt[1], pt[2] ); - point = xmlNewNode( NULL, "point" ); - xmlNodeSetContent( point, buf ); + point = xmlNewNode( NULL, (xmlChar*)"point" ); + xmlNodeSetContent( point, (xmlChar*)buf ); xmlAddChild( node, point ); xml_SendNode( node ); @@@ -199,11 -200,11 +200,11 @@@ void xml_Winding( char *msg, vec3_t p[] char level[2]; int i; - node = xmlNewNode( NULL, "windingmsg" ); - xmlNodeSetContent( node, msg ); + node = xmlNewNode( NULL, (xmlChar*)"windingmsg" ); + xmlNodeSetContent( node, (xmlChar*)msg ); level[0] = (int)'0' + SYS_ERR; level[1] = 0; - xmlSetProp( node, "level", (char *)&level ); + xmlSetProp( node, (xmlChar*)"level", (xmlChar *)&level ); // a 'winding' node sprintf( buf, "%i ", numpoints ); for ( i = 0; i < numpoints; i++ ) @@@ -216,8 -217,8 +217,8 @@@ strcat( buf, smlbuf ); } - winding = xmlNewNode( NULL, "winding" ); - xmlNodeSetContent( winding, buf ); + winding = xmlNewNode( NULL, (xmlChar*)"winding" ); + xmlNodeSetContent( winding, (xmlChar*)buf ); xmlAddChild( node, winding ); xml_SendNode( node ); @@@ -239,7 -240,7 +240,7 @@@ void Broadcast_Setup( const char *dest char sMsg[1024]; Net_Setup(); - Net_StringToAddress( (char *)dest, &address ); + Net_StringToAddress( dest, &address ); brdcst_socket = Net_Connect( &address, 0 ); if ( brdcst_socket ) { // send in a header @@@ -281,19 -282,19 +282,19 @@@ void FPrintf( int flag, char *buf ) */ if ( !bGotXML ) { // initialize - doc = xmlNewDoc( "1.0" ); - doc->children = xmlNewDocRawNode( doc, NULL, "q3map_feedback", NULL ); + doc = xmlNewDoc( (xmlChar*)"1.0" ); + doc->children = xmlNewDocRawNode( doc, NULL, (xmlChar*)"q3map_feedback", NULL ); bGotXML = qtrue; } - node = xmlNewNode( NULL, "message" ); + node = xmlNewNode( NULL, (xmlChar*)"message" ); { gchar* utf8 = g_locale_to_utf8( buf, -1, NULL, NULL, NULL ); - xmlNodeSetContent( node, utf8 ); + xmlNodeSetContent( node, (xmlChar*)utf8 ); g_free( utf8 ); } level[0] = (int)'0' + flag; level[1] = 0; - xmlSetProp( node, "level", (char *)&level ); + xmlSetProp( node, (xmlChar*)"level", (xmlChar *)&level ); xml_SendNode( node ); } diff --combined tools/quake3/q3map2/main.c index b53a6973,e74a89cf..76591a2a --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@@ -1,4 -1,4 +1,4 @@@ -/* ------------------------------------------------------------------------------- +/* -------------------------------------------------------------------------------; Copyright (C) 1999-2007 id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. @@@ -36,8 -36,6 +36,8 @@@ /* dependencies */ #include "q3map2.h" + + /* Random() returns a pseudorandom number between 0 and 1 @@@ -48,6 -46,38 +48,38 @@@ vec_t Random( void ) } + char *Q_strncpyz( char *dst, const char *src, size_t len ) { + if ( len == 0 ) { + abort(); + } + + strncpy( dst, src, len ); + dst[ len - 1 ] = '\0'; + return dst; + } + + + char *Q_strcat( char *dst, size_t dlen, const char *src ) { + size_t n = strlen( dst ); + + if ( n > dlen ) { + abort(); /* buffer overflow */ + } + + return Q_strncpyz( dst + n, src, dlen - n ); + } + + + char *Q_strncat( char *dst, size_t dlen, const char *src, size_t slen ) { + size_t n = strlen( dst ); + + if ( n > dlen ) { + abort(); /* buffer overflow */ + } + + return Q_strncpyz( dst + n, src, MIN( slen, dlen - n ) ); + } + /* ExitQ3Map() @@@ -61,765 -91,17 +93,765 @@@ static void ExitQ3Map( void ) } } -static int MD4BlockChecksum( void * buffer, int length ) { - unsigned char digest[16]; - int checksum; - md4_get_digest( buffer, length, digest ); - /* I suppose it has to be done that way for legacy reasons? */ - checksum = digest[0] & ( digest[1] << 8 ) & ( digest[2] << 16 ) & ( digest[3] << 24 ); - checksum ^= digest[4] & ( digest[5] << 8 ) & ( digest[6] << 16 ) & ( digest[7] << 24 ); - checksum ^= digest[8] & ( digest[9] << 8 ) & ( digest[10] << 16 ) & ( digest[11] << 24 ); - checksum ^= digest[12] & ( digest[13] << 8 ) & ( digest[14] << 16 ) & ( digest[15] << 24 ); - return checksum; + +/* minimap stuff */ + +typedef struct minimap_s +{ + bspModel_t *model; + int width; + int height; + int samples; + float *sample_offsets; + float sharpen_boxmult; + float sharpen_centermult; + float boost, brightness, contrast; + float *data1f; + float *sharpendata1f; + vec3_t mins, size; +} +minimap_t; +static minimap_t minimap; + +qboolean BrushIntersectionWithLine( bspBrush_t *brush, vec3_t start, vec3_t dir, float *t_in, float *t_out ){ + int i; + qboolean in = qfalse, out = qfalse; + bspBrushSide_t *sides = &bspBrushSides[brush->firstSide]; + + for ( i = 0; i < brush->numSides; ++i ) + { + bspPlane_t *p = &bspPlanes[sides[i].planeNum]; + float sn = DotProduct( start, p->normal ); + float dn = DotProduct( dir, p->normal ); + if ( dn == 0 ) { + if ( sn > p->dist ) { + return qfalse; // outside! + } + } + else + { + float t = ( p->dist - sn ) / dn; + if ( dn < 0 ) { + if ( !in || t > *t_in ) { + *t_in = t; + in = qtrue; + // as t_in can only increase, and t_out can only decrease, early out + if ( out && *t_in >= *t_out ) { + return qfalse; + } + } + } + else + { + if ( !out || t < *t_out ) { + *t_out = t; + out = qtrue; + // as t_in can only increase, and t_out can only decrease, early out + if ( in && *t_in >= *t_out ) { + return qfalse; + } + } + } + } + } + return in && out; +} + +static float MiniMapSample( float x, float y ){ + vec3_t org, dir; + int i, bi; + float t0, t1; + float samp; + bspBrush_t *b; + bspBrushSide_t *s; + int cnt; + + org[0] = x; + org[1] = y; + org[2] = 0; + dir[0] = 0; + dir[1] = 0; + dir[2] = 1; + + cnt = 0; + samp = 0; + for ( i = 0; i < minimap.model->numBSPBrushes; ++i ) + { + bi = minimap.model->firstBSPBrush + i; + if ( opaqueBrushes[bi >> 3] & ( 1 << ( bi & 7 ) ) ) { + b = &bspBrushes[bi]; + + // sort out mins/maxs of the brush + s = &bspBrushSides[b->firstSide]; + if ( x < -bspPlanes[s[0].planeNum].dist ) { + continue; + } + if ( x > +bspPlanes[s[1].planeNum].dist ) { + continue; + } + if ( y < -bspPlanes[s[2].planeNum].dist ) { + continue; + } + if ( y > +bspPlanes[s[3].planeNum].dist ) { + continue; + } + + if ( BrushIntersectionWithLine( b, org, dir, &t0, &t1 ) ) { + samp += t1 - t0; + ++cnt; + } + } + } + + return samp; +} + +void RandomVector2f( float v[2] ){ + do + { + v[0] = 2 * Random() - 1; + v[1] = 2 * Random() - 1; + } + while ( v[0] * v[0] + v[1] * v[1] > 1 ); +} + +static void MiniMapRandomlySupersampled( int y ){ + int x, i; + float *p = &minimap.data1f[y * minimap.width]; + float ymin = minimap.mins[1] + minimap.size[1] * ( y / (float) minimap.height ); + float dx = minimap.size[0] / (float) minimap.width; + float dy = minimap.size[1] / (float) minimap.height; + float uv[2]; + float thisval; + + for ( x = 0; x < minimap.width; ++x ) + { + float xmin = minimap.mins[0] + minimap.size[0] * ( x / (float) minimap.width ); + float val = 0; + + for ( i = 0; i < minimap.samples; ++i ) + { + RandomVector2f( uv ); + thisval = MiniMapSample( + xmin + ( uv[0] + 0.5 ) * dx, /* exaggerated random pattern for better results */ + ymin + ( uv[1] + 0.5 ) * dy /* exaggerated random pattern for better results */ + ); + val += thisval; + } + val /= minimap.samples * minimap.size[2]; + *p++ = val; + } +} + +static void MiniMapSupersampled( int y ){ + int x, i; + float *p = &minimap.data1f[y * minimap.width]; + float ymin = minimap.mins[1] + minimap.size[1] * ( y / (float) minimap.height ); + float dx = minimap.size[0] / (float) minimap.width; + float dy = minimap.size[1] / (float) minimap.height; + + for ( x = 0; x < minimap.width; ++x ) + { + float xmin = minimap.mins[0] + minimap.size[0] * ( x / (float) minimap.width ); + float val = 0; + + for ( i = 0; i < minimap.samples; ++i ) + { + float thisval = MiniMapSample( + xmin + minimap.sample_offsets[2 * i + 0] * dx, + ymin + minimap.sample_offsets[2 * i + 1] * dy + ); + val += thisval; + } + val /= minimap.samples * minimap.size[2]; + *p++ = val; + } +} + +static void MiniMapNoSupersampling( int y ){ + int x; + float *p = &minimap.data1f[y * minimap.width]; + float ymin = minimap.mins[1] + minimap.size[1] * ( ( y + 0.5 ) / (float) minimap.height ); + + for ( x = 0; x < minimap.width; ++x ) + { + float xmin = minimap.mins[0] + minimap.size[0] * ( ( x + 0.5 ) / (float) minimap.width ); + *p++ = MiniMapSample( xmin, ymin ) / minimap.size[2]; + } +} + +static void MiniMapSharpen( int y ){ + int x; + qboolean up = ( y > 0 ); + qboolean down = ( y < minimap.height - 1 ); + float *p = &minimap.data1f[y * minimap.width]; + float *q = &minimap.sharpendata1f[y * minimap.width]; + + for ( x = 0; x < minimap.width; ++x ) + { + qboolean left = ( x > 0 ); + qboolean right = ( x < minimap.width - 1 ); + float val = p[0] * minimap.sharpen_centermult; + + if ( left && up ) { + val += p[-1 - minimap.width] * minimap.sharpen_boxmult; + } + if ( left && down ) { + val += p[-1 + minimap.width] * minimap.sharpen_boxmult; + } + if ( right && up ) { + val += p[+1 - minimap.width] * minimap.sharpen_boxmult; + } + if ( right && down ) { + val += p[+1 + minimap.width] * minimap.sharpen_boxmult; + } + + if ( left ) { + val += p[-1] * minimap.sharpen_boxmult; + } + if ( right ) { + val += p[+1] * minimap.sharpen_boxmult; + } + if ( up ) { + val += p[-minimap.width] * minimap.sharpen_boxmult; + } + if ( down ) { + val += p[+minimap.width] * minimap.sharpen_boxmult; + } + + ++p; + *q++ = val; + } +} + +static void MiniMapContrastBoost( int y ){ + int x; + float *q = &minimap.data1f[y * minimap.width]; + for ( x = 0; x < minimap.width; ++x ) + { + *q = *q * minimap.boost / ( ( minimap.boost - 1 ) * *q + 1 ); + ++q; + } +} + +static void MiniMapBrightnessContrast( int y ){ + int x; + float *q = &minimap.data1f[y * minimap.width]; + for ( x = 0; x < minimap.width; ++x ) + { + *q = *q * minimap.contrast + minimap.brightness; + ++q; + } +} + +void MiniMapMakeMinsMaxs( vec3_t mins_in, vec3_t maxs_in, float border, qboolean keepaspect ){ + vec3_t mins, maxs, extend; + VectorCopy( mins_in, mins ); + VectorCopy( maxs_in, maxs ); + + // line compatible to nexuiz mapinfo + Sys_Printf( "size %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2] ); + + if ( keepaspect ) { + VectorSubtract( maxs, mins, extend ); + if ( extend[1] > extend[0] ) { + mins[0] -= ( extend[1] - extend[0] ) * 0.5; + maxs[0] += ( extend[1] - extend[0] ) * 0.5; + } + else + { + mins[1] -= ( extend[0] - extend[1] ) * 0.5; + maxs[1] += ( extend[0] - extend[1] ) * 0.5; + } + } + + /* border: amount of black area around the image */ + /* input: border, 1-2*border, border but we need border/(1-2*border) */ + + VectorSubtract( maxs, mins, extend ); + VectorScale( extend, border / ( 1 - 2 * border ), extend ); + + VectorSubtract( mins, extend, mins ); + VectorAdd( maxs, extend, maxs ); + + VectorCopy( mins, minimap.mins ); + VectorSubtract( maxs, mins, minimap.size ); + + // line compatible to nexuiz mapinfo + Sys_Printf( "size_texcoords %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2] ); +} + +/* + MiniMapSetupBrushes() + determines solid non-sky brushes in the world + */ + +void MiniMapSetupBrushes( void ){ + SetupBrushesFlags( C_SOLID | C_SKY, C_SOLID, 0, 0 ); + // at least one must be solid + // none may be sky + // not all may be nodraw +} + +qboolean MiniMapEvaluateSampleOffsets( int *bestj, int *bestk, float *bestval ){ + float val, dx, dy; + int j, k; + + *bestj = *bestk = -1; + *bestval = 3; /* max possible val is 2 */ + + for ( j = 0; j < minimap.samples; ++j ) + for ( k = j + 1; k < minimap.samples; ++k ) + { + dx = minimap.sample_offsets[2 * j + 0] - minimap.sample_offsets[2 * k + 0]; + dy = minimap.sample_offsets[2 * j + 1] - minimap.sample_offsets[2 * k + 1]; + if ( dx > +0.5 ) { + dx -= 1; + } + if ( dx < -0.5 ) { + dx += 1; + } + if ( dy > +0.5 ) { + dy -= 1; + } + if ( dy < -0.5 ) { + dy += 1; + } + val = dx * dx + dy * dy; + if ( val < *bestval ) { + *bestj = j; + *bestk = k; + *bestval = val; + } + } + + return *bestval < 3; +} + +void MiniMapMakeSampleOffsets(){ + int i, j, k, jj, kk; + float val, valj, valk, sx, sy, rx, ry; + + Sys_Printf( "Generating good sample offsets (this may take a while)...\n" ); + + /* start with entirely random samples */ + for ( i = 0; i < minimap.samples; ++i ) + { + minimap.sample_offsets[2 * i + 0] = Random(); + minimap.sample_offsets[2 * i + 1] = Random(); + } + + for ( i = 0; i < 1000; ++i ) + { + if ( MiniMapEvaluateSampleOffsets( &j, &k, &val ) ) { + sx = minimap.sample_offsets[2 * j + 0]; + sy = minimap.sample_offsets[2 * j + 1]; + minimap.sample_offsets[2 * j + 0] = rx = Random(); + minimap.sample_offsets[2 * j + 1] = ry = Random(); + if ( !MiniMapEvaluateSampleOffsets( &jj, &kk, &valj ) ) { + valj = -1; + } + minimap.sample_offsets[2 * j + 0] = sx; + minimap.sample_offsets[2 * j + 1] = sy; + + sx = minimap.sample_offsets[2 * k + 0]; + sy = minimap.sample_offsets[2 * k + 1]; + minimap.sample_offsets[2 * k + 0] = rx; + minimap.sample_offsets[2 * k + 1] = ry; + if ( !MiniMapEvaluateSampleOffsets( &jj, &kk, &valk ) ) { + valk = -1; + } + minimap.sample_offsets[2 * k + 0] = sx; + minimap.sample_offsets[2 * k + 1] = sy; + + if ( valj > valk ) { + if ( valj > val ) { + /* valj is the greatest */ + minimap.sample_offsets[2 * j + 0] = rx; + minimap.sample_offsets[2 * j + 1] = ry; + i = -1; + } + else + { + /* valj is the greater and it is useless - forget it */ + } + } + else + { + if ( valk > val ) { + /* valk is the greatest */ + minimap.sample_offsets[2 * k + 0] = rx; + minimap.sample_offsets[2 * k + 1] = ry; + i = -1; + } + else + { + /* valk is the greater and it is useless - forget it */ + } + } + } + else{ + break; + } + } +} + +void MergeRelativePath( char *out, const char *absolute, const char *relative ){ + const char *endpos = absolute + strlen( absolute ); + while ( endpos != absolute && ( endpos[-1] == '/' || endpos[-1] == '\\' ) ) + --endpos; + while ( relative[0] == '.' && relative[1] == '.' && ( relative[2] == '/' || relative[2] == '\\' ) ) + { + relative += 3; + while ( endpos != absolute ) + { + --endpos; + if ( *endpos == '/' || *endpos == '\\' ) { + break; + } + } + while ( endpos != absolute && ( endpos[-1] == '/' || endpos[-1] == '\\' ) ) + --endpos; + } + memcpy( out, absolute, endpos - absolute ); + out[endpos - absolute] = '/'; + strcpy( out + ( endpos - absolute + 1 ), relative ); +} + +int MiniMapBSPMain( int argc, char **argv ){ + char minimapFilename[1024]; + char basename[1024]; + char path[1024]; + char relativeMinimapFilename[1024]; + qboolean autolevel; + float minimapSharpen; + float border; + byte *data4b, *p; + float *q; + int x, y; + int i; + miniMapMode_t mode; + vec3_t mins, maxs; + qboolean keepaspect; + + /* arg checking */ + if ( argc < 2 ) { + Sys_Printf( "Usage: q3map [-v] -minimap [-size n] [-sharpen f] [-samples n | -random n] [-o filename.tga] [-minmax Xmin Ymin Zmin Xmax Ymax Zmax] \n" ); + return 0; + } + + /* load the BSP first */ + strcpy( source, ExpandArg( argv[ argc - 1 ] ) ); + StripExtension( source ); + DefaultExtension( source, ".bsp" ); + Sys_Printf( "Loading %s\n", source ); + BeginMapShaderFile( source ); + LoadShaderInfo(); + LoadBSPFile( source ); + + minimap.model = &bspModels[0]; + VectorCopy( minimap.model->mins, mins ); + VectorCopy( minimap.model->maxs, maxs ); + + *minimapFilename = 0; + minimapSharpen = game->miniMapSharpen; + minimap.width = minimap.height = game->miniMapSize; + border = game->miniMapBorder; + keepaspect = game->miniMapKeepAspect; + mode = game->miniMapMode; + + autolevel = qfalse; + minimap.samples = 1; + minimap.sample_offsets = NULL; + minimap.boost = 1.0; + minimap.brightness = 0.0; + minimap.contrast = 1.0; + + /* process arguments */ + for ( i = 1; i < ( argc - 1 ); i++ ) + { + if ( !strcmp( argv[ i ], "-size" ) ) { + minimap.width = minimap.height = atoi( argv[i + 1] ); + i++; + Sys_Printf( "Image size set to %i\n", minimap.width ); + } + else if ( !strcmp( argv[ i ], "-sharpen" ) ) { + minimapSharpen = atof( argv[i + 1] ); + i++; + Sys_Printf( "Sharpening coefficient set to %f\n", minimapSharpen ); + } + else if ( !strcmp( argv[ i ], "-samples" ) ) { + minimap.samples = atoi( argv[i + 1] ); + i++; + Sys_Printf( "Samples set to %i\n", minimap.samples ); + if ( minimap.sample_offsets ) { + free( minimap.sample_offsets ); + } + minimap.sample_offsets = malloc( 2 * sizeof( *minimap.sample_offsets ) * minimap.samples ); + MiniMapMakeSampleOffsets(); + } + else if ( !strcmp( argv[ i ], "-random" ) ) { + minimap.samples = atoi( argv[i + 1] ); + i++; + Sys_Printf( "Random samples set to %i\n", minimap.samples ); + if ( minimap.sample_offsets ) { + free( minimap.sample_offsets ); + } + minimap.sample_offsets = NULL; + } + else if ( !strcmp( argv[ i ], "-border" ) ) { + border = atof( argv[i + 1] ); + i++; + Sys_Printf( "Border set to %f\n", border ); + } + else if ( !strcmp( argv[ i ], "-keepaspect" ) ) { + keepaspect = qtrue; + Sys_Printf( "Keeping aspect ratio by letterboxing\n", border ); + } + else if ( !strcmp( argv[ i ], "-nokeepaspect" ) ) { + keepaspect = qfalse; + Sys_Printf( "Not keeping aspect ratio\n", border ); + } + else if ( !strcmp( argv[ i ], "-o" ) ) { + strcpy( minimapFilename, argv[i + 1] ); + i++; + Sys_Printf( "Output file name set to %s\n", minimapFilename ); + } + else if ( !strcmp( argv[ i ], "-minmax" ) && i < ( argc - 7 ) ) { + mins[0] = atof( argv[i + 1] ); + mins[1] = atof( argv[i + 2] ); + mins[2] = atof( argv[i + 3] ); + maxs[0] = atof( argv[i + 4] ); + maxs[1] = atof( argv[i + 5] ); + maxs[2] = atof( argv[i + 6] ); + i += 6; + Sys_Printf( "Map mins/maxs overridden\n" ); + } + else if ( !strcmp( argv[ i ], "-gray" ) ) { + mode = MINIMAP_MODE_GRAY; + Sys_Printf( "Writing as white-on-black image\n" ); + } + else if ( !strcmp( argv[ i ], "-black" ) ) { + mode = MINIMAP_MODE_BLACK; + Sys_Printf( "Writing as black alpha image\n" ); + } + else if ( !strcmp( argv[ i ], "-white" ) ) { + mode = MINIMAP_MODE_WHITE; + Sys_Printf( "Writing as white alpha image\n" ); + } + else if ( !strcmp( argv[ i ], "-boost" ) && i < ( argc - 2 ) ) { + minimap.boost = atof( argv[i + 1] ); + i++; + Sys_Printf( "Contrast boost set to %f\n", minimap.boost ); + } + else if ( !strcmp( argv[ i ], "-brightness" ) && i < ( argc - 2 ) ) { + minimap.brightness = atof( argv[i + 1] ); + i++; + Sys_Printf( "Brightness set to %f\n", minimap.brightness ); + } + else if ( !strcmp( argv[ i ], "-contrast" ) && i < ( argc - 2 ) ) { + minimap.contrast = atof( argv[i + 1] ); + i++; + Sys_Printf( "Contrast set to %f\n", minimap.contrast ); + } + else if ( !strcmp( argv[ i ], "-autolevel" ) ) { + autolevel = qtrue; + Sys_Printf( "Auto level enabled\n", border ); + } + else if ( !strcmp( argv[ i ], "-noautolevel" ) ) { + autolevel = qfalse; + Sys_Printf( "Auto level disabled\n", border ); + } + } + + MiniMapMakeMinsMaxs( mins, maxs, border, keepaspect ); + + if ( !*minimapFilename ) { + ExtractFileBase( source, basename ); + ExtractFilePath( source, path ); + sprintf( relativeMinimapFilename, game->miniMapNameFormat, basename ); + MergeRelativePath( minimapFilename, path, relativeMinimapFilename ); + Sys_Printf( "Output file name automatically set to %s\n", minimapFilename ); + } + ExtractFilePath( minimapFilename, path ); + Q_mkdir( path ); + + if ( minimapSharpen >= 0 ) { + minimap.sharpen_centermult = 8 * minimapSharpen + 1; + minimap.sharpen_boxmult = -minimapSharpen; + } + + minimap.data1f = safe_malloc( minimap.width * minimap.height * sizeof( *minimap.data1f ) ); + data4b = safe_malloc( minimap.width * minimap.height * 4 ); + if ( minimapSharpen >= 0 ) { + minimap.sharpendata1f = safe_malloc( minimap.width * minimap.height * sizeof( *minimap.data1f ) ); + } + + MiniMapSetupBrushes(); + + if ( minimap.samples <= 1 ) { + Sys_Printf( "\n--- MiniMapNoSupersampling (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapNoSupersampling ); + } + else + { + if ( minimap.sample_offsets ) { + Sys_Printf( "\n--- MiniMapSupersampled (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapSupersampled ); + } + else + { + Sys_Printf( "\n--- MiniMapRandomlySupersampled (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapRandomlySupersampled ); + } + } + + if ( minimap.boost != 1.0 ) { + Sys_Printf( "\n--- MiniMapContrastBoost (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapContrastBoost ); + } + + if ( autolevel ) { + Sys_Printf( "\n--- MiniMapAutoLevel (%d) ---\n", minimap.height ); + float mi = 1, ma = 0; + float s, o; + + // TODO threads! + q = minimap.data1f; + for ( y = 0; y < minimap.height; ++y ) + for ( x = 0; x < minimap.width; ++x ) + { + float v = *q++; + if ( v < mi ) { + mi = v; + } + if ( v > ma ) { + ma = v; + } + } + if ( ma > mi ) { + s = 1 / ( ma - mi ); + o = mi / ( ma - mi ); + + // equations: + // brightness + contrast * v + // after autolevel: + // brightness + contrast * (v * s - o) + // = + // (brightness - contrast * o) + (contrast * s) * v + minimap.brightness = minimap.brightness - minimap.contrast * o; + minimap.contrast *= s; + + Sys_Printf( "Auto level: Brightness changed to %f\n", minimap.brightness ); + Sys_Printf( "Auto level: Contrast changed to %f\n", minimap.contrast ); + } + else{ + Sys_Printf( "Auto level: failed because all pixels are the same value\n" ); + } + } + + if ( minimap.brightness != 0 || minimap.contrast != 1 ) { + Sys_Printf( "\n--- MiniMapBrightnessContrast (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapBrightnessContrast ); + } + + if ( minimap.sharpendata1f ) { + Sys_Printf( "\n--- MiniMapSharpen (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapSharpen ); + q = minimap.sharpendata1f; + } + else + { + q = minimap.data1f; + } + + Sys_Printf( "\nConverting..." ); + + switch ( mode ) + { + case MINIMAP_MODE_GRAY: + p = data4b; + for ( y = 0; y < minimap.height; ++y ) + for ( x = 0; x < minimap.width; ++x ) + { + byte b; + float v = *q++; + if ( v < 0 ) { + v = 0; + } + if ( v > 255.0 / 256.0 ) { + v = 255.0 / 256.0; + } + b = v * 256; + *p++ = b; + } + Sys_Printf( " writing to %s...", minimapFilename ); + WriteTGAGray( minimapFilename, data4b, minimap.width, minimap.height ); + break; + case MINIMAP_MODE_BLACK: + p = data4b; + for ( y = 0; y < minimap.height; ++y ) + for ( x = 0; x < minimap.width; ++x ) + { + byte b; + float v = *q++; + if ( v < 0 ) { + v = 0; + } + if ( v > 255.0 / 256.0 ) { + v = 255.0 / 256.0; + } + b = v * 256; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = b; + } + Sys_Printf( " writing to %s...", minimapFilename ); + WriteTGA( minimapFilename, data4b, minimap.width, minimap.height ); + break; + case MINIMAP_MODE_WHITE: + p = data4b; + for ( y = 0; y < minimap.height; ++y ) + for ( x = 0; x < minimap.width; ++x ) + { + byte b; + float v = *q++; + if ( v < 0 ) { + v = 0; + } + if ( v > 255.0 / 256.0 ) { + v = 255.0 / 256.0; + } + b = v * 256; + *p++ = 255; + *p++ = 255; + *p++ = 255; + *p++ = b; + } + Sys_Printf( " writing to %s...", minimapFilename ); + WriteTGA( minimapFilename, data4b, minimap.width, minimap.height ); + break; + } + + Sys_Printf( " done.\n" ); + + /* return to sender */ + return 0; +} + + + + + +/* + MD4BlockChecksum() + calculates an md4 checksum for a block of data + */ + +static int MD4BlockChecksum( void *buffer, int length ){ + return Com_BlockChecksum( buffer, length ); } /* @@@ -996,8 -278,8 +1028,8 @@@ int AnalyzeBSP( int argc, char **argv ) lump = (byte*) header + offset; lumpInt = LittleLong( (int) *( (int*) lump ) ); lumpFloat = LittleFloat( (float) *( (float*) lump ) ); - memcpy( lumpString, (char*) lump, ( length < 1024 ? length : 1024 ) ); - lumpString[ 1024 ] = '\0'; + memcpy( lumpString, (char*) lump, ( (size_t)length < sizeof( lumpString ) ? (size_t)length : sizeof( lumpString ) - 1 ) ); + lumpString[ sizeof( lumpString ) - 1 ] = '\0'; /* print basic lump info */ Sys_Printf( "Lump: %d\n", i ); @@@ -1115,72 -397,6 +1147,72 @@@ int BSPInfo( int count, char **fileName } +static void ExtrapolateTexcoords( const float *axyz, const float *ast, const float *bxyz, const float *bst, const float *cxyz, const float *cst, const float *axyz_new, float *ast_out, const float *bxyz_new, float *bst_out, const float *cxyz_new, float *cst_out ){ + vec4_t scoeffs, tcoeffs; + float md; + m4x4_t solvematrix; + + vec3_t norm; + vec3_t dab, dac; + VectorSubtract( bxyz, axyz, dab ); + VectorSubtract( cxyz, axyz, dac ); + CrossProduct( dab, dac, norm ); + + // assume: + // s = f(x, y, z) + // s(v + norm) = s(v) when n ortho xyz + + // s(v) = DotProduct(v, scoeffs) + scoeffs[3] + + // solve: + // scoeffs * (axyz, 1) == ast[0] + // scoeffs * (bxyz, 1) == bst[0] + // scoeffs * (cxyz, 1) == cst[0] + // scoeffs * (norm, 0) == 0 + // scoeffs * [axyz, 1 | bxyz, 1 | cxyz, 1 | norm, 0] = [ast[0], bst[0], cst[0], 0] + solvematrix[0] = axyz[0]; + solvematrix[4] = axyz[1]; + solvematrix[8] = axyz[2]; + solvematrix[12] = 1; + solvematrix[1] = bxyz[0]; + solvematrix[5] = bxyz[1]; + solvematrix[9] = bxyz[2]; + solvematrix[13] = 1; + solvematrix[2] = cxyz[0]; + solvematrix[6] = cxyz[1]; + solvematrix[10] = cxyz[2]; + solvematrix[14] = 1; + solvematrix[3] = norm[0]; + solvematrix[7] = norm[1]; + solvematrix[11] = norm[2]; + solvematrix[15] = 0; + + md = m4_det( solvematrix ); + if ( md * md < 1e-10 ) { + Sys_Printf( "Cannot invert some matrix, some texcoords aren't extrapolated!" ); + return; + } + + m4x4_invert( solvematrix ); + + scoeffs[0] = ast[0]; + scoeffs[1] = bst[0]; + scoeffs[2] = cst[0]; + scoeffs[3] = 0; + m4x4_transform_vec4( solvematrix, scoeffs ); + tcoeffs[0] = ast[1]; + tcoeffs[1] = bst[1]; + tcoeffs[2] = cst[1]; + tcoeffs[3] = 0; + m4x4_transform_vec4( solvematrix, tcoeffs ); + + ast_out[0] = scoeffs[0] * axyz_new[0] + scoeffs[1] * axyz_new[1] + scoeffs[2] * axyz_new[2] + scoeffs[3]; + ast_out[1] = tcoeffs[0] * axyz_new[0] + tcoeffs[1] * axyz_new[1] + tcoeffs[2] * axyz_new[2] + tcoeffs[3]; + bst_out[0] = scoeffs[0] * bxyz_new[0] + scoeffs[1] * bxyz_new[1] + scoeffs[2] * bxyz_new[2] + scoeffs[3]; + bst_out[1] = tcoeffs[0] * bxyz_new[0] + tcoeffs[1] * bxyz_new[1] + tcoeffs[2] * bxyz_new[2] + tcoeffs[3]; + cst_out[0] = scoeffs[0] * cxyz_new[0] + scoeffs[1] * cxyz_new[1] + scoeffs[2] * cxyz_new[2] + scoeffs[3]; + cst_out[1] = tcoeffs[0] * cxyz_new[0] + tcoeffs[1] * cxyz_new[1] + tcoeffs[2] * cxyz_new[2] + tcoeffs[3]; +} /* ScaleBSPMain() @@@ -1188,52 -404,22 +1220,52 @@@ */ int ScaleBSPMain( int argc, char **argv ){ - int i; - float f, scale; + int i, j; + float f, a; + vec3_t scale; vec3_t vec; char str[ 1024 ]; + int uniform, axis; + qboolean texscale; + float *old_xyzst = NULL; + float spawn_ref = 0; /* arg checking */ - if ( argc < 2 ) { - Sys_Printf( "Usage: q3map -scale [-v] \n" ); + if ( argc < 3 ) { + Sys_Printf( "Usage: q3map [-v] -scale [-tex] [-spawn_ref ] \n" ); return 0; } + texscale = qfalse; + for ( i = 1; i < argc - 2; ++i ) + { + if ( !strcmp( argv[i], "-tex" ) ) { + texscale = qtrue; + } + else if ( !strcmp( argv[i], "-spawn_ref" ) ) { + spawn_ref = atof( argv[i + 1] ); + ++i; + } + else{ + break; + } + } + /* get scale */ - scale = atof( argv[ argc - 2 ] ); - if ( scale == 0.0f ) { - Sys_Printf( "Usage: q3map -scale [-v] \n" ); + // if(argc-2 >= i) // always true + scale[2] = scale[1] = scale[0] = atof( argv[ argc - 2 ] ); + if ( argc - 3 >= i ) { + scale[1] = scale[0] = atof( argv[ argc - 3 ] ); + } + if ( argc - 4 >= i ) { + scale[0] = atof( argv[ argc - 4 ] ); + } + + uniform = ( ( scale[0] == scale[1] ) && ( scale[1] == scale[2] ) ); + + if ( scale[0] == 0.0f || scale[1] == 0.0f || scale[2] == 0.0f ) { + Sys_Printf( "Usage: q3map [-v] -scale [-tex] [-spawn_ref ] \n" ); Sys_Printf( "Non-zero scale value required.\n" ); return 0; } @@@ -1257,174 -443,59 +1289,174 @@@ { /* scale origin */ GetVectorForKey( &entities[ i ], "origin", vec ); - if ( ( vec[ 0 ] + vec[ 1 ] + vec[ 2 ] ) ) { - VectorScale( vec, scale, vec ); + if ( ( vec[ 0 ] || vec[ 1 ] || vec[ 2 ] ) ) { + if ( !strncmp( ValueForKey( &entities[i], "classname" ), "info_player_", 12 ) ) { + vec[2] += spawn_ref; + } + vec[0] *= scale[0]; + vec[1] *= scale[1]; + vec[2] *= scale[2]; + if ( !strncmp( ValueForKey( &entities[i], "classname" ), "info_player_", 12 ) ) { + vec[2] -= spawn_ref; + } sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] ); SetKeyValue( &entities[ i ], "origin", str ); } + a = FloatForKey( &entities[ i ], "angle" ); + if ( a == -1 || a == -2 ) { // z scale + axis = 2; + } + else if ( fabs( sin( DEG2RAD( a ) ) ) < 0.707 ) { + axis = 0; + } + else{ + axis = 1; + } + /* scale door lip */ f = FloatForKey( &entities[ i ], "lip" ); if ( f ) { - f *= scale; + f *= scale[axis]; sprintf( str, "%f", f ); SetKeyValue( &entities[ i ], "lip", str ); } + + /* scale plat height */ + f = FloatForKey( &entities[ i ], "height" ); + if ( f ) { + f *= scale[2]; + sprintf( str, "%f", f ); + SetKeyValue( &entities[ i ], "height", str ); + } + + // TODO maybe allow a definition file for entities to specify which values are scaled how? } /* scale models */ for ( i = 0; i < numBSPModels; i++ ) { - VectorScale( bspModels[ i ].mins, scale, bspModels[ i ].mins ); - VectorScale( bspModels[ i ].maxs, scale, bspModels[ i ].maxs ); + bspModels[ i ].mins[0] *= scale[0]; + bspModels[ i ].mins[1] *= scale[1]; + bspModels[ i ].mins[2] *= scale[2]; + bspModels[ i ].maxs[0] *= scale[0]; + bspModels[ i ].maxs[1] *= scale[1]; + bspModels[ i ].maxs[2] *= scale[2]; } /* scale nodes */ for ( i = 0; i < numBSPNodes; i++ ) { - VectorScale( bspNodes[ i ].mins, scale, bspNodes[ i ].mins ); - VectorScale( bspNodes[ i ].maxs, scale, bspNodes[ i ].maxs ); + bspNodes[ i ].mins[0] *= scale[0]; + bspNodes[ i ].mins[1] *= scale[1]; + bspNodes[ i ].mins[2] *= scale[2]; + bspNodes[ i ].maxs[0] *= scale[0]; + bspNodes[ i ].maxs[1] *= scale[1]; + bspNodes[ i ].maxs[2] *= scale[2]; } /* scale leafs */ for ( i = 0; i < numBSPLeafs; i++ ) { - VectorScale( bspLeafs[ i ].mins, scale, bspLeafs[ i ].mins ); - VectorScale( bspLeafs[ i ].maxs, scale, bspLeafs[ i ].maxs ); + bspLeafs[ i ].mins[0] *= scale[0]; + bspLeafs[ i ].mins[1] *= scale[1]; + bspLeafs[ i ].mins[2] *= scale[2]; + bspLeafs[ i ].maxs[0] *= scale[0]; + bspLeafs[ i ].maxs[1] *= scale[1]; + bspLeafs[ i ].maxs[2] *= scale[2]; + } + + if ( texscale ) { + Sys_Printf( "Using texture unlocking (and probably breaking texture alignment a lot)\n" ); + old_xyzst = safe_malloc( sizeof( *old_xyzst ) * numBSPDrawVerts * 5 ); + for ( i = 0; i < numBSPDrawVerts; i++ ) + { + old_xyzst[5 * i + 0] = bspDrawVerts[i].xyz[0]; + old_xyzst[5 * i + 1] = bspDrawVerts[i].xyz[1]; + old_xyzst[5 * i + 2] = bspDrawVerts[i].xyz[2]; + old_xyzst[5 * i + 3] = bspDrawVerts[i].st[0]; + old_xyzst[5 * i + 4] = bspDrawVerts[i].st[1]; + } } /* scale drawverts */ for ( i = 0; i < numBSPDrawVerts; i++ ) - VectorScale( bspDrawVerts[ i ].xyz, scale, bspDrawVerts[ i ].xyz ); + { + bspDrawVerts[i].xyz[0] *= scale[0]; + bspDrawVerts[i].xyz[1] *= scale[1]; + bspDrawVerts[i].xyz[2] *= scale[2]; + bspDrawVerts[i].normal[0] /= scale[0]; + bspDrawVerts[i].normal[1] /= scale[1]; + bspDrawVerts[i].normal[2] /= scale[2]; + VectorNormalize( bspDrawVerts[i].normal, bspDrawVerts[i].normal ); + } + + if ( texscale ) { + for ( i = 0; i < numBSPDrawSurfaces; i++ ) + { + switch ( bspDrawSurfaces[i].surfaceType ) + { + case SURFACE_FACE: + case SURFACE_META: + if ( bspDrawSurfaces[i].numIndexes % 3 ) { + Error( "Not a triangulation!" ); + } + for ( j = bspDrawSurfaces[i].firstIndex; j < bspDrawSurfaces[i].firstIndex + bspDrawSurfaces[i].numIndexes; j += 3 ) + { + int ia = bspDrawIndexes[j] + bspDrawSurfaces[i].firstVert, ib = bspDrawIndexes[j + 1] + bspDrawSurfaces[i].firstVert, ic = bspDrawIndexes[j + 2] + bspDrawSurfaces[i].firstVert; + bspDrawVert_t *a = &bspDrawVerts[ia], *b = &bspDrawVerts[ib], *c = &bspDrawVerts[ic]; + float *oa = &old_xyzst[ia * 5], *ob = &old_xyzst[ib * 5], *oc = &old_xyzst[ic * 5]; + // extrapolate: + // a->xyz -> oa + // b->xyz -> ob + // c->xyz -> oc + ExtrapolateTexcoords( + &oa[0], &oa[3], + &ob[0], &ob[3], + &oc[0], &oc[3], + a->xyz, a->st, + b->xyz, b->st, + c->xyz, c->st ); + } + break; + } + } + } /* scale planes */ - for ( i = 0; i < numBSPPlanes; i++ ) - bspPlanes[ i ].dist *= scale; + if ( uniform ) { + for ( i = 0; i < numBSPPlanes; i++ ) + { + bspPlanes[ i ].dist *= scale[0]; + } + } + else + { + for ( i = 0; i < numBSPPlanes; i++ ) + { + bspPlanes[ i ].normal[0] /= scale[0]; + bspPlanes[ i ].normal[1] /= scale[1]; + bspPlanes[ i ].normal[2] /= scale[2]; + f = 1 / VectorLength( bspPlanes[i].normal ); + VectorScale( bspPlanes[i].normal, f, bspPlanes[i].normal ); + bspPlanes[ i ].dist *= f; + } + } /* scale gridsize */ GetVectorForKey( &entities[ 0 ], "gridsize", vec ); if ( ( vec[ 0 ] + vec[ 1 ] + vec[ 2 ] ) == 0.0f ) { VectorCopy( gridSize, vec ); } - VectorScale( vec, scale, vec ); + vec[0] *= scale[0]; + vec[1] *= scale[1]; + vec[2] *= scale[2]; sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] ); SetKeyValue( &entities[ 0 ], "gridsize", str ); + /* inject command line parameters */ + InjectCommandLine( argv, 0, argc - 1 ); + /* write the bsp */ UnparseEntities(); StripExtension( source ); @@@ -1437,100 -508,6 +1469,100 @@@ } +/* + PseudoCompileBSP() + a stripped down ProcessModels + */ +void PseudoCompileBSP( qboolean need_tree ){ + int models; + char modelValue[10]; + entity_t *entity; + face_t *faces; + tree_t *tree; + node_t *node; + brush_t *brush; + side_t *side; + int i; + + SetDrawSurfacesBuffer(); + mapDrawSurfs = safe_malloc( sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS ); + memset( mapDrawSurfs, 0, sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS ); + numMapDrawSurfs = 0; + + BeginBSPFile(); + models = 1; + for ( mapEntityNum = 0; mapEntityNum < numEntities; mapEntityNum++ ) + { + /* get entity */ + entity = &entities[ mapEntityNum ]; + if ( entity->brushes == NULL && entity->patches == NULL ) { + continue; + } + + if ( mapEntityNum != 0 ) { + sprintf( modelValue, "*%d", models++ ); + SetKeyValue( entity, "model", modelValue ); + } + + /* process the model */ + Sys_FPrintf( SYS_VRB, "############### model %i ###############\n", numBSPModels ); + BeginModel(); + + entity->firstDrawSurf = numMapDrawSurfs; + + ClearMetaTriangles(); + PatchMapDrawSurfs( entity ); + + if ( mapEntityNum == 0 && need_tree ) { + faces = MakeStructuralBSPFaceList( entities[0].brushes ); + tree = FaceBSP( faces ); + node = tree->headnode; + } + else + { + node = AllocNode(); + node->planenum = PLANENUM_LEAF; + tree = AllocTree(); + tree->headnode = node; + } + + /* a minimized ClipSidesIntoTree */ + for ( brush = entity->brushes; brush; brush = brush->next ) + { + /* walk the brush sides */ + for ( i = 0; i < brush->numsides; i++ ) + { + /* get side */ + side = &brush->sides[ i ]; + if ( side->winding == NULL ) { + continue; + } + /* shader? */ + if ( side->shaderInfo == NULL ) { + continue; + } + /* save this winding as a visible surface */ + DrawSurfaceForSide( entity, brush, side, side->winding ); + } + } + + if ( meta ) { + ClassifyEntitySurfaces( entity ); + MakeEntityDecals( entity ); + MakeEntityMetaTriangles( entity ); + SmoothMetaTriangles(); + MergeMetaTriangles(); + } + FilterDrawsurfsIntoTree( entity, tree ); + + FilterStructuralBrushesIntoTree( entity, tree ); + FilterDetailBrushesIntoTree( entity, tree ); + + EmitBrushes( entity->brushes, &entity->firstBrush, &entity->numBrushes ); + EndModel( entity, node ); + } + EndBSPFile( qfalse ); +} /* ConvertBSPMain() @@@ -1541,20 -518,15 +1573,20 @@@ int ConvertBSPMain( int argc, char **ar int i; int ( *convertFunc )( char * ); game_t *convertGame; + char ext[1024]; + qboolean map_allowed, force_bsp, force_map; /* set default */ convertFunc = ConvertBSPToASE; convertGame = NULL; + map_allowed = qfalse; + force_bsp = qfalse; + force_map = qfalse; /* arg checking */ if ( argc < 1 ) { - Sys_Printf( "Usage: q3map -convert [-format ] [-v] \n" ); + Sys_Printf( "Usage: q3map -convert [-format ] [-shadersasbitmap|-lightmapsastexcoord|-deluxemapsastexcoord] [-readbsp|-readmap [-meta|-patchmeta]] [-v] \n" ); return 0; } @@@ -1566,92 -538,36 +1598,92 @@@ i++; if ( !Q_stricmp( argv[ i ], "ase" ) ) { convertFunc = ConvertBSPToASE; + map_allowed = qfalse; + } + else if ( !Q_stricmp( argv[ i ], "obj" ) ) { + convertFunc = ConvertBSPToOBJ; + map_allowed = qfalse; + } + else if ( !Q_stricmp( argv[ i ], "map_bp" ) ) { + convertFunc = ConvertBSPToMap_BP; + map_allowed = qtrue; } else if ( !Q_stricmp( argv[ i ], "map" ) ) { convertFunc = ConvertBSPToMap; + map_allowed = qtrue; } else { convertGame = GetGame( argv[ i ] ); + map_allowed = qfalse; if ( convertGame == NULL ) { Sys_Printf( "Unknown conversion format \"%s\". Defaulting to ASE.\n", argv[ i ] ); } } } + else if ( !strcmp( argv[ i ], "-ne" ) ) { + normalEpsilon = atof( argv[ i + 1 ] ); + i++; + Sys_Printf( "Normal epsilon set to %f\n", normalEpsilon ); + } + else if ( !strcmp( argv[ i ], "-de" ) ) { + distanceEpsilon = atof( argv[ i + 1 ] ); + i++; + Sys_Printf( "Distance epsilon set to %f\n", distanceEpsilon ); + } + else if ( !strcmp( argv[ i ], "-shaderasbitmap" ) || !strcmp( argv[ i ], "-shadersasbitmap" ) ) { + shadersAsBitmap = qtrue; + } + else if ( !strcmp( argv[ i ], "-lightmapastexcoord" ) || !strcmp( argv[ i ], "-lightmapsastexcoord" ) ) { + lightmapsAsTexcoord = qtrue; + } + else if ( !strcmp( argv[ i ], "-deluxemapastexcoord" ) || !strcmp( argv[ i ], "-deluxemapsastexcoord" ) ) { + lightmapsAsTexcoord = qtrue; + deluxemap = qtrue; + } + else if ( !strcmp( argv[ i ], "-readbsp" ) ) { + force_bsp = qtrue; + } + else if ( !strcmp( argv[ i ], "-readmap" ) ) { + force_map = qtrue; + } + else if ( !strcmp( argv[ i ], "-meta" ) ) { + meta = qtrue; + } + else if ( !strcmp( argv[ i ], "-patchmeta" ) ) { + meta = qtrue; + patchMeta = qtrue; + } } - /* clean up map name */ - strcpy( source, ExpandArg( argv[ i ] ) ); - StripExtension( source ); - DefaultExtension( source, ".bsp" ); - LoadShaderInfo(); - Sys_Printf( "Loading %s\n", source ); - - /* ydnar: load surface file */ - //% LoadSurfaceExtraFile( source ); + /* clean up map name */ + strcpy( source, ExpandArg( argv[i] ) ); + ExtractFileExtension( source, ext ); - LoadBSPFile( source ); + if ( !map_allowed && !force_map ) { + force_bsp = qtrue; + } - /* parse bsp entities */ - ParseEntities(); + if ( force_map || ( !force_bsp && !Q_stricmp( ext, "map" ) && map_allowed ) ) { + if ( !map_allowed ) { + Sys_Printf( "WARNING: the requested conversion should not be done from .map files. Compile a .bsp first.\n" ); + } + StripExtension( source ); + DefaultExtension( source, ".map" ); + Sys_Printf( "Loading %s\n", source ); + LoadMapFile( source, qfalse, convertGame == NULL ); + PseudoCompileBSP( convertGame != NULL ); + } + else + { + StripExtension( source ); + DefaultExtension( source, ".bsp" ); + Sys_Printf( "Loading %s\n", source ); + LoadBSPFile( source ); + ParseEntities(); + } /* bsp format convert? */ if ( convertGame != NULL ) { @@@ -1709,10 -625,8 +1741,10 @@@ int main( int argc, char **argv ) /* verbose */ else if ( !strcmp( argv[ i ], "-v" ) ) { - verbose = qtrue; - argv[ i ] = NULL; + if ( !verbose ) { + verbose = qtrue; + argv[ i ] = NULL; + } } /* force */ @@@ -1764,17 -678,12 +1796,17 @@@ Sys_Printf( "Q3Map - v1.0r (c) 1999 Id Software Inc.\n" ); Sys_Printf( "Q3Map (ydnar) - v" Q3MAP_VERSION "\n" ); - Sys_Printf( "GtkRadiant - v" RADIANT_VERSION " " __DATE__ " " __TIME__ "\n" ); + Sys_Printf( "NetRadiant - v" RADIANT_VERSION " " __DATE__ " " __TIME__ "\n" ); Sys_Printf( "%s\n", Q3MAP_MOTD ); /* ydnar: new path initialization */ InitPaths( &argc, argv ); + /* set game options */ + if ( !patchSubdivisions ) { + patchSubdivisions = game->patchSubdivisions; + } + /* check if we have enough options left to attempt something */ if ( argc < 2 ) { Error( "Usage: %s [general options] [options] mapfile", argv[ 0 ] ); @@@ -1832,11 -741,6 +1864,11 @@@ r = ConvertBSPMain( argc - 1, argv + 1 ); } + /* div0: minimap */ + else if ( !strcmp( argv[ 1 ], "-minimap" ) ) { + r = MiniMapBSPMain( argc - 1, argv + 1 ); + } + /* ydnar: otherwise create a bsp */ else{ r = BSPMain( argc, argv ); diff --combined tools/quake3/q3map2/path_init.c index 2591c5bf,901f07fc..07ebc31b --- a/tools/quake3/q3map2/path_init.c +++ b/tools/quake3/q3map2/path_init.c @@@ -49,7 -49,7 +49,7 @@@ int numBasePaths char *basePaths[ MAX_BASE_PATHS ]; int numGamePaths; char *gamePaths[ MAX_GAME_PATHS ]; - +char *homeBasePath = NULL; /* @@@ -66,32 -66,23 +66,27 @@@ char *LokiGetHomeDir( void ) #ifndef Q_UNIX return NULL; #else + static char buf[ 4096 ]; + struct passwd pw, *pwp; char *home; - uid_t id; - struct passwd *pwd; + static char homeBuf[MAX_OS_PATH]; /* get the home environment variable */ home = getenv( "HOME" ); - if ( home == NULL ) { - /* do some more digging */ - id = getuid(); - setpwent(); - while ( ( pwd = getpwent() ) != NULL ) - { - if ( pwd->pw_uid == id ) { - home = pwd->pw_dir; - break; - } - if ( home ) { - return Q_strncpyz( buf, home, sizeof( buf ) ); - } + + /* look up home dir in password database */ - if ( getpwuid_r( getuid(), &pw, buf, sizeof( buf ), &pwp ) == 0 ) { - return pw.pw_dir; ++ if(!home) ++ { ++ if ( getpwuid_r( getuid(), &pw, buf, sizeof( buf ), &pwp ) == 0 ) { ++ return pw.pw_dir; + } - endpwent(); } - return NULL; + snprintf( homeBuf, sizeof( homeBuf ), "%s/.", home ); + + /* return it */ + return homeBuf; #endif } @@@ -103,48 -94,33 +98,43 @@@ */ void LokiInitPaths( char *argv0 ){ + char *home; + + if ( !homePath ) { + /* get home dir */ + home = LokiGetHomeDir(); + if ( home == NULL ) { + home = "."; + } + + /* set home path */ + homePath = home; + } + else{ + home = homePath; + } + #ifndef Q_UNIX /* this is kinda crap, but hey */ strcpy( installPath, "../" ); #else char temp[ MAX_OS_PATH ]; - char *home; + char last0[ 2 ]; char *path; char *last; qboolean found; - /* get home dir */ - home = LokiGetHomeDir(); - if ( home == NULL ) { - home = "."; - } - + path = getenv( "PATH" ); + /* do some path divining */ - strcpy( temp, argv0 ); - if ( strrchr( argv0, '/' ) ) { + Q_strncpyz( temp, argv0, sizeof( temp ) ); + if ( strrchr( temp, '/' ) ) { argv0 = strrchr( argv0, '/' ) + 1; } - else - { - /* get path environment variable */ - path = getenv( "PATH" ); - - /* minor setup */ - last = last0; - last[ 0 ] = path[ 0 ]; - last[ 1 ] = '\0'; + else if ( path ) { found = qfalse; + last = path; /* go through each : segment of path */ while ( last[ 0 ] != '\0' && found == qfalse ) @@@ -160,17 -136,17 +150,17 @@@ /* found home dir candidate */ if ( *path == '~' ) { - strcpy( temp, home ); + Q_strncpyz( temp, home, sizeof( temp ) ); path++; } /* concatenate */ if ( last > ( path + 1 ) ) { - strncat( temp, path, ( last - path ) ); - strcat( temp, "/" ); + Q_strncat( temp, sizeof( temp ), path, ( last - path ) ); + Q_strcat( temp, sizeof( temp ), "/" ); } - strcat( temp, "./" ); - strcat( temp, argv0 ); + Q_strcat( temp, sizeof( temp ), "./" ); + Q_strcat( temp, sizeof( temp ), argv0 ); /* verify the path */ if ( access( temp, X_OK ) == 0 ) { @@@ -186,6 -162,9 +176,6 @@@ *( strrchr( installPath, '/' ) ) = '\0'; *( strrchr( installPath, '/' ) + 1 ) = '\0'; } - - /* set home path */ - homePath = home; #endif } @@@ -277,52 -256,29 +267,52 @@@ void AddBasePath( char *path ) */ void AddHomeBasePath( char *path ){ - #ifdef Q_UNIX int i; char temp[ MAX_OS_PATH ]; + int homePathLen; + if ( !homePath ) { + return; + } /* dummy check */ if ( path == NULL || path[ 0 ] == '\0' ) { return; } + /* strip leading dot, if homePath does not end in /. */ + homePathLen = strlen( homePath ); + if ( !strcmp( path, "." ) ) { + /* -fs_homebase . means that -fs_home is to be used as is */ + strcpy( temp, homePath ); + } + else if ( homePathLen >= 2 && !strcmp( homePath + homePathLen - 2, "/." ) ) { + /* remove trailing /. of homePath */ + homePathLen -= 2; + + /* concatenate home dir and path */ + sprintf( temp, "%.*s/%s", homePathLen, homePath, path ); + } + else + { + /* remove leading . of path */ + if ( path[0] == '.' ) { + ++path; + } + + /* concatenate home dir and path */ + sprintf( temp, "%s/%s", homePath, path ); + } + /* make a hole */ - for ( i = 0; i < ( MAX_BASE_PATHS - 1 ); i++ ) + for ( i = ( MAX_BASE_PATHS - 2 ); i >= 0; i-- ) basePaths[ i + 1 ] = basePaths[ i ]; - /* concatenate home dir and path */ - sprintf( temp, "%s/%s", homePath, path ); - /* add it to the list */ basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 ); strcpy( basePaths[ 0 ], temp ); CleanPath( basePaths[ 0 ] ); numBasePaths++; - #endif } @@@ -405,20 -361,6 +395,20 @@@ void InitPaths( int *argc, char **argv argv[ i ] = NULL; } + /* -fs_forbiddenpath */ + else if ( strcmp( argv[ i ], "-fs_forbiddenpath" ) == 0 ) { + if ( ++i >= *argc ) { + Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] ); + } + argv[ i - 1 ] = NULL; + if ( g_numForbiddenDirs < VFS_MAXDIRS ) { + strncpy( g_strForbiddenDirs[g_numForbiddenDirs], argv[i], PATH_MAX ); + g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = 0; + ++g_numForbiddenDirs; + } + argv[ i ] = NULL; + } + /* -fs_basepath */ else if ( strcmp( argv[ i ], "-fs_basepath" ) == 0 ) { if ( ++i >= *argc ) { @@@ -438,37 -380,6 +428,37 @@@ AddGamePath( argv[ i ] ); argv[ i ] = NULL; } + + /* -fs_home */ + else if ( strcmp( argv[ i ], "-fs_home" ) == 0 ) { + if ( ++i >= *argc ) { + Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] ); + } + argv[ i - 1 ] = NULL; + homePath = argv[i]; + argv[ i ] = NULL; + } + + /* -fs_homebase */ + else if ( strcmp( argv[ i ], "-fs_homebase" ) == 0 ) { + if ( ++i >= *argc ) { + Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] ); + } + argv[ i - 1 ] = NULL; + homeBasePath = argv[i]; + argv[ i ] = NULL; + } + + /* -fs_homepath - sets both of them */ + else if ( strcmp( argv[ i ], "-fs_homepath" ) == 0 ) { + if ( ++i >= *argc ) { + Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] ); + } + argv[ i - 1 ] = NULL; + homePath = argv[i]; + homeBasePath = "."; + argv[ i ] = NULL; + } } /* remove processed arguments */ @@@ -525,12 -436,7 +515,12 @@@ } /* this only affects unix */ - AddHomeBasePath( game->homeBasePath ); + if ( homeBasePath ) { + AddHomeBasePath( homeBasePath ); + } + else{ + AddHomeBasePath( game->homeBasePath ); + } /* initialize vfs paths */ if ( numBasePaths > MAX_BASE_PATHS ) { diff --combined tools/quake3/q3map2/q3map2.h index 935d1c7f,245e34c6..bbb3e76e --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@@ -35,11 -35,8 +35,11 @@@ /* version */ -#define Q3MAP_VERSION "2.5.17" -#define Q3MAP_MOTD "Last one turns the lights off" +#ifndef Q3MAP_VERSION +#error no Q3MAP_VERSION defined +#endif +#define Q3MAP_MOTD "Your map saw the pretty lights from q3map2's BFG" + @@@ -71,6 -68,7 +71,6 @@@ #include "cmdlib.h" #include "mathlib.h" #include "md5lib.h" -#include "md4lib.h" #include "ddslib.h" #include "picomodel.h" @@@ -82,9 -80,11 +82,11 @@@ #include "inout.h" #include "vfs.h" #include "png.h" - +#include "md4.h" #include + #define MIN(a, b) ((a) < (b) ? (a) : (b)) + #define MAX(a, b) ((a) > (b) ? (a) : (b)) /* ------------------------------------------------------------------------------- @@@ -126,6 -126,7 +128,6 @@@ #define Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES 1 #define Q3MAP2_EXPERIMENTAL_SNAP_NORMAL_FIX 1 #define Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX 1 -#define Q3MAP2_EXPERIMENTAL_MODEL_CLIPPING_FIX 1 /* general */ #define MAX_QPATH 64 @@@ -141,7 -142,7 +143,7 @@@ #define DEF_RADIOSITY_BOUNCE 1.0f /* ydnar: default to 100% re-emitted light */ #define MAX_SHADER_INFO 8192 -#define MAX_CUST_SURFACEPARMS 64 +#define MAX_CUST_SURFACEPARMS 256 #define SHADER_MAX_VERTEXES 1000 #define SHADER_MAX_INDEXES ( 6 * SHADER_MAX_VERTEXES ) @@@ -190,7 -191,7 +192,7 @@@ /* bsp */ #define MAX_PATCH_SIZE 32 #define MAX_BRUSH_SIDES 1024 -#define MAX_BUILD_SIDES 300 +#define MAX_BUILD_SIDES 1024 #define MAX_EXPANDED_AXIS 128 @@@ -201,7 -202,6 +203,7 @@@ #define HINT_PRIORITY 1000 /* ydnar: force hint splits first and antiportal/areaportal splits last */ #define ANTIPORTAL_PRIORITY -1000 #define AREAPORTAL_PRIORITY -1000 +#define DETAIL_PRIORITY -3000 #define PSIDE_FRONT 1 #define PSIDE_BACK 2 @@@ -220,10 -220,10 +222,10 @@@ #define PORTALFILE "PRT1" -#define MAX_PORTALS 32768 +#define MAX_PORTALS 0x20000 /* same as MAX_MAP_PORTALS */ #define MAX_SEPERATORS MAX_POINTS_ON_WINDING #define MAX_POINTS_ON_FIXED_WINDING 24 /* ydnar: increased this from 12 at the expense of more memory */ -#define MAX_PORTALS_ON_LEAF 128 +#define MAX_PORTALS_ON_LEAF 1024 /* light */ @@@ -243,7 -243,6 +245,7 @@@ #define LIGHT_FAST_TEMP 512 #define LIGHT_FAST_ACTUAL ( LIGHT_FAST | LIGHT_FAST_TEMP ) #define LIGHT_NEGATIVE 1024 +#define LIGHT_UNNORMALIZED 2048 /* vortex: do not normalize _color */ #define LIGHT_SUN_DEFAULT ( LIGHT_ATTEN_ANGLE | LIGHT_GRID | LIGHT_SURFACES ) #define LIGHT_AREA_DEFAULT ( LIGHT_ATTEN_ANGLE | LIGHT_ATTEN_DISTANCE | LIGHT_GRID | LIGHT_SURFACES ) /* q3a and wolf are the same */ @@@ -258,7 -257,6 +260,7 @@@ #define GRID_EPSILON 0.0f #define DEFAULT_LIGHTMAP_SAMPLE_SIZE 16 +#define DEFAULT_LIGHTMAP_MIN_SAMPLE_SIZE 0 #define DEFAULT_LIGHTMAP_SAMPLE_OFFSET 1.0f #define DEFAULT_SUBDIVIDE_THRESHOLD 1.0f @@@ -273,28 -271,22 +275,28 @@@ #define BSP_LUXEL_SIZE 3 #define RAD_LUXEL_SIZE 3 #define SUPER_LUXEL_SIZE 4 +#define SUPER_FLAG_SIZE 4 +#define FLAG_FORCE_SUBSAMPLING 1 +#define FLAG_ALREADY_SUBSAMPLED 2 #define SUPER_ORIGIN_SIZE 3 #define SUPER_NORMAL_SIZE 4 #define SUPER_DELUXEL_SIZE 3 #define BSP_DELUXEL_SIZE 3 +#define SUPER_FLOODLIGHT_SIZE 4 #define VERTEX_LUXEL( s, v ) ( vertexLuxels[ s ] + ( ( v ) * VERTEX_LUXEL_SIZE ) ) #define RAD_VERTEX_LUXEL( s, v )( radVertexLuxels[ s ] + ( ( v ) * VERTEX_LUXEL_SIZE ) ) #define BSP_LUXEL( s, x, y ) ( lm->bspLuxels[ s ] + ( ( ( ( y ) * lm->w ) + ( x ) ) * BSP_LUXEL_SIZE ) ) #define RAD_LUXEL( s, x, y ) ( lm->radLuxels[ s ] + ( ( ( ( y ) * lm->w ) + ( x ) ) * RAD_LUXEL_SIZE ) ) #define SUPER_LUXEL( s, x, y ) ( lm->superLuxels[ s ] + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_LUXEL_SIZE ) ) +#define SUPER_FLAG( x, y ) ( lm->superFlags + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_FLAG_SIZE ) ) #define SUPER_DELUXEL( x, y ) ( lm->superDeluxels + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_DELUXEL_SIZE ) ) #define BSP_DELUXEL( x, y ) ( lm->bspDeluxels + ( ( ( ( y ) * lm->w ) + ( x ) ) * BSP_DELUXEL_SIZE ) ) #define SUPER_CLUSTER( x, y ) ( lm->superClusters + ( ( ( y ) * lm->sw ) + ( x ) ) ) #define SUPER_ORIGIN( x, y ) ( lm->superOrigins + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_ORIGIN_SIZE ) ) #define SUPER_NORMAL( x, y ) ( lm->superNormals + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_NORMAL_SIZE ) ) #define SUPER_DIRT( x, y ) ( lm->superNormals + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_NORMAL_SIZE ) + 3 ) /* stash dirtyness in normal[ 3 ] */ +#define SUPER_FLOODLIGHT( x, y ) ( lm->superFloodLight + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_FLOODLIGHT_SIZE ) ) @@@ -316,16 -308,28 +318,16 @@@ #define MAX_LIGHTMAP_SHADERS 256 /* ok to increase these at the expense of more memory */ -#define MAX_MAP_MODELS 0x400 -#define MAX_MAP_BRUSHES 0x10000 -#define MAX_MAP_ENTITIES 0x1000 //% 0x800 /* ydnar */ -#define MAX_MAP_ENTSTRING 0x80000 //% 0x40000 /* ydnar */ -#define MAX_MAP_SHADERS 0x800 //% 0x400 /* ydnar */ - #define MAX_MAP_AREAS 0x100 /* MAX_MAP_AREA_BYTES in q_shared must match! */ #define MAX_MAP_FOGS 30 //& 0x100 /* RBSP (32 - world fog - goggles) */ -#define MAX_MAP_PLANES 0x100000 //% 0x20000 /* ydnar for md */ -#define MAX_MAP_NODES 0x20000 -#define MAX_MAP_BRUSHSIDES 0x100000 //% 0x20000 /* ydnar */ #define MAX_MAP_LEAFS 0x20000 -#define MAX_MAP_LEAFFACES 0x100000 //% 0x20000 /* ydnar */ -#define MAX_MAP_LEAFBRUSHES 0x40000 #define MAX_MAP_PORTALS 0x20000 #define MAX_MAP_LIGHTING 0x800000 #define MAX_MAP_LIGHTGRID 0x100000 //% 0x800000 /* ydnar: set to points, not bytes */ -#define MAX_MAP_VISIBILITY 0x200000 +#define MAX_MAP_VISCLUSTERS 0x4000 // <= MAX_MAP_LEAFS +#define MAX_MAP_VISIBILITY ( VIS_HEADER_SIZE + MAX_MAP_VISCLUSTERS * ( ( ( MAX_MAP_VISCLUSTERS + 63 ) & ~63 ) >> 3 ) ) #define MAX_MAP_DRAW_SURFS 0x20000 -#define MAX_MAP_DRAW_VERTS 0x100000 -#define MAX_MAP_DRAW_INDEXES 0x80000 #define MAX_MAP_ADVERTISEMENTS 30 @@@ -523,7 -527,7 +525,7 @@@ typedef struct ------------------------------------------------------------------------------- */ /* ydnar: for smaller structs */ -typedef char qb_t; +typedef unsigned char qb_t; /* ydnar: for q3map_tcMod */ @@@ -540,13 -544,6 +542,13 @@@ typedef struct surfaceParm_ } surfaceParm_t; +typedef enum +{ + MINIMAP_MODE_GRAY, + MINIMAP_MODE_BLACK, + MINIMAP_MODE_WHITE +} +miniMapMode_t; typedef struct game_s { @@@ -563,26 -560,7 +565,26 @@@ qboolean wolfLight; /* when true, lights work like wolf q3map */ int lightmapSize; /* bsp lightmap width/height */ float lightmapGamma; /* default lightmap gamma */ + qboolean lightmapsRGB; /* default lightmap sRGB mode */ + qboolean texturesRGB; /* default texture sRGB mode */ + qboolean colorsRGB; /* default color sRGB mode */ + float lightmapExposure; /* default lightmap exposure */ float lightmapCompensate; /* default lightmap compensate value */ + float gridScale; /* vortex: default lightgrid scale (affects both directional and ambient spectres) */ + float gridAmbientScale; /* vortex: default lightgrid ambient spectre scale */ + qboolean lightAngleHL; /* jal: use half-lambert curve for light angle attenuation */ + qboolean noStyles; /* use lightstyles hack or not */ + qboolean keepLights; /* keep light entities on bsp */ + int patchSubdivisions; /* default patch subdivisions tolerance */ + qboolean patchShadows; /* patch casting enabled */ + qboolean deluxeMap; /* compile deluxemaps */ + int deluxeMode; /* deluxemap mode (0 - modelspace, 1 - tangentspace with renormalization, 2 - tangentspace without renormalization) */ + int miniMapSize; /* minimap size */ + float miniMapSharpen; /* minimap sharpening coefficient */ + float miniMapBorder; /* minimap border amount */ + qboolean miniMapKeepAspect; /* minimap keep aspect ratio by letterboxing */ + miniMapMode_t miniMapMode; /* minimap mode */ + char *miniMapNameFormat; /* minimap name format */ char *bspIdent; /* 4-letter bsp file prefix */ int bspVersion; /* bsp version to use */ qboolean lumpSwap; /* cod-style len/ofs order */ @@@ -649,14 -627,6 +651,14 @@@ typedef struct remap_ } remap_t; +typedef struct skinfile_s +{ + struct skinfile_s *next; + char name[ 1024 ]; + char to[ MAX_QPATH ]; +} +skinfile_t; + /* wingdi.h hack, it's the same: 0 */ #undef CM_NONE @@@ -671,12 -641,8 +673,12 @@@ typedef enu CM_ALPHA_SCALE, CM_COLOR_DOT_PRODUCT, CM_ALPHA_DOT_PRODUCT, + CM_COLOR_DOT_PRODUCT_SCALE, + CM_ALPHA_DOT_PRODUCT_SCALE, CM_COLOR_DOT_PRODUCT_2, - CM_ALPHA_DOT_PRODUCT_2 + CM_ALPHA_DOT_PRODUCT_2, + CM_COLOR_DOT_PRODUCT_2_SCALE, + CM_ALPHA_DOT_PRODUCT_2_SCALE } colorModType_t; @@@ -713,7 -679,6 +715,7 @@@ typedef struct shaderInfo_ char *backShader; /* for surfaces that generate different front and back passes */ char *cloneShader; /* ydnar: for cloning of a surface */ char *remapShader; /* ydnar: remap a shader in final stage */ + char *deprecateShader; /* vortex: shader is deprecated and replaced by this on use */ surfaceModel_t *surfaceModel; /* ydnar: for distribution of models */ foliage_t *foliage; /* ydnar/splash damage: wolf et foliage */ @@@ -765,7 -730,6 +767,7 @@@ qb_t noFog; /* ydnar: supress fogging */ qb_t clipModel; /* ydnar: solid model hack */ qb_t noVertexLight; /* ydnar: leave vertex color alone */ + qb_t noDirty; /* jal: do not apply the dirty pass to this surface */ byte styleMarker; /* ydnar: light styles hack */ @@@ -792,12 -756,6 +794,12 @@@ vec3_t averageColor; byte lightStyle; + /* vortex: per-surface floodlight */ + float floodlightDirectionScale; + vec3_t floodlightRGB; + float floodlightIntensity; + float floodlightDistance; + qb_t lmMergable; /* ydnar */ int lmCustomWidth, lmCustomHeight; /* ydnar */ float lmBrightness; /* ydnar */ @@@ -827,7 -785,7 +829,7 @@@ typedef struct face_ struct face_s *next; int planenum; int priority; - qboolean checked; + //qboolean checked; int compileFlags; winding_t *w; } @@@ -839,8 -797,7 +841,8 @@@ typedef struct plane_ vec3_t normal; vec_t dist; int type; - struct plane_s *hash_chain; + int counter; + int hash_chain; } plane_t; @@@ -907,9 -864,7 +909,9 @@@ typedef struct brush_ shaderInfo_t *celShader; /* :) */ /* ydnar: gs mods */ + int lightmapSampleSize; /* jal : entity based _lightmapsamplesize */ float lightmapScale; + float shadeAngleDegrees; /* jal : entity based _shadeangle */ vec3_t eMins, eMaxs; indexMap_t *im; @@@ -960,7 -915,6 +962,7 @@@ typedef struct parseMesh_ shaderInfo_t *celShader; /* :) */ /* ydnar: gs mods */ + int lightmapSampleSize; /* jal : entity based _lightmapsamplesize */ float lightmapScale; vec3_t eMins, eMaxs; indexMap_t *im; @@@ -1059,9 -1013,6 +1061,9 @@@ typedef struct mapDrawSurface_ /* ydnar: per-surface (per-entity, actually) lightmap sample size scaling */ float lightmapScale; + /* jal: per-surface (per-entity, actually) shadeangle */ + float shadeAngleDegrees; + /* ydnar: surface classification */ vec3_t mins, maxs; vec3_t lightmapAxis; @@@ -1104,7 -1055,6 +1106,7 @@@ typedef struct metaTriangle_ shaderInfo_t *si; side_t *side; int entityNum, surfaceNum, planeNum, fogNum, sampleSize, castShadows, recvShadows; + float shadeAngleDegrees; vec4_t plane; vec3_t lightmapAxis; int indexes[ 3 ]; @@@ -1128,7 -1078,6 +1130,7 @@@ typedef struc int mapEntityNum, firstDrawSurf; int firstBrush, numBrushes; /* only valid during BSP compile */ epair_t *epairs; + vec3_t originbrush_origin; } entity_t; @@@ -1162,8 -1111,6 +1164,8 @@@ typedef struct node_ entity_t *occupant; /* for leak file testing */ struct portal_s *portals; /* also on nodes during construction */ + + qboolean has_structural_children; } node_t; @@@ -1321,7 -1268,6 +1323,7 @@@ typedef struct light_ float radiusByDist; /* for spotlights */ float fade; /* ydnar: from wolf, for linear lights */ float angleScale; /* ydnar: stolen from vlight for K */ + float extraDist; /* "extra dimension" distance of the light, to kill hot spots */ float add; /* ydnar: used for area lights */ float envelope; /* ydnar: units until falloff < tolerance */ @@@ -1367,15 -1313,12 +1369,15 @@@ typedef struc /* input and output */ vec3_t color; /* starts out at full color, may be reduced if transparent surfaces are crossed */ + vec3_t colorNoShadow; /* result color with no shadow casting */ + vec3_t directionContribution; /* result contribution to the deluxe map */ /* output */ vec3_t hit; int compileFlags; /* for determining surface compile flags traced through */ qboolean passSolid; qboolean opaque; + vec_t forceSubsampling; /* needs subsampling (alphashadow), value = max color contribution possible from it */ /* working data */ int numTestNodes; @@@ -1441,13 -1384,6 +1443,13 @@@ typedef struct rawLightmap_ int numLightClusters, *lightClusters; int sampleSize, actualSampleSize, axisNum; + + /* vortex: per-surface floodlight */ + float floodlightDirectionScale; + vec3_t floodlightRGB; + float floodlightIntensity; + float floodlightDistance; + int entityNum; int recvShadows; vec3_t mins, maxs, axis, origin, *vecs; @@@ -1467,14 -1403,12 +1469,14 @@@ float *bspLuxels[ MAX_LIGHTMAPS ]; float *radLuxels[ MAX_LIGHTMAPS ]; float *superLuxels[ MAX_LIGHTMAPS ]; + unsigned char *superFlags; float *superOrigins; float *superNormals; int *superClusters; float *superDeluxels; /* average light direction */ float *bspDeluxels; + float *superFloodLight; } rawLightmap_t; @@@ -1491,7 -1425,7 +1493,7 @@@ rawGridPoint_t typedef struct surfaceInfo_s { - bspModel_t *model; + int modelindex; shaderInfo_t *si; rawLightmap_t *lm; int parentSurfaceNum, childSurfaceNum; @@@ -1504,6 -1438,8 +1506,6 @@@ } surfaceInfo_t; - - /* ------------------------------------------------------------------------------- prototypes @@@ -1512,6 -1448,9 +1514,9 @@@ /* main.c */ vec_t Random( void ); + char *Q_strncpyz( char *dst, const char *src, size_t len ); + char *Q_strcat( char *dst, size_t dlen, const char *src ); + char *Q_strncat( char *dst, size_t dlen, const char *src, size_t slen ); int BSPInfo( int count, char **fileNames ); int ScaleBSPMain( int argc, char **argv ); int ConvertMain( int argc, char **argv ); @@@ -1528,15 -1467,11 +1533,15 @@@ int BSPMain( in /* convert_map.c */ int ConvertBSPToMap( char *bspName ); +int ConvertBSPToMap_BP( char *bspName ); /* convert_ase.c */ int ConvertBSPToASE( char *bspName ); +/* convert_obj.c */ +int ConvertBSPToOBJ( char *bspName ); + /* brush.c */ sideRef_t *AllocSideRef( side_t *side, sideRef_t *next ); @@@ -1583,11 -1518,11 +1588,11 @@@ void MakeNormalV /* map.c */ -void LoadMapFile( char *filename, qboolean onlyLights ); +void LoadMapFile( char *filename, qboolean onlyLights, qboolean noCollapseGroups ); int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points ); int PlaneTypeForNormal( vec3_t normal ); void AddBrushBevels( void ); -brush_t *FinishBrush( void ); +brush_t *FinishBrush( qboolean noCollapseGroups ); /* portals.c */ @@@ -1597,10 -1532,7 +1602,10 @@@ void SplitNodePo qboolean PortalPassable( portal_t *p ); -qboolean FloodEntities( tree_t *tree ); +#define FLOODENTITIES_LEAKED 1 +#define FLOODENTITIES_GOOD 0 +#define FLOODENTITIES_EMPTY -1 +int FloodEntities( tree_t *tree ); void FillOutside( node_t *headnode ); void FloodAreas( tree_t *tree ); face_t *VisibleFaces( entity_t *e, tree_t *tree ); @@@ -1625,7 -1557,7 +1630,7 @@@ void SetLightSty int EmitShader( const char *shader, int *contentFlags, int *surfaceFlags ); void BeginBSPFile( void ); -void EndBSPFile( void ); +void EndBSPFile( qboolean do_write ); void EmitBrushes( brush_t *brushes, int *firstBrush, int *numBrushes ); void EmitFogs( void ); @@@ -1644,7 -1576,6 +1649,7 @@@ void FreeTreePor void ParsePatch( qboolean onlyLights ); mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ); void PatchMapDrawSurfs( entity_t *e ); +void TriangulatePatchSurface( entity_t *e, mapDrawSurface_t *ds ); /* tjunction.c */ @@@ -1667,10 -1598,10 +1672,10 @@@ tree_t *FaceBSP( f /* model.c */ void PicoPrintFunc( int level, const char *str ); -void PicoLoadFileFunc( char *name, byte **buffer, int *bufSize ); -picoModel_t *FindModel( char *name, int frame ); -picoModel_t *LoadModel( char *name, int frame ); -void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale ); +void PicoLoadFileFunc( const char *name, byte **buffer, int *bufSize ); +picoModel_t *FindModel( const char *name, int frame ); +picoModel_t *LoadModel( const char *name, int frame ); +void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle ); void AddTriangleModels( entity_t *e ); @@@ -1678,7 -1609,6 +1683,7 @@@ mapDrawSurface_t *AllocDrawSurface( surfaceType_t type ); void FinishSurface( mapDrawSurface_t *ds ); void StripFaceSurface( mapDrawSurface_t *ds ); +void MaxAreaFaceSurface( mapDrawSurface_t *ds ); qboolean CalcSurfaceTextureRange( mapDrawSurface_t *ds ); qboolean CalcLightmapAxis( vec3_t normal, vec3_t axis ); void ClassifySurfaces( int numSurfs, mapDrawSurface_t *ds ); @@@ -1691,7 -1621,7 +1696,7 @@@ void ClearSurfac void AddEntitySurfaceModels( entity_t *e ); mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, winding_t *w ); mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh ); -mapDrawSurface_t *DrawSurfaceForFlare( int entNum, vec3_t origin, vec3_t normal, vec3_t color, char *flareShader, int lightStyle ); +mapDrawSurface_t *DrawSurfaceForFlare( int entNum, vec3_t origin, vec3_t normal, vec3_t color, const char *flareShader, int lightStyle ); mapDrawSurface_t *DrawSurfaceForShader( char *shader ); void ClipSidesIntoTree( entity_t *e, tree_t *tree ); void MakeDebugPortalSurfs( tree_t *tree ); @@@ -1700,8 -1630,6 +1705,8 @@@ void SubdivideFa void AddEntitySurfaceModels( entity_t *e ); int AddSurfaceModels( mapDrawSurface_t *ds ); void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ); +void EmitPatchSurface( entity_t *e, mapDrawSurface_t *ds ); +void EmitTriangleSurface( mapDrawSurface_t *ds ); /* surface_fur.c */ @@@ -1719,7 -1647,6 +1724,7 @@@ void MakeEntityM void FixMetaTJunctions( void ); void SmoothMetaTriangles( void ); void MergeMetaTriangles( void ); +void EmitMetaStats(); // vortex: print meta statistics even in no-verbose mode /* surface_extra.c */ @@@ -1733,7 -1660,6 +1738,7 @@@ int GetSurfaceE int GetSurfaceExtraCastShadows( int num ); int GetSurfaceExtraRecvShadows( int num ); int GetSurfaceExtraSampleSize( int num ); +int GetSurfaceExtraMinSampleSize( int num ); float GetSurfaceExtraLongestCurve( int num ); void GetSurfaceExtraLightmapAxis( int num, vec3_t lightmapAxis ); @@@ -1745,8 -1671,6 +1750,8 @@@ void LoadSurface void ProcessDecals( void ); void MakeEntityDecals( entity_t *e ); +/* map.c */ +void TextureAxisFromPlane( plane_t *pln, vec3_t xv, vec3_t yv ); /* brush_primit.c */ void ComputeAxisBase( vec3_t normal, vec3_t texX, vec3_t texY ); @@@ -1800,16 -1724,9 +1805,16 @@@ void SetupDirt() float DirtForSample( trace_t *trace ); void DirtyRawLightmap( int num ); +void SetupFloodLight(); +void FloodlightRawLightmaps(); +void FloodlightIlluminateLightmap( rawLightmap_t *lm ); +float FloodLightForSample( trace_t *trace, float floodLightDistance, qboolean floodLightLowQuality ); +void FloodLightRawLightmap( int num ); + void IlluminateRawLightmap( int num ); void IlluminateVertexes( int num ); +void SetupBrushesFlags( int mask_any, int test_any, int mask_all, int test_all ); void SetupBrushes( void ); void SetupClusters( void ); qboolean ClusterVisible( int a, int b ); @@@ -1860,7 -1777,6 +1865,7 @@@ void EmitVertexR void LoadShaderInfo( void ); shaderInfo_t *ShaderInfoForShader( const char *shader ); +shaderInfo_t *ShaderInfoForShaderNull( const char *shader ); /* bspfile_abstract.c */ @@@ -1876,7 -1792,6 +1881,7 @@@ void SwapBlock( int GetLumpElements( bspHeader_t *header, int lump, int size ); void *GetLump( bspHeader_t *header, int lump ); int CopyLump( bspHeader_t *header, int lump, void *dest, int size ); +int CopyLump_Allocate( bspHeader_t *header, int lump, void **dest, int size, int *allocationVariable ); void AddLump( FILE *file, bspHeader_t *header, int lumpNum, const void *data, int length ); void LoadBSPFile( const char *filename ); @@@ -1888,15 -1803,12 +1893,15 @@@ void ParseEntiti void UnparseEntities( void ); void PrintEntity( const entity_t *ent ); void SetKeyValue( entity_t *ent, const char *key, const char *value ); +qboolean KeyExists( const entity_t *ent, const char *key ); /* VorteX: check if key exists */ const char *ValueForKey( const entity_t *ent, const char *key ); int IntForKey( const entity_t *ent, const char *key ); vec_t FloatForKey( const entity_t *ent, const char *key ); void GetVectorForKey( const entity_t *ent, const char *key, vec3_t vec ); entity_t *FindTargetEntity( const char *target ); void GetEntityShadowFlags( const entity_t *ent, const entity_t *ent2, int *castShadows, int *recvShadows ); +void InjectCommandLine( char **argv, int beginArgs, int endArgs ); + /* bspfile_ibsp.c */ @@@ -1936,8 -1848,6 +1941,8 @@@ Q_EXTERN game_t games[ #include "game_quakelive.h" /* most be after game_quake3.h as they share defines! */ , #include "game_nexuiz.h" /* most be after game_quake3.h as they share defines! */ + , + #include "game_xonotic.h" /* most be after game_quake3.h as they share defines! */ , #include "game_tremulous.h" /*LinuxManMikeC: must be after game_quake3.h, depends on #define's set in it */ , @@@ -1961,13 -1871,7 +1966,13 @@@ , #include "game_reaction.h" /* must be after game_quake3.h */ , - { NULL } /* null game */ + #include "game_darkplaces.h" /* vortex: darkplaces q1 engine */ + , + #include "game_dq.h" /* vortex: deluxe quake game ( darkplaces q1 engine) */ + , + #include "game_prophecy.h" /* vortex: prophecy game ( darkplaces q1 engine) */ + , + #include "game__null.h" /* null game (must be last item) */ }; #endif Q_EXTERN game_t *game Q_ASSIGN( &games[ 0 ] ); @@@ -2015,9 -1919,6 +2020,9 @@@ Q_EXTERN qboolean nofog Q_ASSIGN( qfals Q_EXTERN qboolean noHint Q_ASSIGN( qfalse ); /* ydnar */ Q_EXTERN qboolean renameModelShaders Q_ASSIGN( qfalse ); /* ydnar */ Q_EXTERN qboolean skyFixHack Q_ASSIGN( qfalse ); /* ydnar */ +Q_EXTERN qboolean bspAlternateSplitWeights Q_ASSIGN( qfalse ); /* 27 */ +Q_EXTERN qboolean deepBSP Q_ASSIGN( qfalse ); /* div0 */ +Q_EXTERN qboolean maxAreaFaceSurface Q_ASSIGN( qfalse ); /* divVerent */ Q_EXTERN int patchSubdivisions Q_ASSIGN( 8 ); /* ydnar: -patchmeta subdivisions */ @@@ -2034,12 -1935,6 +2039,12 @@@ Q_EXTERN qboolean emitFlares Q_ASSIGN( Q_EXTERN qboolean debugSurfaces Q_ASSIGN( qfalse ); Q_EXTERN qboolean debugInset Q_ASSIGN( qfalse ); Q_EXTERN qboolean debugPortals Q_ASSIGN( qfalse ); +Q_EXTERN qboolean lightmapTriangleCheck Q_ASSIGN( qfalse ); +Q_EXTERN qboolean lightmapExtraVisClusterNudge Q_ASSIGN( qfalse ); +Q_EXTERN qboolean lightmapFill Q_ASSIGN( qfalse ); +Q_EXTERN int metaAdequateScore Q_ASSIGN( -1 ); +Q_EXTERN int metaGoodScore Q_ASSIGN( -1 ); +Q_EXTERN float metaMaxBBoxDistance Q_ASSIGN( -1 ); #if Q3MAP2_EXPERIMENTAL_SNAP_NORMAL_FIX // Increasing the normalEpsilon to compensate for new logic in SnapNormal(), where @@@ -2082,16 -1977,13 +2087,16 @@@ Q_EXTERN char source[ 1024 ] Q_EXTERN char outbase[ 32 ]; Q_EXTERN int sampleSize; /* lightmap sample size in units */ +Q_EXTERN int minSampleSize; /* minimum sample size to use at all */ +Q_EXTERN int sampleScale; /* vortex: lightmap sample scale (ie quality)*/ Q_EXTERN int mapEntityNum Q_ASSIGN( 0 ); Q_EXTERN int entitySourceBrushes; -Q_EXTERN plane_t mapplanes[ MAX_MAP_PLANES ]; /* mapplanes[ num ^ 1 ] will always be the mirror or mapplanes[ num ] */ -Q_EXTERN int nummapplanes; /* nummapplanes will always be even */ +Q_EXTERN plane_t *mapplanes Q_ASSIGN( NULL ); /* mapplanes[ num ^ 1 ] will always be the mirror or mapplanes[ num ] */ +Q_EXTERN int nummapplanes Q_ASSIGN( 0 ); /* nummapplanes will always be even */ +Q_EXTERN int allocatedmapplanes Q_ASSIGN( 0 ); Q_EXTERN int numMapPatches; Q_EXTERN vec3_t mapMins, mapMaxs; @@@ -2114,7 -2006,6 +2119,7 @@@ Q_EXTERN int numMapDrawSurfs Q_EXTERN int numSurfacesByType[ NUM_SURFACE_TYPES ]; Q_EXTERN int numClearedSurfaces; Q_EXTERN int numStripSurfaces; +Q_EXTERN int numMaxAreaSurfaces; Q_EXTERN int numFanSurfaces; Q_EXTERN int numMergedSurfaces; Q_EXTERN int numMergedVerts; @@@ -2161,12 -2052,13 +2166,12 @@@ Q_EXTERN qboolean fastvis Q_EXTERN qboolean noPassageVis; Q_EXTERN qboolean passageVisOnly; Q_EXTERN qboolean mergevis; +Q_EXTERN qboolean mergevisportals; Q_EXTERN qboolean nosort; Q_EXTERN qboolean saveprt; Q_EXTERN qboolean hint; /* ydnar */ Q_EXTERN char inbase[ MAX_QPATH ]; - -/* other bits */ -Q_EXTERN int totalvis; +Q_EXTERN char globalCelShader[ MAX_QPATH ]; Q_EXTERN float farPlaneDist; /* rr2do2, rf, mre, ydnar all contributed to this one... */ @@@ -2207,13 -2099,10 +2212,13 @@@ Q_EXTERN vportal_t *sorted_por /* commandline arguments */ Q_EXTERN qboolean wolfLight Q_ASSIGN( qfalse ); +Q_EXTERN float extraDist Q_ASSIGN( 0.0f ); Q_EXTERN qboolean loMem Q_ASSIGN( qfalse ); Q_EXTERN qboolean noStyles Q_ASSIGN( qfalse ); +Q_EXTERN qboolean keepLights Q_ASSIGN( qfalse ); Q_EXTERN int sampleSize Q_ASSIGN( DEFAULT_LIGHTMAP_SAMPLE_SIZE ); +Q_EXTERN int minSampleSize Q_ASSIGN( DEFAULT_LIGHTMAP_MIN_SAMPLE_SIZE ); Q_EXTERN qboolean noVertexLighting Q_ASSIGN( qfalse ); Q_EXTERN qboolean noGridLighting Q_ASSIGN( qfalse ); @@@ -2224,10 -2113,8 +2229,10 @@@ Q_EXTERN qboolean cpmaHack Q_ASSIGN( qf Q_EXTERN qboolean deluxemap Q_ASSIGN( qfalse ); Q_EXTERN qboolean debugDeluxemap Q_ASSIGN( qfalse ); +Q_EXTERN int deluxemode Q_ASSIGN( 0 ); /* deluxemap format (0 - modelspace, 1 - tangentspace with renormalization, 2 - tangentspace without renormalization) */ Q_EXTERN qboolean fast Q_ASSIGN( qfalse ); +Q_EXTERN qboolean fastpoint Q_ASSIGN( qtrue ); Q_EXTERN qboolean faster Q_ASSIGN( qfalse ); Q_EXTERN qboolean fastgrid Q_ASSIGN( qfalse ); Q_EXTERN qboolean fastbounce Q_ASSIGN( qfalse ); @@@ -2243,19 -2130,14 +2248,19 @@@ Q_EXTERN qboolean shade Q_ASSIGN( qfals Q_EXTERN float shadeAngleDegrees Q_ASSIGN( 0.0f ); Q_EXTERN int superSample Q_ASSIGN( 0 ); Q_EXTERN int lightSamples Q_ASSIGN( 1 ); +Q_EXTERN qboolean lightRandomSamples Q_ASSIGN( qfalse ); +Q_EXTERN int lightSamplesSearchBoxSize Q_ASSIGN( 1 ); Q_EXTERN qboolean filter Q_ASSIGN( qfalse ); Q_EXTERN qboolean dark Q_ASSIGN( qfalse ); Q_EXTERN qboolean sunOnly Q_ASSIGN( qfalse ); Q_EXTERN int approximateTolerance Q_ASSIGN( 0 ); Q_EXTERN qboolean noCollapse Q_ASSIGN( qfalse ); +Q_EXTERN int lightmapSearchBlockSize Q_ASSIGN( 0 ); Q_EXTERN qboolean exportLightmaps Q_ASSIGN( qfalse ); Q_EXTERN qboolean externalLightmaps Q_ASSIGN( qfalse ); Q_EXTERN int lmCustomSize Q_ASSIGN( LIGHTMAP_WIDTH ); +Q_EXTERN char * lmCustomDir Q_ASSIGN( NULL ); +Q_EXTERN int lmLimitSize Q_ASSIGN( 0 ); Q_EXTERN qboolean dirty Q_ASSIGN( qfalse ); Q_EXTERN qboolean dirtDebug Q_ASSIGN( qfalse ); @@@ -2264,15 -2146,6 +2269,15 @@@ Q_EXTERN float dirtDepth Q_ASSIGN( 128. Q_EXTERN float dirtScale Q_ASSIGN( 1.0f ); Q_EXTERN float dirtGain Q_ASSIGN( 1.0f ); +/* 27: floodlighting */ +Q_EXTERN qboolean debugnormals Q_ASSIGN( qfalse ); +Q_EXTERN qboolean floodlighty Q_ASSIGN( qfalse ); +Q_EXTERN qboolean floodlight_lowquality Q_ASSIGN( qfalse ); +Q_EXTERN vec3_t floodlightRGB; +Q_EXTERN float floodlightIntensity Q_ASSIGN( 512.0f ); +Q_EXTERN float floodlightDistance Q_ASSIGN( 1024.0f ); +Q_EXTERN float floodlightDirectionScale Q_ASSIGN( 1.0f ); + Q_EXTERN qboolean dump Q_ASSIGN( qfalse ); Q_EXTERN qboolean debug Q_ASSIGN( qfalse ); Q_EXTERN qboolean debugUnused Q_ASSIGN( qfalse ); @@@ -2286,27 -2159,12 +2291,27 @@@ Q_EXTERN float maxMapDistance Q_ASSIGN /* for run time tweaking of light sources */ Q_EXTERN float pointScale Q_ASSIGN( 7500.0f ); +Q_EXTERN float spotScale Q_ASSIGN( 7500.0f ); Q_EXTERN float areaScale Q_ASSIGN( 0.25f ); Q_EXTERN float skyScale Q_ASSIGN( 1.0f ); Q_EXTERN float bounceScale Q_ASSIGN( 0.25f ); +/* jal: alternative angle attenuation curve */ +Q_EXTERN qboolean lightAngleHL Q_ASSIGN( qfalse ); + +/* vortex: gridscale and gridambientscale */ +Q_EXTERN float gridScale Q_ASSIGN( 1.0f ); +Q_EXTERN float gridAmbientScale Q_ASSIGN( 1.0f ); +Q_EXTERN float gridDirectionality Q_ASSIGN( 1.0f ); +Q_EXTERN float gridAmbientDirectionality Q_ASSIGN( 0.0f ); +Q_EXTERN qboolean inGrid Q_ASSIGN( 0 ); + /* ydnar: lightmap gamma/compensation */ Q_EXTERN float lightmapGamma Q_ASSIGN( 1.0f ); +Q_EXTERN float lightmapsRGB Q_ASSIGN( qfalse ); +Q_EXTERN float texturesRGB Q_ASSIGN( qfalse ); +Q_EXTERN float colorsRGB Q_ASSIGN( qfalse ); +Q_EXTERN float lightmapExposure Q_ASSIGN( 0.0f ); Q_EXTERN float lightmapCompensate Q_ASSIGN( 1.0f ); /* ydnar: for runtime tweaking of falloff tolerance */ @@@ -2315,10 -2173,6 +2320,10 @@@ Q_EXTERN qboolean exactPointToPolygon Q Q_EXTERN float formFactorValueScale Q_ASSIGN( 3.0f ); Q_EXTERN float linearScale Q_ASSIGN( 1.0f / 8000.0f ); +// for .ase conversion +Q_EXTERN qboolean shadersAsBitmap Q_ASSIGN( qfalse ); +Q_EXTERN qboolean lightmapsAsTexcoord Q_ASSIGN( qfalse ); + Q_EXTERN light_t *lights; Q_EXTERN int numPointLights; Q_EXTERN int numSpotLights; @@@ -2415,9 -2269,6 +2420,9 @@@ Q_EXTERN int numBSPLightmaps Q_ASSIGN( Q_EXTERN int numExtLightmaps Q_ASSIGN( 0 ); Q_EXTERN outLightmap_t *outLightmaps Q_ASSIGN( NULL ); +/* vortex: per surface floodlight statictics */ +Q_EXTERN int numSurfacesFloodlighten Q_ASSIGN( 0 ); + /* grid points */ Q_EXTERN int numRawGridPoints Q_ASSIGN( 0 ); Q_EXTERN rawGridPoint_t *rawGridPoints Q_ASSIGN( NULL ); @@@ -2457,47 -2308,37 +2462,47 @@@ Q_EXTERN vec3_t gridSiz Q_EXTERN int numEntities Q_ASSIGN( 0 ); Q_EXTERN int numBSPEntities Q_ASSIGN( 0 ); -Q_EXTERN entity_t entities[ MAX_MAP_ENTITIES ]; +Q_EXTERN int allocatedEntities Q_ASSIGN( 0 ); +Q_EXTERN entity_t* entities Q_ASSIGN( NULL ); Q_EXTERN int numBSPModels Q_ASSIGN( 0 ); -Q_EXTERN bspModel_t bspModels[ MAX_MAP_MODELS ]; +Q_EXTERN int allocatedBSPModels Q_ASSIGN( 0 ); +Q_EXTERN bspModel_t* bspModels Q_ASSIGN( NULL ); Q_EXTERN int numBSPShaders Q_ASSIGN( 0 ); -Q_EXTERN bspShader_t bspShaders[ MAX_MAP_MODELS ]; +Q_EXTERN int allocatedBSPShaders Q_ASSIGN( 0 ); +Q_EXTERN bspShader_t* bspShaders Q_ASSIGN( 0 ); Q_EXTERN int bspEntDataSize Q_ASSIGN( 0 ); -Q_EXTERN char bspEntData[ MAX_MAP_ENTSTRING ]; +Q_EXTERN int allocatedBSPEntData Q_ASSIGN( 0 ); +Q_EXTERN char *bspEntData Q_ASSIGN( 0 ); Q_EXTERN int numBSPLeafs Q_ASSIGN( 0 ); Q_EXTERN bspLeaf_t bspLeafs[ MAX_MAP_LEAFS ]; Q_EXTERN int numBSPPlanes Q_ASSIGN( 0 ); -Q_EXTERN bspPlane_t bspPlanes[ MAX_MAP_PLANES ]; +Q_EXTERN int allocatedBSPPlanes Q_ASSIGN( 0 ); +Q_EXTERN bspPlane_t *bspPlanes; Q_EXTERN int numBSPNodes Q_ASSIGN( 0 ); -Q_EXTERN bspNode_t bspNodes[ MAX_MAP_NODES ]; +Q_EXTERN int allocatedBSPNodes Q_ASSIGN( 0 ); +Q_EXTERN bspNode_t* bspNodes Q_ASSIGN( NULL ); Q_EXTERN int numBSPLeafSurfaces Q_ASSIGN( 0 ); -Q_EXTERN int bspLeafSurfaces[ MAX_MAP_LEAFFACES ]; +Q_EXTERN int allocatedBSPLeafSurfaces Q_ASSIGN( 0 ); +Q_EXTERN int* bspLeafSurfaces Q_ASSIGN( NULL ); Q_EXTERN int numBSPLeafBrushes Q_ASSIGN( 0 ); -Q_EXTERN int bspLeafBrushes[ MAX_MAP_LEAFBRUSHES ]; +Q_EXTERN int allocatedBSPLeafBrushes Q_ASSIGN( 0 ); +Q_EXTERN int* bspLeafBrushes Q_ASSIGN( NULL ); Q_EXTERN int numBSPBrushes Q_ASSIGN( 0 ); -Q_EXTERN bspBrush_t bspBrushes[ MAX_MAP_BRUSHES ]; +Q_EXTERN int allocatedBSPBrushes Q_ASSIGN( 0 ); +Q_EXTERN bspBrush_t* bspBrushes Q_ASSIGN( NULL ); Q_EXTERN int numBSPBrushSides Q_ASSIGN( 0 ); -Q_EXTERN bspBrushSide_t bspBrushSides[ MAX_MAP_BRUSHSIDES ]; +Q_EXTERN int allocatedBSPBrushSides Q_ASSIGN( 0 ); +Q_EXTERN bspBrushSide_t* bspBrushSides Q_ASSIGN( NULL ); Q_EXTERN int numBSPLightBytes Q_ASSIGN( 0 ); Q_EXTERN byte *bspLightBytes Q_ASSIGN( NULL ); @@@ -2512,11 -2353,10 +2517,11 @@@ Q_EXTERN int numBSPVisBytes Q_ASSIGN( Q_EXTERN byte bspVisBytes[ MAX_MAP_VISIBILITY ]; Q_EXTERN int numBSPDrawVerts Q_ASSIGN( 0 ); -Q_EXTERN bspDrawVert_t *bspDrawVerts Q_ASSIGN( NULL ); +Q_EXTERN bspDrawVert_t *bspDrawVerts Q_ASSIGN( NULL ); Q_EXTERN int numBSPDrawIndexes Q_ASSIGN( 0 ); -Q_EXTERN int bspDrawIndexes[ MAX_MAP_DRAW_INDEXES ]; +Q_EXTERN int allocatedBSPDrawIndexes Q_ASSIGN( 0 ); +Q_EXTERN int *bspDrawIndexes Q_ASSIGN( NULL ); Q_EXTERN int numBSPDrawSurfaces Q_ASSIGN( 0 ); Q_EXTERN bspDrawSurface_t *bspDrawSurfaces Q_ASSIGN( NULL ); @@@ -2527,30 -2367,6 +2532,30 @@@ Q_EXTERN bspFog_t bspFogs[ MAX_MAP_FOG Q_EXTERN int numBSPAds Q_ASSIGN( 0 ); Q_EXTERN bspAdvertisement_t bspAds[ MAX_MAP_ADVERTISEMENTS ]; +#define AUTOEXPAND_BY_REALLOC( ptr, reqitem, allocated, def ) \ + do \ + { \ + if ( reqitem >= allocated ) \ + { \ + if ( allocated == 0 ) { \ + allocated = def; } \ + while ( reqitem >= allocated && allocated ) \ + allocated *= 2; \ + if ( !allocated || allocated > 2147483647 / (int)sizeof( *ptr ) ) \ + { \ + Error( # ptr " over 2 GB" ); \ + } \ + ptr = realloc( ptr, sizeof( *ptr ) * allocated ); \ + if ( !ptr ) { \ + Error( # ptr " out of memory" ); } \ + } \ + } \ + while ( 0 ) + +#define AUTOEXPAND_BY_REALLOC_BSP( suffix, def ) AUTOEXPAND_BY_REALLOC( bsp ## suffix, numBSP ## suffix, allocatedBSP ## suffix, def ) + +#define Image_LinearFloatFromsRGBFloat( c ) ( ( ( c ) <= 0.04045f ) ? ( c ) * ( 1.0f / 12.92f ) : (float)pow( ( ( c ) + 0.055f ) * ( 1.0f / 1.055f ), 2.4f ) ) +#define Image_sRGBFloatFromLinearFloat( c ) ( ( ( c ) < 0.0031308f ) ? ( c ) * 12.92f : 1.055f * (float)pow( ( c ), 1.0f / 2.4f ) - 0.055f ) /* end marker */ #endif