Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

3325 lines
90 KiB
C++

// NodeObject.cpp: implementation of the CNodeObject class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ContentTrack.h"
#include "NodeObject.h"
#include "NodeDataValueFileDoc.h"
#include "mainfrm.h"
#include <assert.h>
#include <ElementRenderer\StateChange.hpp>
#include <MLR\MLRTexturePool.hpp>
#include <MLR\MLRTexture.hpp>
#include <MLR\MLRShape.hpp>
#include <GameOS\ToolOS.hpp>
#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<BYTE*>(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;index<count;index++)
{
POSITION pos = listPageName.FindIndex(index);
CString page = listPageName.GetAt(pos);
pos = listPageEntry.FindIndex(index);
CString entry = listPageEntry.GetAt(pos);
pos = listPageValue.FindIndex(index);
CString value = listPageValue.GetAt(pos);
pos = listPageNum.FindIndex(index);
DWORD newpage = (DWORD)listPageNum.GetAt(pos);
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);
}
}*/
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;i<group->GetActiveCount();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<<MidLevelRenderer::MLRTexturePool::Instance->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<ElementRenderer::Element*> *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;i<pElement->GetActiveCount();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;i<zSize;i++)
for(int j=0;j<xSize;j++)
{
CString strFileName;
strFileName += ('A'+(char)i);
strFileName += ('A'+(char)j);
CNodeDataValueFileERF *pChild = new CNodeDataValueFileERF(this,strFileName+".erf",pClone,oldName,newName);
AddChild(pChild);
#if 0
CNodeDataValueERF *pChild1 = CreateChild(this,pElement->GetIndexedElement(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;i<pElement->GetActiveCount();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;i<pElement->GetActiveCount();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;i<pElement->GetSize();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;i<shape->GetNum();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;j<shape->GetNum();j++)
{
CNodeObject *pChild1 = AddChild(pParent,shape->Find(j),oldName,newName);
}*/
}
/* for(int i=0;i<pElement->GetSize();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;i<shape->GetNum();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;i<pElement->GetActiveCount();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;i<pPrim->GetNumPasses();i++)
{
state = pPrim->GetReferenceState(i);
MidLevelRenderer::MLRTexture *tex = NULL;
if (MidLevelRenderer::MLRTexturePool::Instance &&
(state.GetTextureHandle() < MidLevelRenderer::Limits::Max_Number_Textures * (1<<MidLevelRenderer::MLRTexturePool::Instance->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()
{
}