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

735 lines
17 KiB
C++

// MapCopyDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MapCopy.h"
#include "MapCopyDlg.h"
//#include <stuff\stuffheaders.hpp>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// 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)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CString g_szbrowsepath;
int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
RECT rect;
//
//Center the browse dialog on the screen...
//
switch (uMsg)
{
case BFFM_INITIALIZED:
{
SendMessage(hWnd,BFFM_SETSELECTION,TRUE,(LPARAM)(LPCTSTR)g_szbrowsepath);
if (GetWindowRect(hWnd, &rect))
{
SetWindowPos(hWnd,
HWND_TOP,
(GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) >> 1,
(GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) >> 1,
0,
0,
SWP_NOSIZE);
}
}
}
return 0;
}
CString BrowseDirectory(const char *strCurrent,CWnd *pWnd)
{
CString str;
TCHAR szBuffer[MAX_PATH];
LPITEMIDLIST pidlBrowse,pidlRoot;
BROWSEINFO bi;
LPMALLOC lpMalloc;
SHGetMalloc(&lpMalloc);
ASSERT(lpMalloc);
bi.hwndOwner = pWnd->GetSafeHwnd();
// Get the ID for the "My Computer" root folder
SHGetSpecialFolderLocation(pWnd->GetSafeHwnd(),CSIDL_DRIVES,&pidlRoot);
bi.pidlRoot = pidlRoot;
bi.pszDisplayName = szBuffer;
// Localize the descriptive text
bi.lpszTitle = "Select Destination Folder";
// BIF_EDITBOX and BIF_VALIDATE are for versions 4.71 and later, they
// might be ignored by older versions
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;// | BIF_EDITBOX;// | BIF_USENEWUI;// | BIF_VALIDATE;
bi.lParam = (LPARAM)pWnd;
bi.iImage = NULL;
bi.lpfn = BrowseCallbackProc;
bi.lParam = (LPARAM)strCurrent;
//
//Call the Windows shell folder browsing routine...
//
pidlBrowse = SHBrowseForFolder(&bi);
if (NULL != pidlBrowse)
{
if (SHGetPathFromIDList(pidlBrowse, szBuffer))
{
if ('\\' == szBuffer[lstrlen(szBuffer)-1])
szBuffer[lstrlen(szBuffer)-1] = '\0';
str = CString(szBuffer);
}
else
str = "";
//
//Free up shell memory used...
//
lpMalloc->Free(pidlBrowse);
}
else
str = "";
lpMalloc->Free(pidlRoot);
lpMalloc->Release();
return str;
}
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()
/////////////////////////////////////////////////////////////////////////////
// CMapCopyDlg dialog
CMapCopyDlg::CMapCopyDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMapCopyDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMapCopyDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMapCopyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMapCopyDlg)
DDX_Control(pDX, IDC_LIST_STATUS, m_listStatus);
DDX_Control(pDX, IDC_LIST_TEMP, m_listDestination);
DDX_Control(pDX, IDC_LIST_CONTENT, m_listContent);
DDX_Control(pDX, IDC_EDIT_DIRECTORY, m_editDirectory);
DDX_Control(pDX, IDC_BROWSE, m_btnBrowse);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMapCopyDlg, CDialog)
//{{AFX_MSG_MAP(CMapCopyDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
ON_BN_CLICKED(IDC_RADIO1, OnRadio1)
ON_BN_CLICKED(IDC_RADIO2, OnRadio2)
ON_BN_CLICKED(IDC_RADIO3, OnRadio3)
ON_BN_CLICKED(IDC_ADDTEMP, OnAddtemp)
ON_BN_CLICKED(IDC_ADDCONTENT, OnAddcontent)
ON_BN_CLICKED(IDC_UPDATE, OnUpdate)
ON_BN_CLICKED(IDC_EXECUTE, OnExecute)
ON_BN_CLICKED(IDC_SYNC_BUILDINGS, OnSyncBuildings)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMapCopyDlg message handlers
BOOL CMapCopyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
char buf[MAX_PATH];
GetCurrentDirectory(MAX_PATH,buf);
m_strGameDir = buf;
buf[1] = '\0';
CString tempdir = CString(buf)+":\\temp";
m_editDirectory.SetWindowText(tempdir);
SendDlgItemMessage(IDC_RADIO1,BM_CLICK,0,0);
ScanContentMaps();
// ScanDestMaps();
m_listStatus.SetHorizontalExtent(700);
return TRUE; // return TRUE unless you set the focus to a control
}
void CMapCopyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CMapCopyDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMapCopyDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CMapCopyDlg::OnBrowse()
{
CString dest;
m_editDirectory.GetWindowText(dest);
g_szbrowsepath = dest;
dest = BrowseDirectory(dest,&m_editDirectory);
m_editDirectory.SetWindowText(dest);
ScanDestMaps();
}
void CMapCopyDlg::OnRadio1()
{
m_copymode = 0;
ScanDestMaps();
}
void CMapCopyDlg::OnRadio2()
{
m_copymode = 1;
ScanDestMaps();
}
void CMapCopyDlg::OnRadio3()
{
m_copymode = 2;
}
void CMapCopyDlg::OnAddtemp()
{
int maxcount = m_listContent.GetSelCount();
int *items = new int[maxcount];
m_listContent.GetSelItems(maxcount,items);
for (int x=0;x<maxcount;x++)
{
CString name;
m_listContent.GetText(items[x],name);
if (LB_ERR == m_listDestination.FindString(-1,name))
{
int index = m_listDestination.AddString(name);
m_listDestination.SetItemData(index,1);
}
}
delete items;
}
void CMapCopyDlg::OnAddcontent()
{
int maxcount = m_listDestination.GetSelCount();
int *items = new int[maxcount];
m_listDestination.GetSelItems(maxcount,items);
for (int x=0;x<maxcount;x++)
{
CString name;
m_listDestination.GetText(items[x],name);
if (LB_ERR == m_listContent.FindString(-1,name))
{
int index = m_listContent.AddString(name);
m_listContent.SetItemData(index,1);
}
}
delete items;
}
void CMapCopyDlg::OnUpdate()
{
ScanDestMaps();
}
void CMapCopyDlg::OnExecute()
{
CString src;
CString dst;
//CStringList listMaps;
CString dest;
m_editDirectory.GetWindowText(dest);
switch (m_copymode)
{
case 0:
// Content->Content
case 1:
{
// Content->Temp
// Copy the items from content to dest
for (int x=0;x<m_listDestination.GetCount();x++)
{
if (m_listDestination.GetItemData(x))
{
CString name;
m_listDestination.GetText(x,name);
CopyContent(m_strGameDir,dest,name);
if (0 == m_copymode)
{
// Update resources.build
{
NotationFile notefile(dest+"\\content\\resources.build");
Page *page = notefile.GetPage("resources\\main");
Check_Object(page);
page->AppendEntry("data","maps\\"+name+"\\"+name+".data");
page->AppendEntry("instance","missions\\"+name+"\\"+name+".instance");
notefile.Save();
}
// Update editor.contents
{
}
}
}
}
break;
{
}
break;
}
case 2:
{
// Temp->Content
// Copy the items from dest to content
for (int x=0;x<m_listContent.GetCount();x++)
{
if (m_listContent.GetItemData(x))
{
CString name;
m_listContent.GetText(x,name);
CopyContent(dest,m_strGameDir,name);
{
NotationFile notefile(m_strGameDir+"\\content\\resources.build");
Page *page = notefile.GetPage("resources\\main");
Check_Object(page);
page->AppendEntry("data","maps\\"+name+"\\"+name+".data");
page->AppendEntry("instance","missions\\"+name+"\\"+name+".instance");
}
// Update editor.contents
{
}
}
}
break;
}
}
ScanContentMaps();
ScanDestMaps();
}
int CMapCopyDlg::ScanContentMaps()
{
// Clear all items in list
int count = m_listContent.GetCount();
for (int x=0;x<count;x++)
{
m_listContent.DeleteString(0);
}
// Get this from resources.build
NotationFile notefile(m_strGameDir+"\\content\\resources.build");
Page *page = notefile.GetPage("resources\\main");
if (page)
{
Check_Object(page);
Page::NoteIterator *iterator = page->MakeNoteIterator();
Check_Object(iterator);
iterator->First();
Note *entry;
while (entry = iterator->ReadAndNext())
{
Check_Object(entry);
const char *name = entry->GetName();
const char *value;
entry->GetEntry(&value);
if (strnicmp(name,"data",4)==0)
{
if (strnicmp(value,"maps",4)==0)
{
Stuff::MString mapname = value;
Stuff::StripExtension(&mapname);
Stuff::StripDirectory(&mapname);
int index = m_listContent.AddString(mapname);
m_listContent.SetItemData(index,0);
}
}
}
delete iterator;
}
return 0;
}
int CMapCopyDlg::ScanDestMaps()
{
// Clear all items in list
int count = m_listDestination.GetCount();
for (int x=0;x<count;x++)
{
m_listDestination.DeleteString(0);
}
// Get the list from the destination directory
CString strDest;
m_editDirectory.GetWindowText(strDest);
if (0 == m_copymode)
{
// Get this from resources.build
NotationFile notefile(strDest+"\\content\\resources.build");
if (notefile.FindPage("resources\\main"))
{
Page *page = notefile.GetPage("resources\\main");
if (page)
{
Check_Object(page);
Page::NoteIterator *iterator = page->MakeNoteIterator();
Check_Object(iterator);
iterator->First();
Note *entry;
while (entry = iterator->ReadAndNext())
{
Check_Object(entry);
const char *name = entry->GetName();
const char *value;
entry->GetEntry(&value);
if (strnicmp(name,"data",4)==0)
{
if (strnicmp(value,"maps",4)==0)
{
Stuff::MString mapname = value;
Stuff::StripExtension(&mapname);
Stuff::StripDirectory(&mapname);
int index = m_listDestination.AddString(mapname);
m_listDestination.SetItemData(index,0);
}
}
}
delete iterator;
}
}
}
else
{
CFileFind filefind;
if (filefind.FindFile(strDest+"\\content\\maps\\*.*"))
{
bool lastfile = false;
while (1)
{
lastfile = !filefind.FindNextFile();
if (!filefind.IsDots())
{
if (filefind.IsDirectory())
{
int index = m_listDestination.AddString(filefind.GetFileTitle());
// Set to zero if origial - will be set to 1 if it is new (do be added)
m_listDestination.SetItemData(index,0);
}
}
if (lastfile)
break;
}
filefind.Close();
}
}
return 0;
}
int CMapCopyDlg::CopyDirectory(CString src, CString dst,CString param)
{
CString action;
action = "md "+dst;
m_listStatus.AddString(action);
//ShellExecute(NULL,NULL,"md",dst,NULL,SW_HIDE);
//CreateDirectory(dst,NULL);
//system(action);
for (int x=0;x<dst.GetLength();x++)
{
if (dst[x] == '\\')
{
CString str = dst.Left(x+1);
if (str.GetLength()>3)
CreateDirectory(str,NULL);
}
}
CreateDirectory(dst,NULL);
action = "\"" + src + "\" \"" +dst+"\" "+param;
m_listStatus.AddString("xcopy "+action);
//system(action);
HINSTANCE nRet = ShellExecute(NULL,NULL,"xcopy",action,NULL,SW_HIDE);
if (nRet <= (HINSTANCE)32)
{
CString errStr;
switch ((int)nRet)
{
case 0:
errStr = "Operating system out of resources.";
break;
case ERROR_FILE_NOT_FOUND :
errStr = "ERROR_FILE_NOT_FOUND";
break;
case ERROR_PATH_NOT_FOUND :
errStr = "ERROR_PATH_NOT_FOUND ";
break;
case ERROR_BAD_FORMAT :
errStr = "ERROR_BAD_FORMAT ";
break;
case SE_ERR_ACCESSDENIED :
errStr = "SE_ERR_ACCESSDENIED ";
break;
case SE_ERR_ASSOCINCOMPLETE:
errStr = "SE_ERR_ASSOCINCOMPLETE";
break;
case SE_ERR_DDEBUSY :
errStr = "SE_ERR_DDEBUSY ";
break;
case SE_ERR_DDEFAIL :
errStr = "SE_ERR_DDEFAIL";
break;
case SE_ERR_DDETIMEOUT :
errStr = "SE_ERR_DDETIMEOUT ";
break;
case SE_ERR_DLLNOTFOUND :
errStr = "SE_ERR_DLLNOTFOUND";
break;
case SE_ERR_NOASSOC :
errStr = "SE_ERR_NOASSOC";
break;
case SE_ERR_OOM :
errStr = "SE_ERR_OOM";
break;
case SE_ERR_SHARE :
errStr = "SE_ERR_SHARE";
break;
}
errStr += " received while performing \r\n";
errStr += "'xcopy ";
errStr += action;
errStr += "'";
MessageBox((LPCSTR)errStr, "Copy error", MB_OK);
}
return 0;
}
// Copy only files in src that don't exist in dst
int CMapCopyDlg::SyncDirectory(CString src, CString dst)
{
// Find everything in src that is not in dst and copy those
CStringList listdst;
CFileFind filefind;
if (filefind.FindFile(dst+"\\*.*"))
{
bool lastfile = false;
while (1)
{
lastfile = !filefind.FindNextFile();
if (!filefind.IsDots())
{
//if (!filefind.IsDirectory())
{
listdst.AddHead(filefind.GetFileName());
}
}
if (lastfile)
break;
}
filefind.Close();
}
if (filefind.FindFile(src+"\\*.*"))
{
bool lastfile = false;
while (1)
{
lastfile = !filefind.FindNextFile();
if (!filefind.IsDots())
{
//if (!filefind.IsDirectory())
{
CString name = filefind.GetFileName();
if (NULL ==listdst.Find(name))
{
CopyDirectory(src+"\\"+name,dst+"\\"+name,"/E");
}
}
}
if (lastfile)
break;
}
filefind.Close();
}
return 0;
}
int CMapCopyDlg::CopyContent(CString src,CString dst,CString name)
{
CopyDirectory(src+"\\content\\maps\\"+name,
dst+"\\content\\maps\\"+name,
"/E");
CopyDirectory(src+"\\content\\textures\\maps\\"+name,
dst+"\\content\\textures\\maps\\"+name,
"/E");
CopyDirectory(src+"\\content\\textures\\composttexture\\"+name+"*.*",
dst+"\\content\\textures\\composttexture",
"/E");
CopyDirectory(src+"\\content\\missions\\"+name,
dst+"\\content\\missions\\"+name,
"/E");
CopyDirectory(src+"\\content\\textures\\"+name+"*.*",
dst+"\\content\\textures");
SyncDirectory(src+"\\content\\buildings",dst+"\\content\\buildings");
// Copy content\maps\<mapname>
// Copy content\textures\maps\<mapname>
// Copy content\textures\composttexture\<mapname>*
// Copy content\textures\composite\index...
// Copy content\building (only the new ones)
// Copy content\misions\<mapname>
return 0;
}
void CMapCopyDlg::OnSyncBuildings()
{
CString dest;
m_editDirectory.GetWindowText(dest);
SyncDirectory(m_strGameDir+"\\content\\buildings",dest+"\\content\\buildings");
}