// ContentTrack.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "ContentTrack.h" #include "MainFrm.h" #include "ChildFrm.h" #include "KeyTypeDlg.h" #include "NodeDataValueFileDoc.h" #include "NodeDataValueFileView.h" #include #include #if !defined(MW4ANIMATIONSYSTEM_HPP) #include #endif #include "mw4.hpp" #include "mw4headers.hpp" #include "gosfx\gosfx.hpp" #include #include #include #include #include #include CStringMap g_StringMap; DWORD g_stringmem; #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void __stdcall GetGameOSEnvironment(char* CommandLine) { // //---------------------------------------------------------- // This is where to set GOS environment settings. //---------------------------------------------------------- // Environment.applicationName = "DataWalker"; Environment.screenWidth = 640; Environment.screenHeight = 480; Environment.bitDepth = 16; } ///////////////////////////////////////////////////////////////////////////// // CContentTrackApp BEGIN_MESSAGE_MAP(CContentTrackApp, CWinApp) //{{AFX_MSG_MAP(CContentTrackApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) ON_COMMAND(ID_FILE_OPEN, OnFileOpen) ON_COMMAND(ID_EDIT_KEYTYPE, OnEditKeytype) ON_COMMAND(ID_FILE_NEW, OnFileNew) //}}AFX_MSG_MAP // Standard file based document commands ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) // Standard print setup command ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CContentTrackApp construction CContentTrackApp::CContentTrackApp() { m_pNodeSelected = NULL; } ///////////////////////////////////////////////////////////////////////////// // The one and only CContentTrackApp object CContentTrackApp theApp; ///////////////////////////////////////////////////////////////////////////// // CContentTrackApp initialization BOOL CContentTrackApp::InitInstance() { char buf[MAX_PATH]; GetCurrentDirectory(MAX_PATH,buf); InitGameOS( AfxGetInstanceHandle(), NULL, "\0" ); Stuff::ArmorLevel = 4; Stuff::InitializeClasses(); MidLevelRenderer::InitializeClasses(NULL, 8192*4, 1024*256); gosFX::InitializeClasses(); ElementRenderer::InitializeClasses(); //char buf[MAX_PATH]; //GetCurrentDirectory(MAX_PATH,buf); SetCurrentDirectory(buf); m_strRunDir = buf; // //------------------- // Make base managers //------------------- // Verify(!ResourceManager::Instance); ResourceManager::Instance = new ResourceManager; Check_Object(ResourceManager::Instance); AfxEnableControlContainer(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif SetRegistryKey(_T("ContentTrack")); LoadStdProfileSettings(); // Load standard INI file options (including MRU) // Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views. CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_CONTENTYPE, RUNTIME_CLASS(CNodeDataValueFileDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CNodeDataValueFileView)); AddDocTemplate(pDocTemplate); m_mapTemplates[ID_FILE_OPEN] = pDocTemplate; /*pDocTemplate = new CMultiDocTemplate( IDR_CONTENTYPE, RUNTIME_CLASS(CUnusedFilesDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CUnusedFilesView)); AddDocTemplate(pDocTemplate); m_mapTemplates[ID_UNUSEDFILES] = pDocTemplate;*/ /*pDocTemplate = new CMultiDocTemplate( IDR_CONTENTYPE, RUNTIME_CLASS(CUnusedFilesDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CMissingFilesView)); AddDocTemplate(pDocTemplate); m_mapTemplates[ID_MISSINGFILES] = pDocTemplate;*/ // create main MDI Frame window CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line if (!ProcessShellCommand(cmdInfo)) return FALSE; // The main window has been initialized, so show and update it. pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); // Load the default key types { CMainFrame *pFrame = (CMainFrame*)AfxGetMainWnd(); pFrame->SetMessageText("Loading Data Key Map..."); ReadPropFile(); } //Create the texture pool { gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap); MidLevelRenderer::TGAFilePool *pool = new MidLevelRenderer::TGAFilePool("\\content\\textures"); Check_Object(pool); MidLevelRenderer::MLRTexturePool::Instance = new MidLevelRenderer::MLRTexturePool(pool); Check_Object(MidLevelRenderer::MLRTexturePool::Instance); Check_Object(MidLevelRenderer::MLRTexturePool::Instance); gos_PopCurrentHeap(); } return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) // No message handlers //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() // App command to run the dialog void CContentTrackApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); } ///////////////////////////////////////////////////////////////////////////// // CContentTrackApp message handlers int CContentTrackApp::ExitInstance() { // Save the Key Types WritePropFile(); //g_mapKeyType.RemoveAll(); Check_Object(ResourceManager::Instance); delete ResourceManager::Instance; ResourceManager::Instance = NULL; ElementRenderer::TerminateClasses(); gosFX::TerminateClasses(); MidLevelRenderer::TerminateClasses(); Stuff::TerminateClasses(); ExitGameOS(); return CWinApp::ExitInstance(); } void CContentTrackApp::OnFileOpen() { CString newName; if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL)) return; // open cancelled CDocTemplate *pDocTemplate = (CDocTemplate *)m_mapTemplates[ID_FILE_OPEN]; pDocTemplate->OpenDocumentFile(newName); } void CContentTrackApp::OnFileNew() { // New project is handled from mainfrm because this OnFileNew gets called during app initialization } void CContentTrackApp::OnEditKeytype() { CKeyTypeDlg dlg; CMapPtrToWord map; dlg.SetMap(&map); if (IDOK == dlg.DoModal()) { // dlg.GetMap(g_mapKeyType); if (dlg.m_bDirty) { UpdateKeys(); WritePropFile(); } } } int CContentTrackApp::UpdateKeys() { POSITION TempPos = this->GetFirstDocTemplatePosition(); while (TempPos) { CDocTemplate *pTemplate = this->GetNextDocTemplate(TempPos); if (pTemplate) { POSITION DocPos = pTemplate->GetFirstDocPosition(); while (DocPos) { CDocument *pDoc = pTemplate->GetNextDoc(DocPos); pDoc->OnOpenDocument(pDoc->GetPathName()); } } } return 0; } int CContentTrackApp::WritePropFile() { CStringList list; g_StringMap.MakeList(list); FILE *f = fopen(m_strRunDir+"\\keymap.ini","w"); fprintf(f,"[KeyTypes]\n"); POSITION lpos = list.GetHeadPosition(); while (lpos) { CString str = list.GetNext(lpos); fprintf(f,"%s\n",str); } fclose(f); return 0; } int CContentTrackApp::ReadPropFile() { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // CString ini_file = m_strRunDir+"\\"+"keymap.ini"; /*Check_Pointer(Stuff::FileStreamManager::Instance); Stuff::FileStream *file_stream = Stuff::FileStream::MakeFileStream(); Check_Object(file_stream); file_stream->Open(ini_file); if (!file_stream->IsFileOpened()) { return -1; } */ NotationFile notefile(ini_file); if (notefile.IsEmpty()) { // file does not exist //assert(false); return -1; } NotationFile::PageIterator *pages = notefile.MakePageIterator(); Check_Object(pages); Page *page = notefile.FindPage("KeyTypes"); if (page) { Check_Object(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); const char *pKeyName = (char *)entry->GetName(); const char *pValueName; entry->GetEntry(&pValueName); //g_mapKeyType[pKeyName] = (void *)atoi(pValueName); POSITION p = g_StringMap.Find(pKeyName); g_StringMap.SetValue(p,atoi(pValueName)); } Check_Object(entries); delete entries; } Check_Object(pages); delete pages; /* CStringList list; g_StringMap.MakeList(list); FILE *f = fopen("c:\\listout.txt","w"); POSITION lpos = list.GetHeadPosition(); while (lpos) { CString str = list.GetNext(lpos); fprintf(f,"%s\n",str); } fclose(f);*/ g_stringmem = 0; DWORD memcount = g_StringMap.CountMem(); //DWORD memcount1 = sizeof(g_mapKeyType); return 0; } int IdentifyFileType(CString path) { int iKeyType = KEYTYPE_UNKNOWN; // Is this a database file? { DWORD tag = 0; FileStream::IsRedirected = false; HGOSFILE file; gos_OpenFile(&file,path,READONLY); if (file) { gos_ReadFile(file,&tag,sizeof(tag)); gos_CloseFile(file); } switch (tag) { case 'DBV#': { iKeyType = KEYTYPE_RESOURCE; break; } case 'ERF#': { iKeyType = KEYTYPE_ERF; break; } case 'GFX#': { //TODO: Note this is a .effects file break; } case 'OBB#': { iKeyType = KEYTYPE_OBB; break; } default: { switch (char(tag)) { case '!': case '[': case '/': { iKeyType = KEYTYPE_NOTE; break; } default: { // Still don't know what kind, get it from the extension of the filename char dir[MAX_PATH],drive[MAX_PATH],fname[MAX_PATH],ext[MAX_PATH]; _splitpath(path,dir,drive,fname,ext); if (strnicmp(ext,".bsp",4)==0) { iKeyType = KEYTYPE_BSP; } else if (strnicmp(ext,".fgd",4)==0) { iKeyType = KEYTYPE_FGD; } else if (strnicmp(ext,".lights",7)==0) { iKeyType = KEYTYPE_NOTE; } else { // I REALLY can't tell what kind of file this is int x=1; } } } } } } return iKeyType; } CStringMap::MAPNODE::MAPNODE() { szName = NULL; pParent = pLeft = pRight = NULL; parentshare = 0; value = 0; } CStringMap::MAPNODE::~MAPNODE() { if (szName) delete szName; if (pLeft) delete pLeft; if (pRight) delete pRight; } CString CStringMap::MAPNODE::GetName() { CString name(szName); MAPNODE *pNode = this; while (pNode) { MAPNODE *pParentNode = pNode->pParent; if (pNode->parentshare && pParentNode) { CString parentname = pParentNode->szName; parentname = parentname.Left(pNode->parentshare); name = parentname+name; } pNode = pParentNode; } return name; } CStringMap::CStringMap() { m_pMisc = NULL; for (int x=0;x<26;x++) m_arrRoots[x] = NULL; } CStringMap::~CStringMap() { for (int x=0;x<26;x++) { if (m_arrRoots[x]) delete m_arrRoots[x]; m_arrRoots[x] = NULL; } if (m_pMisc) delete m_pMisc; m_pMisc = NULL; } // NOTE: 0x5f mask makes the ascii character uppercase POSITION CStringMap::Find(const char *szInput) { // make the string uppercase char *sz = (char *)szInput; while (*sz) { char c = *sz; if ((c>='a')&&(c<='z')) *sz &= 0x5f; ++sz; } BYTE index = (*szInput)-'A'; if (index<26) { // szInput++; MAPNODE *pNode = m_arrRoots[index]; if (pNode) { POSITION pos = (POSITION)_Find(szInput,pNode,NULL,0); return pos; } else { m_arrRoots[index] = pNode = new MAPNODE; pNode->szName = strdup(szInput); return (POSITION)pNode; } } if (m_pMisc) { POSITION pos = (POSITION)_Find(szInput,m_pMisc,m_pMisc,0); return pos; } else { m_pMisc = new MAPNODE; m_pMisc->szName = strdup(szInput); return (POSITION)m_pMisc; } return NULL; } CStringMap::MAPNODE *CStringMap::_Find(const char *szInput,CStringMap::MAPNODE *pNode,CStringMap::MAPNODE *pParent,int parentdist) { char *name = pNode->szName; Check_Pointer(name); int share = 0; if ((pNode->pParent == pParent)&&(pNode->parentshare == parentdist)) { // The search node has the same parent as the new node, so we can share text while (*szInput || *name) { if (*szInput == *name) { ++share; pParent = pNode; ++name; ++szInput; } else { break; } } } if (*szInput || *name || (0 == share)) { //We're not sharing any of the current pNode so just pass the new node down the tree, with old parent if (0 == share) share = parentdist; MAPNODE *pFind = NULL; if (*szInput < *name) { if (pNode->pLeft) { pFind = _Find(szInput,pNode->pLeft,pParent,share); } else { pFind = pNode->pLeft = new MAPNODE; pFind->szName = strdup(szInput); pFind->pParent = pParent; pFind->parentshare = share; } } else { if (pNode->pRight) { pFind = _Find(szInput,pNode->pRight,pParent,share); } else { pFind = pNode->pRight = new MAPNODE; pFind->szName = strdup(szInput); pFind->pParent = pParent; pFind->parentshare = share; } } return pFind; } // What if there are more character in name? if (*name) { Verify(false); } return pNode; } POSITION CStringMap::Exists(const char *szInput) { // make the string uppercase char *sz = (char *)szInput; while (*sz) { char c = *sz; if ((c>='a')&&(c<='z')) *sz &= 0x5f; ++sz; } MAPNODE *pNode = NULL; MAPNODE *pParent = NULL; BYTE share = 0; BYTE index = (*szInput)-'A'; if (index<26) { pNode = m_arrRoots[index]; // szInput++; } else { pNode = m_pMisc; } char *name = (char *)szInput; bool bFound = false; while (!bFound) { if (NULL == pNode) return NULL; char *szNode = pNode->szName; Check_Pointer(szNode); BYTE newshare = 0; MAPNODE *pNewParent = NULL; if ((pNode->pParent == pParent)&&(pNode->parentshare == share)) { while (*name || *szNode) { if (*name == *szNode) { ++newshare; pNewParent = pNode; ++name; ++szNode; } else { break; } } } // if (NULL == pParent) // pParent = pNode; if (newshare) share = newshare; if (0 == *name) { if (0 == *szNode) { if (0==share) return (POSITION)pNode; else { if (pNode->pParent == pParent) return (POSITION)pNode; else { int x=1; } } } } if (!bFound&&(*name || *szNode || (0 == newshare))) { if (*name < *szNode) { pNode = pNode->pLeft; } else { pNode = pNode->pRight; } } if (pNewParent) pParent = pNewParent; } return (POSITION)pNode; } void CStringMap::SetValue(POSITION pos,BYTE value) { MAPNODE *pNode = (MAPNODE *)pos; if (pNode) { pNode->value = value; } } int CStringMap::MakeList(CStringList &list) { int count = 0; for (int x=0;x<26;x++) { MAPNODE *pNode = m_arrRoots[x]; count += _MakeList(list,pNode); } count += _MakeList(list,m_pMisc); return count; } int CStringMap::MakeList(CPtrList &list) { int count = 0; for (int x=0;x<26;x++) { MAPNODE *pNode = m_arrRoots[x]; count += _MakeList(list,pNode); } count += _MakeList(list,m_pMisc); return count; } int CStringMap::_MakeList(CStringList &list,CStringMap::MAPNODE *pNode) { int count = 0; if (pNode) { count++; CString name = pNode->GetName(); CString name1; name1.Format("%s=%d",name,pNode->value); list.AddTail(name1); count += _MakeList(list,pNode->pLeft); count += _MakeList(list,pNode->pRight); } return count; } int CStringMap::_MakeList(CPtrList &list,CStringMap::MAPNODE *pNode) { int count = 0; if (pNode) { count++; list.AddTail((LPVOID)pNode); count += _MakeList(list,pNode->pLeft); count += _MakeList(list,pNode->pRight); } return count; } DWORD CStringMap::NodeMem(CStringMap::MAPNODE *pNode) { DWORD count = 0; if (pNode) { count += sizeof(*pNode); DWORD strmem = strlen(pNode->szName); count += strmem; g_stringmem += strmem; count += NodeMem(pNode->pLeft); count += NodeMem(pNode->pRight); } return count; } DWORD CStringMap::CountMem() { DWORD count = 0; count += sizeof(*this); for (int x=0;x<26;x++) { count += NodeMem(m_arrRoots[x]); } count += NodeMem(m_pMisc); return count; } BYTE CStringMap::GetValue(POSITION pos) { if (pos) return ((MAPNODE *)pos)->value; return 0; } CString CStringMap::GetName(POSITION pos) { MAPNODE *pNode = (MAPNODE *)pos; Check_Pointer(pNode); MAPNODE *pParent = pNode; while (pParent->pParent) pParent = pParent->pParent; CString str1=""; /* for (int x=0;x<26;x++) { if (pParent == m_arrRoots[x]) str1.Format("%c",x+'A'); }*/ CString str2 = str1+pNode->GetName(); return str2; }