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; }
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 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; } }