// NodeObject.cpp: implementation of the CNodeObject class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ContentTrack.h" #include "NodeObject.h" #include "NodeDataValueFileDoc.h" #include "mainfrm.h" #include #include #include #include #include #include #include "..\..\Code\Buildnum\buildnum.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif //CMapStringToPtr g_mapKeyType; //**************************************************************************** // Procedure ForwardMessage // // Purpose Lets another process do what it needs to when we're in the // middle of something lengthy. // // Parameters none // // Returns nonzero if all messages were removed from the queue; zero // if some are left when we return. // // History //10/06/94 KenSh Don't remove WM_CLOSE, WM_QUIT, etc.,from the queue. Screws up in Win32. // BOOL ForwardMessages() { MSG msg; while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { if( msg.message == WM_QUIT || msg.message == WM_CLOSE || msg.message == WM_DESTROY ) { // Put the message back on the queue and get out of here. PostMessage( msg.hwnd, msg.message, msg.wParam, msg.lParam ); return FALSE; } TranslateMessage (&msg); DispatchMessage (&msg); } return TRUE; } ////////////////////////////////////////////////////////////////////// // CNodeObject ////////////////////////////////////////////////////////////////////// CString ReplaceNoCase(CString input,CString strOld,CString strNew,int *pCount = NULL) { if (pCount) *pCount = 0; if (0 == strOld.GetLength()) return input; CString output; int index = 0; CString strFind = input; strFind.MakeLower(); strOld.MakeLower(); int iFind = 0; while (-1 != iFind) { iFind = strFind.Find(strOld,index); if (iFind>=0) { output += input.Mid(index,(iFind-index))+strNew; if (pCount) (*pCount)++; index = iFind+strOld.GetLength(); } } output += input.Mid(index,input.GetLength()-index); return output; } static DWORD g_dwNameMem = 0; CNodeObject::CNodeObject(CNodeObject *pParent,CString name,CNodeObject *pClone,CString oldName,CString newName) { m_iClassID = CLASS_CNODEOBJECT; m_pNodeParent = pParent; m_bDirty = true; m_iRefCount = 0; m_dwVisited = 0; m_pListChildren = m_pListReferences = NULL; m_szName = NULL; if (name.GetLength()) { int rcount; CString output = ReplaceNoCase(name,oldName,newName,&rcount); if (rcount) { int x=1; } m_szName = strdup(output); g_dwNameMem += strlen(m_szName)+1; } if (pClone) { POSITION pos = pClone->GetFirstChild(); while (pos) { CNodeObject *pChild = pClone->GetNextChild(pos); CNodeObject *pChildClone = pChild->Clone(this,oldName,newName); AddChild(pChildClone); } Paste(pClone); } } CNodeObject::~CNodeObject() { //TODO: this should already be empty m_mapViewHandles.RemoveAll(); if (m_pListChildren) { NODELIST *pos = m_pListChildren; while (pos) { pos->pData->RemoveRef(this); NODELIST *nextpos = pos->pNext; delete pos; pos = nextpos; } } /* POSITION pos = this->GetFirstChild(); while (pos) { CNodeObject *pObj = this->GetNextChild(pos); pObj = pObj->RemoveRef(this); } m_listChildren.RemoveAll();*/ /* pos = m_listReferences.GetHeadPosition(); if (pos) { // Not all references were removed before deleting this item int x=1; }*/ if (m_szName) delete m_szName; } void CNodeObject::SetName(const char *name) { if (m_szName) delete m_szName; m_szName = strdup(name); } int CNodeObject::GetName(CString &str) { char buf[MAX_PATH]; int len = GetName(buf,MAX_PATH); str = buf; return len; } CString CNodeObject::GetNameStr() { CString str; GetName(str); return str; } // Buf must be pre-allocated int CNodeObject::GetName(char *buf,int buflen) { strncpy(buf,m_szName,buflen); return Min(buflen,strlen(m_szName)); } POSITION CNodeObject::GetFirstChild() { // return this->m_listChildren.GetHeadPosition(); return (POSITION)m_pListChildren; } CNodeObject *CNodeObject::GetNextChild(POSITION &pos) { // TODO: Should probably check that the object type is a valid derivative of CNodeObject //return (CNodeObject *)this->m_listChildren.GetNext(pos); NODELIST *pItem = (NODELIST *)pos; pos = (POSITION)pItem->pNext; return pItem->pData; } POSITION CNodeObject::AddChild(CNodeObject *pNode) { NODELIST *pItem = new NODELIST; pItem->pData = pNode; pItem->pNext = m_pListChildren; m_pListChildren = pItem; pNode->AddRef(this); return (POSITION)pItem; /* if(pNode) { pNode->AddRef(this); return this->m_listChildren.AddHead(pNode); } VERIFY(false); return NULL;*/ } CNodeObject *CNodeObject::RemoveChild(POSITION pos) { //CNodeObject *pChild = this->GetAt(pos); /* m_listChildren.RemoveAt(pos); */ // TODO: Speed this up?? NODELIST *pPrev=NULL,*pItem = m_pListChildren; while (pItem && ((POSITION)pItem != pos)) { pPrev = pItem; pItem = pItem->pNext; } if (pItem) { if (pPrev) { pPrev->pNext = pItem->pNext; } else { m_pListChildren = pItem->pNext; } CNodeObject *pNode = pItem->pData; delete pItem; pNode = pNode->RemoveRef(this); if (pNode && (0 == pNode->GetRefCount())) { delete pNode; pNode = NULL; } return pNode; } // Didn't find pos as a child of this node assert(false); return NULL; } CNodeObject *CNodeObject::GetAt(POSITION pos) { NODELIST *pItem = m_pListChildren; while (pItem) { if ((POSITION)pItem == pos) return pItem->pData; pItem = pItem->pNext; } //return (CNodeObject *)m_listChildren.GetAt(pos); assert(false); return NULL; } HANDLE CNodeObject::ViewNode(CTreeCtrl *pCtrl,HTREEITEM hParent,int depth) { HTREEITEM hItem = NULL; CString name; GetName(name); bool bExpand = false; if (GetClassID() == CLASS_CNODEDATAVALUE) { CNodeDataValue *pthis = (CNodeDataValue *)this; if (pthis->GetKeyType() == KEYTYPE_UNKNOWN) name = "(Unknown)"+name; } if (this->IsFile()) { CNodeDataValueFile *pthis = (CNodeDataValueFile *)this; if (!pthis->GetNodeDisk()->IsFound()) name = "(Not Found)"+name; } if (NULL == hParent) { CNodeObject *pNode = this->GetParentNode(); if (pNode) { // We are trying to view a node that has not been expanded, so load up the parent tree HANDLE handle = pNode->ViewNode(pCtrl,NULL,0); hParent = (HTREEITEM)handle; bExpand = true; pCtrl->Expand(hParent,TVE_EXPAND); } } if (NULL == hItem) { if (m_mapViewHandles.Lookup(hParent,(void *&)hItem)) { if (m_bDirty) { // Either change all of the instances in mapViewHandles here (assuming all are same type of view) // or clean the dirty bit after all the views have been updated pCtrl->SetItemText(hItem,name); pCtrl->SetItemData(hItem,(DWORD)this); } } else { hItem = pCtrl->InsertItem(name,hParent); m_mapViewHandles[hParent] = hItem; pCtrl->SetItemData(hItem,(DWORD)this); } } if (!pCtrl->GetItemState(hItem,TVIS_EXPANDED)) { if (depth) depth--; else { // We should only be expanding up here return hItem; } } if (bExpand) { // This is the last one, so set it to bold //pCtrl->Expand(hItem,TVE_EXPAND); //pCtrl->SetItemState(hItem,TVIS_BOLD,TVIS_BOLD); } else { POSITION pos = this->GetFirstChild(); while (pos) { CNodeObject *pNode = this->GetNextChild(pos); HTREEITEM hChildItem; if ((depth >0) || (pNode->m_mapViewHandles.Lookup(hItem,(void *&)hChildItem))) pNode->ViewNode(pCtrl,hItem,depth); } m_bDirty = false; } return hItem; } void CNodeObject::Update() { if (GetVisit(VISIT_FLAG1)) return; SetVisit(VISIT_FLAG1); POSITION pos = this->GetFirstChild(); while (pos) { CNodeObject *pNode = this->GetNextChild(pos); pNode->Update(); } } CNodeObject *CNodeObject::RemoveRef(CNodeObject *pFrom) { NODELIST *pPrev=NULL,*pItem = m_pListReferences; while (pItem && (pItem->pData!=pFrom)) { pPrev = pItem; pItem = pItem->pNext; } if (pItem) { m_iRefCount--; if (pPrev) { pPrev->pNext = pItem->pNext; } else { m_pListReferences = pItem->pNext; } delete pItem; if (0 == m_iRefCount) { delete this; return NULL; } return this; } // pFrom is not a reference of this node assert(false); return NULL; /* POSITION pos = m_listReferences.Find(pFrom); if (pos) { m_listReferences.RemoveAt(pos); m_iRefCount--; } else { // Trying to remove a reference when one wasn't made from here //assert(false); // Or that this is a DiskFile that is not in the content directory so it doesn't have a content root reference VERIFY(false); } if (0 == m_iRefCount) { delete this; return NULL; } return this;*/ } CNodeObject *CNodeObject::FindChild(CString strName,bool bRecurse) { // strName.MakeLower(); POSITION pos = GetFirstChild(); while (pos) { CNodeObject *pChild = GetNextChild(pos); CString name; pChild->GetName(name); //name.MakeLower(); //if (name == strName) if (0 == stricmp(name,strName)) return pChild; if (bRecurse) { pChild = pChild->FindChild(strName,bRecurse); if (pChild) return pChild; } } return NULL; } void CNodeObject::AddRef(CNodeObject *pFrom) { NODELIST *pItem = new NODELIST; pItem->pNext = m_pListReferences; m_pListReferences= pItem; pItem->pData = pFrom; m_iRefCount++; /* m_listReferences.AddHead(pFrom); m_iRefCount++; VERIFY(m_listReferences.GetCount() == m_iRefCount);*/ } POSITION CNodeObject::GetFirstReference() { //return m_listReferences.GetHeadPosition(); return (POSITION)m_pListReferences; } CNodeObject *CNodeObject::GetNextReference(POSITION &pos) { //return (CNodeObject *)this->m_listReferences.GetNext(pos); NODELIST *pItem = (NODELIST *)pos; pos = (POSITION)pItem->pNext; return pItem->pData; } CNodeObject *CNodeObject::Clone(CNodeObject *pParent,CString oldName,CString newName) { CNodeObject *pClone = NULL; // Return a clone of this node CString name; GetName(name); switch (GetClassID()) { case CLASS_CNODEOBJECT: return new CNodeObject(pParent,name,this,oldName,newName); case CLASS_CNODEDISK: case CLASS_CNODEDISKDIRECTORY: case CLASS_CNODEDISKFILE: case CLASS_CNODEDATA: break; case CLASS_CNODEDATAPAGE: return new CNodeDataPage(pParent,NULL,name,"","",this,oldName,newName); case CLASS_CNODEDATAENTRY: return new CNodeDataEntry(pParent,NULL,name,"",this,oldName,newName); case CLASS_CNODEDATAVALUE: return new CNodeDataValue(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFLOAT: return new CNodeDataValueFloat(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEPOINT3: return new CNodeDataValuePoint3(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEBOOL: return new CNodeDataValueBool(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUESTRING: return new CNodeDataValueString(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEINT: return new CNodeDataValueInt(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUECOMPOSTTEXTURE: return new CNodeDataValueCompostTexture(pParent,name,this,oldName,newName); // case CLASS_CNODEDATAVALUEFILE: - This class is over-ridded case CLASS_CNODEDATAVALUEFILEPROJECT:break; case CLASS_CNODEDATAVALUEFILEERF: return new CNodeDataValueFileERF(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILEWAV: return new CNodeDataValueFileWAV(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILEMW4ANIM: return new CNodeDataValueFileMW4ANIM(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILETGA: return new CNodeDataValueFileTGA(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILEPNG: return new CNodeDataValueFilePNG(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILENOTE: return new CNodeDataValueFileNote(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILEBSP: return new CNodeDataValueFileBSP(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILEOBB: return new CNodeDataValueFileOBB(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILEABL: return new CNodeDataValueFileABL(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILEFGD: return new CNodeDataValueFileFGD(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILEMATERIAL: return new CNodeDataValueFileMATERIAL(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILERAW: return new CNodeDataValueFileRAW(pParent,name,this,oldName,newName); case CLASS_CNODEDATAVALUEFILEBID: return new CNodeDataValueFileBID(pParent,name,this,oldName,newName); //case CLASS_CNODEDATAVALUEFILERESOURCE: return new CNodeDataValueFileResource(pParent,GetName(),this); // Dont clone erf data, just re-load the erf and change the names along the way case CLASS_CNODEDATAVALUEERF: return new CNodeDataValueERF(pParent,NULL,this,oldName,newName); case CLASS_CNODEDATAVALUEERFGROUPELEMENT: return new CNodeDataValueERFGroupElement(pParent,NULL,this,oldName,newName); case CLASS_CNODEDATAVALUEERFLISTELEMENT: return new CNodeDataValueERFListElement(pParent,NULL,this,oldName,newName); case CLASS_CNODEDATAVALUEERFGRIDELEMENT: return new CNodeDataValueERFGridElement(pParent,NULL,this,oldName,newName); case CLASS_CNODEDATAVALUEERFLODELEMENT: return new CNodeDataValueERFLODElement(pParent,NULL,this,oldName,newName); case CLASS_CNODEDATAVALUEERFSHAPELODELEMENT: return new CNodeDataValueERFShapeLODElement(pParent,NULL,this,oldName,newName); case CLASS_CNODEDATAVALUEERFSHAPEELEMENT: return new CNodeDataValueERFShapeElement(pParent,NULL,this,oldName,newName); case CLASS_CNODEDATAVALUEERFSWITCHELEMENT: return new CNodeDataValueERFSwitchElement(pParent,NULL,this,oldName,newName); case CLASS_CNODEDATAVALUEMLRELEMENT: return new CNodeDataValueMLRElement(pParent,NULL,this,oldName,newName); { break; } default: { // unknown type assert(false); } } return pClone; } bool CNodeObject::IsFile() { switch (GetClassID()) { case CLASS_CNODEDATAVALUEFILE: case CLASS_CNODEDATAVALUEFILEPROJECT: case CLASS_CNODEDATAVALUEFILEERF: case CLASS_CNODEDATAVALUEFILEWAV: case CLASS_CNODEDATAVALUEFILEMW4ANIM: case CLASS_CNODEDATAVALUEFILETGA: case CLASS_CNODEDATAVALUEFILEPNG: case CLASS_CNODEDATAVALUEFILENOTE: case CLASS_CNODEDATAVALUEFILEBSP: case CLASS_CNODEDATAVALUEFILEOBB: case CLASS_CNODEDATAVALUEFILEABL: case CLASS_CNODEDATAVALUEFILEFGD: case CLASS_CNODEDATAVALUEFILEMATERIAL: case CLASS_CNODEDATAVALUEFILERAW: case CLASS_CNODEDATAVALUEFILEBID: return true; } return false; } bool CNodeObject::IsDataValue() { switch (GetClassID()) { case CLASS_CNODEDATAVALUE: case CLASS_CNODEDATAVALUEFLOAT: case CLASS_CNODEDATAVALUEPOINT3: case CLASS_CNODEDATAVALUEBOOL: case CLASS_CNODEDATAVALUESTRING: case CLASS_CNODEDATAVALUEINT: case CLASS_CNODEDATAVALUECOMPOSTTEXTURE: case CLASS_CNODEDATAVALUEFILE: case CLASS_CNODEDATAVALUEFILEPROJECT: case CLASS_CNODEDATAVALUEFILEERF: case CLASS_CNODEDATAVALUEFILEWAV: case CLASS_CNODEDATAVALUEFILEMW4ANIM: case CLASS_CNODEDATAVALUEFILETGA: case CLASS_CNODEDATAVALUEFILEPNG: case CLASS_CNODEDATAVALUEFILENOTE: case CLASS_CNODEDATAVALUEFILEBSP: case CLASS_CNODEDATAVALUEFILEOBB: case CLASS_CNODEDATAVALUEFILEABL: case CLASS_CNODEDATAVALUEERF: case CLASS_CNODEDATAVALUEFILEFGD: case CLASS_CNODEDATAVALUEFILEMATERIAL: case CLASS_CNODEDATAVALUEFILERAW: case CLASS_CNODEDATAVALUEFILEBID: return true; } return false; } bool CNodeObject::SetVisit(DWORD dwFlag) { bool bret = GetVisit(dwFlag); m_dwVisited = (m_dwVisited | dwFlag) & dwFlag; return false; } bool CNodeObject::GetVisit(DWORD dwFlag) { return m_dwVisited & dwFlag; } void CNodeObject::ResetVisit() { this->m_dwVisited = 0; } void CNodeObject::ResetVisitAll() { ResetVisit(); POSITION pos = GetFirstChild(); while (pos) { CNodeObject *pChild = GetNextChild(pos); pChild->ResetVisitAll(); } } int CNodeObject::Paste(CNodeObject *pClone) { return 0; } CString CNodeObject::GetRootPath() { if (GetClassID() == CLASS_CNODEDATAVALUEFILEPROJECT) { CString str; GetName(str); return str; } CNodeObject *pParent = GetParentNode(); if (pParent) return pParent->GetRootPath(); return ""; } ////////////////////////////////////////////////////////////////////// // CNodeDisk ////////////////////////////////////////////////////////////////////// CNodeDisk::CNodeDisk(CNodeObject *pParent,CString path,bool bFindOverride) : CNodeObject(pParent,path) { m_iClassID = CLASS_CNODEDISK; // Used for creating generic disk node outside of contents directory - like the project node if (bFindOverride) m_bFound = true; else m_bFound = false; m_bLoaded = false; m_bDirty = false; // Extract the deepest subdir from the path, save the prefix as the m_strParentPath // save the suffix as m_strName // There must be a path here if (path.IsEmpty()) { assert(false); return; } // Make sure the end of the path is not trailing a '\' character if ('\\'==path[path.GetLength()-1]) { path.SetAt(path.GetLength()-1,'\0'); SetName(path); } /* // Separate prefix and suffix CString prefix; int index = path.ReverseFind('\\'); if (0<=index) { prefix = path.Left(index); path.Delete(0,index+1); }*/ //SetName(path); } CNodeDisk::~CNodeDisk() { } CString CNodeDisk::GetPath() { CString str; GetName(str); CString dir = GetDirectory(); if (dir.GetLength()) dir += "\\"; return dir+str; } CString CNodeDisk::GetDirectory() { CNodeObject *pParent = GetParentNode(); if (pParent && (pParent->GetClassID() == CLASS_CNODEDISKDIRECTORY)) { CString str; pParent->GetName(str); CString dir = ((CNodeDisk *)pParent)->GetDirectory(); return (dir.GetLength()?dir+"\\":"")+str; } return ""; } CNodeDiskFile *CNodeDisk::DiskCopyFile(CString source,CString dest) { // Create the directory first char drive[MAX_PATH],dir[MAX_PATH],fname[MAX_PATH],ext[MAX_PATH]; _splitpath(dest,drive,dir,fname,ext); CString strRoot = this->GetRootPath()+"\\"; CNodeDisk *pDir = DiskCreateDirectory(dir); CString filename = CString(fname)+ext; CString fullpath = strRoot+pDir->GetPath()+"\\"+filename; bool result; if (source.GetLength()) { result = ::CopyFile(source,fullpath,false); } else { if (!gos_DoesFileExist(fullpath)) { HGOSFILE file; gos_OpenFile(&file,fullpath,READWRITE); gos_CloseFile(file); result = true; } } CNodeDiskFile *pFile = new CNodeDiskFile(pDir,filename); pDir->AddChild(pFile); return pFile; } // Copy the file from memory raw data CNodeDiskFile *CNodeDisk::DiskCopyFile(LPVOID lpData,DWORD dwSize,CString dest) { // Create the directory first char drive[MAX_PATH],dir[MAX_PATH],fname[MAX_PATH],ext[MAX_PATH]; _splitpath(dest,drive,dir,fname,ext); CString strRoot = this->GetRootPath()+"\\"; CNodeDisk *pDir = DiskCreateDirectory(dir); CString filename = CString(fname)+ext; CString fullpath = strRoot+pDir->GetPath()+"\\"+filename; bool result; if (lpData && dwSize) { HANDLE hFile = CreateFile(fullpath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW , FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_ALREADY_EXISTS || GetLastError() == ERROR_FILE_EXISTS) { // File already exists int x=1; } // Error creating file int x=1; } else { DWORD dwBytesWritten; if (!WriteFile(hFile, lpData, dwSize, & dwBytesWritten, NULL) || dwBytesWritten != dwSize) { // Failed to write file int x=1; } CloseHandle(hFile); } } else { if (!gos_DoesFileExist(fullpath)) { HGOSFILE file; gos_OpenFile(&file,fullpath,READWRITE); gos_CloseFile(file); result = true; } } CNodeDiskFile *pFile = new CNodeDiskFile(pDir,filename); pDir->AddChild(pFile); return pFile; } CNodeDisk *CNodeDisk::DiskCreateDirectory(CString name) { if (0 == name.GetLength()) return this; if (name[0] == '\\') name = name.Right(name.GetLength()-1); int index = name.Find("\\",0); if (index<0) return this; CString left = name.Left(index); CString right = name.Right(name.GetLength()-index); POSITION pos = GetFirstChild(); while (pos) { CNodeObject *pChild = GetNextChild(pos); switch (pChild->GetClassID()) { case CLASS_CNODEDISKFILE: { break; } case CLASS_CNODEDISKDIRECTORY: { CString s1; pChild->GetName(s1); CString s2 = left; //s1.MakeLower(); //s2.MakeLower(); //if (0 == strnicmp(pChild->GetName(),left,left.GetLength())) // (s1 == s2) if (0 == stricmp(s1,s2)) return ((CNodeDisk *)pChild)->DiskCreateDirectory(right); break; } default: { return NULL; } } } CString strNewPath = GetPath()+"\\"+left; CString strFullPath = this->GetRootPath()+"\\"+strNewPath; ::CreateDirectory(strFullPath,NULL); CNodeDisk *pDir = new CNodeDiskDirectory(this,left); AddChild(pDir); CNodeDisk *pChildDir = pDir->DiskCreateDirectory(right); return pChildDir; } ////////////////////////////////////////////////////////////////////// // CNodeData ////////////////////////////////////////////////////////////////////// CNodeData::CNodeData(CNodeObject *pParent,CString path,CNodeObject *pClone,CString oldName,CString newName) : CNodeObject(pParent,path,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATA; } CNodeData::~CNodeData() { } ////////////////////////////////////////////////////////////////////// // CNodeDiskDirectory ////////////////////////////////////////////////////////////////////// CNodeDiskDirectory::CNodeDiskDirectory(CNodeObject *pParent,CString path) : CNodeDisk(pParent,path) { m_iClassID = CLASS_CNODEDISKDIRECTORY; // recurse on path to scan the for the children CFileFind ffind; if (pParent && (pParent->GetClassID() == CLASS_CNODEDISKDIRECTORY)) { CNodeDisk *pDisk = (CNodeDisk *)pParent; CString str = pDisk->GetPath(); path = str+"\\"+path; } else { int x=1; } path += "\\*.*"; if (ffind.FindFile(path,0)) { m_bFound = true; while (ffind.FindNextFile()) { if (!ffind.IsDots()) { CNodeDisk *pChild = NULL; if (ffind.IsDirectory()) { // Is a directory pChild = new CNodeDiskDirectory(this,ffind.GetFileName());//GetFilePath()); } else { // Is a file pChild = new CNodeDiskFile(this,ffind.GetFileName());//.GetFilePath()); } AddChild(pChild); } } // There is always one more... { if (!ffind.IsDots()) { CNodeDisk *pChild = NULL; if (ffind.IsDirectory()) { // Is a directory pChild = new CNodeDiskDirectory(this,ffind.GetFileName());//.GetFilePath()); } else { // Is a file pChild = new CNodeDiskFile(this,ffind.GetFileName());//GetFilePath()); } AddChild(pChild); } } } else { // We are making virtual directories int x=1; } ffind.Close(); } CNodeDiskDirectory::~CNodeDiskDirectory() { } ////////////////////////////////////////////////////////////////////// // CNodeDiskFile ////////////////////////////////////////////////////////////////////// CNodeDiskFile::CNodeDiskFile(CNodeObject *pParent,CString name) : CNodeDisk(pParent,name) { m_iClassID = CLASS_CNODEDISKFILE; // For performance I may want the callee to set m_bFound if it was from CNodeDiskDirectory if (CLASS_CNODEDISKDIRECTORY == pParent->GetClassID()) { m_bFound = true; } } CNodeDiskFile::~CNodeDiskFile() { } ////////////////////////////////////////////////////////////////////// // CNodeDataPage ////////////////////////////////////////////////////////////////////// CNodeDataPage::CNodeDataPage(CNodeObject *pParent,Page *page,CString pagename,CString entryname,CString name,CNodeObject *pClone,CString oldName,CString newName) : CNodeData(pParent,page?page->GetName():pagename,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAPAGE; if (pClone) return; // Cloning handled by superclass CNodeDataEntry *pChild=NULL; if (page) { Page::NoteIterator *entries = page->MakeNoteIterator(); Check_Object(entries); Note *entry; // Enumerate the entries in the section while ((entry = entries->ReadAndNext()) != NULL) { Check_Object(entry); pChild = new CNodeDataEntry(this,entry,"",""); AddChild(pChild); } Check_Object(entries); delete entries; } else { pChild = new CNodeDataEntry(this,NULL,entryname,name); AddChild(pChild); } } CNodeDataPage::~CNodeDataPage() { } ////////////////////////////////////////////////////////////////////// // CNodeDataEntry ////////////////////////////////////////////////////////////////////// extern CStringMap g_StringMap; /* Base constructed with string "" so that no bytes are allocated for name, which is pointer to key node*/ CNodeDataEntry::CNodeDataEntry(CNodeObject *pParent,Note *entry,CString keyname,CString valuename,CNodeObject *pClone,CString oldName,CString newName) : CNodeData(pParent,/*entry?(char *)entry->GetName():keyname*/"",pClone,oldName,newName) // Can be constructed either with the Note, or with NULL note and key value pair { m_iClassID = CLASS_CNODEDATAENTRY; if (pClone) { CNodeDataEntry *pCloneEntry = (CNodeDataEntry *)pClone; m_szName = (char *)pCloneEntry->GetKeyPos(); return; // cloning handled by superclass } const char *pKeyName; if (entry) pKeyName = (char *)entry->GetName(); else pKeyName = (LPCTSTR)keyname; const char *pValueName = (LPCTSTR)valuename; if (entry) entry->GetEntry(&pValueName); // need to determine what kind of data this is /*void *value = 0; CString strV(pKeyName); strV.MakeUpper(); if (!g_mapKeyType.Lookup(strV,value)) { // This is a new key type, add it to the known key type list g_mapKeyType[strV] = 0; }*/ POSITION pos = g_StringMap.Exists(pKeyName); if (NULL == pos) pos = g_StringMap.Find(pKeyName); BYTE bval = g_StringMap.GetValue(pos); /* { VERIFY(bval == (DWORD)value); CString str1 = g_StringMap.GetName(pos); VERIFY(strV == str1); } */ this->m_szName = (char *)pos; CNodeData *pChild = CreateChild(this,(int)bval,pValueName); AddChild(pChild); } CNodeDataEntry::~CNodeDataEntry() { //strcpy(m_szName,"000"); m_szName = NULL; } void CNodeDataEntry::Update() { //void *value = 0; //CString name; //CNodeData::GetName(name); //name.MakeUpper(); /*if (!g_mapKeyType.Lookup(name,value)) { // This is a new key type, add it to the known key type list g_mapKeyType[name] = 0; }*/ /* POSITION pos = g_StringMap.Exists(name); if (NULL == pos) pos = g_StringMap.Find(name);*/ BYTE val = GetKeyValue(); POSITION pos,pos1 = this->GetFirstChild(); pos = pos1; while (pos) { CNodeDataValue *pNode = (CNodeDataValue *)this->GetNextChild(pos); if (val == pNode->GetKeyType()) pNode->Update(); else { CString str; pNode->GetName(str); // Copy to a temp map CMapPtrToPtr map; POSITION pos = pNode->m_mapViewHandles.GetStartPosition(); while (pos) { HANDLE key; HANDLE value; pNode->m_mapViewHandles.GetNextAssoc(pos,key,value); map[key] = value; } CNodeObject *pObj = RemoveChild(pos1); pNode = CreateChild(this,(int)val,str); // Copy back to new map pos = map.GetStartPosition(); while (pos) { HANDLE key; HANDLE value; map.GetNextAssoc(pos,key,value); pNode->m_mapViewHandles[key] = value; } AddChild(pNode); SetVisit(VISIT_FLAG1); } pos1 = pos; } } int CNodeDataEntry::GetName(char *buf,int buflen) { POSITION pos = (POSITION)m_szName; CString str = g_StringMap.GetName(pos); strncpy(buf,str,buflen); return str.GetLength(); /*CString key; LPVOID value; g_mapKeyType.GetNextAssoc(pos,key,&value); return key; return CNodeData::GetName();*/ } BYTE CNodeDataEntry::GetKeyValue() { POSITION pos = (POSITION)m_szName; return g_StringMap.GetValue(pos); } POSITION CNodeDataEntry::GetKeyPos() { return (POSITION)m_szName; } CNodeDataValue *CNodeData::CreateChild(CNodeObject *pParent,int key,CString pValueName) { switch (key) { case KEYTYPE_UNKNOWN: { return new CNodeDataValue(pParent,pValueName); break; } case KEYTYPE_NOTE: { return new CNodeDataValueFileNote(pParent,pValueName); break; } case KEYTYPE_MW4ANIM: { return new CNodeDataValueFileMW4ANIM(pParent,pValueName); break; } case KEYTYPE_ERF: { return new CNodeDataValueFileERF(pParent,pValueName); break; } case KEYTYPE_WAV: { return new CNodeDataValueFileWAV(pParent,pValueName); break; } case KEYTYPE_FLOAT: { return new CNodeDataValueFloat(pParent,pValueName); break; } case KEYTYPE_POINT3: { return new CNodeDataValuePoint3(pParent,pValueName); break; } case KEYTYPE_BOOL: { return new CNodeDataValueBool(pParent,pValueName); break; } case KEYTYPE_STRING: { return new CNodeDataValueString(pParent,pValueName); break; } case KEYTYPE_INT: { return new CNodeDataValueInt(pParent,pValueName); break; } case KEYTYPE_COMPOSTTEXTURE: { return new CNodeDataValueCompostTexture(pParent,pValueName); break; } case KEYTYPE_OBB: { return new CNodeDataValueFileOBB(pParent,pValueName); break; } case KEYTYPE_ABL: { return new CNodeDataValueFileABL(pParent,pValueName); break; } case KEYTYPE_FGD: { return new CNodeDataValueFileFGD(pParent,pValueName); break; } case KEYTYPE_MATERIAL: { return new CNodeDataValueFileMATERIAL(pParent,pValueName); break; } case KEYTYPE_RAW: { return new CNodeDataValueFileRAW(pParent,pValueName); break; } case KEYTYPE_BID: { return new CNodeDataValueFileBID(pParent,pValueName); break; } case KEYTYPE_RESOURCE: { return new CNodeDataValueFileResource(pParent,pValueName); break; } case KEYTYPE_TGA: { return new CNodeDataValueFileTGA(pParent,pValueName); break; } case KEYTYPE_PNG: { return new CNodeDataValueFilePNG(pParent,pValueName); break; } case KEYTYPE_BSP: { return new CNodeDataValueFileBSP(pParent,pValueName); break; } case KEYTYPE_PROJECT: { // Cannot create a project as a child assert(false); break; } default: { } } return NULL; } ////////////////////////////////////////////////////////////////////// // CNodeDataValue ////////////////////////////////////////////////////////////////////// CNodeDataValue::CNodeDataValue(CNodeObject *pParent,CString name,CNodeObject *pClone,CString oldName,CString newName) : CNodeData(pParent,name,pClone,oldName,newName) { m_iKeyType = KEYTYPE_UNKNOWN; m_iClassID = CLASS_CNODEDATAVALUE; } CNodeDataValue::~CNodeDataValue() { } HANDLE CNodeDataValue::ViewNode(CTreeCtrl *pCtrl,HTREEITEM hParent,int depth) { HTREEITEM hItem = NULL; if ((NULL == hParent) && (KEYTYPE_UNKNOWN == GetKeyType())&&(CLASS_CNODEOBJECT == GetClassID())) { if (!m_mapViewHandles.Lookup(hParent,(void *&)hItem)) { CString str; GetName(str); hItem = pCtrl->InsertItem(CString("(Unknown )")+str,hParent); m_mapViewHandles[hParent] = hItem; pCtrl->SetItemData(hItem,(DWORD)this); } m_bDirty = false; } else return CNodeObject::ViewNode(pCtrl,hParent,depth); return hItem; } int CNodeDataValue::Paste(CNodeObject *pClone) { // This is where a file merge should happen to update the values (e.g. names, new note files etc) return 0; } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFile ////////////////////////////////////////////////////////////////////// CNodeDisk *CNodeDataValueFile::SetNodeDisk(CNodeDisk *pDisk) { CNodeDisk *pOld = m_pNodeDisk; m_pNodeDisk = pDisk; return pOld; } CNodeDataValueFile::CNodeDataValueFile(CNodeObject *pParent,CString strFileName,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValue(pParent,strFileName,NULL,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEFILE; m_pNodeDisk = NULL; m_iParentDirs = 0; if (pClone) { //strFileName.MakeLower(); CString name1; GetName(name1); //name1.MakeLower(); //if (strFileName != name1) if (stricmp(strFileName,name1)) { // Then this is a node where the file that loaded it needs to be updated // Find the file node that is the parent of this node, and mark it's disk as dirty CNodeObject *pFileParent = pParent; while (pFileParent && !pFileParent->IsFile()) { pFileParent = pFileParent->GetParentNode(); } if (pFileParent) { CNodeDataValueFile *pNode = (CNodeDataValueFile *)pFileParent; pNode->GetNodeDisk()->m_bDirty = true; } } } // Get the name in case we did some clone renaming here GetName(strFileName); //Store the extra data in the name, store the number of parent dirs specified in m_iParentDirs { delete m_szName; m_szName = NULL; CString extra; int i = strFileName.ReverseFind(','); if (i>0) { extra = strFileName.Right(strFileName.GetLength()-i+1); m_szName = strdup(extra); strFileName = strFileName.Left(i); } } // Load the notefile /*int i = strFileName.ReverseFind(','); if (i>0) { strFileName = strFileName.Left(i); }*/ CNodeDisk *pDisk = NULL; CNodeDataValueFileDoc *pDoc = NULL; { CNodeObject *pRoot = pParent; while (pRoot && pRoot->GetClassID() != CLASS_CNODEDATAVALUEFILEPROJECT) pRoot = pRoot->GetParentNode(); if (pRoot) pDoc = ((CNodeDataValueFileProject *)pRoot)->GetDocument(); if (pDoc) { CString strRoot = pDoc->GetRootDir()+"\\content\\"; if (0 == strnicmp(strFileName,strRoot,strRoot.GetLength())) strFileName.Delete(0,strRoot.GetLength()); } } bool bReplace = false; bool bMerge = false; if (pClone) { // This is a node created from the Clone's parameters // If the file already exists, replace or merge? // MERGE (Because pClone is passed up as NULL, as a result the notation file is not updated) CNodeDataValueFile *pFileClone = (CNodeDataValueFile *)pClone; CNodeDisk *pDiskClone = pFileClone->GetNodeDisk(); // Only replace if the source (pClone) disk is marked as "Copy-Able" - this is to avoid accidental overwrites if (pDiskClone->GetVisit(VISIT_FLAG1)) bReplace = true; pDisk = pDoc->FindDirectoryNode(strFileName); /* if (NULL == pDisk) { CString strPath = pDiskClone->GetPath(); pDisk = pDoc->FindDirectoryNode(strPath); }*/ if (pDisk) { // Have we already copied this node? if (pDisk->GetVisit(VISIT_FLAG1)) { bReplace = false; } else { // TODO: File already exists, merge if it a notefile /* if (CLASS_CNODEDATAVALUEFILENOTE == pClone->GetClassID()) { if (pDoc->m_iReplaceAll>=0) { if (pDoc->m_iReplaceAll) bMerge = true; else bMerge = false; } else { CString str = strFileName+" already exists. Merge All?"; bReplace = (IDYES == MessageBox(NULL,str,"File Paste",MB_YESNO)); } if (bMerge) { pDoc->m_iReplaceAll = 1; } else { pDoc->m_iReplaceAll = 0; } } else*/ if (bReplace) { if (pDoc->m_iReplaceAll>=0) { if (pDoc->m_iReplaceAll) bReplace = true; else bReplace = false; } else { CString str = strFileName+" already exists. Replace All?"; bReplace = (IDYES == MessageBox(NULL,str,"File Paste",MB_YESNO)); } // if so, delete the old file if (bReplace) { pDoc->m_iReplaceAll = 1; CNodeObject *pDiskParent = pDisk->GetParentNode(); POSITION fpos=NULL,pos = pDiskParent->GetFirstChild(); while (pos) { fpos = pos; CNodeObject *pChild = pDiskParent->GetNextChild(pos); if (pChild == pDisk) { pos = NULL; break; } } CNodeObject *pObj = pDiskParent->RemoveChild(fpos); pDisk = NULL; } else { pDoc->m_iReplaceAll = 0; } } } } if (bReplace&&!bMerge) { CNodeDataValueFile *pFileClone = (CNodeDataValueFile *)pClone; CString srcFile = pClone->GetRootPath()+"\\"+pDiskClone->GetPath(); CString dstFile = pDiskClone->GetPath(); if (strnicmp(dstFile,"content",7)==0) dstFile.Delete(0,7); //oldName.MakeLower(); //newName.MakeLower(); //dstFile.MakeLower(); int rcount; // = dstFile.Replace(oldName,newName); CString output = ReplaceNoCase(dstFile,oldName,newName,&rcount); if (rcount) { int x=1; } dstFile = output; // Create the file pDisk = pDoc->GetRootNode()->DiskCopyFile(srcFile,dstFile); } //Verify(NULL != pDisk); // pDisk is null here iff the source file does not exist in the destination but the source file is not // marked as a copy-able file if (NULL == pDisk) pDisk = new CNodeDiskFile(this,strFileName); pDisk->SetVisit(VISIT_FLAG1); Paste(pClone); } if (!pDisk) { while (pParent && !pParent->IsFile()) pParent = pParent->GetParentNode(); bool bFound = false; if (pParent) { CNodeDataValueFile *pFile = (CNodeDataValueFile *)pParent; CNodeDisk *pDiskPath = pFile->GetNodeDisk(); do { CString strPath = pDiskPath->GetDirectory()+"\\"+strFileName; if (strPath[0] == '\\') strPath.Delete(0,1); pDisk = pDoc->FindDirectoryNode(strPath); if (pDisk) { // Count the number of subdirs specified in strFileName int count = 0; int result = -1; while ((result = strFileName.Find('\\',result+1))>=0) count++; this->m_iParentDirs = count; strFileName = strPath; bFound = true; break; } pDiskPath = (CNodeDisk *)pDiskPath->GetParentNode(); } while (pDiskPath); } if (!bFound) { if (!gos_DoesFileExist(strFileName)) { int x=1; //char dir[MAX_PATH]; //GetCurrentDirectory(MAX_PATH,dir); //CString str; //GetName(str); // Note: Not Found should not be actually in the name here //SetName(CString("(Not Found) ")+str); // return; } else { int x=1; // We are adding a file that is not in contents folder pDisk = m_pNodeDisk = new CNodeDisk(this,strFileName,true); } } } if (pDisk) { if (!pDisk->IsLoaded()) { CMainFrame *pFrame = (CMainFrame*)AfxGetMainWnd(); pFrame->SetMessageText(strFileName); } m_pNodeDisk = pDisk; pDisk->AddRef(this); } if (NULL == m_pNodeDisk) { // We didn't find this file m_pNodeDisk = new CNodeDisk(this,strFileName); m_pNodeDisk->AddRef(this); } if (pClone) { // Cloning of this node NOT already handled by superclass // This is so that if it is already loaded, duplicate structures aren't made, but referenced by nodedisk if (!m_pNodeDisk->IsLoaded()) { POSITION pos = pClone->GetFirstChild(); while (pos) { CNodeObject *pChild = pClone->GetNextChild(pos); CNodeObject *pCloneChild = pChild->Clone(this,oldName,newName); m_pNodeDisk->AddChild(pCloneChild); } m_pNodeDisk->SetLoaded(); } else { if (bMerge) { // We have to merge because the file already exists POSITION posClone = pClone->GetFirstChild(); /*while (posClone) { CNodeObject *pChild = pClone->GetNextChild(posClone); CNodeObject *pCloneChild = pChild->Clone(this,oldName,newName); //m_pNodeDisk->AddChild(pCloneChild); // This is the same code from Entry::Update to re-load a node POSITION pos1,pos = this->GetFirstChild(); pos1 = pos; while (pos) { // Find the duplicate node in the existing node to the clone node CNodeDataValue *pNode = (CNodeDataValue *)this->GetNextChild(pos); CString name1 = pCloneChild->GetName(); CString name2 = pNode->GetName(); name1.MakeLower(); name2.MakeLower(); if (name1 == name2) { CString str = pNode->GetName(); // Copy to a temp map CMapPtrToPtr map; POSITION pos2 = pNode->m_mapViewHandles.GetStartPosition(); while (pos2) { HANDLE key; HANDLE value; pNode->m_mapViewHandles.GetNextAssoc(pos2,key,value); map[key] = value; } CNodeObject *pObj = RemoveChild(pos1); //pNode = CreateChild(this,(int)value,str); // Copy back to new map to the clone pos2 = map.GetStartPosition(); while (pos2) { HANDLE key; HANDLE value; map.GetNextAssoc(pos2,key,value); pCloneChild->m_mapViewHandles[key] = value; } m_pNodeDisk->AddChild(pCloneChild); m_pNodeDisk->m_bDirty = true; } pos1 = pos; } }*/ } } } if (m_pNodeDisk->IsLoaded()) { POSITION pos = m_pNodeDisk->GetFirstChild(); while (pos) { // Already Loaded - Be sure that subclass checks for that it is loaded before it adds children CNodeObject *pChild = m_pNodeDisk->GetNextChild(pos); AddChild(pChild); // Might need to update this notation file if (m_pNodeDisk->m_bDirty) { // This child will need to be updated by the subclass constructor // TODO: This file is either an ERF or notation file (most likely) // pChild->m_bDirty = true; // The child may or may not be Visited (if it's children are dirty, then it will probably be dirty too int x=1; } } } } CNodeDataValueFile::~CNodeDataValueFile() { if (m_pNodeDisk) { CNodeObject *pObj = m_pNodeDisk->RemoveRef(this); } m_pNodeDisk = NULL; } int CNodeDataValueFile::UpdateSelf(CNodeObject *pChild) { Verify(false); // Not Implemented return 0; } int CNodeDataValueFile::GetName(CString &str) { return CNodeDataValue::GetName(str); } int CNodeDataValueFile::GetName(char *buf,int buflen) { CString extra; if (m_szName) extra = m_szName; CNodeObject *pDisk = GetNodeDisk(); CString path; if (pDisk) { pDisk->GetName(path); pDisk = pDisk->GetParentNode(); int count = m_iParentDirs; while (count && pDisk) { CString dir; pDisk->GetName(dir); count--; pDisk = pDisk->GetParentNode(); //path += ((count && pDisk)?"\\":"")+dir; path = dir+"\\"+path; } } path += extra; strncpy(buf,path,buflen); return path.GetLength(); } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFloat ////////////////////////////////////////////////////////////////////// CNodeDataValueFloat::CNodeDataValueFloat(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValue(pParent,value,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEFLOAT; m_iKeyType = KEYTYPE_FLOAT; } CNodeDataValueFloat::~CNodeDataValueFloat() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValuePoint3 ////////////////////////////////////////////////////////////////////// CNodeDataValuePoint3::CNodeDataValuePoint3(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValue(pParent,value,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEPOINT3; m_iKeyType = KEYTYPE_POINT3; } CNodeDataValuePoint3::~CNodeDataValuePoint3() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueBool ////////////////////////////////////////////////////////////////////// CNodeDataValueBool::CNodeDataValueBool(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValue(pParent,value,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEBOOL; m_iKeyType = KEYTYPE_BOOL; } CNodeDataValueBool::~CNodeDataValueBool() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueString ////////////////////////////////////////////////////////////////////// CNodeDataValueString::CNodeDataValueString(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValue(pParent,value,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUESTRING; m_iKeyType = KEYTYPE_STRING; } CNodeDataValueString::~CNodeDataValueString() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueInt ////////////////////////////////////////////////////////////////////// CNodeDataValueInt::CNodeDataValueInt(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValue(pParent,value,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEINT; m_iKeyType = KEYTYPE_INT; } CNodeDataValueInt::~CNodeDataValueInt() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueCompostTexture ////////////////////////////////////////////////////////////////////// CNodeDataValueCompostTexture::CNodeDataValueCompostTexture(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValue(pParent,value,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUECOMPOSTTEXTURE; m_iKeyType = KEYTYPE_COMPOSTTEXTURE; CNodeObject *pChild1 = CreateChild(this,KEYTYPE_TGA,value); AddChild(pChild1); CNodeObject *pChild2 = CreateChild(this,KEYTYPE_BID,value); AddChild(pChild2); } CNodeDataValueCompostTexture::~CNodeDataValueCompostTexture() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileProject // Notes: Disk File is a directory, this directory is the // working directory for the project // Project cannot be a child of any other node (must be root) ////////////////////////////////////////////////////////////////////// CNodeDataValueFileProject::CNodeDataValueFileProject(CNodeDataValueFileDoc *pDoc,CString name) : CNodeDataValueFile(NULL,name) { m_iKeyType = KEYTYPE_PROJECT; m_iClassID = CLASS_CNODEDATAVALUEFILEPROJECT; m_pDoc = pDoc; } CNodeDataValueFileProject::~CNodeDataValueFileProject() { } int CNodeDataValueFileProject::UpdateSelf(CNodeObject *pChild) { Verify(false); // Not Implemented return 0; } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileERF ////////////////////////////////////////////////////////////////////// // Dont clone erf data, reload the erf, change the names along the way, and save back out CNodeDataValueFileERF::CNodeDataValueFileERF(CNodeObject *pParent,CString path,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,path,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEFILEERF; m_iKeyType = KEYTYPE_ERF; ElementRenderer::GroupElement *pScene = NULL; CNodeDisk *pDisk = GetNodeDisk(); // ElementRenderer::GroupElement *ErfElement=NULL; ElementRenderer::Element *ErfElement=NULL; // Check that this is not already loaded if (pDisk) { CString fname = GetRootPath()+"\\"+pDisk->GetPath(); //if (pClone&&pDisk->m_bDirty) if (pDisk->m_bDirty) { // Gonna need to re-save this erf! // Delete all of the children of this ERF POSITION pos; pos = GetFirstChild(); POSITION pos1 = pos; while (pos) { CNodeObject *pNode = GetNextChild(pos); RemoveChild(pos1); pos1 = pos; } pos1 = pos = pDisk->GetFirstChild(); while (pos) { CNodeObject *pNode = pDisk->GetNextChild(pos); pDisk->RemoveChild(pos1); pos1 = pos; } DWORD attrib = ::GetFileAttributes(fname); if (-1 != attrib) { if (attrib & FILE_ATTRIBUTE_READONLY) { attrib &= ~FILE_ATTRIBUTE_READONLY; ::SetFileAttributes(fname,attrib); } } // The children will remove all references to it automatically, including the disk // But the disk file node will still remain because it has a parent directory // So Don't remove the reference to the disk file, it should even have the correct name // Then Load the ERF it again, but pass in oldName and newName to CNodeDataValueERF::CreateChild // So that texture names will get changed. // Then save the ERF to a .temp name, close the streams, copy the temp erf over the old one, and delete the temp } // VERY IMPORTANT: erf_file must be open to write out temp_erf_file a file (according to JM) CString tempname = fname+".temp"; if (pDisk->IsFound()) { CPtrList elemList; elemList.RemoveAll(); Stuff::FileStream erf_file; Stuff::FileStream temp_erf_file; erf_file.Open(fname); //erf_file.IgnoreReadOnly(true); //erf_file.Open(fname,Stuff::FileStream::WriteOnly); //if (!pDisk->IsLoaded() || (pClone &&pDisk->m_bDirty)) if (!pDisk->IsLoaded() || (pDisk->m_bDirty)) { pScene = new ElementRenderer::GroupElement; Check_Object(pScene); pScene->SetRootMode(); pScene->LockBounds(); int version = ElementRenderer::ReadERFVersion(&erf_file); while(erf_file.GetBytesRemaining() > 0) { ErfElement = ElementRenderer::Element::Create( &erf_file, version // ElementRenderer::ReadERFVersion(&erf_file) ); // ErfElement = Cast_Object( // ElementRenderer::GroupElement*, // ElementRenderer::Element::Create( // &erf_file, // ElementRenderer::ReadERFVersion(&erf_file) // )); elemList.AddTail(ErfElement); ErfElement->LockBounds(); pScene->AttachChild(ErfElement); ErfElement->ClearAlignX(); ErfElement->SetNeverCullMode(); ErfElement->SetLocalToParent(Stuff::LinearMatrix4D::Identity); // this should also change the texture names if necessary CNodeDataValueERF *pChild = CNodeDataValueERF::CreateChild(this,ErfElement,oldName,newName); //erf_file.Close(); AddChild(pChild); pDisk->AddChild(pChild); } pScene->Sync(); } pDisk->SetLoaded(); if (pClone) { if (pDisk->m_bDirty) { temp_erf_file.Open(tempname,Stuff::FileStream::WriteOnly); // ErfElement->SetRootMode(); ElementRenderer::WriteERFVersion(&temp_erf_file); // ErfElement->Save(&temp_erf_file); // ErfElement->SetVolumeCullMode(); // ErfElement->Sync(); // loop through the scene and write out the children POSITION pos = elemList.GetHeadPosition(); while (pos && ((ErfElement = Cast_Object( ElementRenderer::Element*, elemList.GetNext(pos))) != NULL)) { ErfElement->Save(&temp_erf_file); } //erf_file.Close(); } } // Clean up. We don't need the scene anymore if (pScene) { Check_Object(pScene); delete pScene; } pScene = NULL; } if (pClone&&pDisk->m_bDirty) { ::CopyFile(tempname,fname,false); ::DeleteFile(tempname); } } } CNodeDataValueFileERF::~CNodeDataValueFileERF() { } int CNodeDataValueFileERF::UpdateSelf(CNodeObject *pChild) { Verify(false); // Not Implemented return 0; } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileWAV ////////////////////////////////////////////////////////////////////// CNodeDataValueFileWAV::CNodeDataValueFileWAV(CNodeObject *pParent,CString path,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,path,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEFILEWAV; m_iKeyType = KEYTYPE_WAV; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) pDisk->SetLoaded(); } CNodeDataValueFileWAV::~CNodeDataValueFileWAV() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileMW4ANIM ////////////////////////////////////////////////////////////////////// CNodeDataValueFileMW4ANIM::CNodeDataValueFileMW4ANIM(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,pClone?pClone->GetNameStr():value+".mw4anim",pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEFILEMW4ANIM; m_iKeyType = KEYTYPE_MW4ANIM; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) pDisk->SetLoaded(); } CNodeDataValueFileMW4ANIM::~CNodeDataValueFileMW4ANIM() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileTGA ////////////////////////////////////////////////////////////////////// CString CNodeDataValueFileTGA::GetTexturePath() { Stuff::MString name; MidLevelRenderer::MLRTexturePool::Instance->GetGOSImagePool()->GetTexturePath(&name); CString strName = (char *)name; strName.Delete(0,1); return strName; } CString CNodeDataValueFileTGA::FixName(CString value,CNodeObject *pClone) { CString str; // pClone?pClone->GetNameStr():value+((strnicmp(value.Right(4),".tga",4)==0)?"":".tga") if (pClone) { str = pClone->GetNameStr(); } else { str = value; } if (strnicmp(str.Right(4),".tga",4)) str+=".tga"; /* CString tex = GetTexturePath(); if (strnicmp(str,tex,tex.GetLength())) { str = tex+"\\"+str; } */ return str; } CNodeDataValueFileTGA::CNodeDataValueFileTGA(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,FixName(value,pClone),pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEFILETGA; m_iKeyType = KEYTYPE_TGA; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) { if (pDisk->IsFound()) { pDisk->SetLoaded(); } else { CNodeObject *pRoot = pParent; CNodeDataValueFileDoc *pDoc = NULL; while (pRoot && pRoot->GetClassID() != CLASS_CNODEDATAVALUEFILEPROJECT) pRoot = pRoot->GetParentNode(); if (pRoot) pDoc = ((CNodeDataValueFileProject *)pRoot)->GetDocument(); CString strFileName; pDisk->GetName(strFileName); strFileName = GetTexturePath()+"\\"+strFileName; CNodeDisk *pNewDisk = pDoc->FindDirectoryNode(strFileName); if (pNewDisk) { pDisk = (CNodeDisk *)pDisk->RemoveRef(this); pNewDisk->AddRef(this); pNewDisk->SetLoaded(); SetNodeDisk(pNewDisk); } } } int rcount;// = value.Replace(oldName,newName); CString output = ReplaceNoCase(value,oldName,newName,&rcount); if (rcount) { int x=1; } } CNodeDataValueFileTGA::~CNodeDataValueFileTGA() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFilePNG ////////////////////////////////////////////////////////////////////// CString CNodeDataValueFilePNG::GetTexturePath() { Stuff::MString name; MidLevelRenderer::MLRTexturePool::Instance->GetGOSImagePool()->GetTexturePath(&name); CString strName = (char *)name; strName.Delete(0,1); return strName; } CString CNodeDataValueFilePNG::FixName(CString value,CNodeObject *pClone) { CString str; // pClone?pClone->GetNameStr():value+((strnicmp(value.Right(4),".png",4)==0)?"":".png") if (pClone) { str = pClone->GetNameStr(); } else { str = value; } if (strnicmp(str.Right(4),".png",4)) str+=".png"; /* CString tex = GetTexturePath(); if (strnicmp(str,tex,tex.GetLength())) { str = tex+"\\"+str; } */ return str; } CNodeDataValueFilePNG::CNodeDataValueFilePNG(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,FixName(value,pClone),pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEFILEPNG; m_iKeyType = KEYTYPE_PNG; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) { if (pDisk->IsFound()) { pDisk->SetLoaded(); } else { CNodeObject *pRoot = pParent; CNodeDataValueFileDoc *pDoc = NULL; while (pRoot && pRoot->GetClassID() != CLASS_CNODEDATAVALUEFILEPROJECT) pRoot = pRoot->GetParentNode(); if (pRoot) pDoc = ((CNodeDataValueFileProject *)pRoot)->GetDocument(); CString strFileName; pDisk->GetName(strFileName); strFileName = GetTexturePath()+"\\"+strFileName; CNodeDisk *pNewDisk = pDoc->FindDirectoryNode(strFileName); if (pNewDisk) { pDisk = (CNodeDisk *)pDisk->RemoveRef(this); pNewDisk->AddRef(this); pNewDisk->SetLoaded(); SetNodeDisk(pNewDisk); } } } int rcount;// = value.Replace(oldName,newName); CString output = ReplaceNoCase(value,oldName,newName,&rcount); if (rcount) { int x=1; } } CNodeDataValueFilePNG::~CNodeDataValueFilePNG() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileNote ////////////////////////////////////////////////////////////////////// CNodeDataValueFileNote::CNodeDataValueFileNote(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,value,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEFILENOTE; m_iKeyType = KEYTYPE_NOTE; CStringList listPageName,listPageEntry,listPageValue; CStringList listDep; CPtrList listPageNum; listPageName.RemoveAll(); listPageEntry.RemoveAll(); listPageValue.RemoveAll(); listDep.RemoveAll(); listPageNum.RemoveAll(); CNodeObject *pNodeDep = NULL; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk && !pDisk->IsLoaded() && pDisk->IsFound()) { // If this file was found, it may be loaded already // Check that this file isn't already loaded // First time, not loaded CString strRoot = GetRootPath()+"\\"; CString strFileName = strRoot+pDisk->GetPath(); NotationFile notefile(strFileName); NotationFile::PageIterator *pages = notefile.MakePageIterator(); Check_Object(pages); DWORD pagenum = 0; Page *page; while((page = pages->ReadAndNext()) != NULL) { Check_Object(page); Page::NoteIterator *notes = page->MakeNoteIterator(); Check_Object(notes); Note *note; while (note = notes->ReadAndNext()) { const char *value; listPageName.AddTail(page->GetName()); listPageEntry.AddTail(note->GetName()); note->GetEntry(&value); listPageValue.AddTail(value); listPageNum.AddTail((LPVOID)pagenum); } delete notes; pagenum++; #if 0 CNodeDataPage *pChild = new CNodeDataPage(this,page,"","",""); CMainFrame *pFrame = (CMainFrame*)AfxGetMainWnd(); pFrame->SetMessageText(value); AddChild(pChild); pDisk->AddChild(pChild); #endif } Check_Object(pages); delete pages; // Load the dependencies pNodeDep = new CNodeObject(this,"Dependencies"); AddChild(pNodeDep); pDisk->AddChild(pNodeDep); FileDependencies dep(*notefile.GetFileDependencies()); int length = dep.m_fileNameStream.GetBytesUsed(); BYTE *data = static_cast(dep.m_fileNameStream.GetPointer()) - length; while (length) { CString str = CString(data); int len = str.GetLength()+1; data += len; length -= len; CString str1 = this->GetRootPath()+"\\"+pDisk->GetPath(); if (strnicmp(str1,str,(len-1))) { listDep.AddTail(str); #if 0 CNodeObject *pChild = this->CreateChild(pNodeDep,KEYTYPE_NOTE,str); pNodeDep->AddChild(pChild); #endif } } if (pDisk) pDisk->SetLoaded(); } if (listPageName.GetCount()) { DWORD pagenum = 0; CNodeDataPage *pChild = NULL; /* int count = listPageName.GetCount(); for (int index = 0;indexAddChild(pChild); pagenum = newpage; } else { CNodeDataEntry *pEntry= new CNodeDataEntry(pChild,NULL,entry,value); pChild->AddChild(pEntry); } }*/ POSITION namepos = listPageName.GetTailPosition(); POSITION entrypos = listPageEntry.GetTailPosition(); POSITION valuepos = listPageValue.GetTailPosition(); POSITION numpos = listPageNum.GetTailPosition(); while (namepos) { CString page = listPageName.GetPrev(namepos); CString entry = listPageEntry.GetPrev(entrypos); CString value = listPageValue.GetPrev(valuepos); DWORD newpage = (DWORD)listPageNum.GetPrev(numpos); if ((newpage != pagenum) || (NULL == pChild)) { pChild = new CNodeDataPage(this,NULL,page,entry,value); AddChild(pChild); pDisk->AddChild(pChild); pagenum = newpage; } else { CNodeDataEntry *pEntry= new CNodeDataEntry(pChild,NULL,entry,value); pChild->AddChild(pEntry); } } } if (pNodeDep) { POSITION pos = listDep.GetHeadPosition(); while (pos) { CString str = listDep.GetNext(pos); CNodeObject *pChild = this->CreateChild(pNodeDep,KEYTYPE_NOTE,str); pNodeDep->AddChild(pChild); } } if (pClone) { // If the disk node is dirty, then the dirty children need to be updated if (pDisk->IsFound() && pDisk->m_bDirty) { CString strRoot = GetRootPath()+"\\"; CString strFileName = strRoot+pDisk->GetPath(); DWORD attrib = ::GetFileAttributes(strFileName); if (attrib & FILE_ATTRIBUTE_READONLY) { attrib &= ~FILE_ATTRIBUTE_READONLY; ::SetFileAttributes(strFileName,attrib); } //****** Gonna have to write the whole file over again because we didnt' keep the old page name so // don't know which page to rename if the page name changed // Note: Write stuff the pages in reverse order to restore to original order NotationFile notefile; pDisk->m_bDirty = false; POSITION pos = GetFirstChild(); while (pos) { CNodeObject *pPage = GetNextChild(pos); if (pPage->GetClassID() == CLASS_CNODEDATAPAGE) { CString str; pPage->GetName(str); Page *page = notefile.AddPage(str); // Get first here because the entry are appended in the page POSITION posentry = pPage->GetFirstChild(); while (posentry) { CNodeObject *pEntry = pPage->GetNextChild(posentry); // First or last here, doesn't matter because each entry should have only one value POSITION posvalue = pEntry->GetFirstChild(); while (posvalue) { CNodeObject *pValue = pEntry->GetNextChild(posvalue); CString str; pValue->GetName(str); CString str1; pEntry->GetName(str1); page->AppendEntry(str1,str); } } } } notefile.SaveAs(strFileName); } // Update the file by calling virual function this->UpdateSelf() // UpdateSelf(pChild); // m_pNodeDisk->m_bDirty = false; // Don't run this for now - m_bDirty maybe true if this node is renamed // TODO: Merge /* if (pDisk->m_bDirty) { // This node was merged during the cloning process, and now the file needs to be updated CString strFileName = pDisk->GetPath(); NotationFile notefile(strFileName); if (notefile.IsEmpty()) { // This should not happen // assert(false); return; } // make sure all of the children of the pNodeDisk are there POSITION pos = pDisk->GetFirstChild(); while (pos) { CNodeObject *pChild = pDisk->GetNextChild(pos); switch (pChild->GetClassID()) { case CLASS_CNODEDATAPAGE: { CNodeDataPage *pPage = (CNodeDataPage *)pChild; Page *page = notefile.SetPage(pPage->GetName()); POSITION posEntry = pPage->GetFirstChild(); while (posEntry) { CNodeDataEntry *pEntry = (CNodeDataEntry *)pPage->GetNextChild(posEntry); POSITION posValue = pEntry->GetFirstChild(); while (posValue) { CNodeObject *pValue = pEntry->GetNextChild(posValue); // Update/Add pPage,pEntry,pValue in the notefile page->SetEntry(pEntry->GetName(),pValue->GetName()); } } break; } case CLASS_CNODEOBJECT: { // Child is a dependency, these are the !INCLUDE parameters POSITION posValue = pChild->GetFirstChild(); while (posValue) { CNodeObject *pValue = pChild->GetNextChild(posValue); CString strName = pValue->GetName(); // don't Save a !Include as the pValue file because this should already be there } break; } default: { Verify(false); } } } notefile.Save(); }*/ } } CNodeDataValueFileNote::~CNodeDataValueFileNote() { } int CNodeDataValueFileNote::UpdateSelf(CNodeObject *pChild) { Verify(false); // Not Implemented return 0; } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileBSP ////////////////////////////////////////////////////////////////////// CNodeDataValueFileBSP::CNodeDataValueFileBSP(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,pClone?pClone->GetNameStr():value+((strnicmp(value.Right(4),".bsp",4)==0)?"":".bsp"),pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEFILEBSP; m_iKeyType = KEYTYPE_BSP; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) pDisk->SetLoaded(); } CNodeDataValueFileBSP::~CNodeDataValueFileBSP() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileOBB ////////////////////////////////////////////////////////////////////// CNodeDataValueFileOBB::CNodeDataValueFileOBB(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,value,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEFILEOBB; m_iKeyType = KEYTYPE_OBB; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) pDisk->SetLoaded(); } CNodeDataValueFileOBB::~CNodeDataValueFileOBB() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileABL ////////////////////////////////////////////////////////////////////// CNodeDataValueFileABL::CNodeDataValueFileABL(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,value,pClone,oldName,newName) { m_iKeyType = KEYTYPE_ABL; m_iClassID = CLASS_CNODEDATAVALUEFILEABL; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) pDisk->SetLoaded(); } CNodeDataValueFileABL::~CNodeDataValueFileABL() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileFGD ////////////////////////////////////////////////////////////////////// CString CNodeDataValueFileFGD::FixName(CString str) { if (strnicmp(str.Right(4),".fgd",4)) str += ".fgd"; return str; } CNodeDataValueFileFGD::CNodeDataValueFileFGD(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,FixName(value),pClone,oldName,newName) { m_iKeyType = KEYTYPE_FGD; m_iClassID = CLASS_CNODEDATAVALUEFILEFGD; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) pDisk->SetLoaded(); } CNodeDataValueFileFGD::~CNodeDataValueFileFGD() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileMATERIAL ////////////////////////////////////////////////////////////////////// CNodeDataValueFileMATERIAL::CNodeDataValueFileMATERIAL(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,pClone?pClone->GetNameStr():value+((strnicmp(value.Right(9),".material",9)==0)?"":".material"),pClone,oldName,newName) { m_iKeyType = KEYTYPE_MATERIAL; m_iClassID = CLASS_CNODEDATAVALUEFILEMATERIAL; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) pDisk->SetLoaded(); } CNodeDataValueFileMATERIAL::~CNodeDataValueFileMATERIAL() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileRAW ////////////////////////////////////////////////////////////////////// CNodeDataValueFileRAW::CNodeDataValueFileRAW(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,pClone?pClone->GetNameStr():value+((strnicmp(value.Right(4),".raw",4)==0)?"":".raw"),pClone,oldName,newName) { m_iKeyType = KEYTYPE_RAW; m_iClassID = CLASS_CNODEDATAVALUEFILERAW; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) pDisk->SetLoaded(); } CNodeDataValueFileRAW::~CNodeDataValueFileRAW() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileRAW ////////////////////////////////////////////////////////////////////// CNodeDataValueFileBID::CNodeDataValueFileBID(CNodeObject *pParent,CString value,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueFile(pParent,pClone?pClone->GetNameStr():value+((strnicmp(value.Right(4),".bid",4)==0)?"":".bid"),pClone,oldName,newName) { m_iKeyType = KEYTYPE_BID; m_iClassID = CLASS_CNODEDATAVALUEFILEBID; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) pDisk->SetLoaded(); } CNodeDataValueFileBID::~CNodeDataValueFileBID() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueFileResource ////////////////////////////////////////////////////////////////////// extern int IdentifyFileType(CString path); CNodeDataValueFileResource::CNodeDataValueFileResource(CNodeObject *pParent,CString value) : CNodeDataValueFile(pParent,value) { m_iKeyType = KEYTYPE_RESOURCE; m_iClassID = CLASS_CNODEDATAVALUEFILERESOURCE; CStringList nameList; CNodeDisk *pDisk = GetNodeDisk(); if (pDisk) { CMainFrame *pFrame = (CMainFrame*)AfxGetMainWnd(); pFrame->SetMessageText("Loading Resources: "+pDisk->GetPath()); Check_Object(ResourceManager::Instance); ResourceFile *pResourceFile = ResourceManager::Instance->OpenResourceFile( pDisk->GetPath(), 0, VER_CONTENTVERSION, true, true, false ); Check_Object(pResourceFile); // pResourceFile->First(); Resource res; res.First(pResourceFile); while (res.ReadAndNext()) { CNodeObject *pNode = NULL; int iKeyType = KEYTYPE_UNKNOWN; CString name = CString("Content\\")+res.GetName(); int index = name.Find('{'); if (index>=0) { // We have the Entry name CString entryname = name.Right(name.GetLength()-index-1); name = name.Left(index); int index1 = entryname.Find('}'); // This should exist assert(index1>=0); entryname = entryname.Left(index1); int pageindex = name.Find('['); if (pageindex>=0) { CString pagename = name.Right(name.GetLength()-pageindex-1); name = name.Left(pageindex); index1 = pagename.Find(']'); // This should exist assert(index1>=0); pagename = pagename.Left(index1); pNode = new CNodeDataPage(this,NULL,pagename,entryname,name); } else pNode = new CNodeDataEntry(this,NULL,entryname,name); AddChild(pNode); pDisk->AddChild(pNode); } else { index = name.Find('['); if (index>=0) { name = name.Left(index); } nameList.AddHead(name); } } pDisk->SetLoaded(); } POSITION pos = nameList.GetHeadPosition(); while (pos) { CNodeObject *pNode = NULL; int iKeyType = KEYTYPE_UNKNOWN; CString str = nameList.GetNext(pos); if (KEYTYPE_UNKNOWN == iKeyType) iKeyType = IdentifyFileType(str); pNode = CreateChild(this,iKeyType,str); AddChild(pNode); pDisk->AddChild(pNode); } } CNodeDataValueFileResource::~CNodeDataValueFileResource() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueERF ////////////////////////////////////////////////////////////////////// CNodeDataValueERF *CNodeDataValueERF::CreateChild(CNodeObject *pParent,ElementRenderer::Element *pElement,CString oldName,CString newName) { if(pElement->GetClassID()== ElementRenderer::CameraElementClassID) { return NULL; } CNodeDataValueERF *pChild = NULL; switch(pElement->GetClassID()) { /* case ElementRenderer::FXElementClassID: { } break; */ case ElementRenderer::GroupElementClassID: { ElementRenderer::GroupElement *group = Cast_Pointer(ElementRenderer::GroupElement *, pElement); pChild = new CNodeDataValueERFGroupElement(pParent,group,NULL,oldName,newName); } break; case ElementRenderer::ListElementClassID: { ElementRenderer::ListElement *group = Cast_Pointer(ElementRenderer::ListElement *, pElement); pChild = new CNodeDataValueERFListElement(pParent,group,NULL,oldName,newName); } break; case ElementRenderer::GridElementClassID: { ElementRenderer::GridElement *group = Cast_Pointer(ElementRenderer::GridElement *, pElement); pChild = new CNodeDataValueERFGridElement(pParent,group,NULL,oldName,newName); } break; case ElementRenderer::LODElementClassID: { ElementRenderer::ListElement *group = Cast_Pointer(ElementRenderer::ListElement *, pElement); pChild = new CNodeDataValueERFLODElement(pParent,group,NULL,oldName,newName); } break; /* case ElementRenderer::ShapeLODElementClassID: { ElementRenderer::ListElement *group = Cast_Pointer(ElementRenderer::ListElement *, pElement); pChild = new CNodeDataValueERFShapeLODElement(pParent,group,NULL,oldName,newName); } break; */ case ElementRenderer::PointCloudElementClassID: { } break; case ElementRenderer::ScalableShapeElementClassID: case ElementRenderer::ShapeElementClassID: { ElementRenderer::ShapeElement *group = Cast_Pointer(ElementRenderer::ShapeElement *, pElement); pChild = new CNodeDataValueERFShapeElement(pParent,group,NULL,oldName,newName); } break; case ElementRenderer::ScreenQuadsElementClassID: { } break; case ElementRenderer::SwitchElementClassID: { ElementRenderer::ListElement *group = Cast_Pointer(ElementRenderer::ListElement *, pElement); pChild = new CNodeDataValueERFListElement(pParent,group,NULL,oldName,newName); } break; case ElementRenderer::TriangleCloudElementClassID: { Verify(false); } break; case ElementRenderer::MultiLODElementClassID: { ElementRenderer::MultiLODElement *group = Cast_Pointer(ElementRenderer::MultiLODElement *, pElement); assert(false); for(int i=0;iGetActiveCount();i++) { // AddErfBranch(tmpitm,group->GetIndexedElement(i)); } } break; case ElementRenderer::ShapeLODElementClassID: { ElementRenderer::ShapeLODElement *group = Cast_Pointer(ElementRenderer::ShapeLODElement *, pElement); pChild = new CNodeDataValueERFShapeLODElement(pParent,group,NULL,oldName,newName); } break; } return pChild; } // either pElement or pClone must be valid CNodeDataValueERF::CNodeDataValueERF(CNodeObject *pParent,ElementRenderer::Element *pElement,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValue(pParent,pClone?pClone->GetNameStr():CString(pElement->GetClassData()->GetClassName()),pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEERF; m_pElement = pElement; if (pClone) { CNodeDataValueERF *pErf = (CNodeDataValueERF *)pClone; m_pElement = pErf->GetElement(); return; } ElementRenderer::StateChange *pState = pElement->GetStateChange(); if (pState) { MidLevelRenderer::MLRState state = pState->GetMLRState(); MidLevelRenderer::MLRTexture *tex = NULL; if (MidLevelRenderer::MLRTexturePool::Instance && (state.GetTextureHandle() < MidLevelRenderer::Limits::Max_Number_Textures * (1<GetInstanceDepth())) ) { if(state.GetTextureHandle()) { CString strName; char name1[MAX_PATH]; _splitpath(strName,NULL,NULL,name1,NULL); if((tex = (*MidLevelRenderer::MLRTexturePool::Instance)[&state]) != NULL) { strName = CNodeDataValueFileTGA::GetTexturePath()+"\\"+tex->GetTextureName(); CNodeDataValueFile *pChild = new CNodeDataValueFileTGA(this,strName,pClone,oldName,newName); if (pChild->GetNodeDisk()->IsFound()) AddChild(pChild); else { delete pChild; pChild = new CNodeDataValueFilePNG(this,strName,pClone,oldName,newName); AddChild(pChild); } char name2[MAX_PATH] = ""; CString str; pChild->GetName(str); _splitpath(str,NULL,NULL,name2,NULL); if (strnicmp(name1,name2,strlen(name1))) { // The targa file changed names so we need to reflect this int the erf file MidLevelRenderer::MLRTexture *pNewTex = (*MidLevelRenderer::MLRTexturePool::Instance)(strName); if (NULL == pNewTex) pNewTex = MidLevelRenderer::MLRTexturePool::Instance->Add(strName); if (NULL == pNewTex) { // Why isn't this added? assert(false); } state.SetTextureHandle(pNewTex->GetTextureHandle()); pState->SetMLRState(state); } } } else { /* tstr.Format("%c%c Texture=None", (state->GetRenderDeltaMask() & MidLevelRenderer::MLRState::TextureMask) ? 'D' : '0', (state->GetRenderPermissionMask() & MidLevelRenderer::MLRState::TextureMask) ? 'P' : '0'); InfoCtrl->AddString(tstr);*/ } } else { //InfoCtrl->AddString("?? Texture=Error"); } } } CNodeDataValueERF::~CNodeDataValueERF() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueERFGroupElement ////////////////////////////////////////////////////////////////////// CNodeDataValueERFGroupElement::CNodeDataValueERFGroupElement(CNodeObject *pParent,ElementRenderer::GroupElement *pElement,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueERF(pParent,pElement,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEERFGROUPELEMENT; if (pClone) return; Stuff::ChainIteratorOf *children = pElement->MakeIterator(); Check_Object(children); ElementRenderer::Element *child = NULL; while ((child = children->ReadAndNext()) != NULL) { CNodeDataValueERF *pChild = CreateChild(this,child,oldName,newName); AddChild(pChild); } Check_Object(children); delete children; } CNodeDataValueERFGroupElement::~CNodeDataValueERFGroupElement() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueERFListElement ////////////////////////////////////////////////////////////////////// CNodeDataValueERFListElement::CNodeDataValueERFListElement(CNodeObject *pParent,ElementRenderer::ListElement *pElement,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueERF(pParent,pElement,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEERFLISTELEMENT; if (pClone) return; for(int i=0;iGetActiveCount();i++) { CNodeDataValueERF *pChild = CreateChild(this,pElement->GetIndexedElement(i),oldName,newName); AddChild(pChild); } } CNodeDataValueERFListElement::~CNodeDataValueERFListElement() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueERFGridElement ////////////////////////////////////////////////////////////////////// CNodeDataValueERFGridElement::CNodeDataValueERFGridElement(CNodeObject *pParent,ElementRenderer::GridElement *pElement,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueERF(pParent,pElement,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEERFGRIDELEMENT; if (pClone) return; unsigned char xSize, zSize; pElement->GetSize(&xSize, &zSize); while (pParent && !pParent->IsFile()) pParent = pParent->GetParentNode(); CString path = ((CNodeDataValueFileERF *)pParent)->GetNodeDisk()->GetPath(); for(int i=0;iGetIndexedElement(i,j)); AddChild(pChild1); #endif CNodeDataValueFileBSP *pBspChild = new CNodeDataValueFileBSP(this,strFileName,pClone,oldName,newName); AddChild(pBspChild); CNodeDataValueFileMATERIAL *pMaterialChild = new CNodeDataValueFileMATERIAL(this,strFileName,pClone,oldName,newName); AddChild(pMaterialChild); } /* for(int i=0;iGetActiveCount();i++) { CNodeDataValueERF *pChild = CreateChild(this,pElement->GetIndexedElement(i)); AddChild(pChild); } */ } CNodeDataValueERFGridElement::~CNodeDataValueERFGridElement() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueERFLODElement ////////////////////////////////////////////////////////////////////// CNodeDataValueERFLODElement::CNodeDataValueERFLODElement(CNodeObject *pParent,ElementRenderer::ListElement *pElement,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueERF(pParent,pElement,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEERFLODELEMENT; if (pClone) return; for(int i=0;iGetActiveCount();i++) { CNodeDataValueERF *pChild = CreateChild(this,pElement->GetIndexedElement(i),oldName,newName); AddChild(pChild); } } CNodeDataValueERFLODElement::~CNodeDataValueERFLODElement() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueERFShapeLODElement ////////////////////////////////////////////////////////////////////// CNodeDataValueERFShapeLODElement::CNodeDataValueERFShapeLODElement(CNodeObject *pParent,ElementRenderer::ShapeLODElement *pElement,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueERF(pParent,pElement,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEERFSHAPELODELEMENT; if (pClone) return; for(int i=0;iGetSize();i++) { MidLevelRenderer::MLRShape *shape; const ElementRenderer::LODElement::Entry *entry; pElement->GetLOD(i,&shape,&entry); CNodeData *pChild1 = new CNodeData(pParent,shape->GetClassString(),pClone,oldName,newName); AddChild(pChild1); CString str; CNodeDataValue *pValue; pValue = pChild1->CreateChild(pChild1,KEYTYPE_STRING,"Far Squared"); pChild1->AddChild(pValue); str.Format("%f",entry->m_farSquared); CNodeData *pData = pValue->CreateChild(pValue,KEYTYPE_FLOAT,str); pValue->AddChild(pData); pValue = pChild1->CreateChild(pChild1,KEYTYPE_STRING,"Near Squared"); pChild1->AddChild(pValue); str.Format("%f",entry->m_nearSquared); pData = pValue->CreateChild(pValue,KEYTYPE_FLOAT,str); pValue->AddChild(pData); for(int i=0;iGetNum();i++) { CNodeDataValue *pChild = new CNodeDataValueMLRElement(pChild1,shape->Find(i),pClone,oldName,newName); pChild1->AddChild(pChild); } // pChild = new CNodeDataValueERFShapeLODElement(pParent,group,entry,NULL,oldName,newName); //HTREEITEM hChild = erftree->InsertItem((LPCSTR)(shape->GetClassString()), 0, 1, tmpitm, TVI_LAST); //erftree->SetItemData(hChild,(DWORD) shape); /*for(int j=0;jGetNum();j++) { CNodeObject *pChild1 = AddChild(pParent,shape->Find(j),oldName,newName); }*/ } /* for(int i=0;iGetSize();i++) { CNodeDataValueERF *pChild = CreateChild(this,pElement->Find(i),oldName,newName); AddChild(pChild); } */ } CNodeDataValueERFShapeLODElement::~CNodeDataValueERFShapeLODElement() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueERFShapeElement ////////////////////////////////////////////////////////////////////// CNodeDataValueERFShapeElement::CNodeDataValueERFShapeElement(CNodeObject *pParent,ElementRenderer::ShapeElement *pElement,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueERF(pParent,pElement,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEERFSHAPEELEMENT; if (pClone) return; MidLevelRenderer::MLRShape *shape=pElement->GetMLRShape(); for(int i=0;iGetNum();i++) { CNodeDataValue *pChild = new CNodeDataValueMLRElement(this,shape->Find(i),pClone,oldName,newName); AddChild(pChild); } } CNodeDataValueERFShapeElement::~CNodeDataValueERFShapeElement() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueERFSwitchElement ////////////////////////////////////////////////////////////////////// CNodeDataValueERFSwitchElement::CNodeDataValueERFSwitchElement(CNodeObject *pParent,ElementRenderer::ListElement *pElement,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValueERF(pParent,pElement,pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEERFSWITCHELEMENT; if (pClone) return; for(int i=0;iGetActiveCount();i++) { CNodeDataValueERF *pChild = CreateChild(this,pElement->GetIndexedElement(i),oldName,newName); AddChild(pChild); } } CNodeDataValueERFSwitchElement::~CNodeDataValueERFSwitchElement() { } ////////////////////////////////////////////////////////////////////// // CNodeDataValueERFMLRElement ////////////////////////////////////////////////////////////////////// CNodeDataValueMLRElement::CNodeDataValueMLRElement(CNodeObject *pParent,MidLevelRenderer::MLRPrimitiveBase *pPrim,CNodeObject *pClone,CString oldName,CString newName) : CNodeDataValue(pParent,pClone?pClone->GetNameStr():CString(pPrim->GetClassData()->GetClassName()),pClone,oldName,newName) { m_iClassID = CLASS_CNODEDATAVALUEMLRELEMENT; m_pPrimitave = pPrim; if (pClone) { CNodeDataValueMLRElement *pEle = (CNodeDataValueMLRElement *)pClone; m_pPrimitave = pEle->GetPrimitave(); return; } MidLevelRenderer::MLRState state; for(int i=0;iGetNumPasses();i++) { state = pPrim->GetReferenceState(i); MidLevelRenderer::MLRTexture *tex = NULL; if (MidLevelRenderer::MLRTexturePool::Instance && (state.GetTextureHandle() < MidLevelRenderer::Limits::Max_Number_Textures * (1<GetInstanceDepth())) ) { if(state.GetTextureHandle()) { CString strName; if((tex = (*MidLevelRenderer::MLRTexturePool::Instance)[&state]) != NULL) { strName = tex->GetTextureName(); //strName.MakeLower(); int rcount;// = strName.Replace(oldName,newName); CString output = ReplaceNoCase(strName,oldName,newName,&rcount); strName = output; if (rcount) { MidLevelRenderer::MLRTexture *pNewTex = (*MidLevelRenderer::MLRTexturePool::Instance)(strName); if (NULL == pNewTex) pNewTex = MidLevelRenderer::MLRTexturePool::Instance->Add(strName); if (NULL == pNewTex) { // Why isn't this added? assert(false); } state.SetTextureHandle(pNewTex->GetTextureHandle()); pPrim->SetReferenceState(state, i); } CString strFind = "1_0101"; // Terrain - files are named NAME_XX_#_0#_0#.tga CString strRight = strName.Right(6); if (strFind == strRight) { // This is a terrain grid char fname[MAX_PATH],path[MAX_PATH]; _splitpath(strName,NULL,path,fname,NULL); CString strFname(fname); CString prefix = CString(path)+strFname.Left(strFname.GetLength()-6); for (int x=0;x<2;x++) { for (int y=0;y<2;y++) { CString strTga; strTga.Format("%s1_0%d0%d",prefix,y,x); strTga = CNodeDataValueFileTGA::GetTexturePath()+"\\"+strTga; CNodeDataValueFile *pChildTga = new CNodeDataValueFileTGA(this,strTga,pClone,oldName,newName); if (pChildTga->GetNodeDisk()->IsFound()) AddChild(pChildTga); else { delete pChildTga; pChildTga = new CNodeDataValueFilePNG(this,strTga,pClone,oldName,newName); AddChild(pChildTga); } } } CString strTga; strTga.Format("%s0_0000",prefix); strTga = CNodeDataValueFileTGA::GetTexturePath()+"\\"+strTga; CNodeDataValueFile *pChildTga = new CNodeDataValueFileTGA(this,strTga,pClone,oldName,newName); if (pChildTga->GetNodeDisk()->IsFound()) AddChild(pChildTga); else { delete pChildTga; pChildTga = new CNodeDataValueFilePNG(this,strTga,pClone,oldName,newName); AddChild(pChildTga); } } else { strName = CNodeDataValueFileTGA::GetTexturePath()+"\\"+strName; CNodeDataValueFile *pChild = new CNodeDataValueFileTGA(this,strName,pClone,oldName,newName); if (pChild->GetNodeDisk()->IsFound()) AddChild(pChild); else { delete pChild; pChild = new CNodeDataValueFilePNG(this,strName,pClone,oldName,newName); AddChild(pChild); } } } } else { /* tstr.Format("%c%c Texture=None", (state->GetRenderDeltaMask() & MidLevelRenderer::MLRState::TextureMask) ? 'D' : '0', (state->GetRenderPermissionMask() & MidLevelRenderer::MLRState::TextureMask) ? 'P' : '0'); InfoCtrl->AddString(tstr);*/ } } else { //InfoCtrl->AddString("?? Texture=Error"); } //MidLevelRenderer::MLRTexturePool::Instance->LoadImages(); } } CNodeDataValueMLRElement::~CNodeDataValueMLRElement() { }