This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Tools/W3DView/W3DView.cpp

474 lines
11 KiB
C++
Raw Permalink Normal View History

/*
** 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/>.
*/
// W3DView.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "w3dview.h"
#include "mainfrm.h"
#include "w3dviewdoc.h"
#include "w3dviewview.h"
#include "utils.h"
#include "colorutils.h"
#include "verchk.h"
#include "wwmath.h"
#include "wwaudio.h"
#include "viewerassetmgr.h"
#include "globals.h"
#include "animatedsoundoptionsdialog.h"
#include "animatedsoundmgr.h"
#undef STRICT
#include "ww3d.h"
#include "AssetMgr.H"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//
// Local prototypes
//
BOOL CALLBACK fnTopLevelWindowSearch (HWND hwnd, LPARAM lParam);
/////////////////////////////////////////////////////////////////////////////
//
// CW3DViewApp
//
BEGIN_MESSAGE_MAP(CW3DViewApp, CWinApp)
//{{AFX_MSG_MAP(CW3DViewApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//
// CW3DViewApp construction
//
CW3DViewApp::CW3DViewApp (void)
: m_bInitialized (false)
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CW3DViewApp object
CW3DViewApp theApp;
extern int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow);
int WINAPI
WinMain
(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow
)
{
int retcode = 0;
#ifndef _DEBUG
try
{
#endif //_DEBUG
//::AfxWinInit (hInstance, hPrevInstance, lpCmdLine, nCmdShow);
//::AfxInitialize (FALSE, _MFC_VER);
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
pModuleState->m_bDLL = (BYTE)FALSE;
#ifdef _MBCS
// set correct multi-byte code-page for Win32 apps
_setmbcp(_MB_CP_ANSI);
#endif //_MBCS
retcode = ::AfxWinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow);
#ifndef _DEBUG
}
catch (...)
{
::MessageBox (NULL, "Internal Application Error", "Unrecoverable Error", MB_ICONERROR | MB_OK);
}
#endif //_DEBUG
return retcode;
}
///////////////////////////////////////////////////////////////
//
// Do_Version_Check
//
////////////////////////////////////////////////////////////
void
Do_Version_Check (void)
{
char curr_filename[MAX_PATH];
::GetModuleFileName (NULL, curr_filename, MAX_PATH);
CString filename = "\\\\cabal\\mis\\r&d\\w3d\\w3dview\\";
filename += ::Get_Filename_From_Path (curr_filename);
//
// Check the version of the viewer that is out on the network
// against the version we are running.
//
if (Compare_EXE_Version ((int)::AfxGetInstanceHandle (), filename) < 0) {
::MessageBox (NULL, "There is a newer version of the W3DViewer, please run W3DUpdate to upgrade your local copy.", "Version Info", MB_ICONEXCLAMATION | MB_OK | MB_SETFOREGROUND | MB_SYSTEMMODAL);
}
return ;
}
/////////////////////////////////////////////////////////////////////////////
//
// InitInstance
//
BOOL CW3DViewApp::InitInstance (void)
{
// 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
Do_Version_Check ();
RegisterColorPicker (::AfxGetInstanceHandle ());
RegisterColorBar (::AfxGetInstanceHandle ());
// Is there already an instance of the viewer running?
HWND hprev_instance = NULL;
::EnumWindows (fnTopLevelWindowSearch, (LPARAM)&hprev_instance);
if (hprev_instance == NULL) {
// Change the registry key under which our settings are stored.
// You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Westwood Studios"));
//
// Load standard INI file options (including MRU)
//
LoadStdProfileSettings (9);
//
// Initialize the libraries
//
WWMath::Init ();
AnimatedSoundOptionsDialogClass::Load_Animated_Sound_Settings ();
//
// Disable the 3DFX logo
//
_putenv ("FX_GLIDE_NO_SPLASH=1");
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CW3DViewDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CW3DViewView));
AddDocTemplate(pDocTemplate);
// Enable DDE Execute open
EnableShellOpen();
RegisterShellFileTypes(TRUE);
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
//
// Allocate an asset manager
//
_TheAssetMgr = new ViewerAssetMgrClass;
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
::SetProp (*m_pMainWnd, "WW3DVIEWER", (HANDLE)1);
// Enable drag/drop open
m_pMainWnd->DragAcceptFiles();
m_bInitialized = true;
} else {
// Make the previous instance in the foreground
::ShowWindow (hprev_instance, SW_NORMAL);
::BringWindowToTop (hprev_instance);
::SetForegroundWindow (hprev_instance);
}
return (hprev_instance == NULL);
}
/////////////////////////////////////////////////////////////////////////////
// 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)
virtual BOOL OnInitDialog();
//}}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)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// App command to run the dialog
void CW3DViewApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
/*
**
*/
void Debug_Refs(void)
{
#ifndef NDEBUG
TRACE("Detecting Active Refs...\r\n");
//ODS("At time %s", cMiscUtil::Get_Text_Time());
RefCountNodeClass * first = RefCountClass::ActiveRefList.First();
RefCountNodeClass * node = first;
while (node->Is_Valid())
{
RefCountClass * obj = node->Get();
ActiveRefStruct * ref = &(obj->ActiveRefInfo);
bool display = true;
int count = 0;
RefCountNodeClass * search = first;
while (search->Is_Valid()) {
if (search == node) { // if this is not the first one
if (count != 0) {
display = false;
break;
}
}
RefCountClass * search_obj = search->Get();
ActiveRefStruct * search_ref = &(search_obj->ActiveRefInfo);
if ( ref->File && search_ref->File &&
!strcmp(search_ref->File, ref->File) &&
(search_ref->Line == ref->Line) ) {
count++;
} else if ( (ref->File == NULL) && (search_ref->File == NULL) ) {
count++;
}
search = search->Next();
}
if ( display ) {
TRACE ( "%d Active Ref: %s %d %p\n", count, ref->File,ref->Line,obj);
static int num_printed = 0;
if (++num_printed > 20) {
TRACE( "And Many More......\n");
break;
}
}
node = node->Next();
}
TRACE("Done.\r\n");
//ODS("At time %s", cMiscUtil::Get_Text_Time());
#endif
}
/////////////////////////////////////////////////////////////////////////////
//
// CW3DViewApp
//
int
CW3DViewApp::ExitInstance()
{
//
// Free any resources the WW3D engine allocated
//
if (m_bInitialized) {
//
// Shutdown the audio system
//
WWAudioClass::Get_Instance ()->Shutdown ();
//
// Shutdown W3D
//
WW3DAssetManager::Get_Instance()->Free_Assets ();
WW3D::Shutdown ();
//
// Shutdown the libraries
//
WWMath::Shutdown ();
AnimatedSoundMgrClass::Shutdown ();
//
// Free the asset manager
//
delete _TheAssetMgr;
_TheAssetMgr = NULL;
}
Debug_Refs ();
return CWinApp::ExitInstance ();
}
//////////////////////////////////////////////////////////////////////////////
//
// fnTopLevelWindowSearch
//
BOOL CALLBACK
fnTopLevelWindowSearch
(
HWND hwnd,
LPARAM lParam
)
{
BOOL bcontinue = TRUE;
// Is this a viewer window?
if (::GetProp (hwnd, "WW3DVIEWER") != 0) {
bcontinue = false;
(*((HWND *)lParam)) = hwnd;
}
// Return the TRUE/FALSE result code
return bcontinue;
}
//////////////////////////////////////////////////////////////////////////////
//
// OnInitDialog
//
BOOL
CAboutDlg::OnInitDialog (void)
{
// Allow the base class to process this message
CDialog::OnInitDialog ();
// Version 1.0 by default
DWORD version_major = 1;
DWORD version_minor = 0;
// Get the name and path of the currently executing application
TCHAR filename[MAX_PATH];
::GetModuleFileName (NULL, filename, sizeof (filename));
// Get the version information for this file
DWORD dummy_var = 0;
DWORD version_size = ::GetFileVersionInfoSize (filename, &dummy_var);
if (version_size > 0) {
// Get the file version block
LPBYTE pblock = new BYTE[version_size];
if (::GetFileVersionInfo (filename, 0L, version_size, pblock)) {
// Query the block for the file version information
UINT version_len = 0;
VS_FIXEDFILEINFO *pversion_info = NULL;
if (::VerQueryValue (pblock, "\\", (LPVOID *)&pversion_info, &version_len)) {
version_major = pversion_info->dwFileVersionMS;
version_minor = pversion_info->dwFileVersionLS;
}
}
SAFE_DELETE (pblock);
}
// Put the version string into the dialog
CString version_string;
version_string.Format (IDS_VERSION, (version_major >> 16), (version_major & 0xFFFF));
SetDlgItemText (IDC_VERSION, version_string);
return TRUE;
}