diff options
Diffstat (limited to 'vgui2/matsys_controls/QCGenerator.cpp')
| -rw-r--r-- | vgui2/matsys_controls/QCGenerator.cpp | 723 |
1 files changed, 723 insertions, 0 deletions
diff --git a/vgui2/matsys_controls/QCGenerator.cpp b/vgui2/matsys_controls/QCGenerator.cpp new file mode 100644 index 0000000..89f0173 --- /dev/null +++ b/vgui2/matsys_controls/QCGenerator.cpp @@ -0,0 +1,723 @@ +//========= 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[1024] = "\0"; + + // Get the currently set game configuration + GetVConfigRegistrySetting( GAMEDIR_TOKEN, szGamePath, sizeof( szGamePath ) ); + static const char *pSurfacePropFilename = "\\scripts\\surfaceproperties.txt"; + + sprintf( 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" ); + sprintf( 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\nDirectory '%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\treplacemodel \"%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\nValid default reference SMDs are %s%s_ref*.smd and %s%s.smd\nUsing 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\nThe valid default collision SMD is %s%s_phy*.smd.\nUsing 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; +}
\ No newline at end of file |