// 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); } } } }
bool CModel::WriteExternal(bool bPromptForNames, bool& bCFGWritten) { bCFGWritten = false; CString filename; if (bPromptForNames) { CString strInitialPrompt(ghAssimilateView->GetDocument()->GetPathName()); Filename_RemoveFilename(strInitialPrompt); strInitialPrompt.Replace("/","\\"); strInitialPrompt += "\\"; strInitialPrompt += sANIMATION_CFG_NAME; CFileDialog dialog(FALSE, ".cfg", strInitialPrompt, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Config Data Files (*.cfg)|*.cfg|All Files (*.*)|*.*||", NULL); if (dialog.DoModal() != IDOK) { return false; } filename = dialog.GetPathName(); // eg. {"Q:\quake\baseq3\models\players\ste_assimilate_test\ste_assimilate_test.cfg"} } else { filename = ((CAssimilateApp*)AfxGetApp())->GetQuakeDir(); filename+= GetPath(); filename.MakeLower(); filename.Replace('\\', '/'); int loc = filename.Find(m_name);//"/root"); if (loc>=0) { filename = filename.Left(loc+strlen(m_name)); } // dup the dirname to use as the model name... (eg "/.../.../klingon" becomes "/.../.../klingon/klingon" filename += "/"; filename += sANIMATION_CFG_NAME; } CTxtFile* file = CTxtFile::Create(filename); if (file == NULL || !file->IsValid()) { ErrorBox(va("Error creating file \"%s\"!",filename)); return false; } // new bit, check for the existance of an animation.pre file, which means export this in Q3 format (rather than trek) CString strQ3FormatCheckName(filename); Filename_RemoveFilename(strQ3FormatCheckName); strQ3FormatCheckName += "\\"; strQ3FormatCheckName += sANIMATION_PRE_NAME; strQ3FormatCheckName.Replace("/","\\"); bool bExportFormatIsQuake3Multiplayer = //FileExists(strQ3FormatCheckName); ((CAssimilateApp*)AfxGetApp())->GetMultiPlayerMode(); CString strPrePend; if (bExportFormatIsQuake3Multiplayer) { // multi-player format, check for optional animation.pre file... FILE *fhPRE = fopen(strQ3FormatCheckName, "rt"); if (fhPRE) { // read all the lines in this file and just write them straight to the output file... char sLine[16384]; char *psLine; CString strTrimmed; while ((psLine = fgets( sLine, sizeof(sLine), fhPRE ))!=NULL) { strTrimmed = psLine; strTrimmed.Replace("\n",""); strTrimmed.TrimRight(); strTrimmed.TrimLeft(); file->Writeln(strTrimmed); } if (ferror(fhPRE)) { ErrorBox(va("Error during reading of file \"%s\"!\n\n( this shouldn't happen )",(LPCSTR)strQ3FormatCheckName)); } fclose(fhPRE); } file->Writeln(""); file->Writeln("//"); file->Writeln("// Format: targetFrame, frameCount, loopFrame, frameSpeed"); file->Writeln("//"); } else { // single-player format... CString commentLine; CTime time = CTime::GetCurrentTime(); commentLine.Format("// %s %d frames; %d sequences; updated %s", filename, m_totFrames, GetTotSequences(), time.Format("%H:%M %A, %B %d, %Y")); file->Writeln(commentLine); // the Writeln functions I have to call don't handle "\n" chars properly because of being opened in binary mode // (sigh), so I have to explicitly call the Writeln() functions to output CRs... :-( file->Writeln("//"); file->Writeln("// Format: enum, targetFrame, frameCount, loopFrame, frameSpeed"); file->Writeln("//"); } CSequence* curSequence = m_sequences; while(curSequence != NULL) { curSequence->WriteExternal(this, file, bExportFormatIsQuake3Multiplayer); curSequence = curSequence->GetNext(); } file->Delete(); if (HasGLA()) { _unlink(filename); // zap it, since it's meaningless here (only has one seq/enum: the whole GLA) } else { bCFGWritten = true; } return true; }