Initial commit of Command & Conquer Renegade source code.

This commit is contained in:
LFeenanEA
2025-02-27 16:39:46 +00:00
parent 74ab8fa5e0
commit 58ed459113
4918 changed files with 1366710 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// CommandoUpdate.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "CommandoUpdate.h"
#include "CommandoUpdateDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateApp
BEGIN_MESSAGE_MAP(CCommandoUpdateApp, CWinApp)
//{{AFX_MSG_MAP(CCommandoUpdateApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateApp construction
CCommandoUpdateApp::CCommandoUpdateApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CCommandoUpdateApp object
CCommandoUpdateApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateApp initialization
BOOL CCommandoUpdateApp::InitInstance()
{
// 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
CCommandoUpdateDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}

View File

@@ -0,0 +1,164 @@
# Microsoft Developer Studio Project File - Name="CommandoUpdate" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=CommandoUpdate - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "CommandoUpdate.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "CommandoUpdate.mak" CFG="CommandoUpdate - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "CommandoUpdate - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "CommandoUpdate - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tools/CommandoUpdate", BFWBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "CommandoUpdate - Win32 Release"
# PROP BASE Use_MFC 5
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 5
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 /nologo /subsystem:windows /machine:I386 /out:"Release/RenegadeUpdate.exe"
!ELSEIF "$(CFG)" == "CommandoUpdate - Win32 Debug"
# PROP BASE Use_MFC 5
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 5
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /out:"Debug/RenegadeUpdate.exe"
!ENDIF
# Begin Target
# Name "CommandoUpdate - Win32 Release"
# Name "CommandoUpdate - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\CommandoUpdate.cpp
# End Source File
# Begin Source File
SOURCE=.\CommandoUpdate.rc
# End Source File
# Begin Source File
SOURCE=.\CommandoUpdateDlg.cpp
# End Source File
# Begin Source File
SOURCE=.\FileCopyDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\CommandoUpdate.h
# End Source File
# Begin Source File
SOURCE=.\CommandoUpdateDlg.h
# End Source File
# Begin Source File
SOURCE=.\FileCopyDialog.h
# End Source File
# Begin Source File
SOURCE=.\Resource.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\res\CommandoUpdate.ico
# End Source File
# Begin Source File
SOURCE=.\res\CommandoUpdate.rc2
# End Source File
# Begin Source File
SOURCE=.\res\icon1.ico
# End Source File
# End Group
# Begin Source File
SOURCE=.\res\Filecopy.avi
# End Source File
# Begin Source File
SOURCE=.\ReadMe.txt
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,67 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// CommandoUpdate.h : main header file for the COMMANDOUPDATE application
//
#if !defined(AFX_COMMANDOUPDATE_H__4305AC4E_1EAB_11D3_A038_00104B791122__INCLUDED_)
#define AFX_COMMANDOUPDATE_H__4305AC4E_1EAB_11D3_A038_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateApp:
// See CommandoUpdate.cpp for the implementation of this class
//
class CCommandoUpdateApp : public CWinApp
{
public:
CCommandoUpdateApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCommandoUpdateApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CCommandoUpdateApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COMMANDOUPDATE_H__4305AC4E_1EAB_11D3_A038_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,264 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"#ifdef _WIN32\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#endif //_WIN32\r\n"
"#include ""res\\CommandoUpdate.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON DISCARDABLE "res\\CommandoUpdate.ico"
IDI_COPY ICON DISCARDABLE "res\\icon1.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_COMMANDOUPDATE_DIALOG DIALOGEX 0, 0, 332, 282
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Renegade Update"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDI_COPY,IDC_STATIC,7,7,21,20
LTEXT "Select the Renegade applications you wish to update on your machine. Note: If you select 'Clean' all files in the application directory WILL BE DELETED.",
IDC_STATIC,42,7,283,26
GROUPBOX "&Tools",IDC_STATIC,7,39,318,95
CONTROL "&Level Editor",IDC_EDITOR_CHECK,"Button",
BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,56,62,10
CONTROL "Clean",IDC_EDITOR_CLEAN_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,90,56,34,10
PUSHBUTTON "<directory>",IDC_EDITOR_DIR_BUTTON,131,52,179,14
CONTROL "Ligh&tmap",IDC_LIGHTMAP_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,16,75,62,10
CONTROL "Clean",IDC_LIGHTMAP_CLEAN_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,90,75,34,10
PUSHBUTTON "<directory>",IDC_LIGHTMAP_DIR_BUTTON,131,71,179,14
CONTROL "&Vis Farm Slave",IDC_VISFARM_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,16,94,62,10
CONTROL "Clean",IDC_VISFARM_CLEAN_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,90,94,34,10
PUSHBUTTON "<directory>",IDC_VISFARM_DIR_BUTTON,131,91,179,14
CONTROL "&Mix Viewer",IDC_MIXVIEW_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,16,114,62,10
CONTROL "Clean",IDC_MIXVIEW_CLEAN_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,90,114,34,10
PUSHBUTTON "<directory>",IDC_MIXVIEW_DIR_BUTTON,131,111,179,14
GROUPBOX "&Game",IDC_STATIC,7,139,318,68
GROUPBOX "M&ultiplay",IDC_STATIC,7,214,318,38
CONTROL "Multiplay &Build",IDC_MULTIPLAY_CHECK,"Button",
BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,231,68,10
CONTROL "Clean",IDC_MULTIPLAY_CLEAN_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,90,231,34,10
PUSHBUTTON "<directory>",IDC_MULTIPLAY_DIR_BUTTON,131,227,179,14
DEFPUSHBUTTON "OK",IDOK,74,261,50,14,WS_GROUP
PUSHBUTTON "Cancel",IDCANCEL,140,261,50,14
PUSHBUTTON "Defaults",IDC_DEFAULTS,206,261,50,14
CONTROL "&Engine",IDC_GAME_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,16,154,46,10
CONTROL "Le&vels",IDC_GAME_LEVELS_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,16,172,43,10
CONTROL "M&ovies",IDC_GAME_MOVIES_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,16,189,43,10
CONTROL "Clean",IDC_GAME_CLEAN_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,90,161,34,10
PUSHBUTTON "<directory>",IDC_GAME_DIR_BUTTON,131,157,179,14
END
IDD_FILE_COPY DIALOGEX 0, 0, 210, 79
STYLE DS_MODALFRAME | DS_SETFOREGROUND | WS_POPUP | WS_VISIBLE | WS_CAPTION
EXSTYLE WS_EX_APPWINDOW
CAPTION "Updating Application..."
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
CONTROL "Animate1",IDC_ANIMATE_CTRL,"SysAnimate32",ACS_CENTER |
ACS_TRANSPARENT | ACS_AUTOPLAY | WS_TABSTOP,7,23,196,34
LTEXT "Comparing directories...",IDC_FILENAME_TEXT,7,60,196,8
LTEXT "Application:",IDC_CURRENT_APP,7,7,196,8
END
IDD_DIR_SELECT_DIALOG DIALOG DISCARDABLE 36, 24, 268, 134
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CONTEXTHELP | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Open"
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "&Folder Name:",1090,6,6,76,9
EDITTEXT 1152,6,16,90,12,ES_AUTOHSCROLL | ES_OEMCONVERT
LTEXT "",1088,110,16,96,9,SS_NOPREFIX
LISTBOX 1121,110,32,96,68,LBS_SORT | LBS_OWNERDRAWFIXED |
LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL |
WS_TABSTOP
LTEXT "Dri&ves:",1091,110,104,96,9
COMBOBOX 1137,110,114,96,68,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED |
CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_VSCROLL |
WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,212,6,50,14,WS_GROUP
PUSHBUTTON "Cancel",IDCANCEL,212,24,50,14,WS_GROUP
PUSHBUTTON "&Help",1038,212,46,50,14,WS_GROUP
END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "CommandoUpdate MFC Application\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "CommandoUpdate\0"
VALUE "LegalCopyright", "Copyright (C) 1999\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "CommandoUpdate.EXE\0"
VALUE "ProductName", "CommandoUpdate Application\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_COMMANDOUPDATE_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 325
TOPMARGIN, 7
BOTTOMMARGIN, 275
END
IDD_FILE_COPY, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 203
TOPMARGIN, 7
BOTTOMMARGIN, 72
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// AVI
//
IDR_FILECOPY_AVI AVI DISCARDABLE "res\\Filecopy.avi"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif //_WIN32
#include "res\CommandoUpdate.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,974 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// CommandoUpdateDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CommandoUpdate.h"
#include "CommandoUpdateDlg.h"
#include "FileCopyDialog.H"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//
// Data Tables
//
/////////////////////////////////////////////////////////////////////////////
typedef struct
{
FileCopyDialogClass *dialog;
CString src_dir;
CString dest_dir;
bool is_recursive;
bool result;
} UPDATE_INFO;
typedef struct
{
LPCTSTR title;
LPCTSTR src;
LPCTSTR default_dir;
LPCTSTR reg_key;
UINT ctrl_id;
UINT clean_ctrl_id;
UINT dir_ctrl_id;
bool clean_default;
bool is_recursive;
} APP_INFO;
typedef enum
{
APP_EDITOR = 0,
APP_GAME_ENGINE,
APP_GAME_LEVELS,
APP_GAME_MOVIES,
APP_LIGHTMAP,
APP_VISFARM,
APP_MIXVIEW,
APP_MULTIPLAY,
APP_MAX,
} APPLICATION_IDS;
const APP_INFO APPLICATIONS[APP_MAX] =
{
{ "Level Editor", "\\\\mobius\\project7\\projects\\renegade\\programming\\tools\\level edit", "c:\\commando\\leveledit", "LevelEdit\\Install", IDC_EDITOR_CHECK, IDC_EDITOR_CLEAN_CHECK, IDC_EDITOR_DIR_BUTTON, true, false },
{ "Game Engine", "\\\\havoc\\rock\\projects\\renegade\\asset management\\current build", "c:\\commando\\run", "Commando\\Install", IDC_GAME_CHECK, IDC_GAME_CLEAN_CHECK, IDC_GAME_DIR_BUTTON, false, true },
{ "Game Levels", "\\\\havoc\\rock\\projects\\renegade\\asset management\\current levels", "c:\\commando\\run", "Commando\\Install", IDC_GAME_LEVELS_CHECK, IDC_GAME_CLEAN_CHECK, IDC_GAME_DIR_BUTTON, false, true },
{ "Game Movies", "\\\\havoc\\rock\\projects\\renegade\\asset management\\cinematics", "c:\\commando\\run", "Commando\\Install", IDC_GAME_MOVIES_CHECK, IDC_GAME_CLEAN_CHECK, IDC_GAME_DIR_BUTTON, false, true },
{ "Lightmap", "\\\\mobius\\project7\\projects\\renegade\\programming\\tools\\lightmap", "c:\\commando\\lightmap", "LightMap\\Install", IDC_LIGHTMAP_CHECK, IDC_LIGHTMAP_CLEAN_CHECK, IDC_LIGHTMAP_DIR_BUTTON, true, false },
{ "Vis Farm", "\\\\mobius\\project7\\projects\\renegade\\programming\\tools\\vis farm", "c:\\commando\\vis farm", "VisFarm\\Install", IDC_VISFARM_CHECK, IDC_VISFARM_CLEAN_CHECK, IDC_VISFARM_DIR_BUTTON, false, false },
{ "Mix Viewer", "\\\\mobius\\project7\\projects\\renegade\\programming\\tools\\mixview", "c:\\commando\\mixview", "MixView\\Install", IDC_MIXVIEW_CHECK, IDC_MIXVIEW_CLEAN_CHECK, IDC_MIXVIEW_DIR_BUTTON, false, false },
{ "Multiplay", "\\\\tanya\\game\\projects\\renegade\\run", "c:\\renegade\\mplay", "MPlay\\Install", IDC_MULTIPLAY_CHECK, IDC_MULTIPLAY_CLEAN_CHECK, IDC_MULTIPLAY_DIR_BUTTON, false, true }
};
const char * const INSTALL_REG_VALUE = "Path";
const char * const DATA_SUB_DIR = "\\Data";
const char * const MOVIE_SUB_DIR = "\\Data\\Movies";
const char * const SRDLL_SUB_DIR = "\\SrDLL";
/////////////////////////////////////////////////////////////////////////////
//
// Local prototypes
//
/////////////////////////////////////////////////////////////////////////////
bool Update_App (CWnd *parent_wnd, LPCTSTR title, LPCTSTR src_dir, LPCTSTR dest_dir, bool is_recursive);
bool Clean_Directory (LPCTSTR local_dir, bool is_recursive);
bool Get_Install_Directory (HWND hparent_wnd, LPCTSTR title, CString &folder);
bool Delete_File (LPCTSTR filename);
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateDlg dialog
CCommandoUpdateDlg::CCommandoUpdateDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCommandoUpdateDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCommandoUpdateDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCommandoUpdateDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCommandoUpdateDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCommandoUpdateDlg, CDialog)
//{{AFX_MSG_MAP(CCommandoUpdateDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_DEFAULTS, OnDefaults)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateDlg message handlers
BOOL CCommandoUpdateDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 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
//
// Check/uncheck the applications by default
//
for (int index = 0; index < APP_MAX; index ++) {
const APP_INFO &app_info = APPLICATIONS[index];
HKEY hreg_key = NULL;
CString reg_key_name;
reg_key_name.Format ("Software\\Westwood Studios\\%s", app_info.reg_key);
TCHAR path[MAX_PATH] = { 0 };
//
// Is this application installed?
//
if (::RegOpenKeyEx (HKEY_CURRENT_USER, reg_key_name, 0L, KEY_READ, &hreg_key) == ERROR_SUCCESS) {
SendDlgItemMessage (app_info.ctrl_id, BM_SETCHECK, (WPARAM)TRUE);
//
// Read the installation directory from the registry
//
DWORD size = sizeof (path);
::RegQueryValueEx (hreg_key, INSTALL_REG_VALUE, 0L, NULL, (BYTE *)path, &size);
::RegCloseKey (hreg_key);
} else {
::EnableWindow (::GetDlgItem (m_hWnd, app_info.clean_ctrl_id), false);
::EnableWindow (::GetDlgItem (m_hWnd, app_info.dir_ctrl_id), false);
}
//
// Set the text of the install directory buttons
//
if (path[0] == 0) {
::lstrcpy (path, app_info.default_dir);
}
SetDlgItemText (app_info.dir_ctrl_id, path);
//
// Check the clean option (by default) if necessary
//
if (app_info.clean_default) {
SendDlgItemMessage (app_info.clean_ctrl_id, BM_SETCHECK, (WPARAM)TRUE);
}
}
return TRUE;
}
// 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 CCommandoUpdateDlg::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 CCommandoUpdateDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//////////////////////////////////////////////////////////////////////////////////
//
// OnOK
//
//////////////////////////////////////////////////////////////////////////////////
void
CCommandoUpdateDlg::OnOK (void)
{
//
// Install/upgrade each application
//
bool success = true;
for (int index = 0; (index < APP_MAX) && success; index ++) {
const APP_INFO &app_info = APPLICATIONS[index];
//
// Does the user want to install this application?
//
if (SendDlgItemMessage (app_info.ctrl_id, BM_GETCHECK) == 1) {
HKEY hreg_key = NULL;
CString reg_key_name;
reg_key_name.Format ("Software\\Westwood Studios\\%s", app_info.reg_key);
//
// Get the path where this application is installed
//
CString local_path;
GetDlgItemText (app_info.dir_ctrl_id, local_path);
// Ensure the path doesn't contain a terminating delimiter
if (local_path[::lstrlen (local_path) - 1] == '\\') {
local_path.Delete (::lstrlen (local_path) - 1, 1);
}
if (success) {
CWaitCursor wait_cursor;
//
// Clean the old version if necessary
//
if (SendDlgItemMessage (app_info.clean_ctrl_id, BM_GETCHECK) == 1) {
//
// Special case the "game engine only" option. Note: we only want
// to clean the data subdir if we aren't cleaning the game directory
//
if (index == APP_GAME_LEVELS || index == APP_GAME_MOVIES) {
if (SendDlgItemMessage (APPLICATIONS[APP_GAME_ENGINE].ctrl_id, BM_GETCHECK) == 0) {
if (index == APP_GAME_MOVIES) {
CString data_dir = local_path + MOVIE_SUB_DIR;
::Clean_Directory (data_dir, app_info.is_recursive);
} else {
CString data_dir = local_path + DATA_SUB_DIR;
::Clean_Directory (data_dir, app_info.is_recursive);
}
}
} else {
::Clean_Directory (local_path, app_info.is_recursive);
}
}
//
// Special case the "game levels" option
//
if (index == APP_GAME_LEVELS) {
CString data_dir = local_path + DATA_SUB_DIR;
CString src_data_dir = app_info.src;
CString data_title = "Game Levels";
success &= ::Update_App (this, data_title, src_data_dir, data_dir, app_info.is_recursive);
} else if (index == APP_GAME_MOVIES) {
CString data_dir = local_path + MOVIE_SUB_DIR;
CString src_data_dir = app_info.src;
CString data_title = "Game Movies";
success &= ::Update_App (this, data_title, src_data_dir, data_dir, app_info.is_recursive);
} else {
//
// Update the application's files
//
success &= ::Update_App (this, app_info.title, app_info.src, local_path, app_info.is_recursive);
}
//
// Write the app's installation dir to the registry if we
// installed it correctly.
//
if (success) {
success &= (::RegCreateKeyEx ( HKEY_CURRENT_USER,
reg_key_name,
0L,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hreg_key,
NULL) == ERROR_SUCCESS);
if (success) {
::RegSetValueEx ( hreg_key,
INSTALL_REG_VALUE,
0L,
REG_SZ,
(BYTE *)(LPCTSTR)local_path,
local_path.GetLength () + 1);
::RegCloseKey (hreg_key);
}
}
}
}
}
CDialog::OnOK ();
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Get_Install_Directory
//
//////////////////////////////////////////////////////////////////////////////////
bool
Get_Install_Directory (HWND hparent_wnd, LPCTSTR title, CString &folder)
{
bool retval = false;
// Browse for the folder
BROWSEINFO browse_info = { 0 };
browse_info.hwndOwner = hparent_wnd;
browse_info.lpszTitle = title;
browse_info.ulFlags = BIF_RETURNONLYFSDIRS;
LPITEMIDLIST pidl = ::SHBrowseForFolder (&browse_info);
if (pidl != NULL) {
// Convert the 'PIDL' into a string
char path[MAX_PATH];
retval = (::SHGetPathFromIDList (pidl, path) == TRUE);
if (retval) {
folder = path;
}
// Free the 'PIDL'
LPMALLOC pmalloc = NULL;
if (SUCCEEDED (::SHGetMalloc (&pmalloc))) {
pmalloc->Free (pidl);
pmalloc->Release ();
}
}
//CFileDialog dialog (TRUE, ".pth", "test.pth", OFN_PATHMUSTEXIST | OFN_EXPLORER, "files *.*|*.*||", CWnd::FromHandle(hparent_wnd));
//CFileDialog dialog (TRUE, ".pth", "test.pth", OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_ENABLETEMPLATEHANDLE, "files *.*|*.*||", CWnd::FromHandle(hparent_wnd));
//dialog.m_ofn.lpTemplateName = MAKEINTRESOURCE (IDD_DIR_SELECT_DIALOG);
//dialog.m_ofn.hInstance = ::AfxGetInstanceHandle ();
//HRSRC resource = ::FindResource (::AfxGetInstanceHandle (), MAKEINTRESOURCE (IDD_DIR_SELECT_DIALOG), RT_DIALOG);
//dialog.m_ofn.hInstance = (HINSTANCE)::LoadResource (::AfxGetInstanceHandle (), resource);
//dialog.DoModal ();
/*TCHAR path[MAX_PATH] = { 0 };
OPENFILENAME ofn = { 0 };
ofn.lStructSize = sizeof (ofn);
ofn.Flags = OFN_PATHMUSTEXIST | OFN_ENABLETEMPLATE;
ofn.hInstance = ::AfxGetInstanceHandle ();
ofn.lpTemplateName = MAKEINTRESOURCE (IDD_DIR_SELECT_DIALOG);
ofn.hwndOwner = hparent_wnd;
ofn.lpstrFile = path;
ofn.nMaxFile = sizeof (path);
GetOpenFileName (&ofn);
::CommDlgExtendedError ();*/
//retval = (dialog.DoModal () == IDOK);
// Return the true/false result code
return retval;
}
////////////////////////////////////////////////////////////////////////////
//
// Strip_Filename_From_Path
//
////////////////////////////////////////////////////////////////////////////
CString
Strip_Filename_From_Path (LPCTSTR path)
{
// Copy the path to a buffer we can modify
TCHAR temp_path[MAX_PATH];
::lstrcpy (temp_path, path);
// Find the last occurance of the directory deliminator
LPTSTR filename = ::strrchr (temp_path, '\\');
if (filename != NULL) {
// Strip off the filename
filename[0] = 0;
}
// Return the path only
return CString (temp_path);
}
////////////////////////////////////////////////////////////////////////////
//
// Delete_File
//
////////////////////////////////////////////////////////////////////////////
bool
Delete_File (LPCTSTR filename)
{
// Assume failure
bool retval = false;
ASSERT (filename != NULL);
if (filename != NULL) {
// Strip the readonly bit off if necessary
DWORD attributes = ::GetFileAttributes (filename);
if ((attributes != 0xFFFFFFFF) &&
((attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY))
{
::SetFileAttributes (filename, attributes & (~FILE_ATTRIBUTE_READONLY));
}
// Perform the delete operation!
if ((attributes != 0xFFFFFFFF) &&
((attributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
{
retval = ::RemoveDirectory (filename) == TRUE;
} else {
retval = ::DeleteFile (filename) == TRUE;
}
}
// Return the true/false result code
return retval;
}
////////////////////////////////////////////////////////////////////////////
//
// Copy_File
//
////////////////////////////////////////////////////////////////////////////
bool
Copy_File
(
LPCTSTR existing_filename,
LPCTSTR new_filename,
bool bforce_copy
)
{
// Assume failure
bool retval = false;
ASSERT (existing_filename != NULL);
ASSERT (new_filename != NULL);
if ((existing_filename != NULL) &&
(new_filename != NULL)) {
// Make sure we aren't copying over ourselves
bool allow_copy = (::lstrcmpi (existing_filename, new_filename) != 0);
// Strip the readonly bit off if necessary
DWORD attributes = ::GetFileAttributes (new_filename);
if (allow_copy &&
(attributes != 0xFFFFFFFF) &&
((attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY)) {
if (bforce_copy) {
::SetFileAttributes (new_filename, attributes & (~FILE_ATTRIBUTE_READONLY));
} else {
allow_copy = false;
}
}
// Perform the copy operation!
if (allow_copy) {
retval = (::CopyFile (existing_filename, new_filename, FALSE) == TRUE);
}
}
// Return the true/false result code
return retval;
}
__inline void Delimit_Path (CString &path)
{
if (path[::lstrlen (path) - 1] != '\\') {
path += CString ("\\");
}
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Clean_Directory
//
//////////////////////////////////////////////////////////////////////////////////
bool
Clean_Directory (LPCTSTR local_dir, bool is_recursive)
{
bool retval = true;
// Build a search mask from the directory
CString search_mask = CString (local_dir) + "\\*.*";
// Loop through all the files in this directory and add them
// to our list
CStringList file_list;
BOOL bcontinue = TRUE;
WIN32_FIND_DATA find_info = { 0 };
for (HANDLE hfind = ::FindFirstFile (search_mask, &find_info);
(hfind != INVALID_HANDLE_VALUE) && bcontinue;
bcontinue = ::FindNextFile (hfind, &find_info)) {
// If this file isn't a directory, add it to the list
if (!(find_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
CString filename = find_info.cFileName;
file_list.AddTail (filename);
} else if (is_recursive && find_info.cFileName[0] != '.') {
//
// Recurse into this subdirectory
//
CString full_path = local_dir;
::Delimit_Path (full_path);
full_path += find_info.cFileName;
Clean_Directory (full_path, is_recursive);
//
// Add this directory to the list so it will get
// deleted with the files...
//
CString filename = find_info.cFileName;
file_list.AddTail (filename);
}
}
// Close the search handle
if (hfind != NULL) {
::FindClose (hfind);
}
//
// Now loop through all the files and delete them
//
for (POSITION pos = file_list.GetHeadPosition (); pos != NULL; ) {
CString &filename = file_list.GetNext (pos);
CString full_path = local_dir + CString ("\\") + filename;
if (::Delete_File (full_path) == FALSE) {
CString message;
message.Format ("Cannot delete %s. This may result in an incomplete update. Please make sure no applications are running before running the update.", full_path);
::MessageBox (NULL, message, "Delete Error", MB_SETFOREGROUND | MB_TOPMOST | MB_ICONEXCLAMATION | MB_OK);
retval = false;
}
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Create_Dir_If_Necessary
//
//////////////////////////////////////////////////////////////////////////////////
void
Create_Dir_If_Necessary (LPCTSTR path)
{
if (::GetFileAttributes (path) == 0xFFFFFFFF) {
Create_Dir_If_Necessary (::Strip_Filename_From_Path (path));
::CreateDirectory (path, NULL);
}
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Build_File_List
//
//////////////////////////////////////////////////////////////////////////////////
void
Build_File_List (LPCTSTR search_path, CStringList &file_list)
{
//
// Loop through all the files in this directory and add them
// to our list
//
BOOL keep_going = TRUE;
WIN32_FIND_DATA find_info = { 0 };
for (HANDLE hfind = ::FindFirstFile (search_path, &find_info);
(hfind != INVALID_HANDLE_VALUE) && keep_going;
keep_going = ::FindNextFile (hfind, &find_info))
{
//
// If this file isn't a directory, add it to the list
//
if (!(find_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
CString filename = find_info.cFileName;
file_list.AddTail (filename);
}
}
// Close the search handle
if (hfind != NULL) {
::FindClose (hfind);
}
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// Quick_Compare_Files
//
////////////////////////////////////////////////////////////////////////////
int
Quick_Compare_Files
(
LPCTSTR file1,
LPCTSTR file2
)
{
// Assume they are the same
int compare = 0;
// Params OK?
ASSERT (file1 != NULL);
ASSERT (file2 != NULL);
if ((file1 != NULL) && (file2 != NULL)) {
// Attempt to open file1
HANDLE hfile1 = ::CreateFile (file1,
0,
0,
NULL,
OPEN_EXISTING,
0L,
NULL);
// Attempt to open file2
HANDLE hfile2 = ::CreateFile (file2,
0,
0,
NULL,
OPEN_EXISTING,
0L,
NULL);
if ((hfile1 != INVALID_HANDLE_VALUE) && (hfile2 != INVALID_HANDLE_VALUE)) {
// Get information about these 2 files.
BY_HANDLE_FILE_INFORMATION file1_info = { 0 };
BY_HANDLE_FILE_INFORMATION file2_info = { 0 };
::GetFileInformationByHandle (hfile1, &file1_info);
::GetFileInformationByHandle (hfile2, &file2_info);
// Compare the time these files were last written to
compare = ::CompareFileTime (&file1_info.ftLastWriteTime, &file2_info.ftLastWriteTime);
} else if ((hfile1 == INVALID_HANDLE_VALUE) && (hfile2 != INVALID_HANDLE_VALUE)) {
compare = -1;
} else if ((hfile1 != INVALID_HANDLE_VALUE) && (hfile2 == INVALID_HANDLE_VALUE)) {
compare = 1;
}
if (hfile1 != INVALID_HANDLE_VALUE) {
::CloseHandle (hfile1);
}
if (hfile2 != INVALID_HANDLE_VALUE) {
::CloseHandle (hfile2);
}
}
// Same as strcmp, -1 if file1 is older than file2, 0 if equal, 1 if file1 is newer than file2
return compare;
}
//////////////////////////////////////////////////////////////////////////////////
//
// FileNeedsCopying
//
//////////////////////////////////////////////////////////////////////////////////
bool
FileNeedsCopying (LPCTSTR src_path, LPCTSTR dest_path)
{
return (Quick_Compare_Files (src_path, dest_path) != 0);
}
//////////////////////////////////////////////////////////////////////////////////
//
// Update_App_Directory
//
//////////////////////////////////////////////////////////////////////////////////
bool
Update_App_Directory
(
FileCopyDialogClass * dialog,
LPCTSTR src_dir,
LPCTSTR dest_dir,
bool is_recursive
)
{
bool retval = true;
//
// Build search masks from the src and dest directories
//
CString remote_search_mask = src_dir;
remote_search_mask += "\\*.*";
//
// Loop through all the files in this directory and add them
// to our list
//
BOOL keep_going = TRUE;
WIN32_FIND_DATA find_info = { 0 };
CStringList file_list;
for (HANDLE hfind = ::FindFirstFile (remote_search_mask, &find_info);
(hfind != INVALID_HANDLE_VALUE) && keep_going && retval;
keep_going = ::FindNextFile (hfind, &find_info))
{
//
// If this file isn't a directory, add it to the list
//
if (!(find_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
CString filename = find_info.cFileName;
file_list.AddTail (filename);
} else if (is_recursive && find_info.cFileName[0] != '.') {
//
// Recurse into this subdirectory
//
CString full_src_path = src_dir;
CString full_dest_path = dest_dir;
::Delimit_Path (full_src_path);
::Delimit_Path (full_dest_path);
full_src_path += find_info.cFileName;
full_dest_path += find_info.cFileName;
retval &= ::Update_App_Directory ( dialog,
full_src_path,
full_dest_path,
is_recursive);
}
}
// Close the search handle
if (hfind != NULL) {
::FindClose (hfind);
}
//
// Now loop through all the files and copy them to the src
//
for (POSITION pos = file_list.GetHeadPosition (); pos != NULL && retval; ) {
CString &filename = file_list.GetNext (pos);
CString src_file = src_dir + CString ("\\") + filename;
CString dest_file = dest_dir + CString ("\\") + filename;
//
// Make sure the destination directory exists
//
::Create_Dir_If_Necessary (dest_dir);
//
// Do a file comparison to determine whether or not to copy the file
//
if (::FileNeedsCopying (src_file, dest_file)) {
//
// Update the dialog
//
dialog->Set_Current_File (filename);
//
// Copy the file
//
if (::Copy_File (src_file, dest_file, true) == FALSE) {
CString message;
message.Format ("Cannot copy %s to %s. Please make sure no applications are running before running the update.", src_file, dest_file);
::MessageBox (NULL, message, "Copy Error", MB_SETFOREGROUND | MB_TOPMOST | MB_ICONEXCLAMATION | MB_OK);
retval = false;
}
}
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// fnUpdateAppDirectory
//
//////////////////////////////////////////////////////////////////////////////////
UINT
fnUpdateAppDirectory (LPVOID pParam)
{
UPDATE_INFO *info = (UPDATE_INFO *)pParam;
ASSERT (info != NULL);
if (info != NULL) {
//
// Begin updating this directory...
//
info->result = ::Update_App_Directory ( info->dialog,
info->src_dir,
info->dest_dir,
info->is_recursive);
//
// Kill the updating dialog
//
::PostMessage (info->dialog->m_hWnd, WM_USER + 101, 0, 0L);
}
return 1;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Update_App
//
//////////////////////////////////////////////////////////////////////////////////
bool
Update_App
(
CWnd * parent_wnd,
LPCTSTR title,
LPCTSTR src_dir,
LPCTSTR dest_dir,
bool is_recursive
)
{
CWaitCursor wait_cursor;
FileCopyDialogClass dialog (parent_wnd);
dialog.Set_Current_Application (title);
//
// Kick off a worker thread to do the actual file copy
//
UPDATE_INFO *info = new UPDATE_INFO;
info->dialog = &dialog;
info->src_dir = src_dir;
info->dest_dir = dest_dir;
info->is_recursive = is_recursive;
::AfxBeginThread (fnUpdateAppDirectory, (LPVOID)info);
//
// Display a dialog to monitor the progress
//
dialog.DoModal ();
bool retval = info->result;
delete info;
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// OnCommand
//
//////////////////////////////////////////////////////////////////////////////////
BOOL
CCommandoUpdateDlg::OnCommand
(
WPARAM wParam,
LPARAM lParam
)
{
bool found = false;
for (int index = 0; (index < APP_MAX) && (found == false); index ++) {
const APP_INFO &app_info = APPLICATIONS[index];
if (LOWORD (wParam) == app_info.ctrl_id) {
bool enable = (SendDlgItemMessage (LOWORD(wParam), BM_GETCHECK) == 1);
if (index == APP_GAME_ENGINE) {
enable |= (SendDlgItemMessage (APPLICATIONS[APP_GAME_LEVELS].ctrl_id, BM_GETCHECK) == 1);
enable |= (SendDlgItemMessage (APPLICATIONS[APP_GAME_MOVIES].ctrl_id, BM_GETCHECK) == 1);
} else if (index == APP_GAME_LEVELS || index == APP_GAME_MOVIES) {
enable |= (SendDlgItemMessage (APPLICATIONS[APP_GAME_ENGINE].ctrl_id, BM_GETCHECK) == 1);
}
//
// Enable or disable the clean and directory buttons
//
::EnableWindow (::GetDlgItem (m_hWnd, app_info.clean_ctrl_id), enable);
::EnableWindow (::GetDlgItem (m_hWnd, app_info.dir_ctrl_id), enable);
} else if (LOWORD (wParam) == app_info.dir_ctrl_id) {
//
// Change the installation directoy
//
CString directory;
CString dlg_title;
dlg_title.Format ("Select a directory to install the %s to.", app_info.title);
if (Get_Install_Directory (m_hWnd, dlg_title, directory)) {
SetDlgItemText (app_info.dir_ctrl_id, directory);
}
found = true;
}
}
return CDialog::OnCommand(wParam, lParam);
}
//////////////////////////////////////////////////////////////////////////////////
//
// OnDefaults
//
//////////////////////////////////////////////////////////////////////////////////
void
CCommandoUpdateDlg::OnDefaults (void)
{
for (int index = 0; index < APP_MAX; index ++) {
const APP_INFO &app_info = APPLICATIONS[index];
if (SendDlgItemMessage (app_info.ctrl_id, BM_GETCHECK) != 0) {
SetDlgItemText (app_info.dir_ctrl_id, app_info.default_dir);
}
}
return ;
}

View File

@@ -0,0 +1,69 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// CommandoUpdateDlg.h : header file
//
#if !defined(AFX_COMMANDOUPDATEDLG_H__4305AC50_1EAB_11D3_A038_00104B791122__INCLUDED_)
#define AFX_COMMANDOUPDATEDLG_H__4305AC50_1EAB_11D3_A038_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateDlg dialog
class CCommandoUpdateDlg : public CDialog
{
// Construction
public:
CCommandoUpdateDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CCommandoUpdateDlg)
enum { IDD = IDD_COMMANDOUPDATE_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCommandoUpdateDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CCommandoUpdateDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
virtual void OnOK();
afx_msg void OnDefaults();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COMMANDOUPDATEDLG_H__4305AC50_1EAB_11D3_A038_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,99 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// FileCopyDialog.cpp : implementation file
//
#include "stdafx.h"
#include "CommandoUpdate.h"
#include "FileCopyDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// FileCopyDialogClass dialog
FileCopyDialogClass::FileCopyDialogClass(CWnd* pParent /*=NULL*/)
: CDialog(FileCopyDialogClass::IDD, pParent)
{
//{{AFX_DATA_INIT(FileCopyDialogClass)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void FileCopyDialogClass::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(FileCopyDialogClass)
DDX_Control(pDX, IDC_ANIMATE_CTRL, m_AnimateCtrl);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(FileCopyDialogClass, CDialog)
//{{AFX_MSG_MAP(FileCopyDialogClass)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////////
//
// WindowProc
//
//////////////////////////////////////////////////////////////////////////////
LRESULT
FileCopyDialogClass::WindowProc
(
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
if (message == WM_USER + 101) {
EndDialog (TRUE);
}
return CDialog::WindowProc(message, wParam, lParam);
}
//////////////////////////////////////////////////////////////////////////////
//
// OnInitDialog
//
//////////////////////////////////////////////////////////////////////////////
BOOL
FileCopyDialogClass::OnInitDialog (void)
{
CDialog::OnInitDialog();
CString app_title;
app_title.Format ("Application: %s", m_AppTitle);
SetDlgItemText (IDC_CURRENT_APP, app_title);
m_AnimateCtrl.Open (IDR_FILECOPY_AVI);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

View File

@@ -0,0 +1,72 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(AFX_FILECOPYDIALOG_H__4305AC5C_1EAB_11D3_A038_00104B791122__INCLUDED_)
#define AFX_FILECOPYDIALOG_H__4305AC5C_1EAB_11D3_A038_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// FileCopyDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// FileCopyDialogClass dialog
class FileCopyDialogClass : public CDialog
{
// Construction
public:
FileCopyDialogClass(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(FileCopyDialogClass)
enum { IDD = IDD_FILE_COPY };
CAnimateCtrl m_AnimateCtrl;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(FileCopyDialogClass)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(FileCopyDialogClass)
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
void Set_Current_File (LPCTSTR filename) { if (m_hWnd != NULL) SetDlgItemText (IDC_FILENAME_TEXT, filename); }
void Set_Current_Application (LPCTSTR filename) { m_AppTitle = filename; }
private:
CString m_AppTitle;
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_FILECOPYDIALOG_H__4305AC5C_1EAB_11D3_A038_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,26 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// stdafx.cpp : source file that includes just the standard includes
// CommandoUpdate.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View File

@@ -0,0 +1,44 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__4305AC52_1EAB_11D3_A038_00104B791122__INCLUDED_)
#define AFX_STDAFX_H__4305AC52_1EAB_11D3_A038_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__4305AC52_1EAB_11D3_A038_00104B791122__INCLUDED_)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,13 @@
//
// COMMANDOUPDATE.RC2 - resources Microsoft Visual C++ does not edit directly
//
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Add manually edited resources here...
/////////////////////////////////////////////////////////////////////////////

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -0,0 +1,51 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by CommandoUpdate.rc
//
#define IDC_DEFAULTS 3
#define IDD_COMMANDOUPDATE_DIALOG 102
#define IDD_FILE_COPY 103
#define IDR_MAINFRAME 128
#define IDI_COPY 129
#define IDR_FILECOPY_AVI 129
#define IDC_EDITOR_CHECK 1000
#define IDC_ANIMATE_CTRL 1000
#define IDC_GAME_CHECK 1001
#define IDC_FILENAME_TEXT 1001
#define IDC_VIEWER_CHECK 1002
#define IDC_CURRENT_APP 1002
#define IDC_GAME_LEVELS_CHECK 1002
#define IDC_MAX_PLUGIN_CHECK 1003
#define IDC_GAME_MOVIES_CHECK 1003
#define IDC_EDITOR_CLEAN_CHECK 1004
#define IDC_GAME_CLEAN_CHECK 1005
#define IDC_VIEWER_CLEAN_CHECK 1006
#define IDC_MULTIPLAY_CHECK 1006
#define IDC_WDUMP_CHECK 1007
#define IDC_MULTIPLAY_CLEAN_CHECK 1007
#define IDC_MAX_PLUGIN_CLEAN_CHECK 1008
#define IDC_WDUMP_CLEAN_CHECK 1009
#define IDC_LIGHTMAP_CHECK 1010
#define IDC_LIGHTMAP_CLEAN_CHECK 1011
#define IDC_EDITOR_DIR_BUTTON 1012
#define IDC_VISFARM_CHECK 1013
#define IDC_GAME_DIR_BUTTON 1014
#define IDC_VISFARM_CLEAN_CHECK 1015
#define IDC_MIXVIEW_CHECK 1016
#define IDC_MIXVIEW_CLEAN_CHECK 1017
#define IDC_LIGHTMAP_DIR_BUTTON 1018
#define IDD_DIR_SELECT_DIALOG 1019
#define IDC_VISFARM_DIR_BUTTON 1019
#define IDC_MIXVIEW_DIR_BUTTON 1020
#define IDC_MULTIPLAY_DIR_BUTTON 1021
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1013
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif