2013-04-22 05:25:59 +00:00
// AssimilateDoc.cpp : implementation of the CAssimilateDoc class
//
# include "stdafx.h"
# include "Includes.h"
# include "BuildAll.h"
# include "sourcesafe.h"
# include "gla.h" // just for string stuff
# include <set>
using namespace std ;
# define sSAVEINFOSTRINGCHECK "(SaveInfo):" // so comment reader can stop these damn things accumulating
# ifdef _DEBUG
# define new DEBUG_NEW
# undef THIS_FILE
static char THIS_FILE [ ] = __FILE__ ;
# endif
int giLODLevelOverride = 0 ; // MUST default to 0
void SS_DisposingOfCurrent ( LPCSTR psFileName , bool bDirty ) ;
static bool FileUsesGLAReference ( LPCSTR psFilename , LPCSTR psGLAReference ) ;
keywordArray_t CAssimilateDoc : : s_Symbols [ ] =
{
" \\ " , TK_BACKSLASH ,
" / " , TK_SLASH ,
" . " , TK_DOT ,
" _ " , TK_UNDERSCORE ,
" - " , TK_DASH ,
" $ " , TK_DOLLAR ,
NULL , TK_EOF ,
} ;
keywordArray_t CAssimilateDoc : : s_Keywords [ ] =
{
" aseanimgrabinit " , TK_AS_GRABINIT ,
" scale " , TK_AS_SCALE ,
" keepmotion " , TK_AS_KEEPMOTION ,
" pcj " , TK_AS_PCJ ,
" aseanimgrab " , TK_AS_GRAB ,
" aseanimgrab_gla " , TK_AS_GRAB_GLA ,
" aseanimgrabfinalize " , TK_AS_GRABFINALIZE ,
" aseanimconvert " , TK_AS_CONVERT ,
" aseanimconvertmdx " , TK_AS_CONVERTMDX ,
" aseanimconvertmdx_noask " , TK_AS_CONVERTMDX_NOASK ,
NULL , TK_EOF ,
} ;
keywordArray_t CAssimilateDoc : : s_grabKeywords [ ] =
{
" frames " , TK_AS_FRAMES ,
" fill " , TK_AS_FILL ,
" sound " , TK_AS_SOUND ,
" action " , TK_AS_ACTION ,
" enum " , TK_AS_ENUM ,
" loop " , TK_AS_LOOP ,
" qdskipstart " , TK_AS_QDSKIPSTART , // useful so qdata can quickly skip extra stuff without having to know the syntax of what to skip
" qdskipstop " , TK_AS_QDSKIPSTOP ,
" additional " , TK_AS_ADDITIONAL ,
" prequat " , TK_AS_PREQUAT ,
" framespeed " , TK_AS_FRAMESPEED , // retro hack because original format only supported frame speeds on additional sequences, not masters
" genloopframe " , TK_AS_GENLOOPFRAME ,
NULL , TK_EOF ,
} ;
keywordArray_t CAssimilateDoc : : s_convertKeywords [ ] =
{
" playerparms " , TK_AS_PLAYERPARMS ,
" origin " , TK_AS_ORIGIN ,
" smooth " , TK_AS_SMOOTH ,
" losedupverts " , TK_AS_LOSEDUPVERTS ,
" makeskin " , TK_AS_MAKESKIN ,
" ignorebasedeviations " , TK_AS_IGNOREBASEDEVIATIONS , // temporary!
" skew90 " , TK_AS_SKEW90 ,
" noskew90 " , TK_AS_NOSKEW90 ,
" skel " , TK_AS_SKEL ,
" makeskel " , TK_AS_MAKESKEL ,
NULL , TK_EOF ,
} ;
LPCTSTR CAssimilateDoc : : GetKeyword ( int token , int table )
{
if ( ( table = = TABLE_ANY ) | | ( table = = TABLE_QDT ) )
{
int i = 0 ;
while ( s_Keywords [ i ] . m_tokenvalue ! = TK_EOF )
{
if ( s_Keywords [ i ] . m_tokenvalue = = token )
{
return s_Keywords [ i ] . m_keyword ;
}
i + + ;
}
}
if ( ( table = = TABLE_ANY ) | | ( table = = TABLE_GRAB ) )
{
int i = 0 ;
while ( s_grabKeywords [ i ] . m_tokenvalue ! = TK_EOF )
{
if ( s_grabKeywords [ i ] . m_tokenvalue = = token )
{
return s_grabKeywords [ i ] . m_keyword ;
}
i + + ;
}
}
if ( ( table = = TABLE_ANY ) | | ( table = = TABLE_CONVERT ) )
{
int i = 0 ;
while ( s_convertKeywords [ i ] . m_tokenvalue ! = TK_EOF )
{
if ( s_convertKeywords [ i ] . m_tokenvalue = = token )
{
return s_convertKeywords [ i ] . m_keyword ;
}
i + + ;
}
}
return NULL ;
}
/////////////////////////////////////////////////////////////////////////////
// CAssimilateDoc
IMPLEMENT_DYNCREATE ( CAssimilateDoc , CDocument )
BEGIN_MESSAGE_MAP ( CAssimilateDoc , CDocument )
//{{AFX_MSG_MAP(CAssimilateDoc)
ON_COMMAND ( IDM_ADDFILES , OnAddfiles )
ON_COMMAND ( IDM_EXTERNAL , OnExternal )
ON_COMMAND ( IDM_RESEQUENCE , OnResequence )
ON_COMMAND ( IDM_BUILD , OnBuild )
ON_COMMAND ( IDM_BUILD_MULTILOD , OnBuildMultiLOD )
ON_COMMAND ( IDM_VALIDATE , OnValidate )
ON_COMMAND ( IDM_CARWASH , OnCarWash )
ON_COMMAND ( IDM_VALIDATE_MULTILOD , OnValidateMultiLOD )
ON_COMMAND ( ID_VIEW_ANIMENUMS , OnViewAnimEnums )
ON_UPDATE_COMMAND_UI ( ID_VIEW_ANIMENUMS , OnUpdateViewAnimEnums )
ON_COMMAND ( ID_VIEW_FRAMEDETAILS , OnViewFrameDetails )
ON_UPDATE_COMMAND_UI ( ID_VIEW_FRAMEDETAILS , OnUpdateViewFrameDetails )
ON_UPDATE_COMMAND_UI ( IDM_RESEQUENCE , OnUpdateResequence )
ON_UPDATE_COMMAND_UI ( ID_FILE_SAVE , OnUpdateFileSave )
ON_UPDATE_COMMAND_UI ( ID_FILE_SAVE_AS , OnUpdateFileSaveAs )
ON_UPDATE_COMMAND_UI ( IDM_EXTERNAL , OnUpdateExternal )
ON_UPDATE_COMMAND_UI ( IDM_VALIDATE , OnUpdateValidate )
ON_UPDATE_COMMAND_UI ( IDM_BUILD , OnUpdateBuild )
ON_COMMAND ( ID_EDIT_BUILDALL , OnEditBuildall )
ON_COMMAND ( IDM_EDIT_BUILDDEPENDANT , OnEditBuildDependant )
ON_COMMAND ( ID_VIEW_FRAMEDETAILSONADDITIONALSEQUENCES , OnViewFramedetailsonadditionalsequences )
ON_UPDATE_COMMAND_UI ( ID_VIEW_FRAMEDETAILSONADDITIONALSEQUENCES , OnUpdateViewFramedetailsonadditionalsequences )
ON_UPDATE_COMMAND_UI ( IDM_EDIT_BUILDDEPENDANT , OnUpdateEditBuilddependant )
ON_COMMAND ( ID_EDIT_LAUNCHMODVIEWONCURRENT , OnEditLaunchmodviewoncurrent )
ON_UPDATE_COMMAND_UI ( ID_EDIT_LAUNCHMODVIEWONCURRENT , OnUpdateEditLaunchmodviewoncurrent )
//}}AFX_MSG_MAP
END_MESSAGE_MAP ( )
/////////////////////////////////////////////////////////////////////////////
// CAssimilateDoc construction/destruction
CAssimilateDoc : : CAssimilateDoc ( )
{
// TODO: add one-time construction code here
Init ( ) ;
}
CAssimilateDoc : : ~ CAssimilateDoc ( )
{
}
BOOL CAssimilateDoc : : OnNewDocument ( )
{
SS_DisposingOfCurrent ( m_strPathName , ! ! IsModified ( ) ) ;
if ( ! CDocument : : OnNewDocument ( ) )
return FALSE ;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
SetTitle ( " Untitled " ) ; // for some reason MFC doesn't do this from time to time
return TRUE ;
}
void CAssimilateDoc : : Init ( )
{
m_comments = NULL ;
m_modelList = NULL ;
m_curModel = NULL ;
m_lastModel = NULL ;
}
/////////////////////////////////////////////////////////////////////////////
// CAssimilateDoc serialization
CModel * CAssimilateDoc : : AddModel ( )
{
CModel * thisModel = CModel : : Create ( m_comments ) ;
m_comments = NULL ;
if ( m_modelList = = NULL )
{
m_modelList = thisModel ;
}
else
{
CModel * curModel = m_modelList ;
while ( curModel - > GetNext ( ) ! = NULL )
{
curModel = curModel - > GetNext ( ) ;
}
curModel - > SetNext ( thisModel ) ;
}
m_curModel = thisModel ;
return m_curModel ;
}
// remember to account for Mike's m_lastModel and move it down if necessary (until I can throw it away)...
//
void CAssimilateDoc : : DeleteModel ( CModel * deleteModel )
{
// linklist is only 1-way, so we need to find the stage previous to this (if any)...
//
CModel * prevModel = NULL ;
CModel * scanModel = GetFirstModel ( ) ;
while ( scanModel & & scanModel ! = deleteModel )
{
prevModel = scanModel ;
scanModel = scanModel - > GetNext ( ) ;
}
if ( scanModel = = deleteModel )
{
// we found it, so was this the first model in the list?
//
if ( prevModel )
{
prevModel - > SetNext ( scanModel - > GetNext ( ) ) ; // ...no
}
else
{
m_modelList = scanModel - > GetNext ( ) ; // ...yes
}
scanModel - > Delete ( ) ;
}
// fixme: ditch this whenever possible
// keep Mike's var up to date...
//
scanModel = GetFirstModel ( ) ;
while ( scanModel & & scanModel - > GetNext ( ) )
{
scanModel = scanModel - > GetNext ( ) ;
}
m_lastModel = scanModel ;
}
void CAssimilateDoc : : EndModel ( )
{
m_lastModel = m_curModel ;
m_curModel = NULL ;
}
// XSI or GLA anim grab...
//
void CAssimilateDoc : : ParseGrab ( CTokenizer * tokenizer , int iGrabType )
{
if ( m_curModel = = NULL )
{
tokenizer - > Error ( " Grab without an active model " ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
CToken * curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
CString path = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
while ( curToken ! = NULL )
{
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | TKF_SPACETOKENS , 0 ) ;
switch ( curToken - > GetType ( ) )
{
case TK_SLASH :
case TK_BACKSLASH :
path + = " / " ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | TKF_SPACETOKENS , 0 ) ;
// hack for "8472" as in models/players/8472/blah.car. Arrggh!!!!!!!!!!!!!!!!!!
//
if ( curToken - > GetType ( ) = = TK_INT )
{
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
break ;
}
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
break ;
case TK_UNDERSCORE :
case TK_DASH :
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | TKF_SPACETOKENS , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
break ;
case TK_DOT :
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | TKF_SPACETOKENS , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
curToken = NULL ;
break ;
case TK_SPACE :
curToken - > Delete ( ) ;
curToken = NULL ;
break ;
case TK_EOL :
tokenizer - > PutBackToken ( curToken ) ;
curToken = NULL ;
break ;
default :
tokenizer - > PutBackToken ( curToken ) ;
curToken = NULL ;
break ;
}
}
CString enumname ;
int fill = - 1 ;
int loop = 0 ;
CString sound ;
CString action ;
int startFrame = 0 ;
int targetFrame = 0 ;
int framecount = - 1 ;
int framespeed = iDEFAULTSEQFRAMESPEED ;
bool bFrameSpeedFound = false ;
int iFrameSpeedFromHeader ;
//
int iStartFrames [ MAX_ADDITIONAL_SEQUENCES ] = { 0 } ;
int iFrameCounts [ MAX_ADDITIONAL_SEQUENCES ] = { 0 } ;
int iLoopFrames [ MAX_ADDITIONAL_SEQUENCES ] = { 0 } ;
int iFrameSpeeds [ MAX_ADDITIONAL_SEQUENCES ] = { 0 } ;
CString csEnums [ MAX_ADDITIONAL_SEQUENCES ] ;
int iAdditionalSeqNum = 0 ;
bool bGenLoopFrame = false ;
bool bSomeParamsFound = false ;
curToken = tokenizer - > GetToken ( TKF_USES_EOL ) ;
switch ( iGrabType )
{
case TK_AS_GRAB :
{
while ( curToken - > GetType ( ) = = TK_DASH )
{
bSomeParamsFound = true ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( s_grabKeywords , TKF_USES_EOL , 0 ) ;
switch ( curToken - > GetType ( ) )
{
case TK_AS_FRAMES :
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
startFrame = curToken - > GetIntValue ( ) ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
targetFrame = curToken - > GetIntValue ( ) ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
framecount = curToken - > GetIntValue ( ) ;
break ;
case TK_AS_FILL :
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
fill = curToken - > GetIntValue ( ) ;
break ;
case TK_AS_ENUM :
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
enumname = curToken - > GetStringValue ( ) ;
break ;
case TK_AS_SOUND :
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
sound = curToken - > GetStringValue ( ) ;
break ;
case TK_AS_ACTION :
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
action = curToken - > GetStringValue ( ) ;
break ;
case TK_AS_LOOP :
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
loop = curToken - > GetIntValue ( ) ;
break ;
case TK_AS_QDSKIPSTART :
case TK_AS_QDSKIPSTOP :
//curToken->Delete(); // don't do this, the whole thing relies on case statements leaving one current token for the outside loop to delete
break ;
case TK_AS_GENLOOPFRAME :
bGenLoopFrame = true ;
break ;
case TK_AS_FRAMESPEED : // this is still read in for compatibility, but gets overwritten lower down
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
framespeed = curToken - > GetIntValue ( ) ;
bFrameSpeedFound = true ;
break ;
case TK_AS_PREQUAT :
m_curModel - > SetPreQuat ( true ) ;
break ;
case TK_AS_ADDITIONAL :
curToken - > Delete ( ) ;
if ( iAdditionalSeqNum = = MAX_ADDITIONAL_SEQUENCES )
{
tokenizer - > Error ( TKERR_USERERROR , va ( " Trying to define > %d additional sequences for this master " , MAX_ADDITIONAL_SEQUENCES ) ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
// startframe...
//
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
iStartFrames [ iAdditionalSeqNum ] = curToken - > GetIntValue ( ) ;
// framecount...
//
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
iFrameCounts [ iAdditionalSeqNum ] = curToken - > GetIntValue ( ) ;
// loopframe...
//
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
iLoopFrames [ iAdditionalSeqNum ] = curToken - > GetIntValue ( ) ;
// framespeed...
//
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
iFrameSpeeds [ iAdditionalSeqNum ] = curToken - > GetIntValue ( ) ;
// enum...
//
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
csEnums [ iAdditionalSeqNum ] = curToken - > GetStringValue ( ) ;
iAdditionalSeqNum + + ;
break ;
default :
tokenizer - > Error ( TKERR_UNEXPECTED_TOKEN , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( s_grabKeywords , TKF_USES_EOL , 0 ) ;
}
}
break ;
case TK_AS_GRAB_GLA :
{
// no additional params permitted for this type currently...
//
}
break ;
}
path . MakeLower ( ) ;
//
// if no extension, assume ".xsi"... (or ".gla" now)
//
if ( ! ( path . GetAt ( path . GetLength ( ) - 4 ) = = ' . ' ) )
{
path + = ( iGrabType = = TK_AS_GRAB ) ? " .xsi " : " .gla " ;
}
if ( curToken - > GetType ( ) ! = TK_EOL )
{
tokenizer - > Error ( TKERR_UNEXPECTED_TOKEN , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
// ignore any user params about speed and frame counts, and just re-grab them from the XSI file...
//
// if (bSomeParamsFound)
// {
// }
// else
{
// at this point, it must be one of the paramless entries in a .CAR file, so we need to
// provide the values for: startFrame, targetFrame, framecount
//
// read in values from the actual file, in case we need to use them...
//
CString nameASE = ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > GetQuakeDir ( ) ;
nameASE + = path ;
int iStartFrame , iFrameCount ;
ReadASEHeader ( nameASE , iStartFrame , iFrameCount , iFrameSpeedFromHeader , ( iGrabType = = TK_AS_GRAB_GLA ) ) ;
// if (strstr(nameASE,"death16"))
// {
// int z=1;
// }
startFrame = 0 ; // always
targetFrame = 0 ; // any old shite value
framecount = iFrameCount ;
if ( iGrabType ! = TK_AS_GRAB_GLA )
{
if ( ! bFrameSpeedFound )
{
framespeed = iFrameSpeedFromHeader ;
}
}
}
curToken - > Delete ( ) ;
CSequence * sequence = CSequence : : _Create ( bGenLoopFrame , ( iGrabType = = TK_AS_GRAB_GLA ) , path , startFrame , targetFrame , framecount , framespeed , iFrameSpeedFromHeader ) ;
m_curModel - > AddSequence ( sequence ) ;
sequence - > AddComment ( m_curModel - > ExtractComments ( ) ) ;
sequence - > DeriveName ( ) ;
if ( enumname . IsEmpty ( ) )
{
sequence - > SetEnum ( sequence - > GetName ( ) ) ;
}
else
{
sequence - > SetEnum ( enumname ) ;
}
sequence - > SetFill ( fill ) ;
sequence - > SetSound ( sound ) ;
sequence - > SetAction ( action ) ;
sequence - > SetValidEnum ( ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > ValidEnum ( sequence - > GetEnum ( ) ) ) ;
sequence - > SetLoopFrame ( loop ) ;
for ( int i = 0 ; i < MAX_ADDITIONAL_SEQUENCES ; i + + )
{
sequence - > AdditionalSeqs [ i ] - > SetStartFrame ( iStartFrames [ i ] ) ;
sequence - > AdditionalSeqs [ i ] - > SetFrameCount ( iFrameCounts [ i ] ) ;
sequence - > AdditionalSeqs [ i ] - > SetFrameSpeed ( iFrameSpeeds [ i ] ) ;
sequence - > AdditionalSeqs [ i ] - > SetLoopFrame ( iLoopFrames [ i ] ) ;
sequence - > AdditionalSeqs [ i ] - > SetEnum ( csEnums [ i ] ) ;
sequence - > AdditionalSeqs [ i ] - > SetValidEnum ( ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > ValidEnum ( sequence - > AdditionalSeqs [ i ] - > GetEnum ( ) ) ) ;
}
}
// return = success. if false ret, return from caller because of error
//
bool Tokenizer_ReadPath ( CString & path , CTokenizer * & tokenizer , CToken * & curToken )
{
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return false ;
}
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
while ( curToken ! = NULL )
{
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | ( path . IsEmpty ( ) ? 0 : TKF_SPACETOKENS ) , 0 ) ;
switch ( curToken - > GetType ( ) )
{
case TK_SLASH :
case TK_BACKSLASH :
path + = " / " ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | TKF_SPACETOKENS , 0 ) ;
// hack for "8472" as in models/players/8472/blah.car. Arrggh!!!!!!!!!!!!!!!!!!
//
if ( curToken - > GetType ( ) = = TK_INT )
{
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
break ;
}
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return false ;
}
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
break ;
case TK_UNDERSCORE :
case TK_DASH :
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | TKF_SPACETOKENS , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return false ;
}
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
break ;
case TK_DOT :
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | TKF_SPACETOKENS , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return false ;
}
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
curToken = NULL ;
break ;
case TK_SPACE :
case TK_EOL :
curToken - > Delete ( ) ;
curToken = NULL ;
break ;
default :
tokenizer - > PutBackToken ( curToken ) ;
curToken = NULL ;
break ;
}
}
return true ;
}
void CAssimilateDoc : : ParseConvert ( CTokenizer * tokenizer , int iTokenType )
{
if ( m_lastModel = = NULL )
{
tokenizer - > Error ( " Convert without an internal model " ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
CToken * curToken = NULL ;
CString path ;
if ( ! Tokenizer_ReadPath ( path , tokenizer , curToken ) )
return ;
/*
while ( curToken ! = NULL )
{
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | TKF_SPACETOKENS , 0 ) ;
switch ( curToken - > GetType ( ) )
{
case TK_SLASH :
case TK_BACKSLASH :
path + = " / " ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | TKF_SPACETOKENS , 0 ) ;
// hack for "8472" as in models/players/8472/blah.car. Arrggh!!!!!!!!!!!!!!!!!!
//
if ( curToken - > GetType ( ) = = TK_INT )
{
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
break ;
}
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
break ;
case TK_UNDERSCORE :
case TK_DASH :
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | TKF_SPACETOKENS , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
break ;
case TK_DOT :
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( NULL , TKF_NUMERICIDENTIFIERSTART | TKF_USES_EOL | TKF_SPACETOKENS , 0 ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_IDENTIFIER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
path + = curToken - > GetStringValue ( ) ;
curToken - > Delete ( ) ;
curToken = NULL ;
break ;
case TK_SPACE :
case TK_EOL :
curToken - > Delete ( ) ;
curToken = NULL ;
break ;
default :
tokenizer - > PutBackToken ( curToken ) ;
curToken = NULL ;
break ;
}
}
*/
int originx = 0 ; // important to default to 0!
int originy = 0 ; //
int originz = 0 ; //
int parm1 = 0 ;
int parm2 = 0 ;
int parm3 = 0 ;
int parm4 = 0 ;
curToken = tokenizer - > GetToken ( ) ;
while ( curToken - > GetType ( ) = = TK_DASH )
{
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( s_convertKeywords , 0 , 0 ) ;
switch ( curToken - > GetType ( ) )
{
case TK_AS_ORIGIN :
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
originx = curToken - > GetIntValue ( ) ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
originy = curToken - > GetIntValue ( ) ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
originz = curToken - > GetIntValue ( ) ;
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( ) ;
break ;
case TK_AS_PLAYERPARMS :
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
parm1 = curToken - > GetIntValue ( ) ;
curToken - > Delete ( ) ;
/* this param no longer exists...
curToken = tokenizer - > GetToken ( ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
parm2 = curToken - > GetIntValue ( ) ;
curToken - > Delete ( ) ;
*/
curToken = tokenizer - > GetToken ( ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
parm3 = curToken - > GetIntValue ( ) ;
curToken - > Delete ( ) ;
/* this param no longer exists...
curToken = tokenizer - > GetToken ( ) ;
if ( curToken - > GetType ( ) ! = TK_INTEGER )
{
tokenizer - > Error ( TKERR_EXPECTED_INTEGER , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
parm4 = curToken - > GetIntValue ( ) ;
curToken - > Delete ( ) ;
*/ parm4 = 1 ;
curToken = tokenizer - > GetToken ( ) ;
break ;
case TK_AS_SMOOTH :
curToken - > Delete ( ) ;
m_lastModel - > SetSmooth ( true ) ;
curToken = tokenizer - > GetToken ( ) ;
break ;
case TK_AS_LOSEDUPVERTS :
curToken - > Delete ( ) ;
m_lastModel - > SetLoseDupVerts ( true ) ;
curToken = tokenizer - > GetToken ( ) ;
break ;
case TK_AS_MAKESKIN :
curToken - > Delete ( ) ;
m_lastModel - > SetMakeSkin ( true ) ;
curToken = tokenizer - > GetToken ( ) ;
break ;
case TK_AS_IGNOREBASEDEVIATIONS :
curToken - > Delete ( ) ;
m_lastModel - > SetIgnoreBaseDeviations ( true ) ;
curToken = tokenizer - > GetToken ( ) ;
break ;
case TK_AS_SKEW90 :
curToken - > Delete ( ) ;
m_lastModel - > SetSkew90 ( true ) ;
curToken = tokenizer - > GetToken ( ) ;
break ;
case TK_AS_NOSKEW90 :
curToken - > Delete ( ) ;
m_lastModel - > SetNoSkew90 ( true ) ;
curToken = tokenizer - > GetToken ( ) ;
break ;
/*
case TK_AS_SKEL :
{
CString strSkelPath ;
curToken - > Delete ( ) ;
if ( ! Tokenizer_ReadPath ( strSkelPath , tokenizer , curToken ) )
{
return ;
}
m_lastModel - > SetSkelPath ( strSkelPath ) ;
m_lastModel - > SetMakeSkelPath ( " " ) ;
curToken = tokenizer - > GetToken ( ) ;
}
break ;
*/
case TK_AS_MAKESKEL :
{
CString strMakeSkelPath ;
curToken - > Delete ( ) ;
if ( ! Tokenizer_ReadPath ( strMakeSkelPath , tokenizer , curToken ) )
{
return ;
}
m_lastModel - > SetMakeSkelPath ( strMakeSkelPath ) ;
// m_lastModel->SetSkelPath("");
curToken = tokenizer - > GetToken ( ) ;
}
break ;
default :
tokenizer - > Error ( TKERR_UNEXPECTED_TOKEN , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
}
tokenizer - > PutBackToken ( curToken ) ;
path . MakeLower ( ) ;
m_lastModel - > DeriveName ( path ) ;
m_lastModel - > SetParms ( parm1 , parm2 , parm3 , parm4 ) ;
m_lastModel - > SetOrigin ( originx , originy , originz ) ;
m_lastModel - > SetConvertType ( iTokenType ) ;
}
void CAssimilateDoc : : AddComment ( LPCTSTR comment )
{
// some code to stop those damn timestamps accumulating...
//
if ( ! strnicmp ( comment , sSAVEINFOSTRINGCHECK , strlen ( sSAVEINFOSTRINGCHECK ) ) )
{
return ;
}
CComment * thisComment = CComment : : Create ( comment ) ;
if ( m_curModel ! = NULL )
{
m_curModel - > AddComment ( thisComment ) ;
return ;
}
if ( m_comments = = NULL )
{
m_comments = thisComment ;
}
else
{
CComment * curComment = m_comments ;
while ( curComment - > GetNext ( ) ! = NULL )
{
curComment = curComment - > GetNext ( ) ;
}
curComment - > SetNext ( thisComment ) ;
}
}
///////////////////////////////////////////////
# define MAX_FOUND_FILES 0x1000
# define MAX_OSPATH MAX_PATH
# include <stdio.h>
# include <io.h>
char * * Sys_ListFiles ( const char * directory , const char * extension , int * numfiles ) {
char search [ MAX_OSPATH ] ;
int nfiles ;
char * * listCopy ;
char * list [ MAX_FOUND_FILES ] ;
struct _finddata_t findinfo ;
int findhandle ;
int flag ;
int i ;
if ( ! extension ) {
extension = " " ;
}
if ( extension [ 0 ] = = ' / ' & & extension [ 1 ] = = 0 ) {
extension = " " ;
flag = 0 ;
} else {
flag = _A_SUBDIR ;
}
sprintf ( search , " %s \\ *%s " , directory , extension ) ;
// search
nfiles = 0 ;
findhandle = _findfirst ( search , & findinfo ) ;
if ( findhandle = = - 1 ) {
* numfiles = 0 ;
return NULL ;
}
do {
if ( flag ^ ( findinfo . attrib & _A_SUBDIR ) ) {
if ( nfiles = = MAX_FOUND_FILES - 1 ) {
break ;
}
list [ nfiles ] = strdup ( strlwr ( findinfo . name ) ) ;
nfiles + + ;
}
} while ( _findnext ( findhandle , & findinfo ) ! = - 1 ) ;
list [ nfiles ] = 0 ;
_findclose ( findhandle ) ;
// return a copy of the list
* numfiles = nfiles ;
if ( ! nfiles ) {
return NULL ;
}
listCopy = ( char * * ) malloc ( ( nfiles + 1 ) * sizeof ( * listCopy ) ) ;
for ( i = 0 ; i < nfiles ; i + + ) {
listCopy [ i ] = list [ i ] ;
}
listCopy [ i ] = NULL ;
return listCopy ;
}
void Sys_FreeFileList ( char * * _list ) {
int i ;
if ( ! _list ) {
return ;
}
for ( i = 0 ; _list [ i ] ; i + + ) {
free ( _list [ i ] ) ;
}
free ( _list ) ;
}
//////////////////////////////////////////
CString strSkippedFiles ;
CString strSkippedDirs ;
CString strCARsFound ;
int iCARsFound = 0 ;
void AlphaSortCARs ( void )
{
typedef set < string > SortedStrings_t ;
SortedStrings_t SortedStrings ;
for ( int i = 0 ; i < iCARsFound ; i + + )
{
CString strThisFile = strCARsFound ;
int iLoc = strThisFile . Find ( " \n " ) ;
if ( iLoc > = 0 )
{
SortedStrings . insert ( SortedStrings . end ( ) , ( LPCSTR ) ( strThisFile . Left ( iLoc ) ) ) ;
strCARsFound = strCARsFound . Mid ( iLoc + 1 ) ;
}
}
// clear files-found string out, and re-enter from sorted set...
//
strCARsFound = " " ;
for ( SortedStrings_t : : iterator it = SortedStrings . begin ( ) ; it ! = SortedStrings . end ( ) ; + + it )
{
strCARsFound + = ( * it ) . c_str ( ) ;
strCARsFound + = " \n " ;
}
}
void R_CheckCARs ( LPCSTR psDir , int iScanDepth , LPCSTR psGLAReferenceItShouldInclude )
{
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( va ( " (%d .CAR files found so far) Scanning Dir: %s " , iCARsFound , psDir ) ) ;
// ignore any dir with "test" in it...
//
if ( //strstr(psDir,"\\test")
//||
strstr ( psDir , " \\ backup " )
| |
strstr ( psDir , " \\ ignore_ " )
)
{
strSkippedDirs + = psDir ;
strSkippedDirs + = " \n " ;
return ;
}
char * * sysFiles , * * dirFiles ; //, *args[5];
int numSysFiles , i , /*len,*/ numdirs ;
char altname [ MAX_OSPATH ] ;
// char command1[MAX_OSPATH];
// char command2[MAX_OSPATH];
dirFiles = Sys_ListFiles ( psDir , " / " , & numdirs ) ;
if ( numdirs > 2 )
{
// if (!iScanDepth) // recursion limiter, to avoid scanning backup subdirs within model subdirs
{
for ( i = 2 ; i < numdirs ; i + + )
{
sprintf ( altname , " %s \\ %s " , psDir , dirFiles [ i ] ) ;
//if (stricmp(altname,"q:\\send\\quake\\baseq3\\models\\players")) // dont recurse this dir
{
R_CheckCARs ( altname , iScanDepth + 1 , psGLAReferenceItShouldInclude ) ;
}
}
}
}
// sprintf(command1, "-targa");
// sprintf(command2, "-outfile");
sysFiles = Sys_ListFiles ( psDir , " .car " , & numSysFiles ) ;
for ( i = 0 ; i < numSysFiles ; i + + )
{
CString strThisFile = va ( " %s \\ %s " , psDir , sysFiles [ i ] ) ;
if ( strstr ( ( LPCSTR ) strThisFile , " copy of " ) )
{
strSkippedFiles + = strThisFile ;
strSkippedFiles + = " \n " ;
continue ;
}
if ( psGLAReferenceItShouldInclude & & psGLAReferenceItShouldInclude [ 0 ]
& &
! FileUsesGLAReference ( strThisFile , psGLAReferenceItShouldInclude )
)
{
strSkippedFiles + = strThisFile ;
strSkippedFiles + = " \n " ;
continue ;
}
strCARsFound + = strThisFile + " \n " ;
iCARsFound + + ;
/* char tgain[MAX_OSPATH];
sprintf ( tgain , " %s \\ %s " , psDir , sysFiles [ i ] ) ;
strcpy ( altname , tgain ) ;
len = strlen ( altname ) ;
altname [ len - 3 ] = ' j ' ;
altname [ len - 2 ] = ' p ' ;
altname [ len - 1 ] = ' g ' ;
args [ 0 ] = " cjpeg " ;
args [ 1 ] = command2 ;
args [ 2 ] = altname ;
args [ 3 ] = command1 ;
args [ 4 ] = tgain ;
//printf("%s", tgain);
*/
/* len = qmain(5, args);
if ( ! len )
{
iNumberOf_FilesConverted + + ;
iSizeOf_JPGsWritten + = scGetFileLen ( altname ) ;
iSizeOf_TGAsDeleted + = scGetFileLen ( tgain ) ;
printf ( " nuked!(NOT) " ) ;
// remove(tgain);
}
printf ( " \n " ) ;
*/
/*
byte * pPixels = NULL ;
int iWidth ;
int iHeight ;
bool bRedundant = ScanTGA ( tgain , & pPixels , & iWidth , & iHeight ) ;
if ( pPixels )
{
free ( pPixels ) ;
}
if ( bRedundant )
{
strTGAsWithRedundantAlpha + = va ( " %s \n " , tgain ) ;
iRedundantFilesFound + + ;
}
*/
}
Sys_FreeFileList ( sysFiles ) ;
Sys_FreeFileList ( dirFiles ) ;
}
void CAssimilateDoc : : Parse ( CFile * file )
{
Parse ( file - > GetFilePath ( ) ) ;
}
void CAssimilateDoc : : Parse ( LPCSTR psFilename )
{
gbParseError = false ;
CAlertErrHandler errhandler ;
CTokenizer * tokenizer = CTokenizer : : Create ( TKF_NOCASEKEYWORDS | TKF_COMMENTTOKENS ) ;
tokenizer - > SetErrHandler ( & errhandler ) ;
tokenizer - > SetSymbols ( s_Symbols ) ;
tokenizer - > SetKeywords ( s_Keywords ) ;
tokenizer - > AddParseFile ( psFilename ) ;
extern bool gbSkipXSIRead_QuestionAsked ;
extern bool gbSkipXSIRead ;
gbSkipXSIRead_QuestionAsked = false ; // opening a new file so reset our question
gbSkipXSIRead = false ;
int tokType = TK_UNDEFINED ;
while ( tokType ! = TK_EOF )
{
CToken * curToken = tokenizer - > GetToken ( ) ;
tokType = curToken - > GetType ( ) ;
switch ( tokType )
{
case TK_EOF :
curToken - > Delete ( ) ;
break ;
case TK_DOLLAR :
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( ) ;
switch ( curToken - > GetType ( ) )
{
case TK_AS_GRABINIT :
curToken - > Delete ( ) ;
AddModel ( ) ;
break ;
case TK_AS_SCALE :
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( ) ;
if ( curToken - > GetType ( ) ! = TK_FLOAT & & curToken - > GetType ( ) ! = TK_INT )
{
tokenizer - > Error ( TKERR_EXPECTED_FLOAT , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
m_curModel - > SetScale ( ( curToken - > GetType ( ) = = TK_FLOAT ) ? curToken - > GetFloatValue ( ) : curToken - > GetIntValue ( ) ) ;
curToken - > Delete ( ) ;
break ;
case TK_AS_KEEPMOTION :
curToken - > Delete ( ) ;
m_curModel - > SetKeepMotion ( true ) ;
break ;
case TK_AS_PCJ :
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER & & curToken - > GetType ( ) ! = TK_DOLLAR ) // eg: '$pcj pelvis' or '$pcj $flatten'
{
tokenizer - > Error ( TKERR_EXPECTED_STRING , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
if ( curToken - > GetType ( ) = = TK_DOLLAR ) // read string after '$' char
{
curToken - > Delete ( ) ;
curToken = tokenizer - > GetToken ( ) ;
if ( curToken - > GetType ( ) ! = TK_IDENTIFIER )
{
tokenizer - > Error ( TKERR_EXPECTED_STRING , curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
tokenizer - > GetToEndOfLine ( ) - > Delete ( ) ;
return ;
}
m_curModel - > PCJList_AddEntry ( va ( " $%s " , curToken - > GetStringValue ( ) ) ) ;
}
else
{
m_curModel - > PCJList_AddEntry ( curToken - > GetStringValue ( ) ) ;
}
curToken - > Delete ( ) ;
break ;
case TK_AS_GRAB :
curToken - > Delete ( ) ;
ParseGrab ( tokenizer , TK_AS_GRAB ) ;
break ;
case TK_AS_GRAB_GLA :
curToken - > Delete ( ) ;
ParseGrab ( tokenizer , TK_AS_GRAB_GLA ) ;
break ;
case TK_AS_GRABFINALIZE :
curToken - > Delete ( ) ;
EndModel ( ) ;
break ;
case TK_AS_CONVERT :
curToken - > Delete ( ) ;
ParseConvert ( tokenizer , TK_AS_CONVERT ) ;
break ;
case TK_AS_CONVERTMDX :
curToken - > Delete ( ) ;
ParseConvert ( tokenizer , TK_AS_CONVERTMDX ) ;
break ;
case TK_AS_CONVERTMDX_NOASK :
curToken - > Delete ( ) ;
ParseConvert ( tokenizer , TK_AS_CONVERTMDX_NOASK ) ;
break ;
case TK_COMMENT :
AddComment ( curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
break ;
default :
tokenizer - > Error ( TKERR_UNEXPECTED_TOKEN ) ;
curToken - > Delete ( ) ;
break ;
}
break ;
case TK_COMMENT :
AddComment ( curToken - > GetStringValue ( ) ) ;
curToken - > Delete ( ) ;
break ;
default :
tokenizer - > Error ( TKERR_UNEXPECTED_TOKEN ) ;
curToken - > Delete ( ) ;
break ;
}
}
tokenizer - > Delete ( ) ;
UpdateAllViews ( NULL , AS_NEWFILE , NULL ) ;
Resequence ( ) ;
}
void CAssimilateDoc : : Write ( CFile * file )
{
CTxtFile * outfile = CTxtFile : : Create ( file ) ;
/* // write out time/date stamp...
//
CString commentLine ;
CTime time = CTime : : GetCurrentTime ( ) ;
commentLine . Format ( " // %s %s updated %s " , sSAVEINFOSTRINGCHECK , file - > GetFileName ( ) , time . Format ( " %H:%M %A, %B %d, %Y " ) ) ;
outfile - > Writeln ( commentLine ) ;
*/
CModel * curModel = m_modelList ;
while ( curModel ! = NULL )
{
curModel - > Write ( outfile ) ;
curModel = curModel - > GetNext ( ) ;
}
CComment * curComment = m_comments ;
while ( curComment ! = NULL )
{
curComment - > Write ( outfile ) ;
curComment = curComment - > GetNext ( ) ;
}
outfile - > Delete ( ) ;
}
void CAssimilateDoc : : Serialize ( CArchive & ar )
{
if ( ar . IsStoring ( ) )
{
// TODO: add storing code here
Write ( ar . GetFile ( ) ) ;
}
else
{
// TODO: add loading code here
Parse ( ar . GetFile ( ) ) ;
}
}
/////////////////////////////////////////////////////////////////////////////
// CAssimilateDoc diagnostics
# ifdef _DEBUG
void CAssimilateDoc : : AssertValid ( ) const
{
CDocument : : AssertValid ( ) ;
}
void CAssimilateDoc : : Dump ( CDumpContext & dc ) const
{
CDocument : : Dump ( dc ) ;
}
# endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CAssimilateDoc commands
void CAssimilateDoc : : DeleteContents ( )
{
// TODO: Add your specialized code here and/or call the base class
UpdateAllViews ( NULL , AS_DELETECONTENTS , NULL ) ;
while ( m_comments ! = NULL )
{
CComment * curComment = m_comments ;
m_comments = curComment - > GetNext ( ) ;
curComment - > Delete ( ) ;
}
while ( m_modelList ! = NULL )
{
CModel * curModel = m_modelList ;
m_modelList = curModel - > GetNext ( ) ;
curModel - > Delete ( ) ;
}
m_curModel = NULL ;
m_lastModel = NULL ;
gbReportMissingASEs = true ;
giFixUpdatedASEFrameCounts = YES ;
CDocument : : DeleteContents ( ) ;
}
CModel * CAssimilateDoc : : GetFirstModel ( )
{
return m_modelList ;
}
int CAssimilateDoc : : GetNumModels ( )
{
int iCount = 0 ;
CModel * theModel = m_modelList ;
while ( theModel )
{
iCount + + ;
theModel = theModel - > GetNext ( ) ;
}
return iCount ;
}
void CAssimilateDoc : : OnAddfiles ( )
{
// TODO: Add your command handler code here
CFileDialog theDialog ( true , " .xsi " , NULL , OFN_EXPLORER | OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST ,
_T ( " Anim Files (*.ase)(*.xsi)(*.gla)|*.ase;*.xsi;*.gla|All Files|*.*|| " ) , NULL ) ;
////////////
// Model files (*.MDR)(*.MD3)|*.md?|
////////////
char filenamebuffer [ 16384 ] ;
filenamebuffer [ 0 ] = ' \0 ' ;
theDialog . m_ofn . lpstrFile = filenamebuffer ;
theDialog . m_ofn . nMaxFile = sizeof ( filenamebuffer ) ;
CString
strInitialDir = ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > GetQuakeDir ( ) ;
strInitialDir + = " models/players " ;
strInitialDir . Replace ( " / " , " \\ " ) ;
theDialog . m_ofn . lpstrInitialDir = strInitialDir ;
int result = theDialog . DoModal ( ) ;
if ( result ! = IDOK )
{
return ;
}
CWaitCursor waitcursor ;
POSITION pos = theDialog . GetStartPosition ( ) ;
while ( pos ! = NULL )
{
CString thisfile = theDialog . GetNextPathName ( pos ) ;
/* int loc = thisfile.Find(':');
if ( loc > 0 )
{
thisfile = thisfile . Right ( thisfile . GetLength ( ) - loc - 1 ) ;
}
*/
Filename_RemoveBASEQ ( thisfile ) ;
AddFile ( thisfile ) ;
}
SetModifiedFlag ( ) ;
UpdateAllViews ( NULL , AS_NEWFILE , NULL ) ;
Resequence ( ) ; // must be AFTER UpdateAllViews
}
void CAssimilateDoc : : AddFile ( LPCTSTR name )
{
CString strTemp ( name ) ;
strTemp . MakeLower ( ) ;
if ( ! strstr ( strTemp , " root.xsi " ) | | GetYesNo ( " You're trying to add \" root.xsi \" , which is inherent, you should only do this if you're making a model that has no seperate anim files \n \n Proceed? " ) )
{
// update, ignore any files with a "_1" (2,3, etc) just before the suffix (this skips LOD files)...
//
// int iNameLen = strlen(name);
// (also, only check files of at least namelen "_?.ase")
//
// if ( iNameLen>6 && name[iNameLen-6]=='_' && isdigit(name[iNameLen-5]) )
{
// this is a LOD filename, so ignore it...
}
// else
{
CModel * curModel = GetCurrentUserSelectedModel ( ) ;
if ( ! curModel )
{
curModel = AddModel ( ) ;
CString path = name ;
path . MakeLower ( ) ;
path . Replace ( ' \\ ' , ' / ' ) ;
int loc = path . ReverseFind ( ' . ' ) ;
if ( loc > - 1 )
{
path = path . Left ( loc ) ;
}
loc = path . ReverseFind ( ' / ' ) ;
path = path . Left ( loc ) ;
path = path + " /root " ;
curModel - > DeriveName ( path ) ;
}
// check that we don't already have this file...
//
if ( ! curModel - > ContainsFile ( name ) )
{
curModel - > AddSequence ( CSequence : : CreateFromFile ( name , curModel - > ExtractComments ( ) ) ) ;
}
}
}
}
void CAssimilateDoc : : OnExternal ( )
{
bool bCFGWritten = false ;
if ( WriteCFGFiles ( true , bCFGWritten ) )
{
CString strReport ;
if ( bCFGWritten )
{
if ( ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > GetMultiPlayerMode ( ) )
{
strReport = " \n \n ( CFG file written for MULTI-PLAYER format ) " ;
}
else
{
strReport = " \n \n ( CFG file written for SINGLE-PLAYER format ) " ;
}
}
else
{
strReport = " \n \n ( CFG not needed, not written ) " ;
}
InfoBox ( strReport ) ;
}
}
// called both from the menu, and now from the Build() member...
//
bool CAssimilateDoc : : WriteCFGFiles ( bool bPromptForNames , bool & bCFGWritten )
{
bCFGWritten = false ;
CModel * curModel = m_modelList ;
while ( curModel ! = NULL )
{
bool bThisCFGWritten = false ;
if ( ! curModel - > WriteExternal ( bPromptForNames , bThisCFGWritten ) )
{
return false ;
}
if ( bThisCFGWritten )
bCFGWritten = true ;
curModel = curModel - > GetNext ( ) ;
}
return true ;
}
void CAssimilateDoc : : Resequence ( )
{
CModel * curModel = m_modelList ;
while ( curModel ! = NULL )
{
curModel - > Resequence ( true ) ;
curModel = curModel - > GetNext ( ) ;
}
SetModifiedFlag ( ) ;
UpdateAllViews ( NULL , AS_FILESUPDATED , NULL ) ; // needed
}
void CAssimilateDoc : : OnResequence ( )
{
extern bool gbSkipXSIRead_QuestionAsked ;
extern bool gbSkipXSIRead ;
gbSkipXSIRead_QuestionAsked = false ; // make it happen again
gbSkipXSIRead = false ;
Resequence ( ) ;
}
void CAssimilateDoc : : OnViewAnimEnums ( )
{
gbViewAnimEnums = ! gbViewAnimEnums ;
UpdateAllViews ( NULL , AS_FILESUPDATED , NULL ) ;
}
void CAssimilateDoc : : OnUpdateViewAnimEnums ( CCmdUI * pCmdUI )
{
pCmdUI - > SetCheck ( gbViewAnimEnums ) ;
}
void CAssimilateDoc : : OnViewFrameDetails ( )
{
gbViewFrameDetails = ! gbViewFrameDetails ;
UpdateAllViews ( NULL , AS_FILESUPDATED , NULL ) ;
}
void CAssimilateDoc : : OnUpdateViewFrameDetails ( CCmdUI * pCmdUI )
{
pCmdUI - > SetCheck ( gbViewFrameDetails ) ;
}
// 1) save qdt, 2) run qdata on it, 3) if success, save .cfg file...
//
bool CAssimilateDoc : : Build ( bool bAllowedToShowSuccessBox , int iLODLevel , bool bSkipSave ) // damn this stupid Serialize() crap
{
bool bSuccess = false ;
if ( Validate ( ) ) // notepad will have been launched with a textfile of errors at this point if faulty
{
// seems valid, so save the QDT...
//
giLODLevelOverride = iLODLevel ;
if ( ! bSkipSave )
{
OnFileSave ( ) ;
}
CString csQDataLocation = ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > GetQDataFilename ( ) ;
// hack-city!!!!!!!!!!
//
CModel * curModel = ghAssimilateView - > GetDocument ( ) - > GetCurrentUserSelectedModel ( ) ;
if ( curModel - > GetPreQuat ( ) )
{
csQDataLocation . MakeLower ( ) ;
csQDataLocation . Replace ( " carcass " , " carcass_prequat " ) ;
}
CString params = csQDataLocation ;
if ( ! bSkipSave )
{
params + = " -keypress " ;
}
params + = " -silent " ;
params + = " " ;
params + = m_strPathName ; // += (eg) {"Q:\quake\baseq3\models\players\ste_assimilate_test\ste_testaa.qdt"}
Filename_AccountForLOD ( params , giLODLevelOverride ) ;
PROCESS_INFORMATION pi ;
STARTUPINFO startupinfo ;
startupinfo . cb = sizeof ( startupinfo ) ;
startupinfo . lpReserved = NULL ;
startupinfo . lpDesktop = NULL ;
startupinfo . lpTitle = NULL ;
startupinfo . dwFlags = 0 ;
startupinfo . cbReserved2 = 0 ;
startupinfo . lpReserved2 = NULL ;
params . Replace ( " / " , " \\ " ) ;
csQDataLocation . Replace ( " / " , " \\ " ) ;
LPTSTR paramsPass = params . GetBuffer ( params . GetLength ( ) + 1 ) ;
StartWait ( ) ; // ++++++++++++++++++++++++
if ( CreateProcess ( csQDataLocation , paramsPass , NULL , NULL , FALSE , CREATE_NEW_CONSOLE , NULL , NULL , & startupinfo , & pi ) )
{
WaitForSingleObject ( pi . hProcess , INFINITE ) ;
EndWait ( ) ; // ------------------------
DWORD result ;
GetExitCodeProcess ( pi . hProcess , & result ) ;
if ( result )
{
char error [ 64 ] ;
sprintf ( error , " Process returned error: %d " , result ) ;
MessageBox ( NULL , error , " Build Failed " , MB_OK | MB_ICONERROR ) ;
}
CloseHandle ( pi . hProcess ) ;
if ( result = = 0 )
{
// QData was run successfully at this point, so write the CFG file(s)...
//
if ( iLODLevel ) // only LOD 0 writes out the CFG file
{
bSuccess = true ;
}
else
{
bool bCFGWritten = false ;
if ( WriteCFGFiles ( false , bCFGWritten ) ) // false = no name prompt, derive automatically from model name
{
// success (on a plate)...
//
if ( bAllowedToShowSuccessBox )
{
CString strReport ( " Everything seemed to go ok \n \n CAR " ) ;
if ( bCFGWritten )
{
strReport + = " and CFG files written " ;
if ( ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > GetMultiPlayerMode ( ) )
{
strReport + = " \n \n \n \n ( CFG file written for MULTI-PLAYER format ) " ;
}
else
{
strReport + = " \n \n \n \n ( CFG file written for SINGLE-PLAYER format ) " ;
}
}
else
{
strReport + = " file written " ;
strReport + = " \n \n \n \n ( CFG file not written for GLA-referencing model ) " ;
}
InfoBox ( strReport ) ;
}
bSuccess = true ;
}
}
}
}
else
{
EndWait ( ) ; // ------------------------
MessageBox ( NULL , " Could not spawn process. " , " Build Failed " , MB_OK | MB_ICONERROR ) ;
}
params . ReleaseBuffer ( ) ;
}
giLODLevelOverride = 0 ;
return bSuccess ;
}
void CAssimilateDoc : : OnBuildMultiLOD ( )
{
int iErrors = 0 ;
// to save time, I'll run all the validates first, and only if they're all ok will I go on to the build
// (which incidentally does a harmless re-validate again)
//
for ( int i = 0 ; i < 1 + EXTRA_LOD_LEVELS ; i + + )
{
iErrors + = Validate ( false , i ) ? 0 : 1 ;
}
// go ahead if all clear...
//
// (I'll write them in reverse-LOD order so the last one written is the standard one. This should hopefully avoid
// any problems with the current document potentially becoming "(name)_3.qdt" from then on to MFC)
//
if ( ! iErrors )
{
for ( int i = EXTRA_LOD_LEVELS ; i > = 0 ; i - - )
{
Build ( ! i , // bool bAllowedToShowSuccessBox (ie only on last one)
i , // int iLODLevel
false // bool bSkipSave
) ;
}
}
}
// 1) save qdt, 2) run qdata on it, 3) if success, save .cfg file...
//
void CAssimilateDoc : : OnBuild ( )
{
Build ( true , // bool bAllowedToShowSuccessBox,
0 , // int iLODLevel
false // bool bSkipSave
) ;
}
void CAssimilateDoc : : ClearModelUserSelectionBools ( )
{
CModel * curModel = m_modelList ;
while ( curModel )
{
curModel - > SetUserSelectionBool ( false ) ;
curModel = curModel - > GetNext ( ) ;
}
}
// if there's only one model loaded, return that, if none, return NULL, else if >1, return selected one, else NULL
//
CModel * CAssimilateDoc : : GetCurrentUserSelectedModel ( )
{
CModel * curModel = m_modelList ;
if ( ! curModel | | ! curModel - > GetNext ( ) )
{
return curModel ; // 0 or 1 models total loaded
}
// more than one loaded, so find the selected one and return that...
//
while ( curModel )
{
if ( curModel - > GetUserSelectionBool ( ) )
{
return curModel ;
}
curModel = curModel - > GetNext ( ) ;
}
return NULL ; // multiple loaded, but none selected
}
static bool FileUsesGLAReference ( LPCSTR psFilename , LPCSTR psGLAReference )
{
bool bReturn = false ;
FILE * fHandle = fopen ( psFilename , " rt " ) ;
if ( fHandle )
{
int iLen = filesize ( fHandle ) ;
if ( iLen > 0 )
{
char * psText = ( char * ) malloc ( iLen + 1 ) ;
if ( psText )
{
fread ( psText , 1 , iLen , fHandle ) ;
psText [ iLen ] = ' \0 ' ;
strlwr ( psText ) ;
// this is a simple test that could be made more precise, but for now...
//
if ( ( strstr ( psText , " aseanimgrab_gla " ) | | strstr ( psText , " makeskel " ) )
& &
strstr ( psText , psGLAReference )
)
{
bReturn = true ;
}
free ( psText ) ;
}
}
fclose ( fHandle ) ;
}
return bReturn ;
}
# define sASSUMEPATH "w:\\game\\base"
bool gbCarWash_YesToXSIScan ;
bool gbCarWash_DoingScan = false ; // MUST default to this
bool gbQueryGoAhead = true ; // MUST defualt to this
LPCSTR gpsCARWashDirOverride = NULL ; // MUST default to this
CString strCarWashErrors ;
bool gbCarwashErrorsOccured ;
CString strMustContainThisGLA ; // MUST be blank, else name of GLA to be present to be considered
void CAssimilateDoc : : OnCarWashActual ( )
{
gbCarwashErrorsOccured = false ;
CString strStartDir = gpsCARWashDirOverride ? gpsCARWashDirOverride : ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > GetQuakeDir ( ) ;
strStartDir . Replace ( " / " , " \\ " ) ;
if ( ! strStartDir . GetLength ( ) )
{
ErrorBox ( " Quake path not known at this point. Prefs not setup? " ) ;
gbCarwashErrorsOccured = true ;
return ;
// if (!GetYesNo("Quake path not known at this point because you've not loaded anything yet\n\nShould I assume " "\"" sASSUMEPATH "\"" "?"))
// return;
//
// strStartDir = sASSUMEPATH;
}
// (this app was written so that GetQuakeDir() returns a path with a trailing slash, not nice normally, but here...)
//
// if (strStartDir.GetAt(strStartDir.GetLength()-1)=='\\')
// strStartDir = strStartDir.Left(strStartDir.GetLength()-1);
if ( gpsCARWashDirOverride = = NULL )
{
strStartDir + = " models " ; //\\players";
}
if ( gbQueryGoAhead )
{
if ( ! GetYesNo ( va ( " About to scan: \" %s \\ *.CAR /s \" \n \n " /*"This can take a LONG time, "*/ " Proceed? " , strStartDir ) ) )
return ;
}
gbCarWash_YesToXSIScan = GetYesNo ( " Full XSI scan? ( \" NO \" will skip XSI reads, but v3.0 files are quick to read anyway now ) " ) ;
CWaitCursor wait ;
strCARsFound . Empty ( ) ;
iCARsFound = 0 ;
strSkippedDirs . Empty ( ) ;
strSkippedFiles . Empty ( ) ;
R_CheckCARs ( strStartDir , 0 , strMustContainThisGLA ) ; //bool bBuildListOnly
AlphaSortCARs ( ) ; // not important to alpha-sort here (during car-wash), just looks nicer
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( " Ready " ) ;
// ok, now ready to begin pass 2...
//
CString strReport ;
if ( ! iCARsFound )
{
ASSERT ( 0 ) ;
strReport = " No suitable .CAR files found for processing! \n \n " ;
if ( ! strSkippedDirs . IsEmpty ( ) )
{
strReport + = " Skipped Dirs: \n \n " ;
strReport + = strSkippedDirs ;
}
if ( ! strSkippedFiles . IsEmpty ( ) )
{
strReport + = " \n \n Skipped Files: \n \n " ;
strReport + = strSkippedFiles ;
}
ErrorBox ( strReport ) ;
gbCarwashErrorsOccured = true ;
}
else
{
//----------------
gbCarWash_DoingScan = true ;
strCarWashErrors . Empty ( ) ;
//----------------
CString strTotalErrors ;
strReport = " Processed files: \n \n " ;
for ( int i = 0 ; i < iCARsFound ; i + + )
{
CString strThisFile = strCARsFound ;
int iLoc = strThisFile . Find ( " \n " ) ;
if ( iLoc > = 0 )
{
strThisFile = strThisFile . Left ( iLoc ) ;
strCARsFound = strCARsFound . Mid ( iLoc + 1 ) ;
strReport + = strThisFile + " \n " ;
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( va ( " Scanning File %d/%d: %s " , i + 1 , iCARsFound , ( LPCSTR ) strThisFile ) ) ;
if ( 1 ) //strMustContainThisGLA.IsEmpty() || FileUsesGLAReference(strThisFile, strMustContainThisGLA))
{
OnNewDocument ( ) ;
Parse ( strThisFile ) ;
if ( gbParseError )
{
strTotalErrors + = va ( " \n Parse error in CAR file \" %s \" \n " , ( LPCSTR ) strThisFile ) ;
}
else
{
OnValidate ( ) ;
if ( ! strCarWashErrors . IsEmpty ( ) )
{
// "something is wrong..." :-)
//
strTotalErrors + = va ( " \n Error in file \" %s \" : \n \n %s \n " , ( LPCSTR ) strThisFile , ( LPCSTR ) strCarWashErrors ) ;
}
strCarWashErrors . Empty ( ) ;
}
}
}
else
{
ASSERT ( 0 ) ;
strThisFile . Insert ( 0 , " I fucked up, the following line didn't seem to have a CR: (tell me! -Ste) \n \n " ) ;
ErrorBox ( strThisFile ) ;
}
}
//----------------
gbCarWash_DoingScan = false ;
//----------------
OnNewDocument ( ) ; // trash whatever was loaded last
// strReport = "Processed files:\n\n";
// strReport+= strCARsFound;
strReport + = " \n \n Skipped Dirs: \n \n " ;
strReport + = strSkippedDirs ;
strReport + = " \n \n Skipped Files: \n \n " ;
strReport + = strSkippedFiles ;
if ( strTotalErrors . IsEmpty ( ) )
{
strReport . Insert ( 0 , " (No additional errors found) \n \n " ) ;
}
else
{
strReport + = " \n \n Additional errors will now be sent to Notepad!... " ;
gbCarwashErrorsOccured = true ;
}
if ( gbQueryGoAhead | | gbCarwashErrorsOccured )
{
InfoBox ( strReport ) ;
}
if ( ! strTotalErrors . IsEmpty ( ) )
{
strTotalErrors . Insert ( 0 , " The following errors occured during CARWash... \n \n " ) ;
SendToNotePad ( strTotalErrors , " carwash_errors.txt " ) ;
}
}
//#define sASSUMEPATH "q:\\quake\\baseq3"
// strTGAsWithRedundantAlpha.Insert(0,"The following files are defined as 32-bit (ie with alpha), but the alpha channel is blank (ie all 255)...\n\n");
// SendToNotePad(strTGAsWithRedundantAlpha, "TGAs_With_Redundant_Alpha.txt");
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( " Ready " ) ;
}
void CAssimilateDoc : : OnCarWash ( )
{
strMustContainThisGLA . Empty ( ) ;
OnCarWashActual ( ) ;
}
// creates as temp file, then spawns notepad with it...
//
bool SendToNotePad ( LPCSTR psWhatever , LPCSTR psLocalFileName )
{
bool bReturn = false ;
LPCSTR psOutputFileName = va ( " %s \\ %s " , scGetTempPath ( ) , psLocalFileName ) ;
FILE * handle = fopen ( psOutputFileName , " wt " ) ;
if ( handle )
{
fprintf ( handle , psWhatever ) ;
fclose ( handle ) ;
char sExecString [ MAX_PATH ] ;
sprintf ( sExecString , " notepad %s " , psOutputFileName ) ;
if ( WinExec ( sExecString , // LPCSTR lpCmdLine, // address of command line
SW_SHOWNORMAL // UINT uCmdShow // window style for new application
)
> 31 // don't ask me, Windoze just uses >31 as OK in this call.
)
{
// ok...
//
bReturn = true ;
}
else
{
ErrorBox ( " Unable to locate/run NOTEPAD on this machine! \n \n (let me know about this -Ste) " ) ;
}
}
else
{
ErrorBox ( va ( " Unable to create file \" %s \" for notepad to use! " , psOutputFileName ) ) ;
}
return bReturn ;
}
// AFX OnXxxx calls need to be void return, but the validate needs to ret a bool for elsewhere, so...
//
void CAssimilateDoc : : OnValidate ( )
{
Validate ( ! gbCarWash_DoingScan ) ;
}
void CAssimilateDoc : : OnValidateMultiLOD ( )
{
int iErrors = 0 ;
for ( int i = 0 ; i < 1 + EXTRA_LOD_LEVELS ; i + + )
{
iErrors + = Validate ( false , i ) ? 0 : 1 ;
}
if ( ! iErrors )
{
InfoBox ( va ( " Everything seems OK \n \n (Original + %d LOD levels checked) " , EXTRA_LOD_LEVELS ) ) ;
}
}
// checks for things that would stop the build process, such as missing ASE files, invalid loopframes, bad anim enums, etc,
// and writes all the faults to a text file that it displays via launching notepad
//
bool CAssimilateDoc : : Validate ( bool bInfoBoxAllowed , int iLODLevel )
{
OnResequence ( ) ;
int iNumModels = ghAssimilateView - > GetDocument ( ) - > GetNumModels ( ) ;
CModel * curModel = ghAssimilateView - > GetDocument ( ) - > GetCurrentUserSelectedModel ( ) ;
bool bValidateAll = false ;
int iFaults = 0 ;
StartWait ( ) ;
if ( iNumModels )
{
CString sOutputTextFile ;
sOutputTextFile . Format ( " %s \\ validation_faults%s.txt " , scGetTempPath ( ) , iLODLevel ? va ( " _LOD%d " , iLODLevel ) : " " ) ;
FILE * hFile = fopen ( sOutputTextFile , " wt " ) ;
if ( hFile )
{
if ( iNumModels > 1 )
{
if ( ! curModel ) // >1 models, but none selected, so validate all
{
bValidateAll = true ;
}
else
{
// >1 models, 1 selected, ask if we should do all...
//
bValidateAll = GetYesNo ( va ( " Validate ALL models? \n \n ( NO = model \" %s \" only ) " , curModel - > GetName ( ) ) ) ;
}
}
if ( bValidateAll )
{
curModel = ghAssimilateView - > GetDocument ( ) - > GetFirstModel ( ) ;
}
if ( iLODLevel )
{
fprintf ( hFile , " (LOD Level %d) \n " , iLODLevel ) ;
}
while ( curModel )
{
fprintf ( hFile , " \n Model: \" %s \" \n \n " , curModel - > GetName ( ) ) ;
int iThisModelFaults = iFaults ;
if ( ( curModel - > GetMakeSkelPath ( ) & & strlen ( curModel - > GetMakeSkelPath ( ) ) )
// ||
// ( curModel->GetSkelPath() && strlen(curModel->GetSkelPath()) )
)
{
// ... then all is fine
}
else
{
// this is an error, UNLESS you have a GLA sequence...
//
if ( ! curModel - > HasGLA ( ) )
{
//fprintf(hFile, "Model must have either a 'skel' or 'makeskel' path\n ( Double-click on the model name in the treeview to edit )\n");
fprintf ( hFile , " Model must have a 'makeskel' path \n ( Double-click on the top tree item's name (should be a folder), then click \" Makes it's own skeleton \" in the dialog ) \n " ) ;
iFaults + + ;
}
}
//
// validate all sequences within this model...
//
int iGLACount = 0 ;
int iXSICount = 0 ;
CSequence * curSequence = curModel - > GetFirstSequence ( ) ;
while ( curSequence )
{
// we'll need to check these counts after checking all sequences...
//
if ( curSequence - > IsGLA ( ) )
{
iGLACount + + ;
}
else
{
iXSICount + + ;
}
# define SEQREPORT CString temp;temp.Format("Sequence \"%s\":",curSequence->GetName());while (temp.GetLength()<35)temp+=" ";
// check 1, does the ASE file exist? (actually this is talking about XSIs/GLAs, but WTF...
//
CString nameASE = ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > GetQuakeDir ( ) ;
nameASE + = curSequence - > GetPath ( ) ;
Filename_AccountForLOD ( nameASE , iLODLevel ) ;
const int iNameSpacing = 35 ;
if ( ! FileExists ( nameASE ) )
{
if ( ! gbCarWash_DoingScan ) // because this will only duplicate reports otherwise
{
SEQREPORT ;
temp + = va ( " ASE/XSI/GLA file not found: \" %s \" \n " , nameASE ) ;
fprintf ( hFile , temp ) ;
iFaults + + ;
}
}
// new check, if this is an LOD ASE it must have the same framecount as the base (non-LOD) version...
//
if ( iLODLevel )
{
// read this file's framecount...
//
int iStartFrame , iFrameCount , iFrameSpeed ;
curSequence - > ReadASEHeader ( nameASE , iStartFrame , iFrameCount , iFrameSpeed ) ;
// read basefile's framecount...
//
CString baseASEname = ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > GetQuakeDir ( ) ;
baseASEname + = curSequence - > GetPath ( ) ;
int iStartFrameBASE , iFrameCountBASE , iFrameSpeedBASE ;
curSequence - > ReadASEHeader ( baseASEname , iStartFrameBASE , iFrameCountBASE , iFrameSpeedBASE ) ;
// same?...
//
if ( iFrameCount ! = iFrameCountBASE )
{
SEQREPORT ;
temp + = va ( " (SERIOUS ERROR) base ASE has %d frames, but this LOD version has %d frames! \n " , iFrameCountBASE , iFrameCount ) ;
fprintf ( hFile , temp ) ;
iFaults + + ;
}
}
// check 2, is the loopframe higher than the framecount of that sequence?...
//
if ( curSequence - > GetLoopFrame ( ) > = curSequence - > GetFrameCount ( ) )
{
SEQREPORT ;
temp + = va ( " loopframe %d is illegal, max = %d \n " , curSequence - > GetLoopFrame ( ) , curSequence - > GetFrameCount ( ) - 1 ) ;
fprintf ( hFile , temp ) ;
iFaults + + ;
}
if ( ! curModel - > IsGhoul2 ( ) )
{
// check 3, is the enum valid?...
//
if ( curSequence - > GetEnumType ( ) = = ET_INVALID )
{
SEQREPORT ;
temp + = va ( " invalid animation enum \" %s \" \n " , curSequence - > GetEnum ( ) ) ;
fprintf ( hFile , temp ) ;
iFaults + + ;
}
}
int iEnumUsageCount = curModel - > AnimEnumInUse ( curSequence - > GetEnum ( ) ) ;
if ( iEnumUsageCount > 1 )
{
SEQREPORT ;
temp + = va ( " animation enum \" %s \" is used %d times \n " , curSequence - > GetEnum ( ) , iEnumUsageCount ) ;
fprintf ( hFile , temp ) ;
iFaults + + ;
}
// a whole bunch of checks for the additional sequences...
//
if ( ! curSequence - > IsGLA ( ) )
{
for ( int i = 0 ; i < MAX_ADDITIONAL_SEQUENCES ; i + + )
{
CSequence * additionalSeq = curSequence - > AdditionalSeqs [ i ] ;
# define ADDITIONALSEQREPORT CString temp;temp.Format("Sequence \"%s\": (Additional: \"%s\"):",curSequence->GetName(),additionalSeq->GetEnum());while (temp.GetLength()<60)temp+=" ";
if ( additionalSeq - > AdditionalSequenceIsValid ( ) )
{
// check for duplicate enum names...
//
int iEnumUsageCount = curModel - > AnimEnumInUse ( additionalSeq - > GetEnum ( ) ) ;
if ( iEnumUsageCount > 1 )
{
ADDITIONALSEQREPORT ;
temp + = va ( " animation enum \" %s \" is used %d times \n " , additionalSeq - > GetEnum ( ) , iEnumUsageCount ) ;
fprintf ( hFile , temp ) ;
iFaults + + ;
}
// additional sequences must actually have some frames...
//
if ( additionalSeq - > GetFrameCount ( ) < = 0 )
{
ADDITIONALSEQREPORT ;
temp + = va ( " a frame count of %d is illegal (min = 1) \n " , additionalSeq - > GetFrameCount ( ) ) ;
fprintf ( hFile , temp ) ;
iFaults + + ;
}
else
{
// the start/count range of this additional seq can't exceed it's master...
//
if ( additionalSeq - > GetStartFrame ( ) + additionalSeq - > GetFrameCount ( ) > curSequence - > GetFrameCount ( ) )
{
ADDITIONALSEQREPORT ;
temp + = va ( " illegal start/count range of %d..%d exceeds master range of %d..%d \n " ,
additionalSeq - > GetStartFrame ( ) ,
additionalSeq - > GetStartFrame ( ) + additionalSeq - > GetFrameCount ( ) ,
curSequence - > GetStartFrame ( ) ,
curSequence - > GetStartFrame ( ) + curSequence - > GetFrameCount ( )
) ;
fprintf ( hFile , temp ) ;
iFaults + + ;
}
else
{
// loopframe of an additional seq must be within its own seq framecount...
//
if ( additionalSeq - > GetLoopFrame ( ) > = additionalSeq - > GetFrameCount ( ) )
{
ADDITIONALSEQREPORT ;
temp + = va ( " loopframe %d is illegal, max is %d \n " , additionalSeq - > GetLoopFrame ( ) , additionalSeq - > GetFrameCount ( ) - 1 ) ;
fprintf ( hFile , temp ) ;
iFaults + + ;
}
}
}
}
else
{
// is this additional sequence invalid because of being just empty or being bad?...
//
if ( strlen ( additionalSeq - > GetEnum ( ) ) )
{
// it's a bad sequence (probably because of its enum being deleted from anims.h since it was saved)
//
ADDITIONALSEQREPORT ;
temp + = va ( " this animation enum no longer exists in \" %s \" \n " , sDEFAULT_ENUM_FILENAME ) ;
fprintf ( hFile , temp ) ;
iFaults + + ;
}
}
}
}
curSequence = curSequence - > GetNext ( ) ;
}
// special GLA/XSI checks...
//
{
if ( iGLACount > 1 )
{
fprintf ( hFile , " Model has more than one GLA file specified \n " ) ;
iFaults + + ;
}
if ( iGLACount & & iXSICount )
{
fprintf ( hFile , " Model has both GLA and XSI files specified. Pick one method or the other \n " ) ;
iFaults + + ;
}
if ( iGLACount & & ( curModel - > GetMakeSkelPath ( ) & & strlen ( curModel - > GetMakeSkelPath ( ) ) ) )
{
fprintf ( hFile , " Model has both a GLA sequence and a '-makeskel' path, this is meaningless \n " ) ;
iFaults + + ;
}
/*
if ( iGLACount & & ( curModel - > GetSkelPath ( ) & & strlen ( curModel - > GetSkelPath ( ) ) ) )
{
fprintf ( hFile , " Model has both a GLA sequence and a '-skel' path, you should probably blank out the 'skel' path \n " ) ;
iFaults + + ;
}
*/
}
if ( iThisModelFaults = = iFaults )
{
fprintf ( hFile , " (ok) \n " ) ; // just to be nice if reporting on >1 model...
}
else
{
fprintf ( hFile , " \n (%d faults) \n " , iFaults - iThisModelFaults ) ;
}
curModel = curModel - > GetNext ( ) ;
if ( ! bValidateAll )
break ;
} // while (curModel)
fclose ( hFile ) ;
if ( iFaults )
{
// now run notepad.exe on the file we've just created...
//
CString sExecString ;
sExecString . Format ( " notepad %s " , sOutputTextFile ) ;
if ( WinExec ( sExecString , // LPCSTR lpCmdLine, // address of command line
SW_SHOWNORMAL // UINT uCmdShow // window style for new application
)
> 31 // don't ask me, Windoze just uses >31 as OK in this call.
)
{
// ok.
}
else
{
ErrorBox ( " Unable to locate/run NOTEPAD on this machine! \n \n (let me know about this -Ste) " ) ;
}
}
else
{
if ( bInfoBoxAllowed )
{
InfoBox ( " Everything ok \n \n ( All files exist, enums exist, and frames seem to be valid ranges ) " ) ;
}
}
} // if (hFile)
else
{
ErrorBox ( va ( " Arrgh! Unable to create file '%s'! \n \n (let me know about this -Ste) " , sOutputTextFile ) ) ;
}
} // if (iNumModels)
EndWait ( ) ;
return ! iFaults ;
}
void CAssimilateDoc : : OnUpdateResequence ( CCmdUI * pCmdUI )
{
pCmdUI - > Enable ( ! ! GetNumModels ( ) ) ;
}
void CAssimilateDoc : : OnUpdateFileSave ( CCmdUI * pCmdUI )
{
pCmdUI - > Enable ( ! ! GetNumModels ( ) ) ;
}
void CAssimilateDoc : : OnUpdateFileSaveAs ( CCmdUI * pCmdUI )
{
pCmdUI - > Enable ( ! ! GetNumModels ( ) ) ;
}
void CAssimilateDoc : : OnUpdateExternal ( CCmdUI * pCmdUI )
{
pCmdUI - > Enable ( ! ! GetNumModels ( ) ) ;
}
void CAssimilateDoc : : OnUpdateValidate ( CCmdUI * pCmdUI )
{
pCmdUI - > Enable ( ! ! GetNumModels ( ) ) ;
}
void CAssimilateDoc : : OnUpdateBuild ( CCmdUI * pCmdUI )
{
pCmdUI - > Enable ( ! ! GetNumModels ( ) ) ;
}
BOOL CAssimilateDoc : : DoFileSave ( )
{
// sourcesafe stuff
{
///////////////////////////////////////////
//
// some stuff so I can leave the code below untouched...
//
LPCSTR filename = ( LPCSTR ) m_strPathName ;
# define Sys_Printf(blah) StatusText(blah)
//
///////////////////////////////////////////
//
// check it out first, if necessary...
//
if ( SS_FunctionsAvailable ( ) )
{
if ( SS_IsUnderSourceControl ( filename ) )
{
if ( SS_IsCheckedOut ( filename ) )
{
if ( ! SS_IsCheckedOutByMe ( filename ) )
{
CString strCheckOuts ;
int iCount ;
if ( SS_ListCheckOuts ( filename , strCheckOuts , iCount ) )
{
ErrorBox ( va ( " File \" %s \" is checked out by: \n \n %s \n ... so you can't save over it... \n \n ... so you can't compile... \n \n Tough luck matey!....(bwahahahaha!!!!!) " , filename , ( LPCSTR ) strCheckOuts ) ) ;
return false ;
}
}
else
{
Sys_Printf ( " (You own this file under SourceSafe) \n " ) ;
}
}
else
{
if ( GetYesNo ( va ( " The file \" %s \" \n \n ...needs to be checked out so I can save over it \n \n Proceed? ('No' will abort the save) " , filename ) ) )
{
if ( SS_CheckOut ( filename ) )
{
Sys_Printf ( " (File checked out ok) \n " ) ;
}
else
{
ASSERT ( 0 ) ; // I want to know if this ever happens
Sys_Printf ( " (Error during file checkout, aborting save \n " ) ;
return false ;
}
}
else
{
Sys_Printf ( " (Checkout cancelled, aborting save \n " ) ;
return false ;
}
}
}
else
{
Sys_Printf ( " (This file is not under SourceSafe control) \n " ) ;
}
}
// now do seperate check for files that are still write-protected...
//
DWORD dw = GetFileAttributes ( filename ) ;
if ( dw ! = 0xFFFFFFFF & & ( dw & FILE_ATTRIBUTE_READONLY ) )
{
// hmmm, still write protected...
//
if ( SS_SetupOk ( ) )
{
if ( GetYesNo ( va ( " The file \" %s \" is write-protected, but probably not because of SourceSafe, just as a safety thing. \n \n (Tell me if you believe this is wrong -Ste) \n \n Do you want me to un-writeprotect it so you can save over it? ('No' will abort the save) " , filename ) ) )
{
if ( ! SetFileAttributes ( filename , dw & ~ FILE_ATTRIBUTE_READONLY ) )
{
ErrorBox ( " Failed to remove write protect, aborting... " ) ;
return false ;
}
}
else
{
Sys_Printf ( " (File was not write-enabled, aborting save) " ) ;
return false ;
}
}
else
{
ErrorBox ( va ( " The file \" %s \" is write-protected, but you don't appear to have SourceSafe set up properly on this machine, so I can't tell if the file is protected or just not checked out to you. \n \n If you really want to edit this you'll have to write-enable it yourself (which I'm deliberately not offering to do for you here <g>) " , filename ) ) ;
}
}
}
BOOL b = CDocument : : DoFileSave ( ) ;
if ( b = = TRUE )
{
// sourcesafe
LPCSTR filename = ( LPCSTR ) m_strPathName ;
# define Sys_Printf(blah) StatusText(blah)
if ( SS_FunctionsAvailable ( ) )
{
if ( SS_IsUnderSourceControl ( filename ) )
{
if ( SS_IsCheckedOutByMe ( filename ) )
{
// if ( SS_CheckIn( filename ))
// {
// Sys_Printf("(Checked in ok)\n");
// }
// else
// {
// Sys_Printf("Error during CheckIn\n");
// }
}
else
{
ErrorBox ( va ( " You do not have file \" %s \" checked out " , filename ) ) ;
}
}
else
{
// new bit, if it wasn't under SourceSafe, then ask if they want to add it...
//
if ( GetYesNo ( va ( " File \" %s \" is not under SourceSafe control, add to database? " , filename ) ) )
{
if ( SS_Add ( filename ) )
{
Sys_Printf ( " (File was added to SourceSafe Ok) \n " ) ;
// check it out as well...
//
if ( SS_CheckOut ( filename ) )
{
Sys_Printf ( " (File checked out ok) \n " ) ;
}
else
{
ASSERT ( 0 ) ; // I want to know if this ever happens
Sys_Printf ( " ( Error during file checkout! ) \n " ) ;
}
}
else
{
ErrorBox ( va ( " Error adding file \" %s \" to SourceSafe " , filename ) ) ;
}
}
}
}
}
StatusText ( NULL ) ;
return b ;
}
BOOL CAssimilateDoc : : OnSaveDocument ( LPCTSTR lpszPathName )
{
CString strFileName = lpszPathName ;
Filename_AccountForLOD ( strFileName , giLODLevelOverride ) ; // this is actually junk now, should lose all this LODoverride stuff
return CDocument : : OnSaveDocument ( strFileName ) ;
}
// remember these two from session to session, maybe write to registry sometime?...
//
bool gbPreValidate = true ;
CString strInitialBuildPath = " models/players " ;
void CAssimilateDoc : : OnEditBuildDependant ( )
{
CModel * curModel = m_modelList ;
if ( curModel )
{
CString strStartDir = ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > GetQuakeDir ( ) ;
if ( ! strStartDir . GetLength ( ) )
{
// should never happen...
//
ErrorBox ( " Base path not known at this point. Prefs not setup? " ) ;
return ;
}
LPCSTR psCurrentGLAName = curModel - > GetMakeSkelPath ( ) ;
if ( psCurrentGLAName )
{
char sCurrentGLAName [ 1024 ] ;
strcpy ( sCurrentGLAName , psCurrentGLAName ) ;
strMustContainThisGLA = sCurrentGLAName ;
CBuildAll dlgBuildAll ( strInitialBuildPath , gbPreValidate ) ;
if ( dlgBuildAll . DoModal ( ) = = IDOK )
{
dlgBuildAll . GetData ( strInitialBuildPath , gbPreValidate ) ;
strStartDir + = strInitialBuildPath ;
strStartDir . Replace ( " / " , " \\ " ) ;
while ( strStartDir . Replace ( " \\ \\ " , " \\ " ) ) { }
if ( gbPreValidate )
{
gbQueryGoAhead = false ;
gpsCARWashDirOverride = ( LPCSTR ) strStartDir ;
OnCarWashActual ( ) ;
gbQueryGoAhead = true ;
gpsCARWashDirOverride = NULL ;
if ( gbCarwashErrorsOccured )
{
InfoBox ( " Build-All aborted because of errors " ) ;
return ;
}
}
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( " Validated Ok, building... " ) ;
//////////////////////// largely block-pasted from CarWash.... :-)
CWaitCursor wait ;
strCARsFound . Empty ( ) ;
iCARsFound = 0 ;
strSkippedDirs . Empty ( ) ;
strSkippedFiles . Empty ( ) ;
// build up a list...
//
R_CheckCARs ( strStartDir , 0 , strMustContainThisGLA ) ; //bool bBuildListOnly
AlphaSortCARs ( ) ; // important to do them in alpha-order during build, because of "_humanoid" - type dirs.
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( " Ready " ) ;
// ok, now ready to begin pass 2...
//
CString strReport ;
if ( ! iCARsFound )
{
ASSERT ( 0 ) ;
strReport = " No suitable .CAR files found for processing! \n \n " ;
if ( ! strSkippedDirs . IsEmpty ( ) )
{
strReport + = " Skipped Dirs: \n \n " ;
strReport + = strSkippedDirs ;
}
if ( ! strSkippedFiles . IsEmpty ( ) )
{
strReport + = " \n \n Skipped Files: \n \n " ;
strReport + = strSkippedFiles ;
}
ErrorBox ( strReport ) ;
}
else
{
//----------------
gbCarWash_DoingScan = true ;
strCarWashErrors . Empty ( ) ;
//----------------
CString strTotalErrors ;
strReport = " Processed files: \n \n " ;
for ( int i = 0 ; i < iCARsFound ; i + + )
{
CString strThisFile = strCARsFound ;
int iLoc = strThisFile . Find ( " \n " ) ;
if ( iLoc > = 0 )
{
strThisFile = strThisFile . Left ( iLoc ) ;
strCARsFound = strCARsFound . Mid ( iLoc + 1 ) ;
strReport + = strThisFile + " \n " ;
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( va ( " Scanning File %d/%d: %s " , i + 1 , iCARsFound , ( LPCSTR ) strThisFile ) ) ;
if ( 1 ) //FileUsesGLAReference(strThisFile, sCurrentGLAName))
{
OnNewDocument ( ) ;
if ( OnOpenDocument_Actual ( strThisFile , false ) )
{
if ( gbParseError )
{
strTotalErrors + = va ( " \n Parse error in file \" %s \" \n " , ( LPCSTR ) strThisFile ) ;
break ;
}
else
{
m_strPathName = strThisFile ; // fucking stupid MFC doesn't set this!!!!!!!!!!!!!
bool bSuccess = Build ( false , // bool bAllowedToShowSuccessBox,
0 , // int iLODLevel
true // bool bSkipSave
) ;
if ( ! strCarWashErrors . IsEmpty ( ) )
{
// "something is wrong..." :-)
//
strTotalErrors + = va ( " \n Error in file \" %s \" : \n \n %s \n " , strThisFile , strCarWashErrors ) ;
}
strCarWashErrors . Empty ( ) ;
if ( ! bSuccess )
break ;
}
}
else
{
strTotalErrors + = va ( " \n Unable to open file \" %s \" \n " , ( LPCSTR ) strThisFile ) ;
break ;
}
}
else
{
// this CAR file doesn't use the current GLA name, so ignore it
}
}
else
{
ASSERT ( 0 ) ;
strThisFile . Insert ( 0 , " I fucked up, the following line didn't seem to have a CR: (tell me! -Ste) \n \n " ) ;
ErrorBox ( strThisFile ) ;
}
}
//----------------
gbCarWash_DoingScan = false ;
//----------------
OnNewDocument ( ) ; // trash whatever was loaded last
// strReport = "Processed files:\n\n";
// strReport+= strCARsFound;
strReport + = " \n \n Skipped Dirs: \n \n " ;
strReport + = strSkippedDirs ;
strReport + = " \n \n Skipped Files: \n \n " ;
strReport + = strSkippedFiles ;
if ( strTotalErrors . IsEmpty ( ) )
{
strReport . Insert ( 0 , " (No additional errors found) \n \n " ) ;
}
else
{
strReport + = " \n \n Additional errors will now be sent to Notepad!... " ;
}
InfoBox ( strReport ) ;
if ( ! strTotalErrors . IsEmpty ( ) )
{
strTotalErrors . Insert ( 0 , " The following errors occured during build... \n \n " ) ;
SendToNotePad ( strTotalErrors , " build_errors.txt " ) ;
}
}
}
}
else
{
ErrorBox ( " Currently loaded model does not make a skeleton, so there are no dependants \n \n \n DUH!! " ) ;
}
}
else
{
ErrorBox ( " No model loaded to build dependants of! \n \n \n DUH!! " ) ;
}
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( " Ready " ) ;
}
void CAssimilateDoc : : OnEditBuildall ( )
{
// if (!GetYesNo("Safety Feature: Do you really want to rebuild every CAR file in the whole game?"))
// return;
// validity-check...
//
CString strStartDir = ( ( CAssimilateApp * ) AfxGetApp ( ) ) - > GetQuakeDir ( ) ;
if ( ! strStartDir . GetLength ( ) )
{
ErrorBox ( " Base path not known at this point. Prefs not setup? " ) ;
return ;
}
CBuildAll dlgBuildAll ( strInitialBuildPath , gbPreValidate ) ;
if ( dlgBuildAll . DoModal ( ) = = IDOK )
{
dlgBuildAll . GetData ( strInitialBuildPath , gbPreValidate ) ;
strStartDir + = strInitialBuildPath ;
strStartDir . Replace ( " / " , " \\ " ) ;
while ( strStartDir . Replace ( " \\ \\ " , " \\ " ) ) { }
if ( gbPreValidate )
{
gbQueryGoAhead = false ;
gpsCARWashDirOverride = ( LPCSTR ) strStartDir ;
OnCarWash ( ) ;
gbQueryGoAhead = true ;
gpsCARWashDirOverride = NULL ;
if ( gbCarwashErrorsOccured )
{
InfoBox ( " Build-All aborted because of errors " ) ;
return ;
}
}
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( " Validated Ok, building... " ) ;
//////////////////////// largely block-pasted from CarWash.... :-)
CWaitCursor wait ;
strCARsFound . Empty ( ) ;
iCARsFound = 0 ;
strSkippedDirs . Empty ( ) ;
strSkippedFiles . Empty ( ) ;
// build up a list...
//
R_CheckCARs ( strStartDir , 0 , " " ) ; //bool bBuildListOnly
AlphaSortCARs ( ) ; // important to do them in alpha-order during build, because of "_humanoid" - type dirs.
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( " Ready " ) ;
// ok, now ready to begin pass 2...
//
CString strReport ;
if ( ! iCARsFound )
{
ASSERT ( 0 ) ;
strReport = " No suitable .CAR files found for processing! \n \n " ;
if ( ! strSkippedDirs . IsEmpty ( ) )
{
strReport + = " Skipped Dirs: \n \n " ;
strReport + = strSkippedDirs ;
}
if ( ! strSkippedFiles . IsEmpty ( ) )
{
strReport + = " \n \n Skipped Files: \n \n " ;
strReport + = strSkippedFiles ;
}
ErrorBox ( strReport ) ;
}
else
{
//----------------
gbCarWash_DoingScan = true ;
strCarWashErrors . Empty ( ) ;
//----------------
CString strTotalErrors ;
strReport = " Processed files: \n \n " ;
for ( int i = 0 ; i < iCARsFound ; i + + )
{
CString strThisFile = strCARsFound ;
int iLoc = strThisFile . Find ( " \n " ) ;
if ( iLoc > = 0 )
{
strThisFile = strThisFile . Left ( iLoc ) ;
strCARsFound = strCARsFound . Mid ( iLoc + 1 ) ;
strReport + = strThisFile + " \n " ;
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( va ( " Scanning File %d/%d: %s " , i + 1 , iCARsFound , ( LPCSTR ) strThisFile ) ) ;
OnNewDocument ( ) ;
if ( OnOpenDocument_Actual ( strThisFile , false ) )
{
if ( gbParseError )
{
strTotalErrors + = va ( " \n Parse error in file \" %s \" \n " , ( LPCSTR ) strThisFile ) ;
break ;
}
else
{
m_strPathName = strThisFile ; // fucking stupid MFC doesn't set this!!!!!!!!!!!!!
bool bSuccess = Build ( false , // bool bAllowedToShowSuccessBox,
0 , // int iLODLevel
true // bool bSkipSave
) ;
if ( ! strCarWashErrors . IsEmpty ( ) )
{
// "something is wrong..." :-)
//
strTotalErrors + = va ( " \n Error in file \" %s \" : \n \n %s \n " , strThisFile , strCarWashErrors ) ;
}
strCarWashErrors . Empty ( ) ;
if ( ! bSuccess )
break ;
}
}
else
{
strTotalErrors + = va ( " \n Unable to open file \" %s \" \n " , ( LPCSTR ) strThisFile ) ;
break ;
}
}
else
{
ASSERT ( 0 ) ;
strThisFile . Insert ( 0 , " I fucked up, the following line didn't seem to have a CR: (tell me! -Ste) \n \n " ) ;
ErrorBox ( strThisFile ) ;
}
}
//----------------
gbCarWash_DoingScan = false ;
//----------------
OnNewDocument ( ) ; // trash whatever was loaded last
// strReport = "Processed files:\n\n";
// strReport+= strCARsFound;
strReport + = " \n \n Skipped Dirs: \n \n " ;
strReport + = strSkippedDirs ;
strReport + = " \n \n Skipped Files: \n \n " ;
strReport + = strSkippedFiles ;
if ( strTotalErrors . IsEmpty ( ) )
{
strReport . Insert ( 0 , " (No additional errors found) \n \n " ) ;
}
else
{
strReport + = " \n \n Additional errors will now be sent to Notepad!... " ;
}
InfoBox ( strReport ) ;
if ( ! strTotalErrors . IsEmpty ( ) )
{
strTotalErrors . Insert ( 0 , " The following errors occured during build... \n \n " ) ;
SendToNotePad ( strTotalErrors , " build_errors.txt " ) ;
}
}
}
( ( CMainFrame * ) AfxGetMainWnd ( ) ) - > StatusMessage ( " Ready " ) ;
}
void SS_DisposingOfCurrent ( LPCSTR psFileName , bool bDirty )
{
if ( psFileName [ 0 ] )
{
LPCSTR filename = psFileName ; // compile laziness
# undef Sys_Printf
# define Sys_Printf(blah)
if ( SS_FunctionsAvailable ( ) )
{
if ( SS_IsUnderSourceControl ( filename ) )
{
if ( SS_IsCheckedOutByMe ( filename ) )
{
if ( bDirty )
{
// if 'need_save' then the user has clicked ok-to-lose-changes, so...
//
if ( GetYesNo ( va ( " Since you've decided to lose changes on the file: \n \n \" %s \" \n \n ...do you want to Undo Checkout as well? " , filename ) ) )
{
if ( SS_UndoCheckOut ( filename ) )
{
Sys_Printf ( " (Undo Checkout performed on map) \n " ) ;
}
else
{
ErrorBox ( " Undo Checkout failed! \n " ) ;
}
}
}
else
{
// if !'need_save' here then the user has saved this out already, so prompt for check in...
//
if ( GetYesNo ( va ( " Since you've finished with the file: \n \n \" %s \" \n \n ...do you want to do a Check In? " , filename ) ) )
{
if ( SS_CheckIn ( filename ) )
{
//Sys_Printf ("(CheckIn performed on map)\n");
}
else
{
ErrorBox ( " CheckIn failed! \n " ) ;
}
}
}
}
}
}
}
}
BOOL CAssimilateDoc : : OnOpenDocument_Actual ( LPCTSTR lpszPathName , bool bCheckOut )
{
SS_DisposingOfCurrent ( m_strPathName , ! ! IsModified ( ) ) ;
if ( bCheckOut )
{
// checkout the new file?
LPCSTR filename = lpszPathName ; // compile-laziness :-)
if ( SS_FunctionsAvailable ( ) )
{
if ( SS_IsUnderSourceControl ( filename ) )
{
if ( SS_IsCheckedOut ( filename ) )
{
if ( ! SS_IsCheckedOutByMe ( filename ) )
{
CString strCheckOuts ;
int iCount ;
if ( SS_ListCheckOuts ( filename , strCheckOuts , iCount ) )
{
if ( ! GetYesNo ( va ( " Warning: File \" %s \" is checked out by: \n \n %s \n ... Continue loading? " , filename , ( LPCSTR ) strCheckOuts ) ) )
{
return FALSE ;
}
}
}
else
{
//InfoBox ("(You own this file under SourceSafe)\n");
}
}
else
{
if ( GetYesNo ( va ( " The file \" %s \" \n \n ...is under SourceSafe control, check it out now? " , filename ) ) )
{
if ( SS_CheckOut ( filename ) )
{
//InfoBox ("(File checked out ok)\n");
}
else
{
WarningBox ( va ( " ( Problem encountered during check out of file \" %s \" ) " , filename ) ) ;
}
}
}
}
else
{
//InfoBox ("(This file is not under SourceSafe control)\n");
}
}
}
if ( ! CDocument : : OnOpenDocument ( lpszPathName ) )
return FALSE ;
return TRUE ;
}
BOOL CAssimilateDoc : : OnOpenDocument ( LPCTSTR lpszPathName )
{
return OnOpenDocument_Actual ( lpszPathName , true ) ;
}
void CAssimilateDoc : : OnCloseDocument ( )
{
SS_DisposingOfCurrent ( m_strPathName , ! ! IsModified ( ) ) ;
CDocument : : OnCloseDocument ( ) ;
}
void CAssimilateDoc : : OnViewFramedetailsonadditionalsequences ( )
{
gbViewFrameDetails_Additional = ! gbViewFrameDetails_Additional ;
UpdateAllViews ( NULL , AS_FILESUPDATED , NULL ) ;
}
void CAssimilateDoc : : OnUpdateViewFramedetailsonadditionalsequences ( CCmdUI * pCmdUI )
{
pCmdUI - > SetCheck ( gbViewFrameDetails_Additional ) ;
}
void CAssimilateDoc : : OnUpdateEditBuilddependant ( CCmdUI * pCmdUI )
{
pCmdUI - > Enable ( ! ! GetNumModels ( ) ) ;
}
bool RunApp ( LPCSTR psAppCommand )
{
CString strExec = psAppCommand ; // eg "start q:\\bin_nt\\behaved.exe";
strExec . Replace ( " / " , " \\ " ) ; // otherwise it only works under NT...
char sBatchFilename [ 512 ] ;
GetTempPath ( sizeof ( sBatchFilename ) , sBatchFilename ) ;
strcat ( sBatchFilename , " ~temp.bat " ) ;
FILE * handle = fopen ( sBatchFilename , " wt " ) ;
fprintf ( handle , strExec ) ;
fprintf ( handle , " \n " ) ;
fclose ( handle ) ;
STARTUPINFO startupinfo ;
PROCESS_INFORMATION ProcessInformation ;
GetStartupInfo ( & startupinfo ) ;
BOOL ret = CreateProcess ( sBatchFilename ,
//batpath, // pointer to name of executable module
NULL , // pointer to command line string
NULL , // pointer to process security attributes
NULL , // pointer to thread security attributes
FALSE , // handle inheritance flag
0 /*DETACHED_PROCESS*/ , // creation flags
NULL , // pointer to new environment block
NULL , // pointer to current directory name
& startupinfo , // pointer to STARTUPINFO
& ProcessInformation // pointer to PROCESS_INFORMATION
) ;
// remove(sBatchFilename); // if you do this, the CreateProcess fails, presumably it needs it for a few seconds
return ! ! ret ;
}
void CAssimilateDoc : : OnEditLaunchmodviewoncurrent ( )
{
char sExecString [ MAX_PATH ] ;
sprintf ( sExecString , " start %s.glm " , Filename_WithoutExt ( m_strPathName ) ) ;
if ( RunApp ( sExecString ) )
{
// ok...
//
}
else
{
ErrorBox ( va ( " CreateProcess() call \" %s \" failed! \n \n (let me know about this -Ste) " , sExecString ) ) ;
}
}
void CAssimilateDoc : : OnUpdateEditLaunchmodviewoncurrent ( CCmdUI * pCmdUI )
{
pCmdUI - > Enable ( ! ! GetNumModels ( ) ) ;
}