string Decode(CSequence inSequence) { string result; for (CSequence::iterator i = inSequence.begin(); i != inSequence.end(); ++i) result.push_back(Decode(*i)); return result; }
int CModel::AnimEnumInUse(LPCSTR psAnimEnum) { int iCount = 0; if (strlen(psAnimEnum)) // added for G2 models, which don't necessarily use enums yet { CSequence *curSequence = GetFirstSequence(); while (curSequence) { if (!strcmp(psAnimEnum,curSequence->GetEnum())) { iCount++;// return true; } // new bit, ask the additional sequences as well... // for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++) { if (!strcmp(psAnimEnum,curSequence->AdditionalSeqs[i]->GetEnum())) { iCount++;// return true; } } curSequence = curSequence->GetNext(); } } return iCount;//false; }
void CModel::ReOrderSequences() { typedef vector<CSequence*> sequences_t; sequences_t sequences; // add sequences to list... CSequence *curSequence = m_sequences; while (curSequence) { sequences.push_back(curSequence); curSequence = curSequence->GetNext(); } // re-order sequences... qsort( (void *)&sequences[0], (size_t)(sequences.size()), sizeof(CSequence *), ModelSequenceCompareFunc ); // now rebuild links... int iTotMasterSequences = GetTotMasterSequences(); // this needs to be eval'd here, you can't do it in the for-next below m_sequences = NULL; for (int i=0; i<iTotMasterSequences; i++) { curSequence = sequences[i]; curSequence->SetNext(NULL); AddSequence(curSequence); } Resequence(); }
void CInstrumentEditorN163::OnCloneSequence() { CFamiTrackerDoc *pDoc = GetDocument(); int FreeIndex = pDoc->GetFreeSequenceN163(m_iSelectedSetting); CSequence *pSeq = pDoc->GetSequence(SNDCHIP_N163, FreeIndex, m_iSelectedSetting); pSeq->Copy(m_pSequence); SetDlgItemInt(IDC_SEQ_INDEX, FreeIndex, FALSE); }
int CModel::GetTotMasterSequences() { int tot = 0; CSequence* curSequence = m_sequences; while(curSequence != NULL) { tot++; curSequence = curSequence->GetNext(); } return tot; }
CSequence *CSequence::Create( void ) { CSequence *seq = new CSequence; //TODO: Emit warning assert(seq); if ( seq == NULL ) return NULL; seq->SetFlag( SQ_COMMON ); return seq; }
void CModel::GetMasterEnumBoundaryFrameNumbers(int *piFirstFrameAfterBOTH, int *piFirstFrameAfterTORSO) { ENUMTYPE prevET = ET_INVALID; int iFirstFrameAfterBOTH = 0; int iFirstFrameAfterTORSO= 0; CSequence* curSequence = m_sequences; while(curSequence != NULL) { ENUMTYPE thisET = curSequence->GetEnumType(); // update any frame markers first... if (prevET == ET_BOTH && thisET != ET_BOTH) { iFirstFrameAfterBOTH = curSequence->GetTargetFrame(); iFirstFrameAfterTORSO= curSequence->GetTargetFrame(); // set this as well in case there are no TORSOs at all } if (prevET == ET_TORSO && thisET != ET_TORSO) { iFirstFrameAfterTORSO= curSequence->GetTargetFrame(); } prevET = thisET; curSequence = curSequence->GetNext(); } // bug fix, if there are no leg frames at all, then we need to check if the ...AfterTORSO marker needs moving... if (prevET == ET_BOTH) { iFirstFrameAfterBOTH = GetTotFrames(); iFirstFrameAfterTORSO= GetTotFrames(); } if (prevET == ET_TORSO) { iFirstFrameAfterTORSO = GetTotFrames(); } if (piFirstFrameAfterBOTH) { *piFirstFrameAfterBOTH = iFirstFrameAfterBOTH; } if (piFirstFrameAfterTORSO) { *piFirstFrameAfterTORSO= iFirstFrameAfterTORSO; } }
LPCSTR CModel::GLAName(void) { CSequence* curSequence = GetFirstSequence(); while (curSequence) { if (curSequence->IsGLA()) { return curSequence->GetName(); } curSequence = curSequence->GetNext(); } return NULL; }
bool CModel::HasGLA() { CSequence* curSequence = GetFirstSequence(); while (curSequence) { if (curSequence->IsGLA()) { return true; } curSequence = curSequence->GetNext(); } return false; }
void CModel::AddSequence(CSequence* sequence) { if (m_sequences == NULL) { m_sequences = sequence; } else { CSequence* curSequence = m_sequences; while(curSequence->GetNext() != NULL) { curSequence = curSequence->GetNext(); } curSequence->SetNext(sequence); } }
int main() { CSequence seq; if (seq.ReadSequence("test5.txt")) { seq.CalculationSequence(); cout << seq.GetCount() << endl; } else { cout << "error input file"; } cout << "runtime = " << clock() / 1000.0 << endl; return 0; }
void CModel::Delete() { while(m_comments != NULL) { CComment* curComment = m_comments; m_comments = curComment->GetNext(); curComment->Delete(); } while(m_sequences != NULL) { CSequence* curSequence = m_sequences; m_sequences = curSequence->GetNext(); curSequence->Delete(); } if (m_name != NULL) { free(m_name); m_name = NULL; } if (m_path != NULL) { free(m_path); m_path = NULL; } if (m_psSkelPath != NULL) { free(m_psSkelPath); m_psSkelPath = NULL; } if (m_psMakeSkelPath != NULL) { free(m_psMakeSkelPath); m_psMakeSkelPath = NULL; } if (m_psRefGLAPath != NULL) { free(m_psRefGLAPath); m_psRefGLAPath = NULL; } m_curSequence = NULL; PCJList_Clear(); // not really necessary, but useful reminder delete this; }
void CModel::DeleteSequence(CSequence* deleteSequence) { // linklist is only 1-way, so we need to find the stage previous to this (if any)... CSequence* prevSequence = NULL; CSequence* scanSequence = GetFirstSequence(); while (scanSequence && scanSequence != deleteSequence) { prevSequence = scanSequence; scanSequence = scanSequence->GetNext(); } if (scanSequence == deleteSequence) { // we found it, so was this the first sequence in the list? if (prevSequence) { prevSequence->SetNext(scanSequence->GetNext()); // ...no } else { m_sequences = scanSequence->GetNext(); // ...yes } scanSequence->Delete(); } }
int CModel::GetTotSequences() { int tot = 0; CSequence* curSequence = m_sequences; while(curSequence != NULL) { tot++; for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++) { if (curSequence->AdditionalSeqs[i]->AdditionalSequenceIsValid()) tot++; } curSequence = curSequence->GetNext(); } return tot; }
bool CModel::ContainsFile(LPCSTR psFilename) { if (m_sequences == NULL) { return false; } else { CSequence* curSequence = m_sequences; while(curSequence) { if (_stricmp(curSequence->GetPath(),psFilename)==0) return true; curSequence = curSequence->GetNext(); } } return false; }
void PrintAlignment( const CSequence& inQuery, uint32 inQueryStart, const CSequence& inTarget, uint32 inTargetStart) { assert(inQuery.length() == inTarget.length()); CMutableSequence q(inQuery.begin(), inQuery.end()); CMutableSequence s(inTarget.begin(), inTarget.end()); while (q.length()) { uint32 n = q.length(); if (n > 60) n = 60; cout << setw(6) << inQueryStart << " "; for (uint32 i = 0; i < n; ++i) { if (q[i] == '-') cout << '-'; else { cout << Decode(q[i]); ++inQueryStart; } } cout << endl; cout << " "; for (uint32 i = 0; i < n; ++i) { if (s[i] == q[i]) cout << '|'; else cout << " "; } cout << endl; cout << setw(6) << inTargetStart << " "; for (uint32 i = 0; i < n; ++i) { if (s[i] == '-') cout << '-'; else { cout << Decode(s[i]); ++inTargetStart; } } cout << endl << endl; q.erase(q.begin(), q.begin() + n); s.erase(s.begin(), s.begin() + n); } cout << endl; }
void CInstrumentN163::SaveFile(CFile *pFile, CFamiTrackerDoc *pDoc) { // Sequences unsigned char SeqCount = SEQUENCE_COUNT; pFile->Write(&SeqCount, sizeof(char)); for (int i = 0; i < SEQUENCE_COUNT; ++i) { int Sequence = GetSeqIndex(i); if (GetSeqEnable(i)) { CSequence *pSeq = pDoc->GetSequence(SNDCHIP_N163, Sequence, i); char Enabled = 1; int ItemCount = pSeq->GetItemCount(); int LoopPoint = pSeq->GetLoopPoint(); int ReleasePoint = pSeq->GetReleasePoint(); int Setting = pSeq->GetSetting(); pFile->Write(&Enabled, sizeof(char)); pFile->Write(&ItemCount, sizeof(int)); pFile->Write(&LoopPoint, sizeof(int)); pFile->Write(&ReleasePoint, sizeof(int)); pFile->Write(&Setting, sizeof(int)); for (unsigned int j = 0; j < pSeq->GetItemCount(); j++) { int Value = pSeq->GetItem(j); pFile->Write(&Value, sizeof(char)); } } else { char Enabled = 0; pFile->Write(&Enabled, sizeof(char)); } } // Write wave config int WaveSize = GetWaveSize(); pFile->Write(&WaveSize, sizeof(int)); int WavePos = GetWavePos(); pFile->Write(&WavePos, sizeof(int)); int WaveCount = GetWaveCount(); pFile->Write(&WaveCount, sizeof(int)); for (int i = 0; i < WaveCount; ++i) { for (int j = 0; j < WaveSize; ++j) { char w = GetSample(i, j); pFile->Write(&w, sizeof(char)); } } }
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 MidLine(const CSequence& inQuery, const CSequence& inTarget, const CMatrix& inMatrix, uint32& outIdentity, uint32& outPositives, uint32& outGaps, string& outMidline) { outMidline.clear(); outIdentity = 0; outPositives = 0; outGaps = 0; assert(inQuery.length() == inTarget.length()); if (inQuery.length() != inTarget.length()) THROW(("To calculate a midline you need a query and a target of the same length")); for (CSequence::const_iterator a = inQuery.begin(), b = inTarget.begin(); a != inQuery.end(); ++a, ++b) { if (*a == *b) { ++outIdentity; ++outPositives; outMidline += Decode(*a); } else if (inMatrix(*a, *b) > 0) { ++outPositives; outMidline += '+'; } else { if (*a == kSignalGapCode or *b == kSignalGapCode) ++outGaps; outMidline += ' '; } } }
void CInstrument2A03::SaveFile(CFile *pFile, CFamiTrackerDoc *pDoc) { // Saves an 2A03 instrument // Current version 2.2 // Sequences unsigned char SeqCount = SEQUENCE_COUNT; pFile->Write(&SeqCount, sizeof(char)); for (int i = 0; i < SEQUENCE_COUNT; ++i) { int Sequence = GetSeqIndex(i); if (GetSeqEnable(i)) { CSequence *pSeq = pDoc->GetSequence(Sequence, i); char Enabled = 1; int ItemCount = pSeq->GetItemCount(); int LoopPoint = pSeq->GetLoopPoint(); int ReleasePoint = pSeq->GetReleasePoint(); int Setting = pSeq->GetSetting(); pFile->Write(&Enabled, sizeof(char)); pFile->Write(&ItemCount, sizeof(int)); pFile->Write(&LoopPoint, sizeof(int)); pFile->Write(&ReleasePoint, sizeof(int)); pFile->Write(&Setting, sizeof(int)); for (unsigned int j = 0; j < pSeq->GetItemCount(); j++) { int Value = pSeq->GetItem(j); pFile->Write(&Value, sizeof(char)); } } else { char Enabled = 0; pFile->Write(&Enabled, sizeof(char)); } } unsigned int Count = 0; // Count assigned keys for (int i = 0; i < 6; i++) { // octaves for (int j = 0; j < 12; j++) { // notes if (GetSample(i, j) > 0) Count++; } } pFile->Write(&Count, sizeof(int)); bool UsedSamples[MAX_DSAMPLES]; memset(UsedSamples, 0, sizeof(bool) * MAX_DSAMPLES); // DPCM for (int i = 0; i < 6; ++i) { // octaves for (int j = 0; j < 12; ++j) { // notes if (GetSample(i, j) > 0) { unsigned char Index = i * 12 + j, Sample, Pitch; pFile->Write(&Index, sizeof(char)); Sample = GetSample(i, j); Pitch = GetSamplePitch(i, j); pFile->Write(&Sample, sizeof(char)); pFile->Write(&Pitch, sizeof(char)); UsedSamples[GetSample(i, j) - 1] = true; } } } int SampleCount = 0; // Count samples for (int i = 0; i < MAX_DSAMPLES; ++i) { if (pDoc->GetSampleSize(i) > 0 && UsedSamples[i]) SampleCount++; } // Write the number pFile->Write(&SampleCount, sizeof(int)); // List of sample names, the samples itself won't be stored for (int i = 0; i < MAX_DSAMPLES; ++i) { if (pDoc->GetSampleSize(i) > 0 && UsedSamples[i]) { CDSample *pSample = pDoc->GetDSample(i); int Len = (int)strlen(pSample->Name); pFile->Write(&i, sizeof(int)); pFile->Write(&Len, sizeof(int)); pFile->Write(pSample->Name, Len); pFile->Write(&pSample->SampleSize, sizeof(int)); pFile->Write(pSample->SampleData, pSample->SampleSize); } } }
bool CInstrumentN163::LoadFile(CFile *pFile, int iVersion, CFamiTrackerDoc *pDoc) { // Sequences unsigned char SeqCount; pFile->Read(&SeqCount, sizeof(char)); // Loop through all instrument effects for (unsigned int i = 0; i < SeqCount; ++i) { unsigned char Enabled; pFile->Read(&Enabled, sizeof(char)); if (Enabled == 1) { // Read the sequence int Count; pFile->Read(&Count, sizeof(int)); if (Count < 0 || Count > MAX_SEQUENCE_ITEMS) return false; // Find a free sequence int Index = pDoc->GetFreeSequenceN163(i); CSequence *pSeq = pDoc->GetSequenceN163(Index, i); pSeq->SetItemCount(Count); int LoopPoint; int Setting; pFile->Read(&LoopPoint, sizeof(int)); pSeq->SetLoopPoint(LoopPoint); int ReleasePoint; pFile->Read(&ReleasePoint, sizeof(int)); pSeq->SetReleasePoint(ReleasePoint); pFile->Read(&Setting, sizeof(int)); pSeq->SetSetting(Setting); for (int j = 0; j < Count; ++j) { char Val; pFile->Read(&Val, sizeof(char)); pSeq->SetItem(j, Val); } SetSeqEnable(i, true); SetSeqIndex(i, Index); } else { SetSeqEnable(i, false); SetSeqIndex(i, 0); } } // Read wave config int WaveSize, WavePos, WaveCount; pFile->Read(&WaveSize, sizeof(int)); pFile->Read(&WavePos, sizeof(int)); pFile->Read(&WaveCount, sizeof(int)); if (WaveSize <= 0 || WaveSize > 32) return false; if (WaveCount <= 0 || WaveCount > MAX_WAVE_COUNT) return false; SetWaveSize(WaveSize); SetWavePos(WavePos); SetWaveCount(WaveCount); for (int i = 0; i < WaveCount; ++i) { for (int j = 0; j < WaveSize; ++j) { char w; pFile->Read(&w, sizeof(char)); SetSample(i, j, w); } } 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; }
// 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); } } } }
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(); }
void CBlastIndex::AddSequence(const CSequence& inSequence) { fSequences.push_back(inSequence); ++fSequenceCount; fTotalSequenceLength += inSequence.length(); }
void CModel::Write(CTxtFile* file) { file->Write("$"); file->Writeln(CAssimilateDoc::GetKeyword(TK_AS_GRABINIT, TABLE_QDT)); if (!HasGLA()) { if (GetScale() != 1.0f) { file->Write("$"); file->Write(CAssimilateDoc::GetKeyword(TK_AS_SCALE, TABLE_QDT)," "); file->Writeln(va("%g",GetScale())); } if (GetKeepMotion()) { file->Write("$"); file->Writeln(CAssimilateDoc::GetKeyword(TK_AS_KEEPMOTION, TABLE_QDT)); } if (GetRefGLAPath()) { file->Write("$"); file->Write(CAssimilateDoc::GetKeyword(TK_AS_REF_GLA, TABLE_QDT), " "); file->Writeln(va("%s", GetRefGLAPath())); } for (int iPCJ=0; iPCJ < PCJList_GetEntries(); iPCJ++) { file->Write("$"); file->Write(CAssimilateDoc::GetKeyword(TK_AS_PCJ, TABLE_QDT)," "); file->Writeln( PCJList_GetEntry(iPCJ) ); } } CComment* curComment = m_comments; while(curComment != NULL) { curComment->Write(file); curComment = curComment->GetNext(); } bool bFirstSeqWritten = false; CSequence* curSequence = m_sequences; while(curSequence != NULL) { curSequence->Write(file, !bFirstSeqWritten && GetPreQuat()); curSequence = curSequence->GetNext(); bFirstSeqWritten = true; } file->Writeln("$", CAssimilateDoc::GetKeyword(TK_AS_GRABFINALIZE, TABLE_QDT)); if (m_path != NULL) { file->Write("$", CAssimilateDoc::GetKeyword(GetConvertType(), 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; } file->Write(" ", path, " "); // params stuff... if (IsGhoul2()) { if (GetMakeSkin()) { file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_MAKESKIN, TABLE_CONVERT), " "); } if (GetSmooth()) { file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_SMOOTH, TABLE_CONVERT), " "); } if (GetLoseDupVerts()) { file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_LOSEDUPVERTS, TABLE_CONVERT), " "); } if (GetIgnoreBaseDeviations()) { file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_IGNOREBASEDEVIATIONS, TABLE_CONVERT), " "); } if (GetSkew90()) { file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_SKEW90, TABLE_CONVERT), " "); } if (GetNoSkew90()) { file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_NOSKEW90, TABLE_CONVERT), " "); } if (GetMakeSkelPath() && strlen(GetMakeSkelPath())) { file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_MAKESKEL, TABLE_CONVERT), " "); file->Write(GetMakeSkelPath(), " "); } // params below not used for ghoul2 } else { if (giLODLevelOverride) { file->Write(va("-lod %d ",giLODLevelOverride)); } file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_PLAYERPARMS, TABLE_CONVERT), " "); file->Write(0);//m_skipStart+1); // ignore these, but don't want to update parser and have invalid prev files file->Space(); file->Write(0);//m_skipEnd);//max upper frames); file->Space(); } if (m_originx || m_originy || m_originz) { file->Write("-", CAssimilateDoc::GetKeyword(TK_AS_ORIGIN, TABLE_CONVERT), " "); file->Write(m_originx); file->Space(); file->Write(m_originy); file->Space(); file->Write(m_originz); } file->Writeln(); } }
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; }
void CModel::Resequence(bool bReScanASEFiles /* = false */) { CWaitCursor wait; CRect Rect; CProgressCtrl *pProgress = NULL; if (bReScanASEFiles && ((CAssimilateApp*)AfxGetApp())->m_pMainWnd) { pProgress = new CProgressCtrl; bool bOK = !!pProgress->Create( WS_CHILD|WS_VISIBLE|PBS_SMOOTH, // DWORD dwStyle, CRect(100,100,200,200), // const RECT& rect, ((CAssimilateApp*)AfxGetApp())->m_pMainWnd, // CWnd* pParentWnd, 1 // UINT nID ); if (!bOK) { delete pProgress; pProgress = NULL; } } int iTotMasterSequences = GetTotMasterSequences(); if (pProgress) { pProgress->SetRange(0,iTotMasterSequences); } int iSequenceNumber=0; int curFrame = 0; CSequence* curSequence = m_sequences; while(curSequence != NULL) { if (pProgress) { pProgress->SetPos(iSequenceNumber++); wait.Restore(); } // mark current enums as valid or not... curSequence->SetValidEnum(((CAssimilateApp*)AfxGetApp())->ValidEnum(curSequence->GetEnum())); for (int _i=0; _i<MAX_ADDITIONAL_SEQUENCES; _i++) { CSequence *additionalSeq = curSequence->AdditionalSeqs[_i]; additionalSeq->SetValidEnum(((CAssimilateApp*)AfxGetApp())->ValidEnum(additionalSeq->GetEnum())); } if ( bReScanASEFiles ) { // new code, first of all check for changed framecounts (ie updated ASE file), and update sequence if nec... CString nameASE = ((CAssimilateApp*)AfxGetApp())->GetQuakeDir(); nameASE+= curSequence->GetPath(); if (!FileExists(nameASE)) { if (gbCarWash_DoingScan) { strCarWashErrors += va("Model file missing: \"%s\"\n",nameASE); } else { if ( gbReportMissingASEs ) { gbReportMissingASEs = GetYesNo(va("Model file missing: \"%s\"\n\nContinue recieving this message?",nameASE)); } } } else { int iStartFrame, iFrameCount, iFrameSpeed; iFrameCount = curSequence->GetFrameCount(); // default it in case we skip an XSI read iFrameSpeed = curSequence->GetFrameSpeed(); // default it in case we cache this file curSequence->ReadASEHeader( nameASE, iStartFrame, iFrameCount, iFrameSpeed, true); // true = can skip XSI read if ( iFrameCount != curSequence->GetFrameCount() ) { if (gbCarWash_DoingScan) { strCarWashErrors += va("file: \"%s\" has a framecount of %d, but .CAR file says %d\n",nameASE,iFrameCount,curSequence->GetFrameCount()); } else { // don't mention it if the current count is zero, it's probably a new anim we've just added... if ( curSequence->GetFrameCount() ) { if (giFixUpdatedASEFrameCounts == YES || giFixUpdatedASEFrameCounts == NO) { CYesNoYesAllNoAll query( va("Model file: \"%s\"",nameASE), "", va("... has a framecount of %d instead of %d as the QDT/CAR file says",iFrameCount, curSequence->GetFrameCount()), "", "", "Do you want me to fix this?" ); giFixUpdatedASEFrameCounts = query.DoModal(); } } // update the sequence?... if (giFixUpdatedASEFrameCounts == YES || giFixUpdatedASEFrameCounts == YES_ALL || !curSequence->GetFrameCount() // update: I think this should be here? ) { curSequence->SetFrameCount( iFrameCount ); } } } } // findmeste: this no longer seems to do anything under JK2, presumablt EF1-only? #if 0 // now try to do any auto-associate between the ASE filename base and the existing enums, // so if we find (eg) /...../...../CROUCH.ASE and we have BOTH_CROUCH then auto-set the enum to BOTH_CROUCH CString stringASEName = nameASE; Filename_BaseOnly(stringASEName); // now = (eg) "falldeath" or "injured" etc for (int i=0; ; i++) { LPCSTR p = ((CAssimilateApp*)AfxGetApp())->GetEnumEntry(i); if (!p) // EOS? break; CString stringEnum = p; // note, I could check stuff like "IsEnumSeperator(LPCSTR lpString)" on <p>, but you'd never // have one of those enums assigned to a sequence anyway. char *psEnumPosAfterUnderScore = strchr(stringEnum,'_'); if (psEnumPosAfterUnderScore++) // check it, and skip to next char { // does this enum match the ASE name? if ( !stricmp( psEnumPosAfterUnderScore, stringASEName ) ) { // ok, we've found a good candidate, so set it... (no need for query-prev code, but I wanted to) if ( strcmp( curSequence->GetEnum(), stringEnum)) { curSequence->SetEnum(stringEnum); } } } else { // this should never happen... if (gbCarWash_DoingScan) { strCarWashErrors += va("found an anim enum with no underscore: \"%s\"\n",stringEnum); } else { ASSERT(0); ErrorBox(va("Error! Somehow I found an anim enum with no underscore: \"%s\"",stringEnum)); } } } #endif } // More bollox for Gummelt... :-) // now do the other freaky trick (you'd better be grateful for all this Mike!!! <g>), which is: // If you find the substring DEATH in this (master) sequence's enum, then ensure that the first *additional* // sequence of it is set to be the corresponding DEAD enum, but using the last frame only (and non-looping) // // (... or something...) { // keep scope local for neatness if ( strstr (curSequence->GetEnum(), "DEATH") ) { // scan this sequence's additional sequences for a DEAD of the same basic type... CString stringEnumDEAD = curSequence->GetEnum(); ASSERT(!IsEnumSeperator(stringEnumDEAD)); stringEnumDEAD.Replace("DEATH","DEAD"); // 1st, is there even a corresponding DEAD enum in the global enum table that we can look for... CString stringEnum; bool bEnumFound = false; for (int iEnumEntry=0; !bEnumFound; iEnumEntry++) { LPCSTR p = ((CAssimilateApp*)AfxGetApp())->GetEnumEntry(iEnumEntry); if (!p) // EOS? break; stringEnum = p; // note, I could check stuff like "IsEnumSeperator(LPCSTR lpString)" on <p>, but you'd never // have one of those enums assigned to a sequence anyway. // does this enum match the one we've built? if ( !_stricmp( stringEnum, stringEnumDEAD ) ) { bEnumFound = true; } } if ( bEnumFound ) { // ok, there *is* one of these, so let's scan this sequence's additional sequences to see if we've // got it... CSequence *additionalSeq; // outside FOR scope for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++) { additionalSeq = curSequence->AdditionalSeqs[i]; if (additionalSeq->AdditionalSequenceIsValid()) { if (!strcmp(additionalSeq->GetEnum(),stringEnum)) { break; // we've found one! } } } // if we didn't find one, NULL the ptr if (int i=MAX_ADDITIONAL_SEQUENCES) { additionalSeq = NULL; } // did we find one? (or did it have the wrong info in?) if ( additionalSeq == NULL // didn't find one || additionalSeq->GetFrameCount()!=1 || additionalSeq->GetLoopFrame() !=-1 || additionalSeq->GetStartFrame()!= curSequence->GetFrameCount()-1 || additionalSeq->GetFrameSpeed()!= curSequence->GetFrameSpeed() ) { // find a slot to add this new sequence to, or use the faulty one... if (additionalSeq == NULL) { for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++) { additionalSeq = curSequence->AdditionalSeqs[i]; if (!additionalSeq->AdditionalSequenceIsValid()) { break; // found an unused slot } } } // so have we got a slot to work with? if ( additionalSeq == NULL ) { if (gbCarWash_DoingScan) { strCarWashErrors += va( "F**k!!!: I need an 'additional sequence' slot free in the entry: \"%s\" to generate a DEAD seq, but there isn't one spare. Edit this yourself later.\n",curSequence->GetPath()); } else { ErrorBox( va( "F**k!!!\n\nI need an 'additional sequence' slot free in the ASE:\n\n\"%s\"\n\n... to generate a DEAD seq, but there isn't one spare. Edit this yourself later.",curSequence->GetPath())); } } else { additionalSeq->SetStartFrame( curSequence->GetFrameCount()-1 ); additionalSeq->SetFrameCount( 1 ); additionalSeq->SetLoopFrame (-1 ); additionalSeq->SetFrameSpeed( curSequence->GetFrameSpeed() ); additionalSeq->SetEnum ( stringEnumDEAD ); } } } } } curSequence->SetTargetFrame(curFrame + curSequence->GetStartFrame()); // slightly more legal than just (curFrame) // update: now set any additional sequences within it... for (int i=0; i<MAX_ADDITIONAL_SEQUENCES; i++) { curSequence->AdditionalSeqs[i]->SetTargetFrame(curFrame + curSequence->AdditionalSeqs[i]->GetStartFrame()); } curFrame += curSequence->GetFrameCount(); curFrame += curSequence->GetGenLoopFrame()?1:0; // findme: is this right? I hate this system curSequence = curSequence->GetNext(); } m_totFrames = curFrame; ghAssimilateView->GetDocument()->SetModifiedFlag(); if (pProgress) { delete pProgress; pProgress = 0; } }
bool CInstrument2A03::LoadFile(CFile *pFile, int iVersion, CFamiTrackerDoc *pDoc) { // Reads an FTI file // //CFamiTrackerDoc *pDoc = (CFamiTrackerDoc*)theApp.GetFirstDocument(); char SampleNames[MAX_DSAMPLES][256]; stSequence OldSequence; // Sequences unsigned char SeqCount; pFile->Read(&SeqCount, sizeof(char)); // Loop through all instrument effects for (unsigned int i = 0; i < SeqCount; ++i) { unsigned char Enabled; pFile->Read(&Enabled, sizeof(char)); if (Enabled == 1) { // Read the sequence int Count; pFile->Read(&Count, sizeof(int)); if (Count < 0 || Count > MAX_SEQUENCE_ITEMS) return false; // Find a free sequence int Index = pDoc->GetFreeSequence(i); CSequence *pSeq = pDoc->GetSequence(Index, i); if (iVersion < 20) { OldSequence.Count = Count; for (int j = 0; j < Count; ++j) { pFile->Read(&OldSequence.Length[j], sizeof(char)); pFile->Read(&OldSequence.Value[j], sizeof(char)); } pDoc->ConvertSequence(&OldSequence, pSeq, i); // convert } else { pSeq->SetItemCount(Count); int LoopPoint; int Setting; pFile->Read(&LoopPoint, sizeof(int)); pSeq->SetLoopPoint(LoopPoint); if (iVersion > 20) { int ReleasePoint; pFile->Read(&ReleasePoint, sizeof(int)); pSeq->SetReleasePoint(ReleasePoint); } if (iVersion >= 23) { pFile->Read(&Setting, sizeof(int)); pSeq->SetSetting(Setting); } for (int j = 0; j < Count; ++j) { char Val; pFile->Read(&Val, sizeof(char)); pSeq->SetItem(j, Val); } } SetSeqEnable(i, true); SetSeqIndex(i, Index); } else { SetSeqEnable(i, false); SetSeqIndex(i, 0); } } bool SamplesFound[MAX_DSAMPLES]; memset(SamplesFound, 0, sizeof(bool) * MAX_DSAMPLES); unsigned int Count; pFile->Read(&Count, sizeof(int)); // DPCM instruments for (unsigned int i = 0; i < Count; ++i) { unsigned char InstNote; pFile->Read(&InstNote, sizeof(char)); int Octave = InstNote / 12; int Note = InstNote % 12; unsigned char Sample, Pitch; pFile->Read(&Sample, sizeof(char)); pFile->Read(&Pitch, sizeof(char)); SetSamplePitch(Octave, Note, Pitch); SetSample(Octave, Note, Sample); } // DPCM samples list bool bAssigned[OCTAVE_RANGE][NOTE_RANGE]; memset(bAssigned, 0, sizeof(bool) * OCTAVE_RANGE * NOTE_RANGE); unsigned int SampleCount; pFile->Read(&SampleCount, sizeof(int)); for (unsigned int i = 0; i < SampleCount; ++i) { int Index, Len; pFile->Read(&Index, sizeof(int)); pFile->Read(&Len, sizeof(int)); if (Index >= MAX_DSAMPLES || Len >= 256) return false; pFile->Read(SampleNames[Index], Len); SampleNames[Index][Len] = 0; int Size; pFile->Read(&Size, sizeof(int)); char *SampleData = new char[Size]; pFile->Read(SampleData, Size); bool Found = false; for (int j = 0; j < MAX_DSAMPLES; ++j) { CDSample *pSample = pDoc->GetDSample(j); // Compare size and name to see if identical sample exists if (pSample->SampleSize == Size && !strcmp(pSample->Name, SampleNames[Index])) { Found = true; // Assign sample for (int o = 0; o < OCTAVE_RANGE; ++o) { for (int n = 0; n < NOTE_RANGE; ++n) { if (GetSample(o, n) == (Index + 1) && !bAssigned[o][n]) { SetSample(o, n, j + 1); bAssigned[o][n] = true; } } } } } if (!Found) { // Load sample int FreeSample = pDoc->GetFreeDSample(); if (FreeSample != -1) { if ((pDoc->GetTotalSampleSize() + Size) <= MAX_SAMPLE_SPACE) { CDSample *Sample = pDoc->GetDSample(FreeSample); strcpy(Sample->Name, SampleNames[Index]); Sample->SampleSize = Size; Sample->SampleData = SampleData; // Assign it for (int o = 0; o < OCTAVE_RANGE; ++o) { for (int n = 0; n < NOTE_RANGE; ++n) { if (GetSample(o, n) == (Index + 1) && !bAssigned[o][n]) { SetSample(o, n, FreeSample + 1); bAssigned[o][n] = true; } } } } else { // AfxMessageBox(IDS_OUT_OF_SAMPLEMEM, MB_ICONERROR); SAFE_RELEASE_ARRAY(SampleData); return false; } } else { // AfxMessageBox(IDS_OUT_OF_SLOTS, MB_ICONERROR); SAFE_RELEASE_ARRAY(SampleData); return false; } } else { SAFE_RELEASE_ARRAY(SampleData); } } return true; }