//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
# if defined(WIN32) && !defined( _X360 )
# include <windows.h>
# endif
# include "filesystem.h"
# include "filesystem_init.h"
# include "appframework/IAppSystemGroup.h"
# include "appframework/IAppSystem.h"
# include "appframework/AppFramework.h"
# include "filesystem_helpers.h"
# include "matsys_controls/QCGenerator.h"
# include "tier1/KeyValues.h"
# include "tier2/vconfig.h"
# include "vgui_controls/ListPanel.h"
# include "vgui_controls/TextEntry.h"
# include "vgui_controls/Button.h"
# include "vgui_controls/FileOpenDialog.h"
# include "vgui_controls/DirectorySelectDialog.h"
# include "vgui_controls/ComboBox.h"
# include "vgui_controls/CheckButton.h"
# include "vgui_controls/MessageBox.h"
# include "vgui/ISurface.h"
# include "vgui/IInput.h"
# include "vgui/Cursor.h"
# include "vgui_controls/KeyBoardEditorDialog.h"
# if defined( _X360 )
# include "xbox/xbox_win32stubs.h"
# endif
using namespace vgui ;
# define MAX_KEYVALUE 1024
//-----------------------------------------------------------------------------
// Purpose: returns a pointer to the 'count' occurence of a character from the end of a string
// returns 0 of there aren't 'count' number of the character in the string
//-----------------------------------------------------------------------------
char * strrchrcount ( char * string , int character , int count )
{
int j = count ;
int numChars = strlen ( string ) ;
for ( int i = numChars ; i > 0 ; i - - )
{
if ( string [ i - 1 ] = = character )
{
j - - ;
}
if ( j = = 0 )
{
return string + i - 1 ;
}
}
return 0 ;
}
class CModalPreserveMessageBox : public vgui : : MessageBox
{
public :
CModalPreserveMessageBox ( const char * title , const char * text , vgui : : Panel * parent )
: vgui : : MessageBox ( title , text , parent )
{
m_PrevAppFocusPanel = vgui : : input ( ) - > GetAppModalSurface ( ) ;
}
~ CModalPreserveMessageBox ( )
{
vgui : : input ( ) - > SetAppModalSurface ( m_PrevAppFocusPanel ) ;
}
public :
vgui : : VPANEL m_PrevAppFocusPanel ;
} ;
void VGUIMessageBox ( vgui : : Panel * pParent , const char * pTitle , const char * pMsg , . . . )
{
char msg [ 4096 ] ;
va_list marker ;
va_start ( marker , pMsg ) ;
Q_vsnprintf ( msg , sizeof ( msg ) , pMsg , marker ) ;
va_end ( marker ) ;
vgui : : MessageBox * dlg = new CModalPreserveMessageBox ( pTitle , msg , pParent ) ;
dlg - > DoModal ( ) ;
dlg - > Activate ( ) ;
dlg - > RequestFocus ( ) ;
}
//-----------------------------------------------------------------------------
// Purpose: Places all the info from the vgui controls into the QCInfo struct
//-----------------------------------------------------------------------------
void QCInfo : : SyncFromControls ( )
{
char tempText [ MAX_PATH ] ;
vgui : : Panel * pTargetField = pQCGenerator - > FindChildByName ( " staticPropCheck " ) ;
bStaticProp = ( ( CheckButton * ) pTargetField ) - > IsSelected ( ) ;
pTargetField = pQCGenerator - > FindChildByName ( " mostlyOpaqueCheck " ) ;
bMostlyOpaque = ( ( CheckButton * ) pTargetField ) - > IsSelected ( ) ;
pTargetField = pQCGenerator - > FindChildByName ( " disableCollisionsCheck " ) ;
bDisableCollision = ( ( CheckButton * ) pTargetField ) - > IsSelected ( ) ;
pTargetField = pQCGenerator - > FindChildByName ( " referencePhysicsCheck " ) ;
bReferenceAsPhys = ( ( CheckButton * ) pTargetField ) - > IsSelected ( ) ;
pTargetField = pQCGenerator - > FindChildByName ( " concaveCheck " ) ;
bConcave = ( ( CheckButton * ) pTargetField ) - > IsSelected ( ) ;
pTargetField = pQCGenerator - > FindChildByName ( " automassCheck " ) ;
bAutomass = ( ( CheckButton * ) pTargetField ) - > IsSelected ( ) ;
pTargetField = pQCGenerator - > FindChildByName ( " massField " ) ;
( ( TextEntry * ) pTargetField ) - > GetText ( tempText , MAX_PATH ) ;
fMass = atof ( tempText ) ;
pTargetField = pQCGenerator - > FindChildByName ( " scaleField " ) ;
( ( TextEntry * ) pTargetField ) - > GetText ( tempText , MAX_PATH ) ;
fScale = atof ( tempText ) ;
pTargetField = pQCGenerator - > FindChildByName ( " collisionSMDField " ) ;
( ( TextEntry * ) pTargetField ) - > GetText ( tempText , MAX_PATH ) ;
V_strcpy_safe ( pszCollisionPath , tempText ) ;
pTargetField = pQCGenerator - > FindChildByName ( " surfacePropertyDropDown " ) ;
( ( ComboBox * ) pTargetField ) - > GetText ( tempText , MAX_PATH ) ;
V_strcpy_safe ( pszSurfaceProperty , tempText ) ;
pTargetField = pQCGenerator - > FindChildByName ( " materialsField " ) ;
( ( TextEntry * ) pTargetField ) - > GetText ( tempText , MAX_PATH ) ;
V_strcpy_safe ( pszMaterialPath , tempText ) ;
LODs . RemoveAll ( ) ;
pTargetField = pQCGenerator - > FindChildByName ( " LODList " ) ;
int numLOD = ( ( ListPanel * ) pTargetField ) - > GetItemCount ( ) ;
for ( int i = 0 ; i < numLOD ; i + + )
{
KeyValues * key = ( ( ListPanel * ) pTargetField ) - > GetItem ( i ) ;
LODInfo newLOD ;
V_strcpy_safe ( newLOD . pszFilename , key - > GetString ( " SMD " ) ) ;
newLOD . iLOD = key - > GetInt ( " LOD " ) ;
LODs . AddToTail ( newLOD ) ;
}
}
//-----------------------------------------------------------------------------
// Purpose: Called during intialization to setup the initial state of the VGUI controls
//-----------------------------------------------------------------------------
void QCInfo : : SyncToControls ( )
{
char tempText [ MAX_PATH ] ;
vgui : : Panel * pTargetField = pQCGenerator - > FindChildByName ( " staticPropCheck " ) ;
( ( CheckButton * ) pTargetField ) - > SetSelected ( bStaticProp ) ;
pTargetField = pQCGenerator - > FindChildByName ( " mostlyOpaqueCheck " ) ;
( ( CheckButton * ) pTargetField ) - > SetSelected ( bMostlyOpaque ) ;
pTargetField = pQCGenerator - > FindChildByName ( " disableCollisionsCheck " ) ;
( ( CheckButton * ) pTargetField ) - > SetSelected ( bDisableCollision ) ;
pTargetField = pQCGenerator - > FindChildByName ( " referencePhysicsCheck " ) ;
( ( CheckButton * ) pTargetField ) - > SetSelected ( bReferenceAsPhys ) ;
pTargetField = pQCGenerator - > FindChildByName ( " concaveCheck " ) ;
( ( CheckButton * ) pTargetField ) - > SetSelected ( bConcave ) ;
pTargetField = pQCGenerator - > FindChildByName ( " automassCheck " ) ;
( ( CheckButton * ) pTargetField ) - > SetSelected ( bAutomass ) ;
Q_snprintf ( tempText , 10 , " %d " , ( int ) fMass ) ;
pTargetField = pQCGenerator - > FindChildByName ( " massField " ) ;
( ( TextEntry * ) pTargetField ) - > SetText ( tempText ) ;
Q_snprintf ( tempText , 10 , " %d " , ( int ) fScale ) ;
pTargetField = pQCGenerator - > FindChildByName ( " scaleField " ) ;
( ( TextEntry * ) pTargetField ) - > SetText ( tempText ) ;
pTargetField = pQCGenerator - > FindChildByName ( " collisionSMDField " ) ;
( ( TextEntry * ) pTargetField ) - > SetText ( pszCollisionPath ) ;
pTargetField = pQCGenerator - > FindChildByName ( " materialsField " ) ;
( ( TextEntry * ) pTargetField ) - > SetText ( pszMaterialPath ) ;
pTargetField = pQCGenerator - > FindChildByName ( " surfacePropertyDropDown " ) ;
int numItems = ( ( ComboBox * ) pTargetField ) - > GetItemCount ( ) ;
for ( int i = 0 ; i < numItems ; i + + )
{
( ( ComboBox * ) pTargetField ) - > GetItemText ( i , tempText , MAX_PATH ) ;
if ( ! Q_strcmp ( tempText , pszSurfaceProperty ) )
{
( ( ComboBox * ) pTargetField ) - > SetItemEnabled ( i , true ) ;
( ( ComboBox * ) pTargetField ) - > SetText ( tempText ) ;
break ;
}
}
}
CBrowseButton : : CBrowseButton ( vgui : : Panel * pParent ) : BaseClass ( pParent , " Browse Button " , " ... " , pParent , " browse " )
{
SetParent ( pParent ) ;
pszStartingDirectory = NULL ;
pszFileFilter = NULL ;
pszTargetField = NULL ;
}
CBrowseButton : : ~ CBrowseButton ( )
{
}
void CBrowseButton : : SetCharVar ( char * * pVar , const char * pszNewText )
{
if ( * pVar & & pszNewText & & ! Q_strcmp ( * pVar , pszNewText ) )
{
return ;
}
if ( * pVar )
{
delete [ ] * pVar ;
* pVar = NULL ;
}
if ( pszNewText )
{
int len = Q_strlen ( pszNewText ) + 1 ;
* pVar = new char [ len ] ;
Q_strncpy ( * pVar , pszNewText , len ) ;
}
}
void CBrowseButton : : InitBrowseInfo ( int x , int y , const char * pszName , const char * pszDir , const char * pszFilter , const char * pszField )
{
SetSize ( 24 , 24 ) ;
SetPos ( x , y ) ;
SetName ( pszName ) ;
SetCharVar ( GetStartingDirectory ( ) , pszDir ) ;
SetCharVar ( GetFileFilter ( ) , pszFilter ) ;
SetCharVar ( GetTargetField ( ) , pszField ) ;
SetActionMessage ( ) ;
}
void CBrowseButton : : SetActionMessage ( )
{
KeyValues * newActionMessage = new KeyValues ( " browse " , " directory " , pszStartingDirectory , " filter " , pszFileFilter ) ;
newActionMessage - > SetString ( " targetField " , pszTargetField ) ;
SetCommand ( newActionMessage ) ;
}
const char * ParseKeyvalue ( const char * pBuffer , char * key , char * value )
{
char com_token [ 1024 ] ;
pBuffer = ( const char * ) ParseFile ( pBuffer , com_token , NULL ) ;
if ( Q_strlen ( com_token ) < MAX_KEYVALUE )
{
Q_strncpy ( key , com_token , MAX_KEYVALUE ) ;
Q_strlower ( key ) ;
}
// no value on a close brace
if ( ! Q_strcmp ( key , " } " ) )
{
value [ 0 ] = 0 ;
return pBuffer ;
}
pBuffer = ( const char * ) ParseFile ( pBuffer , com_token , NULL ) ;
if ( Q_strlen ( com_token ) < MAX_KEYVALUE )
{
Q_strncpy ( value , com_token , MAX_KEYVALUE ) ;
Q_strlower ( value ) ;
}
return pBuffer ;
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CQCGenerator : : CQCGenerator ( vgui : : Panel * pParent , const char * pszPath , const char * pszScene ) : BaseClass ( pParent , " QCGenerator " )
{
m_QCInfo_t . Init ( this ) ;
SetMinimumSize ( 846 , 770 ) ;
m_pLODPanel = new ListPanel ( this , " LODList " ) ;
m_pLODPanel - > SetSelectIndividualCells ( true ) ;
m_pLODPanel - > AddColumnHeader ( 0 , " SMD " , " LOD SMD " , 450 , 0 ) ;
m_pLODPanel - > AddColumnHeader ( 1 , " LOD " , " LOD Distance " , 50 , 0 ) ;
m_pLODPanel - > AddActionSignalTarget ( this ) ;
m_pLODPanel - > SetMouseInputEnabled ( true ) ;
LoadControlSettings ( " QCGenerator.res " ) ;
m_pCollisionBrowseButton = new CBrowseButton ( this ) ;
m_pCollisionBrowseButton - > InitBrowseInfo ( 808 , 158 , " collisionBrowseButton " , pszPath , " *.smd " , " collisionSMDField " ) ;
char szTerminatedPath [ 1024 ] = " \0 " ;
sprintf ( szTerminatedPath , " %s \\ " , pszPath ) ;
InitializeSMDPaths ( szTerminatedPath , pszScene ) ;
char * pszMaterialsStart = strrchrcount ( szTerminatedPath , ' \\ ' , 3 ) + 1 ;
char * pszMaterialsEnd = strrchr ( szTerminatedPath , ' \\ ' ) ;
Q_strncpy ( m_QCInfo_t . pszMaterialPath , pszMaterialsStart , pszMaterialsEnd - pszMaterialsStart + 1 ) ;
SetParent ( pParent ) ;
char szGamePath [ 1024 ] = " \0 " ;
char szSearchPath [ 2048 ] = " \0 " ;
// Get the currently set game configuration
GetVConfigRegistrySetting ( GAMEDIR_TOKEN , szGamePath , sizeof ( szGamePath ) ) ;
static const char * pSurfacePropFilename = " \\ scripts \\ surfaceproperties.txt " ;
snprintf ( szSearchPath , sizeof ( szSearchPath ) , " %s%s " , szGamePath , pSurfacePropFilename ) ;
FileHandle_t fp = g_pFullFileSystem - > Open ( szSearchPath , " rb " ) ;
if ( ! fp )
{
//the set game configuration didn't have a surfaceproperties file; we are grabbing it from hl2
//TODO: This only works if they are in a subdirectory that is a peer to an hl2 directory
// that contains the file. It potentially needs to search the entire drive or prompt for the location
char * pszEndGamePath = Q_strrchr ( szGamePath , ' \\ ' ) ;
pszEndGamePath [ 0 ] = 0 ;
V_strcat_safe ( szGamePath , " \\ hl2 " ) ;
snprintf ( szSearchPath , sizeof ( szSearchPath ) , " %s%s " , szGamePath , pSurfacePropFilename ) ;
fp = g_pFullFileSystem - > Open ( szSearchPath , " rb " ) ;
}
int len = g_pFullFileSystem - > Size ( fp ) ;
const char * szSurfacePropContents = new char [ len + 1 ] ;
g_pFullFileSystem - > Read ( ( void * ) szSurfacePropContents , len , fp ) ;
char key [ MAX_KEYVALUE ] , value [ MAX_KEYVALUE ] ;
vgui : : Panel * pSurfacePropDropDown = FindChildByName ( " surfacePropertyDropDown " ) ;
//filling up the surface property dropdown
while ( szSurfacePropContents )
{
szSurfacePropContents = ParseKeyvalue ( szSurfacePropContents , key , value ) ;
( ( ComboBox * ) pSurfacePropDropDown ) - > AddItem ( key , NULL ) ;
while ( szSurfacePropContents )
{
szSurfacePropContents = ParseKeyvalue ( szSurfacePropContents , key , value ) ;
if ( ! stricmp ( key , " } " ) )
{
break ;
}
}
}
m_QCInfo_t . SyncToControls ( ) ;
m_pLODEdit = 0 ;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CQCGenerator : : ~ CQCGenerator ( )
{
}
void CQCGenerator : : OnCommand ( const char * command )
{
if ( Q_stricmp ( command , " createQC " ) = = 0 )
{
m_QCInfo_t . SyncFromControls ( ) ;
GenerateQCFile ( ) ;
}
if ( Q_stricmp ( command , " deleteSeq " ) = = 0 )
{
//delete it
DeleteLOD ( ) ;
}
if ( Q_stricmp ( command , " editSeq " ) = = 0 )
{
//edit
EditLOD ( ) ;
}
BaseClass : : OnCommand ( command ) ;
}
void CQCGenerator : : OnKeyCodeTyped ( KeyCode code )
{
switch ( code )
{
case KEY_ENTER :
EditLOD ( ) ;
}
}
void CQCGenerator : : OnBrowse ( KeyValues * data )
{
V_strcpy_safe ( m_szTargetField , data - > GetString ( " targetField " ) ) ;
const char * filter = data - > GetString ( " filter " ) ;
if ( Q_strlen ( filter ) = = 0 )
{
// BrowseDirectory( data );
}
else
{
BrowseFile ( data ) ;
}
}
/*
//This function is no longer used in the current version of the program.
void CQCGenerator : : BrowseDirectory ( KeyValues * data )
{
DirectorySelectDialog * pDialog = new DirectorySelectDialog ( this , " Select Directory " ) ;
pDialog - > AddActionSignalTarget ( this ) ;
pDialog - > DoModal ( ) ;
pDialog - > SetStartDirectory ( data - > GetString ( " directory " ) ) ;
}
*/
void CQCGenerator : : BrowseFile ( KeyValues * data )
{
const char * filter = data - > GetString ( " filter " ) ;
FileOpenDialog * pDialog = new FileOpenDialog ( this , " Select File " , true ) ;
pDialog - > AddFilter ( filter , filter , true ) ;
pDialog - > AddActionSignalTarget ( this ) ;
pDialog - > SetStartDirectory ( data - > GetString ( " directory " ) ) ;
pDialog - > DoModal ( true ) ;
}
void CQCGenerator : : OnFileSelected ( KeyValues * data )
{
if ( m_szTargetField )
{
vgui : : Panel * pTargetField = FindChildByName ( m_szTargetField ) ;
( ( TextEntry * ) pTargetField ) - > SetText ( data - > GetString ( " fullpath " ) ) ;
Repaint ( ) ;
}
}
void CQCGenerator : : OnDirectorySelected ( KeyValues * data )
{
if ( m_szTargetField )
{
vgui : : Panel * pTargetField = FindChildByName ( m_szTargetField ) ;
( ( TextEntry * ) pTargetField ) - > SetText ( data - > GetString ( " dir " ) ) ;
Repaint ( ) ;
}
}
bool CQCGenerator : : GenerateQCFile ( )
{
//TODO: clean this up. Consider creating a datatype that includes the string to write out when the QC file is created
char * nameBegin = strrchr ( m_QCInfo_t . pszSMDPath , ' \\ ' ) ;
char szPath [ MAX_PATH ] ;
char szName [ MAX_PATH ] ;
Q_strncpy ( szPath , m_QCInfo_t . pszSMDPath , nameBegin - m_QCInfo_t . pszSMDPath + 2 ) ;
V_strcpy_safe ( szName , szPath ) ;
V_strcat_safe ( szName , m_QCInfo_t . pszSceneName ) ;
V_strcat_safe ( szName , " .qc " ) ;
FileHandle_t pSaveFile = g_pFullFileSystem - > Open ( szName , " wt " ) ;
if ( ! pSaveFile )
{
char szSaveError [ 1024 ] = " " ;
Q_snprintf ( szSaveError , 1024 , " Save failed: invalid file name '%s' \n \n Directory '%s' must exist. " , szName , szPath ) ;
VGUIMessageBox ( this , " QC Generator error " , szSaveError ) ;
return 0 ;
}
//write qc header
g_pFullFileSystem - > FPrintf ( pSaveFile , " // \n // .qc file version 1.0 \n \n " ) ;
//write out modelname info
char szModelName [ MAX_PATH ] ;
char * modelStart = strrchrcount ( szName , ' \\ ' , 2 ) + 1 ;
char * modelEnd = strrchr ( szName , ' . ' ) ;
Q_strncpy ( szModelName , modelStart , modelEnd - modelStart + 1 ) ;
V_strcat_safe ( szModelName , " .mdl " ) ;
g_pFullFileSystem - > FPrintf ( pSaveFile , " $modelname %s \n \n " , szModelName ) ;
//write out scale info
g_pFullFileSystem - > FPrintf ( pSaveFile , " $scale %f \n " , m_QCInfo_t . fScale ) ;
//write out body info
g_pFullFileSystem - > FPrintf ( pSaveFile , " $body \" Body \" \" %s \" \n " , strrchr ( m_QCInfo_t . pszSMDPath , ' \\ ' ) + 1 ) ;
if ( m_QCInfo_t . bStaticProp = = true )
{
g_pFullFileSystem - > FPrintf ( pSaveFile , " $staticprop \n " ) ;
}
if ( m_QCInfo_t . bMostlyOpaque = = true )
{
g_pFullFileSystem - > FPrintf ( pSaveFile , " $mostlyopaque \n " ) ;
}
//write out surfaceprop info
g_pFullFileSystem - > FPrintf ( pSaveFile , " $surfaceprop \" %s \" \n \n " , m_QCInfo_t . pszSurfaceProperty ) ;
//write materials
g_pFullFileSystem - > FPrintf ( pSaveFile , " $cdmaterials %s \n \n " , m_QCInfo_t . pszMaterialPath ) ;
if ( m_QCInfo_t . bStaticProp | | m_QCInfo_t . bNoAnimation )
{
g_pFullFileSystem - > FPrintf ( pSaveFile , " // --------- Animation sequences ------- \n " ) ;
g_pFullFileSystem - > FPrintf ( pSaveFile , " $sequence \" idle \" \" %s \" fps 30 \n \n " , strrchr ( m_QCInfo_t . pszSMDPath , ' \\ ' ) + 1 ) ;
}
//write out lod info
for ( int i = 0 ; i < m_QCInfo_t . LODs . Count ( ) ; i + + )
{
LODInfo thisLOD = m_QCInfo_t . LODs . Element ( i ) ;
g_pFullFileSystem - > FPrintf ( pSaveFile , " $lod %d \n { \n \t replacemodel \" %s \" \" %s \" \n } \n \n " , thisLOD . iLOD , strrchr ( m_QCInfo_t . pszSMDPath , ' \\ ' ) + 1 , thisLOD . pszFilename ) ;
}
if ( m_QCInfo_t . bDisableCollision ! = true )
{
//write out collision header
g_pFullFileSystem - > FPrintf ( pSaveFile , " \n " ) ;
//write out collision info
if ( m_QCInfo_t . bReferenceAsPhys = = true )
{
g_pFullFileSystem - > FPrintf ( pSaveFile , " $collisionmodel \" %s \" " , strrchr ( m_QCInfo_t . pszSMDPath , ' \\ ' ) + 1 ) ;
}
else
{
if ( Q_strcmp ( m_QCInfo_t . pszCollisionPath , " " ) )
{
g_pFullFileSystem - > FPrintf ( pSaveFile , " $collisionmodel \" %s \" " , strrchr ( m_QCInfo_t . pszCollisionPath , ' \\ ' ) + 1 ) ;
}
}
g_pFullFileSystem - > FPrintf ( pSaveFile , " { \n \t // Mass in kilograms \n " ) ;
if ( m_QCInfo_t . bAutomass = = true )
{
g_pFullFileSystem - > FPrintf ( pSaveFile , " \t $automass \n " ) ;
}
else
{
g_pFullFileSystem - > FPrintf ( pSaveFile , " \t $mass %f \n " , m_QCInfo_t . fMass ) ;
}
if ( m_QCInfo_t . bConcave = = true )
{
g_pFullFileSystem - > FPrintf ( pSaveFile , " \t $concave \n " ) ;
}
g_pFullFileSystem - > FPrintf ( pSaveFile , " } \n \n " ) ;
}
g_pFullFileSystem - > Close ( pSaveFile ) ;
char szCommand [ MAX_PATH ] ;
char szGamePath [ MAX_PATH ] ;
char studiomdlPath [ 512 ] ;
g_pFullFileSystem - > RelativePathToFullPath ( " studiomdl.bat " , NULL , studiomdlPath , sizeof ( studiomdlPath ) ) ;
GetVConfigRegistrySetting ( GAMEDIR_TOKEN , szGamePath , sizeof ( szGamePath ) ) ;
# ifdef WIN32
STARTUPINFO startup ;
PROCESS_INFORMATION process ;
memset ( & startup , 0 , sizeof ( startup ) ) ;
startup . cb = sizeof ( startup ) ;
sprintf ( szCommand , " %s -game %s %s " , studiomdlPath , szGamePath , szName ) ;
bool bReturn = CreateProcess ( NULL , szCommand , NULL , NULL , TRUE , CREATE_NEW_CONSOLE , NULL , NULL , & startup , & process ) ;
# else
Assert ( ! " Implement me, why aren't we using a thread tool abstraction? " ) ;
bool bReturn = false ;
# endif
return bReturn ;
}
void CQCGenerator : : InitializeSMDPaths ( const char * pszPath , const char * pszScene )
{
V_strcpy_safe ( m_QCInfo_t . pszSceneName , pszScene ) ;
FileFindHandle_t * pFileHandle = new FileFindHandle_t ( ) ;
g_pFullFileSystem - > AddSearchPath ( pszPath , " SMD_DIR " ) ;
const char * filename = g_pFullFileSystem - > FindFirst ( " *.smd " , pFileHandle ) ;
bool bFoundReference = false ;
bool bFoundCollision = false ;
bool bFoundLOD = false ;
//iterate through .smd files
const char * startName = pszScene ;
int nSearchLength = Q_strlen ( pszScene ) ;
int currentLOD = 1 ;
while ( filename )
{
if ( ! strncmp ( startName , filename , nSearchLength ) )
{
const char * filenameEnd = filename + nSearchLength ;
if ( ! strncmp ( filenameEnd , " _ref " , 4 ) | | ! strncmp ( filenameEnd , " .smd " , 4 ) )
{
bFoundReference = true ;
//we have found the reference smd.
V_strcpy_safe ( m_QCInfo_t . pszSMDPath , pszPath ) ;
V_strcat_safe ( m_QCInfo_t . pszSMDPath , filename ) ;
}
if ( ! strncmp ( filenameEnd , " _phy " , 4 ) | | ! strncmp ( filenameEnd , " _col " , 4 ) )
{
bFoundCollision = true ;
//we have found the collision smd.
V_strcpy_safe ( m_QCInfo_t . pszCollisionPath , pszPath ) ;
V_strcat_safe ( m_QCInfo_t . pszCollisionPath , filename ) ;
}
if ( ! strncmp ( filenameEnd , " _lod " , 4 ) )
{
bFoundLOD = true ;
//we found an LOD smd.
char lodName [ 255 ] ;
Q_snprintf ( lodName , Q_strlen ( lodName ) , " lod%d " , currentLOD ) ;
//we found an LOD
KeyValues * newKv = new KeyValues ( lodName , " SMD " , filename , " LOD " , " 10 " ) ;
m_pLODPanel - > AddItem ( newKv , currentLOD , false , false ) ;
currentLOD + + ;
}
}
filename = g_pFullFileSystem - > FindNext ( * pFileHandle ) ;
}
char pszMessage [ 2048 ] = " " ;
char pszRefMessage [ 1024 ] = " " ;
char pszColMessage [ 1024 ] = " " ;
if ( ! bFoundReference )
{
V_strcat_safe ( m_QCInfo_t . pszSMDPath , pszPath ) ;
V_strcat_safe ( m_QCInfo_t . pszSMDPath , pszScene ) ;
V_strcat_safe ( m_QCInfo_t . pszSMDPath , " .smd " ) ;
Q_snprintf ( pszRefMessage , 1024 , " Reference SMD not found. \n \n Valid default reference SMDs are %s%s_ref*.smd and %s%s.smd \n Using default of %s. Model will not compile. \n \n " , pszPath , pszScene , pszPath , pszScene , m_QCInfo_t . pszSMDPath ) ;
}
if ( ! bFoundCollision )
{
Q_snprintf ( pszColMessage , 1024 , " Collision SMD not found. \n \n The valid default collision SMD is %s%s_phy*.smd. \n Using reference SMD as default. \n " , pszPath , pszScene ) ;
V_strcpy_safe ( m_QCInfo_t . pszCollisionPath , m_QCInfo_t . pszSMDPath ) ;
m_QCInfo_t . bReferenceAsPhys = true ;
}
if ( ! bFoundReference | | ! bFoundCollision )
{
V_strcpy_safe ( pszMessage , pszRefMessage ) ;
V_strcat_safe ( pszMessage , pszColMessage ) ;
VGUIMessageBox ( this , " Error Initializing Paths " , pszMessage ) ;
}
}
void CQCGenerator : : DeleteLOD ( )
{
int numSelected = m_pLODPanel - > GetSelectedItemsCount ( ) ;
int selected ;
for ( int i = numSelected - 1 ; i > = 0 ; i - - )
{
selected = m_pLODPanel - > GetSelectedItem ( i ) ;
m_pLODPanel - > RemoveItem ( selected ) ;
}
}
void CQCGenerator : : EditLOD ( )
{
int numSelected = m_pLODPanel - > GetSelectedItemsCount ( ) ;
if ( numSelected = = 1 & & ! m_pLODPanel - > IsInEditMode ( ) )
{
if ( m_pLODEdit )
{
m_pLODEdit - > MarkForDeletion ( ) ;
m_pLODEdit = NULL ;
}
m_pLODEdit = new vgui : : TextEntry ( this , " Edit " ) ;
m_pLODEdit - > SendNewLine ( true ) ;
m_nSelectedSequence = m_pLODPanel - > GetSelectedItem ( 0 ) ;
m_nSelectedColumn = m_pLODPanel - > GetSelectedColumn ( ) ;
m_pLODPanel - > EnterEditMode ( m_nSelectedSequence , m_nSelectedColumn , m_pLODEdit ) ;
}
}
void CQCGenerator : : OnNewLODText ( )
{
KeyValues * pEditItem = m_pLODPanel - > GetItem ( m_nSelectedSequence ) ;
KeyValues * pListItem = pEditItem ;
wchar_t szEditText [ MAX_PATH ] ;
pEditItem = pEditItem - > GetFirstValue ( ) ;
const char * name = pEditItem - > GetName ( ) ;
for ( int i = 0 ; i < m_nSelectedColumn ; i + + )
{
pEditItem = pEditItem - > GetNextValue ( ) ;
name = pEditItem - > GetName ( ) ;
}
m_pLODEdit - > GetText ( szEditText , MAX_PATH ) ;
pListItem - > SetWString ( name , szEditText ) ;
m_pLODPanel - > LeaveEditMode ( ) ;
m_pLODPanel - > InvalidateLayout ( ) ;
return ;
}