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.
3325 lines
90 KiB
C++
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()
|
|
{
|
|
|
|
} |