jedi-outcast/utils/Assimilate/Sequences.cpp
2013-04-22 15:25:59 +10:00

1792 lines
40 KiB
C++

// Sequences.cpp
#include "Stdafx.h"
#include "Includes.h"
#include "gla.h"
#include "matrix4.h"
#include "xsiimp.h"
#define ONKILLFOCUS UpdateData(DIALOG_TO_DATA)
keywordArray_t CSequence_s_Symbols[] =
{
"*", TK_ASTERISK,
NULL, TK_EOF,
};
keywordArray_t CSequence_s_Keywords[] =
{
"SCENE_FRAMESPEED", TK_ASE_FRAMESPEED,
"SCENE_FIRSTFRAME", TK_ASE_FIRSTFRAME,
"SCENE_LASTFRAME", TK_ASE_LASTFRAME,
NULL, TK_EOF,
};
CSequence::CSequence()
{
}
CSequence::~CSequence()
{
}
void CSequence::Delete()
{
while(m_comments != NULL)
{
CComment* curComment = m_comments;
m_comments = curComment->GetNext();
curComment->Delete();
}
if (m_path != NULL)
{
free(m_path);
m_path = NULL;
}
if (m_name != NULL)
{
free(m_name);
m_name = NULL;
}
if (m_action != NULL)
{
free(m_action);
m_action = NULL;
}
if (m_sound != NULL)
{
free(m_sound);
m_sound = NULL;
}
// now a cstring
// if (m_enum != NULL)
// {
// free(m_enum);
// m_enum = NULL;
// }
for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++)
{
if (AdditionalSeqs[i])
{
AdditionalSeqs[i]->Delete();
AdditionalSeqs[i] = NULL;
}
}
delete this;
}
CSequence* CSequence::CreateFromFile(LPCTSTR path, CComment* comments)
{
CSequence* retval = new CSequence();
CString name = path;
name.Replace('\\', '/');
name.MakeLower();
retval->_Init(false,!!(strstr(path,".gla")),name, 0, 0, 0, iDEFAULTSEQFRAMESPEED,iDEFAULTSEQFRAMESPEED,comments); // (noticed) this fills in certain fields wrongly until the next 2 lines correct them
retval->DeriveName();
retval->ReadHeader();
//
// at this point the m_path member is wrong because it contains the full path including "\quake\...", so...
//
CString newPath = retval->GetPath();
Filename_RemoveBASEQ(newPath);
retval->SetPath(newPath);
return retval;
}
void CSequence::ReadHeader()
{
int iStartFrame, iFrameCount, iFrameSpeed;
CString nameASE = ((CAssimilateApp*)AfxGetApp())->GetQuakeDir();
nameASE+= GetPath();
ReadASEHeader( nameASE, iStartFrame, iFrameCount, iFrameSpeed);
SetStartFrame( iStartFrame );
SetFrameCount( iFrameCount );
SetFrameSpeed( iFrameSpeed ); // iDEFAULTSEQFRAMESPEED
SetFrameSpeedFromHeader( iFrameSpeed );
}
void ReadXSIHeader(LPCSTR psFilename, int &iStartFrame, int &iFrameCount, int &iFrameSpeed)
{
OutputDebugString(va("ReadXSIHeader(): %s\n",psFilename));
// let's try the fast way of reading first, by scanning directly for the header value if it's a 3.0 file...
//
{
bool bGotInfo = false;
FILE *fp = fopen(psFilename,"ra");
if (fp)
{
fseek(fp,0,SEEK_END);
int iLen = ftell(fp);
if (iLen>1024)//2048)
iLen=1024;//2048; // findmeste
char *psFileBin = new char[iLen+1];
assert(psFileBin);
psFileBin[iLen]='\0';
fseek(fp,0,SEEK_SET);
if (fread(psFileBin,1,iLen,fp) == (size_t)iLen)
{
// I'm not sure how to tie this in with Gil's rather-complex XSI reader, so do this seperately...
//
{
/* Field I want to read looks like this:
SI_Scene testdeath {
"FRAMES",
1.000000,
62.000000,
30.000000,
}
*/
char *psSearch = strstr(psFileBin,"SI_Scene");
if (psSearch)
{
while (psSearch != (psFileBin+iLen) && *psSearch != '{') // '}' don't bugger-up brace-matching
{
psSearch++;
}
if (*psSearch++=='{') // '}' don't bugger-up brace-matching
{
char sScanBuffer[2048]={0};
for (int i=0; i<sizeof(sScanBuffer)-1 && psSearch != psFileBin+iLen; i++, psSearch++)
{
if (isspace(*psSearch) || *psSearch=='"')
continue;
strcat(sScanBuffer,va("%c",*psSearch));
}
char sTemp[2048];
float fOneBased; // this number seems to be either 0 or 1, which affects the fFrames val.
float fFrames;
float fFPS;
int iFieldsRead = sscanf(sScanBuffer,"%6s, %f, %f, %f",&sTemp,&fOneBased,&fFrames,&fFPS);
if (iFieldsRead==4 && !strcmp(sTemp,"FRAMES"))
{
// success...
//
iStartFrame = 0;
iFrameCount = ((int) fFrames - (int) fOneBased)+1;
iFrameSpeed = (int) fFPS;
bGotInfo = true;
}
}
}
}
}
delete [] psFileBin;
fclose(fp);
if (bGotInfo)
return;
}
}
// if we get here, then this is probably an old 1.3 format file, so read the frames count etc the tedious way...
//
// (Note that the XSI reader here is the original Assimilate one, not Gil's super-spiffy read-anything version, since it
// only has to deal with the old format files which this one copes with ok)...
//
int iNumFrames = XSI_LoadFile(psFilename);
// assert(iNumFrames == iFrameCount);
iStartFrame = 0;
iFrameCount = iNumFrames;
iFrameSpeed = iDEFAULTSEQFRAMESPEED;
XSI_Cleanup();
}
bool gbSkipXSIRead_QuestionAsked = false;
bool gbSkipXSIRead = false;
typedef pair< int, int> FrameCountAndSpeed_t;
typedef map <CString, FrameCountAndSpeed_t> ASECachedInfo_t;
ASECachedInfo_t ASECachedInfo;
//
// this actually reads XSI or GLA headers... historical mutation strikes again...
//
static void ReadASEHeader_Actual(LPCSTR psFilename, int &iStartFrame, int &iFrameCount, int &iFrameSpeed, bool bReadingGLA, bool bCanSkipXSIRead /* = false */)
{
// since the XSI loader is so damn slow and flakey I'm going to have to cache the info to avoid re-reading...
//
// do we have it in the cache?...
//
if (strstr(psFilename,".xsi") || strstr(psFilename,".XSI"))
{
ASECachedInfo_t::iterator iter = ASECachedInfo.find(psFilename);
if (iter != ASECachedInfo.end())
{
iStartFrame = 0;
iFrameCount = (*iter).second.first;
iFrameSpeed = (*iter).second.second;
return;
}
}
// is it a GLA file?...
//
if (bReadingGLA)
{
char sTemp[1024];
strcpy(sTemp,psFilename);
if (!(strstr(psFilename,".gla") || strstr(psFilename,".GLA")))
{
strcat(sTemp,".gla");
}
iStartFrame = 0;
iFrameCount = GLA_ReadHeader(sTemp);
iFrameSpeed = 20; // any old value for GLA file
return;
}
// it's not in the cache, but we may be able to avoid having to read it under some circumstances...
//
bool bXSIShouldBeRead = true;
if (gbCarWash_DoingScan)
{
bCanSkipXSIRead = false; // stop it asking the question
bXSIShouldBeRead= gbCarWash_YesToXSIScan;
}
if ( (strstr(psFilename,".xsi") || strstr(psFilename,".XSI"))
&& bCanSkipXSIRead
)
{
if (!gbSkipXSIRead && !gbSkipXSIRead_QuestionAsked)
{
gbSkipXSIRead_QuestionAsked = true;
gbSkipXSIRead = !GetYesNo(va("Model file: \"%s\"\n\n... is an XSI, and they can be damn slow to read in\n\nDo you want to scan all the XSIs?",psFilename));
}
bXSIShouldBeRead = !gbSkipXSIRead;
}
if (strstr(psFilename,".xsi") || strstr(psFilename,".XSI"))
{
if (bXSIShouldBeRead)
{
ReadXSIHeader(psFilename, iStartFrame, iFrameCount, iFrameSpeed);
if (iFrameCount!=0)
{
// cache it for future...
//
ASECachedInfo[psFilename] = FrameCountAndSpeed_t(iFrameCount,iFrameSpeed);
}
}
return;
}
// it must be an ASE file then instead....
//
CTokenizer* tokenizer = CTokenizer::Create();
tokenizer->AddParseFile(psFilename, ((CAssimilateApp*)AfxGetApp())->GetBufferSize());
tokenizer->SetSymbols(CSequence_s_Symbols);
tokenizer->SetKeywords(CSequence_s_Keywords);
CToken* curToken = tokenizer->GetToken();
while(curToken != NULL)
{
switch (curToken->GetType())
{
case TK_EOF:
curToken->Delete();
curToken = NULL;
break;
case TK_ASTERISK:
curToken->Delete();
curToken = tokenizer->GetToken();
switch(curToken->GetType())
{
case TK_ASE_FIRSTFRAME:
curToken->Delete();
curToken = tokenizer->GetToken();
if (curToken->GetType() == TK_INTEGER)
{
iStartFrame = curToken->GetIntValue();
curToken->Delete();
curToken = tokenizer->GetToken();
}
break;
case TK_ASE_LASTFRAME:
curToken->Delete();
curToken = tokenizer->GetToken();
if (curToken->GetType() == TK_INTEGER)
{
iFrameCount = curToken->GetIntValue() + 1;
curToken->Delete();
curToken = NULL; // tells outer loop to finish
}
break;
case TK_ASE_FRAMESPEED:
curToken->Delete();
curToken = tokenizer->GetToken();
if (curToken->GetType() == TK_INTEGER)
{
iFrameSpeed = curToken->GetIntValue();
curToken->Delete();
curToken = tokenizer->GetToken();
}
break;
case TK_EOF:
curToken->Delete();
curToken = NULL;
break;
default:
curToken->Delete();
curToken = tokenizer->GetToken();
break;
}
break;
default:
curToken->Delete();
curToken = tokenizer->GetToken();
break;
}
}
tokenizer->Delete();
iFrameCount -= iStartFrame;
iStartFrame = 0;
}
void ReadASEHeader(LPCSTR psFilename, int &iStartFrame, int &iFrameCount, int &iFrameSpeed, bool bReadingGLA, bool bCanSkipXSIRead /* = false */)
{
StatusText(va("Reading Header: \"%s\"",psFilename));
ReadASEHeader_Actual(psFilename, iStartFrame, iFrameCount, iFrameSpeed, bReadingGLA, bCanSkipXSIRead);
StatusText(NULL);
}
// this does NOT update any member vars, so can be called from outside this class, it just reads member vars to
// find out what tables to pass to tokenizer...
//
void CSequence::ReadASEHeader(LPCSTR psFilename, int &iStartFrame, int &iFrameCount, int &iFrameSpeed, bool bCanSkipXSIRead /* = false */)
{
::ReadASEHeader(psFilename, iStartFrame, iFrameCount, iFrameSpeed, m_bIsGLA, bCanSkipXSIRead);
}
bool CSequence::Parse()
{
CASEFile* aseFile = CASEFile::Create(m_path);
aseFile->Parse();
aseFile->Delete();
return true;
}
CSequence* CSequence::_Create(bool bGenLoopFrame, bool bIsGLA, LPCTSTR path, int startFrame, int targetFrame, int frameCount, int frameSpeed, int frameSpeedFromHeader, CComment* comments)
{
CSequence* retval = new CSequence();
retval->_Init(bGenLoopFrame, bIsGLA, path, startFrame, targetFrame, frameCount, frameSpeed, frameSpeedFromHeader, comments);
return retval;
}
bool CSequence::DoProperties()
{
bool dirty = false;
if (IsGLA())
{
InfoBox("You can't edit the properties of a GLA file");
}
else
{
CPropertySheet* propSheet = new CPropertySheet(m_name);
CSequencePropPage* propPage = new CSequencePropPage();
propPage->m_sequence = this;
propPage->m_soilFlag = &dirty;
propSheet->AddPage(propPage);
propSheet->DoModal();
delete propPage;
delete propSheet;
}
return dirty;
}
CSequence* CSequence::GetNext()
{
return m_next;
}
void CSequence::SetNext(CSequence* next)
{
m_next = next;
}
bool CSequence::ValidEnum()
{
return m_validEnum;
}
void CSequence::SetValidEnum(bool value)
{
m_validEnum = value;
}
LPCTSTR CSequence::GetPath()
{
return m_path;
}
void CSequence::SetPath(LPCTSTR path)
{
if (m_path != NULL)
{
free(m_path);
}
if (path == NULL)
{
m_path = NULL;
}
else
{
m_path = (char*)malloc(strlen(path) + 1);
strcpy(m_path, path);
}
}
int CSequence::GetStartFrame()
{
return m_startFrame;
}
void CSequence::SetStartFrame(int frame)
{
m_startFrame = frame;
}
int CSequence::GetTargetFrame()
{
return m_targetFrame;
}
void CSequence::SetTargetFrame(int frame)
{
m_targetFrame = frame;
}
int CSequence::GetFrameCount()
{
return m_frameCount;
}
void CSequence::SetFrameCount(int count)
{
m_frameCount = count;
}
int CSequence::GetFrameSpeedFromHeader()
{
return m_iFrameSpeedFromHeader;
}
void CSequence::SetFrameSpeedFromHeader(int speed)
{
m_iFrameSpeedFromHeader = speed;
}
int CSequence::GetFrameSpeed()
{
return m_frameSpeed;
}
void CSequence::SetFrameSpeed(int speed)
{
m_frameSpeed = speed;
}
int CSequence::GetLoopFrame()
{
return m_loopFrame;
}
void CSequence::SetLoopFrame(int loop)
{
m_loopFrame = loop;
}
bool CSequence::GetGenLoopFrame(void)
{
return m_bGenLoopFrame;
}
void CSequence::SetGenLoopFrame(bool bGenLoopFrame)
{
m_bGenLoopFrame = bGenLoopFrame;
}
int CSequence::GetFill()
{
return m_fill;
}
void CSequence::SetFill(int value)
{
m_fill = value;
}
// this is now recursive, so watch what you're doing...
//
void CSequence::_Init(bool bGenLoopFrame, bool bIsGLA, LPCTSTR path, int startFrame, int targetFrame, int frameCount, int frameSpeed, int frameSpeedFromHeader, CComment* comments)
{
static bool bHere = false;
m_path = NULL;
m_next = NULL;
m_name = NULL;
m_fill = -1;
// another Jake thing, not sure if this'll stay in when valid StarWars enums are available
#if 0
m_enum = "";//NULL;
#else
m_enum = path;
if (!m_enum.IsEmpty())
{
Filename_BaseOnly(m_enum);
m_enum.MakeUpper();
}
#endif
m_sound = NULL;
m_action = NULL;
m_comments = comments;
m_validEnum = false;
m_loopFrame = -1;
m_bIsGLA = bIsGLA;
m_bGenLoopFrame = bGenLoopFrame;
SetPath(path);
SetStartFrame(startFrame);
SetTargetFrame(targetFrame);
SetFrameCount(frameCount);
SetFrameSpeed(frameSpeed);
SetFrameSpeedFromHeader(frameSpeedFromHeader);
if (bHere)
{
for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++)
{
AdditionalSeqs[i] = NULL;
}
}
else
{
bHere = true;
for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++)
{
AdditionalSeqs[i] = new CSequence();
AdditionalSeqs[i]->_Init(false, false,NULL, 0, 0, 0, iDEFAULTSEQFRAMESPEED, iDEFAULTSEQFRAMESPEED, NULL);
}
bHere = false;
}
}
void CSequence::SetName(LPCTSTR name)
{
if (m_name != NULL)
{
free(m_name);
}
if ((name == NULL) || (strlen(name) < 1))
{
m_name = NULL;
}
else
{
m_name = (char*)malloc(strlen(name) + 1);
strcpy(m_name, name);
}
}
ENUMTYPE GetEnumTypeFromString(LPCSTR lpString)
{
if (lpString)
{
if (!strnicmp(lpString,"BOTH_",5))
{
return ET_BOTH;
}
if (!strnicmp(lpString,"TORSO_",6))
{
return ET_TORSO;
}
if (!strnicmp(lpString,"LEGS_",5))
{
return ET_LEGS;
}
if (!strnicmp(lpString,"FACE_",5))
{
return ET_FACE;
}
}
return ET_INVALID;
}
// some enums are actually only seperators, the way to check is if the char straight after the 1st '_' is valid...
//
bool IsEnumSeperator(LPCSTR lpString)
{
while (*lpString && *lpString!='_') lpString++;
if (*lpString++)
{
if (*lpString)
{
if (!(isalpha(*lpString) || isdigit(*lpString)))
return true;
}
}
return false;
}
// converts (eg) "BOTH_ THE DEATH ANIMS" to "THE DEATH ANIMS"...
//
LPCSTR StripSeperatorStart(LPCSTR lpString)
{
if (!IsEnumSeperator(lpString))
return lpString;
while (*lpString && *lpString != '_') lpString++;
if (*lpString)
{
lpString++;
while (*lpString && isspace(*lpString)) lpString++;
}
return lpString;
}
// this is so that part of it can be called for a dialog box string that's not actually in the m_enum var...
//
ENUMTYPE CSequence::GetEnumTypeFromString(LPCSTR lpString)
{
if (!lpString)
{
return ET_INVALID;
}
if (!strlen(lpString))
{
return ET_INVALID; // special bit so blank strings don't assert in this one enumtype-return function
}
ENUMTYPE et = ::GetEnumTypeFromString(lpString);
// it has to be valid here, so check we haven't forgotten some code...
//
ASSERT(et!=ET_INVALID);
return et;
}
ENUMTYPE CSequence::GetEnumType()
{
// this check done first to cope with sequences named (eg) "TORSO_" but not having an entry in anims.h
// to match this (which a strcmp won't detect). This shouldn't really be necessary since the menu system only
// allows you to pick valid ones from anims.h, but it copes with people editing ascii files by hand (or alerts
// people to entries being subsequently deleted from anims.h after use)
//
if (ValidEnum())
{
return GetEnumTypeFromString(GetEnum());
}
return ET_INVALID;
}
int CSequence::GetDisplayIconForTree(CModel *pModel)
{
if (pModel->IsGhoul2())
{
if ( IsGLA() )
{
return ObjID_ENUMG2GLA;
}
else
{
if (GetEnumType() == ET_INVALID)
{
return ObjID_ENUMINVALID;
}
else
{
return ObjID_ENUMG2;
}
}
}
switch (GetEnumType())
{
case ET_INVALID: return ObjID_ENUMINVALID;
case ET_BOTH: return ObjID_ENUMBOTH;
case ET_TORSO: return ObjID_ENUMTORSO;
case ET_LEGS: return ObjID_ENUMLEGS;
}
ASSERT(0);
return ObjID_ENUMINVALID;
}
// not the fastest of routines, but I only call it occasionally...
//
LPCSTR CSequence::GetDisplayNameForTree(CModel* pModel, bool bIncludeAnimEnum, bool bIncludeFrameDetails, bool bViewFrameDetails_Additional, CDC* pDC)
{
if (pModel->IsGhoul2())
{
// bIncludeAnimEnum = false; // :-)
}
#define ACCOUNTFORWIDTH(width) \
iWidthSoFar+=width; \
while (1) \
{ \
size = pDC->GetOutputTextExtent(string); \
if (size.cx>=iWidthSoFar) \
break; \
string+=" "; \
}
static CString string;
int iWidthSoFar=0;
CSize size;
string.Empty();
if (bIncludeFrameDetails)
{
CString temp;
temp.Format("( Frames: Target %4d, Count %4d%sLoop %4d, Speed %4d )",GetTargetFrame(),GetFrameCount(),GetGenLoopFrame()?"+1, ":", ",GetLoopFrame(),GetFrameSpeed());
string += temp;
ACCOUNTFORWIDTH(400);
}
string += GetName();
ACCOUNTFORWIDTH(250);
if (bIncludeAnimEnum && strlen(GetEnum())) //ValidEnum())
{
CString _enum;
if (ValidEnum())
{
_enum.Format("( %s",GetEnum());
}
else
{
_enum.Format("( (BAD: %s)",GetEnum());
}
string += _enum;
for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++)
{
if (AdditionalSeqs[i]->AdditionalSequenceIsValid())
{
string += ", "; // spaces seem pretty small in default font
string += AdditionalSeqs[i]->GetEnum();
if (bViewFrameDetails_Additional)
{
CString temp;
temp.Format("(T:%d C:%d L:%d S:%d)",
AdditionalSeqs[i]->GetTargetFrame(),
AdditionalSeqs[i]->GetFrameCount(),
AdditionalSeqs[i]->GetLoopFrame(),
AdditionalSeqs[i]->GetFrameSpeed()
);
string += temp;
}
}
else
{
// either empty string, or a bad enum... (because of anims.h being edited)
//
if (strlen(AdditionalSeqs[i]->GetEnum()))
{
string += ", ";
string += va("(BAD: %s)",AdditionalSeqs[i]->GetEnum());
}
}
}
string += " )";
ACCOUNTFORWIDTH(200); // this is flawed now because of additional-seqs, so keep this string as the last one
}
return string;
}
LPCTSTR CSequence::GetName()
{
return m_name;
}
void CSequence::DeriveName()
{
if (m_path == NULL)
{
if (m_name != NULL)
{
free(m_name);
m_name = NULL;
}
return;
}
CString name = m_path;
int loc = name.ReverseFind('.');
if (loc > -1)
{
name = name.Left(loc);
}
loc = name.ReverseFind('/');
if (loc > -1)
{
name = name.Right(name.GetLength() - loc - 1);
}
name.MakeUpper();
SetName(name);
}
void CSequence::SetSound(LPCTSTR name)
{
if (m_sound != NULL)
{
free(m_sound);
}
if ((name == NULL) || (strlen(name) < 1))
{
m_sound = NULL;
}
else
{
m_sound = (char*)malloc(strlen(name) + 1);
strcpy(m_sound, name);
}
}
LPCTSTR CSequence::GetSound()
{
return m_sound;
}
void CSequence::SetAction(LPCTSTR name)
{
if (m_action != NULL)
{
free(m_action);
}
if ((name == NULL) || (strlen(name) < 1))
{
m_action = NULL;
}
else
{
m_action = (char*)malloc(strlen(name) + 1);
strcpy(m_action, name);
}
}
bool CSequence::IsGLA()
{
return m_bIsGLA;
}
LPCTSTR CSequence::GetAction()
{
return m_action;
}
void CSequence::SetEnum(LPCTSTR name)
{
/*
if (m_enum != NULL)
{
free(m_enum);
}
if ((name == NULL) || (strlen(name) < 1))
{
m_enum = NULL;
}
else
{
m_enum = (char*)malloc(strlen(name) + 1);
strcpy(m_enum, name);
}
*/
m_enum = name;
SetValidEnum(((CAssimilateApp*)AfxGetApp())->ValidEnum(m_enum));
}
LPCTSTR CSequence::GetEnum()
{
return m_enum;
}
void CSequence::AddComment(CComment* comment)
{
if (m_comments == NULL)
{
m_comments = comment;
}
else
{
CComment* curComment = m_comments;
while (curComment->GetNext() != NULL)
{
curComment = curComment->GetNext();
}
curComment->SetNext(comment);
}
}
// this should only be called on sequence that you know are Additional ones...
//
bool CSequence::AdditionalSequenceIsValid()
{
return (GetEnumType()!=ET_INVALID);
}
// should only really be called on master sequences, though harmless otherwise...
//
int CSequence::GetValidAdditionalSequences()
{
int iCount = 0;
for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++)
{
if (AdditionalSeqs[i])
{
if (AdditionalSeqs[i]->AdditionalSequenceIsValid())
{
iCount++;
}
}
}
return iCount;
}
CComment* CSequence::GetFirstComment()
{
return m_comments;
}
void CSequence::Write(CTxtFile* file, bool bPreQuat)
{
CComment* curComment = m_comments;
while(curComment != NULL)
{
curComment->Write(file);
curComment = curComment->GetNext();
}
file->Write("$", CAssimilateDoc::GetKeyword(IsGLA()?TK_AS_GRAB_GLA:TK_AS_GRAB, TABLE_QDT), " ");
CString path = m_path;
int loc = path.Find("/base");
if (loc > -1)
{
path = path.Right(path.GetLength() - loc - 5);
loc = path.Find("/");
path = path.Right(path.GetLength() - loc - 1);
}
if (!path.GetLength()) // check that some dopey artist hasn't use the name "base" on the right hand side
{
path = m_path;
}
Filename_AccountForLOD(path, giLODLevelOverride);
file->Write(path);
/*
if (m_frameCount > -1)
{
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_FRAMES, TABLE_GRAB), " ");
file->Write(m_startFrame);
file->Space();
file->Write(m_targetFrame);
file->Space();
file->Write(m_frameCount);
}
*/
// if (strstr(path,"death16"))
// {
// int z=1;
// }
if (!IsGLA())
{
if (m_fill > -1)
{
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_FILL, TABLE_GRAB), " ");
// file->Space();
file->Write(m_fill);
}
if (m_loopFrame != 0)
{
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_LOOP, TABLE_GRAB), " ");
// file->Space();
file->Write(m_loopFrame);
}
// if (m_enum && (strcmp(m_name, m_enum) != 0))
if (m_enum.GetLength() && (strcmp(m_name, m_enum) != 0))
{
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_ENUM, TABLE_GRAB), " ");
// file->Space();
file->Write(m_enum);
}
if (m_sound != NULL)
{
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_SOUND, TABLE_GRAB), " ");
// file->Space();
file->Write(m_sound);
}
if (m_action != NULL)
{
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_ACTION, TABLE_GRAB), " ");
// file->Space();
file->Write(m_action);
}
if (m_bGenLoopFrame)
{
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_GENLOOPFRAME, TABLE_GRAB), " ");
}
if (m_frameSpeed != m_iFrameSpeedFromHeader ||
GetValidAdditionalSequences() ||
bPreQuat
)
{
// write out start marker (and stop-marker at bottom) so qdata can skip this more easily...
//
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_QDSKIPSTART, TABLE_GRAB));
if (m_frameSpeed != m_iFrameSpeedFromHeader)
{
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_FRAMESPEED, TABLE_GRAB), " ");
file->Write(m_frameSpeed);
}
for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++)
{
CSequence* additionalSeq = AdditionalSeqs[i];
if (additionalSeq->AdditionalSequenceIsValid())
{
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_ADDITIONAL, TABLE_GRAB), " ");
file->Write(additionalSeq->GetStartFrame());
file->Space();
file->Write(additionalSeq->GetFrameCount());
file->Space();
file->Write(additionalSeq->GetLoopFrame());
file->Space();
file->Write(additionalSeq->GetFrameSpeed());
file->Space();
file->Write(additionalSeq->GetEnum());
}
}
// this is an unpleasant abuse, but needed to retro-hack into old versions of carcass...
//
if (bPreQuat)
{
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_PREQUAT, TABLE_GRAB));
}
// any other stuff in future (sound events etc)...
//
// ...
// write end marker (so QData knows to start reading again)...
//
file->Space();
file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_QDSKIPSTOP, TABLE_GRAB));
}
}
file->Writeln();
}
// this writes the CFG file... (it's also now recursive, albeit with changing 'this' ptrs, so be aware of that)
//
void CSequence::WriteExternal(CModel *pModel, CTxtFile* file, bool bMultiPlayerFormat)
{
// this now keeps the spacing nicer for cutting and pasting into source...
//
CString sOutputEnum = m_enum;
if (sOutputEnum.IsEmpty())
{
sOutputEnum = "???";
}
if (bMultiPlayerFormat)
{
// Format: targetFrame, frameCount, loopFrame, frameSpeed
//0 47 0 10 //BOTH_DEATH1
file->Write(m_targetFrame);
file->Write("\t");
file->Write(m_frameCount);
file->Write("\t");
if (m_loopFrame == -1)
file->Write(0);
else
file->Write(m_frameCount-m_loopFrame);
file->Write("\t");
file->Write(m_frameSpeed);
file->Write("\t");
if (!m_validEnum)
{
file->Write("// fix me - invalid enum -");
}
else
{
file->Write("//");
file->Write(sOutputEnum);
file->Writeln();
}
}
else
{
while(sOutputEnum.GetLength()<20) sOutputEnum+=" ";
file->Write(sOutputEnum, "\t");
// file->Write(m_startFrame);
// file->Write("\t");
// special code, if this is a LEGS type enum then we need to adjust the target frame to 'lose' the chunk
// of frames occupied by the TORSO types...
//
int iTargetFrame = m_targetFrame;
file->Write(iTargetFrame);
file->Write("\t");
file->Write(m_frameCount);
file->Write("\t");
file->Write(m_loopFrame);
file->Write("\t");
file->Write(m_frameSpeed);
if (!m_validEnum && !pModel->IsGhoul2())
{
file->Write("\t// fix me - invalid enum -");
}
if (m_sound != NULL)
{
file->Write("\t// sound - ");
}
if (m_action != NULL)
{
file->Write ("\t// action - ");
}
if (m_fill > -1)
{
file->Write("\t// fill = ");
file->Write(m_fill);
}
file->Writeln();
}
// now for a bit of recursion, write out any additional sequences that this sequence owns...
//
for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++)
{
CSequence *seq = AdditionalSeqs[i];
if (seq)
{
if (seq->AdditionalSequenceIsValid())
{
seq->WriteExternal(pModel, file, bMultiPlayerFormat);
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CSequencePropPage property page
IMPLEMENT_DYNCREATE(CSequencePropPage, CPropertyPage)
CSequencePropPage::CSequencePropPage() : CPropertyPage(CSequencePropPage::IDD)
{
//{{AFX_DATA_INIT(CSequencePropPage)
m_frameCount = 0;
m_frameSpeed = 0;
m_path = _T("");
m_startFrame = 0;
m_iLoopFrame = 0;
m_AnimationEnum = _T("");
m_AnimationEnum2 = _T("");
m_AnimationEnum3 = _T("");
m_AnimationEnum4 = _T("");
m_AnimationEnum5 = _T("");
m_frameCount2 = 0;
m_frameCount3 = 0;
m_frameCount4 = 0;
m_frameCount5 = 0;
m_frameSpeed2 = 0;
m_frameSpeed3 = 0;
m_frameSpeed4 = 0;
m_frameSpeed5 = 0;
m_iLoopFrame2 = 0;
m_iLoopFrame3 = 0;
m_iLoopFrame4 = 0;
m_iLoopFrame5 = 0;
m_startFrame2 = 0;
m_startFrame3 = 0;
m_startFrame4 = 0;
m_startFrame5 = 0;
m_bGenLoopFrame = FALSE;
//}}AFX_DATA_INIT
}
CSequencePropPage::~CSequencePropPage()
{
}
void CSequencePropPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSequencePropPage)
DDX_Text(pDX, IDC_FRAMECOUNT, m_frameCount);
DDX_Text(pDX, IDC_FRAMESPEED, m_frameSpeed);
DDX_Text(pDX, IDC_PATH, m_path);
DDX_Text(pDX, IDC_STARTFRAME, m_startFrame);
DDX_Text(pDX, IDC_LOOPFRAME, m_iLoopFrame);
DDX_Text(pDX, IDC_EDIT_ANIMATIONENUM, m_AnimationEnum);
DDX_Text(pDX, IDC_EDIT_ANIMATIONENUM2, m_AnimationEnum2);
DDX_Text(pDX, IDC_EDIT_ANIMATIONENUM3, m_AnimationEnum3);
DDX_Text(pDX, IDC_EDIT_ANIMATIONENUM4, m_AnimationEnum4);
DDX_Text(pDX, IDC_EDIT_ANIMATIONENUM5, m_AnimationEnum5);
DDX_Text(pDX, IDC_FRAMECOUNT2, m_frameCount2);
DDX_Text(pDX, IDC_FRAMECOUNT3, m_frameCount3);
DDX_Text(pDX, IDC_FRAMECOUNT4, m_frameCount4);
DDX_Text(pDX, IDC_FRAMECOUNT5, m_frameCount5);
DDX_Text(pDX, IDC_FRAMESPEED2, m_frameSpeed2);
DDX_Text(pDX, IDC_FRAMESPEED3, m_frameSpeed3);
DDX_Text(pDX, IDC_FRAMESPEED4, m_frameSpeed4);
DDX_Text(pDX, IDC_FRAMESPEED5, m_frameSpeed5);
DDX_Text(pDX, IDC_LOOPFRAME2, m_iLoopFrame2);
DDX_Text(pDX, IDC_LOOPFRAME3, m_iLoopFrame3);
DDX_Text(pDX, IDC_LOOPFRAME4, m_iLoopFrame4);
DDX_Text(pDX, IDC_LOOPFRAME5, m_iLoopFrame5);
DDX_Text(pDX, IDC_STARTFRAME2, m_startFrame2);
DDX_Text(pDX, IDC_STARTFRAME3, m_startFrame3);
DDX_Text(pDX, IDC_STARTFRAME4, m_startFrame4);
DDX_Text(pDX, IDC_STARTFRAME5, m_startFrame5);
DDX_Check(pDX, IDC_CHECK_GENLOOPFRAME, m_bGenLoopFrame);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSequencePropPage, CPropertyPage)
//{{AFX_MSG_MAP(CSequencePropPage)
ON_BN_CLICKED(IDC_BUTTON_CHOOSEANIMATIONENUM, OnButtonChooseanimationenum)
ON_BN_CLICKED(IDC_BUTTON_CHOOSEANIMATIONENUM2, OnButtonChooseanimationenum2)
ON_BN_CLICKED(IDC_BUTTON_CHOOSEANIMATIONENUM3, OnButtonChooseanimationenum3)
ON_BN_CLICKED(IDC_BUTTON_CHOOSEANIMATIONENUM4, OnButtonChooseanimationenum4)
ON_BN_CLICKED(IDC_BUTTON_CHOOSEANIMATIONENUM5, OnButtonChooseanimationenum5)
ON_BN_CLICKED(IDC_BUTTON_CLEARANIMATIONENUM, OnButtonClearanimationenum)
ON_BN_CLICKED(IDC_BUTTON_CLEARANIMATIONENUM2, OnButtonClearanimationenum2)
ON_BN_CLICKED(IDC_BUTTON_CLEARANIMATIONENUM3, OnButtonClearanimationenum3)
ON_BN_CLICKED(IDC_BUTTON_CLEARANIMATIONENUM4, OnButtonClearanimationenum4)
ON_BN_CLICKED(IDC_BUTTON_CLEARANIMATIONENUM5, OnButtonClearanimationenum5)
ON_EN_KILLFOCUS(IDC_STARTFRAME, OnKillfocusStartframe)
ON_EN_KILLFOCUS(IDC_STARTFRAME2, OnKillfocusStartframe2)
ON_EN_KILLFOCUS(IDC_STARTFRAME3, OnKillfocusStartframe3)
ON_EN_KILLFOCUS(IDC_STARTFRAME4, OnKillfocusStartframe4)
ON_EN_KILLFOCUS(IDC_STARTFRAME5, OnKillfocusStartframe5)
ON_EN_KILLFOCUS(IDC_LOOPFRAME, OnKillfocusLoopframe)
ON_EN_KILLFOCUS(IDC_LOOPFRAME2, OnKillfocusLoopframe2)
ON_EN_KILLFOCUS(IDC_LOOPFRAME3, OnKillfocusLoopframe3)
ON_EN_KILLFOCUS(IDC_LOOPFRAME4, OnKillfocusLoopframe4)
ON_EN_KILLFOCUS(IDC_LOOPFRAME5, OnKillfocusLoopframe5)
ON_EN_KILLFOCUS(IDC_FRAMESPEED5, OnKillfocusFramespeed5)
ON_EN_KILLFOCUS(IDC_FRAMESPEED4, OnKillfocusFramespeed4)
ON_EN_KILLFOCUS(IDC_FRAMESPEED3, OnKillfocusFramespeed3)
ON_EN_KILLFOCUS(IDC_FRAMESPEED2, OnKillfocusFramespeed2)
ON_EN_KILLFOCUS(IDC_FRAMESPEED, OnKillfocusFramespeed)
ON_EN_KILLFOCUS(IDC_FRAMECOUNT5, OnKillfocusFramecount5)
ON_EN_KILLFOCUS(IDC_FRAMECOUNT4, OnKillfocusFramecount4)
ON_EN_KILLFOCUS(IDC_FRAMECOUNT3, OnKillfocusFramecount3)
ON_EN_KILLFOCUS(IDC_FRAMECOUNT2, OnKillfocusFramecount2)
ON_EN_KILLFOCUS(IDC_FRAMECOUNT, OnKillfocusFramecount)
ON_EN_KILLFOCUS(IDC_EDIT_ANIMATIONENUM5, OnKillfocusEditAnimationenum5)
ON_EN_KILLFOCUS(IDC_EDIT_ANIMATIONENUM4, OnKillfocusEditAnimationenum4)
ON_EN_KILLFOCUS(IDC_EDIT_ANIMATIONENUM3, OnKillfocusEditAnimationenum3)
ON_EN_KILLFOCUS(IDC_EDIT_ANIMATIONENUM2, OnKillfocusEditAnimationenum2)
ON_EN_KILLFOCUS(IDC_EDIT_ANIMATIONENUM, OnKillfocusEditAnimationenum)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSequencePropPage message handlers
void CSequencePropPage::OnButtonChooseanimationenum()
{
char sReturnString[200]; // OTT
if (UpdateData(DIALOG_TO_DATA))
{
CAnimPicker animDialog(&sReturnString[0]);
if (animDialog.DoModal()==IDOK)
{
SetModified(true); // enable the apply button
m_AnimationEnum = sReturnString;
UpdateData(DATA_TO_DIALOG);
HandleAllItemsGraying();
}
}
}
// deliberately does not do enum...
//
#define DEFAULT_FROM_MASTER(number) \
if (m_AnimationEnum ## number.IsEmpty()) \
{ \
m_frameCount ## number = m_frameCount; \
m_frameSpeed ## number = m_frameSpeed; \
m_iLoopFrame ## number = m_iLoopFrame; \
m_startFrame ## number = m_startFrame; \
}
void CSequencePropPage::OnButtonChooseanimationenum2()
{
char sReturnString[200]; // OTT
if (UpdateData(DIALOG_TO_DATA))
{
CAnimPicker animDialog(&sReturnString[0]);
if (animDialog.DoModal()==IDOK)
{
SetModified(true); // enable the apply button
DEFAULT_FROM_MASTER(2);
m_AnimationEnum2 = sReturnString;
UpdateData(DATA_TO_DIALOG);
HandleAllItemsGraying();
}
}
}
void CSequencePropPage::OnButtonChooseanimationenum3()
{
char sReturnString[200]; // OTT
if (UpdateData(DIALOG_TO_DATA))
{
CAnimPicker animDialog(&sReturnString[0]);
if (animDialog.DoModal()==IDOK)
{
SetModified(true); // enable the apply button
DEFAULT_FROM_MASTER(3);
m_AnimationEnum3 = sReturnString;
UpdateData(DATA_TO_DIALOG);
HandleAllItemsGraying();
}
}
}
void CSequencePropPage::OnButtonChooseanimationenum4()
{
char sReturnString[200]; // OTT
if (UpdateData(DIALOG_TO_DATA))
{
CAnimPicker animDialog(&sReturnString[0]);
if (animDialog.DoModal()==IDOK)
{
SetModified(true); // enable the apply button
DEFAULT_FROM_MASTER(4);
m_AnimationEnum4 = sReturnString;
UpdateData(DATA_TO_DIALOG);
HandleAllItemsGraying();
}
}
}
void CSequencePropPage::OnButtonChooseanimationenum5()
{
char sReturnString[200]; // OTT
if (UpdateData(DIALOG_TO_DATA))
{
CAnimPicker animDialog(&sReturnString[0]);
if (animDialog.DoModal()==IDOK)
{
SetModified(true); // enable the apply button
DEFAULT_FROM_MASTER(5);
m_AnimationEnum5 = sReturnString;
UpdateData(DATA_TO_DIALOG);
HandleAllItemsGraying();
}
}
}
void CSequencePropPage::OnButtonClearanimationenum()
{
if (UpdateData(DIALOG_TO_DATA))
{
SetModified(true); // enable the apply button
m_AnimationEnum = "";
UpdateData(DATA_TO_DIALOG);
HandleAllItemsGraying();
}
}
void CSequencePropPage::OnButtonClearanimationenum2()
{
if (UpdateData(DIALOG_TO_DATA))
{
SetModified(true); // enable the apply button
m_AnimationEnum2 = "";
UpdateData(DATA_TO_DIALOG);
HandleAllItemsGraying();
}
}
void CSequencePropPage::OnButtonClearanimationenum3()
{
if (UpdateData(DIALOG_TO_DATA))
{
SetModified(true); // enable the apply button
m_AnimationEnum3 = "";
UpdateData(DATA_TO_DIALOG);
HandleAllItemsGraying();
}
}
void CSequencePropPage::OnButtonClearanimationenum4()
{
if (UpdateData(DIALOG_TO_DATA))
{
SetModified(true); // enable the apply button
m_AnimationEnum4 = "";
UpdateData(DATA_TO_DIALOG);
HandleAllItemsGraying();
}
}
void CSequencePropPage::OnButtonClearanimationenum5()
{
if (UpdateData(DIALOG_TO_DATA))
{
SetModified(true); // enable the apply button
m_AnimationEnum5 = "";
UpdateData(DATA_TO_DIALOG);
HandleAllItemsGraying();
}
}
void CSequencePropPage::OnCancel()
{
UpdateData(DATA_TO_DIALOG); // stops a nasty bug in MFC whereby having crap data (eg 'a' in an int-box) gets you stuck in a loop if you ESC from a prop page
CPropertyPage::OnCancel();
}
void CSequencePropPage::OnKillfocusStartframe()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusStartframe2()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusStartframe3()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusStartframe4()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusStartframe5()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusLoopframe()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusLoopframe2()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusLoopframe3()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusLoopframe4()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusLoopframe5()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusFramespeed5()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusFramespeed4()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusFramespeed3()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusFramespeed2()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusFramespeed()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusFramecount5()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusFramecount4()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusFramecount3()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusFramecount2()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusFramecount()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusEditAnimationenum5()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusEditAnimationenum4()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusEditAnimationenum3()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusEditAnimationenum2()
{
ONKILLFOCUS;
}
void CSequencePropPage::OnKillfocusEditAnimationenum()
{
ONKILLFOCUS;
}
// this is called by the OK and/or Apply buttons...
//
void CSequencePropPage::OkOrApply()
{
m_sequence->SetFrameCount(m_frameCount);
m_sequence->SetFrameSpeed(m_frameSpeed);
m_sequence->SetStartFrame(m_startFrame);
m_sequence->SetLoopFrame(m_iLoopFrame);
m_sequence->SetEnum(m_AnimationEnum);
m_sequence->SetGenLoopFrame(!!m_bGenLoopFrame);
#define OK_ADDITIONAL(number) \
m_sequence->AdditionalSeqs[number-2]->SetFrameCount (m_frameCount ## number); \
m_sequence->AdditionalSeqs[number-2]->SetFrameSpeed (m_frameSpeed ## number); \
m_sequence->AdditionalSeqs[number-2]->SetStartFrame (m_startFrame ## number); \
m_sequence->AdditionalSeqs[number-2]->SetLoopFrame (m_iLoopFrame ## number); \
m_sequence->AdditionalSeqs[number-2]->SetEnum (m_AnimationEnum ## number);
OK_ADDITIONAL(2);
OK_ADDITIONAL(3);
OK_ADDITIONAL(4);
OK_ADDITIONAL(5);
// ensure I don't forget any future expansions by putting the next index in the sequence in an err-check...
//
#if !(6 == (MAX_ADDITIONAL_SEQUENCES+2))
#error Need more OK_ code...
#endif
m_sequence->SetPath(m_path);
*m_soilFlag = true;
}
void CSequencePropPage::OnOK()
{
OkOrApply();
// damn stupid C++...
//
if (ghAssimilateView)
{
CAssimilateDoc* pDoc = ghAssimilateView->GetDocument();
if (pDoc)
{
pDoc->UpdateAllViews(NULL, AS_FILESUPDATED, NULL);
}
}
CPropertyPage::OnOK();
}
BOOL CSequencePropPage::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: Add extra initialization here
m_frameCount = m_sequence->GetFrameCount();
m_frameSpeed = m_sequence->GetFrameSpeed();
m_startFrame = m_sequence->GetStartFrame();
m_iLoopFrame = m_sequence->GetLoopFrame();
m_AnimationEnum = m_sequence->GetEnum();
m_bGenLoopFrame = m_sequence->GetGenLoopFrame();
#define INIT_ADDITIONAL(number) \
m_frameCount ## number = m_sequence->AdditionalSeqs[number-2]->GetFrameCount(); \
m_frameSpeed ## number = m_sequence->AdditionalSeqs[number-2]->GetFrameSpeed(); \
m_startFrame ## number = m_sequence->AdditionalSeqs[number-2]->GetStartFrame(); \
m_iLoopFrame ## number = m_sequence->AdditionalSeqs[number-2]->GetLoopFrame(); \
m_AnimationEnum ## number = m_sequence->AdditionalSeqs[number-2]->GetEnum();
INIT_ADDITIONAL(2);
INIT_ADDITIONAL(3);
INIT_ADDITIONAL(4);
INIT_ADDITIONAL(5);
// ensure I don't forget any future expansions by putting the next index in the sequence in an err-check...
//
#if !(6 == (MAX_ADDITIONAL_SEQUENCES+2))
#error Need more INIT_ code...
#endif
m_path = m_sequence->GetPath();
UpdateData(DATA_TO_DIALOG);
HandleAllItemsGraying();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
BOOL CSequencePropPage::OnApply()
{
OkOrApply();
return CPropertyPage::OnApply();
}
void CSequencePropPage::HandleAdditionalEditBoxesGraying()
{
bool bOnOff;
// note check runs off the dialog box strings, NOT the standard m_sequence member (because the data isn't set till OK)
//
#define GRAY_ADDITIONAL(number) \
bOnOff = !(m_sequence->GetEnumTypeFromString(m_AnimationEnum ## number) == ET_INVALID);\
GetDlgItem(IDC_STARTFRAME ## number)->EnableWindow(bOnOff); \
GetDlgItem(IDC_FRAMECOUNT ## number)->EnableWindow(bOnOff); \
GetDlgItem(IDC_LOOPFRAME ## number)->EnableWindow(bOnOff); \
GetDlgItem(IDC_FRAMESPEED ## number)->EnableWindow(bOnOff);
GRAY_ADDITIONAL(2);
GRAY_ADDITIONAL(3);
GRAY_ADDITIONAL(4);
GRAY_ADDITIONAL(5);
// ensure I don't forget any future expansions by putting the next index in the sequence in an err-check...
//
#if !(6 == (MAX_ADDITIONAL_SEQUENCES+2))
#error Need more gray-handler code...
#endif
}
void CSequencePropPage::HandleAllItemsGraying()
{
if (UpdateData(DIALOG_TO_DATA))
{
HandleAdditionalEditBoxesGraying();
}
}