mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-16 07:31:40 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
111
Code/Tools/W3DView/AddToLineupDialog.cpp
Normal file
111
Code/Tools/W3DView/AddToLineupDialog.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// AddToLineupDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "AddToLineupDialog.h"
|
||||
|
||||
#include "ViewerScene.h"
|
||||
#include <rendobj.h>
|
||||
#include <assetmgr.h>
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAddToLineupDialog dialog
|
||||
|
||||
|
||||
CAddToLineupDialog::CAddToLineupDialog(ViewerSceneClass *scene, CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CAddToLineupDialog::IDD, pParent),
|
||||
m_pCScene(scene)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CAddToLineupDialog)
|
||||
m_Object = _T("");
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void CAddToLineupDialog::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CAddToLineupDialog)
|
||||
DDX_CBString(pDX, IDC_OBJECT, m_Object);
|
||||
DDV_MaxChars(pDX, m_Object, 64);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAddToLineupDialog, CDialog)
|
||||
//{{AFX_MSG_MAP(CAddToLineupDialog)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAddToLineupDialog message handlers
|
||||
|
||||
BOOL CAddToLineupDialog::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
if (m_pCScene)
|
||||
{
|
||||
// Get a pointer to the combo box control.
|
||||
CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_OBJECT);
|
||||
ASSERT_VALID(pCombo);
|
||||
|
||||
// Populate the combo box with the names of the objects that
|
||||
// can be added to the lineup.
|
||||
WW3DAssetManager *assets = WW3DAssetManager::Get_Instance();
|
||||
ASSERT(assets != NULL);
|
||||
RenderObjIterator *it = assets->Create_Render_Obj_Iterator();
|
||||
ASSERT(it != NULL);
|
||||
for (; !it->Is_Done(); it->Next())
|
||||
{
|
||||
if (m_pCScene->Can_Line_Up(it->Current_Item_Class_ID()))
|
||||
pCombo->AddString(it->Current_Item_Name());
|
||||
}
|
||||
assets->Release_Render_Obj_Iterator(it);
|
||||
}
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
void CAddToLineupDialog::OnOK()
|
||||
{
|
||||
// Make sure the user actually chose a name.
|
||||
CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_OBJECT);
|
||||
ASSERT_VALID(pCombo);
|
||||
CString text;
|
||||
pCombo->GetWindowText(text);
|
||||
if (text.IsEmpty())
|
||||
{
|
||||
::AfxMessageBox("Please select an object, or type in an object name.");
|
||||
return;
|
||||
}
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
69
Code/Tools/W3DView/AddToLineupDialog.h
Normal file
69
Code/Tools/W3DView/AddToLineupDialog.h
Normal 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/>.
|
||||
*/
|
||||
|
||||
#if !defined(AFX_ADDTOLINEUPDIALOG_H__AD8B92C5_25CB_11D4_8A1D_0090272E6F90__INCLUDED_)
|
||||
#define AFX_ADDTOLINEUPDIALOG_H__AD8B92C5_25CB_11D4_8A1D_0090272E6F90__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AddToLineupDialog.h : header file
|
||||
//
|
||||
|
||||
class ViewerSceneClass;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAddToLineupDialog dialog
|
||||
|
||||
class CAddToLineupDialog : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CAddToLineupDialog(ViewerSceneClass *scene, CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CAddToLineupDialog)
|
||||
enum { IDD = IDD_ADD_TO_LINEUP };
|
||||
CString m_Object;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAddToLineupDialog)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
ViewerSceneClass * m_pCScene;
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CAddToLineupDialog)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ADDTOLINEUPDIALOG_H__AD8B92C5_25CB_11D4_8A1D_0090272E6F90__INCLUDED_)
|
||||
197
Code/Tools/W3DView/AdvancedAnimSheet.cpp
Normal file
197
Code/Tools/W3DView/AdvancedAnimSheet.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// AdvancedAnimSheet.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "W3dViewDoc.h"
|
||||
#include "AdvancedAnimSheet.h"
|
||||
|
||||
#include "AssetMgr.h"
|
||||
#include "HAnim.h"
|
||||
#include "HTree.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// QSort comparison function for HAnimClass pointers.
|
||||
// Will compare their names.
|
||||
static int anim_name_compare (const void *arg1, const void *arg2)
|
||||
{
|
||||
ASSERT(arg1 != NULL);
|
||||
ASSERT(arg2 != NULL);
|
||||
HAnimClass *a1 = *(HAnimClass**)arg1;
|
||||
HAnimClass *a2 = *(HAnimClass**)arg2;
|
||||
return _stricmp( a1->Get_Name(), a2->Get_Name() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAdvancedAnimSheet
|
||||
|
||||
IMPLEMENT_DYNAMIC(CAdvancedAnimSheet, CPropertySheet)
|
||||
|
||||
CAdvancedAnimSheet::CAdvancedAnimSheet(CWnd* pParentWnd, UINT iSelectPage)
|
||||
: CPropertySheet("Advanced Animation", pParentWnd, iSelectPage),
|
||||
m_MixingPage(this),
|
||||
m_ReportPage(this),
|
||||
AnimsValid(false),
|
||||
AnimCount(0)
|
||||
{
|
||||
// Blank out the array of animation pointers.
|
||||
ZeroMemory(Anims, sizeof(Anims));
|
||||
|
||||
// Add the property pages into this property sheet.
|
||||
AddPage(&m_MixingPage);
|
||||
AddPage(&m_ReportPage);
|
||||
}
|
||||
|
||||
CAdvancedAnimSheet::~CAdvancedAnimSheet()
|
||||
{
|
||||
if (AnimsValid)
|
||||
{
|
||||
for (int i = 0; i < AnimCount; i++)
|
||||
{
|
||||
MEMBER_RELEASE(Anims[i]);
|
||||
}
|
||||
AnimsValid = false;
|
||||
AnimCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAdvancedAnimSheet, CPropertySheet)
|
||||
//{{AFX_MSG_MAP(CAdvancedAnimSheet)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAdvancedAnimSheet message handlers
|
||||
|
||||
int CAdvancedAnimSheet::GetAnimCount (void)
|
||||
{
|
||||
if (AnimsValid)
|
||||
return AnimCount;
|
||||
|
||||
LoadAnims();
|
||||
|
||||
if (AnimsValid)
|
||||
return AnimCount;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
HAnimClass ** CAdvancedAnimSheet::GetAnims (void)
|
||||
{
|
||||
if (AnimsValid)
|
||||
return Anims;
|
||||
|
||||
LoadAnims();
|
||||
|
||||
// Return the array regardless of validity. If the entries are
|
||||
// invalid, they'll all be NULL, but the array itself is cool.
|
||||
return Anims;
|
||||
}
|
||||
|
||||
|
||||
void CAdvancedAnimSheet::LoadAnims (void)
|
||||
{
|
||||
// Get the current render object and it's HTree. If it doesn't have
|
||||
// an HTree, then it's not animating and we're not interested.
|
||||
RenderObjClass *robj = ::GetCurrentDocument()->GetDisplayedObject();
|
||||
if (robj == NULL)
|
||||
return;
|
||||
const HTreeClass *htree = robj->Get_HTree();
|
||||
if (htree == NULL)
|
||||
return;
|
||||
const char *htree_name = htree->Get_Name();
|
||||
|
||||
/*
|
||||
** Figure out which animations apply to the current object, and
|
||||
** add each one to the array of animations which we will later sort.
|
||||
*/
|
||||
|
||||
// Get an iterator from the asset manager that we can
|
||||
// use to enumerate the currently loaded assets
|
||||
AssetIterator *pAnimEnum = WW3DAssetManager::Get_Instance()->Create_HAnim_Iterator();
|
||||
ASSERT(pAnimEnum != NULL);
|
||||
if (pAnimEnum)
|
||||
{
|
||||
// Loop through all the animations in the manager
|
||||
for (pAnimEnum->First(); pAnimEnum->Is_Done() == FALSE; pAnimEnum->Next())
|
||||
{
|
||||
LPCTSTR pszAnimName = pAnimEnum->Current_Item_Name();
|
||||
|
||||
// Get an instance of the animation object
|
||||
HAnimClass *pHierarchyAnim = WW3DAssetManager::Get_Instance()->Get_HAnim(pszAnimName);
|
||||
|
||||
ASSERT(pHierarchyAnim != NULL);
|
||||
if (pHierarchyAnim)
|
||||
{
|
||||
// Does this animation apply to the current model's HTree?
|
||||
if (stricmp(htree_name, pHierarchyAnim->Get_HName()) == 0)
|
||||
{
|
||||
// Add this Anims pointer to the array.
|
||||
if (AnimCount < MAX_REPORT_ANIMS)
|
||||
{
|
||||
MEMBER_ADD(Anims[AnimCount], pHierarchyAnim);
|
||||
AnimCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char msg[256];
|
||||
sprintf(msg, "Error: Only %d animations are supported in this report. "
|
||||
" There are more than that loaded...", MAX_REPORT_ANIMS);
|
||||
MessageBox(msg, "Too Many Animations");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Release our hold on this animation.
|
||||
MEMBER_RELEASE(pHierarchyAnim);
|
||||
}
|
||||
}
|
||||
|
||||
// Free the object
|
||||
delete pAnimEnum;
|
||||
pAnimEnum = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** Sort the array of animations in alphabetical order.
|
||||
*/
|
||||
qsort(Anims, AnimCount, sizeof(HAnimClass*), anim_name_compare);
|
||||
|
||||
|
||||
AnimsValid = true;
|
||||
}
|
||||
|
||||
|
||||
92
Code/Tools/W3DView/AdvancedAnimSheet.h
Normal file
92
Code/Tools/W3DView/AdvancedAnimSheet.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
** 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_ADVANCEDANIMSHEET_H__67C01724_7C0D_11D3_9A3A_0090272E6F90__INCLUDED_)
|
||||
#define AFX_ADVANCEDANIMSHEET_H__67C01724_7C0D_11D3_9A3A_0090272E6F90__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AdvancedAnimSheet.h : header file
|
||||
//
|
||||
|
||||
#include "AnimMixingPage.h"
|
||||
#include "AnimReportPage.h"
|
||||
|
||||
#define MAX_REPORT_ANIMS 128
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAdvancedAnimSheet
|
||||
|
||||
class CAdvancedAnimSheet : public CPropertySheet
|
||||
{
|
||||
DECLARE_DYNAMIC(CAdvancedAnimSheet)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CAdvancedAnimSheet(CWnd *pParentWnd = NULL, UINT iSelectPage = 0);
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Pages in the property sheet.
|
||||
CAnimMixingPage m_MixingPage;
|
||||
CAnimReportPage m_ReportPage;
|
||||
|
||||
// Indeces of animations selected in the mixing page.
|
||||
DynamicVectorClass<int> m_SelectedAnims;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
int GetAnimCount (void);
|
||||
HAnimClass ** GetAnims (void);
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAdvancedAnimSheet)
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CAdvancedAnimSheet();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
|
||||
void LoadAnims (void);
|
||||
|
||||
HAnimClass *Anims[MAX_REPORT_ANIMS];
|
||||
int AnimCount;
|
||||
bool AnimsValid;
|
||||
|
||||
|
||||
//{{AFX_MSG(CAdvancedAnimSheet)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ADVANCEDANIMSHEET_H__67C01724_7C0D_11D3_9A3A_0090272E6F90__INCLUDED_)
|
||||
126
Code/Tools/W3DView/AggregateNameDialog.cpp
Normal file
126
Code/Tools/W3DView/AggregateNameDialog.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : W3DView *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/W3DView/AggregateNameDialog.cpp $Modtime:: $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "StdAfx.H"
|
||||
#include "W3DView.H"
|
||||
#include "AggregateNameDialog.H"
|
||||
#include "W3D_File.H"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AggregateNameDialogClass
|
||||
//
|
||||
AggregateNameDialogClass::AggregateNameDialogClass (CWnd* pParent /*=NULL*/)
|
||||
: CDialog(AggregateNameDialogClass::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(AggregateNameDialogClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AggregateNameDialogClass
|
||||
//
|
||||
AggregateNameDialogClass::AggregateNameDialogClass
|
||||
(
|
||||
UINT resource_id,
|
||||
const CString &def_name,
|
||||
CWnd *pParent
|
||||
)
|
||||
: m_Name (def_name),
|
||||
CDialog (resource_id, pParent)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AggregateNameDialogClass
|
||||
//
|
||||
void
|
||||
AggregateNameDialogClass::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange (pDX);
|
||||
//{{AFX_DATA_MAP(AggregateNameDialogClass)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(AggregateNameDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(AggregateNameDialogClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnOK
|
||||
//
|
||||
void
|
||||
AggregateNameDialogClass::OnOK (void)
|
||||
{
|
||||
GetDlgItemText (IDC_AGGREGATE_NAME, m_Name);
|
||||
CDialog::OnOK ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
AggregateNameDialogClass::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
// Restrict the amount of text a user can type into the control
|
||||
SendDlgItemMessage (IDC_AGGREGATE_NAME, EM_LIMITTEXT, (WPARAM)W3D_NAME_LEN-1);
|
||||
SetDlgItemText (IDC_AGGREGATE_NAME, m_Name);
|
||||
return TRUE;
|
||||
}
|
||||
83
Code/Tools/W3DView/AggregateNameDialog.h
Normal file
83
Code/Tools/W3DView/AggregateNameDialog.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
** 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_AGGREGATENAMEDIALOG_H__3F618448_CDEA_11D2_9FFC_00104B791122__INCLUDED_)
|
||||
#define AFX_AGGREGATENAMEDIALOG_H__3F618448_CDEA_11D2_9FFC_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AggregateNameDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AggregateNameDialogClass dialog
|
||||
|
||||
class AggregateNameDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
AggregateNameDialogClass(CWnd* pParent = NULL);
|
||||
AggregateNameDialogClass(UINT resource_id, const CString &def_name, CWnd* pParent = NULL);
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(AggregateNameDialogClass)
|
||||
enum { IDD = IDD_MAKE_AGGREGATE };
|
||||
// NOTE: the ClassWizard will add data members here
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(AggregateNameDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(AggregateNameDialogClass)
|
||||
virtual void OnOK();
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
const CString & Get_Name (void) const { return m_Name; }
|
||||
void Set_Name (const CString &name) { m_Name = name; }
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
CString m_Name;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_AGGREGATENAMEDIALOG_H__3F618448_CDEA_11D2_9FFC_00104B791122__INCLUDED_)
|
||||
248
Code/Tools/W3DView/AmbientLightDialog.cpp
Normal file
248
Code/Tools/W3DView/AmbientLightDialog.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// AmbientLightDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "W3DView.h"
|
||||
#include "AmbientLightDialog.h"
|
||||
#include "MainFrm.H"
|
||||
#include "W3DViewDoc.H"
|
||||
#include "ViewerScene.H"
|
||||
#include "Utils.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAmbientLightDialog dialog
|
||||
|
||||
|
||||
CAmbientLightDialog::CAmbientLightDialog(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CAmbientLightDialog::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CAmbientLightDialog)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void CAmbientLightDialog::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CAmbientLightDialog)
|
||||
DDX_Control(pDX, IDC_SLIDER_BLUE, m_blueSlider);
|
||||
DDX_Control(pDX, IDC_SLIDER_GREEN, m_greenSlider);
|
||||
DDX_Control(pDX, IDC_SLIDER_RED, m_redSlider);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAmbientLightDialog, CDialog)
|
||||
//{{AFX_MSG_MAP(CAmbientLightDialog)
|
||||
ON_WM_HSCROLL()
|
||||
ON_BN_CLICKED(IDC_GRAYSCALE_CHECK, OnGrayscaleCheck)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
CAmbientLightDialog::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
// Center the dialog around the data tree view instead
|
||||
// of the direct center of the screen
|
||||
::CenterDialogAroundTreeView (m_hWnd);
|
||||
|
||||
m_redSlider.SetRange (0, 100);
|
||||
m_greenSlider.SetRange (0, 100);
|
||||
m_blueSlider.SetRange (0, 100);
|
||||
|
||||
// Get a pointer to the doc so we can get at the current scene
|
||||
// pointer.
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc && pCDoc->GetScene ())
|
||||
{
|
||||
Vector3 lightSettings = pCDoc->GetScene ()->Get_Ambient_Light ();
|
||||
|
||||
// Remember these initial settings so we can restore them
|
||||
// if the user cancels
|
||||
m_initialRed = int(lightSettings.X * 100.00F);
|
||||
m_initialGreen = int(lightSettings.Y * 100.00F);
|
||||
m_initialBlue = int(lightSettings.Z * 100.00F);
|
||||
}
|
||||
|
||||
if ((m_initialRed == m_initialGreen) &&
|
||||
(m_initialRed == m_initialBlue))
|
||||
{
|
||||
// Check the grayscale checkbox
|
||||
SendDlgItemMessage (IDC_GRAYSCALE_CHECK, BM_SETCHECK, (WPARAM)TRUE);
|
||||
}
|
||||
|
||||
// Set the initial slider position
|
||||
m_redSlider.SetPos (m_initialRed);
|
||||
m_greenSlider.SetPos (m_initialGreen);
|
||||
m_blueSlider.SetPos (m_initialBlue);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnHScroll
|
||||
//
|
||||
void
|
||||
CAmbientLightDialog::OnHScroll
|
||||
(
|
||||
UINT nSBCode,
|
||||
UINT nPos,
|
||||
CScrollBar* pScrollBar
|
||||
)
|
||||
{
|
||||
if (SendDlgItemMessage (IDC_GRAYSCALE_CHECK, BM_GETCHECK))
|
||||
{
|
||||
int iCurrentPos = 0;
|
||||
if (pScrollBar == GetDlgItem (IDC_SLIDER_RED))
|
||||
{
|
||||
iCurrentPos = m_redSlider.GetPos ();
|
||||
}
|
||||
else if (pScrollBar == GetDlgItem (IDC_SLIDER_GREEN))
|
||||
{
|
||||
iCurrentPos = m_greenSlider.GetPos ();
|
||||
}
|
||||
else
|
||||
{
|
||||
iCurrentPos = m_blueSlider.GetPos ();
|
||||
}
|
||||
|
||||
// Make all the sliders the same pos
|
||||
m_redSlider.SetPos (iCurrentPos);
|
||||
m_greenSlider.SetPos (iCurrentPos);
|
||||
m_blueSlider.SetPos (iCurrentPos);
|
||||
}
|
||||
|
||||
Vector3 lightSettings;
|
||||
lightSettings.X = float(m_redSlider.GetPos ()) / 100.00F;
|
||||
lightSettings.Y = float(m_greenSlider.GetPos ()) / 100.00F;
|
||||
lightSettings.Z = float(m_blueSlider.GetPos ()) / 100.00F;
|
||||
|
||||
// Get a pointer to the document so we can change the scene's light
|
||||
// settings
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc && pCDoc->GetScene ())
|
||||
{
|
||||
// Modify the ambient light for this scene
|
||||
pCDoc->GetScene ()->Set_Ambient_Light (lightSettings);
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnHScroll (nSBCode, nPos, pScrollBar);
|
||||
return ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCancel
|
||||
//
|
||||
void
|
||||
CAmbientLightDialog::OnCancel (void)
|
||||
{
|
||||
Vector3 lightSettings;
|
||||
lightSettings.X = float(m_initialRed) / 100.00F;
|
||||
lightSettings.Y = float(m_initialGreen) / 100.00F;
|
||||
lightSettings.Z = float(m_initialBlue) / 100.00F;
|
||||
|
||||
// Get a pointer to the document so we can change the scene's light
|
||||
// settings
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc && pCDoc->GetScene ())
|
||||
{
|
||||
// Modify the ambient light for this scene
|
||||
pCDoc->GetScene ()->Set_Ambient_Light (lightSettings);
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnCancel();
|
||||
return ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WindowProc
|
||||
//
|
||||
LRESULT
|
||||
CAmbientLightDialog::WindowProc
|
||||
(
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
if (message == WM_PAINT)
|
||||
{
|
||||
// Paint the gradients for each color
|
||||
::Paint_Gradient (::GetDlgItem (m_hWnd, IDC_RED_GRADIENT), 1, 0, 0);
|
||||
::Paint_Gradient (::GetDlgItem (m_hWnd, IDC_GREEN_GRADIENT), 0, 1, 0);
|
||||
::Paint_Gradient (::GetDlgItem (m_hWnd, IDC_BLUE_GRADIENT), 0, 0, 1);
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CDialog::WindowProc (message, wParam, lParam);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnGrayscaleCheck
|
||||
//
|
||||
void
|
||||
CAmbientLightDialog::OnGrayscaleCheck (void)
|
||||
{
|
||||
if (SendDlgItemMessage (IDC_GRAYSCALE_CHECK, BM_GETCHECK))
|
||||
{
|
||||
// Make the green and blue sliders the same as red
|
||||
m_greenSlider.SetPos (m_redSlider.GetPos ());
|
||||
m_blueSlider.SetPos (m_redSlider.GetPos ());
|
||||
|
||||
Vector3 lightSettings;
|
||||
lightSettings.X = float(m_redSlider.GetPos ()) / 100.00F;
|
||||
lightSettings.Y = float(m_greenSlider.GetPos ()) / 100.00F;
|
||||
lightSettings.Z = float(m_blueSlider.GetPos ()) / 100.00F;
|
||||
|
||||
// Get a pointer to the document so we can change the scene's light
|
||||
// settings
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc && pCDoc->GetScene ())
|
||||
{
|
||||
// Modify the ambient light for this scene
|
||||
pCDoc->GetScene ()->Set_Ambient_Light (lightSettings);
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
75
Code/Tools/W3DView/AmbientLightDialog.h
Normal file
75
Code/Tools/W3DView/AmbientLightDialog.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
** 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_AMBIENTLIGHTDIALOG_H__D60CC3CE_5F94_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
#define AFX_AMBIENTLIGHTDIALOG_H__D60CC3CE_5F94_11D2_9FC7_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// AmbientLightDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAmbientLightDialog dialog
|
||||
|
||||
class CAmbientLightDialog : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CAmbientLightDialog(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CAmbientLightDialog)
|
||||
enum { IDD = IDD_LIGHT_AMBIENT_DIALOG };
|
||||
CSliderCtrl m_blueSlider;
|
||||
CSliderCtrl m_greenSlider;
|
||||
CSliderCtrl m_redSlider;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAmbientLightDialog)
|
||||
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(CAmbientLightDialog)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||||
virtual void OnCancel();
|
||||
afx_msg void OnGrayscaleCheck();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
int m_initialRed;
|
||||
int m_initialGreen;
|
||||
int m_initialBlue;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_AMBIENTLIGHTDIALOG_H__D60CC3CE_5F94_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
169
Code/Tools/W3DView/AnimMixingPage.cpp
Normal file
169
Code/Tools/W3DView/AnimMixingPage.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// AnimMixingPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "W3dViewDoc.h"
|
||||
#include "AdvancedAnimSheet.h"
|
||||
#include "AnimMixingPage.h"
|
||||
|
||||
#include "RendObj.h"
|
||||
#include "HTree.h"
|
||||
#include "HAnim.h"
|
||||
#include "Utils.h"
|
||||
#include "AssetMgr.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAnimMixingPage property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(CAnimMixingPage, CPropertyPage)
|
||||
|
||||
CAnimMixingPage::CAnimMixingPage(CAdvancedAnimSheet *sheet)
|
||||
: CPropertyPage(CAnimMixingPage::IDD),
|
||||
m_Sheet(sheet)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CAnimMixingPage)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
CAnimMixingPage::~CAnimMixingPage()
|
||||
{
|
||||
}
|
||||
|
||||
void CAnimMixingPage::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CAnimMixingPage)
|
||||
DDX_Control(pDX, IDC_ANIMATION_LIST, m_AnimList);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAnimMixingPage, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(CAnimMixingPage)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAnimMixingPage message handlers
|
||||
|
||||
BOOL CAnimMixingPage::OnInitDialog()
|
||||
{
|
||||
CPropertyPage::OnInitDialog();
|
||||
|
||||
ASSERT(m_Sheet != NULL);
|
||||
FillListCtrl();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
|
||||
void CAnimMixingPage::FillListCtrl (void)
|
||||
{
|
||||
// Get the current render object and it's HTree. If it doesn't have
|
||||
// an HTree, then it's not animating and we're not interested.
|
||||
RenderObjClass *robj = ::GetCurrentDocument()->GetDisplayedObject();
|
||||
if (robj == NULL)
|
||||
return;
|
||||
const HTreeClass *htree = robj->Get_HTree();
|
||||
if (htree == NULL)
|
||||
return;
|
||||
|
||||
// Get a sorted array of animations that affect the currently active object.
|
||||
HAnimClass **anim = m_Sheet->GetAnims();
|
||||
int anim_count = m_Sheet->GetAnimCount();
|
||||
|
||||
// Add an item to the list view for each animation.
|
||||
int i;
|
||||
for (i = 0; i < anim_count; i++)
|
||||
m_AnimList.InsertItem(i, anim[i]->Get_Name());
|
||||
}
|
||||
|
||||
void CAnimMixingPage::OnOK()
|
||||
{
|
||||
/*
|
||||
** Create a new HAnimCombo class containing the animations selected by the user.
|
||||
*/
|
||||
int num_selected = m_AnimList.GetSelectedCount();
|
||||
RenderObjClass *current_obj = ::GetCurrentDocument()->GetDisplayedObject();
|
||||
const char *obj_name = current_obj->Get_Name();
|
||||
RenderObjClass *robj = WW3DAssetManager::Get_Instance()->Create_Render_Obj(obj_name);
|
||||
if (num_selected > 0 && robj != NULL)
|
||||
{
|
||||
HAnimClass **anim = m_Sheet->GetAnims();
|
||||
|
||||
HAnimComboClass *combo = new HAnimComboClass(num_selected);
|
||||
ASSERT(combo != NULL);
|
||||
|
||||
POSITION pos = m_AnimList.GetFirstSelectedItemPosition();
|
||||
int array_idx, idx = 0;
|
||||
while (pos)
|
||||
{
|
||||
array_idx = m_AnimList.GetNextSelectedItem(pos);
|
||||
combo->Set_Motion(idx, anim[array_idx]);
|
||||
combo->Set_Weight(idx, 1.0f);
|
||||
combo->Peek_Anim_Combo_Data(idx)->Build_Active_Pivot_Map();
|
||||
idx++;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set this new combo to be used by the doc.
|
||||
*/
|
||||
::GetCurrentDocument()->PlayAnimation(robj, combo);
|
||||
robj->Release_Ref();
|
||||
}
|
||||
|
||||
CPropertyPage::OnOK();
|
||||
}
|
||||
|
||||
BOOL CAnimMixingPage::OnKillActive()
|
||||
{
|
||||
/*
|
||||
** Update the parent with info on the current selection.
|
||||
*/
|
||||
m_Sheet->m_SelectedAnims.Clear();
|
||||
m_Sheet->m_SelectedAnims.Resize(m_AnimList.GetSelectedCount());
|
||||
|
||||
int selected_idx, i=0;
|
||||
POSITION pos = m_AnimList.GetFirstSelectedItemPosition();
|
||||
while (pos)
|
||||
{
|
||||
selected_idx = m_AnimList.GetNextSelectedItem(pos);
|
||||
if (!m_Sheet->m_SelectedAnims.Add(selected_idx))
|
||||
{
|
||||
char buf[128];
|
||||
sprintf(buf, "Failed to insert item %d! Talk to Andre if "\
|
||||
"you see this message.", i);
|
||||
MessageBox(buf);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return CPropertyPage::OnKillActive();
|
||||
}
|
||||
77
Code/Tools/W3DView/AnimMixingPage.h
Normal file
77
Code/Tools/W3DView/AnimMixingPage.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
** 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_ANIMMIXINGPAGE_H__67C01722_7C0D_11D3_9A3A_0090272E6F90__INCLUDED_)
|
||||
#define AFX_ANIMMIXINGPAGE_H__67C01722_7C0D_11D3_9A3A_0090272E6F90__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AnimMixingPage.h : header file
|
||||
//
|
||||
|
||||
class CAdvancedAnimSheet;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAnimMixingPage dialog
|
||||
|
||||
class CAnimMixingPage : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(CAnimMixingPage)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CAnimMixingPage(CAdvancedAnimSheet *sheet = NULL);
|
||||
~CAnimMixingPage();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CAnimMixingPage)
|
||||
enum { IDD = IDD_PROP_PAGE_ADVANIM_MIXING };
|
||||
CListCtrl m_AnimList;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAnimMixingPage)
|
||||
public:
|
||||
virtual void OnOK();
|
||||
virtual BOOL OnKillActive();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
void FillListCtrl (void);
|
||||
|
||||
CAdvancedAnimSheet *m_Sheet;
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CAnimMixingPage)
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ANIMMIXINGPAGE_H__67C01722_7C0D_11D3_9A3A_0090272E6F90__INCLUDED_)
|
||||
216
Code/Tools/W3DView/AnimReportPage.cpp
Normal file
216
Code/Tools/W3DView/AnimReportPage.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// AnimReportPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "W3DViewDoc.h"
|
||||
#include "AdvancedAnimSheet.h"
|
||||
#include "AnimReportPage.h"
|
||||
|
||||
|
||||
#include "HAnim.h"
|
||||
#include "HTree.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAnimReportPage property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(CAnimReportPage, CPropertyPage)
|
||||
|
||||
CAnimReportPage::CAnimReportPage(CAdvancedAnimSheet *sheet)
|
||||
: CPropertyPage(CAnimReportPage::IDD),
|
||||
m_Sheet(sheet)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CAnimReportPage)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
CAnimReportPage::~CAnimReportPage()
|
||||
{
|
||||
}
|
||||
|
||||
void CAnimReportPage::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CAnimReportPage)
|
||||
DDX_Control(pDX, IDC_ANIM_REPORT, m_AnimReport);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAnimReportPage, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(CAnimReportPage)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAnimReportPage message handlers
|
||||
|
||||
BOOL CAnimReportPage::OnInitDialog()
|
||||
{
|
||||
CPropertyPage::OnInitDialog();
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
void CAnimReportPage::FillListControl()
|
||||
{
|
||||
// Add the first column to the animation report. All bone names will
|
||||
// go in this column.
|
||||
m_AnimReport.InsertColumn(0, "Bone Name");
|
||||
|
||||
// Get the current render object and it's HTree. If it doesn't have
|
||||
// an HTree, then it's not animating and we're not interested.
|
||||
RenderObjClass *robj = ::GetCurrentDocument()->GetDisplayedObject();
|
||||
if (robj == NULL)
|
||||
return;
|
||||
const HTreeClass *htree = robj->Get_HTree();
|
||||
if (htree == NULL)
|
||||
return;
|
||||
|
||||
// Get a sorted array of animations that affect the currently active object.
|
||||
HAnimClass **anim = m_Sheet->GetAnims();
|
||||
int anim_count = m_Sheet->GetAnimCount();
|
||||
|
||||
|
||||
/*
|
||||
** Create a column in the report view for each animation.
|
||||
*/
|
||||
|
||||
int column_count; // number of columns in the report view (EXCLUDING the bone column)
|
||||
bool indirect; // true if we have one column per animation selected in the mixing page
|
||||
if (m_Sheet->m_SelectedAnims.Count() > 0)
|
||||
{
|
||||
column_count = m_Sheet->m_SelectedAnims.Count();
|
||||
indirect = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
column_count = anim_count;
|
||||
indirect = false;
|
||||
}
|
||||
|
||||
int i, j;
|
||||
int anim_idx; // column index, essentially (anim_idx + 1 == column for that anim)
|
||||
for (i = 0; i < column_count; i++)
|
||||
{
|
||||
// Add a new column with the name of this animation as the title.
|
||||
anim_idx = indirect ? m_Sheet->m_SelectedAnims[i] : i;
|
||||
if (m_AnimReport.InsertColumn(anim_idx+1, anim[anim_idx]->Get_Name(), LVCFMT_CENTER) == -1)
|
||||
{
|
||||
// Failed to add a new column to the list control.
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Add a row to the report for each bone in the object affected by
|
||||
** an animation. It's entry (row/col) will contain the animation
|
||||
** channels with valid animation data.
|
||||
*/
|
||||
|
||||
for (i = 0; i < column_count; i++)
|
||||
{
|
||||
// Grab the anim pointer directly.
|
||||
anim_idx = indirect ? m_Sheet->m_SelectedAnims[i] : i;
|
||||
HAnimClass *pAnim = anim[anim_idx];
|
||||
|
||||
// Which bones does it affect, and how?
|
||||
int num_bones = robj->Get_Num_Bones();
|
||||
for (j = 1; j < num_bones; j++) // skip bone 0, which is always the root bone
|
||||
{
|
||||
// Add each bone to the report (regardless of animation status)
|
||||
// if it isn't already there.
|
||||
int idx = FindItem(htree->Get_Bone_Name(j));
|
||||
if (idx == -1)
|
||||
{
|
||||
// Wasn't present, add a new item for this bone.
|
||||
idx = m_AnimReport.InsertItem(m_AnimReport.GetItemCount(),
|
||||
htree->Get_Bone_Name(j));
|
||||
}
|
||||
|
||||
if (pAnim->Is_Node_Motion_Present(j))
|
||||
{
|
||||
// Add motion channel info to the appropriate column.
|
||||
char channels[6]; // strlen("XYZQV")+1
|
||||
ZeroMemory(channels, sizeof(channels));
|
||||
MakeChannelStr(j, pAnim, channels);
|
||||
m_AnimReport.SetItem(idx, i+1, LVIF_TEXT, channels, 0,0,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make the columns sized nicely.
|
||||
m_AnimReport.SetColumnWidth(0, LVSCW_AUTOSIZE);
|
||||
for (i = 0; i < column_count; i++)
|
||||
m_AnimReport.SetColumnWidth(i+1, LVSCW_AUTOSIZE_USEHEADER);
|
||||
|
||||
// All done, the report view is set up.
|
||||
}
|
||||
|
||||
int CAnimReportPage::FindItem (const char *item_name)
|
||||
{
|
||||
LVFINDINFO lvfi;
|
||||
lvfi.flags = LVFI_STRING;
|
||||
lvfi.psz = item_name;
|
||||
return m_AnimReport.FindItem(&lvfi);
|
||||
}
|
||||
|
||||
void CAnimReportPage::MakeChannelStr (int bone_idx, HAnimClass *hanim, char *channels)
|
||||
{
|
||||
if (hanim->Has_X_Translation(bone_idx))
|
||||
strcat(channels, "X");
|
||||
if (hanim->Has_Y_Translation(bone_idx))
|
||||
strcat(channels, "Y");
|
||||
if (hanim->Has_Z_Translation(bone_idx))
|
||||
strcat(channels, "Z");
|
||||
if (hanim->Has_Rotation(bone_idx))
|
||||
strcat(channels, "Q");
|
||||
if (hanim->Has_Visibility(bone_idx))
|
||||
strcat(channels, "V");
|
||||
}
|
||||
|
||||
BOOL CAnimReportPage::OnSetActive()
|
||||
{
|
||||
// Delete all info in the report view.
|
||||
m_AnimReport.DeleteAllItems();
|
||||
while (m_AnimReport.DeleteColumn(0));
|
||||
|
||||
// Fill the list control each time we're set active so that
|
||||
// a change in selection on the mixing page will have an
|
||||
// effect on this page.
|
||||
FillListControl();
|
||||
|
||||
return CPropertyPage::OnSetActive();
|
||||
}
|
||||
78
Code/Tools/W3DView/AnimReportPage.h
Normal file
78
Code/Tools/W3DView/AnimReportPage.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
** 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_ANIMREPORTPAGE_H__67C01723_7C0D_11D3_9A3A_0090272E6F90__INCLUDED_)
|
||||
#define AFX_ANIMREPORTPAGE_H__67C01723_7C0D_11D3_9A3A_0090272E6F90__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AnimReportPage.h : header file
|
||||
//
|
||||
|
||||
class HAnimClass;
|
||||
class CAdvancedAnimSheet;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAnimReportPage dialog
|
||||
|
||||
class CAnimReportPage : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(CAnimReportPage)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CAnimReportPage(CAdvancedAnimSheet *sheet = NULL);
|
||||
~CAnimReportPage();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CAnimReportPage)
|
||||
enum { IDD = IDD_PROP_PAGE_ADVANIM_REPORT };
|
||||
CListCtrl m_AnimReport;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAnimReportPage)
|
||||
public:
|
||||
virtual BOOL OnSetActive();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
void FillListControl (void);
|
||||
int FindItem (const char *item_name);
|
||||
void MakeChannelStr (int bone_idx, HAnimClass *hanim, char *channels);
|
||||
|
||||
CAdvancedAnimSheet *m_Sheet;
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CAnimReportPage)
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ANIMREPORTPAGE_H__67C01723_7C0D_11D3_9A3A_0090272E6F90__INCLUDED_)
|
||||
258
Code/Tools/W3DView/AnimatedSoundOptionsDialog.cpp
Normal file
258
Code/Tools/W3DView/AnimatedSoundOptionsDialog.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// AnimatedSoundOptionsDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "globals.h"
|
||||
#include "animatedsoundoptionsdialog.h"
|
||||
#include "ffactory.h"
|
||||
#include "animatedsoundmgr.h"
|
||||
#include "wwsaveload.h"
|
||||
#include "definitionmgr.h"
|
||||
#include "wwfile.h"
|
||||
#include "chunkio.h"
|
||||
#include "wwdebug.h"
|
||||
#include "restrictedfiledialog.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AnimatedSoundOptionsDialogClass dialog
|
||||
|
||||
|
||||
AnimatedSoundOptionsDialogClass::AnimatedSoundOptionsDialogClass(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(AnimatedSoundOptionsDialogClass::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(AnimatedSoundOptionsDialogClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void AnimatedSoundOptionsDialogClass::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(AnimatedSoundOptionsDialogClass)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(AnimatedSoundOptionsDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(AnimatedSoundOptionsDialogClass)
|
||||
ON_BN_CLICKED(IDC_SOUND_DEFINITION_LIBRARY_BROWSE_BUTTON, OnSoundDefinitionLibraryBrowseButton)
|
||||
ON_BN_CLICKED(IDC_SOUND_INI_BROWSE_BUTTON, OnSoundIniBrowseButton)
|
||||
ON_BN_CLICKED(IDC_SOUND_PATH_BROWSE_BUTTON, OnSoundPathBrowseButton)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSoundDefinitionLibraryBrowseButton
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AnimatedSoundOptionsDialogClass::OnSoundDefinitionLibraryBrowseButton (void)
|
||||
{
|
||||
CFileDialog dialog ( TRUE,
|
||||
".ddb",
|
||||
"20480.ddb",
|
||||
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER,
|
||||
"Definition Database Files(*.ddb)|*.ddb||",
|
||||
this);
|
||||
|
||||
//
|
||||
// Prompt the user
|
||||
//
|
||||
if (dialog.DoModal () == IDOK) {
|
||||
SetDlgItemText (IDC_SOUND_DEFINITION_LIBRARY_EDIT, dialog.GetPathName ());
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSoundIniBrowseButton
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AnimatedSoundOptionsDialogClass::OnSoundIniBrowseButton (void)
|
||||
{
|
||||
CFileDialog dialog ( TRUE,
|
||||
".ini",
|
||||
"w3danimsound.ini",
|
||||
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER,
|
||||
"INI Files (*.ini)|*.ini||",
|
||||
this);
|
||||
|
||||
//
|
||||
// Prompt the user
|
||||
//
|
||||
if (dialog.DoModal () == IDOK) {
|
||||
SetDlgItemText (IDC_SOUND_INI_EDIT, dialog.GetPathName ());
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnOK
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AnimatedSoundOptionsDialogClass::OnOK (void)
|
||||
{
|
||||
CDialog::OnOK ();
|
||||
|
||||
//
|
||||
// Get the user's response
|
||||
//
|
||||
CString sound_def_lib_path;
|
||||
CString sound_ini_path;
|
||||
CString sound_data_path;
|
||||
GetDlgItemText (IDC_SOUND_DEFINITION_LIBRARY_EDIT, sound_def_lib_path);
|
||||
GetDlgItemText (IDC_SOUND_INI_EDIT, sound_ini_path);
|
||||
GetDlgItemText (IDC_SOUND_FILE_PATH_EDIT, sound_data_path);
|
||||
|
||||
//
|
||||
// Store this information in the registry
|
||||
//
|
||||
theApp.WriteProfileString ("Config", "SoundDefLibPath", sound_def_lib_path);
|
||||
theApp.WriteProfileString ("Config", "AnimSoundINIPath", sound_ini_path);
|
||||
theApp.WriteProfileString ("Config", "AnimSoundDataPath", sound_data_path);
|
||||
|
||||
Load_Animated_Sound_Settings ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
AnimatedSoundOptionsDialogClass::OnInitDialog (void)
|
||||
{
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
StringClass sound_def_lib_path = theApp.GetProfileString ("Config", "SoundDefLibPath");
|
||||
StringClass sound_ini_path = theApp.GetProfileString ("Config", "AnimSoundINIPath");
|
||||
StringClass sound_data_path = theApp.GetProfileString ("Config", "AnimSoundDataPath");
|
||||
|
||||
//
|
||||
// Fill in the default values
|
||||
//
|
||||
SetDlgItemText (IDC_SOUND_DEFINITION_LIBRARY_EDIT, sound_def_lib_path);
|
||||
SetDlgItemText (IDC_SOUND_INI_EDIT, sound_ini_path);
|
||||
SetDlgItemText (IDC_SOUND_FILE_PATH_EDIT, sound_data_path);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Load_Animated_Sound_Settings
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AnimatedSoundOptionsDialogClass::Load_Animated_Sound_Settings (void)
|
||||
{
|
||||
//
|
||||
// Start fresh
|
||||
//
|
||||
DefinitionMgrClass::Free_Definitions ();
|
||||
|
||||
//
|
||||
// Get the data from the registry
|
||||
//
|
||||
StringClass sound_def_lib_path = theApp.GetProfileString ("Config", "SoundDefLibPath");
|
||||
StringClass sound_ini_path = theApp.GetProfileString ("Config", "AnimSoundINIPath");
|
||||
StringClass sound_data_path = theApp.GetProfileString ("Config", "AnimSoundDataPath");
|
||||
|
||||
//
|
||||
// Try to load the definitions into the definition mgr
|
||||
//
|
||||
FileClass *file = _TheFileFactory->Get_File (sound_def_lib_path);
|
||||
if (file != NULL) {
|
||||
file->Open (FileClass::READ);
|
||||
ChunkLoadClass cload (file);
|
||||
SaveLoadSystemClass::Load (cload);
|
||||
file->Close ();
|
||||
_TheFileFactory->Return_File (file);
|
||||
} else {
|
||||
WWDEBUG_SAY (("Failed to load file %s\n", sound_def_lib_path.Peek_Buffer ()));
|
||||
}
|
||||
|
||||
//
|
||||
// Load the sound settings from the ini file
|
||||
//
|
||||
AnimatedSoundMgrClass::Shutdown ();
|
||||
AnimatedSoundMgrClass::Initialize (sound_ini_path);
|
||||
|
||||
//
|
||||
// Add a sub-directory to the file factory for audio use
|
||||
//
|
||||
_TheSimpleFileFactory->Append_Sub_Directory (sound_data_path);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSoundPathBrowseButton
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AnimatedSoundOptionsDialogClass::OnSoundPathBrowseButton (void)
|
||||
{
|
||||
RestrictedFileDialogClass dialog ( TRUE,
|
||||
".wav",
|
||||
"test.wav",
|
||||
OFN_HIDEREADONLY | OFN_EXPLORER,
|
||||
"Directories|*.wav||",
|
||||
AfxGetMainWnd ());
|
||||
|
||||
dialog.m_ofn.lpstrTitle = "Pick Sound Path";
|
||||
|
||||
//
|
||||
// Prompt the user
|
||||
//
|
||||
if (dialog.DoModal () == IDOK) {
|
||||
|
||||
CString path = ::Strip_Filename_From_Path (dialog.GetPathName ());
|
||||
SetDlgItemText (IDC_SOUND_FILE_PATH_EDIT, path);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
81
Code/Tools/W3DView/AnimatedSoundOptionsDialog.h
Normal file
81
Code/Tools/W3DView/AnimatedSoundOptionsDialog.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
** 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_ANIMATEDSOUNDOPTIONSDIALOG_H__5FD0B3D4_3975_4315_B412_44586622684B__INCLUDED_)
|
||||
#define AFX_ANIMATEDSOUNDOPTIONSDIALOG_H__5FD0B3D4_3975_4315_B412_44586622684B__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// AnimatedSoundOptionsDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AnimatedSoundOptionsDialogClass dialog
|
||||
|
||||
class AnimatedSoundOptionsDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
AnimatedSoundOptionsDialogClass(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(AnimatedSoundOptionsDialogClass)
|
||||
enum { IDD = IDD_ANIMATED_SOUND_DIALOG };
|
||||
// NOTE: the ClassWizard will add data members here
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(AnimatedSoundOptionsDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(AnimatedSoundOptionsDialogClass)
|
||||
afx_msg void OnSoundDefinitionLibraryBrowseButton();
|
||||
afx_msg void OnSoundIniBrowseButton();
|
||||
virtual void OnOK();
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnSoundPathBrowseButton();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
///////////////////////////////////////////////////////////////////
|
||||
static void Load_Animated_Sound_Settings (void);
|
||||
|
||||
private:
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ANIMATEDSOUNDOPTIONSDIALOG_H__5FD0B3D4_3975_4315_B412_44586622684B__INCLUDED_)
|
||||
125
Code/Tools/W3DView/AnimationPropPage.cpp
Normal file
125
Code/Tools/W3DView/AnimationPropPage.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// AnimationPropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "AnimationPropPage.h"
|
||||
#include "RendObj.H"
|
||||
#include "AssetMgr.H"
|
||||
#include "Mesh.H"
|
||||
#include "W3DViewDoc.H"
|
||||
#include "Utils.H"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAnimationPropPage property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(CAnimationPropPage, CPropertyPage)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CAnimationPropPage
|
||||
//
|
||||
CAnimationPropPage::CAnimationPropPage (void)
|
||||
: CPropertyPage(CAnimationPropPage::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CAnimationPropPage)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CAnimationPropPage
|
||||
//
|
||||
CAnimationPropPage::~CAnimationPropPage (void)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
CAnimationPropPage::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CAnimationPropPage)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAnimationPropPage, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(CAnimationPropPage)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
CAnimationPropPage::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::OnInitDialog ();
|
||||
|
||||
// Get a pointer to the doc so we can get at the current animation object
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc && pCDoc->GetCurrentAnimation ())
|
||||
{
|
||||
HAnimClass *pCAnimation = pCDoc->GetCurrentAnimation ();
|
||||
|
||||
// Set the description text at the top of the dialog
|
||||
CString stringTemp;
|
||||
stringTemp.Format (IDS_ANI_PROP_DESC, pCAnimation->Get_Name ());
|
||||
SetDlgItemText (IDC_DESCRIPTION, stringTemp);
|
||||
|
||||
// Fill in the number of frames
|
||||
SetDlgItemInt (IDC_FRAME_COUNT, pCAnimation->Get_Num_Frames ());
|
||||
|
||||
// Fill in the frame rate of the animation
|
||||
stringTemp.Format ("%.2f fps", pCAnimation->Get_Frame_Rate ());
|
||||
SetDlgItemText (IDC_FRAME_RATE, stringTemp);
|
||||
|
||||
// Fill in the total time taken by the animation
|
||||
stringTemp.Format ("%.3f seconds", pCAnimation->Get_Total_Time ());
|
||||
SetDlgItemText (IDC_TOTAL_TIME, stringTemp);
|
||||
|
||||
// Set the name of the hierarchy this animation belongs to.
|
||||
SetDlgItemText (IDC_HIERARCHY_NAME, pCAnimation->Get_HName ());
|
||||
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
68
Code/Tools/W3DView/AnimationPropPage.h
Normal file
68
Code/Tools/W3DView/AnimationPropPage.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
** 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_ANIMATIONPROPPAGE_H__9B07DA65_62B6_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
#define AFX_ANIMATIONPROPPAGE_H__9B07DA65_62B6_11D2_9FC7_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// AnimationPropPage.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAnimationPropPage dialog
|
||||
|
||||
class CAnimationPropPage : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(CAnimationPropPage)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CAnimationPropPage();
|
||||
~CAnimationPropPage();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CAnimationPropPage)
|
||||
enum { IDD = IDD_PROP_PAGE_ANIMATION };
|
||||
// NOTE - ClassWizard will add data members here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAnimationPropPage)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CAnimationPropPage)
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ANIMATIONPROPPAGE_H__9B07DA65_62B6_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
243
Code/Tools/W3DView/AnimationSpeed.cpp
Normal file
243
Code/Tools/W3DView/AnimationSpeed.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// AnimationSpeed.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "W3DView.h"
|
||||
#include "AnimationSpeed.h"
|
||||
#include "MainFrm.H"
|
||||
#include "GraphicView.H"
|
||||
#include "Utils.H"
|
||||
#include "W3DViewDoc.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
//extern bool CompressQ;
|
||||
//extern int QnBytes;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAnimationSpeed dialog
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CAnimationSpeed
|
||||
//
|
||||
CAnimationSpeed::CAnimationSpeed (CWnd* pParent)
|
||||
: m_iInitialPercent (0),
|
||||
CDialog(CAnimationSpeed::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CAnimationSpeed)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
CAnimationSpeed::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CAnimationSpeed)
|
||||
DDX_Control(pDX, IDC_SPEED_SLIDER, m_speedSlider);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAnimationSpeed, CDialog)
|
||||
//{{AFX_MSG_MAP(CAnimationSpeed)
|
||||
ON_WM_HSCROLL()
|
||||
ON_WM_DESTROY()
|
||||
ON_BN_CLICKED(IDC_BLEND, OnBlend)
|
||||
ON_BN_CLICKED(IDC_COMPRESSQ, OnCompressq)
|
||||
ON_BN_CLICKED(IDC_16BIT, On16bit)
|
||||
ON_BN_CLICKED(IDC_8BIT, On8bit)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
CAnimationSpeed::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
// Center the dialog around the data tree view instead
|
||||
// of the direct center of the screen
|
||||
::CenterDialogAroundTreeView (m_hWnd);
|
||||
|
||||
// Get a pointer to the doc so we can get at the current scene
|
||||
// pointer.
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
SendDlgItemMessage (IDC_BLEND, BM_SETCHECK, (WPARAM)pCDoc->GetAnimationBlend ());
|
||||
CheckDlgButton(IDC_COMPRESSQ, pCDoc->GetChannelQCompression());
|
||||
CheckRadioButton(IDC_16BIT, IDC_8BIT, IDC_16BIT+2);//-pCDoc->GetChannelQnBytes());
|
||||
if(pCDoc->GetChannelQCompression()){
|
||||
GetDlgItem(IDC_16BIT)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_8BIT)->EnableWindow(TRUE);
|
||||
}else{
|
||||
GetDlgItem(IDC_16BIT)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_8BIT)->EnableWindow(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// Get a pointer to the main window
|
||||
CMainFrame *pCMainWnd = (CMainFrame *)::AfxGetMainWnd ();
|
||||
if (pCMainWnd)
|
||||
{
|
||||
// Get a pointer to the graphic view pane
|
||||
CGraphicView *pCGraphicView = (CGraphicView *)pCMainWnd->GetPane (0, 1);
|
||||
if (pCGraphicView)
|
||||
{
|
||||
// Determine the current display speed
|
||||
float animationSpeed = pCGraphicView->GetAnimationSpeed ();
|
||||
|
||||
// Convert the current display speed to a percentage
|
||||
m_iInitialPercent = int(animationSpeed*100.00F);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the range of the slider control
|
||||
m_speedSlider.SetRange (1, 200);
|
||||
|
||||
// Set the initial pos of the slider control
|
||||
m_speedSlider.SetPos (m_iInitialPercent);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
void
|
||||
CAnimationSpeed::OnHScroll
|
||||
(
|
||||
UINT nSBCode,
|
||||
UINT nPos,
|
||||
CScrollBar* pScrollBar
|
||||
)
|
||||
{
|
||||
// Get the current position of the slider control
|
||||
m_iInitialPercent = m_speedSlider.GetPos ();
|
||||
|
||||
// Get a pointer to the main window
|
||||
CMainFrame *pCMainWnd = (CMainFrame *)::AfxGetMainWnd ();
|
||||
if (pCMainWnd)
|
||||
{
|
||||
// Get a pointer to the graphic view pane
|
||||
CGraphicView *pCGraphicView = (CGraphicView *)pCMainWnd->GetPane (0, 1);
|
||||
if (pCGraphicView)
|
||||
{
|
||||
pCGraphicView->SetAnimationSpeed (((float)m_iInitialPercent) / (100.00F));
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnHScroll (nSBCode, nPos, pScrollBar);
|
||||
return ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnDestroy
|
||||
//
|
||||
void
|
||||
CAnimationSpeed::OnDestroy (void)
|
||||
{
|
||||
m_iInitialPercent = m_speedSlider.GetPos ();
|
||||
CDialog::OnDestroy();
|
||||
return ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnBlend
|
||||
//
|
||||
void
|
||||
CAnimationSpeed::OnBlend (void)
|
||||
{
|
||||
// Get a pointer to the doc so we can get at the current scene
|
||||
// pointer.
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
// Turn on/off the blending option
|
||||
pCDoc->SetAnimationBlend (SendDlgItemMessage (IDC_BLEND, BM_GETCHECK));
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
void CAnimationSpeed::
|
||||
OnCompressq(){
|
||||
/* CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if(pCDoc){
|
||||
bool b_was_compressed = pCDoc->GetChannelQCompression();
|
||||
bool b_compress = IsDlgButtonChecked(IDC_COMPRESSQ) == BST_CHECKED;
|
||||
pCDoc->SetChannelQCompression(b_compress);
|
||||
//Enable/Disable
|
||||
if(b_compress){
|
||||
GetDlgItem(IDC_16BIT)->EnableWindow(TRUE);
|
||||
GetDlgItem(IDC_8BIT)->EnableWindow(TRUE);
|
||||
}else{
|
||||
GetDlgItem(IDC_16BIT)->EnableWindow(FALSE);
|
||||
GetDlgItem(IDC_8BIT)->EnableWindow(FALSE);
|
||||
}
|
||||
//Update
|
||||
if(b_compress != b_was_compressed){
|
||||
int n_bytes = pCDoc->GetChannelQnBytes();
|
||||
CompressQ = b_compress;
|
||||
QnBytes = n_bytes;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void CAnimationSpeed::
|
||||
On16bit(){
|
||||
/*
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
pCDoc->SetChannelQnBytes(2);
|
||||
QnBytes = 2;
|
||||
*/
|
||||
}
|
||||
void CAnimationSpeed::
|
||||
On8bit(){
|
||||
/*
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
pCDoc->SetChannelQnBytes(1);
|
||||
QnBytes = 1;
|
||||
*/
|
||||
}
|
||||
73
Code/Tools/W3DView/AnimationSpeed.h
Normal file
73
Code/Tools/W3DView/AnimationSpeed.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
** 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_ANIMATIONSPEED_H__D60CC3CD_5F94_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
#define AFX_ANIMATIONSPEED_H__D60CC3CD_5F94_11D2_9FC7_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// AnimationSpeed.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAnimationSpeed dialog
|
||||
|
||||
class CAnimationSpeed : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CAnimationSpeed(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CAnimationSpeed)
|
||||
enum { IDD = IDD_DISPLAYSPEED };
|
||||
CSliderCtrl m_speedSlider;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAnimationSpeed)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CAnimationSpeed)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||||
afx_msg void OnDestroy();
|
||||
afx_msg void OnBlend();
|
||||
afx_msg void OnCompressq();
|
||||
afx_msg void On16bit();
|
||||
afx_msg void On8bit();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
int m_iInitialPercent;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ANIMATIONSPEED_H__D60CC3CD_5F94_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
81
Code/Tools/W3DView/AssetInfo.cpp
Normal file
81
Code/Tools/W3DView/AssetInfo.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : W3DView *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/W3DView/AssetInfo.cpp $*
|
||||
* *
|
||||
* Author:: Patrick Smith *
|
||||
* *
|
||||
* $Modtime:: 2/25/00 4:16p $*
|
||||
* *
|
||||
* $Revision:: 4 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "StdAfx.H"
|
||||
#include "AssetInfo.H"
|
||||
//#include "HModel.H"
|
||||
#include "AssetMgr.H"
|
||||
#include "HTree.H"
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
void
|
||||
AssetInfoClass::Initialize (void)
|
||||
{
|
||||
// If this isn't a material, then try to get its hierarchy name (if there is one)
|
||||
if (m_AssetType != TypeMaterial) {
|
||||
|
||||
// Assume we are wrapping an instance as apposed to an asset 'name'.
|
||||
RenderObjClass *prender_obj = m_pRenderObj;
|
||||
SAFE_ADD_REF (prender_obj);
|
||||
|
||||
// If we are wrapping an asset name, then create an instance of it.
|
||||
if (prender_obj == NULL) {
|
||||
prender_obj = WW3DAssetManager::Get_Instance()->Create_Render_Obj (m_Name);
|
||||
}
|
||||
|
||||
if (prender_obj != NULL) {
|
||||
|
||||
// Get the hierarchy tree for this object (if one exists)
|
||||
const HTreeClass *phtree = prender_obj->Get_HTree ();
|
||||
if (phtree) {
|
||||
|
||||
// Get the name of the hierarchy tree
|
||||
m_HierarchyName = phtree->Get_Name ();
|
||||
}
|
||||
}
|
||||
|
||||
// Release our hold on the temporary object
|
||||
MEMBER_RELEASE (prender_obj);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
133
Code/Tools/W3DView/AssetInfo.h
Normal file
133
Code/Tools/W3DView/AssetInfo.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : W3DView *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/W3DView/AssetInfo.h $*
|
||||
* *
|
||||
* Author:: Patrick Smith *
|
||||
* *
|
||||
* $Modtime:: 3/09/99 2:50p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ASSET_INFO_H
|
||||
#define __ASSET_INFO_H
|
||||
|
||||
#include "RendObj.H"
|
||||
#include "Utils.H"
|
||||
#include "AssetTypes.H"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AssetInfoClass
|
||||
//
|
||||
// Class used by the data tree to identify each individual
|
||||
// entry in the tree.
|
||||
//
|
||||
class AssetInfoClass
|
||||
{
|
||||
public:
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public constructors/destructors
|
||||
//
|
||||
AssetInfoClass (void)
|
||||
: m_AssetType (TypeUnknown),
|
||||
m_dwUserData (0L),
|
||||
m_pRenderObj (NULL) { Initialize (); }
|
||||
|
||||
AssetInfoClass (LPCTSTR passet_name, ASSET_TYPE type, RenderObjClass *prender_obj = NULL, DWORD user_data = 0L)
|
||||
: m_Name (passet_name),
|
||||
m_AssetType (type),
|
||||
m_dwUserData (user_data),
|
||||
m_pRenderObj (NULL) { MEMBER_ADD (m_pRenderObj, prender_obj); Initialize (); }
|
||||
|
||||
virtual ~AssetInfoClass (void) { MEMBER_RELEASE (m_pRenderObj); }
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
//
|
||||
// Inline accessors
|
||||
//
|
||||
const CString & Get_Name (void) const { return m_Name; }
|
||||
const CString & Get_Hierarchy_Name (void) const { return m_HierarchyName; }
|
||||
const CString & Get_Original_Name (void) const { return m_OriginalName; }
|
||||
ASSET_TYPE Get_Type (void) const { return m_AssetType; }
|
||||
DWORD Get_User_Number (void) const { return m_dwUserData; }
|
||||
const CString & Get_User_String (void) const { return m_UserString; }
|
||||
RenderObjClass * Get_Render_Obj (void) const { SAFE_ADD_REF (m_pRenderObj); return m_pRenderObj; }
|
||||
RenderObjClass * Peek_Render_Obj (void) const { return m_pRenderObj; }
|
||||
void Set_Name (LPCTSTR pname) { m_Name = pname; }
|
||||
void Set_Hierarchy_Name (LPCTSTR pname) { m_HierarchyName = pname; }
|
||||
void Set_Type (ASSET_TYPE type) { m_AssetType = type; }
|
||||
void Set_User_Number (DWORD user_data) { m_dwUserData = user_data; }
|
||||
void Set_User_String (LPCTSTR string) { m_UserString = string; }
|
||||
void Set_Render_Obj (RenderObjClass *pobj) { MEMBER_ADD (m_pRenderObj, pobj); }
|
||||
|
||||
//
|
||||
// Information methods
|
||||
//
|
||||
bool Can_Asset_Have_Animations (void) const { return bool(m_HierarchyName.GetLength () > 0); }
|
||||
|
||||
protected:
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Initialize (void);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
CString m_Name;
|
||||
CString m_HierarchyName;
|
||||
CString m_UserString;
|
||||
CString m_OriginalName;
|
||||
ASSET_TYPE m_AssetType;
|
||||
DWORD m_dwUserData;
|
||||
RenderObjClass * m_pRenderObj;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //__ASSET_INFO_H
|
||||
76
Code/Tools/W3DView/AssetPropertySheet.cpp
Normal file
76
Code/Tools/W3DView/AssetPropertySheet.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// AssetPropertySheet.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "W3DView.h"
|
||||
#include "AssetPropertySheet.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAssetPropertySheet
|
||||
|
||||
IMPLEMENT_DYNAMIC(CAssetPropertySheet, CPropertySheet)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CAssetPropertySheet
|
||||
//
|
||||
CAssetPropertySheet::CAssetPropertySheet
|
||||
(
|
||||
int iCaptionID,
|
||||
CPropertyPage *pCPropertyPage,
|
||||
CWnd *pCParentWnd
|
||||
)
|
||||
: m_pCPropertyPage (pCPropertyPage),
|
||||
CPropertySheet (iCaptionID, pCParentWnd)
|
||||
{
|
||||
ASSERT (m_pCPropertyPage);
|
||||
|
||||
m_psh.dwFlags |= PSH_NOAPPLYNOW;
|
||||
|
||||
// Add this page to the property sheet
|
||||
AddPage (m_pCPropertyPage);
|
||||
return ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// :~CAssetPropertySheet
|
||||
//
|
||||
CAssetPropertySheet::~CAssetPropertySheet ()
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAssetPropertySheet, CPropertySheet)
|
||||
//{{AFX_MSG_MAP(CAssetPropertySheet)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAssetPropertySheet message handlers
|
||||
74
Code/Tools/W3DView/AssetPropertySheet.h
Normal file
74
Code/Tools/W3DView/AssetPropertySheet.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
** 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_ASSETPROPERTYSHEET_H__FB40246D_5DFB_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
#define AFX_ASSETPROPERTYSHEET_H__FB40246D_5DFB_11D2_9FC7_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// AssetPropertySheet.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAssetPropertySheet
|
||||
|
||||
class CAssetPropertySheet : public CPropertySheet
|
||||
{
|
||||
DECLARE_DYNAMIC(CAssetPropertySheet)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CAssetPropertySheet (int iCaptionID, CPropertyPage *pCPropertyPage, CWnd *pCParentWnd = NULL);
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAssetPropertySheet)
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CAssetPropertySheet();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CAssetPropertySheet)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
// Private constructors (shouldn't be called)
|
||||
CAssetPropertySheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0) {}
|
||||
CAssetPropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0) {}
|
||||
|
||||
CPropertyPage *m_pCPropertyPage;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_ASSETPROPERTYSHEET_H__FB40246D_5DFB_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
64
Code/Tools/W3DView/AssetTypes.h
Normal file
64
Code/Tools/W3DView/AssetTypes.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : W3DView *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/W3DView/AssetTypes.h $*
|
||||
* *
|
||||
* Author:: Patrick Smith *
|
||||
* *
|
||||
* $Modtime:: 10/11/00 9:36a $*
|
||||
* *
|
||||
* $Revision:: 5 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef __ASSET_TYPES_H
|
||||
#define __ASSET_TYPES_H
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TypeUnknown = -1,
|
||||
TypeMaterial = 0,
|
||||
TypeMesh,
|
||||
TypeHierarchy,
|
||||
TypeAggregate,
|
||||
TypeLOD,
|
||||
TypeAnimation,
|
||||
TypeCollection,
|
||||
TypeEmitter,
|
||||
TypeCompressedAnimation,
|
||||
TypePrimitives,
|
||||
TypeSound
|
||||
|
||||
} ASSET_TYPE;
|
||||
|
||||
|
||||
#endif //__ASSET_TYPES_H
|
||||
160
Code/Tools/W3DView/BackgroundBMPDialog.cpp
Normal file
160
Code/Tools/W3DView/BackgroundBMPDialog.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// BackgroundBMPDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "BackgroundBMPDialog.h"
|
||||
#include "W3DViewDoc.H"
|
||||
#include "Utils.H"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CBackgroundBMPDialog dialog
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CBackgroundBMPDialog
|
||||
//
|
||||
CBackgroundBMPDialog::CBackgroundBMPDialog (CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CBackgroundBMPDialog::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CBackgroundBMPDialog)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
CBackgroundBMPDialog::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::DoDataExchange (pDX);
|
||||
|
||||
//{{AFX_DATA_MAP(CBackgroundBMPDialog)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CBackgroundBMPDialog, CDialog)
|
||||
//{{AFX_MSG_MAP(CBackgroundBMPDialog)
|
||||
ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CBackgroundBMPDialog message handlers
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
CBackgroundBMPDialog::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
// Center the dialog around the data tree view instead
|
||||
// of the direct center of the screen
|
||||
::CenterDialogAroundTreeView (m_hWnd);
|
||||
|
||||
// Gett a pointer to the current document
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
// Set the initial filename in the edit control
|
||||
SetDlgItemText (IDC_FILENAME_EDIT, pCDoc->GetBackgroundBMP ());
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnOK
|
||||
//
|
||||
void
|
||||
CBackgroundBMPDialog::OnOK (void)
|
||||
{
|
||||
// Gett a pointer to the current document
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
CString stringBackgroundBMPName;
|
||||
|
||||
// Get the filename the user entered
|
||||
if (GetDlgItemText (IDC_FILENAME_EDIT, stringBackgroundBMPName) > 0)
|
||||
{
|
||||
// Ask the doc to create a new background from this BMP
|
||||
pCDoc->SetBackgroundBMP (stringBackgroundBMPName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ask the doc to clear any existing background BMP
|
||||
pCDoc->SetBackgroundBMP (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnOK ();
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnBrowse
|
||||
//
|
||||
void
|
||||
CBackgroundBMPDialog::OnBrowse (void)
|
||||
{
|
||||
// Get a pointer to the current document
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
CFileDialog openFileDialog (TRUE,
|
||||
".tga",
|
||||
pCDoc->GetBackgroundBMP (),
|
||||
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER,
|
||||
"Targa files (*.tga)|*.tga||",
|
||||
this);
|
||||
|
||||
// Ask the user what Targa file they wish to load
|
||||
if (openFileDialog.DoModal () == IDOK)
|
||||
{
|
||||
// Set the text of the filename edit control
|
||||
SetDlgItemText (IDC_FILENAME_EDIT, openFileDialog.GetPathName ());
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
66
Code/Tools/W3DView/BackgroundBMPDialog.h
Normal file
66
Code/Tools/W3DView/BackgroundBMPDialog.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
** 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_BACKGROUNDBMPDIALOG_H__5D8C201B_6380_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
#define AFX_BACKGROUNDBMPDIALOG_H__5D8C201B_6380_11D2_9FC7_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// BackgroundBMPDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CBackgroundBMPDialog dialog
|
||||
|
||||
class CBackgroundBMPDialog : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CBackgroundBMPDialog(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CBackgroundBMPDialog)
|
||||
enum { IDD = IDD_BACKGROUND_BMP };
|
||||
// NOTE: the ClassWizard will add data members here
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CBackgroundBMPDialog)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CBackgroundBMPDialog)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnBrowse();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_BACKGROUNDBMPDIALOG_H__5D8C201B_6380_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
250
Code/Tools/W3DView/BackgroundColorDialog.cpp
Normal file
250
Code/Tools/W3DView/BackgroundColorDialog.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// BackgroundColorDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "W3DView.h"
|
||||
#include "BackgroundColorDialog.h"
|
||||
#include "MainFrm.H"
|
||||
#include "W3DViewDoc.H"
|
||||
#include "Utils.H"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CBackgroundColorDialog dialog
|
||||
|
||||
|
||||
CBackgroundColorDialog::CBackgroundColorDialog(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CBackgroundColorDialog::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CBackgroundColorDialog)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void CBackgroundColorDialog::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CBackgroundColorDialog)
|
||||
DDX_Control(pDX, IDC_SLIDER_BLUE, m_blueSlider);
|
||||
DDX_Control(pDX, IDC_SLIDER_GREEN, m_greenSlider);
|
||||
DDX_Control(pDX, IDC_SLIDER_RED, m_redSlider);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CBackgroundColorDialog, CDialog)
|
||||
//{{AFX_MSG_MAP(CBackgroundColorDialog)
|
||||
ON_WM_HSCROLL()
|
||||
ON_BN_CLICKED(IDC_GRAYSCALE_CHECK, OnGrayscaleCheck)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CBackgroundColorDialog message handlers
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
CBackgroundColorDialog::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
// Center the dialog around the data tree view instead
|
||||
// of the direct center of the screen
|
||||
::CenterDialogAroundTreeView (m_hWnd);
|
||||
|
||||
m_redSlider.SetRange (0, 100);
|
||||
m_greenSlider.SetRange (0, 100);
|
||||
m_blueSlider.SetRange (0, 100);
|
||||
|
||||
// Get a pointer to the doc so we can get at the current
|
||||
// background color
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
// Get the background color from the document
|
||||
Vector3 colorSettings = pCDoc->GetBackgroundColor ();
|
||||
|
||||
// Remember these initial settings so we can restore them
|
||||
// if the user cancels
|
||||
m_initialRed = int(colorSettings.X * 100.00F);
|
||||
m_initialGreen = int(colorSettings.Y * 100.00F);
|
||||
m_initialBlue = int(colorSettings.Z * 100.00F);
|
||||
}
|
||||
|
||||
if ((m_initialRed == m_initialGreen) &&
|
||||
(m_initialRed == m_initialBlue))
|
||||
{
|
||||
// Check the grayscale checkbox
|
||||
SendDlgItemMessage (IDC_GRAYSCALE_CHECK, BM_SETCHECK, (WPARAM)TRUE);
|
||||
}
|
||||
|
||||
// Set the initial slider position
|
||||
m_redSlider.SetPos (m_initialRed);
|
||||
m_greenSlider.SetPos (m_initialGreen);
|
||||
m_blueSlider.SetPos (m_initialBlue);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnHScroll
|
||||
//
|
||||
void
|
||||
CBackgroundColorDialog::OnHScroll
|
||||
(
|
||||
UINT nSBCode,
|
||||
UINT nPos,
|
||||
CScrollBar* pScrollBar
|
||||
)
|
||||
{
|
||||
if (SendDlgItemMessage (IDC_GRAYSCALE_CHECK, BM_GETCHECK))
|
||||
{
|
||||
int iCurrentPos = 0;
|
||||
if (pScrollBar == GetDlgItem (IDC_SLIDER_RED))
|
||||
{
|
||||
iCurrentPos = m_redSlider.GetPos ();
|
||||
}
|
||||
else if (pScrollBar == GetDlgItem (IDC_SLIDER_GREEN))
|
||||
{
|
||||
iCurrentPos = m_greenSlider.GetPos ();
|
||||
}
|
||||
else
|
||||
{
|
||||
iCurrentPos = m_blueSlider.GetPos ();
|
||||
}
|
||||
|
||||
// Make all the sliders the same pos
|
||||
m_redSlider.SetPos (iCurrentPos);
|
||||
m_greenSlider.SetPos (iCurrentPos);
|
||||
m_blueSlider.SetPos (iCurrentPos);
|
||||
}
|
||||
|
||||
Vector3 colorSettings;
|
||||
colorSettings.X = float(m_redSlider.GetPos ()) / 100.00F;
|
||||
colorSettings.Y = float(m_greenSlider.GetPos ()) / 100.00F;
|
||||
colorSettings.Z = float(m_blueSlider.GetPos ()) / 100.00F;
|
||||
|
||||
// Get a pointer to the document so we can change the current
|
||||
// background color
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
// Modify the ambient light for this scene
|
||||
pCDoc->SetBackgroundColor (colorSettings);
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnHScroll (nSBCode, nPos, pScrollBar);
|
||||
return ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnGrayscaleCheck
|
||||
//
|
||||
void
|
||||
CBackgroundColorDialog::OnGrayscaleCheck (void)
|
||||
{
|
||||
if (SendDlgItemMessage (IDC_GRAYSCALE_CHECK, BM_GETCHECK))
|
||||
{
|
||||
// Make the green and blue sliders the same as red
|
||||
m_greenSlider.SetPos (m_redSlider.GetPos ());
|
||||
m_blueSlider.SetPos (m_redSlider.GetPos ());
|
||||
|
||||
Vector3 colorSettings;
|
||||
colorSettings.X = float(m_redSlider.GetPos ()) / 100.00F;
|
||||
colorSettings.Y = float(m_greenSlider.GetPos ()) / 100.00F;
|
||||
colorSettings.Z = float(m_blueSlider.GetPos ()) / 100.00F;
|
||||
|
||||
// Get a pointer to the document so we can change the background
|
||||
// color
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
// Modify the current background color
|
||||
pCDoc->SetBackgroundColor (colorSettings);
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCancel
|
||||
//
|
||||
void
|
||||
CBackgroundColorDialog::OnCancel (void)
|
||||
{
|
||||
Vector3 colorSettings;
|
||||
colorSettings.X = float(m_initialRed) / 100.00F;
|
||||
colorSettings.Y = float(m_initialGreen) / 100.00F;
|
||||
colorSettings.Z = float(m_initialBlue) / 100.00F;
|
||||
|
||||
// Get a pointer to the document so we can change the
|
||||
// background color
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
// Restore the current background color
|
||||
pCDoc->SetBackgroundColor (colorSettings);
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnCancel();
|
||||
return ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WindowProc
|
||||
//
|
||||
LRESULT
|
||||
CBackgroundColorDialog::WindowProc
|
||||
(
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
if (message == WM_PAINT)
|
||||
{
|
||||
// Paint the gradients for each color
|
||||
::Paint_Gradient (::GetDlgItem (m_hWnd, IDC_RED_GRADIENT), 1, 0, 0);
|
||||
::Paint_Gradient (::GetDlgItem (m_hWnd, IDC_GREEN_GRADIENT), 0, 1, 0);
|
||||
::Paint_Gradient (::GetDlgItem (m_hWnd, IDC_BLUE_GRADIENT), 0, 0, 1);
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CDialog::WindowProc (message, wParam, lParam);
|
||||
}
|
||||
75
Code/Tools/W3DView/BackgroundColorDialog.h
Normal file
75
Code/Tools/W3DView/BackgroundColorDialog.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
** 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_BACKGROUNDCOLORDIALOG_H__AF3CDE8C_61EC_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
#define AFX_BACKGROUNDCOLORDIALOG_H__AF3CDE8C_61EC_11D2_9FC7_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// BackgroundColorDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CBackgroundColorDialog dialog
|
||||
|
||||
class CBackgroundColorDialog : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CBackgroundColorDialog(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CBackgroundColorDialog)
|
||||
enum { IDD = IDD_BACKGROUND_COLOR };
|
||||
CSliderCtrl m_blueSlider;
|
||||
CSliderCtrl m_greenSlider;
|
||||
CSliderCtrl m_redSlider;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CBackgroundColorDialog)
|
||||
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(CBackgroundColorDialog)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||||
afx_msg void OnGrayscaleCheck();
|
||||
virtual void OnCancel();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
int m_initialRed;
|
||||
int m_initialGreen;
|
||||
int m_initialBlue;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_BACKGROUNDCOLORDIALOG_H__AF3CDE8C_61EC_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
240
Code/Tools/W3DView/BackgroundObjectDialog.cpp
Normal file
240
Code/Tools/W3DView/BackgroundObjectDialog.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// BackgroundObjectDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "BackgroundObjectDialog.h"
|
||||
#include "AssetMgr.H"
|
||||
#include "Utils.H"
|
||||
#include "W3DViewDoc.H"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CBackgroundObjectDialog
|
||||
//
|
||||
CBackgroundObjectDialog::CBackgroundObjectDialog (CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CBackgroundObjectDialog::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CBackgroundObjectDialog)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
CBackgroundObjectDialog::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CBackgroundObjectDialog)
|
||||
DDX_Control(pDX, IDC_HIERARCHY_LIST, m_heirarchyListCtrl);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CBackgroundObjectDialog, CDialog)
|
||||
//{{AFX_MSG_MAP(CBackgroundObjectDialog)
|
||||
ON_NOTIFY(LVN_ITEMCHANGED, IDC_HIERARCHY_LIST, OnItemChangedHierarchyList)
|
||||
ON_BN_CLICKED(IDC_CLEAR, OnClear)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CBackgroundObjectDialog message handlers
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
CBackgroundObjectDialog::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
// Center the dialog around the data tree view instead
|
||||
// of the direct center of the screen
|
||||
::CenterDialogAroundTreeView (m_hWnd);
|
||||
|
||||
m_heirarchyListCtrl.InsertColumn (0, "Name");
|
||||
//m_heirarchyListCtrl.InsertColumn (1, "Subobjects");
|
||||
|
||||
// Get an iterator from the asset manager that we can
|
||||
// use to enumerate the currently loaded assets
|
||||
RenderObjIterator *pObjEnum = WW3DAssetManager::Get_Instance()->Create_Render_Obj_Iterator ();
|
||||
|
||||
ASSERT (pObjEnum);
|
||||
if (pObjEnum)
|
||||
{
|
||||
// Loop through all the assets in the manager
|
||||
for (pObjEnum->First ();
|
||||
pObjEnum->Is_Done () == FALSE;
|
||||
pObjEnum->Next ())
|
||||
{
|
||||
LPCTSTR pszItemName = pObjEnum->Current_Item_Name ();
|
||||
|
||||
// Is this a hierarchy?
|
||||
if (WW3DAssetManager::Get_Instance()->Render_Obj_Exists (pszItemName) &&
|
||||
(pObjEnum->Current_Item_Class_ID () == RenderObjClass::CLASSID_HMODEL))
|
||||
{
|
||||
// Add this hierarchy to the list
|
||||
m_heirarchyListCtrl.InsertItem (0, pszItemName);
|
||||
}
|
||||
}
|
||||
|
||||
// Free the enumerator object we created earlier
|
||||
delete pObjEnum;
|
||||
pObjEnum = NULL;
|
||||
}
|
||||
|
||||
// Get a pointer to the doc
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
// Get the name of the current background object
|
||||
CString stringCurrObject = pCDoc->GetBackgroundObjectName ();
|
||||
|
||||
LV_FINDINFO findInfo = { 0 };
|
||||
findInfo.flags = LVFI_STRING;
|
||||
findInfo.psz = (LPCTSTR)stringCurrObject;
|
||||
|
||||
// Attempt to find this item in the list control
|
||||
int iIndex = m_heirarchyListCtrl.FindItem (&findInfo);
|
||||
if (iIndex != -1)
|
||||
{
|
||||
// Select the item in the list control
|
||||
m_heirarchyListCtrl.SetItemState (iIndex, LVNI_SELECTED, LVNI_SELECTED);
|
||||
SetDlgItemText (IDC_CURR_OBJ, m_heirarchyListCtrl.GetItemText (iIndex, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select the first item in the list control
|
||||
m_heirarchyListCtrl.SetItemState (0, LVNI_SELECTED, LVNI_SELECTED);
|
||||
SetDlgItemText (IDC_CURR_OBJ, m_heirarchyListCtrl.GetItemText (0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// Size the columns so they are large enough to display their contents
|
||||
m_heirarchyListCtrl.SetColumnWidth (0, LVSCW_AUTOSIZE);
|
||||
//m_heirarchyListCtrl.SetColumnWidth (1, LVSCW_AUTOSIZE_USEHEADER);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
void
|
||||
CBackgroundObjectDialog::OnOK (void)
|
||||
{
|
||||
// Get a pointer to the doc
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
// Get the index of the currently selected item.
|
||||
int iIndex = m_heirarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
|
||||
if (iIndex != -1)
|
||||
{
|
||||
// Get the name of the item from the list control
|
||||
CString stringItemName = m_heirarchyListCtrl.GetItemText (iIndex, 0);
|
||||
|
||||
// Ask the doc to load the background object and display it
|
||||
pCDoc->SetBackgroundObject (stringItemName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ask the doc to clear the background object
|
||||
pCDoc->SetBackgroundObject (NULL);
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnOK ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnItemChangedHierarchyList
|
||||
//
|
||||
void
|
||||
CBackgroundObjectDialog::OnItemChangedHierarchyList
|
||||
(
|
||||
NMHDR* pNMHDR,
|
||||
LRESULT* pResult
|
||||
)
|
||||
{
|
||||
// Did the 'state' of the entry change?
|
||||
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
|
||||
if (pNMListView &&
|
||||
(pNMListView->uChanged & LVIF_STATE) == LVIF_STATE)
|
||||
{
|
||||
// Is the new state a selected state?
|
||||
if ((pNMListView->uNewState & LVIS_SELECTED) != LVIS_SELECTED)
|
||||
{
|
||||
// Is there a selected item in the list control?
|
||||
if (m_heirarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED) == -1)
|
||||
{
|
||||
// Clear the text of the current object static text control
|
||||
SetDlgItemText (IDC_CURR_OBJ, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the text of the current object static text control
|
||||
SetDlgItemText (IDC_CURR_OBJ, m_heirarchyListCtrl.GetItemText (pNMListView->iItem, 0));
|
||||
}
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnClear
|
||||
//
|
||||
void
|
||||
CBackgroundObjectDialog::OnClear (void)
|
||||
{
|
||||
// Get the current selection (if any)
|
||||
int iIndex = m_heirarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
|
||||
if (iIndex != -1)
|
||||
{
|
||||
// Clear the selection state from this entry
|
||||
m_heirarchyListCtrl.SetItemState (iIndex, 0, LVIS_SELECTED);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
67
Code/Tools/W3DView/BackgroundObjectDialog.h
Normal file
67
Code/Tools/W3DView/BackgroundObjectDialog.h
Normal 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/>.
|
||||
*/
|
||||
|
||||
#if !defined(AFX_BACKGROUNDOBJECTDIALOG_H__9B07DA63_62B6_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
#define AFX_BACKGROUNDOBJECTDIALOG_H__9B07DA63_62B6_11D2_9FC7_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// BackgroundObjectDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CBackgroundObjectDialog dialog
|
||||
|
||||
class CBackgroundObjectDialog : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CBackgroundObjectDialog(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CBackgroundObjectDialog)
|
||||
enum { IDD = IDD_BACKGROUND_OBJECT };
|
||||
CListCtrl m_heirarchyListCtrl;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CBackgroundObjectDialog)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CBackgroundObjectDialog)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnItemChangedHierarchyList(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnClear();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_BACKGROUNDOBJECTDIALOG_H__9B07DA63_62B6_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
539
Code/Tools/W3DView/BoneMgrDialog.cpp
Normal file
539
Code/Tools/W3DView/BoneMgrDialog.cpp
Normal file
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// BoneMgrDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "StdAfx.H"
|
||||
#include "W3DView.H"
|
||||
#include "BoneMgrDialog.H"
|
||||
#include "HTree.H"
|
||||
#include "AssetMgr.H"
|
||||
#include "Utils.H"
|
||||
#include "MainFrm.H"
|
||||
#include "W3DViewDoc.H"
|
||||
#include "DataTreeView.H"
|
||||
//#include "HModel.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoneMgrDialogClass
|
||||
//
|
||||
BoneMgrDialogClass::BoneMgrDialogClass
|
||||
(
|
||||
RenderObjClass *prender_obj,
|
||||
CWnd *pparent
|
||||
)
|
||||
: m_pBaseModel (prender_obj),
|
||||
m_pBackupModel (NULL),
|
||||
m_bAttach (true),
|
||||
CDialog (BoneMgrDialogClass::IDD, pparent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(BoneMgrDialogClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
BoneMgrDialogClass::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(BoneMgrDialogClass)
|
||||
DDX_Control(pDX, IDC_OBJECT_COMBO, m_ObjectCombo);
|
||||
DDX_Control(pDX, IDC_BONE_TREE, m_BoneTree);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(BoneMgrDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(BoneMgrDialogClass)
|
||||
ON_NOTIFY(TVN_SELCHANGED, IDC_BONE_TREE, OnSelchangedBoneTree)
|
||||
ON_CBN_SELCHANGE(IDC_OBJECT_COMBO, OnSelchangeObjectCombo)
|
||||
ON_WM_DESTROY()
|
||||
ON_BN_CLICKED(IDC_ATTACH_BUTTON, OnAttachButton)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
BoneMgrDialogClass::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
// Make a backup of this hierarchy in case we need to restore it.
|
||||
m_pBackupModel = m_pBaseModel->Clone ();
|
||||
|
||||
// Create an icon imagelist for the tree control
|
||||
CImageList *pimagelist = new CImageList;
|
||||
pimagelist->Create (16, 16, ILC_COLOR | ILC_MASK, 2, 2);
|
||||
|
||||
// Load this icon and add it to our imagelist
|
||||
pimagelist->Add ((HICON)::LoadImage (::AfxGetResourceHandle (),
|
||||
MAKEINTRESOURCE (IDI_FOLDER),
|
||||
IMAGE_ICON,
|
||||
16,
|
||||
16,
|
||||
LR_SHARED));
|
||||
|
||||
pimagelist->Add ((HICON)::LoadImage (::AfxGetResourceHandle (),
|
||||
MAKEINTRESOURCE (IDI_OBJECT),
|
||||
IMAGE_ICON,
|
||||
16,
|
||||
16,
|
||||
LR_SHARED));
|
||||
|
||||
m_BoneTree.SetImageList (pimagelist, TVSIL_NORMAL);
|
||||
|
||||
// Get the hierarchy tree for this model so we can enumerate bone's
|
||||
// and subobjects.
|
||||
HTREEITEM hfirst_item = NULL;
|
||||
|
||||
// Loop through all the bones in this model
|
||||
int bone_count = m_pBaseModel->Get_Num_Bones ();
|
||||
for (int index = 0; index < bone_count; index ++) {
|
||||
const char *pbone_name = m_pBaseModel->Get_Bone_Name (index);
|
||||
|
||||
// Add this bone to the tree control
|
||||
HTREEITEM hbone_item = m_BoneTree.InsertItem (pbone_name, 0, 0);
|
||||
Fill_Bone_Item (hbone_item, index);
|
||||
|
||||
// Is this the first item we've added to the tree?
|
||||
if (hfirst_item == NULL) {
|
||||
hfirst_item = hbone_item;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Sort the tree control
|
||||
//
|
||||
m_BoneTree.SortChildren (TVI_ROOT);
|
||||
|
||||
// Build a list of all the render objects currently loaded
|
||||
CW3DViewDoc *pdoc = (CW3DViewDoc *)((CMainFrame *)::AfxGetMainWnd())->GetActiveDocument ();
|
||||
CDataTreeView *pdata_tree = pdoc->GetDataTreeView ();
|
||||
DynamicVectorClass <CString> asset_list;
|
||||
pdata_tree->Build_Render_Object_List (asset_list);
|
||||
|
||||
// Add this render object list to the combobox
|
||||
for (index = 0; index < asset_list.Count (); index ++) {
|
||||
m_ObjectCombo.AddString (asset_list[index]);
|
||||
}
|
||||
|
||||
// Select the first entry in the combobox
|
||||
m_ObjectCombo.SetCurSel (0);
|
||||
OnSelchangeObjectCombo ();
|
||||
|
||||
// Select the first item in the tree
|
||||
m_BoneTree.SelectItem (hfirst_item);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Fill_Bone_Item
|
||||
//
|
||||
void
|
||||
BoneMgrDialogClass::Fill_Bone_Item
|
||||
(
|
||||
HTREEITEM hbone_item,
|
||||
int bone_index
|
||||
)
|
||||
{
|
||||
// Create a new instance of the hmodel which we can use
|
||||
// to compare with the supplied hmodel and determine
|
||||
// which 'bones-models' are new.
|
||||
const char *orig_model_name = m_pBaseModel->Get_Base_Model_Name ();
|
||||
orig_model_name = (orig_model_name == NULL) ? m_pBaseModel->Get_Name () : orig_model_name;
|
||||
RenderObjClass *porig_model = WW3DAssetManager::Get_Instance()->Create_Render_Obj (orig_model_name);
|
||||
|
||||
// Build a list of nodes that are contained in the vanilla model
|
||||
DynamicVectorClass <RenderObjClass *> orig_node_list;
|
||||
for (int index = 0;
|
||||
index < porig_model->Get_Num_Sub_Objects_On_Bone (bone_index);
|
||||
index ++) {
|
||||
RenderObjClass *psubobj = porig_model->Get_Sub_Object_On_Bone (index, bone_index);
|
||||
if (psubobj != NULL) {
|
||||
orig_node_list.Add (psubobj);
|
||||
}
|
||||
}
|
||||
|
||||
// Build a list of nodes that are contained in this bone
|
||||
DynamicVectorClass <RenderObjClass *> node_list;
|
||||
for (index = 0;
|
||||
index < m_pBaseModel->Get_Num_Sub_Objects_On_Bone (bone_index);
|
||||
index ++) {
|
||||
RenderObjClass *psubobj = m_pBaseModel->Get_Sub_Object_On_Bone (index, bone_index);
|
||||
if (psubobj != NULL) {
|
||||
node_list.Add (psubobj);
|
||||
}
|
||||
}
|
||||
|
||||
if (node_list.Count () > 0) {
|
||||
|
||||
// Add the subobjects to the tree control
|
||||
for (int node_index = 0; node_index < node_list.Count (); node_index ++) {
|
||||
RenderObjClass *psubobject = node_list[node_index];
|
||||
ASSERT (psubobject != NULL);
|
||||
|
||||
// Is this subobject new? (i.e. not in a 'vanilla' instance?)
|
||||
if (psubobject != NULL &&
|
||||
(Is_Object_In_List (psubobject->Get_Name (), orig_node_list) == false)) {
|
||||
m_BoneTree.InsertItem (psubobject->Get_Name (), 1, 1, hbone_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Free our hold on the render objs in the original node list
|
||||
for (index = 0; index < orig_node_list.Count (); index ++) {
|
||||
MEMBER_RELEASE (orig_node_list[index]);
|
||||
}
|
||||
|
||||
// Free our hold on the render objs in the node list
|
||||
for (index = 0; index < node_list.Count (); index ++) {
|
||||
MEMBER_RELEASE (node_list[index]);
|
||||
}
|
||||
|
||||
MEMBER_RELEASE (porig_model);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Is_Object_In_List
|
||||
//
|
||||
bool
|
||||
BoneMgrDialogClass::Is_Object_In_List
|
||||
(
|
||||
const char *passet_name,
|
||||
DynamicVectorClass <RenderObjClass *> &node_list
|
||||
)
|
||||
{
|
||||
// Assume failure
|
||||
bool retval = false;
|
||||
|
||||
// Loop through the nodes in the list until we've found the one
|
||||
// were are looking for.
|
||||
for (int node_index = 0; (node_index < node_list.Count ()) && (retval == false); node_index ++) {
|
||||
RenderObjClass *prender_obj = node_list[node_index];
|
||||
|
||||
// Is this the render object we were looking for?
|
||||
if (prender_obj != NULL &&
|
||||
::lstrcmpi (prender_obj->Get_Name (), passet_name) == 0) {
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the true/false result code
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSelchangedBoneTree
|
||||
//
|
||||
void
|
||||
BoneMgrDialogClass::OnSelchangedBoneTree
|
||||
(
|
||||
NMHDR *pNMHDR,
|
||||
LRESULT *pResult
|
||||
)
|
||||
{
|
||||
// Make the dialog controls reflect the new selection
|
||||
NM_TREEVIEW *pNMTreeView = (NM_TREEVIEW *)pNMHDR;
|
||||
Update_Controls (pNMTreeView->itemNew.hItem);
|
||||
|
||||
(*pResult) = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSelchangeObjectCombo
|
||||
//
|
||||
void
|
||||
BoneMgrDialogClass::OnSelchangeObjectCombo (void)
|
||||
{
|
||||
// Get the name of the currently selected render object
|
||||
CString name;
|
||||
int index = m_ObjectCombo.GetCurSel ();
|
||||
m_ObjectCombo.GetLBText (index, name);
|
||||
|
||||
// Change the text of the 'Attach' button based on whether or not
|
||||
// this render object is already attached to the current bone.
|
||||
if (Is_Render_Obj_Already_Attached (name)) {
|
||||
SetDlgItemText (IDC_ATTACH_BUTTON, "&Remove");
|
||||
m_bAttach = false;
|
||||
} else {
|
||||
SetDlgItemText (IDC_ATTACH_BUTTON, "&Attach");
|
||||
m_bAttach = true;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Is_Render_Obj_Already_Attached
|
||||
//
|
||||
bool
|
||||
BoneMgrDialogClass::Is_Render_Obj_Already_Attached (const CString &name)
|
||||
{
|
||||
// Assume not already attached
|
||||
bool retval = false;
|
||||
|
||||
HTREEITEM htree_item = m_BoneTree.GetSelectedItem ();
|
||||
HTREEITEM hparent_item = m_BoneTree.GetParentItem (htree_item);
|
||||
htree_item = (hparent_item != NULL) ? hparent_item : htree_item;
|
||||
if (htree_item != NULL) {
|
||||
|
||||
// Loop through all the children of this bone
|
||||
for (HTREEITEM hchild_item = m_BoneTree.GetChildItem (htree_item);
|
||||
(hchild_item != NULL) && (retval == false);
|
||||
hchild_item = m_BoneTree.GetNextSiblingItem (hchild_item)) {
|
||||
|
||||
// Is this the render object we were looking for?
|
||||
CString child_name = m_BoneTree.GetItemText (hchild_item);
|
||||
if (name.CompareNoCase (child_name) == 0) {
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the true/false result code
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Controls
|
||||
//
|
||||
void
|
||||
BoneMgrDialogClass::Update_Controls (HTREEITEM selected_item)
|
||||
{
|
||||
// Get the name of the currently selected item
|
||||
CString name = m_BoneTree.GetItemText (selected_item);
|
||||
bool bis_bone = (m_BoneTree.GetParentItem (selected_item) == NULL);
|
||||
|
||||
// Did the user select a bone name?
|
||||
if (bis_bone) {
|
||||
m_BoneName = name;
|
||||
} else {
|
||||
|
||||
// Select this render object in the combobox
|
||||
int index = m_ObjectCombo.FindStringExact (-1, name);
|
||||
m_ObjectCombo.SetCurSel ((index != CB_ERR) ? index : 0);
|
||||
|
||||
// The bone name is the name of the parent item of the selected item.
|
||||
m_BoneName = m_BoneTree.GetItemText (m_BoneTree.GetParentItem (selected_item));
|
||||
}
|
||||
|
||||
OnSelchangeObjectCombo ();
|
||||
|
||||
// Change the text of the group box to reflect the bone name
|
||||
CString text;
|
||||
text.Format ("Bone: %s", m_BoneName);
|
||||
SetDlgItemText (IDC_BONE_GROUPBOX, text);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnDestroy
|
||||
//
|
||||
void
|
||||
BoneMgrDialogClass::OnDestroy (void)
|
||||
{
|
||||
// Free the state image list we associated with the control
|
||||
CImageList *pimagelist = m_BoneTree.GetImageList (TVSIL_NORMAL);
|
||||
m_BoneTree.SetImageList (NULL, TVSIL_NORMAL);
|
||||
SAFE_DELETE (pimagelist);
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnDestroy ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnOK
|
||||
//
|
||||
void
|
||||
BoneMgrDialogClass::OnOK (void)
|
||||
{
|
||||
// Simply forget about the backup we made
|
||||
MEMBER_RELEASE (m_pBackupModel);
|
||||
|
||||
// Update the hierarchy's cached information to reflect the new settings
|
||||
CW3DViewDoc *pdoc = (CW3DViewDoc *)((CMainFrame *)::AfxGetMainWnd())->GetActiveDocument ();
|
||||
pdoc->Update_Aggregate_Prototype (*m_pBaseModel);
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnOK ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCancel
|
||||
//
|
||||
void
|
||||
BoneMgrDialogClass::OnCancel (void)
|
||||
{
|
||||
CWaitCursor wait_cursor;
|
||||
|
||||
// Display the backup hierarchy
|
||||
CW3DViewDoc *pdoc = (CW3DViewDoc *)((CMainFrame *)::AfxGetMainWnd())->GetActiveDocument ();
|
||||
pdoc->DisplayObject (m_pBackupModel, false, false);
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnCancel ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnAttachButton
|
||||
//
|
||||
void
|
||||
BoneMgrDialogClass::OnAttachButton (void)
|
||||
{
|
||||
// Get the name of the currently selected render object
|
||||
CString name;
|
||||
int index = m_ObjectCombo.GetCurSel ();
|
||||
m_ObjectCombo.GetLBText (index, name);
|
||||
|
||||
// Lookup the currently selected bone item
|
||||
HTREEITEM hbone_item = Get_Current_Bone_Item ();
|
||||
|
||||
// Should we attach or remove the render object?
|
||||
if (m_bAttach) {
|
||||
|
||||
// Create an instance of the render object and attach it to the bone
|
||||
RenderObjClass *prender_obj = WW3DAssetManager::Get_Instance()->Create_Render_Obj (name);
|
||||
if (prender_obj != NULL) {
|
||||
m_pBaseModel->Add_Sub_Object_To_Bone (prender_obj, m_BoneName);
|
||||
m_BoneTree.InsertItem (name, 1, 1, hbone_item);
|
||||
MEMBER_RELEASE (prender_obj);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Loop through all the subobjects on the bone
|
||||
bool found = false;
|
||||
int bone_index = m_pBaseModel->Get_Bone_Index (m_BoneName);
|
||||
int count = m_pBaseModel->Get_Num_Sub_Objects_On_Bone (bone_index);
|
||||
for (int index = 0; (index < count) && !found; index ++) {
|
||||
|
||||
// Is this the subobject we were looking for?
|
||||
RenderObjClass *psub_obj = m_pBaseModel->Get_Sub_Object_On_Bone (index, bone_index);
|
||||
if ((psub_obj != NULL) &&
|
||||
(::lstrcmpi (psub_obj->Get_Name (), name) == 0)) {
|
||||
|
||||
// Remove this subobject from the bone
|
||||
m_pBaseModel->Remove_Sub_Object (psub_obj);
|
||||
found = true;
|
||||
}
|
||||
|
||||
// Release our hold on this pointer
|
||||
MEMBER_RELEASE (psub_obj);
|
||||
}
|
||||
|
||||
// Remove the object from our UI
|
||||
Remove_Object_From_Bone (hbone_item, name);
|
||||
}
|
||||
|
||||
// Refresh the UI state
|
||||
m_BoneTree.InvalidateRect (NULL, TRUE);
|
||||
m_BoneTree.UpdateWindow ();
|
||||
Update_Controls (hbone_item);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get_Current_Bone_Item
|
||||
//
|
||||
HTREEITEM
|
||||
BoneMgrDialogClass::Get_Current_Bone_Item (void)
|
||||
{
|
||||
// Get the currently selected item and its parent
|
||||
HTREEITEM htree_item = m_BoneTree.GetSelectedItem ();
|
||||
HTREEITEM hparent_item = m_BoneTree.GetParentItem (htree_item);
|
||||
|
||||
// Return the bone item
|
||||
return (hparent_item != NULL) ? hparent_item : htree_item;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Remove_Object_From_Bone
|
||||
//
|
||||
void
|
||||
BoneMgrDialogClass::Remove_Object_From_Bone
|
||||
(
|
||||
HTREEITEM bone_item,
|
||||
const CString &name
|
||||
)
|
||||
{
|
||||
// Loop through all the children of this bone
|
||||
for (HTREEITEM hchild_item = m_BoneTree.GetChildItem (bone_item);
|
||||
(hchild_item != NULL);
|
||||
hchild_item = m_BoneTree.GetNextSiblingItem (hchild_item)) {
|
||||
|
||||
// Is this the render object we were looking for?
|
||||
CString child_name = m_BoneTree.GetItemText (hchild_item);
|
||||
if (name.CompareNoCase (child_name) == 0) {
|
||||
m_BoneTree.DeleteItem (hchild_item);
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
111
Code/Tools/W3DView/BoneMgrDialog.h
Normal file
111
Code/Tools/W3DView/BoneMgrDialog.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
** 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_BONEMGRDIALOG_H__66DA0E58_BFCA_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
#define AFX_BONEMGRDIALOG_H__66DA0E58_BFCA_11D2_9FFA_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// BoneMgrDialog.h : header file
|
||||
//
|
||||
|
||||
#include "Resource.H"
|
||||
#include "Vector.H"
|
||||
|
||||
// Forward declarations
|
||||
class HModelClass;
|
||||
class RenderObjClass;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoneMgrDialogClass
|
||||
//
|
||||
class BoneMgrDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
BoneMgrDialogClass (RenderObjClass *prender_obj, CWnd* pParent = NULL);
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(BoneMgrDialogClass)
|
||||
enum { IDD = IDD_BONE_MANAGEMENT };
|
||||
CComboBox m_ObjectCombo;
|
||||
CTreeCtrl m_BoneTree;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(BoneMgrDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(BoneMgrDialogClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnSelchangedBoneTree(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnSelchangeObjectCombo();
|
||||
afx_msg void OnDestroy();
|
||||
virtual void OnOK();
|
||||
virtual void OnCancel();
|
||||
afx_msg void OnAttachButton();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Fill_Bone_Item (HTREEITEM hbone_item, int bone_index);
|
||||
bool Is_Object_In_List (const char *passet_name, DynamicVectorClass <RenderObjClass *> &node_list);
|
||||
bool Is_Render_Obj_Already_Attached (const CString &name);
|
||||
void Update_Controls (HTREEITEM selected_item);
|
||||
HTREEITEM Get_Current_Bone_Item (void);
|
||||
void Remove_Object_From_Bone (HTREEITEM bone_item, const CString &name);
|
||||
|
||||
private:
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
RenderObjClass * m_pBaseModel;
|
||||
RenderObjClass * m_pBackupModel;
|
||||
bool m_bAttach;
|
||||
CString m_BoneName;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_BONEMGRDIALOG_H__66DA0E58_BFCA_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
132
Code/Tools/W3DView/CameraDistanceDialog.cpp
Normal file
132
Code/Tools/W3DView/CameraDistanceDialog.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// CameraDistanceDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "cameradistancedialog.h"
|
||||
#include "utils.h"
|
||||
#include "graphicview.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CameraDistanceDialogClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
CameraDistanceDialogClass::CameraDistanceDialogClass(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CameraDistanceDialogClass::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CameraDistanceDialogClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CameraDistanceDialogClass::DoDataExchange (CDataExchange *pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CameraDistanceDialogClass)
|
||||
DDX_Control(pDX, IDC_DISTANCE_SPIN, m_DistanceSpinCtrl);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CameraDistanceDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(CameraDistanceDialogClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
CameraDistanceDialogClass::OnInitDialog (void)
|
||||
{
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
CGraphicView *graphic_view = ::Get_Graphic_View ();
|
||||
|
||||
::Initialize_Spinner (m_DistanceSpinCtrl, graphic_view->Get_Camera_Distance (), 0, 25000.0F);
|
||||
::SetDlgItemFloat (m_hWnd, IDC_DISTANCE_EDIT, graphic_view->Get_Camera_Distance ());
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnOK
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CameraDistanceDialogClass::OnOK (void)
|
||||
{
|
||||
CDialog::OnOK ();
|
||||
|
||||
float distance = ::GetDlgItemFloat (m_hWnd, IDC_DISTANCE_EDIT);
|
||||
CGraphicView *graphic_view = ::Get_Graphic_View ();
|
||||
graphic_view->Set_Camera_Distance (distance);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
CameraDistanceDialogClass::OnNotify
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
LRESULT *pResult
|
||||
)
|
||||
{
|
||||
//
|
||||
// Update the spinner control if necessary
|
||||
//
|
||||
NMHDR *pheader = (NMHDR *)lParam;
|
||||
if ((pheader != NULL) && (pheader->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN pupdown = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (pheader->hwndFrom, pupdown->iDelta);
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CDialog::OnNotify (wParam, lParam, pResult);
|
||||
}
|
||||
68
Code/Tools/W3DView/CameraDistanceDialog.h
Normal file
68
Code/Tools/W3DView/CameraDistanceDialog.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
** 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_CAMERADISTANCEDIALOG_H__548D3315_D582_4B97_8607_31B4659DF498__INCLUDED_)
|
||||
#define AFX_CAMERADISTANCEDIALOG_H__548D3315_D582_4B97_8607_31B4659DF498__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CameraDistanceDialogClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
class CameraDistanceDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CameraDistanceDialogClass(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CameraDistanceDialogClass)
|
||||
enum { IDD = IDD_CAMERA_DISTANCE };
|
||||
CSpinButtonCtrl m_DistanceSpinCtrl;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CameraDistanceDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CameraDistanceDialogClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_CAMERADISTANCEDIALOG_H__548D3315_D582_4B97_8607_31B4659DF498__INCLUDED_)
|
||||
402
Code/Tools/W3DView/CameraSettingsDialog.cpp
Normal file
402
Code/Tools/W3DView/CameraSettingsDialog.cpp
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// CameraSettingsDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "w3dviewdoc.h"
|
||||
#include "graphicview.h"
|
||||
#include "CameraSettingsDialog.h"
|
||||
#include "utils.h"
|
||||
#include "camera.h"
|
||||
#include "viewerscene.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CameraSettingsDialogClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
CameraSettingsDialogClass::CameraSettingsDialogClass(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CameraSettingsDialogClass::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CameraSettingsDialogClass)
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CameraSettingsDialogClass::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CameraSettingsDialogClass)
|
||||
DDX_Control(pDX, IDC_LENS_SPIN, m_LensSpin);
|
||||
DDX_Control(pDX, IDC_FAR_CLIP_SPIN, m_FarClipSpin);
|
||||
DDX_Control(pDX, IDC_VFOV_SPIN, m_VFOVSpin);
|
||||
DDX_Control(pDX, IDC_NEAR_CLIP_SPIN, m_NearClipSpin);
|
||||
DDX_Control(pDX, IDC_HFOV_SPIN, m_HFOVSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CameraSettingsDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(CameraSettingsDialogClass)
|
||||
ON_BN_CLICKED(IDC_FOV_CHECK, OnFovCheck)
|
||||
ON_BN_CLICKED(IDC_CLIP_PLANE_CHECK, OnClipPlaneCheck)
|
||||
ON_BN_CLICKED(IDC_RESET, OnReset)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
CameraSettingsDialogClass::OnInitDialog (void)
|
||||
{
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
CW3DViewDoc *doc = ::GetCurrentDocument ();
|
||||
CGraphicView *graphic_view = doc->GetGraphicView ();
|
||||
CameraClass *camera = graphic_view->GetCamera ();
|
||||
|
||||
//
|
||||
// Enable/disable the group boxes
|
||||
//
|
||||
SendDlgItemMessage (IDC_FOV_CHECK, BM_SETCHECK, (WPARAM)doc->Is_FOV_Manual ());
|
||||
SendDlgItemMessage (IDC_CLIP_PLANE_CHECK, BM_SETCHECK, (WPARAM)doc->Are_Clip_Planes_Manual ());
|
||||
|
||||
float znear = 0;
|
||||
float zfar = 0;
|
||||
camera->Get_Clip_Planes (znear, zfar);
|
||||
::Initialize_Spinner (m_NearClipSpin, znear, 0.0F, 999999.0F);
|
||||
::Initialize_Spinner (m_FarClipSpin, zfar, 1.0F, 999999.0F);
|
||||
|
||||
//
|
||||
// Setup the FOV controls
|
||||
//
|
||||
int hfov_deg = (int)RAD_TO_DEG (camera->Get_Horizontal_FOV ());
|
||||
int vfov_deg = (int)RAD_TO_DEG (camera->Get_Vertical_FOV ());
|
||||
::Initialize_Spinner (m_HFOVSpin, hfov_deg, 0.0F, 180.0F);
|
||||
::Initialize_Spinner (m_VFOVSpin, vfov_deg, 0.0F, 180.0F);
|
||||
|
||||
//
|
||||
// Setup the camera lens controls
|
||||
//
|
||||
float hfov = camera->Get_Horizontal_FOV ();
|
||||
const float constant = (18.0F / 1000.0F);
|
||||
float lens = (constant / (::tan (hfov / 2))) * 1000.0F;
|
||||
::Initialize_Spinner (m_LensSpin, lens, 1.0F, 200.0F);
|
||||
|
||||
OnFovCheck ();
|
||||
OnClipPlaneCheck ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnOK
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CameraSettingsDialogClass::OnOK (void)
|
||||
{
|
||||
CW3DViewDoc *doc = ::GetCurrentDocument ();
|
||||
CGraphicView *graphic_view = doc->GetGraphicView ();
|
||||
CameraClass *camera = graphic_view->GetCamera ();
|
||||
|
||||
bool manual_fov = (SendDlgItemMessage (IDC_FOV_CHECK, BM_GETCHECK) == 1);
|
||||
bool manual_planes = (SendDlgItemMessage (IDC_CLIP_PLANE_CHECK, BM_GETCHECK) == 1);
|
||||
|
||||
doc->Set_Manual_FOV (manual_fov);
|
||||
doc->Set_Manul_Clip_Planes (manual_planes);
|
||||
if (manual_fov == false) {
|
||||
graphic_view->Reset_FOV ();
|
||||
} else {
|
||||
|
||||
//
|
||||
// Update the camera's FOV
|
||||
//
|
||||
float hfov_deg = ::GetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT);
|
||||
float vfov_deg = ::GetDlgItemFloat (m_hWnd, IDC_VFOV_EDIT);
|
||||
camera->Set_View_Plane (DEG_TO_RAD (hfov_deg), DEG_TO_RAD (vfov_deg));
|
||||
}
|
||||
|
||||
//
|
||||
// Update the camera's clip planes
|
||||
//
|
||||
float znear = ::GetDlgItemFloat (m_hWnd, IDC_NEAR_CLIP_EDIT);
|
||||
float zfar = ::GetDlgItemFloat (m_hWnd, IDC_FAR_CLIP_EDIT);
|
||||
camera->Set_Clip_Planes (znear, zfar);
|
||||
doc->Save_Camera_Settings ();
|
||||
|
||||
//
|
||||
// Update the fog settings. The fog near clip plane should always be equal
|
||||
// to the camera near clip plane, but the fog far clip plane is scene
|
||||
// dependant. We will be sure to modify only the near clip plane here.
|
||||
//
|
||||
float fog_near, fog_far;
|
||||
doc->GetScene()->Get_Fog_Range(&fog_near, &fog_far);
|
||||
doc->GetScene()->Set_Fog_Range(znear, fog_far);
|
||||
doc->GetScene()->Recalculate_Fog_Planes();
|
||||
|
||||
//
|
||||
// Refresh the camera settings
|
||||
//
|
||||
RenderObjClass *render_obj = doc->GetDisplayedObject ();
|
||||
if (render_obj != NULL) {
|
||||
graphic_view->Reset_Camera_To_Display_Object (*render_obj);
|
||||
}
|
||||
|
||||
CDialog::OnOK ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnFovCheck
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CameraSettingsDialogClass::OnFovCheck (void)
|
||||
{
|
||||
bool manual_fov = (SendDlgItemMessage (IDC_FOV_CHECK, BM_GETCHECK) == 1);
|
||||
::EnableWindow (m_VFOVSpin, manual_fov);
|
||||
::EnableWindow (m_HFOVSpin, manual_fov);
|
||||
::EnableWindow (m_LensSpin, manual_fov);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_VFOV_EDIT), manual_fov);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_HFOV_EDIT), manual_fov);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_LENS_EDIT), manual_fov);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnClipPlaneCheck
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CameraSettingsDialogClass::OnClipPlaneCheck (void)
|
||||
{
|
||||
bool manual_planes = (SendDlgItemMessage (IDC_CLIP_PLANE_CHECK, BM_GETCHECK) == 1);
|
||||
::EnableWindow (m_NearClipSpin, manual_planes);
|
||||
::EnableWindow (m_FarClipSpin, manual_planes);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_NEAR_CLIP_EDIT), manual_planes);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_FAR_CLIP_EDIT), manual_planes);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnReset
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CameraSettingsDialogClass::OnReset (void)
|
||||
{
|
||||
CW3DViewDoc *doc = ::GetCurrentDocument ();
|
||||
CGraphicView *graphic_view = doc->GetGraphicView ();
|
||||
CameraClass *camera = graphic_view->GetCamera ();
|
||||
|
||||
doc->Set_Manual_FOV (false);
|
||||
doc->Set_Manul_Clip_Planes (false);
|
||||
|
||||
graphic_view->Reset_FOV ();
|
||||
RenderObjClass *render_obj = doc->GetDisplayedObject ();
|
||||
if (render_obj != NULL) {
|
||||
graphic_view->Reset_Camera_To_Display_Object (*render_obj);
|
||||
}
|
||||
|
||||
//
|
||||
// Update the clip plane controls
|
||||
//
|
||||
float znear = 0;
|
||||
float zfar = 0;
|
||||
camera->Get_Clip_Planes (znear, zfar);
|
||||
::SetDlgItemFloat (m_hWnd, IDC_NEAR_CLIP_EDIT, znear);
|
||||
::SetDlgItemFloat (m_hWnd, IDC_FAR_CLIP_EDIT, zfar);
|
||||
|
||||
//
|
||||
// Update the FOV controls
|
||||
//
|
||||
int hfov_deg = (int)RAD_TO_DEG (camera->Get_Horizontal_FOV ());
|
||||
int vfov_deg = (int)RAD_TO_DEG (camera->Get_Vertical_FOV ());
|
||||
::SetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT, hfov_deg);
|
||||
::SetDlgItemFloat (m_hWnd, IDC_VFOV_EDIT, vfov_deg);
|
||||
|
||||
//
|
||||
// Setup the camera lens controls
|
||||
//
|
||||
float vfov = camera->Get_Vertical_FOV ();
|
||||
float lens = ((::atan ((18.0F / 1000.0F)) / vfov) * 2.0F) * 1000.0F;
|
||||
::SetDlgItemFloat (m_hWnd, IDC_LENS_EDIT, lens);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
CameraSettingsDialogClass::OnNotify
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
LRESULT *pResult
|
||||
)
|
||||
{
|
||||
//
|
||||
// Update the spinner control if necessary
|
||||
//
|
||||
NMHDR *header = (NMHDR *)lParam;
|
||||
if ((header != NULL) && (header->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN updown_info = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (header->hwndFrom, updown_info->iDelta);
|
||||
|
||||
//
|
||||
// Update the FOV settings (they are dependent on each other)
|
||||
//
|
||||
if (updown_info->hdr.idFrom == IDC_LENS_SPIN) {
|
||||
Update_FOV ();
|
||||
} else if (updown_info->hdr.idFrom == IDC_HFOV_SPIN) {
|
||||
Update_Camera_Lens ();
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CDialog::OnNotify (wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Camera_Lens
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CameraSettingsDialogClass::Update_Camera_Lens (void)
|
||||
{
|
||||
//
|
||||
// Get the current vertical FOV settings
|
||||
//
|
||||
float hfov = ::GetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT);
|
||||
|
||||
//
|
||||
// Convert the vertical FOV to a camera lens setting
|
||||
//
|
||||
if (hfov > 0) {
|
||||
const float constant = (18.0F / 1000.0F);
|
||||
float lens = (constant / (::tan (DEG_TO_RAD (hfov) / 2))) * 1000.0F;
|
||||
::SetDlgItemFloat (m_hWnd, IDC_LENS_EDIT, lens);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_FOV
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CameraSettingsDialogClass::Update_FOV (void)
|
||||
{
|
||||
//
|
||||
// Get the current camera lens setting
|
||||
//
|
||||
float lens = (::GetDlgItemFloat (m_hWnd, IDC_LENS_EDIT) / 1000.0F);
|
||||
|
||||
//
|
||||
// Convert the camera lens to a FOV
|
||||
//
|
||||
if (lens > 0) {
|
||||
const float constant = (18.0F / 1000.0F);
|
||||
float hfov = (::atan (constant / lens) * 2.0F);
|
||||
float vfov = (3 * hfov / 4);
|
||||
|
||||
//
|
||||
// Pass the new FOV settings onto the dialog
|
||||
//
|
||||
::SetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT, RAD_TO_DEG (hfov));
|
||||
::SetDlgItemFloat (m_hWnd, IDC_VFOV_EDIT, RAD_TO_DEG (vfov));
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_FOV
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
CameraSettingsDialogClass::OnCommand
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
static bool updating = false;
|
||||
if (updating == false) {
|
||||
|
||||
//
|
||||
// Update the FOV settings if necessary
|
||||
//
|
||||
if ( LOWORD (wParam) == IDC_HFOV_EDIT &&
|
||||
HIWORD (wParam) == EN_UPDATE)
|
||||
{
|
||||
updating = true;
|
||||
Update_Camera_Lens ();
|
||||
updating = false;
|
||||
} else if ( LOWORD (wParam) == IDC_LENS_EDIT &&
|
||||
HIWORD (wParam) == EN_UPDATE)
|
||||
{
|
||||
updating = true;
|
||||
Update_FOV ();
|
||||
updating = false;
|
||||
}
|
||||
}
|
||||
|
||||
return CDialog::OnCommand(wParam, lParam);
|
||||
}
|
||||
82
Code/Tools/W3DView/CameraSettingsDialog.h
Normal file
82
Code/Tools/W3DView/CameraSettingsDialog.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
** 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_CAMERASETTINGSDIALOG_H__7E43F424_8191_11D3_A064_00104B791122__INCLUDED_)
|
||||
#define AFX_CAMERASETTINGSDIALOG_H__7E43F424_8191_11D3_A064_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// CameraSettingsDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CameraSettingsDialogClass dialog
|
||||
|
||||
class CameraSettingsDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CameraSettingsDialogClass(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CameraSettingsDialogClass)
|
||||
enum { IDD = IDD_CAMERA_SETTINGS };
|
||||
CSpinButtonCtrl m_LensSpin;
|
||||
CSpinButtonCtrl m_FarClipSpin;
|
||||
CSpinButtonCtrl m_VFOVSpin;
|
||||
CSpinButtonCtrl m_NearClipSpin;
|
||||
CSpinButtonCtrl m_HFOVSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CameraSettingsDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CameraSettingsDialogClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnFovCheck();
|
||||
afx_msg void OnClipPlaneCheck();
|
||||
afx_msg void OnReset();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
protected:
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Protected methods
|
||||
///////////////////////////////////////////////////////////////////
|
||||
void Update_Camera_Lens (void);
|
||||
void Update_FOV (void);
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_CAMERASETTINGSDIALOG_H__7E43F424_8191_11D3_A064_00104B791122__INCLUDED_)
|
||||
1929
Code/Tools/W3DView/ColorBar.cpp
Normal file
1929
Code/Tools/W3DView/ColorBar.cpp
Normal file
File diff suppressed because it is too large
Load Diff
252
Code/Tools/W3DView/ColorBar.h
Normal file
252
Code/Tools/W3DView/ColorBar.h
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
** 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_COLORBAR_H__D1243F40_D4D2_11D2_8DDF_00104B6FD9E3__INCLUDED_)
|
||||
#define AFX_COLORBAR_H__D1243F40_D4D2_11D2_8DDF_00104B6FD9E3__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// ColorBar.h : header file
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
const int MAX_COLOR_POINTS = 15;
|
||||
|
||||
//
|
||||
// Window styles
|
||||
//
|
||||
#define CBRS_SUNKEN 0x00000001
|
||||
#define CBRS_RAISED 0x00000002
|
||||
#define CBRS_FRAME 0x00000004
|
||||
#define CBRS_FRAME_MASK CBRS_FRAME | CBRS_RAISED | CBRS_SUNKEN
|
||||
#define CBRS_HORZ 0x00000008
|
||||
#define CBRS_VERT 0x00000010
|
||||
#define CBRS_HAS_SEL 0x00000020
|
||||
#define CBRS_SHOW_FRAMES 0x00000040
|
||||
#define CBRS_PAINT_GRAPH 0x00000080
|
||||
|
||||
//
|
||||
// Window messages and notifications
|
||||
//
|
||||
#define CBRN_MOVED_POINT 0x0001
|
||||
#define CBRN_MOVING_POINT 0x0002
|
||||
#define CBRN_DBLCLK_POINT 0x0003
|
||||
#define CBRN_SEL_CHANGED 0x0004
|
||||
#define CBRN_DEL_POINT 0x0005
|
||||
#define CBRN_DELETED_POINT 0x0006
|
||||
#define CBRN_INSERTED_POINT 0x0007
|
||||
#define CBRM_GETCOLOR (WM_USER+101)
|
||||
#define CBRM_SETCOLOR ( WM_USER+102)
|
||||
|
||||
//
|
||||
// Point styles
|
||||
//
|
||||
#define POINT_VISIBLE 0x00000001
|
||||
#define POINT_CAN_MOVE 0x00000002
|
||||
|
||||
//
|
||||
// Return values for WM_NOTIFY
|
||||
//
|
||||
#define STOP_EVENT 0x00000077
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Structures
|
||||
//
|
||||
|
||||
// Structure used to send notifications via WM_NOTIFY
|
||||
typedef struct
|
||||
{
|
||||
NMHDR hdr;
|
||||
int key_index;
|
||||
float red;
|
||||
float green;
|
||||
float blue;
|
||||
float position;
|
||||
} CBR_NMHDR;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorBarClass
|
||||
//
|
||||
class ColorBarClass : public CWnd
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
ColorBarClass();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(ColorBarClass)
|
||||
public:
|
||||
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~ColorBarClass();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(ColorBarClass)
|
||||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||||
afx_msg void OnSize(UINT nType, int cx, int cy);
|
||||
afx_msg void OnPaint();
|
||||
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
|
||||
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
|
||||
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
|
||||
afx_msg void OnKillFocus(CWnd* pNewWnd);
|
||||
afx_msg void OnSetFocus(CWnd* pOldWnd);
|
||||
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
friend LRESULT WINAPI fnColorBarProc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
bool Insert_Point (int index, float position, float red, float green, float blue, DWORD flags = POINT_VISIBLE | POINT_CAN_MOVE);
|
||||
bool Insert_Point (CPoint point, DWORD flags = POINT_VISIBLE | POINT_CAN_MOVE);
|
||||
bool Modify_Point (int index, float position, float red, float green, float blue, DWORD flags = POINT_VISIBLE | POINT_CAN_MOVE);
|
||||
bool Set_User_Data (int index, DWORD data);
|
||||
DWORD Get_User_Data (int index);
|
||||
bool Set_Graph_Percent (int index, float percent);
|
||||
float Get_Graph_Percent (int index);
|
||||
bool Delete_Point (int index);
|
||||
void Clear_Points (void);
|
||||
|
||||
int Get_Point_Count (void) const { return m_iColorPoints; }
|
||||
bool Get_Point (int index, float *position, float *red, float *green, float *blue);
|
||||
|
||||
int Marker_From_Point (CPoint point);
|
||||
void Set_Selection_Pos (float pos);
|
||||
float Get_Selection_Pos (void) const { return m_SelectionPos; }
|
||||
void Get_Color (float position, float *red, float *green, float *blue);
|
||||
|
||||
void Get_Range (float &min, float &max) const { min = m_MinPos; max = m_MaxPos; }
|
||||
void Set_Range (float min, float max);
|
||||
|
||||
void Set_Redraw (bool redraw = true);
|
||||
LRESULT Send_Notification (int code, int key);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Static members
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static ColorBarClass *Get_Color_Bar (HWND window_handle) { return (ColorBarClass *)::GetProp (window_handle, "CLASSPOINTER"); }
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected data types
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
float PosPercent;
|
||||
int StartPos;
|
||||
int EndPos;
|
||||
|
||||
float StartGraphPercent;
|
||||
float GraphPercentInc;
|
||||
|
||||
float StartRed;
|
||||
float StartGreen;
|
||||
float StartBlue;
|
||||
|
||||
float RedInc;
|
||||
float GreenInc;
|
||||
float BlueInc;
|
||||
|
||||
DWORD user_data;
|
||||
int flags;
|
||||
|
||||
} COLOR_POINT;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Paint_DIB (void);
|
||||
void Create_Bitmap (void);
|
||||
void Free_Bitmap (void);
|
||||
void Free_Marker_Bitmap (void);
|
||||
void Paint_Bar_Horz (int x_pos, int y_pos, int width, int height, UCHAR *pbits);
|
||||
void Paint_Bar_Vert (int x_pos, int y_pos, int width, int height, UCHAR *pbits);
|
||||
void Update_Point_Info (void);
|
||||
void Load_Key_Frame_BMP (void);
|
||||
void Paint_Key_Frame (int x_pos, int y_pos);
|
||||
void Paint_Screen (HDC hwnd_dc);
|
||||
void Get_Selection_Rectangle (CRect &rect);
|
||||
void Move_Selection (CPoint point, bool send_notify = true);
|
||||
void Move_Selection (float new_pos, bool send_notify = true);
|
||||
void Repaint (void);
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
HBITMAP m_hBitmap;
|
||||
HBITMAP m_KeyFrameDIB;
|
||||
HDC m_hMemDC;
|
||||
UCHAR * m_pBits;
|
||||
UCHAR * m_pKeyFrameBits;
|
||||
int m_iColorWidth;
|
||||
int m_iColorHeight;
|
||||
int m_iBMPWidth;
|
||||
int m_iBMPHeight;
|
||||
int m_iMarkerWidth;
|
||||
int m_iMarkerHeight;
|
||||
int m_iScanlineSize;
|
||||
int m_iColorPoints;
|
||||
float m_MinPos;
|
||||
float m_MaxPos;
|
||||
COLOR_POINT m_ColorPoints[MAX_COLOR_POINTS];
|
||||
CRect m_ColorArea;
|
||||
int m_iCurrentKey;
|
||||
bool m_bMoving;
|
||||
bool m_bMoved;
|
||||
bool m_bRedraw;
|
||||
float m_SelectionPos;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_COLORBAR_H__D1243F40_D4D2_11D2_8DDF_00104B6FD9E3__INCLUDED_)
|
||||
985
Code/Tools/W3DView/ColorPicker.cpp
Normal file
985
Code/Tools/W3DView/ColorPicker.cpp
Normal file
@@ -0,0 +1,985 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorPicker.cpp : implementation file
|
||||
//
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "colorpicker.h"
|
||||
#include "colorpickerdialogclass.h"
|
||||
#include <math.h>
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//extern HINSTANCE _hinstance;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorPickerClass
|
||||
//
|
||||
ColorPickerClass::ColorPickerClass (void)
|
||||
: m_hBitmap (NULL),
|
||||
m_iWidth (0),
|
||||
m_iHeight (0),
|
||||
m_CurrentPoint (0, 0),
|
||||
m_CurrentColor (0),
|
||||
m_bSelecting (false),
|
||||
m_pBits (NULL),
|
||||
m_hMemDC (NULL),
|
||||
m_CurrentHue (0),
|
||||
CWnd ()
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~ColorPickerClass
|
||||
//
|
||||
ColorPickerClass::~ColorPickerClass (void)
|
||||
{
|
||||
if (m_hMemDC != NULL) {
|
||||
::DeleteObject (m_hMemDC);
|
||||
m_hMemDC = NULL;
|
||||
}
|
||||
|
||||
Free_Bitmap ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(ColorPickerClass, CWnd)
|
||||
//{{AFX_MSG_MAP(ColorPickerClass)
|
||||
ON_WM_PAINT()
|
||||
ON_WM_CREATE()
|
||||
ON_WM_SIZE()
|
||||
ON_WM_ERASEBKGND()
|
||||
ON_WM_LBUTTONDOWN()
|
||||
ON_WM_LBUTTONUP()
|
||||
ON_WM_MOUSEMOVE()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnPaint
|
||||
//
|
||||
void
|
||||
ColorPickerClass::OnPaint (void)
|
||||
{
|
||||
CPaintDC dc (this);
|
||||
|
||||
if (m_hMemDC != NULL) {
|
||||
|
||||
HBITMAP hold_bmp = (HBITMAP)::SelectObject (m_hMemDC, m_hBitmap);
|
||||
|
||||
CRect rect;
|
||||
GetClientRect (&rect);
|
||||
::BitBlt (dc, 0, 0, rect.Width (), rect.Height (), m_hMemDC, 0, 0, SRCCOPY);
|
||||
|
||||
::SelectObject (m_hMemDC, hold_bmp);
|
||||
Paint_Marker ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// RegisterColorPicker
|
||||
//
|
||||
void
|
||||
RegisterColorPicker (HINSTANCE hinst)
|
||||
{
|
||||
// Has the class already been registered?
|
||||
WNDCLASS wndclass = { 0 };
|
||||
if (::GetClassInfo (hinst, "WWCOLORPICKER", &wndclass) == FALSE) {
|
||||
|
||||
wndclass.style = CS_GLOBALCLASS | CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
|
||||
wndclass.lpfnWndProc = fnColorPickerProc;
|
||||
wndclass.hInstance = hinst;
|
||||
wndclass.hbrBackground = (HBRUSH)COLOR_3DFACE + 1;
|
||||
wndclass.hCursor = ::LoadCursor (NULL, IDC_ARROW);
|
||||
wndclass.lpszClassName = "WWCOLORPICKER";
|
||||
|
||||
// Let the windows manager know about this global class
|
||||
::RegisterClass (&wndclass);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// fnColorPickerProc
|
||||
//
|
||||
LRESULT WINAPI
|
||||
fnColorPickerProc
|
||||
(
|
||||
HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam
|
||||
)
|
||||
{
|
||||
//static ColorPickerClass *pwnd = NULL;
|
||||
//static bool bcreated = false;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_CREATE:
|
||||
{
|
||||
LPCREATESTRUCT pcreate_info = (LPCREATESTRUCT)lparam;
|
||||
if (pcreate_info != NULL) {
|
||||
|
||||
// Should we create a new class manager for this window?
|
||||
ColorPickerClass *pwnd = (ColorPickerClass *)pcreate_info->lpCreateParams;
|
||||
BOOL created = FALSE;
|
||||
if (pwnd == NULL) {
|
||||
pwnd = new ColorPickerClass;
|
||||
created = TRUE;
|
||||
}
|
||||
|
||||
// Pull some hacks to get MFC to use the message map
|
||||
pwnd->Attach (hwnd);
|
||||
|
||||
// Let the window know its being created
|
||||
pwnd->OnCreate (pcreate_info);
|
||||
|
||||
WNDPROC *pOldWndProc = pwnd->GetSuperWndProcAddr ();
|
||||
if (pOldWndProc) {
|
||||
WNDPROC pold_proc = (WNDPROC)::SetWindowLong (hwnd, GWL_WNDPROC, (DWORD)::AfxGetAfxWndProc ());
|
||||
ASSERT (pold_proc != NULL);
|
||||
(*pOldWndProc) = pold_proc;
|
||||
}
|
||||
|
||||
// Store some information in the window handle
|
||||
::SetProp (hwnd, "CLASSPOINTER", (HANDLE)pwnd);
|
||||
::SetProp (hwnd, "CREATED", (HANDLE)created);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
/*pwnd->Detach ();
|
||||
|
||||
WNDPROC *pOldWndProc = pwnd->GetSuperWndProcAddr ();
|
||||
if (pOldWndProc) {
|
||||
::SetWindowLong (hwnd, GWL_WNDPROC, (DWORD)(*pOldWndProc));
|
||||
(*pOldWndProc) = NULL;
|
||||
}
|
||||
|
||||
if (bcreated) {
|
||||
delete pwnd;
|
||||
pwnd = NULL;
|
||||
}*/
|
||||
|
||||
// Get the creation information from the window handle
|
||||
ColorPickerClass *pwnd = (ColorPickerClass *)::GetProp (hwnd, "CLASSPOINTER");
|
||||
BOOL created = (BOOL)::GetProp (hwnd, "CREATED");
|
||||
|
||||
if (pwnd != NULL) {
|
||||
pwnd->Detach ();
|
||||
|
||||
WNDPROC *pOldWndProc = pwnd->GetSuperWndProcAddr ();
|
||||
if (pOldWndProc) {
|
||||
::SetWindowLong (hwnd, GWL_WNDPROC, (DWORD)(*pOldWndProc));
|
||||
(*pOldWndProc) = NULL;
|
||||
}
|
||||
|
||||
if (created) {
|
||||
delete pwnd;
|
||||
pwnd = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Allow default processing to occur
|
||||
return ::DefWindowProc (hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCreate
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
ColorPickerClass::OnCreate (LPCREATESTRUCT lpCreateStruct)
|
||||
{
|
||||
if (CWnd::OnCreate(lpCreateStruct) == -1)
|
||||
return -1;
|
||||
|
||||
m_hMemDC = ::CreateCompatibleDC (NULL);
|
||||
Create_Bitmap ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Create
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
ColorPickerClass::Create
|
||||
(
|
||||
LPCTSTR /*lpszClassName*/,
|
||||
LPCTSTR lpszWindowName,
|
||||
DWORD dwStyle,
|
||||
const RECT &rect,
|
||||
CWnd *pparent_wnd,
|
||||
UINT nID,
|
||||
CCreateContext * /*pContext*/
|
||||
)
|
||||
{
|
||||
// Create the window (it will force the message map and everthing)
|
||||
HWND hparent_wnd = (pparent_wnd != NULL) ? pparent_wnd->m_hWnd : NULL;
|
||||
HWND hwnd = ::CreateWindow ("WWCOLORPICKER",
|
||||
lpszWindowName,
|
||||
dwStyle,
|
||||
rect.left,
|
||||
rect.top,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top,
|
||||
hparent_wnd,
|
||||
(HMENU)nID,
|
||||
::AfxGetInstanceHandle (),
|
||||
this);
|
||||
|
||||
// Return the true/false result code
|
||||
return (hwnd != NULL);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Create_Bitmap
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::Create_Bitmap (void)
|
||||
{
|
||||
// Start fresh
|
||||
Free_Bitmap ();
|
||||
|
||||
CRect rect;
|
||||
GetClientRect (&rect);
|
||||
m_iWidth = rect.Width ();
|
||||
m_iHeight = rect.Height ();
|
||||
|
||||
// Set-up the fields of the BITMAPINFOHEADER
|
||||
BITMAPINFOHEADER bitmap_info;
|
||||
bitmap_info.biSize = sizeof (BITMAPINFOHEADER);
|
||||
bitmap_info.biWidth = m_iWidth;
|
||||
bitmap_info.biHeight = -m_iHeight; // Top-down DIB uses negative height
|
||||
bitmap_info.biPlanes = 1;
|
||||
bitmap_info.biBitCount = 24;
|
||||
bitmap_info.biCompression = BI_RGB;
|
||||
bitmap_info.biSizeImage = ((m_iWidth * m_iHeight) * 3);
|
||||
bitmap_info.biXPelsPerMeter = 0;
|
||||
bitmap_info.biYPelsPerMeter = 0;
|
||||
bitmap_info.biClrUsed = 0;
|
||||
bitmap_info.biClrImportant = 0;
|
||||
|
||||
// Get a temporary screen DC
|
||||
HDC hscreen_dc = ::GetDC (NULL);
|
||||
|
||||
// Create a bitmap that we can access the bits directly of
|
||||
m_hBitmap = ::CreateDIBSection (hscreen_dc,
|
||||
(const BITMAPINFO *)&bitmap_info,
|
||||
DIB_RGB_COLORS,
|
||||
(void **)&m_pBits,
|
||||
NULL,
|
||||
0L);
|
||||
|
||||
// Release our temporary screen DC
|
||||
::ReleaseDC (NULL, hscreen_dc);
|
||||
|
||||
// Paint the color range into this bitmap
|
||||
Paint_DIB (m_iWidth, m_iHeight, m_pBits);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Fill_Rect
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::Fill_Rect
|
||||
(
|
||||
UCHAR *pbits,
|
||||
const RECT &rect,
|
||||
COLORREF color,
|
||||
int scanline_size
|
||||
)
|
||||
{
|
||||
UCHAR red = GetRValue (color);
|
||||
UCHAR green = GetRValue (color);
|
||||
UCHAR blue = GetRValue (color);
|
||||
|
||||
for (int irow = rect.top; irow < rect.bottom; irow ++) {
|
||||
int index = irow * scanline_size;
|
||||
index += (rect.left * 3);
|
||||
|
||||
for (int col = rect.left; col < rect.right; col ++) {
|
||||
pbits[index++] = blue;
|
||||
pbits[index++] = green;
|
||||
pbits[index++] = red;
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Color_From_Point
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
COLORREF
|
||||
ColorPickerClass::Color_From_Point
|
||||
(
|
||||
int x,
|
||||
int y
|
||||
)
|
||||
{
|
||||
COLORREF color = RGB (0,0,0);
|
||||
|
||||
// x,y location inside boundaries?
|
||||
if ((x >= 0) && (x < m_iWidth) &&
|
||||
(y >= 0) && (y < m_iHeight)) {
|
||||
|
||||
// Window's bitmaps are DWORD aligned, so make sure
|
||||
// we take that into account.
|
||||
int alignment_offset = (m_iWidth * 3) % 4;
|
||||
alignment_offset = (alignment_offset != 0) ? (4 - alignment_offset) : 0;
|
||||
int scanline_size = (m_iWidth * 3) + alignment_offset;
|
||||
|
||||
// Read the color value straight from the BMP
|
||||
int index = (scanline_size * y) + (x * 3);
|
||||
int blue = m_pBits[index];
|
||||
int green = m_pBits[index + 1];
|
||||
int red = m_pBits[index + 2];
|
||||
|
||||
// Turn the individual compenents into a color
|
||||
color = RGB (red, green, blue);
|
||||
|
||||
RECT rect;
|
||||
Calc_Display_Rect (rect);
|
||||
int width = rect.right-rect.left;
|
||||
m_CurrentHue = ((float)x) / ((float)width);
|
||||
}
|
||||
|
||||
// Return the color
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Polar_To_Rect
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
Polar_To_Rect (float radius, float angle, float &x, float &y)
|
||||
{
|
||||
x = radius * float(cos(angle));
|
||||
y = radius * float(sin(angle));
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Rect_To_Polar
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
Rect_To_Polar (float x, float y, float &radius, float &angle)
|
||||
{
|
||||
if (x == 0 && y == 0) {
|
||||
radius = 0;
|
||||
angle = 0;
|
||||
} else {
|
||||
radius = (float)::sqrt ((x * x) + (y * y));
|
||||
angle = (float)::atan2 (y, x);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// RGB_to_Hue
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
RGB_to_Hue (int red_val, int green_val, int blue_val, float &hue, float &value)
|
||||
{
|
||||
float red_radius = (float)red_val;
|
||||
float green_radius = (float)green_val;
|
||||
float blue_radius = (float)blue_val;
|
||||
|
||||
float red_angle = 0;
|
||||
float green_angle = (3.1415926535F * 2.0F) / 3.0F;
|
||||
float blue_angle = (3.1415926535F * 4.0F) / 3.0F;
|
||||
|
||||
struct Color2D
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
Color2D red = { 0 };
|
||||
Color2D green = { 0 };
|
||||
Color2D blue = { 0 };
|
||||
Color2D result = { 0 };
|
||||
|
||||
::Polar_To_Rect (red_radius, red_angle, red.x, red.y);
|
||||
::Polar_To_Rect (green_radius, green_angle, green.x, green.y);
|
||||
::Polar_To_Rect (blue_radius, blue_angle, blue.x, blue.y);
|
||||
|
||||
result.x = red.x + green.x + blue.x;
|
||||
result.y = red.y + green.y + blue.y;
|
||||
|
||||
float hue_angle = 0;
|
||||
float hue_radius = 0;
|
||||
::Rect_To_Polar (result.x, result.y, hue_radius, hue_angle);
|
||||
|
||||
hue = hue_angle / (3.14159265359F * 2.0F);
|
||||
if (hue < 0) {
|
||||
hue += 1;
|
||||
} else if (hue > 1) {
|
||||
hue -= 1;
|
||||
}
|
||||
|
||||
value = (float)::fabs (hue_radius / 255);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Point_From_Color
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
CPoint
|
||||
ColorPickerClass::Point_From_Color (COLORREF color)
|
||||
{
|
||||
// Window's bitmaps are DWORD aligned, so make sure
|
||||
// we take that into account.
|
||||
int alignment_offset = (m_iWidth * 3) % 4;
|
||||
alignment_offset = (alignment_offset != 0) ? (4 - alignment_offset) : 0;
|
||||
int scanline_size = (m_iWidth * 3) + alignment_offset;
|
||||
|
||||
int red = GetRValue (color);
|
||||
int green = GetGValue (color);
|
||||
int blue = GetBValue (color);
|
||||
|
||||
float hue = 0;
|
||||
float value = 0;
|
||||
RGB_to_Hue (red, green, blue, hue, value);
|
||||
|
||||
RECT rect;
|
||||
Calc_Display_Rect (rect);
|
||||
int width = rect.right-rect.left;
|
||||
int height = rect.bottom-rect.top;
|
||||
|
||||
float whiteness = (float)min (min (red, green), blue);
|
||||
float percent = whiteness / 255;
|
||||
float darkness = 0;
|
||||
|
||||
//
|
||||
// Determine what the 'darkness' of the hue should be
|
||||
//
|
||||
if (percent != 1) {
|
||||
float start_red = (red - whiteness) / (1 - percent);
|
||||
float start_green = (green - whiteness) / (1 - percent);
|
||||
float start_blue = (blue - whiteness) / (1 - percent);
|
||||
darkness = max (max (start_red, start_green), start_blue);
|
||||
}
|
||||
|
||||
int x = int(width * hue);
|
||||
int y = ((255 - (int)darkness) * height) / 255;
|
||||
|
||||
// Return the point
|
||||
return CPoint (x, y);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Paint_DIB
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::Paint_DIB
|
||||
(
|
||||
int width,
|
||||
int height,
|
||||
UCHAR *pbits
|
||||
)
|
||||
{
|
||||
// Window's bitmaps are DWORD aligned, so make sure
|
||||
// we take that into account.
|
||||
int alignment_offset = (width * 3) % 4;
|
||||
alignment_offset = (alignment_offset != 0) ? (4 - alignment_offset) : 0;
|
||||
int scanline_size = (width * 3) + alignment_offset;
|
||||
|
||||
//
|
||||
// Paint the border (if any)
|
||||
//
|
||||
CRect rect (0, 0, width, height);
|
||||
LONG lstyle = ::GetWindowLong (m_hWnd, GWL_STYLE);
|
||||
if (lstyle & CPS_SUNKEN) {
|
||||
::Draw_Sunken_Rect (pbits, rect, scanline_size);
|
||||
rect.DeflateRect (1, 1);
|
||||
} else if (lstyle & CPS_RAISED) {
|
||||
::Draw_Raised_Rect (pbits, rect, scanline_size);
|
||||
rect.DeflateRect (1, 1);
|
||||
} else if (lstyle & WS_BORDER) {
|
||||
::Frame_Rect (pbits, rect, RGB (255, 255, 255), scanline_size);
|
||||
rect.DeflateRect (1, 1);
|
||||
}
|
||||
|
||||
// Recalc the width and height (it could of changed)
|
||||
width = rect.Width ();
|
||||
height = rect.Height ();
|
||||
|
||||
// Build an array of column indicies where we will switch color
|
||||
// components...
|
||||
int col_remainder = (width % 6);
|
||||
int channel_switch_cols[6];
|
||||
for (int channel = 0; channel < 6; channel ++) {
|
||||
|
||||
// Each column has at least X/6 pixels
|
||||
channel_switch_cols[channel] = width / 6;
|
||||
|
||||
// Do we need to add a remainder to this col?
|
||||
// (Occurs when the width isn't evenly divisible by 6)
|
||||
if (col_remainder > 0) {
|
||||
channel_switch_cols[channel] += 1;
|
||||
col_remainder --;
|
||||
}
|
||||
|
||||
// Add the previous column's switching index
|
||||
if (channel > 0) {
|
||||
channel_switch_cols[channel] += channel_switch_cols[channel - 1];
|
||||
}
|
||||
}
|
||||
|
||||
// Start with max red
|
||||
float red = 255.0F;
|
||||
float green = 0;
|
||||
float blue = 0;
|
||||
|
||||
// Calculate some starting channel variables
|
||||
int curr_channel = 0;
|
||||
float curr_inc = (255.0F / ((float)channel_switch_cols[0]));
|
||||
float *pcurr_component = &green;
|
||||
|
||||
//
|
||||
// Paint the image
|
||||
//
|
||||
for (int icol = rect.left; icol < rect.right; icol ++) {
|
||||
|
||||
// Determine how much to 'darken' the current hue by for each row (goes to black)
|
||||
float red_dec = -((float)(red) / (float)(height-1));
|
||||
float green_dec = -((float)(green) / (float)(height-1));
|
||||
float blue_dec = -((float)(blue) / (float)(height-1));
|
||||
|
||||
// Start with the normal hue color
|
||||
float curr_red = red;
|
||||
float curr_green = green;
|
||||
float curr_blue = blue;
|
||||
|
||||
// Paint all pixels in this row
|
||||
int bitmap_index = (icol * 3) + (rect.left * scanline_size);
|
||||
for (int irow = rect.top; irow < rect.bottom; irow ++) {
|
||||
|
||||
// Put these values into the bitmap
|
||||
pbits[bitmap_index] = UCHAR(((int)curr_blue) & 0xFF);
|
||||
pbits[bitmap_index + 1] = UCHAR(((int)curr_green) & 0xFF);
|
||||
pbits[bitmap_index + 2] = UCHAR(((int)curr_red) & 0xFF);
|
||||
|
||||
// Determine the current red, green, and blue values
|
||||
curr_red = curr_red + red_dec;
|
||||
curr_green = curr_green + green_dec;
|
||||
curr_blue = curr_blue + blue_dec;
|
||||
|
||||
// Increment our offset into the bitmap
|
||||
bitmap_index += scanline_size;
|
||||
}
|
||||
|
||||
// Is it time to switch to a new color channel?
|
||||
if ((icol - rect.left) == channel_switch_cols[curr_channel]) {
|
||||
|
||||
// Recompute values for the new channel
|
||||
curr_channel ++;
|
||||
curr_inc = (255.0F / ((float)(channel_switch_cols[curr_channel] - channel_switch_cols[curr_channel-1])));
|
||||
|
||||
// Which channel are we painting?
|
||||
if (curr_channel == 1) {
|
||||
pcurr_component = &red;
|
||||
curr_inc = -curr_inc;
|
||||
} else if (curr_channel == 2) {
|
||||
pcurr_component = &blue;
|
||||
} else if (curr_channel == 3) {
|
||||
pcurr_component = &green;
|
||||
curr_inc = -curr_inc;
|
||||
} else if (curr_channel == 4) {
|
||||
pcurr_component = &red;
|
||||
} else if (curr_channel == 5) {
|
||||
pcurr_component = &blue;
|
||||
curr_inc = -curr_inc;
|
||||
}
|
||||
}
|
||||
|
||||
// Increment the current color component
|
||||
(*pcurr_component) = (*pcurr_component) + curr_inc;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Free_Bitmap
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::Free_Bitmap (void)
|
||||
{
|
||||
if (m_hBitmap != NULL) {
|
||||
::DeleteObject (m_hBitmap);
|
||||
m_hBitmap = NULL;
|
||||
m_pBits = NULL;
|
||||
}
|
||||
|
||||
m_iWidth = 0;
|
||||
m_iHeight = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSize
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::OnSize
|
||||
(
|
||||
UINT nType,
|
||||
int cx,
|
||||
int cy
|
||||
)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CWnd::OnSize (nType, cx, cy);
|
||||
|
||||
// Recreate the BMP to reflect the new window size
|
||||
Create_Bitmap ();
|
||||
|
||||
// Determine the new point based on the current color
|
||||
//m_CurrentColor = RGB (128, 222, 199);
|
||||
//m_CurrentPoint = Point_From_Color (m_CurrentColor);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnEraseBkgnd
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
ColorPickerClass::OnEraseBkgnd (CDC * /*pDC*/)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnLButtonDown
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::OnLButtonDown
|
||||
(
|
||||
UINT nFlags,
|
||||
CPoint point
|
||||
)
|
||||
{
|
||||
SetCapture ();
|
||||
m_bSelecting = true;
|
||||
|
||||
RECT rect;
|
||||
Calc_Display_Rect (rect);
|
||||
ClientToScreen (&rect);
|
||||
::ClipCursor (&rect);
|
||||
|
||||
Erase_Marker ();
|
||||
|
||||
m_CurrentPoint = point;
|
||||
m_CurrentColor = Color_From_Point (point.x, point.y);
|
||||
|
||||
//
|
||||
// Notify the parent window that the user double-clicked
|
||||
// one of the keyframes
|
||||
//
|
||||
LONG id = ::GetWindowLong (m_hWnd, GWL_ID);
|
||||
CP_NMHDR notify_hdr = { 0 };
|
||||
notify_hdr.hdr.hwndFrom = m_hWnd;
|
||||
notify_hdr.hdr.idFrom = id;
|
||||
notify_hdr.hdr.code = CPN_COLORCHANGE;
|
||||
notify_hdr.red = GetRValue (m_CurrentColor);
|
||||
notify_hdr.green = GetGValue (m_CurrentColor);
|
||||
notify_hdr.blue = GetBValue (m_CurrentColor);
|
||||
notify_hdr.hue = m_CurrentHue;
|
||||
::SendMessage (::GetParent (m_hWnd),
|
||||
WM_NOTIFY,
|
||||
id,
|
||||
(LPARAM)¬ify_hdr);
|
||||
|
||||
Paint_Marker ();
|
||||
|
||||
// Allow the base class to process this message
|
||||
CWnd::OnLButtonDown (nFlags, point);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnLButtonUp
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::OnLButtonUp
|
||||
(
|
||||
UINT nFlags,
|
||||
CPoint point
|
||||
)
|
||||
{
|
||||
if (m_bSelecting) {
|
||||
::ClipCursor (NULL);
|
||||
ReleaseCapture ();
|
||||
m_bSelecting = false;
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
CWnd::OnLButtonUp (nFlags, point);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnMouseMove
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::OnMouseMove
|
||||
(
|
||||
UINT nFlags,
|
||||
CPoint point
|
||||
)
|
||||
{
|
||||
if (m_bSelecting) {
|
||||
Erase_Marker ();
|
||||
|
||||
m_CurrentPoint = point;
|
||||
m_CurrentColor = Color_From_Point (point.x, point.y);
|
||||
|
||||
//
|
||||
// Notify the parent window that the user double-clicked
|
||||
// one of the keyframes
|
||||
//
|
||||
LONG id = ::GetWindowLong (m_hWnd, GWL_ID);
|
||||
CP_NMHDR notify_hdr = { 0 };
|
||||
notify_hdr.hdr.hwndFrom = m_hWnd;
|
||||
notify_hdr.hdr.idFrom = id;
|
||||
notify_hdr.hdr.code = CPN_COLORCHANGE;
|
||||
notify_hdr.red = GetRValue (m_CurrentColor);
|
||||
notify_hdr.green = GetGValue (m_CurrentColor);
|
||||
notify_hdr.blue = GetBValue (m_CurrentColor);
|
||||
notify_hdr.hue = m_CurrentHue;
|
||||
::SendMessage (::GetParent (m_hWnd),
|
||||
WM_NOTIFY,
|
||||
id,
|
||||
(LPARAM)¬ify_hdr);
|
||||
|
||||
Paint_Marker ();
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
CWnd::OnMouseMove (nFlags, point);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calc_Display_Rect
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::Calc_Display_Rect (RECT &rect)
|
||||
{
|
||||
GetClientRect (&rect);
|
||||
|
||||
LONG lstyle = ::GetWindowLong (m_hWnd, GWL_STYLE);
|
||||
if ((lstyle & CPS_SUNKEN) || (lstyle & CPS_RAISED) || (lstyle & WS_BORDER)) {
|
||||
rect.left += 1;
|
||||
rect.right -= 1;
|
||||
rect.top += 1;
|
||||
rect.bottom -= 1;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Erase_Marker
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::Erase_Marker (void)
|
||||
{
|
||||
HDC hdc = ::GetDC (m_hWnd);
|
||||
if (m_hMemDC != NULL) {
|
||||
|
||||
HBITMAP hold_bmp = (HBITMAP)::SelectObject (m_hMemDC, m_hBitmap);
|
||||
|
||||
CRect rect;
|
||||
GetClientRect (&rect);
|
||||
::BitBlt (hdc,
|
||||
m_CurrentPoint.x - 5,
|
||||
m_CurrentPoint.y - 5,
|
||||
11,
|
||||
11,
|
||||
m_hMemDC,
|
||||
m_CurrentPoint.x - 5,
|
||||
m_CurrentPoint.y - 5,
|
||||
SRCCOPY);
|
||||
|
||||
::SelectObject (m_hMemDC, hold_bmp);
|
||||
}
|
||||
|
||||
::ReleaseDC (m_hWnd, hdc);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Paint_Marker
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::Paint_Marker (void)
|
||||
{
|
||||
HDC hdc = ::GetDC (m_hWnd);
|
||||
if (m_hMemDC != NULL) {
|
||||
|
||||
HBITMAP hmarker_bmp = ::LoadBitmap (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDB_MARKER));
|
||||
HBITMAP hold_bmp = (HBITMAP)::SelectObject (m_hMemDC, hmarker_bmp);
|
||||
|
||||
CRect rect;
|
||||
GetClientRect (&rect);
|
||||
::BitBlt (hdc,
|
||||
m_CurrentPoint.x - 5,
|
||||
m_CurrentPoint.y - 5,
|
||||
11,
|
||||
11,
|
||||
m_hMemDC,
|
||||
0,
|
||||
0,
|
||||
SRCINVERT);
|
||||
|
||||
::SelectObject (m_hMemDC, hold_bmp);
|
||||
::DeleteObject (hmarker_bmp);
|
||||
}
|
||||
|
||||
::ReleaseDC (m_hWnd, hdc);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Select_Color
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::Select_Color (int red, int green, int blue)
|
||||
{
|
||||
m_CurrentColor = RGB (red, green, blue);
|
||||
m_CurrentPoint = Point_From_Color (m_CurrentColor);
|
||||
m_CurrentColor = Color_From_Point (m_CurrentPoint.x, m_CurrentPoint.y);
|
||||
|
||||
// Refresh the window
|
||||
InvalidateRect (NULL, FALSE);
|
||||
UpdateWindow ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get_Current_Color
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerClass::Get_Current_Color (int *red, int *green, int *blue)
|
||||
{
|
||||
(*red) = GetRValue (m_CurrentColor);
|
||||
(*green) = GetGValue (m_CurrentColor);
|
||||
(*blue) = GetBValue (m_CurrentColor);
|
||||
return ;
|
||||
}
|
||||
161
Code/Tools/W3DView/ColorPicker.h
Normal file
161
Code/Tools/W3DView/ColorPicker.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
** 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_COLORPICKER_H__C943A7EC_CAA3_11D2_8DDF_00104B6FD9E3__INCLUDED_)
|
||||
#define AFX_COLORPICKER_H__C943A7EC_CAA3_11D2_8DDF_00104B6FD9E3__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// ColorPicker.h : header file
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
|
||||
//
|
||||
// Window styles
|
||||
//
|
||||
#define CPS_SUNKEN 0x00000001
|
||||
#define CPS_RAISED 0x00000002
|
||||
|
||||
//
|
||||
// Window messages and notifications
|
||||
//
|
||||
#define CPN_COLORCHANGE 0x0001
|
||||
#define CPM_GETCOLOR (WM_USER+101)
|
||||
#define CPM_SETCOLOR (WM_USER+102)
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Structures
|
||||
//
|
||||
|
||||
// Structure used to send notifications via WM_NOTIFY
|
||||
typedef struct
|
||||
{
|
||||
NMHDR hdr;
|
||||
float red;
|
||||
float green;
|
||||
float blue;
|
||||
float hue;
|
||||
} CP_NMHDR;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorPickerClass window
|
||||
//
|
||||
class ColorPickerClass : public CWnd
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
ColorPickerClass();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(ColorPickerClass)
|
||||
public:
|
||||
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~ColorPickerClass();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(ColorPickerClass)
|
||||
afx_msg void OnPaint();
|
||||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||||
afx_msg void OnSize(UINT nType, int cx, int cy);
|
||||
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
||||
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
|
||||
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
|
||||
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
friend LRESULT WINAPI fnColorPickerProc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
public:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Public members
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Select_Color (int red, int green, int blue);
|
||||
void Get_Current_Color (int *red, int *green, int *blue);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Static members
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static ColorPickerClass *Get_Color_Picker (HWND window_handle) { return (ColorPickerClass *)::GetProp (window_handle, "CLASSPOINTER"); }
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
void Paint_DIB (int width, int height, UCHAR *pbits);
|
||||
void Create_Bitmap (void);
|
||||
void Free_Bitmap (void);
|
||||
void Fill_Rect (UCHAR *pbits, const RECT &rect, COLORREF color, int scanline_size);
|
||||
void Frame_Rect (UCHAR *pbits, const RECT &rect, COLORREF color, int scanline_size);
|
||||
void Draw_Horz_Line (UCHAR *pbits, int x, int y, int len, COLORREF color, int scanline_size);
|
||||
void Draw_Vert_Line (UCHAR *pbits, int x, int y, int len, COLORREF color, int scanline_size);
|
||||
COLORREF Color_From_Point (int x, int y);
|
||||
CPoint Point_From_Color (COLORREF color);
|
||||
void Paint_Marker (void);
|
||||
void Erase_Marker (void);
|
||||
void Calc_Display_Rect (RECT &rect);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
HBITMAP m_hBitmap;
|
||||
HDC m_hMemDC;
|
||||
UCHAR * m_pBits;
|
||||
int m_iWidth;
|
||||
int m_iHeight;
|
||||
CPoint m_CurrentPoint;
|
||||
COLORREF m_CurrentColor;
|
||||
bool m_bSelecting;
|
||||
float m_CurrentHue;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_COLORPICKER_H__C943A7EC_CAA3_11D2_8DDF_00104B6FD9E3__INCLUDED_)
|
||||
653
Code/Tools/W3DView/ColorPickerDialogClass.cpp
Normal file
653
Code/Tools/W3DView/ColorPickerDialogClass.cpp
Normal file
@@ -0,0 +1,653 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// ColorPickerDialogClass.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "colorpickerdialogclass.h"
|
||||
#include "colorbar.h"
|
||||
#include "colorpicker.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
//extern HINSTANCE _hinstance;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local constants
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
const DWORD UPDATE_COLOR_BARS = 0x00000001;
|
||||
const DWORD UPDATE_WHITENESS = 0x00000002;
|
||||
const DWORD UPDATE_HUE_PICKER = 0x00000004;
|
||||
|
||||
/*class MyManageStateClass
|
||||
{
|
||||
public:
|
||||
MyManageStateClass (void)
|
||||
{
|
||||
m_hResHandle = ::AfxGetResourceHandle ();
|
||||
::AfxSetResourceHandle (_hinstance);
|
||||
}
|
||||
|
||||
~MyManageStateClass (void) { ::AfxSetResourceHandle (m_hResHandle); }
|
||||
|
||||
private:
|
||||
HINSTANCE m_hResHandle;
|
||||
};*/
|
||||
|
||||
//#define MY_MANAGE_STATE() MyManageStateClass _xmystate;
|
||||
|
||||
HWND
|
||||
Create_Color_Picker_Form (HWND parent, int red, int green, int blue)
|
||||
{
|
||||
//MY_MANAGE_STATE ()
|
||||
|
||||
CWnd *parent_wnd = CWnd::FromHandle (parent);
|
||||
|
||||
ColorPickerDialogClass *dialog = new ColorPickerDialogClass (red, green, blue, parent_wnd, IDD_COLOR_FORM);
|
||||
dialog->Create_Form (parent_wnd);
|
||||
|
||||
//HINSTANCE old_handle = ::AfxGetResourceHandle ();
|
||||
//::AfxSetResourceHandle (_hinstance);
|
||||
return dialog->m_hWnd;
|
||||
}
|
||||
|
||||
BOOL
|
||||
Get_Form_Color (HWND form_wnd, int *red, int *green, int *blue)
|
||||
{
|
||||
//MY_MANAGE_STATE ()
|
||||
|
||||
BOOL retval = FALSE;
|
||||
|
||||
ColorPickerDialogClass *dialog = (ColorPickerDialogClass *)::GetProp (form_wnd, "COLORPICKERDLGCLASS");
|
||||
if (dialog != NULL) {
|
||||
(*red) = dialog->Get_Red ();
|
||||
(*green) = dialog->Get_Green ();
|
||||
(*blue) = dialog->Get_Blue ();
|
||||
retval = TRUE;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
Set_Form_Color (HWND form_wnd, int red, int green, int blue)
|
||||
{
|
||||
//MY_MANAGE_STATE ()
|
||||
|
||||
BOOL retval = FALSE;
|
||||
|
||||
ColorPickerDialogClass *dialog = (ColorPickerDialogClass *)::GetProp (form_wnd, "COLORPICKERDLGCLASS");
|
||||
if (dialog != NULL) {
|
||||
dialog->Set_Color (red, green, blue);
|
||||
retval = TRUE;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
Set_Form_Original_Color (HWND form_wnd, int red, int green, int blue)
|
||||
{
|
||||
//MY_MANAGE_STATE ()
|
||||
|
||||
BOOL retval = FALSE;
|
||||
|
||||
ColorPickerDialogClass *dialog = (ColorPickerDialogClass *)::GetProp (form_wnd, "COLORPICKERDLGCLASS");
|
||||
if (dialog != NULL) {
|
||||
dialog->Set_Original_Color (red, green, blue);
|
||||
retval = TRUE;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
Show_Color_Picker (int *red, int *green, int *blue)
|
||||
{
|
||||
//MY_MANAGE_STATE ()
|
||||
|
||||
BOOL retval = FALSE;
|
||||
|
||||
ColorPickerDialogClass dialog (*red, *green, *blue);
|
||||
if (dialog.DoModal () == IDOK) {
|
||||
(*red) = dialog.Get_Red ();
|
||||
(*green) = dialog.Get_Green ();
|
||||
(*blue) = dialog.Get_Blue ();
|
||||
retval = TRUE;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
Set_Update_Callback (HWND form_wnd, WWCTRL_COLORCALLBACK callback, void *arg)
|
||||
{
|
||||
//MY_MANAGE_STATE()
|
||||
|
||||
BOOL retval = FALSE;
|
||||
|
||||
ColorPickerDialogClass *dialog = (ColorPickerDialogClass *)::GetProp (form_wnd, "COLORPICKERDLGCLASS");
|
||||
if (dialog != NULL) {
|
||||
dialog->Set_Update_Callback(callback, arg);
|
||||
retval = TRUE;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorPickerDialogClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
ColorPickerDialogClass::ColorPickerDialogClass
|
||||
(
|
||||
int red,
|
||||
int green,
|
||||
int blue,
|
||||
CWnd *pParent,
|
||||
UINT res_id
|
||||
)
|
||||
: m_OrigRed ((float)red),
|
||||
m_OrigGreen ((float)green),
|
||||
m_OrigBlue ((float)blue),
|
||||
m_CurrentRed ((float)red),
|
||||
m_CurrentGreen ((float)green),
|
||||
m_CurrentBlue ((float)blue),
|
||||
m_CurrentColorBar (NULL),
|
||||
m_OrigColorBar (NULL),
|
||||
m_RedColorBar (NULL),
|
||||
m_GreenColorBar (NULL),
|
||||
m_BlueColorBar (NULL),
|
||||
m_WhitenessColorBar (NULL),
|
||||
m_HuePicker (NULL),
|
||||
m_bDeleteOnClose (false),
|
||||
m_UpdateCallback(NULL),
|
||||
CDialog(res_id, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(ColorPickerDialogClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Create_Form
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerDialogClass::Create_Form (CWnd *parent)
|
||||
{
|
||||
Create (IDD_COLOR_FORM, parent);
|
||||
SetProp (m_hWnd, "COLORPICKERDLGCLASS", (HANDLE)this);
|
||||
m_bDeleteOnClose = true;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerDialogClass::DoDataExchange (CDataExchange *pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(ColorPickerDialogClass)
|
||||
DDX_Control(pDX, IDC_BLUE_SPIN, m_BlueSpin);
|
||||
DDX_Control(pDX, IDC_GREEN_SPIN, m_GreenSpin);
|
||||
DDX_Control(pDX, IDC_RED_SPIN, m_RedSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(ColorPickerDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(ColorPickerDialogClass)
|
||||
ON_BN_CLICKED(IDC_RESET, OnReset)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
ColorPickerDialogClass::OnInitDialog (void)
|
||||
{
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
//
|
||||
// Setup the spin controls
|
||||
//
|
||||
m_BlueSpin.SetRange (0, 255);
|
||||
m_GreenSpin.SetRange (0, 255);
|
||||
m_RedSpin.SetRange (0, 255);
|
||||
m_BlueSpin.SetPos ((int)m_CurrentBlue);
|
||||
m_GreenSpin.SetPos ((int)m_CurrentGreen);
|
||||
m_RedSpin.SetPos ((int)m_CurrentRed);
|
||||
|
||||
//
|
||||
// Get control of all the color bars on the dialog
|
||||
//
|
||||
m_CurrentColorBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_CURRENT_COLOR_BAR));
|
||||
m_OrigColorBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_ORIG_COLOR_BAR));
|
||||
m_RedColorBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_RED_BAR));
|
||||
m_GreenColorBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_GREEN_BAR));
|
||||
m_BlueColorBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_BLUE_BAR));
|
||||
m_WhitenessColorBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_WHITENESS_BAR));
|
||||
m_HuePicker = ColorPickerClass::Get_Color_Picker (::GetDlgItem (m_hWnd, IDC_HUE_PICKER));
|
||||
|
||||
// Setup the original color bar
|
||||
m_OrigColorBar->Modify_Point (0, 0, m_OrigRed, m_OrigGreen, m_OrigBlue);
|
||||
m_HuePicker->Select_Color ((int)m_OrigRed, (int)m_OrigGreen, (int)m_OrigBlue);
|
||||
//m_WhitenessColorBar->Modify_Point (0, 0, m_OrigRed, m_OrigGreen, m_OrigBlue);
|
||||
|
||||
m_RedColorBar->Set_Range (0, 255);
|
||||
m_GreenColorBar->Set_Range (0, 255);
|
||||
m_BlueColorBar->Set_Range (0, 255);
|
||||
m_WhitenessColorBar->Set_Range (0, 255);
|
||||
|
||||
m_WhitenessColorBar->Insert_Point (1, 255, 255, 255, 255);
|
||||
|
||||
//
|
||||
// Setup the red/green/blue color bars
|
||||
//
|
||||
//m_RedColorBar->Insert_Point (1, 1, 255, 0, 0);
|
||||
//m_GreenColorBar->Insert_Point (1, 1, 0, 255, 0);
|
||||
//m_BlueColorBar->Insert_Point (1, 1, 0, 0, 255);
|
||||
|
||||
//
|
||||
// Update the remaining color bars to reflect the initial color
|
||||
//
|
||||
Update_Red_Bar ();
|
||||
Update_Green_Bar ();
|
||||
Update_Blue_Bar ();
|
||||
Update_Current_Color_Bar ();
|
||||
Update_Whiteness_Bar ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Red_Bar
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerDialogClass::Update_Red_Bar (void)
|
||||
{
|
||||
m_RedColorBar->Set_Selection_Pos (m_CurrentRed);
|
||||
m_RedColorBar->Modify_Point (0, 0, 0, (float)m_CurrentGreen, (float)m_CurrentBlue);
|
||||
m_RedColorBar->Modify_Point (1, 255, 255, (float)m_CurrentGreen, (float)m_CurrentBlue);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Green_Bar
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerDialogClass::Update_Green_Bar (void)
|
||||
{
|
||||
m_GreenColorBar->Set_Selection_Pos (m_CurrentGreen);
|
||||
m_GreenColorBar->Modify_Point (0, 0, m_CurrentRed, 0, m_CurrentBlue);
|
||||
m_GreenColorBar->Modify_Point (1, 255, m_CurrentRed, 255, m_CurrentBlue);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Blue_Bar
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerDialogClass::Update_Blue_Bar (void)
|
||||
{
|
||||
m_BlueColorBar->Set_Selection_Pos (m_CurrentBlue);
|
||||
m_BlueColorBar->Modify_Point (0, 0, m_CurrentRed, m_CurrentGreen, 0);
|
||||
m_BlueColorBar->Modify_Point (1, 255, m_CurrentRed, m_CurrentGreen, 255);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Current_Color_Bar
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerDialogClass::Update_Current_Color_Bar (void)
|
||||
{
|
||||
m_CurrentColorBar->Modify_Point (0, 0, m_CurrentRed, m_CurrentGreen, m_CurrentBlue);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Whiteness_Bar
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerDialogClass::Update_Whiteness_Bar (void)
|
||||
{
|
||||
int red = 0;
|
||||
int green = 0;
|
||||
int blue = 0;
|
||||
m_HuePicker->Get_Current_Color (&red, &green, &blue);
|
||||
|
||||
//
|
||||
// Given the current color, determine the 'whiteness' and update
|
||||
//
|
||||
float whiteness = min (m_CurrentRed, m_CurrentGreen);
|
||||
whiteness = min (whiteness, m_CurrentBlue);
|
||||
float percent = whiteness / 255;
|
||||
m_WhitenessColorBar->Set_Selection_Pos (whiteness);
|
||||
|
||||
m_WhitenessColorBar->Modify_Point (0, 0, (float)red, (float)green, (float)blue);
|
||||
|
||||
// Can we extrapolate the starting color from the whiteness factor?
|
||||
/*if (percent == 1) {
|
||||
m_WhitenessColorBar->Modify_Point (0, 0, 0, 0, 0);
|
||||
} else {
|
||||
|
||||
//
|
||||
// Extrapolate the starting color
|
||||
//
|
||||
float start_red = (m_CurrentRed - whiteness) / (1 - percent);
|
||||
float start_green = (m_CurrentGreen - whiteness) / (1 - percent);
|
||||
float start_blue = (m_CurrentBlue - whiteness) / (1 - percent);
|
||||
m_WhitenessColorBar->Modify_Point (0, 0, start_red, start_green, start_blue);
|
||||
}*/
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
ColorPickerDialogClass::OnNotify
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
LRESULT *pResult
|
||||
)
|
||||
{
|
||||
CBR_NMHDR *color_bar_hdr = (CBR_NMHDR *)lParam;
|
||||
switch (color_bar_hdr->hdr.idFrom)
|
||||
{
|
||||
case IDC_RED_BAR:
|
||||
{
|
||||
if (color_bar_hdr->hdr.code == CBRN_SEL_CHANGED) {
|
||||
float red = color_bar_hdr->red;
|
||||
float green = m_CurrentGreen;
|
||||
float blue = m_CurrentBlue;
|
||||
Update_Color (red, green, blue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_GREEN_BAR:
|
||||
{
|
||||
if (color_bar_hdr->hdr.code == CBRN_SEL_CHANGED) {
|
||||
float red = m_CurrentRed;
|
||||
float green = color_bar_hdr->green;
|
||||
float blue = m_CurrentBlue;
|
||||
Update_Color (red, green, blue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_BLUE_BAR:
|
||||
{
|
||||
if (color_bar_hdr->hdr.code == CBRN_SEL_CHANGED) {
|
||||
float red = m_CurrentRed;
|
||||
float green = m_CurrentGreen;
|
||||
float blue = color_bar_hdr->blue;
|
||||
Update_Color (red, green, blue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_WHITENESS_BAR:
|
||||
{
|
||||
if (color_bar_hdr->hdr.code == CBRN_SEL_CHANGED) {
|
||||
float red = color_bar_hdr->red;
|
||||
float green = color_bar_hdr->green;
|
||||
float blue = color_bar_hdr->blue;
|
||||
Update_Color (red, green, blue, UPDATE_COLOR_BARS);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_HUE_PICKER:
|
||||
{
|
||||
CP_NMHDR *picker_hdr = (CP_NMHDR *)lParam;
|
||||
if (picker_hdr->hdr.code == CPN_COLORCHANGE) {
|
||||
float red = picker_hdr->red;
|
||||
float green = picker_hdr->green;
|
||||
float blue = picker_hdr->blue;
|
||||
float whiteness = m_WhitenessColorBar->Get_Selection_Pos () / 255;
|
||||
red = red + ((255 - red) * whiteness);
|
||||
green = green + ((255 - green) * whiteness);
|
||||
blue = blue + ((255 - blue) * whiteness);
|
||||
Update_Color (red, green, blue, UPDATE_COLOR_BARS | UPDATE_WHITENESS);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_RED_SPIN:
|
||||
case IDC_GREEN_SPIN:
|
||||
case IDC_BLUE_SPIN:
|
||||
{
|
||||
if (color_bar_hdr->hdr.code == UDN_DELTAPOS) {
|
||||
float red = (float)m_RedSpin.GetPos ();
|
||||
float green = (float)m_GreenSpin.GetPos ();
|
||||
float blue = (float)m_BlueSpin.GetPos ();
|
||||
Update_Color (red, green, blue, UPDATE_COLOR_BARS | UPDATE_WHITENESS | UPDATE_HUE_PICKER);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CDialog::OnNotify (wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Color
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerDialogClass::Update_Color
|
||||
(
|
||||
float red,
|
||||
float green,
|
||||
float blue,
|
||||
DWORD flags
|
||||
)
|
||||
{
|
||||
/*bool update_red = m_CurrentRed != red;
|
||||
bool update_green = m_CurrentGreen != green;
|
||||
bool update_blue = m_CurrentBlue != blue;*/
|
||||
|
||||
m_CurrentRed = red;
|
||||
m_CurrentGreen = green;
|
||||
m_CurrentBlue = blue;
|
||||
|
||||
int int_blue = (int)blue;
|
||||
int int_green = (int)green;
|
||||
int int_red = (int)red;
|
||||
if (int_blue != m_BlueSpin.GetPos ()) {
|
||||
m_BlueSpin.SetPos (int_blue);
|
||||
}
|
||||
if (int_green != m_GreenSpin.GetPos ()) {
|
||||
m_GreenSpin.SetPos (int_green);
|
||||
}
|
||||
if (int_red != m_RedSpin.GetPos ()) {
|
||||
m_RedSpin.SetPos (int_red);
|
||||
}
|
||||
|
||||
// Hack to get the edit controls to update in a timely fashion
|
||||
::UpdateWindow (::GetDlgItem (m_hWnd, IDC_RED_EDIT));
|
||||
::UpdateWindow (::GetDlgItem (m_hWnd, IDC_GREEN_EDIT));
|
||||
::UpdateWindow (::GetDlgItem (m_hWnd, IDC_BLUE_EDIT));
|
||||
|
||||
//
|
||||
// Update the red, green and blue color bars
|
||||
//
|
||||
if (flags & UPDATE_COLOR_BARS) {
|
||||
Update_Red_Bar ();
|
||||
Update_Green_Bar ();
|
||||
Update_Blue_Bar ();
|
||||
}
|
||||
|
||||
//
|
||||
// Update the hue picker
|
||||
//
|
||||
if (flags & UPDATE_HUE_PICKER) {
|
||||
m_HuePicker->Select_Color ((int)red, (int)green, (int)blue);
|
||||
}
|
||||
|
||||
//
|
||||
// Update the whiteness color bar
|
||||
//
|
||||
if (flags & UPDATE_WHITENESS) {
|
||||
Update_Whiteness_Bar ();
|
||||
}
|
||||
|
||||
Update_Current_Color_Bar ();
|
||||
|
||||
// If a callback is registered, call it.
|
||||
if (m_UpdateCallback)
|
||||
m_UpdateCallback((int)red, (int)green, (int)blue, m_CallArg);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Original_Color
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void ColorPickerDialogClass::Set_Original_Color (int r, int g, int b)
|
||||
{
|
||||
m_OrigRed = (float)r;
|
||||
m_OrigGreen = (float)g;
|
||||
m_OrigBlue = (float)b;
|
||||
m_OrigColorBar->Modify_Point (0, 0, m_OrigRed, m_OrigGreen, m_OrigBlue);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnReset
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerDialogClass::OnReset (void)
|
||||
{
|
||||
Update_Color (m_OrigRed,
|
||||
m_OrigGreen,
|
||||
m_OrigBlue,
|
||||
UPDATE_COLOR_BARS| UPDATE_WHITENESS | UPDATE_HUE_PICKER);
|
||||
return ;
|
||||
}
|
||||
|
||||
LRESULT ColorPickerDialogClass::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return CDialog::WindowProc(message, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCommand
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
ColorPickerDialogClass::OnCommand
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
switch (LOWORD (wParam))
|
||||
{
|
||||
case IDC_RED_EDIT:
|
||||
case IDC_GREEN_EDIT:
|
||||
case IDC_BLUE_EDIT:
|
||||
{
|
||||
if (HIWORD (wParam) == EN_KILLFOCUS) {
|
||||
float red = (float)GetDlgItemInt (IDC_RED_EDIT);
|
||||
float green = (float)GetDlgItemInt (IDC_GREEN_EDIT);
|
||||
float blue = (float)GetDlgItemInt (IDC_BLUE_EDIT);
|
||||
Update_Color (red, green, blue, UPDATE_COLOR_BARS| UPDATE_WHITENESS | UPDATE_HUE_PICKER);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CDialog::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PostNcDestroy
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ColorPickerDialogClass::PostNcDestroy (void)
|
||||
{
|
||||
CDialog::PostNcDestroy();
|
||||
|
||||
if (m_bDeleteOnClose) {
|
||||
delete this;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
136
Code/Tools/W3DView/ColorPickerDialogClass.h
Normal file
136
Code/Tools/W3DView/ColorPickerDialogClass.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
** 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_COLORPICKERDIALOGCLASS_H__C943A7F1_CAA3_11D2_8DDF_00104B6FD9E3__INCLUDED_)
|
||||
#define AFX_COLORPICKERDIALOGCLASS_H__C943A7F1_CAA3_11D2_8DDF_00104B6FD9E3__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// ColorPickerDialogClass.h : header file
|
||||
//
|
||||
|
||||
#include "resource.h"
|
||||
#include "colorutils.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Forward declarations
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
class ColorBarClass;
|
||||
class ColorPickerClass;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorPickerDialogClass dialog
|
||||
//
|
||||
class ColorPickerDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
ColorPickerDialogClass (int red, int green, int blue, CWnd* pParent = NULL, UINT res_id = ColorPickerDialogClass::IDD);
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(ColorPickerDialogClass)
|
||||
enum { IDD = IDD_COLOR_PICKER };
|
||||
CSpinButtonCtrl m_BlueSpin;
|
||||
CSpinButtonCtrl m_GreenSpin;
|
||||
CSpinButtonCtrl m_RedSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(ColorPickerDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
virtual void PostNcDestroy();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(ColorPickerDialogClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnReset();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
/////////////////////////////////////////////////////////////
|
||||
int Get_Red (void) const { return (int)m_CurrentRed; }
|
||||
int Get_Green (void) const { return (int)m_CurrentGreen; }
|
||||
int Get_Blue (void) const { return (int)m_CurrentBlue; }
|
||||
void Set_Color (int r, int g, int b)
|
||||
{ Update_Color((float)r, (float)g, (float)b); }
|
||||
void Set_Original_Color (int r, int g, int b);
|
||||
void Create_Form (CWnd *parent);
|
||||
void Set_Update_Callback (WWCTRL_COLORCALLBACK callme, void *arg)
|
||||
{ m_UpdateCallback = callme; m_CallArg = arg; }
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Protected methods
|
||||
/////////////////////////////////////////////////////////////
|
||||
void Update_Red_Bar (void);
|
||||
void Update_Green_Bar (void);
|
||||
void Update_Blue_Bar (void);
|
||||
void Update_Current_Color_Bar (void);
|
||||
void Update_Whiteness_Bar (void);
|
||||
void Update_Color (float red, float green, float blue, DWORD flags = 0xFFFFFFFF);
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Private member data
|
||||
/////////////////////////////////////////////////////////////
|
||||
float m_OrigRed;
|
||||
float m_OrigGreen;
|
||||
float m_OrigBlue;
|
||||
|
||||
float m_CurrentRed;
|
||||
float m_CurrentGreen;
|
||||
float m_CurrentBlue;
|
||||
|
||||
ColorBarClass * m_CurrentColorBar;
|
||||
ColorBarClass * m_OrigColorBar;
|
||||
ColorBarClass * m_RedColorBar;
|
||||
ColorBarClass * m_GreenColorBar;
|
||||
ColorBarClass * m_BlueColorBar;
|
||||
ColorBarClass * m_WhitenessColorBar;
|
||||
ColorPickerClass *m_HuePicker;
|
||||
|
||||
bool m_bDeleteOnClose;
|
||||
|
||||
// Callback function when color is updated.
|
||||
WWCTRL_COLORCALLBACK m_UpdateCallback;
|
||||
void * m_CallArg;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_COLORPICKERDIALOGCLASS_H__C943A7F1_CAA3_11D2_8DDF_00104B6FD9E3__INCLUDED_)
|
||||
345
Code/Tools/W3DView/ColorSelectionDialog.cpp
Normal file
345
Code/Tools/W3DView/ColorSelectionDialog.cpp
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// ColorSelectionDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "StdAfx.H"
|
||||
#include "W3DView.H"
|
||||
#include "ColorSelectionDialog.H"
|
||||
#include "Utils.H"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorSelectionDialogClass
|
||||
//
|
||||
ColorSelectionDialogClass::ColorSelectionDialogClass
|
||||
(
|
||||
const Vector3 &def_color,
|
||||
CWnd *pParent
|
||||
)
|
||||
: m_Color (def_color),
|
||||
m_PaintColor (def_color),
|
||||
CDialog(ColorSelectionDialogClass::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(ColorSelectionDialogClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
ColorSelectionDialogClass::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(ColorSelectionDialogClass)
|
||||
DDX_Control(pDX, IDC_BLUE_SPIN, m_BlueSpin);
|
||||
DDX_Control(pDX, IDC_GREEN_SPIN, m_GreenSpin);
|
||||
DDX_Control(pDX, IDC_RED_SPIN, m_RedSpin);
|
||||
DDX_Control(pDX, IDC_COLOR_WINDOW, m_ColorWindow);
|
||||
DDX_Control(pDX, IDC_SLIDER_BLUE, m_BlueSlider);
|
||||
DDX_Control(pDX, IDC_SLIDER_GREEN, m_GreenSlider);
|
||||
DDX_Control(pDX, IDC_SLIDER_RED, m_RedSlider);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(ColorSelectionDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(ColorSelectionDialogClass)
|
||||
ON_WM_HSCROLL()
|
||||
ON_WM_PAINT()
|
||||
ON_BN_CLICKED(IDC_GRAYSCALE_CHECK, OnGrayscaleCheck)
|
||||
ON_EN_CHANGE(IDC_BLUE_EDIT, OnChangeBlueEdit)
|
||||
ON_EN_CHANGE(IDC_GREEN_EDIT, OnChangeGreenEdit)
|
||||
ON_EN_CHANGE(IDC_RED_EDIT, OnChangeRedEdit)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorSelectionDialogClass
|
||||
//
|
||||
BOOL
|
||||
ColorSelectionDialogClass::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
// Set the ranges of the slider and spin controls
|
||||
m_RedSlider.SetRange (0, 255);
|
||||
m_GreenSlider.SetRange (0, 255);
|
||||
m_BlueSlider.SetRange (0, 255);
|
||||
m_RedSpin.SetRange (0, 255);
|
||||
m_GreenSpin.SetRange (0, 255);
|
||||
m_BlueSpin.SetRange (0, 255);
|
||||
|
||||
// Determine the initial settings (in integers)
|
||||
int red_value = int(m_Color.X * 255.00F);
|
||||
int green_value = int(m_Color.Y * 255.00F);
|
||||
int blue_value = int(m_Color.Z * 255.00F);
|
||||
|
||||
if ((red_value == green_value) &&
|
||||
(red_value == blue_value)) {
|
||||
|
||||
// Check the grayscale checkbox
|
||||
SendDlgItemMessage (IDC_GRAYSCALE_CHECK, BM_SETCHECK, (WPARAM)TRUE);
|
||||
}
|
||||
|
||||
// Set the initial slider positions
|
||||
m_RedSlider.SetPos (red_value);
|
||||
m_GreenSlider.SetPos (green_value);
|
||||
m_BlueSlider.SetPos (blue_value);
|
||||
m_RedSpin.SetPos (red_value);
|
||||
m_GreenSpin.SetPos (green_value);
|
||||
m_BlueSpin.SetPos (blue_value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorSelectionDialogClass
|
||||
//
|
||||
void
|
||||
ColorSelectionDialogClass::OnOK (void)
|
||||
{
|
||||
// Record the color
|
||||
m_Color = m_PaintColor;
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnOK ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnHScroll
|
||||
//
|
||||
void
|
||||
ColorSelectionDialogClass::OnHScroll
|
||||
(
|
||||
UINT nSBCode,
|
||||
UINT nPos,
|
||||
CScrollBar *pScrollBar
|
||||
)
|
||||
{
|
||||
// Update the slider positions and the color window
|
||||
Update_Sliders (::GetWindowLong (*pScrollBar, GWL_ID));
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnHScroll (nSBCode, nPos, pScrollBar);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnPaint
|
||||
//
|
||||
void
|
||||
ColorSelectionDialogClass::OnPaint (void)
|
||||
{
|
||||
CPaintDC dc (this);
|
||||
|
||||
// Paint the gradients for each color
|
||||
::Paint_Gradient (::GetDlgItem (m_hWnd, IDC_RED_GRADIENT), 1, 0, 0);
|
||||
::Paint_Gradient (::GetDlgItem (m_hWnd, IDC_GREEN_GRADIENT), 0, 1, 0);
|
||||
::Paint_Gradient (::GetDlgItem (m_hWnd, IDC_BLUE_GRADIENT), 0, 0, 1);
|
||||
|
||||
// Update the window that displays the color the user has selected
|
||||
Paint_Color_Window ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Paint_Color_Window
|
||||
//
|
||||
void
|
||||
ColorSelectionDialogClass::Paint_Color_Window (void)
|
||||
{
|
||||
// Get the client coords of the 'color' window
|
||||
CRect rect;
|
||||
m_ColorWindow.GetClientRect (&rect);
|
||||
|
||||
// Fill the window with the selected color
|
||||
CDC *pdc = m_ColorWindow.GetDC ();
|
||||
::FrameRect (*pdc, &rect, (HBRUSH)::GetStockObject (BLACK_BRUSH));
|
||||
rect.DeflateRect (1, 1);
|
||||
pdc->FillSolidRect (&rect, RGB (int(m_PaintColor.X * 255), int(m_PaintColor.Y * 255), int(m_PaintColor.Z * 255)));
|
||||
m_ColorWindow.ReleaseDC (pdc);
|
||||
|
||||
// Let the window know it doesn't need to be repainted
|
||||
m_ColorWindow.ValidateRect (NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnGrayscaleCheck
|
||||
//
|
||||
void
|
||||
ColorSelectionDialogClass::OnGrayscaleCheck (void)
|
||||
{
|
||||
// Is the checkbox checked?
|
||||
if (SendDlgItemMessage (IDC_GRAYSCALE_CHECK, BM_GETCHECK)) {
|
||||
|
||||
// Make the green and blue sliders the same as red
|
||||
m_GreenSlider.SetPos (m_RedSlider.GetPos ());
|
||||
m_BlueSlider.SetPos (m_RedSlider.GetPos ());
|
||||
|
||||
m_PaintColor.X = float(m_RedSlider.GetPos ()) / 255.00F;
|
||||
m_PaintColor.Y = float(m_GreenSlider.GetPos ()) / 255.00F;
|
||||
m_PaintColor.Z = float(m_BlueSlider.GetPos ()) / 255.00F;
|
||||
|
||||
// Update the window that displays the color the user has selected
|
||||
Paint_Color_Window ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnChangeBlueEdit
|
||||
//
|
||||
void
|
||||
ColorSelectionDialogClass::OnChangeBlueEdit (void)
|
||||
{
|
||||
if (::IsWindow (m_BlueSlider)) {
|
||||
int value = GetDlgItemInt (IDC_BLUE_EDIT);
|
||||
m_BlueSlider.SetPos (value);
|
||||
|
||||
// Update the slider positions and the color window
|
||||
Update_Sliders (IDC_SLIDER_BLUE);
|
||||
|
||||
// Reset the cursor to the end of the edit box
|
||||
SendDlgItemMessage (IDC_BLUE_EDIT, EM_SETSEL, (WPARAM)(int)10, (LPARAM)(int)20);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnChangeGreenEdit
|
||||
//
|
||||
void
|
||||
ColorSelectionDialogClass::OnChangeGreenEdit (void)
|
||||
{
|
||||
if (::IsWindow (m_GreenSlider)) {
|
||||
int value = GetDlgItemInt (IDC_GREEN_EDIT);
|
||||
m_GreenSlider.SetPos (value);
|
||||
|
||||
// Update the slider positions and the color window
|
||||
Update_Sliders (IDC_SLIDER_GREEN);
|
||||
|
||||
// Reset the cursor to the end of the edit box
|
||||
SendDlgItemMessage (IDC_GREEN_EDIT, EM_SETSEL, (WPARAM)(int)10, (LPARAM)(int)20);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnChangeRedEdit
|
||||
//
|
||||
void
|
||||
ColorSelectionDialogClass::OnChangeRedEdit (void)
|
||||
{
|
||||
if (::IsWindow (m_RedSlider)) {
|
||||
int value = GetDlgItemInt (IDC_RED_EDIT);
|
||||
m_RedSlider.SetPos (value);
|
||||
|
||||
// Update the slider positions and the color window
|
||||
Update_Sliders (IDC_SLIDER_RED);
|
||||
|
||||
// Reset the cursor to the end of the edit box
|
||||
SendDlgItemMessage (IDC_RED_EDIT, EM_SETSEL, (WPARAM)(int)10, (LPARAM)(int)20);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Sliders
|
||||
//
|
||||
void
|
||||
ColorSelectionDialogClass::Update_Sliders (int slider_id)
|
||||
{
|
||||
// Are the sliders moving together?
|
||||
if (SendDlgItemMessage (IDC_GRAYSCALE_CHECK, BM_GETCHECK)) {
|
||||
int position = 0;
|
||||
|
||||
// Determine which slider sent this message and
|
||||
// use its current position
|
||||
if (slider_id == IDC_SLIDER_RED) {
|
||||
position = m_RedSlider.GetPos ();
|
||||
} else if (slider_id == IDC_SLIDER_GREEN) {
|
||||
position = m_GreenSlider.GetPos ();
|
||||
} else {
|
||||
position = m_BlueSlider.GetPos ();
|
||||
}
|
||||
|
||||
// Make all the sliders the same pos
|
||||
m_RedSlider.SetPos (position);
|
||||
m_GreenSlider.SetPos (position);
|
||||
m_BlueSlider.SetPos (position);
|
||||
}
|
||||
|
||||
// Update the edit controls (and their spin controls)
|
||||
float red_val = m_RedSlider.GetPos ();
|
||||
float green_val = m_GreenSlider.GetPos ();
|
||||
float blue_val = m_BlueSlider.GetPos ();
|
||||
m_RedSpin.SetPos (red_val);
|
||||
m_GreenSpin.SetPos (green_val);
|
||||
m_BlueSpin.SetPos (blue_val);
|
||||
|
||||
// Record the selected color for later use
|
||||
m_PaintColor.X = red_val / 255.00F;
|
||||
m_PaintColor.Y = green_val / 255.00F;
|
||||
m_PaintColor.Z = blue_val / 255.00F;
|
||||
|
||||
// Update the window that displays the color the user has selected
|
||||
Paint_Color_Window ();
|
||||
return ;
|
||||
}
|
||||
109
Code/Tools/W3DView/ColorSelectionDialog.h
Normal file
109
Code/Tools/W3DView/ColorSelectionDialog.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
** 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_OLORSELECTIONDIALOG_H__C0BCECAE_B6EA_11D2_9FF8_00104B791122__INCLUDED_)
|
||||
#define AFX_OLORSELECTIONDIALOG_H__C0BCECAE_B6EA_11D2_9FF8_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// ColorSelectionDialog.h : header file
|
||||
//
|
||||
|
||||
#include "Resource.H"
|
||||
#include "Vector3.H"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorSelectionDialogClass dialog
|
||||
//
|
||||
class ColorSelectionDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
ColorSelectionDialogClass (const Vector3 &def_color, CWnd *pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(ColorSelectionDialogClass)
|
||||
enum { IDD = IDD_COLOR_SEL };
|
||||
CSpinButtonCtrl m_BlueSpin;
|
||||
CSpinButtonCtrl m_GreenSpin;
|
||||
CSpinButtonCtrl m_RedSpin;
|
||||
CStatic m_ColorWindow;
|
||||
CSliderCtrl m_BlueSlider;
|
||||
CSliderCtrl m_GreenSlider;
|
||||
CSliderCtrl m_RedSlider;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(ColorSelectionDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(ColorSelectionDialogClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||||
afx_msg void OnPaint();
|
||||
afx_msg void OnGrayscaleCheck();
|
||||
afx_msg void OnChangeBlueEdit();
|
||||
afx_msg void OnChangeGreenEdit();
|
||||
afx_msg void OnChangeRedEdit();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
const Vector3 & Get_Color (void) const { return m_Color; }
|
||||
void Set_Color (const Vector3 &color) { m_Color = color; }
|
||||
|
||||
protected:
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// Inline accessors
|
||||
//
|
||||
void Paint_Color_Window (void);
|
||||
void Update_Sliders (int slider_id);
|
||||
|
||||
private:
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
Vector3 m_Color;
|
||||
Vector3 m_PaintColor;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_OLORSELECTIONDIALOG_H__C0BCECAE_B6EA_11D2_9FF8_00104B791122__INCLUDED_)
|
||||
188
Code/Tools/W3DView/ColorUtils.cpp
Normal file
188
Code/Tools/W3DView/ColorUtils.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Utils.cpp
|
||||
//
|
||||
//
|
||||
|
||||
#include "StdAfx.H"
|
||||
#include "ColorUtils.H"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Draw_Sunken_Rect
|
||||
//
|
||||
void
|
||||
Draw_Sunken_Rect
|
||||
(
|
||||
UCHAR *pbits,
|
||||
const RECT &rect,
|
||||
int scanline_size
|
||||
)
|
||||
{
|
||||
int width = rect.right - rect.left;
|
||||
int height = rect.bottom - rect.top;
|
||||
|
||||
// Draw the 4 lines that compose the rectangle
|
||||
::Draw_Vert_Line (pbits, rect.left, rect.top, height, ::GetSysColor (COLOR_3DSHADOW), scanline_size);
|
||||
::Draw_Vert_Line (pbits, rect.right-1, rect.top, height, ::GetSysColor (COLOR_3DHIGHLIGHT), scanline_size);
|
||||
::Draw_Horz_Line (pbits, rect.left, rect.top, width, ::GetSysColor (COLOR_3DSHADOW), scanline_size);
|
||||
::Draw_Horz_Line (pbits, rect.left, rect.bottom-1, width, ::GetSysColor (COLOR_3DHIGHLIGHT), scanline_size);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Draw_Raised_Rect
|
||||
//
|
||||
void
|
||||
Draw_Raised_Rect
|
||||
(
|
||||
UCHAR *pbits,
|
||||
const RECT &rect,
|
||||
int scanline_size
|
||||
)
|
||||
{
|
||||
int width = rect.right - rect.left;
|
||||
int height = rect.bottom - rect.top;
|
||||
|
||||
// Draw the 4 lines that compose the rectangle
|
||||
::Draw_Vert_Line (pbits, rect.left, rect.top, height, ::GetSysColor (COLOR_3DHIGHLIGHT), scanline_size);
|
||||
::Draw_Vert_Line (pbits, rect.right-1, rect.top, height, ::GetSysColor (COLOR_3DSHADOW), scanline_size);
|
||||
::Draw_Horz_Line (pbits, rect.left, rect.top, width, ::GetSysColor (COLOR_3DHIGHLIGHT), scanline_size);
|
||||
::Draw_Horz_Line (pbits, rect.left, rect.bottom-1, width, ::GetSysColor (COLOR_3DSHADOW), scanline_size);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Frame_Rect
|
||||
//
|
||||
void
|
||||
Frame_Rect
|
||||
(
|
||||
UCHAR *pbits,
|
||||
const RECT &rect,
|
||||
COLORREF color,
|
||||
int scanline_size
|
||||
)
|
||||
{
|
||||
UCHAR red = GetRValue (color);
|
||||
UCHAR green = GetRValue (color);
|
||||
UCHAR blue = GetRValue (color);
|
||||
|
||||
int index = (rect.top * scanline_size) + (rect.left * 3);
|
||||
for (int col = rect.left; col < rect.right; col ++) {
|
||||
pbits[index++] = blue;
|
||||
pbits[index++] = green;
|
||||
pbits[index++] = red;
|
||||
}
|
||||
|
||||
index = ((rect.bottom-1) * scanline_size) + (rect.left * 3);
|
||||
for (col = rect.left; col < rect.right; col ++) {
|
||||
pbits[index++] = blue;
|
||||
pbits[index++] = green;
|
||||
pbits[index++] = red;
|
||||
}
|
||||
|
||||
index = (rect.top * scanline_size) + (rect.left * 3);
|
||||
for (int row = rect.top; row < rect.bottom; row ++) {
|
||||
pbits[index] = blue;
|
||||
pbits[index + 1] = green;
|
||||
pbits[index + 2] = red;
|
||||
index += scanline_size;
|
||||
}
|
||||
|
||||
index = (rect.top * scanline_size) + ((rect.right-1) * 3);
|
||||
for (row = rect.top; row < rect.bottom; row ++) {
|
||||
pbits[index] = blue;
|
||||
pbits[index + 1] = green;
|
||||
pbits[index + 2] = red;
|
||||
index += scanline_size;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Draw_Vert_Line
|
||||
//
|
||||
void
|
||||
Draw_Vert_Line
|
||||
(
|
||||
UCHAR *pbits,
|
||||
int x,
|
||||
int y,
|
||||
int len,
|
||||
COLORREF color,
|
||||
int scanline_size
|
||||
)
|
||||
{
|
||||
UCHAR red = GetRValue (color);
|
||||
UCHAR green = GetRValue (color);
|
||||
UCHAR blue = GetRValue (color);
|
||||
|
||||
int index = (y * scanline_size) + (x * 3);
|
||||
for (int row = y; row < len; row ++) {
|
||||
pbits[index] = blue;
|
||||
pbits[index + 1] = green;
|
||||
pbits[index + 2] = red;
|
||||
index += scanline_size;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Draw_Horz_Line
|
||||
//
|
||||
void
|
||||
Draw_Horz_Line
|
||||
(
|
||||
UCHAR *pbits,
|
||||
int x,
|
||||
int y,
|
||||
int len,
|
||||
COLORREF color,
|
||||
int scanline_size
|
||||
)
|
||||
{
|
||||
UCHAR red = GetRValue (color);
|
||||
UCHAR green = GetRValue (color);
|
||||
UCHAR blue = GetRValue (color);
|
||||
|
||||
int index = (y * scanline_size) + (x * 3);
|
||||
for (int col = x; col < len; col ++) {
|
||||
pbits[index++] = blue;
|
||||
pbits[index++] = green;
|
||||
pbits[index++] = red;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
51
Code/Tools/W3DView/ColorUtils.h
Normal file
51
Code/Tools/W3DView/ColorUtils.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorUtils.H
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __COLORUTILS_H
|
||||
#define __COLORUTILS_H
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Callbacks
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
typedef void (*WWCTRL_COLORCALLBACK)(int,int,int,void*);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Prototypes
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void Frame_Rect (UCHAR *pbits, const RECT &rect, COLORREF color, int scanline_size);
|
||||
void Draw_Vert_Line (UCHAR *pbits, int x, int y, int len, COLORREF color, int scanline_size);
|
||||
void Draw_Horz_Line (UCHAR *pbits, int x, int y, int len, COLORREF color, int scanline_size);
|
||||
void Draw_Sunken_Rect (UCHAR *pbits, const RECT &rect, int scanline_size);
|
||||
void Draw_Raised_Rect (UCHAR *pbits, const RECT &rect, int scanline_size);
|
||||
BOOL Show_Color_Picker (int *red, int *green, int *blue);
|
||||
HWND Create_Color_Picker_Form (HWND parent, int red, int green, int blue);
|
||||
BOOL Get_Form_Color (HWND form_wnd, int *red, int *green, int *blue);
|
||||
BOOL Set_Form_Color (HWND form_wnd, int red, int green, int blue);
|
||||
BOOL Set_Form_Original_Color (HWND form_wnd, int red, int green, int blue);
|
||||
BOOL Set_Update_Callback (HWND form_wnd, WWCTRL_COLORCALLBACK callback, void *arg=NULL);
|
||||
void RegisterColorPicker (HINSTANCE hinst);
|
||||
void RegisterColorBar (HINSTANCE hinst);
|
||||
|
||||
|
||||
#endif //__COLORUTILS_H
|
||||
1517
Code/Tools/W3DView/DataTreeView.cpp
Normal file
1517
Code/Tools/W3DView/DataTreeView.cpp
Normal file
File diff suppressed because it is too large
Load Diff
180
Code/Tools/W3DView/DataTreeView.h
Normal file
180
Code/Tools/W3DView/DataTreeView.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
** 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_DATATREEVIEW_H__2BB39E40_5D3A_11D2_9FC6_00104B791122__INCLUDED_)
|
||||
#define AFX_DATATREEVIEW_H__2BB39E40_5D3A_11D2_9FC6_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// DataTreeView.h : header file
|
||||
//
|
||||
|
||||
#include "AfxCView.H"
|
||||
#include "AssetTypes.H"
|
||||
#include "Vector.H"
|
||||
|
||||
// Forward declarations
|
||||
class RenderObjClass;
|
||||
class AssetInfoClass;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CDataTreeView view
|
||||
//
|
||||
class CDataTreeView : public CTreeView
|
||||
{
|
||||
protected:
|
||||
CDataTreeView(); // protected constructor used by dynamic creation
|
||||
DECLARE_DYNCREATE(CDataTreeView)
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CDataTreeView)
|
||||
public:
|
||||
virtual void OnInitialUpdate();
|
||||
protected:
|
||||
virtual void OnDraw(CDC* pDC); // overridden to draw this view
|
||||
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
virtual ~CDataTreeView();
|
||||
#ifdef _DEBUG
|
||||
virtual void AssertValid() const;
|
||||
virtual void Dump(CDumpContext& dc) const;
|
||||
#endif
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CDataTreeView)
|
||||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||||
afx_msg void OnSelChanged(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnDeleteItem(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnDblclk(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Asset insertion methods
|
||||
//
|
||||
bool Add_Asset_To_Tree (LPCTSTR name, ASSET_TYPE type, bool bselect);
|
||||
void LoadAssetsIntoTree (void);
|
||||
void Refresh_Asset (LPCTSTR new_name, LPCTSTR old_name, ASSET_TYPE type);
|
||||
|
||||
//
|
||||
// Animation insertion methods
|
||||
//
|
||||
void LoadAnimationsIntoTree (void);
|
||||
void LoadAnimationsIntoTree (HTREEITEM hItem);
|
||||
|
||||
bool Are_Anims_Restricted (void) const { return m_RestrictAnims; }
|
||||
void Restrict_Anims (bool onoff);
|
||||
|
||||
//
|
||||
// Texture insertion methods
|
||||
//
|
||||
void Load_Materials_Into_Tree (void);
|
||||
|
||||
//
|
||||
// Display methods
|
||||
//
|
||||
void Display_Asset (HTREEITEM htree_item = NULL);
|
||||
void Select_Next (void);
|
||||
void Select_Prev (void);
|
||||
void Reload_Lightmap_Models (void);
|
||||
|
||||
//
|
||||
// Information methods
|
||||
//
|
||||
RenderObjClass * Get_Current_Render_Obj (void) const;
|
||||
AssetInfoClass * Get_Current_Asset_Info (void) const;
|
||||
LPCTSTR GetCurrentSelectionName (void);
|
||||
ASSET_TYPE GetCurrentSelectionType (void);
|
||||
HTREEITEM FindChildItem (HTREEITEM hParentItem, LPCTSTR pszChildItemName);
|
||||
HTREEITEM FindChildItem (HTREEITEM hParentItem, RenderObjClass *prender_obj);
|
||||
HTREEITEM FindFirstChildItemBasedOnHierarchyName (HTREEITEM hParentItem, LPCTSTR pszHierarchyName);
|
||||
HTREEITEM FindSiblingItemBasedOnHierarchyName (HTREEITEM hCurrentItem, LPCTSTR pszHierarchyName);
|
||||
void Build_Render_Object_List (DynamicVectorClass <CString> &asset_list, HTREEITEM hparent = TVI_ROOT);
|
||||
|
||||
//
|
||||
// Initialization methods
|
||||
//
|
||||
void CreateRootNodes (void);
|
||||
|
||||
protected:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Protected methods
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
ASSET_TYPE Determine_Tree_Location (RenderObjClass &render_obj, HTREEITEM &hroot, int &icon_index);
|
||||
void Determine_Tree_Location (ASSET_TYPE type, HTREEITEM &hroot, int &icon_index);
|
||||
RenderObjClass * Create_Render_Obj_To_Display (HTREEITEM htree_item);
|
||||
void Add_Emitters_To_Menu (HMENU hmenu, RenderObjClass &render_obj);
|
||||
void Free_Child_Models (HTREEITEM parent_item);
|
||||
|
||||
private:
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
HTREEITEM m_hMaterialsRoot;
|
||||
HTREEITEM m_hMeshRoot;
|
||||
HTREEITEM m_hAggregateRoot;
|
||||
HTREEITEM m_hLODRoot;
|
||||
HTREEITEM m_hMeshCollectionRoot;
|
||||
HTREEITEM m_hEmitterRoot;
|
||||
HTREEITEM m_hPrimitivesRoot;
|
||||
HTREEITEM m_hHierarchyRoot;
|
||||
HTREEITEM m_hSoundRoot;
|
||||
int m_iAnimationIcon;
|
||||
int m_iTCAnimationIcon;
|
||||
int m_iADAnimationIcon;
|
||||
int m_iMeshIcon;
|
||||
int m_iMaterialIcon;
|
||||
int m_iLODIcon;
|
||||
int m_iEmitterIcon;
|
||||
int m_iPrimitivesIcon;
|
||||
int m_iAggregateIcon;
|
||||
int m_iHierarchyIcon;
|
||||
int m_iSoundIcon;
|
||||
bool m_RestrictAnims;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_DATATREEVIEW_H__2BB39E40_5D3A_11D2_9FC6_00104B791122__INCLUDED_)
|
||||
|
||||
248
Code/Tools/W3DView/DeviceSelectionDialog.cpp
Normal file
248
Code/Tools/W3DView/DeviceSelectionDialog.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// DeviceSelectionDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "StdAfx.H"
|
||||
|
||||
#include "W3DView.h"
|
||||
#include "DeviceSelectionDialog.h"
|
||||
#include "WW3D.H"
|
||||
#include "Resource.H"
|
||||
#include "Globals.h"
|
||||
#include "W3DView.H"
|
||||
#include "Utils.H"
|
||||
#include "rddesc.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDeviceSelectionDialog dialog
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CDeviceSelectionDialog
|
||||
//
|
||||
CDeviceSelectionDialog::CDeviceSelectionDialog
|
||||
(
|
||||
BOOL bLookupCachedInfo,
|
||||
CWnd* pParent /*=NULL*/
|
||||
)
|
||||
: m_iDeviceIndex (1),
|
||||
m_iBitsPerPixel (16),
|
||||
m_bLookupCachedInfo (bLookupCachedInfo),
|
||||
CDialog(CDeviceSelectionDialog::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CDeviceSelectionDialog)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
CDeviceSelectionDialog::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CDeviceSelectionDialog)
|
||||
DDX_Control(pDX, IDC_RENDER_DEVICE_COMBO, m_deviceListComboBox);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CDeviceSelectionDialog, CDialog)
|
||||
//{{AFX_MSG_MAP(CDeviceSelectionDialog)
|
||||
ON_CBN_SELCHANGE(IDC_RENDER_DEVICE_COMBO, OnSelchangeRenderDeviceCombo)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDeviceSelectionDialog message handlers
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
CDeviceSelectionDialog::OnInitDialog (void)
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
//
|
||||
// Loop through all the devices and add them to the combobox
|
||||
//
|
||||
int device_count = WW3D::Get_Render_Device_Count ();
|
||||
int selected_index = 0;
|
||||
for (int index = 0; index < device_count; index ++) {
|
||||
|
||||
//
|
||||
// Add this device to the combobox
|
||||
//
|
||||
const char *name = WW3D::Get_Render_Device_Name(index);
|
||||
int combo_index = m_deviceListComboBox.InsertString (index, name);
|
||||
if (m_DriverName.CompareNoCase (name) == 0) {
|
||||
selected_index = combo_index;
|
||||
}
|
||||
|
||||
// Associate the index of this device with the item we just inserted
|
||||
m_deviceListComboBox.SetItemData (combo_index, index);
|
||||
}
|
||||
|
||||
// Check the '16bpp' radio by default
|
||||
SendDlgItemMessage (IDC_COLORDEPTH_16, BM_SETCHECK, (WPARAM)TRUE);
|
||||
|
||||
// Force the first entry in the combobox to be selected.
|
||||
//m_deviceListComboBox.SetCurSel (0);
|
||||
m_deviceListComboBox.SetCurSel (selected_index);
|
||||
|
||||
// Update the static controls on the dialog to reflect the device
|
||||
UpdateDeviceDescription ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSelchangeRenderDeviceCombo
|
||||
//
|
||||
void
|
||||
CDeviceSelectionDialog::OnSelchangeRenderDeviceCombo (void)
|
||||
{
|
||||
int index = m_deviceListComboBox.GetCurSel ();
|
||||
if (index != CB_ERR) {
|
||||
//WW3D::Set_Render_Device ();
|
||||
|
||||
// Update the static controls with the information from the device
|
||||
UpdateDeviceDescription ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// UpdateDeviceDescription
|
||||
//
|
||||
void
|
||||
CDeviceSelectionDialog::UpdateDeviceDescription (void)
|
||||
{
|
||||
const RenderDeviceDescClass &device_desc = WW3D::Get_Render_Device_Desc ();
|
||||
|
||||
//
|
||||
// Reload the static text controls on the dialog
|
||||
//
|
||||
SetDlgItemText (IDC_DRIVER_NAME, m_DriverName);
|
||||
SetDlgItemText (IDC_DEVICE_NAME_STATIC, device_desc.Get_Device_Name());
|
||||
SetDlgItemText (IDC_DEVICE_VENDOR_STATIC, device_desc.Get_Device_Vendor());
|
||||
SetDlgItemText (IDC_DEVICE_PLATFORM_STATIC, device_desc.Get_Device_Platform());
|
||||
SetDlgItemText (IDC_DRIVER_NAME_STATIC, device_desc.Get_Driver_Name());
|
||||
SetDlgItemText (IDC_DRIVER_VENDOR_STATIC, device_desc.Get_Driver_Vendor());
|
||||
SetDlgItemText (IDC_DRIVER_VERSION_STATIC, device_desc.Get_Driver_Version());
|
||||
SetDlgItemText (IDC_HARDWARE_NAME_STATIC, device_desc.Get_Hardware_Name());
|
||||
SetDlgItemText (IDC_HARDWARE_VENDOR_STATIC, device_desc.Get_Hardware_Vendor());
|
||||
SetDlgItemText (IDC_HARDWARE_CHIPSET_STATIC, device_desc.Get_Hardware_Chipset());
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnOK
|
||||
//
|
||||
void
|
||||
CDeviceSelectionDialog::OnOK (void)
|
||||
{
|
||||
// Ask the combobox for its current selection
|
||||
m_iDeviceIndex = m_deviceListComboBox.GetItemData (m_deviceListComboBox.GetCurSel ());
|
||||
m_iBitsPerPixel = (SendDlgItemMessage (IDC_COLORDEPTH_16, BM_GETCHECK) == TRUE) ? 16 : 24;
|
||||
|
||||
// Get the device name of the currently selected device
|
||||
CString stringDeviceName;
|
||||
m_deviceListComboBox.GetLBText (m_deviceListComboBox.GetCurSel (), stringDeviceName);
|
||||
m_DriverName = stringDeviceName;
|
||||
|
||||
// Cache this information in the registry
|
||||
theApp.WriteProfileString ("Config", "DeviceName", stringDeviceName);
|
||||
theApp.WriteProfileInt ("Config", "DeviceBitsPerPix", m_iBitsPerPixel);
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnOK();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoModal
|
||||
//
|
||||
int
|
||||
CDeviceSelectionDialog::DoModal (void)
|
||||
{
|
||||
BOOL bFoundDevice = FALSE;
|
||||
int iReturn = IDOK;
|
||||
|
||||
// Get the name of the last used device driver from the registry
|
||||
m_DriverName = theApp.GetProfileString ("Config", "DeviceName");
|
||||
if (m_bLookupCachedInfo &&
|
||||
(m_DriverName.GetLength () > 0) &&
|
||||
!(::GetKeyState (VK_SHIFT) & 0xF000)) {
|
||||
|
||||
//
|
||||
// Loop through all the devices and see if we can find the right one
|
||||
//
|
||||
int device_count = WW3D::Get_Render_Device_Count ();
|
||||
for (int index = 0; (index < device_count) && !bFoundDevice; index ++) {
|
||||
|
||||
//
|
||||
// Is this the device we are looking for?
|
||||
//
|
||||
const char *name = WW3D::Get_Render_Device_Name (index);
|
||||
if (m_DriverName.CompareNoCase (name) == 0) {
|
||||
|
||||
//
|
||||
// Set the internal device information to simulate 'showing' the dialog
|
||||
//
|
||||
m_iDeviceIndex = index;
|
||||
m_iBitsPerPixel = theApp.GetProfileInt ("Config", "DeviceBitsPerPix", 16);
|
||||
|
||||
// Found it!
|
||||
bFoundDevice = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show the dialog and allow the user to select the device
|
||||
if (bFoundDevice == FALSE) {
|
||||
iReturn = CDialog::DoModal ();
|
||||
}
|
||||
|
||||
// Return the integer return code
|
||||
return iReturn;
|
||||
}
|
||||
90
Code/Tools/W3DView/DeviceSelectionDialog.h
Normal file
90
Code/Tools/W3DView/DeviceSelectionDialog.h
Normal 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/>.
|
||||
*/
|
||||
|
||||
#if !defined(AFX_DEVICESELECTIONDIALOG_H__49E2DFF9_5D3F_11D2_9FC6_00104B791122__INCLUDED_)
|
||||
#define AFX_DEVICESELECTIONDIALOG_H__49E2DFF9_5D3F_11D2_9FC6_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// DeviceSelectionDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDeviceSelectionDialog dialog
|
||||
|
||||
class CDeviceSelectionDialog : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CDeviceSelectionDialog(BOOL bLookupCachedInfo = TRUE, CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CDeviceSelectionDialog)
|
||||
enum { IDD = IDD_RENDER_DEVICE_SELECTOR };
|
||||
CComboBox m_deviceListComboBox;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CDeviceSelectionDialog)
|
||||
public:
|
||||
virtual int DoModal();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CDeviceSelectionDialog)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnSelchangeRenderDeviceCombo();
|
||||
virtual void OnOK();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
// Return the selected device index
|
||||
int GetDeviceIndex () const
|
||||
{ return m_iDeviceIndex; }
|
||||
|
||||
// Return the selected bits per pixel
|
||||
int GetBitsPerPixel () const
|
||||
{ return m_iBitsPerPixel; }
|
||||
|
||||
const CString &GetDriverName () const
|
||||
{ return m_DriverName; }
|
||||
|
||||
protected:
|
||||
void UpdateDeviceDescription (void);
|
||||
|
||||
private:
|
||||
BOOL m_bLookupCachedInfo;
|
||||
int m_iDeviceIndex;
|
||||
int m_iBitsPerPixel;
|
||||
CString m_DriverName;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_DEVICESELECTIONDIALOG_H__49E2DFF9_5D3F_11D2_9FC6_00104B791122__INCLUDED_)
|
||||
147
Code/Tools/W3DView/DialogToolbar.cpp
Normal file
147
Code/Tools/W3DView/DialogToolbar.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : LevelEdit *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/W3DView/DialogToolbar.cpp $*
|
||||
* *
|
||||
* Author:: Patrick Smith *
|
||||
* *
|
||||
* $Modtime:: 2/23/99 10:58a $*
|
||||
* *
|
||||
* $Revision:: 1 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "StdAfx.H"
|
||||
#include "DialogToolbar.H"
|
||||
#include "AfxPriv.H"
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(DialogToolbarClass, CToolBar)
|
||||
//{{AFX_MSG_MAP(DialogToolbarClass)
|
||||
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
|
||||
ON_MESSAGE_VOID(WM_INITIALUPDATE, OnInitialUpdate)
|
||||
ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnNeedToolTipText)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
DialogToolbarClass::DialogToolbarClass (void)
|
||||
: CToolBar ()
|
||||
{
|
||||
//{{AFX_DATA_INIT(DialogToolbarClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
void DialogToolbarClass::AssertValid() const
|
||||
{
|
||||
CToolBar::AssertValid();
|
||||
}
|
||||
|
||||
void DialogToolbarClass::Dump(CDumpContext& dc) const
|
||||
{
|
||||
CToolBar::Dump(dc);
|
||||
}
|
||||
#endif //_DEBUG
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Enable_Button
|
||||
//
|
||||
void
|
||||
DialogToolbarClass::Enable_Button
|
||||
(
|
||||
int id,
|
||||
bool benable
|
||||
)
|
||||
{
|
||||
// Get the button's style (we enable by using a style bit)
|
||||
int index = CommandToIndex (id);
|
||||
UINT style = GetButtonStyle (index) & (~TBBS_DISABLED);
|
||||
|
||||
// If we are disabling the button, set the
|
||||
// disabled style bit.
|
||||
if (benable == false) {
|
||||
style |= TBBS_DISABLED;
|
||||
style &= ~TBBS_PRESSED;
|
||||
}
|
||||
|
||||
// If the button isn't a separator, then modify its style
|
||||
if (!(style & TBBS_SEPARATOR)) {
|
||||
SetButtonStyle (index, style);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnIdleUpdateCmdUI
|
||||
//
|
||||
LRESULT
|
||||
DialogToolbarClass::OnIdleUpdateCmdUI (WPARAM, LPARAM)
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitialUpdate
|
||||
//
|
||||
void
|
||||
DialogToolbarClass::OnInitialUpdate (void)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
BOOL
|
||||
DialogToolbarClass::OnNeedToolTipText
|
||||
(
|
||||
UINT id,
|
||||
NMHDR *pTTTStruct,
|
||||
LRESULT *pResult
|
||||
)
|
||||
{
|
||||
if (pTTTStruct->code == TTN_NEEDTEXTA) {
|
||||
|
||||
TOOLTIPTEXTA *ptooltip_info = (TOOLTIPTEXTA*)pTTTStruct;
|
||||
::lstrcpy (ptooltip_info->szText, "test");
|
||||
}
|
||||
|
||||
(*pResult) = 0L;
|
||||
return TRUE;
|
||||
}
|
||||
105
Code/Tools/W3DView/DialogToolbar.h
Normal file
105
Code/Tools/W3DView/DialogToolbar.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : LevelEdit *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/W3DView/DialogToolbar.h $*
|
||||
* *
|
||||
* Author:: Patrick Smith *
|
||||
* *
|
||||
* $Modtime:: 2/23/99 10:58a $*
|
||||
* *
|
||||
* $Revision:: 1 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __DIALOGTOOLBAR_H
|
||||
#define __DIALOGTOOLBAR_H
|
||||
|
||||
#include "Resource.H"
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DialogToolbarClass
|
||||
//
|
||||
class DialogToolbarClass : public CToolBar
|
||||
{
|
||||
public:
|
||||
DialogToolbarClass (void);
|
||||
virtual ~DialogToolbarClass (void) {}
|
||||
|
||||
// Form Data
|
||||
public:
|
||||
//{{AFX_DATA(DialogToolbarClass)
|
||||
//}}AFX_DATA
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(DialogToolbarClass)
|
||||
protected:
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
#ifdef _DEBUG
|
||||
virtual void AssertValid() const;
|
||||
virtual void Dump(CDumpContext& dc) const;
|
||||
#endif
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(DialogToolbarClass)
|
||||
afx_msg LRESULT OnIdleUpdateCmdUI(WPARAM wParam, LPARAM lParam);
|
||||
afx_msg void OnInitialUpdate();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
//virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
BOOL OnNeedToolTipText (UINT id, NMHDR *pTTTStruct, LRESULT *pResult);
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
void Enable_Button (int id, bool benable = true);
|
||||
};
|
||||
|
||||
|
||||
#endif //__DIALOGTOOLBAR_H
|
||||
|
||||
104
Code/Tools/W3DView/DirectoryDialog.cpp
Normal file
104
Code/Tools/W3DView/DirectoryDialog.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : W3DView *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/W3DView/DirectoryDialog.cpp $*
|
||||
* *
|
||||
* Author:: Patrick Smith *
|
||||
* *
|
||||
* $Modtime:: 1/25/00 2:56p $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "directorydialog.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Browse_For_Folder_Hook_Proc
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
UINT CALLBACK Browse_For_Folder_Hook_Proc
|
||||
(
|
||||
HWND hdlg,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam
|
||||
)
|
||||
{
|
||||
//
|
||||
// If the user clicked OK, then stuff a dummy filename
|
||||
// into the control so the dialog will close...
|
||||
//
|
||||
if ( message == WM_COMMAND &&
|
||||
LOWORD (wparam) == IDOK &&
|
||||
HIWORD (wparam) == BN_CLICKED)
|
||||
{
|
||||
::SetDlgItemText (hdlg, 1152, "xxx.xxx");
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Browse_For_Folder
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
Browse_For_Folder (HWND parent_wnd, LPCTSTR initial_path, CString &path)
|
||||
{
|
||||
bool retval = false;
|
||||
|
||||
OPENFILENAME openfilename = { sizeof (OPENFILENAME), 0 };
|
||||
TCHAR filename[MAX_PATH] = { 0 };
|
||||
|
||||
openfilename.lpstrInitialDir = initial_path;
|
||||
openfilename.hwndOwner = parent_wnd;
|
||||
openfilename.hInstance = ::AfxGetResourceHandle ();
|
||||
openfilename.lpstrFilter = _T("\0\0");
|
||||
openfilename.lpstrFile = filename;
|
||||
openfilename.nMaxFile = sizeof (filename);
|
||||
openfilename.lpstrTitle = _T("Choose Directory");
|
||||
openfilename.lpfnHook = Browse_For_Folder_Hook_Proc;
|
||||
openfilename.lpTemplateName = MAKEINTRESOURCE (1536);
|
||||
openfilename.Flags = OFN_HIDEREADONLY | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK | OFN_LONGNAMES;
|
||||
|
||||
//
|
||||
// Display the modified 'file-open' dialog.
|
||||
//
|
||||
if (::GetOpenFileName (&openfilename) == IDOK) {
|
||||
path = ::Strip_Filename_From_Path (filename);
|
||||
retval = true;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
55
Code/Tools/W3DView/DirectoryDialog.h
Normal file
55
Code/Tools/W3DView/DirectoryDialog.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : W3DView *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/W3DView/DirectoryDialog.h $*
|
||||
* *
|
||||
* Author:: Patrick Smith *
|
||||
* *
|
||||
* $Modtime:: 1/25/00 2:52p $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef __DIRECTORY_DIALOG_H
|
||||
#define __DIRECTORY_DIALOG_H
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Prototypes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
bool Browse_For_Folder (HWND parent_wnd, LPCTSTR initial_path, CString &path);
|
||||
|
||||
|
||||
#endif //__DIRECTORY_DIALOG_H
|
||||
|
||||
504
Code/Tools/W3DView/EditLODDialog.cpp
Normal file
504
Code/Tools/W3DView/EditLODDialog.cpp
Normal file
@@ -0,0 +1,504 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// EditLODDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "W3DView.h"
|
||||
#include "EditLODDialog.h"
|
||||
#include "DistLod.H"
|
||||
#include "Utils.H"
|
||||
#include "RendObj.H"
|
||||
#include "W3DViewDoc.H"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Constants
|
||||
//
|
||||
const int COL_NAME = 0;
|
||||
const int COL_SWITCH_UP = 1;
|
||||
const int COL_SWITCH_DN = 2;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CEditLODDialog
|
||||
//
|
||||
CEditLODDialog::CEditLODDialog(CWnd* pParent /*=NULL*/)
|
||||
: m_spinIncrement (0.5F),
|
||||
CDialog(CEditLODDialog::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CEditLODDialog)
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
CEditLODDialog::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::DoDataExchange(pDX);
|
||||
|
||||
//{{AFX_DATA_MAP(CEditLODDialog)
|
||||
DDX_Control(pDX, IDC_SWITCH_UP_SPIN, m_switchUpSpin);
|
||||
DDX_Control(pDX, IDC_SWITCH_DN_SPIN, m_switchDownSpin);
|
||||
DDX_Control(pDX, IDC_HIERARCHY_LIST, m_hierarchyListCtrl);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CEditLODDialog, CDialog)
|
||||
//{{AFX_MSG_MAP(CEditLODDialog)
|
||||
ON_NOTIFY(UDN_DELTAPOS, IDC_SWITCH_UP_SPIN, OnDeltaposSwitchUpSpin)
|
||||
ON_NOTIFY(UDN_DELTAPOS, IDC_SWITCH_DN_SPIN, OnDeltaposSwitchDnSpin)
|
||||
ON_NOTIFY(LVN_ITEMCHANGED, IDC_HIERARCHY_LIST, OnItemChangedHierarchyList)
|
||||
ON_EN_UPDATE(IDC_SWITCH_DN_EDIT, OnUpdateSwitchDnEdit)
|
||||
ON_EN_UPDATE(IDC_SWITCH_UP_EDIT, OnUpdateSwitchUpEdit)
|
||||
ON_BN_CLICKED(IDC_RECALC, OnRecalc)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
CEditLODDialog::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnInitDialog ();
|
||||
|
||||
// Center the dialog around the data tree view instead
|
||||
// of the direct center of the screen
|
||||
::CenterDialogAroundTreeView (m_hWnd);
|
||||
|
||||
// Get a pointer to the doc
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
// Get the current LOD from the doc
|
||||
DistLODClass *pLOD = (DistLODClass *)pCDoc->GetDisplayedObject ();
|
||||
ASSERT (pLOD);
|
||||
if (pLOD)
|
||||
{
|
||||
int iSubObjects = pLOD->Get_Num_Sub_Objects ();
|
||||
|
||||
// Add the columns to the list control
|
||||
m_hierarchyListCtrl.InsertColumn (COL_NAME, "Name");
|
||||
m_hierarchyListCtrl.InsertColumn (COL_SWITCH_UP, "Switch Up");
|
||||
m_hierarchyListCtrl.InsertColumn (COL_SWITCH_DN, "Switch Down");
|
||||
|
||||
RenderObjClass *pfirst_subobj = pLOD->Get_Sub_Object (0);
|
||||
if (pfirst_subobj != NULL) {
|
||||
m_spinIncrement = pfirst_subobj->Get_Bounding_Sphere ().Radius / 5.0F;
|
||||
MEMBER_RELEASE (pfirst_subobj);
|
||||
}
|
||||
|
||||
// Loop through all the subobjects
|
||||
for (int iObject = 0;
|
||||
(iObject < iSubObjects);
|
||||
iObject ++)
|
||||
{
|
||||
// Get this subobject
|
||||
RenderObjClass *pCSubObject = pLOD->Get_Sub_Object (iObject);
|
||||
if (pCSubObject)
|
||||
{
|
||||
// Add this object to the list
|
||||
int iIndex = m_hierarchyListCtrl.InsertItem (COL_NAME, pCSubObject->Get_Name ());
|
||||
|
||||
CString stringTemp;
|
||||
stringTemp.Format ("%.2f", pLOD->Get_Switch_Up_Dist (iObject));
|
||||
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_UP, stringTemp);
|
||||
|
||||
stringTemp.Format ("%.2f", pLOD->Get_Switch_Down_Dist (iObject));
|
||||
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_DN, stringTemp);
|
||||
|
||||
// Free this object
|
||||
MEMBER_RELEASE (pCSubObject);
|
||||
}
|
||||
}
|
||||
|
||||
m_switchUpSpin.SetRange (-20, UD_MAXVAL-20);
|
||||
m_switchDownSpin.SetRange (-20, UD_MAXVAL-20);
|
||||
|
||||
// Resize the columns so they are wide enough to display the largest string
|
||||
m_hierarchyListCtrl.SetColumnWidth (COL_NAME, LVSCW_AUTOSIZE);
|
||||
m_hierarchyListCtrl.SetColumnWidth (COL_SWITCH_UP, LVSCW_AUTOSIZE_USEHEADER);
|
||||
m_hierarchyListCtrl.SetColumnWidth (COL_SWITCH_DN, LVSCW_AUTOSIZE_USEHEADER);
|
||||
|
||||
// Select the first item in the list
|
||||
m_hierarchyListCtrl.SetItemState (0, LVIS_SELECTED, LVIS_SELECTED);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnOK
|
||||
//
|
||||
void
|
||||
CEditLODDialog::OnOK (void)
|
||||
{
|
||||
|
||||
// Get a pointer to the doc
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
// Get the current LOD from the doc
|
||||
DistLODClass *pLOD = (DistLODClass *)pCDoc->GetDisplayedObject ();
|
||||
ASSERT (pLOD);
|
||||
if (pLOD)
|
||||
{
|
||||
int iSubObjects = pLOD->Get_Num_Sub_Objects ();
|
||||
|
||||
// Loop through all the subobjects and add them to the list control
|
||||
for (int iObject = 0;
|
||||
(iObject < iSubObjects);
|
||||
iObject ++)
|
||||
{
|
||||
// Get the switch up distance from the list control
|
||||
CString stringTemp = m_hierarchyListCtrl.GetItemText (iObject, COL_SWITCH_UP);
|
||||
|
||||
// Convert the string to a float and pass this value
|
||||
// onto the LOD manager
|
||||
float switchDistance = ::atof (stringTemp);
|
||||
pLOD->Set_Switch_Up_Dist (iObject, switchDistance);
|
||||
|
||||
// Get the switch down distance from the list control
|
||||
stringTemp = m_hierarchyListCtrl.GetItemText (iObject, COL_SWITCH_DN);
|
||||
|
||||
// Convert the string to a float and pass this value
|
||||
// onto the LOD manager
|
||||
switchDistance = ::atof (stringTemp);
|
||||
pLOD->Set_Switch_Down_Dist (iObject, switchDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnOK ();
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCancel
|
||||
//
|
||||
void
|
||||
CEditLODDialog::OnCancel (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CDialog::OnCancel ();
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnDeltaposSwitchUpSpin
|
||||
//
|
||||
void
|
||||
CEditLODDialog::OnDeltaposSwitchUpSpin
|
||||
(
|
||||
NMHDR* pNMHDR,
|
||||
LRESULT* pResult
|
||||
)
|
||||
{
|
||||
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||||
if (pNMUpDown)
|
||||
{
|
||||
float newVal = float(pNMUpDown->iPos) / 10.00F;
|
||||
|
||||
// Change the switching distance in the edit control
|
||||
CString stringTemp;
|
||||
stringTemp.Format ("%.2f", newVal);
|
||||
SetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp);
|
||||
|
||||
// Find the selected item in the list control
|
||||
int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
|
||||
if (iIndex != -1)
|
||||
{
|
||||
// Change the switching distance in the list control
|
||||
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_UP, stringTemp);
|
||||
}
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnDeltaposSwitchDnSpin
|
||||
//
|
||||
void
|
||||
CEditLODDialog::OnDeltaposSwitchDnSpin
|
||||
(
|
||||
NMHDR* pNMHDR,
|
||||
LRESULT* pResult
|
||||
)
|
||||
{
|
||||
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||||
if (pNMUpDown)
|
||||
{
|
||||
float newVal = float(pNMUpDown->iPos) / 10.00F;
|
||||
|
||||
// Change the switching distance in the edit control
|
||||
CString stringTemp;
|
||||
stringTemp.Format ("%.2f", newVal);
|
||||
SetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp);
|
||||
|
||||
// Find the selected item in the list control
|
||||
int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
|
||||
if (iIndex != -1)
|
||||
{
|
||||
// Change the switching distance in the list control
|
||||
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_DN, stringTemp);
|
||||
}
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnItemChangedHierarchyList
|
||||
//
|
||||
void
|
||||
CEditLODDialog::OnItemChangedHierarchyList
|
||||
(
|
||||
NMHDR* pNMHDR,
|
||||
LRESULT* pResult
|
||||
)
|
||||
{
|
||||
// Did the 'state' of the entry change?
|
||||
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
|
||||
if (pNMListView &&
|
||||
(pNMListView->uChanged & LVIF_STATE) == LVIF_STATE)
|
||||
{
|
||||
|
||||
if ((pNMListView->uNewState & LVIS_SELECTED) != LVIS_SELECTED)
|
||||
{
|
||||
// Is there a selected item in the list control?
|
||||
if (m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED) == -1)
|
||||
{
|
||||
// Disabled the edit and spin controls
|
||||
EnableControls (FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Enable the edit and spin controls
|
||||
EnableControls (TRUE);
|
||||
|
||||
// Load the control with data for the selected item.
|
||||
ResetControls (pNMListView->iItem);
|
||||
}
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ResetControls
|
||||
//
|
||||
void
|
||||
CEditLODDialog::ResetControls (int iIndex)
|
||||
{
|
||||
//
|
||||
// Set the text of the group box
|
||||
//
|
||||
CString stringTemp = m_hierarchyListCtrl.GetItemText (iIndex, COL_NAME);
|
||||
|
||||
// Set the text of the group box
|
||||
CString stringTitle;
|
||||
stringTitle.Format ("Settings (%s)", (LPCTSTR)stringTemp);
|
||||
SetDlgItemText (IDC_SETTINGS_GROUP, stringTitle);
|
||||
|
||||
//
|
||||
// Reset the switch up controls
|
||||
//
|
||||
|
||||
// Get the switch up distance from the list control
|
||||
stringTemp = m_hierarchyListCtrl.GetItemText (iIndex, COL_SWITCH_UP);
|
||||
|
||||
// Set the text of the edit control to reflect the switching distance
|
||||
SetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp);
|
||||
|
||||
// Set the current position of the spin control
|
||||
float switchDistance = ::atof (stringTemp);
|
||||
m_switchUpSpin.SetPos (int(switchDistance * 10.00F));
|
||||
|
||||
//
|
||||
// Reset the switch down controls
|
||||
//
|
||||
|
||||
// Get the switch down distance from the list control
|
||||
stringTemp = m_hierarchyListCtrl.GetItemText (iIndex, COL_SWITCH_DN);
|
||||
|
||||
// Set the text of the edit control to reflect the switching distance
|
||||
SetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp);
|
||||
|
||||
// Set the current position of the spin control
|
||||
switchDistance = ::atof (stringTemp);
|
||||
m_switchDownSpin.SetPos (int(switchDistance * 10.00F));
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EnableControls
|
||||
//
|
||||
void
|
||||
CEditLODDialog::EnableControls (BOOL bEnable)
|
||||
{
|
||||
// Enable or disable the windows
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_SETTINGS_GROUP), bEnable);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_UP_SPIN), bEnable);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_UP_EDIT), bEnable);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_DN_SPIN), bEnable);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_DN_EDIT), bEnable);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_RECALC), bEnable);
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnUpdateSwitchDnEdit
|
||||
//
|
||||
void
|
||||
CEditLODDialog::OnUpdateSwitchDnEdit (void)
|
||||
{
|
||||
// Get the switching distance from the edit control
|
||||
CString stringTemp;
|
||||
GetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp);
|
||||
float newVal = ::atof (stringTemp);
|
||||
|
||||
// Change the switching distance in the spin control
|
||||
m_switchDownSpin.SetPos (int(newVal * 10.00F));
|
||||
|
||||
// Find the selected item in the list control
|
||||
int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
|
||||
if (iIndex != -1)
|
||||
{
|
||||
// Change the switching distance in the list control
|
||||
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_DN, stringTemp);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnUpdateSwitchUpEdit
|
||||
//
|
||||
void CEditLODDialog::OnUpdateSwitchUpEdit (void)
|
||||
{
|
||||
// Get the switching distance from the edit control
|
||||
CString stringTemp;
|
||||
GetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp);
|
||||
float newVal = ::atof (stringTemp);
|
||||
|
||||
// Change the switching distance in the spin control
|
||||
m_switchUpSpin.SetPos (int(newVal * 10.00F));
|
||||
|
||||
// Find the selected item in the list control
|
||||
int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
|
||||
if (iIndex != -1)
|
||||
{
|
||||
// Change the switching distance in the list control
|
||||
m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_UP, stringTemp);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnRecalc
|
||||
//
|
||||
void CEditLODDialog::OnRecalc (void)
|
||||
{
|
||||
// Get the up switching distance from the edit control
|
||||
CString stringTemp;
|
||||
GetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp);
|
||||
float switchUp = ::atof (stringTemp);
|
||||
|
||||
// Get the down switching distance from the edit control
|
||||
stringTemp;
|
||||
GetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp);
|
||||
float switchDown = ::atof (stringTemp);
|
||||
|
||||
if (switchUp < switchDown)
|
||||
{
|
||||
// Calculate the current range
|
||||
float switchDelta = switchDown - switchUp;
|
||||
float switchOverlap = switchDelta * 0.1F;
|
||||
|
||||
// Get a pointer to the doc
|
||||
CW3DViewDoc *pCDoc = ::GetCurrentDocument ();
|
||||
if (pCDoc)
|
||||
{
|
||||
// Get the current LOD from the doc
|
||||
DistLODClass *pLOD = (DistLODClass *)pCDoc->GetDisplayedObject ();
|
||||
ASSERT (pLOD);
|
||||
if (pLOD)
|
||||
{
|
||||
int iSubObjects = pLOD->Get_Num_Sub_Objects ();
|
||||
switchUp = switchDown - switchOverlap;
|
||||
|
||||
// Loop through all the subobjects (following the highlighted one)
|
||||
for (int iObject = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED) + 1;
|
||||
(iObject < iSubObjects);
|
||||
iObject ++)
|
||||
{
|
||||
// Set the text of the switch up column
|
||||
CString stringTemp;
|
||||
stringTemp.Format ("%.2f", switchUp);
|
||||
m_hierarchyListCtrl.SetItemText (iObject, COL_SWITCH_UP, stringTemp);
|
||||
|
||||
// Set the text of the switch dn column
|
||||
stringTemp.Format ("%.2f", switchUp+switchDelta);
|
||||
m_hierarchyListCtrl.SetItemText (iObject, COL_SWITCH_DN, stringTemp);
|
||||
|
||||
// Add the range to the switch up distance
|
||||
switchUp += switchDelta-switchOverlap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
82
Code/Tools/W3DView/EditLODDialog.h
Normal file
82
Code/Tools/W3DView/EditLODDialog.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
** 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_EDITLODDIALOG_H__AF3CDE8E_61EC_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
#define AFX_EDITLODDIALOG_H__AF3CDE8E_61EC_11D2_9FC7_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// EditLODDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CEditLODDialog dialog
|
||||
|
||||
class CEditLODDialog : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CEditLODDialog(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CEditLODDialog)
|
||||
enum { IDD = IDD_EDIT_LOD };
|
||||
CSpinButtonCtrl m_switchUpSpin;
|
||||
CSpinButtonCtrl m_switchDownSpin;
|
||||
CListCtrl m_hierarchyListCtrl;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CEditLODDialog)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CEditLODDialog)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
virtual void OnCancel();
|
||||
afx_msg void OnDeltaposSwitchUpSpin(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnDeltaposSwitchDnSpin(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnItemChangedHierarchyList(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnUpdateSwitchDnEdit();
|
||||
afx_msg void OnUpdateSwitchUpEdit();
|
||||
afx_msg void OnRecalc();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
protected:
|
||||
void ResetControls (int iIndex);
|
||||
void EnableControls (BOOL bEnable);
|
||||
|
||||
private:
|
||||
float m_spinIncrement;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EDITLODDIALOG_H__AF3CDE8E_61EC_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
672
Code/Tools/W3DView/EmitterColorPropPage.cpp
Normal file
672
Code/Tools/W3DView/EmitterColorPropPage.cpp
Normal file
@@ -0,0 +1,672 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// EmitterColorPropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "emittercolorproppage.h"
|
||||
#include "part_emt.h"
|
||||
#include "utils.h"
|
||||
#include "opacitysettingsdialog.h"
|
||||
#include "colorutils.h"
|
||||
#include "emitterinstancelist.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterColorPropPageClass property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(EmitterColorPropPageClass, CPropertyPage)
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterColorPropPageClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
EmitterColorPropPageClass::EmitterColorPropPageClass (EmitterInstanceListClass *pemitter)
|
||||
: m_pEmitterList (NULL),
|
||||
m_bValid (true),
|
||||
m_ColorBar (NULL),
|
||||
m_OpacityBar (NULL),
|
||||
m_Lifetime (0),
|
||||
CPropertyPage (EmitterColorPropPageClass::IDD)
|
||||
{
|
||||
|
||||
::memset (&m_OrigColors, 0, sizeof (m_OrigColors));
|
||||
::memset (&m_OrigOpacities, 0, sizeof (m_OrigOpacities));
|
||||
::memset (&m_CurrentColors, 0, sizeof (m_CurrentColors));
|
||||
::memset (&m_CurrentOpacities, 0, sizeof (m_CurrentOpacities));
|
||||
|
||||
//{{AFX_DATA_INIT(EmitterColorPropPageClass)
|
||||
//}}AFX_DATA_INIT
|
||||
Initialize ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~EmitterColorPropPageClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
EmitterColorPropPageClass::~EmitterColorPropPageClass (void)
|
||||
{
|
||||
// Free the original setting arrays
|
||||
SAFE_DELETE_ARRAY (m_OrigColors.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_OrigColors.Values);
|
||||
SAFE_DELETE_ARRAY (m_OrigOpacities.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_OrigOpacities.Values);
|
||||
|
||||
// Free the current setting arrays
|
||||
SAFE_DELETE_ARRAY (m_CurrentColors.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_CurrentColors.Values);
|
||||
SAFE_DELETE_ARRAY (m_CurrentOpacities.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_CurrentOpacities.Values);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterColorPropPageClass::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(EmitterColorPropPageClass)
|
||||
DDX_Control(pDX, IDC_OPACITY_RANDOM_SPIN, m_OpacityRandomSpin);
|
||||
DDX_Control(pDX, IDC_RED_RANDOM_SPIN, m_RedRandomSpin);
|
||||
DDX_Control(pDX, IDC_GREEN_RANDOM_SPIN, m_GreenRandomSpin);
|
||||
DDX_Control(pDX, IDC_BLUE_RANDOM_SPIN, m_BlueRandomSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(EmitterColorPropPageClass, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(EmitterColorPropPageClass)
|
||||
ON_WM_DESTROY()
|
||||
ON_NOTIFY(UDN_DELTAPOS, IDC_RED_RANDOM_SPIN, OnDeltaposRedRandomSpin)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterColorPropPageClass::Initialize (void)
|
||||
{
|
||||
SAFE_DELETE_ARRAY (m_OrigColors.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_OrigColors.Values);
|
||||
SAFE_DELETE_ARRAY (m_OrigOpacities.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_OrigOpacities.Values);
|
||||
SAFE_DELETE_ARRAY (m_CurrentColors.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_CurrentColors.Values);
|
||||
SAFE_DELETE_ARRAY (m_CurrentOpacities.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_CurrentOpacities.Values);
|
||||
|
||||
if (m_pEmitterList != NULL) {
|
||||
|
||||
m_Lifetime = m_pEmitterList->Get_Lifetime ();
|
||||
|
||||
//
|
||||
// Get the initial values from the emitter
|
||||
//
|
||||
m_pEmitterList->Get_Color_Keyframes (m_OrigColors);
|
||||
m_pEmitterList->Get_Color_Keyframes (m_CurrentColors);
|
||||
m_pEmitterList->Get_Opacity_Keyframes (m_OrigOpacities);
|
||||
m_pEmitterList->Get_Opacity_Keyframes (m_CurrentOpacities);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterColorPropPageClass::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::OnInitDialog ();
|
||||
|
||||
m_ColorBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_COLOR_BAR));
|
||||
m_OpacityBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_OPACITY_BAR));
|
||||
|
||||
//
|
||||
// Setup the color bars
|
||||
//
|
||||
m_ColorBar->Set_Range (0, 1);
|
||||
m_OpacityBar->Set_Range (0, 1);
|
||||
m_OpacityBar->Modify_Point (0, 0, 255, 255, 255);
|
||||
|
||||
//
|
||||
// Setup the spinners
|
||||
//
|
||||
m_OpacityRandomSpin.SetRange (0, 100);
|
||||
m_RedRandomSpin.SetRange (0, 255);
|
||||
m_GreenRandomSpin.SetRange (0, 255);
|
||||
m_BlueRandomSpin.SetRange (0, 255);
|
||||
|
||||
m_OpacityRandomSpin.SetPos (m_OrigOpacities.Rand * 100);
|
||||
m_RedRandomSpin.SetPos (m_OrigColors.Rand.X * 255);
|
||||
m_GreenRandomSpin.SetPos (m_OrigColors.Rand.Y * 255);
|
||||
m_BlueRandomSpin.SetPos (m_OrigColors.Rand.Z * 255);
|
||||
|
||||
//
|
||||
// Reset the color bars
|
||||
//
|
||||
m_ColorBar->Clear_Points ();
|
||||
m_OpacityBar->Clear_Points ();
|
||||
m_ColorBar->Modify_Point (0, 0, m_OrigColors.Start.X * 255, m_OrigColors.Start.Y * 255, m_OrigColors.Start.Z * 255);
|
||||
m_OpacityBar->Modify_Point (0, 0, m_OrigOpacities.Start * 255, m_OrigOpacities.Start * 255, m_OrigOpacities.Start * 255);
|
||||
|
||||
//
|
||||
// Setup the ranges
|
||||
//
|
||||
m_ColorBar->Set_Range (0, 1);
|
||||
m_OpacityBar->Set_Range (0, 1);
|
||||
|
||||
//
|
||||
// Set-up the color bar
|
||||
//
|
||||
for (UINT index = 0; index < m_OrigColors.NumKeyFrames; index ++) {
|
||||
m_ColorBar->Modify_Point (index + 1,
|
||||
m_OrigColors.KeyTimes[index] / m_Lifetime,
|
||||
m_OrigColors.Values[index].X * 255,
|
||||
m_OrigColors.Values[index].Y * 255,
|
||||
m_OrigColors.Values[index].Z * 255);
|
||||
}
|
||||
|
||||
//
|
||||
// Set-up the opacity bar
|
||||
//
|
||||
for (index = 0; index < m_OrigOpacities.NumKeyFrames; index ++) {
|
||||
m_OpacityBar->Modify_Point (index + 1,
|
||||
m_OrigOpacities.KeyTimes[index] / m_Lifetime,
|
||||
m_OrigOpacities.Values[index] * 255,
|
||||
m_OrigOpacities.Values[index] * 255,
|
||||
m_OrigOpacities.Values[index] * 255);
|
||||
}
|
||||
|
||||
//
|
||||
// Ensure our initial 'current' values are up-to-date
|
||||
//
|
||||
m_CurrentColors.Rand = m_OrigColors.Rand;
|
||||
m_CurrentOpacities.Rand = m_OrigOpacities.Rand;
|
||||
Update_Colors ();
|
||||
Update_Opacities ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnApply
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterColorPropPageClass::OnApply (void)
|
||||
{
|
||||
/*SAFE_DELETE_ARRAY (m_OrigColors.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_OrigColors.Values);
|
||||
SAFE_DELETE_ARRAY (m_OrigOpacities.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_OrigOpacities.Values);
|
||||
|
||||
//
|
||||
// Make the current values from the emitter the default values.
|
||||
//
|
||||
m_pEmitter->Get_Color_Key_Frames (m_OrigColors);
|
||||
m_pEmitter->Get_Opacity_Key_Frames (m_OrigOpacities);*/
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertyPage::OnApply ();
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnDestroy
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterColorPropPageClass::OnDestroy (void)
|
||||
{
|
||||
CPropertyPage::OnDestroy();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterColorPropPageClass::OnNotify
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
LRESULT *pResult
|
||||
)
|
||||
{
|
||||
CBR_NMHDR *color_bar_hdr = (CBR_NMHDR *)lParam;
|
||||
|
||||
//
|
||||
// Which control sent the notification?
|
||||
//
|
||||
switch (color_bar_hdr->hdr.idFrom)
|
||||
{
|
||||
case IDC_OPACITY_BAR:
|
||||
{
|
||||
if (color_bar_hdr->hdr.code == CBRN_DBLCLK_POINT) {
|
||||
|
||||
//
|
||||
// Allow the user to edit the keyframe
|
||||
//
|
||||
OpacitySettingsDialogClass dialog (color_bar_hdr->red / 255, this);
|
||||
if (dialog.DoModal () == IDOK) {
|
||||
m_OpacityBar->Modify_Point (color_bar_hdr->key_index,
|
||||
color_bar_hdr->position,
|
||||
dialog.Get_Opacity () * 255,
|
||||
dialog.Get_Opacity () * 255,
|
||||
dialog.Get_Opacity () * 255);
|
||||
|
||||
// Update the emitter
|
||||
Update_Opacities ();
|
||||
m_pEmitterList->Set_Opacity_Keyframes (m_CurrentOpacities);
|
||||
SetModified ();
|
||||
}
|
||||
} else if ((color_bar_hdr->hdr.code == CBRN_MOVING_POINT) ||
|
||||
(color_bar_hdr->hdr.code == CBRN_DELETED_POINT)) {
|
||||
|
||||
// Update the emitter
|
||||
Update_Opacities ();
|
||||
m_pEmitterList->Set_Opacity_Keyframes (m_CurrentOpacities);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_COLOR_BAR:
|
||||
{
|
||||
if (color_bar_hdr->hdr.code == CBRN_DBLCLK_POINT) {
|
||||
|
||||
//
|
||||
// Allow the user to edit the keyframe
|
||||
//
|
||||
int red = (int)color_bar_hdr->red;
|
||||
int green = (int)color_bar_hdr->green;
|
||||
int blue = (int)color_bar_hdr->blue;
|
||||
if (Show_Color_Picker (&red, &green, &blue)) {
|
||||
m_ColorBar->Modify_Point (color_bar_hdr->key_index,
|
||||
color_bar_hdr->position,
|
||||
red,
|
||||
green,
|
||||
blue);
|
||||
|
||||
// Update the emitter
|
||||
Update_Colors ();
|
||||
m_pEmitterList->Set_Color_Keyframes (m_CurrentColors);
|
||||
SetModified ();
|
||||
}
|
||||
} else if ((color_bar_hdr->hdr.code == CBRN_MOVING_POINT) ||
|
||||
(color_bar_hdr->hdr.code == CBRN_DELETED_POINT)) {
|
||||
|
||||
// Update the emitter
|
||||
Update_Colors ();
|
||||
m_pEmitterList->Set_Color_Keyframes (m_CurrentColors);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_RED_RANDOM_SPIN:
|
||||
{
|
||||
// Update the emitter
|
||||
NMUPDOWN *pudnotif = (NMUPDOWN *)lParam;
|
||||
if (pudnotif->hdr.code == UDN_DELTAPOS) {
|
||||
float pos = (pudnotif->iPos + pudnotif->iDelta);
|
||||
m_CurrentColors.Rand.X = pos / 255.0F;
|
||||
m_pEmitterList->Set_Color_Keyframes (m_CurrentColors);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_GREEN_RANDOM_SPIN:
|
||||
{
|
||||
// Update the emitter
|
||||
NMUPDOWN *pudnotif = (NMUPDOWN *)lParam;
|
||||
if (pudnotif->hdr.code == UDN_DELTAPOS) {
|
||||
float pos = (pudnotif->iPos + pudnotif->iDelta);
|
||||
m_CurrentColors.Rand.Y = pos / 255.0F;
|
||||
m_pEmitterList->Set_Color_Keyframes (m_CurrentColors);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_BLUE_RANDOM_SPIN:
|
||||
{
|
||||
// Update the emitter
|
||||
NMUPDOWN *pudnotif = (NMUPDOWN *)lParam;
|
||||
if (pudnotif->hdr.code == UDN_DELTAPOS) {
|
||||
float pos = (pudnotif->iPos + pudnotif->iDelta);
|
||||
m_CurrentColors.Rand.Z = pos / 255.0F;
|
||||
m_pEmitterList->Set_Color_Keyframes (m_CurrentColors);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_OPACITY_RANDOM_SPIN:
|
||||
{
|
||||
// Update the emitter
|
||||
NMUPDOWN *pudnotif = (NMUPDOWN *)lParam;
|
||||
if (pudnotif->hdr.code == UDN_DELTAPOS) {
|
||||
float pos = (pudnotif->iPos + pudnotif->iDelta);
|
||||
m_CurrentOpacities.Rand = pos / 100.0F;
|
||||
m_pEmitterList->Set_Opacity_Keyframes (m_CurrentOpacities);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CPropertyPage::OnNotify(wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCancel
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterColorPropPageClass::OnCancel (void)
|
||||
{
|
||||
//
|
||||
// Reset the emitter to its original state
|
||||
//
|
||||
m_pEmitterList->Set_Color_Keyframes (m_OrigColors);
|
||||
m_pEmitterList->Set_Opacity_Keyframes (m_OrigOpacities);
|
||||
|
||||
CPropertyPage::OnCancel ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Opacities
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterColorPropPageClass::Update_Opacities (void)
|
||||
{
|
||||
float position = 0;
|
||||
float red = 0;
|
||||
float green = 0;
|
||||
float blue = 0;
|
||||
m_OpacityBar->Get_Point (0, &position, &red, &green, &blue);
|
||||
|
||||
//
|
||||
// Setup the initial or 'starting' opacity
|
||||
//
|
||||
m_CurrentOpacities.Start = red / 255;
|
||||
|
||||
//
|
||||
// Free the current setting arrays
|
||||
//
|
||||
SAFE_DELETE_ARRAY (m_CurrentOpacities.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_CurrentOpacities.Values);
|
||||
|
||||
//
|
||||
// Determine if we need to build the array of key frames or not
|
||||
//
|
||||
int count = m_OpacityBar->Get_Point_Count ();
|
||||
m_CurrentOpacities.NumKeyFrames = count - 1;
|
||||
if (count > 1) {
|
||||
m_CurrentOpacities.KeyTimes = new float[count - 1];
|
||||
m_CurrentOpacities.Values = new float[count - 1];
|
||||
|
||||
//
|
||||
// Get all the opacity key frames and add them to our structure
|
||||
//
|
||||
for (int index = 1; index < count; index ++) {
|
||||
m_OpacityBar->Get_Point (index, &position, &red, &green, &blue);
|
||||
m_CurrentOpacities.KeyTimes[index - 1] = position * m_Lifetime;
|
||||
m_CurrentOpacities.Values[index - 1] = red / 255;
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Colors
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterColorPropPageClass::Update_Colors (void)
|
||||
{
|
||||
float position = 0;
|
||||
float red = 0;
|
||||
float green = 0;
|
||||
float blue = 0;
|
||||
m_ColorBar->Get_Point (0, &position, &red, &green, &blue);
|
||||
|
||||
//
|
||||
// Setup the initial or 'starting' color
|
||||
//
|
||||
m_CurrentColors.Start.X = red / 255;
|
||||
m_CurrentColors.Start.Y = green / 255;
|
||||
m_CurrentColors.Start.Z = blue / 255;
|
||||
|
||||
//
|
||||
// Free the current setting arrays
|
||||
//
|
||||
SAFE_DELETE_ARRAY (m_CurrentColors.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_CurrentColors.Values);
|
||||
|
||||
//
|
||||
// Determine if we need to build the array of key frames or not
|
||||
//
|
||||
int count = m_ColorBar->Get_Point_Count ();
|
||||
m_CurrentColors.NumKeyFrames = count - 1;
|
||||
if (count > 1) {
|
||||
m_CurrentColors.KeyTimes = new float[count - 1];
|
||||
m_CurrentColors.Values = new Vector3[count - 1];
|
||||
|
||||
//
|
||||
// Get all the color points and add them to our structure
|
||||
//
|
||||
for (int index = 1; index < count; index ++) {
|
||||
m_ColorBar->Get_Point (index, &position, &red, &green, &blue);
|
||||
m_CurrentColors.KeyTimes[index-1] = position * m_Lifetime;
|
||||
m_CurrentColors.Values[index-1].X = red / 255;
|
||||
m_CurrentColors.Values[index-1].Y = green / 255;
|
||||
m_CurrentColors.Values[index-1].Z = blue / 255;
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCommand
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterColorPropPageClass::OnCommand
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
switch (LOWORD (wParam))
|
||||
{
|
||||
case IDC_RED_RANDOM_EDIT:
|
||||
{
|
||||
if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY)) {
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
|
||||
m_CurrentColors.Rand.X = ((float)GetDlgItemInt (IDC_RED_RANDOM_EDIT)) / 255;
|
||||
m_pEmitterList->Set_Color_Keyframes (m_CurrentColors);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_GREEN_RANDOM_EDIT:
|
||||
{
|
||||
if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY)) {
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
|
||||
m_CurrentColors.Rand.Y = ((float)GetDlgItemInt (IDC_GREEN_RANDOM_EDIT)) / 255;
|
||||
m_pEmitterList->Set_Color_Keyframes (m_CurrentColors);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_BLUE_RANDOM_EDIT:
|
||||
{
|
||||
if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY)) {
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
|
||||
m_CurrentColors.Rand.Z = ((float)GetDlgItemInt (IDC_BLUE_RANDOM_EDIT)) / 255;
|
||||
m_pEmitterList->Set_Color_Keyframes (m_CurrentColors);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_OPACITY_RANDOM_EDIT:
|
||||
{
|
||||
if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY)) {
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
|
||||
m_CurrentOpacities.Rand = ((float)GetDlgItemInt (IDC_OPACITY_RANDOM_EDIT)) / 100;
|
||||
m_pEmitterList->Set_Opacity_Keyframes (m_CurrentOpacities);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CPropertyPage::OnCommand (wParam, lParam);
|
||||
}
|
||||
|
||||
void EmitterColorPropPageClass::OnDeltaposRedRandomSpin(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
|
||||
// TODO: Add your control notification handler code here
|
||||
int test = 0;
|
||||
|
||||
*pResult = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// On_Lifetime_Changed
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterColorPropPageClass::On_Lifetime_Changed (float lifetime)
|
||||
{
|
||||
if (m_Lifetime != lifetime) {
|
||||
float conversion = lifetime / m_Lifetime;
|
||||
|
||||
//
|
||||
// Rescale the colors
|
||||
//
|
||||
for (UINT index = 0; index < m_CurrentColors.NumKeyFrames; index ++) {
|
||||
m_CurrentColors.KeyTimes[index] *= conversion;
|
||||
}
|
||||
|
||||
//
|
||||
// Rescale the opacities
|
||||
//
|
||||
for (index = 0; index < m_CurrentOpacities.NumKeyFrames; index ++) {
|
||||
m_CurrentOpacities.KeyTimes[index] *= conversion;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
m_pEmitterList->Set_Color_Keyframes (m_CurrentColors);
|
||||
m_pEmitterList->Set_Opacity_Keyframes (m_CurrentOpacities);
|
||||
m_Lifetime = lifetime;
|
||||
/*if (m_hWnd != NULL) {
|
||||
Update_Colors ();
|
||||
Update_Opacities ();
|
||||
}*/
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
134
Code/Tools/W3DView/EmitterColorPropPage.h
Normal file
134
Code/Tools/W3DView/EmitterColorPropPage.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
** 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_EMITTERCOLORPROPPAGE_H__83A8B83F_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
#define AFX_EMITTERCOLORPROPPAGE_H__83A8B83F_BA3B_11D2_9FFA_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// EmitterColorPropPage.h : header file
|
||||
//
|
||||
|
||||
#include "Resource.H"
|
||||
#include "Vector3.H"
|
||||
#include "ColorBar.H"
|
||||
#include "Part_Emt.H"
|
||||
|
||||
// Forward declarations
|
||||
class EmitterInstanceListClass;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterColorPropPageClass dialog
|
||||
|
||||
class EmitterColorPropPageClass : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(EmitterColorPropPageClass)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
EmitterColorPropPageClass (EmitterInstanceListClass *pemitter_list = NULL);
|
||||
~EmitterColorPropPageClass ();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(EmitterColorPropPageClass)
|
||||
enum { IDD = IDD_PROP_PAGE_EMITTER_COLOR };
|
||||
CSpinButtonCtrl m_OpacityRandomSpin;
|
||||
CSpinButtonCtrl m_RedRandomSpin;
|
||||
CSpinButtonCtrl m_GreenRandomSpin;
|
||||
CSpinButtonCtrl m_BlueRandomSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(EmitterColorPropPageClass)
|
||||
public:
|
||||
virtual BOOL OnApply();
|
||||
virtual void OnCancel();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(EmitterColorPropPageClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnDestroy();
|
||||
afx_msg void OnDeltaposRedRandomSpin(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
//
|
||||
// Inline accessors
|
||||
//
|
||||
EmitterInstanceListClass * Get_Emitter (void) const { return m_pEmitterList; }
|
||||
void Set_Emitter (EmitterInstanceListClass *pemitter_list) { m_pEmitterList = pemitter_list; Initialize (); }
|
||||
bool Is_Data_Valid (void) const { return m_bValid; }
|
||||
|
||||
void Get_Color_Keyframes (ParticlePropertyStruct<Vector3> &colors) { colors = m_CurrentColors; }
|
||||
void Get_Opacity_Keyframes (ParticlePropertyStruct<float> &opacity) { opacity = m_CurrentOpacities; }
|
||||
/*const Vector3 & Get_Start_Color (void) const { return m_StartColor; }
|
||||
const Vector3 & Get_End_Color (void) const { return m_EndColor; }
|
||||
float Get_Start_Opacity (void) const { return m_StartOpacity; }
|
||||
float Get_End_Opacity (void) const { return m_EndOpacity; }
|
||||
float Get_Fade_Time (void) const { return m_FadeTime; }*/
|
||||
|
||||
void On_Lifetime_Changed (float lifetime);
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Initialize (void);
|
||||
void Update_Colors (void);
|
||||
void Update_Opacities (void);
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
EmitterInstanceListClass * m_pEmitterList;
|
||||
bool m_bValid;
|
||||
ColorBarClass * m_ColorBar;
|
||||
ColorBarClass * m_OpacityBar;
|
||||
ParticlePropertyStruct<Vector3> m_OrigColors;
|
||||
ParticlePropertyStruct<float> m_OrigOpacities;
|
||||
ParticlePropertyStruct<Vector3> m_CurrentColors;
|
||||
ParticlePropertyStruct<float> m_CurrentOpacities;
|
||||
float m_Lifetime;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EMITTERCOLORPROPPAGE_H__83A8B83F_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
420
Code/Tools/W3DView/EmitterFramePropPage.cpp
Normal file
420
Code/Tools/W3DView/EmitterFramePropPage.cpp
Normal file
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// EmitterFramePropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "EmitterFramePropPage.h"
|
||||
#include "Utils.H"
|
||||
#include "ParticleFrameKeyDialog.H"
|
||||
#include "EmitterInstanceList.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterFramePropPageClass property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(EmitterFramePropPageClass, CPropertyPage)
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterFramePropPageClass - constructor
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
EmitterFramePropPageClass::EmitterFramePropPageClass() :
|
||||
CPropertyPage(EmitterFramePropPageClass::IDD),
|
||||
m_pEmitterList(NULL),
|
||||
m_bValid(true),
|
||||
m_FrameBar(NULL),
|
||||
m_Lifetime(0),
|
||||
m_MinFrame(0),
|
||||
m_MaxFrame(1)
|
||||
{
|
||||
::memset (&m_Frames, 0, sizeof (m_Frames));
|
||||
|
||||
//{{AFX_DATA_INIT(EmitterFramePropPageClass)
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~EmitterFramePropPageClass - destructor
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
EmitterFramePropPageClass::~EmitterFramePropPageClass()
|
||||
{
|
||||
// Free the frame arrays
|
||||
SAFE_DELETE_ARRAY (m_Frames.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_Frames.Values);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void EmitterFramePropPageClass::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(EmitterFramePropPageClass)
|
||||
DDX_Control(pDX, IDC_FRAME_LAYOUT_COMBO, m_FrameLayoutCombo);
|
||||
DDX_Control(pDX, IDC_FRAME_RANDOM_SPIN, m_FrameRandomSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(EmitterFramePropPageClass, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(EmitterFramePropPageClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterFramePropPageClass::Initialize (void)
|
||||
{
|
||||
SAFE_DELETE_ARRAY (m_Frames.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_Frames.Values);
|
||||
|
||||
if (m_pEmitterList != NULL) {
|
||||
m_Lifetime = m_pEmitterList->Get_Lifetime ();
|
||||
m_pEmitterList->Get_Frame_Keyframes (m_Frames);
|
||||
|
||||
//
|
||||
// Determine what the min and max rotations are
|
||||
//
|
||||
m_MaxFrame = WWMath::Max(m_Frames.Start,1.0f);
|
||||
m_MinFrame = WWMath::Min(m_Frames.Start,0.0f);
|
||||
|
||||
for (UINT index = 0; index < m_Frames.NumKeyFrames; index ++) {
|
||||
if (m_Frames.Values[index] > m_MaxFrame) {
|
||||
m_MaxFrame = m_Frames.Values[index];
|
||||
}
|
||||
if (m_Frames.Values[index] < m_MinFrame) {
|
||||
m_MinFrame = m_Frames.Values[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterFramePropPageClass::OnInitDialog()
|
||||
{
|
||||
CPropertyPage::OnInitDialog();
|
||||
|
||||
//
|
||||
// Set the frame layout combo box
|
||||
//
|
||||
int mode = m_pEmitterList->Get_Frame_Mode();
|
||||
switch (mode) {
|
||||
case W3D_EMITTER_FRAME_MODE_1x1: m_FrameLayoutCombo.SetCurSel(0); break;
|
||||
case W3D_EMITTER_FRAME_MODE_2x2: m_FrameLayoutCombo.SetCurSel(1); break;
|
||||
case W3D_EMITTER_FRAME_MODE_4x4: m_FrameLayoutCombo.SetCurSel(2); break;
|
||||
case W3D_EMITTER_FRAME_MODE_8x8: m_FrameLayoutCombo.SetCurSel(3); break;
|
||||
case W3D_EMITTER_FRAME_MODE_16x16: m_FrameLayoutCombo.SetCurSel(4); break;
|
||||
default:
|
||||
m_FrameLayoutCombo.SetCurSel(4);
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the keyframe control
|
||||
//
|
||||
m_FrameBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_FRAME_BAR));
|
||||
|
||||
//
|
||||
// Setup the spinners
|
||||
//
|
||||
Initialize_Spinner (m_FrameRandomSpin, m_Frames.Rand, 0, 10000);
|
||||
|
||||
//
|
||||
// Reset the keyframe control
|
||||
//
|
||||
m_FrameBar->Set_Range (0, 1);
|
||||
m_FrameBar->Clear_Points ();
|
||||
m_FrameBar->Modify_Point (0, 0, 0, 0, 0);
|
||||
m_FrameBar->Set_Graph_Percent (0, Normalize_Frame(m_Frames.Start));
|
||||
|
||||
//
|
||||
// Load the current set of frame keyframes into the control
|
||||
//
|
||||
for (UINT index = 0; index < m_Frames.NumKeyFrames; index ++) {
|
||||
m_FrameBar->Modify_Point (index + 1,
|
||||
m_Frames.KeyTimes[index] / m_Lifetime,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
m_FrameBar->Set_Graph_Percent (index + 1, Normalize_Frame(m_Frames.Values[index]));
|
||||
}
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnApply
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL EmitterFramePropPageClass::OnApply()
|
||||
{
|
||||
return CPropertyPage::OnApply();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL EmitterFramePropPageClass::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
||||
{
|
||||
CBR_NMHDR *color_bar_hdr = (CBR_NMHDR *)lParam;
|
||||
|
||||
//
|
||||
// Update the spinner controls if necessary
|
||||
//
|
||||
NMHDR *pheader = (NMHDR *)lParam;
|
||||
if ((pheader != NULL) && (pheader->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN pupdown = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (pheader->hwndFrom, pupdown->iDelta);
|
||||
}
|
||||
|
||||
//
|
||||
// Which control sent the notification?
|
||||
//
|
||||
switch (color_bar_hdr->hdr.idFrom)
|
||||
{
|
||||
case IDC_FRAME_BAR:
|
||||
{
|
||||
if (color_bar_hdr->hdr.code == CBRN_DBLCLK_POINT) {
|
||||
|
||||
//
|
||||
// Allow the user to edit the keyframe
|
||||
//
|
||||
float frame = Denormalize_Frame(m_FrameBar->Get_Graph_Percent (color_bar_hdr->key_index));
|
||||
|
||||
ParticleFrameKeyDialogClass dialog (frame, this);
|
||||
if (dialog.DoModal () == IDOK) {
|
||||
frame = dialog.Get_Frame ();
|
||||
float norm_val = Normalize_Frame(frame);
|
||||
|
||||
m_FrameBar->Set_Redraw (false);
|
||||
m_FrameBar->Set_Graph_Percent (color_bar_hdr->key_index, norm_val);
|
||||
|
||||
//
|
||||
// Determine if the user changed the 'max' or 'min' frame
|
||||
//
|
||||
float new_max = WWMath::Max(frame,1.0f);
|
||||
float new_min = WWMath::Min(frame,0.0f);
|
||||
|
||||
int count = m_FrameBar->Get_Point_Count ();
|
||||
for (int index = 0; index < count; index ++) {
|
||||
float tmp = Denormalize_Frame(m_FrameBar->Get_Graph_Percent (index) );
|
||||
if (tmp > new_max) {
|
||||
new_max = tmp;
|
||||
}
|
||||
if (tmp < new_min) {
|
||||
new_min = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Renormalize the FrameBar key frame points if necessary
|
||||
//
|
||||
if ((new_max != m_MaxFrame) || (new_min != m_MinFrame)) {
|
||||
|
||||
int count = m_FrameBar->Get_Point_Count ();
|
||||
for (int index = 0; index < count; index ++) {
|
||||
|
||||
float frame = Denormalize_Frame(m_FrameBar->Get_Graph_Percent (index));
|
||||
float new_norm = Normalize_Frame(frame,new_min,new_max);
|
||||
|
||||
m_FrameBar->Set_Graph_Percent (index, new_norm);
|
||||
}
|
||||
|
||||
// Remember the new min and max
|
||||
m_MinFrame = new_min;
|
||||
m_MaxFrame = new_max;
|
||||
}
|
||||
m_FrameBar->Set_Redraw (true);
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
Update_Frames ();
|
||||
m_pEmitterList->Set_Frame_Keyframes (m_Frames);
|
||||
SetModified ();
|
||||
}
|
||||
} else if ((color_bar_hdr->hdr.code == CBRN_MOVING_POINT) ||
|
||||
(color_bar_hdr->hdr.code == CBRN_DELETED_POINT)) {
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
Update_Frames ();
|
||||
m_pEmitterList->Set_Frame_Keyframes (m_Frames);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_FRAME_RANDOM_SPIN:
|
||||
{
|
||||
// Update the emitter
|
||||
m_Frames.Rand = ::GetDlgItemFloat (m_hWnd, IDC_FRAME_RANDOM_EDIT);
|
||||
m_pEmitterList->Set_Frame_Keyframes (m_Frames);
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return CPropertyPage::OnNotify(wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Rotations
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterFramePropPageClass::Update_Frames (void)
|
||||
{
|
||||
float position = 0;
|
||||
float red = 0;
|
||||
float green = 0;
|
||||
float blue = 0;
|
||||
|
||||
//
|
||||
// Setup the initial or 'starting' size
|
||||
//
|
||||
m_Frames.Start = Denormalize_Frame(m_FrameBar->Get_Graph_Percent (0));
|
||||
|
||||
//
|
||||
// Free the current setting arrays
|
||||
//
|
||||
SAFE_DELETE_ARRAY (m_Frames.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_Frames.Values);
|
||||
|
||||
//
|
||||
// Determine if we need to build the array of key frames or not
|
||||
//
|
||||
int count = m_FrameBar->Get_Point_Count ();
|
||||
m_Frames.NumKeyFrames = count - 1;
|
||||
if (count > 1) {
|
||||
m_Frames.KeyTimes = new float[count - 1];
|
||||
m_Frames.Values = new float[count - 1];
|
||||
|
||||
//
|
||||
// Get all the key frames and add them to our structure
|
||||
//
|
||||
for (int index = 1; index < count; index ++) {
|
||||
m_FrameBar->Get_Point (index, &position, &red, &green, &blue);
|
||||
m_Frames.KeyTimes[index - 1] = position * m_Lifetime;
|
||||
m_Frames.Values[index - 1] = Denormalize_Frame(m_FrameBar->Get_Graph_Percent (index) );
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCommand
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterFramePropPageClass::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (LOWORD (wParam))
|
||||
{
|
||||
case IDC_FRAME_RANDOM_EDIT:
|
||||
{
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY))
|
||||
{
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
m_Frames.Rand = ::GetDlgItemFloat (m_hWnd, IDC_FRAME_RANDOM_EDIT);
|
||||
m_pEmitterList->Set_Frame_Keyframes (m_Frames);
|
||||
SetModified ();
|
||||
} else if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
|
||||
case IDC_FRAME_LAYOUT_COMBO:
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||
m_pEmitterList->Set_Frame_Mode(m_FrameLayoutCombo.GetCurSel());
|
||||
SetModified();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CPropertyPage::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// On_Lifetime_Changed
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterFramePropPageClass::On_Lifetime_Changed (float lifetime)
|
||||
{
|
||||
if (m_Lifetime != lifetime) {
|
||||
float conversion = lifetime / m_Lifetime;
|
||||
|
||||
//
|
||||
// Rescale the sizes
|
||||
//
|
||||
for (UINT index = 0; index < m_Frames.NumKeyFrames; index ++) {
|
||||
m_Frames.KeyTimes[index] *= conversion;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
m_pEmitterList->Set_Frame_Keyframes (m_Frames);
|
||||
m_Lifetime = lifetime;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
134
Code/Tools/W3DView/EmitterFramePropPage.h
Normal file
134
Code/Tools/W3DView/EmitterFramePropPage.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
** 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_EMITTERFRAMEPROPPAGE_H__6F068804_EAD5_4A19_BE03_C9C7B534E6E8__INCLUDED_)
|
||||
#define AFX_EMITTERFRAMEPROPPAGE_H__6F068804_EAD5_4A19_BE03_C9C7B534E6E8__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// EmitterFramePropPage.h : header file
|
||||
//
|
||||
|
||||
#include "ColorBar.H"
|
||||
#include "Part_Emt.H"
|
||||
|
||||
class EmitterInstanceListClass;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterFramePropPageClass dialog
|
||||
|
||||
class EmitterFramePropPageClass : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(EmitterFramePropPageClass)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
EmitterFramePropPageClass();
|
||||
~EmitterFramePropPageClass();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(EmitterFramePropPageClass)
|
||||
enum { IDD = IDD_PROP_PAGE_EMITTER_FRAME };
|
||||
CComboBox m_FrameLayoutCombo;
|
||||
CSpinButtonCtrl m_FrameRandomSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(EmitterFramePropPageClass)
|
||||
public:
|
||||
virtual BOOL OnApply();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(EmitterFramePropPageClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
//
|
||||
// Inline accessors
|
||||
//
|
||||
EmitterInstanceListClass * Get_Emitter (void) const { return m_pEmitterList; }
|
||||
void Set_Emitter (EmitterInstanceListClass *pemitter_list) { m_pEmitterList = pemitter_list; Initialize (); }
|
||||
bool Is_Data_Valid (void) const { return m_bValid; }
|
||||
|
||||
void Get_Frame_Keyframes (ParticlePropertyStruct<float> &frames) { frames = m_Frames; }
|
||||
void On_Lifetime_Changed (float lifetime);
|
||||
|
||||
void Initialize (void);
|
||||
void Update_Frames (void);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
float Normalize_Frame(float frame);
|
||||
float Normalize_Frame(float frame,float min,float max);
|
||||
float Denormalize_Frame(float normalized_val);
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
EmitterInstanceListClass * m_pEmitterList;
|
||||
bool m_bValid;
|
||||
|
||||
ColorBarClass * m_FrameBar;
|
||||
ParticlePropertyStruct<float> m_Frames;
|
||||
float m_Lifetime;
|
||||
float m_MinFrame;
|
||||
float m_MaxFrame;
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline float EmitterFramePropPageClass::Normalize_Frame(float frame)
|
||||
{
|
||||
return (frame - m_MinFrame) / (m_MaxFrame - m_MinFrame);
|
||||
}
|
||||
|
||||
inline float EmitterFramePropPageClass::Normalize_Frame(float frame,float min,float max)
|
||||
{
|
||||
return (frame - min) / (max - min);
|
||||
}
|
||||
|
||||
inline float EmitterFramePropPageClass::Denormalize_Frame(float normalized_val)
|
||||
{
|
||||
return normalized_val * (m_MaxFrame - m_MinFrame) + m_MinFrame;
|
||||
}
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EMITTERFRAMEPROPPAGE_H__6F068804_EAD5_4A19_BE03_C9C7B534E6E8__INCLUDED_)
|
||||
413
Code/Tools/W3DView/EmitterGeneralPropPage.cpp
Normal file
413
Code/Tools/W3DView/EmitterGeneralPropPage.cpp
Normal file
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// EmitterGeneralPropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "StdAfx.H"
|
||||
#include "W3DView.H"
|
||||
#include "EmitterGeneralPropPage.H"
|
||||
#include "EmitterPropertySheet.H"
|
||||
#include "Part_Emt.H"
|
||||
#include "Utils.H"
|
||||
#include "texture.h"
|
||||
#include "Shader.H"
|
||||
#include "EmitterInstanceList.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterGeneralPropPageClass property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(EmitterGeneralPropPageClass, CPropertyPage)
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterGeneralPropPageClass
|
||||
//
|
||||
EmitterGeneralPropPageClass::EmitterGeneralPropPageClass (EmitterInstanceListClass *pemitter)
|
||||
: m_pEmitterList (NULL),
|
||||
m_Parent (NULL),
|
||||
m_bValid (true),
|
||||
m_Lifetime (0),
|
||||
CPropertyPage(EmitterGeneralPropPageClass::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(EmitterGeneralPropPageClass)
|
||||
//}}AFX_DATA_INIT
|
||||
Initialize ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~EmitterGeneralPropPageClass
|
||||
//
|
||||
EmitterGeneralPropPageClass::~EmitterGeneralPropPageClass (void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
EmitterGeneralPropPageClass::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(EmitterGeneralPropPageClass)
|
||||
DDX_Control(pDX, IDC_RENDER_MODE_COMBO, m_RenderModeCombo);
|
||||
DDX_Control(pDX, IDC_PARTICLE_LIFETIME_SPIN, m_LifetimeSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(EmitterGeneralPropPageClass, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(EmitterGeneralPropPageClass)
|
||||
ON_BN_CLICKED(IDC_BROWSE_BUTTON, OnBrowseButton)
|
||||
ON_EN_CHANGE(IDC_FILENAME_EDIT, OnChangeFilenameEdit)
|
||||
ON_EN_CHANGE(IDC_NAME_EDIT, OnChangeNameEdit)
|
||||
ON_EN_CHANGE(IDC_PARTICLE_LIFETIME_EDIT, OnChangeParticleLifetimeEdit)
|
||||
ON_CBN_SELCHANGE(IDC_SHADER_COMBO, OnSelchangeShaderCombo)
|
||||
ON_BN_CLICKED(IDC_PARTICLE_LIFETIME_CHECK, OnParticleLifetimeCheck)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
void
|
||||
EmitterGeneralPropPageClass::Initialize (void)
|
||||
{
|
||||
if (m_pEmitterList != NULL) {
|
||||
|
||||
//
|
||||
// Get the emitter's texture
|
||||
//
|
||||
m_TextureFilename = m_pEmitterList->Get_Texture_Filename ();
|
||||
|
||||
m_Lifetime = m_pEmitterList->Get_Lifetime ();
|
||||
m_EmitterName = m_pEmitterList->Get_Name ();
|
||||
m_pEmitterList->Get_Shader (m_Shader);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Add_Shader_To_Combo
|
||||
//
|
||||
void
|
||||
EmitterGeneralPropPageClass::Add_Shader_To_Combo
|
||||
(
|
||||
ShaderClass &shader,
|
||||
LPCTSTR name
|
||||
)
|
||||
{
|
||||
int index = SendDlgItemMessage (IDC_SHADER_COMBO, CB_ADDSTRING, 0, (LPARAM)name);
|
||||
if (index != CB_ERR) {
|
||||
SendDlgItemMessage (IDC_SHADER_COMBO, CB_SETITEMDATA, (WPARAM)index, (LPARAM)&shader);
|
||||
|
||||
//
|
||||
// Is the blend mode of this shader the same as that of the
|
||||
// particle emitter's shader.
|
||||
//
|
||||
if ((shader.Get_Alpha_Test () == m_Shader.Get_Alpha_Test ()) &&
|
||||
(shader.Get_Dst_Blend_Func () == m_Shader.Get_Dst_Blend_Func ()) &&
|
||||
(shader.Get_Src_Blend_Func () == m_Shader.Get_Src_Blend_Func ())) {
|
||||
SendDlgItemMessage (IDC_SHADER_COMBO, CB_SETCURSEL, (WPARAM)index);
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
EmitterGeneralPropPageClass::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::OnInitDialog ();
|
||||
|
||||
//
|
||||
// Add the known shaders to the combobox
|
||||
//
|
||||
Add_Shader_To_Combo (ShaderClass::_PresetAdditiveSpriteShader, "Additive");
|
||||
Add_Shader_To_Combo (ShaderClass::_PresetAlphaSpriteShader, "Alpha");
|
||||
Add_Shader_To_Combo (ShaderClass::_PresetATestSpriteShader, "Alpha-Test");
|
||||
Add_Shader_To_Combo (ShaderClass::_PresetATestBlendSpriteShader, "Alpha-Test-Blend");
|
||||
Add_Shader_To_Combo (ShaderClass::_PresetScreenSpriteShader, "Screen");
|
||||
Add_Shader_To_Combo (ShaderClass::_PresetMultiplicativeSpriteShader, "Multiplicative");
|
||||
Add_Shader_To_Combo (ShaderClass::_PresetOpaqueSpriteShader, "Opaque");
|
||||
|
||||
//
|
||||
// Fill the edit controls with the default values
|
||||
//
|
||||
SetDlgItemText (IDC_NAME_EDIT, m_EmitterName);
|
||||
SetDlgItemText (IDC_FILENAME_EDIT, m_TextureFilename);
|
||||
|
||||
//
|
||||
// Initialize the lifetime control
|
||||
//
|
||||
SendDlgItemMessage (IDC_PARTICLE_LIFETIME_CHECK, BM_SETCHECK, (WPARAM)(m_Lifetime < 100));
|
||||
if (m_Lifetime > 100) {
|
||||
m_Lifetime = 0;
|
||||
}
|
||||
::Initialize_Spinner (m_LifetimeSpin, m_Lifetime, 0, 1000);
|
||||
|
||||
OnParticleLifetimeCheck ();
|
||||
|
||||
//
|
||||
// Initialize the render mode combo
|
||||
//
|
||||
m_RenderModeCombo.SetCurSel(m_pEmitterList->Get_Render_Mode());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnApply
|
||||
//
|
||||
BOOL
|
||||
EmitterGeneralPropPageClass::OnApply (void)
|
||||
{
|
||||
// Get the data from the dialog controls
|
||||
GetDlgItemText (IDC_NAME_EDIT, m_EmitterName);
|
||||
GetDlgItemText (IDC_FILENAME_EDIT, m_TextureFilename);
|
||||
m_Lifetime = ::GetDlgItemFloat (m_hWnd, IDC_PARTICLE_LIFETIME_EDIT);
|
||||
if (SendDlgItemMessage (IDC_PARTICLE_LIFETIME_CHECK, BM_GETCHECK) == 0) {
|
||||
m_Lifetime = 5000000.0F;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the shader from the combobox
|
||||
//
|
||||
int index = SendDlgItemMessage (IDC_SHADER_COMBO, CB_GETCURSEL);
|
||||
if (index != CB_ERR) {
|
||||
ShaderClass *shader = (ShaderClass *)SendDlgItemMessage (IDC_SHADER_COMBO, CB_GETITEMDATA, (WPARAM)index);
|
||||
if (shader != NULL) {
|
||||
m_Shader = (*shader);
|
||||
}
|
||||
}
|
||||
|
||||
// Check to make sure the user entered a valid name for the emitter.
|
||||
BOOL retval = FALSE;
|
||||
if (m_EmitterName.GetLength () == 0) {
|
||||
::MessageBox (m_hWnd, "Invalid emitter name. Please enter a new name.", "Invalid settings", MB_ICONEXCLAMATION | MB_OK);
|
||||
m_bValid = false;
|
||||
} else {
|
||||
|
||||
//
|
||||
// Apply the changes to the emitter
|
||||
//
|
||||
m_pEmitterList->Set_Lifetime (m_Lifetime);
|
||||
m_pEmitterList->Set_Texture_Filename (m_TextureFilename);
|
||||
m_pEmitterList->Set_Name (m_EmitterName);
|
||||
m_pEmitterList->Set_Shader (m_Shader);
|
||||
m_pEmitterList->Set_Render_Mode (m_RenderModeCombo.GetCurSel());
|
||||
|
||||
// Allow the base class to process this message
|
||||
retval = CPropertyPage::OnApply ();
|
||||
m_bValid = true;
|
||||
}
|
||||
|
||||
// Return the TRUE/FALSE result code
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnBrowseButton
|
||||
//
|
||||
void
|
||||
EmitterGeneralPropPageClass::OnBrowseButton (void)
|
||||
{
|
||||
CFileDialog openFileDialog (TRUE,
|
||||
".tga",
|
||||
NULL,
|
||||
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER,
|
||||
"Textures files (*.tga)|*.tga||",
|
||||
::AfxGetMainWnd ());
|
||||
|
||||
// Ask the user what texture file they wish to load
|
||||
if (openFileDialog.DoModal () == IDOK) {
|
||||
SetDlgItemText (IDC_FILENAME_EDIT, openFileDialog.GetPathName ());
|
||||
SetModified ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnChangeFilenameEdit
|
||||
//
|
||||
void
|
||||
EmitterGeneralPropPageClass::OnChangeFilenameEdit (void)
|
||||
{
|
||||
SetModified ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnChangeNameEdit
|
||||
//
|
||||
void
|
||||
EmitterGeneralPropPageClass::OnChangeNameEdit (void)
|
||||
{
|
||||
SetModified ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
BOOL
|
||||
EmitterGeneralPropPageClass::OnNotify
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
LRESULT *pResult
|
||||
)
|
||||
{
|
||||
//
|
||||
// Update the spinner control if necessary
|
||||
//
|
||||
NMHDR *pheader = (NMHDR *)lParam;
|
||||
if ((pheader != NULL) && (pheader->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN pupdown = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (pheader->hwndFrom, pupdown->iDelta);
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertyPage::OnNotify (wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnChangeParticleLifetimeEdit
|
||||
//
|
||||
void
|
||||
EmitterGeneralPropPageClass::OnChangeParticleLifetimeEdit (void)
|
||||
{
|
||||
SetModified ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSelchangeShaderCombo
|
||||
//
|
||||
void
|
||||
EmitterGeneralPropPageClass::OnSelchangeShaderCombo (void)
|
||||
{
|
||||
SetModified ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCommand
|
||||
//
|
||||
BOOL
|
||||
EmitterGeneralPropPageClass::OnCommand
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
switch (LOWORD (wParam)) {
|
||||
case IDC_FILENAME_EDIT:
|
||||
case IDC_NAME_EDIT:
|
||||
case IDC_PARTICLE_LIFETIME_EDIT:
|
||||
if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_PARTICLE_LIFETIME_CHECK:
|
||||
if (HIWORD (wParam) == BN_CLICKED) {
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_RENDER_MODE_COMBO:
|
||||
if (HIWORD (wParam) == CBN_SELCHANGE) {
|
||||
SetModified ();
|
||||
if (m_Parent != NULL) {
|
||||
int cur_mode = ::SendMessage ((HWND)lParam, CB_GETCURSEL, 0, 0);
|
||||
m_Parent->Notify_Render_Mode_Changed(cur_mode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return CPropertyPage::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnParticleLifetimeCheck
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterGeneralPropPageClass::OnParticleLifetimeCheck (void)
|
||||
{
|
||||
bool enable = (SendDlgItemMessage (IDC_PARTICLE_LIFETIME_CHECK, BM_GETCHECK) == 1);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_PARTICLE_LIFETIME_EDIT), enable);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_PARTICLE_LIFETIME_SPIN), enable);
|
||||
|
||||
if (enable == false) {
|
||||
m_Lifetime = 0;
|
||||
::SetDlgItemFloat (m_hWnd, IDC_PARTICLE_LIFETIME_EDIT, 0);
|
||||
}
|
||||
|
||||
SetModified ();
|
||||
return ;
|
||||
}
|
||||
|
||||
134
Code/Tools/W3DView/EmitterGeneralPropPage.h
Normal file
134
Code/Tools/W3DView/EmitterGeneralPropPage.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
** 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_EMITTERGENERALPROPPAGE_H__83A8B83C_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
#define AFX_EMITTERGENERALPROPPAGE_H__83A8B83C_BA3B_11D2_9FFA_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// EmitterGeneralPropPage.h : header file
|
||||
//
|
||||
|
||||
#include "Resource.H"
|
||||
#include "Shader.H"
|
||||
|
||||
// Forward delcarations
|
||||
class EmitterInstanceListClass;
|
||||
class EmitterPropertySheetClass;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterGeneralPropPageClass dialog
|
||||
//
|
||||
class EmitterGeneralPropPageClass : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(EmitterGeneralPropPageClass)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
EmitterGeneralPropPageClass (EmitterInstanceListClass *pemitter_list = NULL);
|
||||
~EmitterGeneralPropPageClass ();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(EmitterGeneralPropPageClass)
|
||||
enum { IDD = IDD_PROP_PAGE_EMITTER_GEN };
|
||||
CComboBox m_RenderModeCombo;
|
||||
CSpinButtonCtrl m_LifetimeSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(EmitterGeneralPropPageClass)
|
||||
public:
|
||||
virtual BOOL OnApply();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(EmitterGeneralPropPageClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnBrowseButton();
|
||||
afx_msg void OnChangeFilenameEdit();
|
||||
afx_msg void OnChangeNameEdit();
|
||||
afx_msg void OnChangeParticleLifetimeEdit();
|
||||
afx_msg void OnSelchangeShaderCombo();
|
||||
afx_msg void OnParticleLifetimeCheck();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
//
|
||||
// Inline accessors
|
||||
//
|
||||
EmitterInstanceListClass * Get_Emitter (void) const { return m_pEmitterList; }
|
||||
void Set_Emitter (EmitterInstanceListClass *pemitter_list) { m_pEmitterList = pemitter_list; Initialize (); }
|
||||
|
||||
EmitterPropertySheetClass *Get_Parent (void) const { return m_Parent; }
|
||||
void Set_Parent (EmitterPropertySheetClass * parent) { m_Parent = parent; }
|
||||
|
||||
bool Is_Data_Valid (void) const { return m_bValid; }
|
||||
|
||||
const CString & Get_Name (void) const { return m_EmitterName; }
|
||||
const CString & Get_Texture_Filename (void) const { return m_TextureFilename; }
|
||||
float Get_Lifetime (void) const { return m_Lifetime; }
|
||||
const ShaderClass & Get_Shader (void) const { return m_Shader; }
|
||||
//void Get_Shader (ShaderClass &shader);
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Initialize (void);
|
||||
void Add_Shader_To_Combo (ShaderClass &shader, LPCTSTR name);
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
EmitterInstanceListClass * m_pEmitterList;
|
||||
EmitterPropertySheetClass *m_Parent;
|
||||
|
||||
CString m_EmitterName;
|
||||
CString m_TextureFilename;
|
||||
ShaderClass m_Shader;
|
||||
//int m_ShaderType;
|
||||
float m_Lifetime;
|
||||
bool m_bValid;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EMITTERGENERALPROPPAGE_H__83A8B83C_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
470
Code/Tools/W3DView/EmitterInstanceList.cpp
Normal file
470
Code/Tools/W3DView/EmitterInstanceList.cpp
Normal file
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : W3DView *
|
||||
* *
|
||||
* $Archive:: /VSS_Sync/W3DView/EmitterInstanceList.cpp $Modtime:: $*
|
||||
* *
|
||||
* $Revision:: 7 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "StdAfx.H"
|
||||
#include "EmitterInstanceList.H"
|
||||
#include "Utils.H"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~EmitterInstanceListClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
EmitterInstanceListClass::~EmitterInstanceListClass (void)
|
||||
{
|
||||
Free_List ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Free_List
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Free_List (void)
|
||||
{
|
||||
//
|
||||
// Release our hold on each of the emitter pointers
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
MEMBER_RELEASE (m_List[index]);
|
||||
}
|
||||
|
||||
m_List.Delete_All ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Add_Emitter
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Add_Emitter (ParticleEmitterClass *emitter)
|
||||
{
|
||||
ASSERT (emitter != NULL);
|
||||
if (emitter != NULL) {
|
||||
|
||||
//
|
||||
// If this is the first emitter in the list, then initialize
|
||||
// the definition to it's state
|
||||
//
|
||||
if (m_List.Count () == 0) {
|
||||
ParticleEmitterDefClass *def = emitter->Build_Definition ();
|
||||
if (def != NULL) {
|
||||
ParticleEmitterDefClass::operator= (*def);
|
||||
SAFE_DELETE (def);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add this emitter to the list and put a hold on its reference
|
||||
//
|
||||
SAFE_ADD_REF (emitter);
|
||||
m_List.Add (emitter);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Velocity
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Velocity (const Vector3 &value)
|
||||
{
|
||||
ParticleEmitterDefClass::Set_Velocity (value);
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Set_Base_Velocity (value);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Acceleration
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Acceleration (const Vector3 &value)
|
||||
{
|
||||
ParticleEmitterDefClass::Set_Acceleration (value);
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Set_Acceleration (value);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Burst_Size
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Burst_Size (unsigned int count)
|
||||
{
|
||||
ParticleEmitterDefClass::Set_Burst_Size (count);
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Set_Burst_Size (count);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Outward_Vel
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Outward_Vel (float value)
|
||||
{
|
||||
ParticleEmitterDefClass::Set_Outward_Vel (value);
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Set_Outwards_Velocity (value);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Vel_Inherit
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Vel_Inherit (float value)
|
||||
{
|
||||
ParticleEmitterDefClass::Set_Vel_Inherit (value);
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Set_Velocity_Inheritance_Factor (value);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Velocity_Random
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Velocity_Random (Vector3Randomizer *randomizer)
|
||||
{
|
||||
ParticleEmitterDefClass::Set_Velocity_Random (randomizer);
|
||||
if (randomizer != NULL) {
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Set_Velocity_Randomizer (randomizer->Clone ());
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Color_Keyframes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Color_Keyframes (ParticlePropertyStruct<Vector3> &keyframes)
|
||||
{
|
||||
//
|
||||
// Make sure tha any value that is supposed to go to zero, really
|
||||
// does even if its got a randomizer.
|
||||
//
|
||||
if ( (keyframes.Rand.X != 0) ||
|
||||
(keyframes.Rand.Y != 0) ||
|
||||
(keyframes.Rand.Z != 0))
|
||||
{
|
||||
for (UINT index = 0; index < keyframes.NumKeyFrames; index ++) {
|
||||
if ((keyframes.Values[index].X <= 0.000001F) &&
|
||||
(keyframes.Values[index].Y <= 0.000001F) &&
|
||||
(keyframes.Values[index].Z <= 0.000001F)) {
|
||||
keyframes.Values[index].X = -keyframes.Rand.X;
|
||||
keyframes.Values[index].Y = -keyframes.Rand.Y;
|
||||
keyframes.Values[index].Z = -keyframes.Rand.Z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParticleEmitterDefClass::Set_Color_Keyframes (keyframes);
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Reset_Colors (keyframes);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Opacity_Keyframes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Opacity_Keyframes (ParticlePropertyStruct<float> &keyframes)
|
||||
{
|
||||
//
|
||||
// Make sure tha any value that is supposed to go to zero, really
|
||||
// does even if its got a randomizer.
|
||||
//
|
||||
if (keyframes.Rand != 0)
|
||||
{
|
||||
for (UINT index = 0; index < keyframes.NumKeyFrames; index ++) {
|
||||
if (keyframes.Values[index] <= 0.000001F) {
|
||||
keyframes.Values[index] = -keyframes.Rand;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParticleEmitterDefClass::Set_Opacity_Keyframes (keyframes);
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Reset_Opacity (keyframes);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Size_Keyframes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Size_Keyframes (ParticlePropertyStruct<float> &keyframes)
|
||||
{
|
||||
//
|
||||
// Make sure tha any value that is supposed to go to zero, really
|
||||
// does even if its got a randomizer.
|
||||
//
|
||||
if (keyframes.Rand != 0)
|
||||
{
|
||||
for (UINT index = 0; index < keyframes.NumKeyFrames; index ++) {
|
||||
if (keyframes.Values[index] <= 0.000001F) {
|
||||
keyframes.Values[index] = -keyframes.Rand;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParticleEmitterDefClass::Set_Size_Keyframes (keyframes);
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Reset_Size (keyframes);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Rotation_Keyframes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Rotation_Keyframes (ParticlePropertyStruct<float> &keyframes, float orient_rnd)
|
||||
{
|
||||
ParticleEmitterDefClass::Set_Rotation_Keyframes (keyframes, orient_rnd);
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Reset_Rotations (keyframes, orient_rnd);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Frame_Keyframes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Frame_Keyframes (ParticlePropertyStruct<float> &keyframes)
|
||||
{
|
||||
ParticleEmitterDefClass::Set_Frame_Keyframes (keyframes);
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Reset_Frames (keyframes);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set_Blur_Time_Keyframes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterInstanceListClass::Set_Blur_Time_Keyframes (ParticlePropertyStruct<float> &keyframes)
|
||||
{
|
||||
ParticleEmitterDefClass::Set_Blur_Time_Keyframes (keyframes);
|
||||
|
||||
//
|
||||
// Pass this setting onto the emitters immediately
|
||||
//
|
||||
for (int index = 0; index < m_List.Count (); index ++) {
|
||||
m_List[index]->Reset_Blur_Times (keyframes);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get_Color_Keyframes
|
||||
//
|
||||
void
|
||||
EmitterInstanceListClass::Get_Color_Keyframes (ParticlePropertyStruct<Vector3> &keyframes) const
|
||||
{
|
||||
ParticleEmitterDefClass::Get_Color_Keyframes (keyframes);
|
||||
|
||||
//
|
||||
// Normalize the data
|
||||
//
|
||||
for (UINT index = 0; index < keyframes.NumKeyFrames; index ++) {
|
||||
if (keyframes.Values[index].X <= 0.000001F) {
|
||||
keyframes.Values[index].X = 0;
|
||||
}
|
||||
if (keyframes.Values[index].Y <= 0.000001F) {
|
||||
keyframes.Values[index].Y = 0;
|
||||
}
|
||||
if (keyframes.Values[index].Z <= 0.000001F) {
|
||||
keyframes.Values[index].Z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get_Opacity_Keyframes
|
||||
//
|
||||
void
|
||||
EmitterInstanceListClass::Get_Opacity_Keyframes (ParticlePropertyStruct<float> &keyframes) const
|
||||
{
|
||||
ParticleEmitterDefClass::Get_Opacity_Keyframes (keyframes);
|
||||
|
||||
//
|
||||
// Normalize the data
|
||||
//
|
||||
for (UINT index = 0; index < keyframes.NumKeyFrames; index ++) {
|
||||
if (keyframes.Values[index] <= 0.000001F) {
|
||||
keyframes.Values[index] = 0;
|
||||
}
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get_Size_Keyframes
|
||||
//
|
||||
void
|
||||
EmitterInstanceListClass::Get_Size_Keyframes (ParticlePropertyStruct<float> &keyframes) const
|
||||
{
|
||||
ParticleEmitterDefClass::Get_Size_Keyframes (keyframes);
|
||||
|
||||
//
|
||||
// Normalize the data
|
||||
//
|
||||
for (UINT index = 0; index < keyframes.NumKeyFrames; index ++) {
|
||||
if (keyframes.Values[index] <= 0.000001F) {
|
||||
keyframes.Values[index] = 0;
|
||||
}
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
114
Code/Tools/W3DView/EmitterInstanceList.h
Normal file
114
Code/Tools/W3DView/EmitterInstanceList.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : W3DView *
|
||||
* *
|
||||
* $Archive:: /VSS_Sync/W3DView/EmitterInstanceList.h $Modtime:: $*
|
||||
* *
|
||||
* $Revision:: 6 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef __EMITTER_INSTANCE_LIST_H
|
||||
#define __EMITTER_INSTANCE_LIST_H
|
||||
|
||||
#include "Vector.H"
|
||||
#include "Part_Ldr.H"
|
||||
#include "Part_Emt.H"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterInstanceListClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
class EmitterInstanceListClass : public ParticleEmitterDefClass
|
||||
{
|
||||
public:
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Public constructors/destructors
|
||||
///////////////////////////////////////////////////////
|
||||
EmitterInstanceListClass (void) { }
|
||||
EmitterInstanceListClass (const EmitterInstanceListClass &src)
|
||||
: ParticleEmitterDefClass (src) { }
|
||||
|
||||
virtual ~EmitterInstanceListClass (void);
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
///////////////////////////////////////////////////////
|
||||
virtual void Add_Emitter (ParticleEmitterClass *emitter);
|
||||
virtual void Free_List (void);
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Derived overrides
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Note: The following are settings that can be changed on
|
||||
// the fly. All other settings are simply cached in the
|
||||
// definition and can be used to create a new prototype loader.
|
||||
//
|
||||
|
||||
virtual void Set_Velocity (const Vector3 &value);
|
||||
virtual void Set_Acceleration (const Vector3 &value);
|
||||
virtual void Set_Burst_Size (unsigned int count);
|
||||
virtual void Set_Outward_Vel (float value);
|
||||
virtual void Set_Vel_Inherit (float value);
|
||||
|
||||
//
|
||||
// Randomizer accessors
|
||||
//
|
||||
virtual void Set_Velocity_Random (Vector3Randomizer *randomizer);
|
||||
|
||||
//
|
||||
// Keyframe accessors
|
||||
//
|
||||
virtual void Set_Color_Keyframes (ParticlePropertyStruct<Vector3> &keyframes);
|
||||
virtual void Set_Opacity_Keyframes (ParticlePropertyStruct<float> &keyframes);
|
||||
virtual void Set_Size_Keyframes (ParticlePropertyStruct<float> &keyframes);
|
||||
virtual void Set_Rotation_Keyframes (ParticlePropertyStruct<float> &keyframes, float orient_rnd);
|
||||
virtual void Set_Frame_Keyframes (ParticlePropertyStruct<float> &keyframes);
|
||||
virtual void Set_Blur_Time_Keyframes (ParticlePropertyStruct<float> &keyframes);
|
||||
|
||||
virtual void Get_Color_Keyframes (ParticlePropertyStruct<Vector3> &keyframes) const;
|
||||
virtual void Get_Opacity_Keyframes (ParticlePropertyStruct<float> &keyframes) const;
|
||||
virtual void Get_Size_Keyframes (ParticlePropertyStruct<float> &keyframes) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Private member data
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
DynamicVectorClass<ParticleEmitterClass *> m_List;
|
||||
};
|
||||
|
||||
#endif //__EMITTER_INSTANCE_LIST_H
|
||||
372
Code/Tools/W3DView/EmitterLineGroupPropPage.cpp
Normal file
372
Code/Tools/W3DView/EmitterLineGroupPropPage.cpp
Normal file
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// EmitterLineGroupPropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "EmitterLineGroupPropPage.h"
|
||||
#include "w3d_file.h"
|
||||
#include "EmitterInstanceList.h"
|
||||
#include "Utils.h"
|
||||
#include "ColorBar.H"
|
||||
#include "ParticleBlurTimeKeyDialog.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterLineGroupPropPageClass property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(EmitterLineGroupPropPageClass, CPropertyPage)
|
||||
|
||||
EmitterLineGroupPropPageClass::EmitterLineGroupPropPageClass() :
|
||||
CPropertyPage(EmitterLineGroupPropPageClass::IDD),
|
||||
m_pEmitterList(NULL),
|
||||
m_bValid(true),
|
||||
m_BlurTimeBar(NULL),
|
||||
m_Lifetime(0),
|
||||
m_MinBlurTime(0),
|
||||
m_MaxBlurTime(1)
|
||||
{
|
||||
::memset (&m_BlurTimes, 0, sizeof (m_BlurTimes));
|
||||
|
||||
//{{AFX_DATA_INIT(EmitterLineGroupPropPageClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
EmitterLineGroupPropPageClass::~EmitterLineGroupPropPageClass()
|
||||
{
|
||||
// Free the blur time arrays
|
||||
SAFE_DELETE_ARRAY (m_BlurTimes.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_BlurTimes.Values);
|
||||
}
|
||||
|
||||
void EmitterLineGroupPropPageClass::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(EmitterLineGroupPropPageClass)
|
||||
DDX_Control(pDX, IDC_BLUR_TIME_RANDOM_SPIN, m_BlurTimeRandomSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(EmitterLineGroupPropPageClass, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(EmitterLineGroupPropPageClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterLineGroupPropPageClass::Initialize (void)
|
||||
{
|
||||
SAFE_DELETE_ARRAY (m_BlurTimes.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_BlurTimes.Values);
|
||||
|
||||
if (m_pEmitterList != NULL) {
|
||||
m_Lifetime = m_pEmitterList->Get_Lifetime ();
|
||||
m_pEmitterList->Get_Blur_Time_Keyframes (m_BlurTimes);
|
||||
|
||||
//
|
||||
// Determine what the min and max blur times are
|
||||
//
|
||||
m_MaxBlurTime = WWMath::Max(m_BlurTimes.Start,1.0f);
|
||||
m_MinBlurTime = WWMath::Min(m_BlurTimes.Start,0.0f);
|
||||
|
||||
for (UINT index = 0; index < m_BlurTimes.NumKeyFrames; index ++) {
|
||||
if (m_BlurTimes.Values[index] > m_MaxBlurTime) {
|
||||
m_MaxBlurTime = m_BlurTimes.Values[index];
|
||||
}
|
||||
if (m_BlurTimes.Values[index] < m_MinBlurTime) {
|
||||
m_MinBlurTime = m_BlurTimes.Values[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterLineGroupPropPageClass message handlers
|
||||
|
||||
BOOL EmitterLineGroupPropPageClass::OnInitDialog()
|
||||
{
|
||||
CPropertyPage::OnInitDialog();
|
||||
|
||||
//
|
||||
// Create the keyframe control
|
||||
//
|
||||
m_BlurTimeBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_BLUR_TIME_BAR));
|
||||
|
||||
//
|
||||
// Setup the spinners
|
||||
//
|
||||
Initialize_Spinner (m_BlurTimeRandomSpin, m_BlurTimes.Rand, 0, 10000);
|
||||
|
||||
//
|
||||
// Reset the keyframe control
|
||||
//
|
||||
m_BlurTimeBar->Set_Range (0, 1);
|
||||
m_BlurTimeBar->Clear_Points ();
|
||||
m_BlurTimeBar->Modify_Point (0, 0, 0, 0, 0);
|
||||
m_BlurTimeBar->Set_Graph_Percent (0, Normalize_Blur_Time(m_BlurTimes.Start));
|
||||
|
||||
//
|
||||
// Load the current set of frame keyframes into the control
|
||||
//
|
||||
for (UINT index = 0; index < m_BlurTimes.NumKeyFrames; index ++) {
|
||||
m_BlurTimeBar->Modify_Point (index + 1,
|
||||
m_BlurTimes.KeyTimes[index] / m_Lifetime,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
m_BlurTimeBar->Set_Graph_Percent (index + 1, Normalize_Blur_Time(m_BlurTimes.Values[index]));
|
||||
}
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Blur_Times
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterLineGroupPropPageClass::Update_Blur_Times (void)
|
||||
{
|
||||
float position = 0;
|
||||
float red = 0;
|
||||
float green = 0;
|
||||
float blue = 0;
|
||||
|
||||
//
|
||||
// Setup the initial or 'starting' size
|
||||
//
|
||||
m_BlurTimes.Start = Denormalize_Blur_Time(m_BlurTimeBar->Get_Graph_Percent (0));
|
||||
|
||||
//
|
||||
// Free the current setting arrays
|
||||
//
|
||||
SAFE_DELETE_ARRAY (m_BlurTimes.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_BlurTimes.Values);
|
||||
|
||||
//
|
||||
// Determine if we need to build the array of key frames or not
|
||||
//
|
||||
int count = m_BlurTimeBar->Get_Point_Count ();
|
||||
m_BlurTimes.NumKeyFrames = count - 1;
|
||||
if (count > 1) {
|
||||
m_BlurTimes.KeyTimes = new float[count - 1];
|
||||
m_BlurTimes.Values = new float[count - 1];
|
||||
|
||||
//
|
||||
// Get all the key frames and add them to our structure
|
||||
//
|
||||
for (int index = 1; index < count; index ++) {
|
||||
m_BlurTimeBar->Get_Point (index, &position, &red, &green, &blue);
|
||||
m_BlurTimes.KeyTimes[index - 1] = position * m_Lifetime;
|
||||
m_BlurTimes.Values[index - 1] = Denormalize_Blur_Time(m_BlurTimeBar->Get_Graph_Percent (index) );
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// On_Lifetime_Changed
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterLineGroupPropPageClass::On_Lifetime_Changed (float lifetime)
|
||||
{
|
||||
if (m_Lifetime != lifetime) {
|
||||
float conversion = lifetime / m_Lifetime;
|
||||
|
||||
//
|
||||
// Rescale the sizes
|
||||
//
|
||||
for (UINT index = 0; index < m_BlurTimes.NumKeyFrames; index ++) {
|
||||
m_BlurTimes.KeyTimes[index] *= conversion;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
m_pEmitterList->Set_Blur_Time_Keyframes (m_BlurTimes);
|
||||
m_Lifetime = lifetime;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
BOOL EmitterLineGroupPropPageClass::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (LOWORD (wParam))
|
||||
{
|
||||
case IDC_BLUR_TIME_RANDOM_EDIT:
|
||||
{
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY))
|
||||
{
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
m_BlurTimes.Rand = ::GetDlgItemFloat (m_hWnd, IDC_BLUR_TIME_RANDOM_EDIT);
|
||||
m_pEmitterList->Set_Blur_Time_Keyframes (m_BlurTimes);
|
||||
SetModified ();
|
||||
} else if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CPropertyPage::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
BOOL EmitterLineGroupPropPageClass::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
||||
{
|
||||
CBR_NMHDR *color_bar_hdr = (CBR_NMHDR *)lParam;
|
||||
|
||||
//
|
||||
// Update the spinner controls if necessary
|
||||
//
|
||||
NMHDR *pheader = (NMHDR *)lParam;
|
||||
if ((pheader != NULL) && (pheader->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN pupdown = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (pheader->hwndFrom, pupdown->iDelta);
|
||||
}
|
||||
|
||||
//
|
||||
// Which control sent the notification?
|
||||
//
|
||||
switch (color_bar_hdr->hdr.idFrom)
|
||||
{
|
||||
case IDC_BLUR_TIME_BAR:
|
||||
{
|
||||
if (color_bar_hdr->hdr.code == CBRN_DBLCLK_POINT) {
|
||||
|
||||
//
|
||||
// Allow the user to edit the keyframe
|
||||
//
|
||||
float blur_time = Denormalize_Blur_Time(m_BlurTimeBar->Get_Graph_Percent (color_bar_hdr->key_index));
|
||||
|
||||
ParticleBlurTimeKeyDialogClass dialog (blur_time, this);
|
||||
if (dialog.DoModal () == IDOK) {
|
||||
blur_time = dialog.Get_Blur_Time ();
|
||||
float norm_val = Normalize_Blur_Time(blur_time);
|
||||
|
||||
m_BlurTimeBar->Set_Redraw (false);
|
||||
m_BlurTimeBar->Set_Graph_Percent (color_bar_hdr->key_index, norm_val);
|
||||
|
||||
//
|
||||
// Determine if the user changed the 'max' or 'min' frame
|
||||
//
|
||||
float new_max = WWMath::Max(blur_time,1.0f);
|
||||
float new_min = WWMath::Min(blur_time,0.0f);
|
||||
|
||||
int count = m_BlurTimeBar->Get_Point_Count ();
|
||||
for (int index = 0; index < count; index ++) {
|
||||
float tmp = Denormalize_Blur_Time(m_BlurTimeBar->Get_Graph_Percent (index) );
|
||||
if (tmp > new_max) {
|
||||
new_max = tmp;
|
||||
}
|
||||
if (tmp < new_min) {
|
||||
new_min = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Renormalize the BlurTimeBar key frame points if necessary
|
||||
//
|
||||
if ((new_max != m_MaxBlurTime) || (new_min != m_MinBlurTime)) {
|
||||
|
||||
int count = m_BlurTimeBar->Get_Point_Count ();
|
||||
for (int index = 0; index < count; index ++) {
|
||||
|
||||
float frame = Denormalize_Blur_Time(m_BlurTimeBar->Get_Graph_Percent (index));
|
||||
float new_norm = Normalize_Blur_Time(frame,new_min,new_max);
|
||||
|
||||
m_BlurTimeBar->Set_Graph_Percent (index, new_norm);
|
||||
}
|
||||
|
||||
// Remember the new min and max
|
||||
m_MinBlurTime = new_min;
|
||||
m_MaxBlurTime = new_max;
|
||||
}
|
||||
m_BlurTimeBar->Set_Redraw (true);
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
Update_Blur_Times ();
|
||||
m_pEmitterList->Set_Blur_Time_Keyframes (m_BlurTimes);
|
||||
SetModified ();
|
||||
}
|
||||
} else if ((color_bar_hdr->hdr.code == CBRN_MOVING_POINT) ||
|
||||
(color_bar_hdr->hdr.code == CBRN_DELETED_POINT)) {
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
Update_Blur_Times ();
|
||||
m_pEmitterList->Set_Blur_Time_Keyframes (m_BlurTimes);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_BLUR_TIME_RANDOM_SPIN:
|
||||
{
|
||||
// Update the emitter
|
||||
m_BlurTimes.Rand = ::GetDlgItemFloat (m_hWnd, IDC_BLUR_TIME_RANDOM_EDIT);
|
||||
m_pEmitterList->Set_Blur_Time_Keyframes (m_BlurTimes);
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CPropertyPage::OnNotify(wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
float EmitterLineGroupPropPageClass::Normalize_Blur_Time(float blur)
|
||||
{
|
||||
return (blur - m_MinBlurTime) / (m_MaxBlurTime - m_MinBlurTime);
|
||||
}
|
||||
|
||||
float EmitterLineGroupPropPageClass::Normalize_Blur_Time(float blur,float min,float max)
|
||||
{
|
||||
return (blur - min) / (max - min);
|
||||
}
|
||||
|
||||
float EmitterLineGroupPropPageClass::Denormalize_Blur_Time(float normalized_val)
|
||||
{
|
||||
return normalized_val * (m_MaxBlurTime - m_MinBlurTime) + m_MinBlurTime;
|
||||
}
|
||||
116
Code/Tools/W3DView/EmitterLineGroupPropPage.h
Normal file
116
Code/Tools/W3DView/EmitterLineGroupPropPage.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
** 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_EMITTERLINEGROUPPROPPAGE_H__51E7B2D1_1943_454E_B188_5F7D508D7203__INCLUDED_)
|
||||
#define AFX_EMITTERLINEGROUPPROPPAGE_H__51E7B2D1_1943_454E_B188_5F7D508D7203__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// EmitterLineGroupPropPage.h : header file
|
||||
//
|
||||
|
||||
#include "part_emt.h"
|
||||
|
||||
// Forward declarations
|
||||
|
||||
class EmitterInstanceListClass;
|
||||
class ColorBarClass;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterLineGroupPropPageClass dialog
|
||||
|
||||
class EmitterLineGroupPropPageClass : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(EmitterLineGroupPropPageClass)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
EmitterLineGroupPropPageClass();
|
||||
~EmitterLineGroupPropPageClass();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(EmitterLineGroupPropPageClass)
|
||||
enum { IDD = IDD_PROP_PAGE_EMITTER_LINEGROUP };
|
||||
CSpinButtonCtrl m_BlurTimeRandomSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(EmitterLineGroupPropPageClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(EmitterLineGroupPropPageClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
//
|
||||
// Inline accessors
|
||||
//
|
||||
EmitterInstanceListClass * Get_Emitter (void) const { return m_pEmitterList; }
|
||||
void Set_Emitter (EmitterInstanceListClass *pemitter_list) { m_pEmitterList = pemitter_list; Initialize (); }
|
||||
bool Is_Data_Valid (void) const { return m_bValid; }
|
||||
|
||||
void Get_Blur_Time_Keyframes (ParticlePropertyStruct<float> &blurtimes) { blurtimes = m_BlurTimes; }
|
||||
void On_Lifetime_Changed (float lifetime);
|
||||
|
||||
void Initialize (void);
|
||||
void Update_Blur_Times (void);
|
||||
|
||||
private:
|
||||
|
||||
float Normalize_Blur_Time(float blur);
|
||||
float Normalize_Blur_Time(float blur,float min,float max);
|
||||
float Denormalize_Blur_Time(float normalized_val);
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
EmitterInstanceListClass * m_pEmitterList;
|
||||
bool m_bValid;
|
||||
|
||||
ColorBarClass * m_BlurTimeBar;
|
||||
ParticlePropertyStruct<float> m_BlurTimes;
|
||||
float m_Lifetime;
|
||||
float m_MinBlurTime;
|
||||
float m_MaxBlurTime;
|
||||
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EMITTERLINEGROUPPROPPAGE_H__51E7B2D1_1943_454E_B188_5F7D508D7203__INCLUDED_)
|
||||
231
Code/Tools/W3DView/EmitterLinePropPage.cpp
Normal file
231
Code/Tools/W3DView/EmitterLinePropPage.cpp
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// EmitterLinePropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "EmitterLinePropPage.h"
|
||||
#include "w3d_file.h"
|
||||
#include "EmitterInstanceList.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterLinePropPageClass property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(EmitterLinePropPageClass, CPropertyPage)
|
||||
|
||||
EmitterLinePropPageClass::EmitterLinePropPageClass() :
|
||||
CPropertyPage(EmitterLinePropPageClass::IDD),
|
||||
m_pEmitterList(NULL),
|
||||
m_bValid(true),
|
||||
m_MappingMode(W3D_EMITTER_RENDER_MODE_TRI_PARTICLES),
|
||||
m_MergeIntersections(false),
|
||||
m_EndCaps(false),
|
||||
m_DisableSorting(false),
|
||||
m_SubdivisionLevel(0),
|
||||
m_NoiseAmplitude(0.0f),
|
||||
m_MergeAbortFactor(0.0f),
|
||||
m_TextureTileFactor(0.0f),
|
||||
m_UPerSec(0.0f),
|
||||
m_VPerSec(0.0f)
|
||||
{
|
||||
//{{AFX_DATA_INIT(EmitterLinePropPageClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
EmitterLinePropPageClass::~EmitterLinePropPageClass()
|
||||
{
|
||||
}
|
||||
|
||||
void EmitterLinePropPageClass::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(EmitterLinePropPageClass)
|
||||
DDX_Control(pDX, IDC_MAPMODE_COMBO, m_MapModeCombo);
|
||||
DDX_Control(pDX, IDC_MERGE_ABORT_FACTOR_SPIN, m_MergeAbortFactorSpin);
|
||||
DDX_Control(pDX, IDC_VPERSEC_SPIN, m_VPerSecSpin);
|
||||
DDX_Control(pDX, IDC_UVTILING_SPIN, m_UVTilingSpin);
|
||||
DDX_Control(pDX, IDC_UPERSEC_SPIN, m_UPerSecSpin);
|
||||
DDX_Control(pDX, IDC_NOISE_AMPLITUDE_SPIN, m_NoiseAmplitudeSpin);
|
||||
DDX_Control(pDX, IDC_SUBDIVISION_LEVEL_SPIN, m_SubdivisionLevelSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(EmitterLinePropPageClass, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(EmitterLinePropPageClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterLinePropPageClass message handlers
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
void
|
||||
EmitterLinePropPageClass::Initialize (void)
|
||||
{
|
||||
if (m_pEmitterList != NULL) {
|
||||
|
||||
//
|
||||
// Read the settings from the emitter
|
||||
//
|
||||
m_MappingMode = m_pEmitterList->Get_Line_Texture_Mapping_Mode();
|
||||
m_MergeIntersections = !!m_pEmitterList->Is_Merge_Intersections();
|
||||
m_DisableSorting = !!m_pEmitterList->Is_Sorting_Disabled();
|
||||
m_EndCaps = !!m_pEmitterList->Are_End_Caps_Enabled();
|
||||
m_SubdivisionLevel = m_pEmitterList->Get_Subdivision_Level();
|
||||
m_NoiseAmplitude = m_pEmitterList->Get_Noise_Amplitude();
|
||||
m_MergeAbortFactor = m_pEmitterList->Get_Merge_Abort_Factor();
|
||||
m_TextureTileFactor = m_pEmitterList->Get_Texture_Tile_Factor();
|
||||
|
||||
Vector2 uvrate = m_pEmitterList->Get_UV_Offset_Rate();
|
||||
m_UPerSec = uvrate.X;
|
||||
m_VPerSec = uvrate.Y;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
BOOL EmitterLinePropPageClass::OnInitDialog()
|
||||
{
|
||||
CPropertyPage::OnInitDialog();
|
||||
|
||||
// Set up the spinner ranges
|
||||
m_SubdivisionLevelSpin.SetRange(0,8);
|
||||
m_SubdivisionLevelSpin.SetPos(m_SubdivisionLevel);
|
||||
|
||||
::Initialize_Spinner (m_NoiseAmplitudeSpin, m_NoiseAmplitude, -10000, 10000);
|
||||
::Initialize_Spinner (m_MergeAbortFactorSpin, m_MergeAbortFactor, -10000, 10000);
|
||||
::Initialize_Spinner (m_UVTilingSpin, m_TextureTileFactor, 0.0f,8.0f);
|
||||
::Initialize_Spinner (m_UPerSecSpin, m_UPerSec, 0.0f,32.0f);
|
||||
::Initialize_Spinner (m_VPerSecSpin, m_VPerSec, 0.0f,32.0f);
|
||||
|
||||
// Set the combo box
|
||||
m_MapModeCombo.SetCurSel(m_MappingMode);
|
||||
|
||||
// Set the checkboxes
|
||||
SendDlgItemMessage (IDC_MERGE_INTERSECTIONS_CHECK, BM_SETCHECK, (WPARAM)(m_MergeIntersections != 0));
|
||||
SendDlgItemMessage (IDC_END_CAPS_CHECK, BM_SETCHECK, (WPARAM)(m_EndCaps != 0));
|
||||
SendDlgItemMessage (IDC_DISABLE_SORTING_CHECK, BM_SETCHECK, (WPARAM)(m_DisableSorting != 0));
|
||||
|
||||
bool enable = (m_pEmitterList->Get_Render_Mode() == W3D_EMITTER_RENDER_MODE_LINE);
|
||||
::Enable_Dialog_Controls(m_hWnd,enable);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EmitterLinePropPageClass::OnApply()
|
||||
{
|
||||
//
|
||||
// Get the data from the controls
|
||||
//
|
||||
m_SubdivisionLevel = GetDlgItemInt (IDC_SUBDIVISION_LEVEL_EDIT);
|
||||
m_NoiseAmplitude = ::GetDlgItemFloat (m_hWnd, IDC_NOISE_AMPLITUDE_EDIT);
|
||||
m_MergeAbortFactor = ::GetDlgItemFloat (m_hWnd, IDC_MERGE_ABORT_FACTOR_EDIT);
|
||||
m_TextureTileFactor = ::GetDlgItemFloat (m_hWnd, IDC_UVTILING_EDIT);
|
||||
m_UPerSec = ::GetDlgItemFloat (m_hWnd, IDC_UPERSEC_EDIT);
|
||||
m_VPerSec = ::GetDlgItemFloat (m_hWnd, IDC_VPERSEC_EDIT);
|
||||
|
||||
m_MappingMode = SendDlgItemMessage (IDC_MAPMODE_COMBO, CB_GETCURSEL);
|
||||
m_MergeIntersections = !!SendDlgItemMessage (IDC_MERGE_INTERSECTIONS_CHECK, BM_GETCHECK);
|
||||
m_EndCaps = !!SendDlgItemMessage (IDC_END_CAPS_CHECK, BM_GETCHECK);
|
||||
m_DisableSorting = !!SendDlgItemMessage (IDC_DISABLE_SORTING_CHECK, BM_GETCHECK);
|
||||
|
||||
//
|
||||
// Apply the changes to the emitter
|
||||
//
|
||||
m_pEmitterList->Set_Subdivision_Level (m_SubdivisionLevel);
|
||||
m_pEmitterList->Set_Noise_Amplitude (m_NoiseAmplitude);
|
||||
m_pEmitterList->Set_Merge_Abort_Factor (m_MergeAbortFactor);
|
||||
m_pEmitterList->Set_Texture_Tile_Factor (m_TextureTileFactor);
|
||||
m_pEmitterList->Set_UV_Offset_Rate (Vector2(m_UPerSec,m_VPerSec));
|
||||
|
||||
m_pEmitterList->Set_Line_Texture_Mapping_Mode (m_MappingMode);
|
||||
m_pEmitterList->Set_Merge_Intersections (m_MergeIntersections);
|
||||
m_pEmitterList->Set_Disable_Sorting(m_DisableSorting);
|
||||
m_pEmitterList->Set_End_Caps(m_EndCaps);
|
||||
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertyPage::OnApply();
|
||||
}
|
||||
|
||||
|
||||
BOOL EmitterLinePropPageClass::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (LOWORD (wParam))
|
||||
{
|
||||
// Check if any of the edit boxes were modified,
|
||||
case IDC_SUBDIVISION_LEVEL_EDIT:
|
||||
case IDC_NOISE_AMPLITUDE_EDIT:
|
||||
case IDC_MERGE_ABORT_FACTOR_EDIT:
|
||||
case IDC_UVTILING_EDIT:
|
||||
case IDC_UPERSEC_EDIT:
|
||||
case IDC_VPERSEC_EDIT:
|
||||
if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_MERGE_INTERSECTIONS_CHECK:
|
||||
case IDC_END_CAPS_CHECK:
|
||||
case IDC_DISABLE_SORTING_CHECK:
|
||||
if (HIWORD (wParam) == BN_CLICKED) {
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_MAPMODE_COMBO:
|
||||
if (HIWORD (wParam) == CBN_SELCHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return CPropertyPage::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
BOOL EmitterLinePropPageClass::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
||||
{
|
||||
//
|
||||
// Update the spinner control if necessary
|
||||
//
|
||||
NMHDR *pheader = (NMHDR *)lParam;
|
||||
if ((pheader != NULL) && (pheader->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN pupdown = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (pheader->hwndFrom, pupdown->iDelta);
|
||||
SetModified ();
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertyPage::OnNotify (wParam, lParam, pResult);
|
||||
}
|
||||
135
Code/Tools/W3DView/EmitterLinePropPage.h
Normal file
135
Code/Tools/W3DView/EmitterLinePropPage.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
** 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_EMITTERLINEPROPPAGE_H__BBD9ED4C_E752_439A_81D5_A4FA9A6F6FC8__INCLUDED_)
|
||||
#define AFX_EMITTERLINEPROPPAGE_H__BBD9ED4C_E752_439A_81D5_A4FA9A6F6FC8__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// EmitterLinePropPage.h : header file
|
||||
//
|
||||
|
||||
|
||||
// Forward delcarations
|
||||
class EmitterInstanceListClass;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterLinePropPageClass dialog
|
||||
|
||||
class EmitterLinePropPageClass : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(EmitterLinePropPageClass)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
EmitterLinePropPageClass();
|
||||
~EmitterLinePropPageClass();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(EmitterLinePropPageClass)
|
||||
enum { IDD = IDD_PROP_PAGE_EMITTER_LINEPROPS };
|
||||
CComboBox m_MapModeCombo;
|
||||
CSpinButtonCtrl m_MergeAbortFactorSpin;
|
||||
CSpinButtonCtrl m_VPerSecSpin;
|
||||
CSpinButtonCtrl m_UVTilingSpin;
|
||||
CSpinButtonCtrl m_UPerSecSpin;
|
||||
CSpinButtonCtrl m_NoiseAmplitudeSpin;
|
||||
CSpinButtonCtrl m_SubdivisionLevelSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(EmitterLinePropPageClass)
|
||||
public:
|
||||
virtual BOOL OnApply();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(EmitterLinePropPageClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
EmitterInstanceListClass * Get_Emitter (void) const { return m_pEmitterList; }
|
||||
void Set_Emitter (EmitterInstanceListClass *pemitter_list) { m_pEmitterList = pemitter_list; Initialize (); }
|
||||
bool Is_Data_Valid (void) const { return m_bValid; }
|
||||
|
||||
int Get_Mapping_Mode (void) const { return m_MappingMode; }
|
||||
bool Get_Merge_Intersections (void) const { return m_MergeIntersections; }
|
||||
bool Get_End_Caps (void) const { return m_EndCaps; }
|
||||
bool Get_Disable_Sorting (void) const { return m_DisableSorting; }
|
||||
|
||||
int Get_Subdivision_Level (void) const { return m_SubdivisionLevel; }
|
||||
float Get_Noise_Amplitude (void) const { return m_NoiseAmplitude; }
|
||||
float Get_Merge_Abort_Factor (void) const { return m_MergeAbortFactor; }
|
||||
float Get_Texture_Tile_Factor (void) const { return m_TextureTileFactor; }
|
||||
float Get_U_Per_Sec(void) const { return m_UPerSec; }
|
||||
float Get_V_Per_Sed(void) const { return m_VPerSec; }
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Initialize (void);
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
EmitterInstanceListClass * m_pEmitterList;
|
||||
bool m_bValid;
|
||||
|
||||
int m_MappingMode;
|
||||
bool m_MergeIntersections;
|
||||
bool m_EndCaps;
|
||||
bool m_DisableSorting;
|
||||
|
||||
int m_SubdivisionLevel;
|
||||
float m_NoiseAmplitude;
|
||||
float m_MergeAbortFactor;
|
||||
float m_TextureTileFactor;
|
||||
float m_UPerSec;
|
||||
float m_VPerSec;
|
||||
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EMITTERLINEPROPPAGE_H__BBD9ED4C_E752_439A_81D5_A4FA9A6F6FC8__INCLUDED_)
|
||||
298
Code/Tools/W3DView/EmitterParticlePropPage.cpp
Normal file
298
Code/Tools/W3DView/EmitterParticlePropPage.cpp
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// EmitterParticlePropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "EmitterParticlePropPage.h"
|
||||
#include "Part_Emt.H"
|
||||
#include "Utils.H"
|
||||
#include "Vector3RndCombo.H"
|
||||
#include "VolumeRandomDialog.H"
|
||||
#include "EmitterInstanceList.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterParticlePropPageClass property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(EmitterParticlePropPageClass, CPropertyPage)
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterParticlePropPageClass
|
||||
//
|
||||
EmitterParticlePropPageClass::EmitterParticlePropPageClass (EmitterInstanceListClass *pemitter)
|
||||
: m_pEmitterList (pemitter),
|
||||
m_bValid (true),
|
||||
m_Rate (0),
|
||||
m_BurstSize (0),
|
||||
m_MaxParticles (0),
|
||||
m_Randomizer (NULL),
|
||||
CPropertyPage(EmitterParticlePropPageClass::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(EmitterParticlePropPageClass)
|
||||
//}}AFX_DATA_INIT
|
||||
Initialize ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~EmitterParticlePropPageClass
|
||||
//
|
||||
EmitterParticlePropPageClass::~EmitterParticlePropPageClass (void)
|
||||
{
|
||||
SAFE_DELETE (m_Randomizer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
EmitterParticlePropPageClass::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(EmitterParticlePropPageClass)
|
||||
DDX_Control(pDX, IDC_BURST_SIZE_SPIN, m_BurstSizeSpin);
|
||||
DDX_Control(pDX, IDC_EMISSION_RATE_SPIN, m_EmitionRateSpin);
|
||||
DDX_Control(pDX, IDC_MAX_PARTICLES_SPIN, m_MaxParticlesSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(EmitterParticlePropPageClass, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(EmitterParticlePropPageClass)
|
||||
ON_BN_CLICKED(IDC_SPECIFY_CREATION_VOLUME, OnSpecifyCreationVolume)
|
||||
ON_BN_CLICKED(IDC_MAX_PARTICLES_CHECK, OnMaxParticlesCheck)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
void
|
||||
EmitterParticlePropPageClass::Initialize (void)
|
||||
{
|
||||
SAFE_DELETE (m_Randomizer);
|
||||
if (m_pEmitterList != NULL) {
|
||||
|
||||
//
|
||||
// Read the settings from the emitter
|
||||
//
|
||||
m_Rate = m_pEmitterList->Get_Emission_Rate ();
|
||||
m_BurstSize = m_pEmitterList->Get_Burst_Size ();
|
||||
m_MaxParticles = m_pEmitterList->Get_Max_Emissions ();
|
||||
m_Randomizer = m_pEmitterList->Get_Creation_Volume ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
EmitterParticlePropPageClass::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::OnInitDialog ();
|
||||
|
||||
//
|
||||
// Setup the burst controls
|
||||
//
|
||||
m_BurstSizeSpin.SetRange (0, 10000);
|
||||
m_BurstSizeSpin.SetPos (m_BurstSize);
|
||||
::Initialize_Spinner (m_EmitionRateSpin, m_Rate, -10000, 10000);
|
||||
|
||||
//
|
||||
// Setup the max particles spin
|
||||
//
|
||||
m_MaxParticlesSpin.SetRange (0, 10000);
|
||||
m_MaxParticlesSpin.SetPos (m_MaxParticles);
|
||||
SendDlgItemMessage (IDC_MAX_PARTICLES_CHECK, BM_SETCHECK, WPARAM(m_MaxParticles != 0));
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_MAX_PARTICLES_EDIT), m_MaxParticles != 0);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_MAX_PARTICLES_SPIN), m_MaxParticles != 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnApply
|
||||
//
|
||||
BOOL
|
||||
EmitterParticlePropPageClass::OnApply (void)
|
||||
{
|
||||
//
|
||||
// Get the data from the controls
|
||||
//
|
||||
m_Rate = ::GetDlgItemFloat (m_hWnd, IDC_EMISSION_RATE_EDIT);
|
||||
m_BurstSize = GetDlgItemInt (IDC_BURST_SIZE_EDIT);
|
||||
|
||||
//
|
||||
// Determine if we need to cap the particles or not
|
||||
//
|
||||
m_MaxParticles = 0;
|
||||
if (SendDlgItemMessage (IDC_MAX_PARTICLES_CHECK, BM_GETCHECK)) {
|
||||
m_MaxParticles = GetDlgItemInt (IDC_MAX_PARTICLES_EDIT);
|
||||
}
|
||||
|
||||
//
|
||||
// Apply the changes to the emitter
|
||||
//
|
||||
m_pEmitterList->Set_Emission_Rate (m_Rate);
|
||||
m_pEmitterList->Set_Burst_Size (m_BurstSize);
|
||||
m_pEmitterList->Set_Max_Emissions (m_MaxParticles);
|
||||
m_pEmitterList->Set_Creation_Volume (m_Randomizer->Clone ());
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertyPage::OnApply ();
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WindowProc
|
||||
//
|
||||
LRESULT
|
||||
EmitterParticlePropPageClass::WindowProc
|
||||
(
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
/*switch (message)
|
||||
{
|
||||
}*/
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertyPage::WindowProc(message, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
BOOL
|
||||
EmitterParticlePropPageClass::OnNotify
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
LRESULT *pResult
|
||||
)
|
||||
{
|
||||
//
|
||||
// Update the spinner control if necessary
|
||||
//
|
||||
NMHDR *pheader = (NMHDR *)lParam;
|
||||
if ((pheader != NULL) && (pheader->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN pupdown = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (pheader->hwndFrom, pupdown->iDelta);
|
||||
SetModified ();
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertyPage::OnNotify (wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSpecifyCreationVolume
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterParticlePropPageClass::OnSpecifyCreationVolume (void)
|
||||
{
|
||||
VolumeRandomDialogClass dialog (m_Randomizer, this);
|
||||
if (dialog.DoModal () == IDOK) {
|
||||
|
||||
//
|
||||
// Get the new randomizer from the dialog
|
||||
//
|
||||
SAFE_DELETE (m_Randomizer);
|
||||
m_Randomizer = dialog.Get_Randomizer ();
|
||||
SetModified ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCommand
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterParticlePropPageClass::OnCommand
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
switch (LOWORD (wParam))
|
||||
{
|
||||
case IDC_BURST_SIZE_EDIT:
|
||||
case IDC_EMISSION_RATE_EDIT:
|
||||
case IDC_MAX_PARTICLES_EDIT:
|
||||
if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CPropertyPage::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnMaxParticlesCheck
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterParticlePropPageClass::OnMaxParticlesCheck (void)
|
||||
{
|
||||
BOOL enable = SendDlgItemMessage (IDC_MAX_PARTICLES_CHECK, BM_GETCHECK);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_MAX_PARTICLES_EDIT), enable);
|
||||
::EnableWindow (::GetDlgItem (m_hWnd, IDC_MAX_PARTICLES_SPIN), enable);
|
||||
|
||||
SetModified ();
|
||||
return ;
|
||||
}
|
||||
124
Code/Tools/W3DView/EmitterParticlePropPage.h
Normal file
124
Code/Tools/W3DView/EmitterParticlePropPage.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
** 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_EMITTERPARTICLEPROPPAGE_H__83A8B83D_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
#define AFX_EMITTERPARTICLEPROPPAGE_H__83A8B83D_BA3B_11D2_9FFA_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// EmitterParticlePropPage.h : header file
|
||||
//
|
||||
|
||||
#include "Resource.H"
|
||||
#include "Vector3.H"
|
||||
#include "V3_Rnd.H"
|
||||
|
||||
// Forward delcarations
|
||||
class EmitterInstanceListClass;
|
||||
//class Vector3Randomizer;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterParticlePropPageClass dialog
|
||||
|
||||
class EmitterParticlePropPageClass : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(EmitterParticlePropPageClass)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
EmitterParticlePropPageClass (EmitterInstanceListClass *pemitter_list = NULL);
|
||||
~EmitterParticlePropPageClass ();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(EmitterParticlePropPageClass)
|
||||
enum { IDD = IDD_PROP_PAGE_EMITTER_PARTICLE };
|
||||
CSpinButtonCtrl m_BurstSizeSpin;
|
||||
CSpinButtonCtrl m_EmitionRateSpin;
|
||||
CSpinButtonCtrl m_MaxParticlesSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(EmitterParticlePropPageClass)
|
||||
public:
|
||||
virtual BOOL OnApply();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(EmitterParticlePropPageClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnSpecifyCreationVolume();
|
||||
afx_msg void OnMaxParticlesCheck();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
//
|
||||
// Inline accessors
|
||||
//
|
||||
EmitterInstanceListClass * Get_Emitter (void) const { return m_pEmitterList; }
|
||||
void Set_Emitter (EmitterInstanceListClass *pemitter_list) { m_pEmitterList = pemitter_list; Initialize (); }
|
||||
bool Is_Data_Valid (void) const { return m_bValid; }
|
||||
|
||||
float Get_Rate (void) const { return m_Rate; }
|
||||
int Get_Burst_Size (void) const { return m_BurstSize; }
|
||||
int Get_Max_Particles (void) const { return m_MaxParticles; }
|
||||
Vector3Randomizer * Get_Creation_Volume (void) const { return m_Randomizer->Clone (); }
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Initialize (void);
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
EmitterInstanceListClass * m_pEmitterList;
|
||||
bool m_bValid;
|
||||
float m_Rate;
|
||||
int m_BurstSize;
|
||||
int m_MaxParticles;
|
||||
Vector3Randomizer * m_Randomizer;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EMITTERPARTICLEPROPPAGE_H__83A8B83D_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
|
||||
382
Code/Tools/W3DView/EmitterPhysicsPropPage.cpp
Normal file
382
Code/Tools/W3DView/EmitterPhysicsPropPage.cpp
Normal file
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// EmitterPhysicsPropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "StdAfx.H"
|
||||
#include "W3DView.H"
|
||||
#include "EmitterPhysicsPropPage.H"
|
||||
#include "Utils.H"
|
||||
#include "Part_Emt.H"
|
||||
#include "VolumeRandomDialog.H"
|
||||
#include "EmitterInstanceList.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterPhysicsPropPageClass property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(EmitterPhysicsPropPageClass, CPropertyPage)
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterPhysicsPropPageClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
EmitterPhysicsPropPageClass::EmitterPhysicsPropPageClass (EmitterInstanceListClass *pemitter)
|
||||
: m_pEmitterList (NULL),
|
||||
m_bValid (true),
|
||||
m_Velocity (0, 0, 1),
|
||||
m_Acceleration (0, 0, 0),
|
||||
m_OutFactor (0),
|
||||
m_InheritanceFactor (0),
|
||||
m_Randomizer (NULL),
|
||||
CPropertyPage(EmitterPhysicsPropPageClass::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(EmitterPhysicsPropPageClass)
|
||||
//}}AFX_DATA_INIT
|
||||
Initialize ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~EmitterPhysicsPropPageClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
EmitterPhysicsPropPageClass::~EmitterPhysicsPropPageClass (void)
|
||||
{
|
||||
SAFE_DELETE (m_Randomizer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterPhysicsPropPageClass::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(EmitterPhysicsPropPageClass)
|
||||
DDX_Control(pDX, IDC_OUT_FACTOR_SPIN, m_OutSpin);
|
||||
DDX_Control(pDX, IDC_INHERITANCE_FACTOR_SPIN, m_InheritanceSpin);
|
||||
DDX_Control(pDX, IDC_VELOCITY_Z_SPIN, m_VelocityZSpin);
|
||||
DDX_Control(pDX, IDC_VELOCITY_Y_SPIN, m_VelocityYSpin);
|
||||
DDX_Control(pDX, IDC_VELOCITY_X_SPIN, m_VelocityXSpin);
|
||||
DDX_Control(pDX, IDC_ACCELERATION_Z_SPIN, m_AccelZSpin);
|
||||
DDX_Control(pDX, IDC_ACCELERATION_Y_SPIN, m_AccelYSpin);
|
||||
DDX_Control(pDX, IDC_ACCELERATION_X_SPIN, m_AccelXSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(EmitterPhysicsPropPageClass, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(EmitterPhysicsPropPageClass)
|
||||
ON_BN_CLICKED(IDC_SPECIFY_VELOCITY_RANDOM, OnSpecifyVelocityRandom)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterPhysicsPropPageClass::Initialize (void)
|
||||
{
|
||||
SAFE_DELETE (m_Randomizer);
|
||||
if (m_pEmitterList != NULL) {
|
||||
|
||||
//
|
||||
// Get the emitter's settings
|
||||
//
|
||||
m_Velocity = m_pEmitterList->Get_Velocity ();
|
||||
m_Acceleration = m_pEmitterList->Get_Acceleration ();
|
||||
m_OutFactor = m_pEmitterList->Get_Outward_Vel ();
|
||||
m_InheritanceFactor = m_pEmitterList->Get_Vel_Inherit ();
|
||||
m_Randomizer = m_pEmitterList->Get_Velocity_Random ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterPhysicsPropPageClass::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::OnInitDialog ();
|
||||
|
||||
//
|
||||
// Setup the velocity controls
|
||||
//
|
||||
::Initialize_Spinner (m_OutSpin, m_OutFactor, -10000, 10000);
|
||||
::Initialize_Spinner (m_InheritanceSpin, m_InheritanceFactor, -10000, 10000);
|
||||
::Initialize_Spinner (m_VelocityXSpin, m_Velocity.X, -10000, 10000);
|
||||
::Initialize_Spinner (m_VelocityYSpin, m_Velocity.Y, -10000, 10000);
|
||||
::Initialize_Spinner (m_VelocityZSpin, m_Velocity.Z, -10000, 10000);
|
||||
|
||||
//
|
||||
// Setup the acceleration controls
|
||||
//
|
||||
::Initialize_Spinner (m_AccelXSpin, m_Acceleration.X, -10000, 10000);
|
||||
::Initialize_Spinner (m_AccelYSpin, m_Acceleration.Y, -10000, 10000);
|
||||
::Initialize_Spinner (m_AccelZSpin, m_Acceleration.Z, -10000, 10000);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnApply
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterPhysicsPropPageClass::OnApply (void)
|
||||
{
|
||||
//
|
||||
// Read the velocity settings
|
||||
//
|
||||
m_Velocity.X = ::GetDlgItemFloat (m_hWnd, IDC_VELOCITY_X_EDIT);
|
||||
m_Velocity.Y = ::GetDlgItemFloat (m_hWnd, IDC_VELOCITY_Y_EDIT);
|
||||
m_Velocity.Z = ::GetDlgItemFloat (m_hWnd, IDC_VELOCITY_Z_EDIT);
|
||||
m_OutFactor = ::GetDlgItemFloat (m_hWnd, IDC_OUT_FACTOR_SPIN);
|
||||
m_InheritanceFactor = ::GetDlgItemFloat (m_hWnd, IDC_INHERITANCE_FACTOR_SPIN);
|
||||
|
||||
//
|
||||
// Read the acceleration settings
|
||||
//
|
||||
m_Acceleration.X = ::GetDlgItemFloat (m_hWnd, IDC_ACCELERATION_X_EDIT);
|
||||
m_Acceleration.Y = ::GetDlgItemFloat (m_hWnd, IDC_ACCELERATION_Y_EDIT);
|
||||
m_Acceleration.Z = ::GetDlgItemFloat (m_hWnd, IDC_ACCELERATION_Z_EDIT);
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertyPage::OnApply ();
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterPhysicsPropPageClass::OnNotify
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
LRESULT *pResult
|
||||
)
|
||||
{
|
||||
//
|
||||
// Update the spinner control if necessary
|
||||
//
|
||||
NMHDR *pheader = (NMHDR *)lParam;
|
||||
if ((pheader != NULL) && (pheader->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN pupdown = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (pheader->hwndFrom, pupdown->iDelta);
|
||||
On_Setting_Changed (wParam);
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertyPage::OnNotify (wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSpecifyCreationVolume
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterPhysicsPropPageClass::OnSpecifyVelocityRandom (void)
|
||||
{
|
||||
VolumeRandomDialogClass dialog (m_Randomizer, this);
|
||||
if (dialog.DoModal () == IDOK) {
|
||||
|
||||
//
|
||||
// Get the new randomizer from the dialog
|
||||
//
|
||||
SAFE_DELETE (m_Randomizer);
|
||||
m_Randomizer = dialog.Get_Randomizer ();
|
||||
if (m_Randomizer != NULL) {
|
||||
m_pEmitterList->Set_Velocity_Random (m_Randomizer->Clone ());
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCommand
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterPhysicsPropPageClass::OnCommand
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
switch (LOWORD (wParam))
|
||||
{
|
||||
case IDC_VELOCITY_X_EDIT:
|
||||
case IDC_VELOCITY_Y_EDIT:
|
||||
case IDC_VELOCITY_Z_EDIT:
|
||||
{
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY)) {
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
On_Setting_Changed (LOWORD (wParam));
|
||||
} else if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_ACCELERATION_X_EDIT:
|
||||
case IDC_ACCELERATION_Y_EDIT:
|
||||
case IDC_ACCELERATION_Z_EDIT:
|
||||
{
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY)) {
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
On_Setting_Changed (LOWORD (wParam));
|
||||
} else if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_INHERITANCE_FACTOR_EDIT:
|
||||
{
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY)) {
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
On_Setting_Changed (LOWORD (wParam));
|
||||
} else if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_OUT_FACTOR_EDIT:
|
||||
{
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY)) {
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
On_Setting_Changed (LOWORD (wParam));
|
||||
} else if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CPropertyPage::OnCommand (wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// On_Setting_Changed
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterPhysicsPropPageClass::On_Setting_Changed (UINT ctrl_id)
|
||||
{
|
||||
switch (ctrl_id)
|
||||
{
|
||||
case IDC_VELOCITY_X_EDIT:
|
||||
case IDC_VELOCITY_Y_EDIT:
|
||||
case IDC_VELOCITY_Z_EDIT:
|
||||
case IDC_VELOCITY_X_SPIN:
|
||||
case IDC_VELOCITY_Y_SPIN:
|
||||
case IDC_VELOCITY_Z_SPIN:
|
||||
{
|
||||
Vector3 velocity;
|
||||
velocity.X = ::GetDlgItemFloat (m_hWnd, IDC_VELOCITY_X_EDIT);
|
||||
velocity.Y = ::GetDlgItemFloat (m_hWnd, IDC_VELOCITY_Y_EDIT);
|
||||
velocity.Z = ::GetDlgItemFloat (m_hWnd, IDC_VELOCITY_Z_EDIT);
|
||||
m_pEmitterList->Set_Velocity (velocity);
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_ACCELERATION_X_EDIT:
|
||||
case IDC_ACCELERATION_Y_EDIT:
|
||||
case IDC_ACCELERATION_Z_EDIT:
|
||||
case IDC_ACCELERATION_X_SPIN:
|
||||
case IDC_ACCELERATION_Y_SPIN:
|
||||
case IDC_ACCELERATION_Z_SPIN:
|
||||
{
|
||||
Vector3 acceleration;
|
||||
acceleration.X = ::GetDlgItemFloat (m_hWnd, IDC_ACCELERATION_X_EDIT);
|
||||
acceleration.Y = ::GetDlgItemFloat (m_hWnd, IDC_ACCELERATION_Y_EDIT);
|
||||
acceleration.Z = ::GetDlgItemFloat (m_hWnd, IDC_ACCELERATION_Z_EDIT);
|
||||
m_pEmitterList->Set_Acceleration (acceleration);
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_INHERITANCE_FACTOR_EDIT:
|
||||
case IDC_INHERITANCE_FACTOR_SPIN:
|
||||
{
|
||||
float value = ::GetDlgItemFloat (m_hWnd, IDC_INHERITANCE_FACTOR_EDIT);
|
||||
m_pEmitterList->Set_Vel_Inherit (value);
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_OUT_FACTOR_EDIT:
|
||||
case IDC_OUT_FACTOR_SPIN:
|
||||
{
|
||||
float value = ::GetDlgItemFloat (m_hWnd, IDC_OUT_FACTOR_EDIT);
|
||||
m_pEmitterList->Set_Outward_Vel (value);
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
129
Code/Tools/W3DView/EmitterPhysicsPropPage.h
Normal file
129
Code/Tools/W3DView/EmitterPhysicsPropPage.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
** 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_EMITTERPHYSICSPROPPAGE_H__83A8B83E_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
#define AFX_EMITTERPHYSICSPROPPAGE_H__83A8B83E_BA3B_11D2_9FFA_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// EmitterPhysicsPropPage.h : header file
|
||||
//
|
||||
|
||||
#include "Resource.H"
|
||||
#include "Vector3.H"
|
||||
|
||||
// Forward delcarations
|
||||
class EmitterInstanceListClass;
|
||||
class Vector3Randomizer;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterPhysicsPropPageClass dialog
|
||||
|
||||
class EmitterPhysicsPropPageClass : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(EmitterPhysicsPropPageClass)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
EmitterPhysicsPropPageClass (EmitterInstanceListClass *pemitter_list = NULL);
|
||||
~EmitterPhysicsPropPageClass ();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(EmitterPhysicsPropPageClass)
|
||||
enum { IDD = IDD_PROP_PAGE_EMITTER_PHYSICS };
|
||||
CSpinButtonCtrl m_OutSpin;
|
||||
CSpinButtonCtrl m_InheritanceSpin;
|
||||
CSpinButtonCtrl m_VelocityZSpin;
|
||||
CSpinButtonCtrl m_VelocityYSpin;
|
||||
CSpinButtonCtrl m_VelocityXSpin;
|
||||
CSpinButtonCtrl m_AccelZSpin;
|
||||
CSpinButtonCtrl m_AccelYSpin;
|
||||
CSpinButtonCtrl m_AccelXSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(EmitterPhysicsPropPageClass)
|
||||
public:
|
||||
virtual BOOL OnApply();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(EmitterPhysicsPropPageClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnSpecifyVelocityRandom();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
//
|
||||
// Inline accessors
|
||||
//
|
||||
EmitterInstanceListClass * Get_Emitter (void) const { return m_pEmitterList; }
|
||||
void Set_Emitter (EmitterInstanceListClass *pemitter_list) { m_pEmitterList = pemitter_list; Initialize (); }
|
||||
bool Is_Data_Valid (void) const { return m_bValid; }
|
||||
|
||||
Vector3Randomizer * Get_Velocity_Random (void) const { return m_Randomizer; }
|
||||
const Vector3 & Get_Velocity (void) const { return m_Velocity; }
|
||||
const Vector3 & Get_Acceleration (void) const { return m_Acceleration; }
|
||||
float Get_Out_Factor (void) const { return m_OutFactor; }
|
||||
float Get_Inheritance_Factor (void) const { return m_InheritanceFactor; }
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Initialize (void);
|
||||
void On_Setting_Changed (UINT ctrl_id);
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
EmitterInstanceListClass * m_pEmitterList;
|
||||
bool m_bValid;
|
||||
|
||||
Vector3 m_Velocity;
|
||||
Vector3 m_Acceleration;
|
||||
float m_OutFactor;
|
||||
float m_InheritanceFactor;
|
||||
Vector3Randomizer * m_Randomizer;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EMITTERPHYSICSPROPPAGE_H__83A8B83E_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
521
Code/Tools/W3DView/EmitterPropertySheet.cpp
Normal file
521
Code/Tools/W3DView/EmitterPropertySheet.cpp
Normal file
@@ -0,0 +1,521 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : W3DView *
|
||||
* *
|
||||
* $Archive:: /VSS_Sync/W3DView/EmitterPropertySheet.cpp $Modtime:: $*
|
||||
* *
|
||||
* $Revision:: 12 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "StdAfx.H"
|
||||
#include "W3DView.H"
|
||||
#include "EmitterPropertySheet.H"
|
||||
#include "Part_Emt.H"
|
||||
#include "Part_Ldr.H"
|
||||
#include "AssetMgr.H"
|
||||
#include "W3DViewDoc.H"
|
||||
#include "Utils.H"
|
||||
#include "DataTreeView.H"
|
||||
#include "AssetInfo.H"
|
||||
#include "texture.h"
|
||||
#include "EmitterInstanceList.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterPropertySheetClass
|
||||
|
||||
IMPLEMENT_DYNAMIC(EmitterPropertySheetClass, CPropertySheet)
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterPropertySheetClass
|
||||
//
|
||||
EmitterPropertySheetClass::EmitterPropertySheetClass
|
||||
(
|
||||
EmitterInstanceListClass *emitter_list,
|
||||
UINT nIDCaption,
|
||||
CWnd *pParentWnd
|
||||
)
|
||||
: m_pEmitterList (NULL),
|
||||
CPropertySheet (nIDCaption, pParentWnd, 0)
|
||||
{
|
||||
m_pEmitterList = emitter_list;
|
||||
Initialize ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterPropertySheetClass
|
||||
//
|
||||
EmitterPropertySheetClass::EmitterPropertySheetClass
|
||||
(
|
||||
EmitterInstanceListClass *emitter_list,
|
||||
LPCTSTR pszCaption,
|
||||
CWnd *pParentWnd
|
||||
)
|
||||
: m_pEmitterList (NULL),
|
||||
CPropertySheet (pszCaption, pParentWnd, 0)
|
||||
{
|
||||
m_pEmitterList = emitter_list;
|
||||
Initialize ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterPropertySheetClass
|
||||
//
|
||||
EmitterPropertySheetClass::~EmitterPropertySheetClass (void)
|
||||
{
|
||||
SAFE_DELETE (m_pEmitterList);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(EmitterPropertySheetClass, CPropertySheet)
|
||||
//{{AFX_MSG_MAP(EmitterPropertySheetClass)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterPropertySheetClass message handlers
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterPropertySheetClass
|
||||
//
|
||||
LRESULT
|
||||
EmitterPropertySheetClass::WindowProc
|
||||
(
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
// Is a control sending us an oldstyle notification?
|
||||
case WM_COMMAND:
|
||||
{
|
||||
// What control sent the notification?
|
||||
switch (LOWORD (wParam))
|
||||
{
|
||||
case IDCANCEL:
|
||||
{
|
||||
::GetCurrentDocument ()->Reload_Displayed_Object ();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDOK:
|
||||
{
|
||||
// If the apply button isn't enabled, then don't do the apply operation.
|
||||
if (::IsWindowEnabled (::GetDlgItem (m_hWnd, ID_APPLY_NOW)) == FALSE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
case ID_APPLY_NOW:
|
||||
{
|
||||
// Did the user click the button?
|
||||
if (HIWORD (wParam) == BN_CLICKED) {
|
||||
LRESULT lresult = CPropertySheet::WindowProc (message, wParam, lParam);
|
||||
|
||||
// If all the pages contain valid data, then update the emitter
|
||||
if (m_GeneralPage.Is_Data_Valid () &&
|
||||
m_ParticlePage.Is_Data_Valid () &&
|
||||
m_PhysicsPage.Is_Data_Valid () &&
|
||||
m_ColorPage.Is_Data_Valid () &&
|
||||
m_UserPage.Is_Data_Valid () &&
|
||||
m_SizePage.Is_Data_Valid () &&
|
||||
m_LinePage.Is_Data_Valid () &&
|
||||
m_RotationPage.Is_Data_Valid () &&
|
||||
m_FramePage.Is_Data_Valid () &&
|
||||
m_LineGroupPage.Is_Data_Valid () )
|
||||
{
|
||||
// Update the current emitter to match the data
|
||||
Update_Emitter ();
|
||||
}
|
||||
|
||||
return lresult;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertySheet::WindowProc (message, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Add_Emitter_To_Viewer
|
||||
//
|
||||
void
|
||||
EmitterPropertySheetClass::Add_Emitter_To_Viewer (void)
|
||||
{
|
||||
CW3DViewDoc *pdoc = ::GetCurrentDocument ();
|
||||
if ((pdoc != NULL) && (m_pEmitterList != NULL)) {
|
||||
|
||||
//
|
||||
// Create a new prototype for this emitter and add it to the asset manager
|
||||
//
|
||||
ParticleEmitterDefClass *pdefinition = new ParticleEmitterDefClass (*m_pEmitterList);
|
||||
ParticleEmitterPrototypeClass *pprototype = new ParticleEmitterPrototypeClass (pdefinition);
|
||||
|
||||
//
|
||||
// Update the asset manager with the new prototype
|
||||
//
|
||||
if (m_LastSavedName.GetLength () > 0) {
|
||||
WW3DAssetManager::Get_Instance()->Remove_Prototype (m_LastSavedName);
|
||||
}
|
||||
WW3DAssetManager::Get_Instance()->Add_Prototype (pprototype);
|
||||
|
||||
//
|
||||
// Add this emitter to the data tree
|
||||
//
|
||||
CDataTreeView *pdata_tree = pdoc->GetDataTreeView ();
|
||||
pdata_tree->Refresh_Asset (m_pEmitterList->Get_Name (), m_LastSavedName, TypeEmitter);
|
||||
/*if (m_LastSavedName.GetLength () > 0) {
|
||||
pdata_tree->Refresh_Asset (m_pEmitterList->Get_Name (), m_LastSavedName, TypeEmitter);
|
||||
} else {
|
||||
pdata_tree->Add_Asset_To_Tree (m_pEmitterList->Get_Name (), TypeEmitter, true);
|
||||
}*/
|
||||
|
||||
//
|
||||
// Display the emitter
|
||||
//
|
||||
pdoc->Reload_Displayed_Object ();
|
||||
m_LastSavedName = m_pEmitterList->Get_Name ();
|
||||
|
||||
//
|
||||
// Regenerate the emitter pointer list
|
||||
//
|
||||
m_pEmitterList->Free_List ();
|
||||
pdoc->Build_Emitter_List (m_pEmitterList, m_pEmitterList->Get_Name ());
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Emitter
|
||||
//
|
||||
void
|
||||
EmitterPropertySheetClass::Update_Emitter (void)
|
||||
{
|
||||
//
|
||||
// Update those pages that are dependant on the particle's
|
||||
// lifetime.
|
||||
//
|
||||
float lifetime = m_GeneralPage.Get_Lifetime ();
|
||||
m_ColorPage.On_Lifetime_Changed (lifetime);
|
||||
m_SizePage.On_Lifetime_Changed (lifetime);
|
||||
m_RotationPage.On_Lifetime_Changed (lifetime);
|
||||
m_FramePage.On_Lifetime_Changed (lifetime);
|
||||
m_LineGroupPage.On_Lifetime_Changed (lifetime);
|
||||
|
||||
Add_Emitter_To_Viewer ();
|
||||
|
||||
//
|
||||
// Create a new emitter
|
||||
//
|
||||
/*ParticleEmitterClass *pemitter = Create_Emitter ();
|
||||
Add_Emitter_To_Viewer (pemitter);
|
||||
|
||||
//
|
||||
// Use this emitter as the edited emitter from here on out
|
||||
//
|
||||
MEMBER_RELEASE (m_pEmitter);
|
||||
m_pEmitter = pemitter;*/
|
||||
|
||||
// Pass the emitter along to the pages
|
||||
/*m_GeneralPage.Set_Emitter (m_pEmitterList);
|
||||
m_ParticlePage.Set_Emitter (m_pEmitterList);
|
||||
m_PhysicsPage.Set_Emitter (m_pEmitterList);
|
||||
m_ColorPage.Set_Emitter (m_pEmitterList);
|
||||
m_UserPage.Set_Emitter (m_pEmitterList);
|
||||
m_SizePage.Set_Emitter (m_pEmitterList);*/
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
void
|
||||
EmitterPropertySheetClass::Initialize (void)
|
||||
{
|
||||
if (m_pEmitterList == NULL) {
|
||||
Create_New_Emitter ();
|
||||
} else {
|
||||
m_LastSavedName = m_pEmitterList->Get_Name ();
|
||||
}
|
||||
|
||||
// Pass the emitter along to the pages
|
||||
m_GeneralPage.Set_Emitter (m_pEmitterList);
|
||||
m_ParticlePage.Set_Emitter (m_pEmitterList);
|
||||
m_PhysicsPage.Set_Emitter (m_pEmitterList);
|
||||
m_ColorPage.Set_Emitter (m_pEmitterList);
|
||||
m_UserPage.Set_Emitter (m_pEmitterList);
|
||||
m_SizePage.Set_Emitter (m_pEmitterList);
|
||||
m_LinePage.Set_Emitter (m_pEmitterList);
|
||||
m_RotationPage.Set_Emitter (m_pEmitterList);
|
||||
m_FramePage.Set_Emitter (m_pEmitterList);
|
||||
m_LineGroupPage.Set_Emitter (m_pEmitterList);
|
||||
|
||||
// Initialize the user page with data from the prototype
|
||||
/*if (m_pEmitter != NULL) {
|
||||
ParticleEmitterPrototypeClass *proto = NULL;
|
||||
proto = (ParticleEmitterPrototypeClass *)WW3DAssetManager::Get_Instance ()->Find_Prototype (m_pEmitter->Get_Name ());
|
||||
if (proto != NULL) {
|
||||
ParticleEmitterDefClass *definition = proto->Get_Definition ();
|
||||
m_UserPage.Set_Type (definition->Get_User_Type ());
|
||||
m_UserPage.Set_String (definition->Get_User_String ());
|
||||
}
|
||||
}*/
|
||||
|
||||
// Add the pages to the sheet
|
||||
AddPage (&m_GeneralPage);
|
||||
AddPage (&m_ParticlePage);
|
||||
AddPage (&m_PhysicsPage);
|
||||
AddPage (&m_ColorPage);
|
||||
AddPage (&m_SizePage);
|
||||
AddPage (&m_UserPage);
|
||||
AddPage (&m_LinePage);
|
||||
AddPage (&m_RotationPage);
|
||||
AddPage (&m_FramePage);
|
||||
AddPage (&m_LineGroupPage);
|
||||
|
||||
m_GeneralPage.Set_Parent(this);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Create_Emitter
|
||||
//
|
||||
/*ParticleEmitterClass *
|
||||
EmitterPropertySheetClass::Create_Emitter (void)
|
||||
{
|
||||
//
|
||||
// Read the particle settings
|
||||
//
|
||||
float rate = m_ParticlePage.Get_Rate ();
|
||||
int burst = m_ParticlePage.Get_Burst_Size ();
|
||||
float max_particles = m_ParticlePage.Get_Max_Particles ();
|
||||
|
||||
//
|
||||
// Read the physics settings
|
||||
//
|
||||
Vector3 velocity = m_PhysicsPage.Get_Velocity ();
|
||||
Vector3 acceleration = m_PhysicsPage.Get_Acceleration ();
|
||||
float out_factor = m_PhysicsPage.Get_Out_Factor ();
|
||||
float inherit_factor = m_PhysicsPage.Get_Inheritance_Factor ();
|
||||
|
||||
//
|
||||
// Read the general settings
|
||||
//
|
||||
CString name = m_GeneralPage.Get_Name ();
|
||||
CString texture_name = m_GeneralPage.Get_Texture_Filename ();
|
||||
float lifetime = m_GeneralPage.Get_Lifetime ();
|
||||
ShaderClass shader = m_GeneralPage.Get_Shader ();
|
||||
|
||||
//
|
||||
// Read the keyframe settings
|
||||
//
|
||||
ParticlePropertyStruct<Vector3> colors;
|
||||
ParticlePropertyStruct<float> opacity;
|
||||
ParticlePropertyStruct<float> size;
|
||||
m_ColorPage.Get_Color_Keyframes (colors);
|
||||
m_ColorPage.Get_Opacity_Keyframes (opacity);
|
||||
m_SizePage.Get_Size_Keyframes (size);
|
||||
|
||||
//
|
||||
// Read the randomizers
|
||||
//
|
||||
Vector3Randomizer *creation_vol = m_ParticlePage.Get_Creation_Volume ();
|
||||
Vector3Randomizer *vel_random = m_PhysicsPage.Get_Velocity_Random ();
|
||||
|
||||
//
|
||||
// Load the texture
|
||||
//
|
||||
TextureClass *ptexture = NULL;
|
||||
if (texture_name.GetLength () > 0) {
|
||||
ptexture = WW3DAssetManager::Get_Instance()->Get_Texture (texture_name);
|
||||
}
|
||||
|
||||
//
|
||||
// Create the new particle emitter
|
||||
//
|
||||
ParticleEmitterClass *pemitter = new ParticleEmitterClass (rate,
|
||||
burst,
|
||||
creation_vol,
|
||||
velocity,
|
||||
vel_random,
|
||||
out_factor,
|
||||
inherit_factor,
|
||||
colors,
|
||||
opacity,
|
||||
size,
|
||||
acceleration,
|
||||
lifetime,
|
||||
ptexture,
|
||||
shader,
|
||||
max_particles);
|
||||
|
||||
|
||||
//
|
||||
// Pass the name onto the emitter
|
||||
//
|
||||
pemitter->Set_Name (name);
|
||||
|
||||
// Return the emitter
|
||||
return pemitter;
|
||||
}*/
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Create_New_Emitter
|
||||
//
|
||||
void
|
||||
EmitterPropertySheetClass::Create_New_Emitter (void)
|
||||
{
|
||||
ParticlePropertyStruct<Vector3> color;
|
||||
color.Start = Vector3 (1, 1, 1);
|
||||
color.Rand.Set (0,0,0);
|
||||
color.NumKeyFrames = 0;
|
||||
color.KeyTimes = NULL;
|
||||
color.Values = NULL;
|
||||
|
||||
ParticlePropertyStruct<float> opacity;
|
||||
opacity.Start = 1.0F;
|
||||
opacity.Rand = 0.0F;
|
||||
opacity.NumKeyFrames = 0;
|
||||
opacity.KeyTimes = NULL;
|
||||
opacity.Values = NULL;
|
||||
|
||||
ParticlePropertyStruct<float> size;
|
||||
size.Start = 0.1F;
|
||||
size.Rand = 0.0F;
|
||||
size.NumKeyFrames = 0;
|
||||
size.KeyTimes = NULL;
|
||||
size.Values = NULL;
|
||||
|
||||
ParticlePropertyStruct<float> rotation;
|
||||
rotation.Start = 0.0f;
|
||||
rotation.Rand = 0.0f;
|
||||
rotation.NumKeyFrames = 0;
|
||||
rotation.KeyTimes = NULL;
|
||||
rotation.Values = NULL;
|
||||
|
||||
ParticlePropertyStruct<float> frames;
|
||||
frames.Start = 0.0f;
|
||||
frames.Rand = 0.0f;
|
||||
frames.NumKeyFrames = 0;
|
||||
frames.KeyTimes = NULL;
|
||||
frames.Values = NULL;
|
||||
|
||||
ParticlePropertyStruct<float> blurtimes;
|
||||
blurtimes.Start = 0.0f;
|
||||
blurtimes.Rand = 0.0f;
|
||||
blurtimes.NumKeyFrames = 0;
|
||||
blurtimes.KeyTimes = NULL;
|
||||
blurtimes.Values = NULL;
|
||||
|
||||
//
|
||||
// Create the new emitter
|
||||
//
|
||||
ParticleEmitterClass *emitter = NULL;
|
||||
emitter = new ParticleEmitterClass (10,
|
||||
1,
|
||||
new Vector3SolidBoxRandomizer(Vector3(0.1F, 0.1F, 0.1F)),
|
||||
Vector3 (0, 0, 1),
|
||||
new Vector3SolidBoxRandomizer(Vector3(0, 0, 0.1F)),
|
||||
0,
|
||||
0,
|
||||
color,
|
||||
opacity,
|
||||
size,
|
||||
rotation,
|
||||
0.0f,
|
||||
frames,
|
||||
blurtimes,
|
||||
Vector3 (0, 0, 0),
|
||||
1.0F,
|
||||
NULL,
|
||||
ShaderClass::_PresetAdditiveSpriteShader,
|
||||
0);
|
||||
|
||||
//
|
||||
// Create the new emitter list
|
||||
//
|
||||
m_pEmitterList = new EmitterInstanceListClass;
|
||||
m_pEmitterList->Add_Emitter (emitter);
|
||||
|
||||
//
|
||||
// Display the new emitter
|
||||
//
|
||||
::GetCurrentDocument ()->Display_Emitter (emitter);
|
||||
MEMBER_RELEASE (emitter);
|
||||
|
||||
/*SAFE_DELETE_ARRAY (color.Values);
|
||||
SAFE_DELETE_ARRAY (color.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (opacity.Values);
|
||||
SAFE_DELETE_ARRAY (opacity.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (size.Values);
|
||||
SAFE_DELETE_ARRAY (size.KeyTimes);*/
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EmitterPropertySheetClass::Notify_Render_Mode_Changed(int new_mode)
|
||||
{
|
||||
bool enable_line_page = (new_mode == W3D_EMITTER_RENDER_MODE_LINE);
|
||||
::Enable_Dialog_Controls(m_LinePage,enable_line_page);
|
||||
}
|
||||
|
||||
128
Code/Tools/W3DView/EmitterPropertySheet.h
Normal file
128
Code/Tools/W3DView/EmitterPropertySheet.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
** 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_EMITTERPROPERTYSHEET_H__83A8B844_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
#define AFX_EMITTERPROPERTYSHEET_H__83A8B844_BA3B_11D2_9FFA_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// EmitterPropertySheet.h : header file
|
||||
//
|
||||
|
||||
#include "EmitterColorPropPage.H"
|
||||
#include "EmitterGeneralPropPage.H"
|
||||
#include "EmitterParticlePropPage.H"
|
||||
#include "EmitterPhysicsPropPage.H"
|
||||
#include "EmitterSizePropPage.H"
|
||||
#include "EmitterUserPropPage.H"
|
||||
#include "EmitterLinePropPage.H"
|
||||
#include "EmitterRotationPropPage.H"
|
||||
#include "EmitterFramePropPage.H"
|
||||
#include "EmitterLineGroupPropPage.H"
|
||||
|
||||
// Forward declarations
|
||||
class ParticleEmitterClass;
|
||||
class EmitterInstanceListClass;
|
||||
class AssetInfoClass;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterPropertySheetClass
|
||||
//
|
||||
class EmitterPropertySheetClass : public CPropertySheet
|
||||
{
|
||||
DECLARE_DYNAMIC(EmitterPropertySheetClass)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
EmitterPropertySheetClass (EmitterInstanceListClass *emitter_list, UINT nIDCaption, CWnd* pParentWnd = NULL);
|
||||
EmitterPropertySheetClass (EmitterInstanceListClass *emitter_list, LPCTSTR pszCaption, CWnd* pParentWnd = NULL);
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(EmitterPropertySheetClass)
|
||||
protected:
|
||||
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~EmitterPropertySheetClass();
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(EmitterPropertySheetClass)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
void Notify_Render_Mode_Changed(int new_mode);
|
||||
|
||||
protected:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Initialize (void);
|
||||
ParticleEmitterClass * Create_Emitter (void);
|
||||
void Update_Emitter (void);
|
||||
void Add_Emitter_To_Viewer (void);
|
||||
void Create_New_Emitter (void);
|
||||
|
||||
private:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
EmitterGeneralPropPageClass m_GeneralPage;
|
||||
EmitterParticlePropPageClass m_ParticlePage;
|
||||
EmitterPhysicsPropPageClass m_PhysicsPage;
|
||||
EmitterColorPropPageClass m_ColorPage;
|
||||
EmitterUserPropPageClass m_UserPage;
|
||||
EmitterSizePropPageClass m_SizePage;
|
||||
EmitterLinePropPageClass m_LinePage;
|
||||
EmitterRotationPropPageClass m_RotationPage;
|
||||
EmitterFramePropPageClass m_FramePage;
|
||||
EmitterLineGroupPropPageClass m_LineGroupPage;
|
||||
|
||||
EmitterInstanceListClass * m_pEmitterList;
|
||||
CString m_LastSavedName;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EMITTERPROPERTYSHEET_H__83A8B844_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
420
Code/Tools/W3DView/EmitterRotationPropPage.cpp
Normal file
420
Code/Tools/W3DView/EmitterRotationPropPage.cpp
Normal file
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// EmitterRotationPropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "EmitterRotationPropPage.h"
|
||||
#include "Utils.H"
|
||||
#include "ParticleRotationKeyDialog.H"
|
||||
#include "EmitterInstanceList.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterRotationPropPageClass property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(EmitterRotationPropPageClass, CPropertyPage)
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterRotationPropPageClass - constructor
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
EmitterRotationPropPageClass::EmitterRotationPropPageClass() :
|
||||
CPropertyPage(EmitterRotationPropPageClass::IDD),
|
||||
m_pEmitterList(NULL),
|
||||
m_bValid(true),
|
||||
m_RotationBar(NULL),
|
||||
m_Lifetime(0),
|
||||
m_MinRotation(0),
|
||||
m_MaxRotation(1),
|
||||
m_InitialOrientationRandom(0)
|
||||
|
||||
{
|
||||
::memset (&m_Rotations, 0, sizeof (m_Rotations));
|
||||
|
||||
//{{AFX_DATA_INIT(EmitterRotationPropPageClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~EmitterRotationPropPageClass - destructor
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
EmitterRotationPropPageClass::~EmitterRotationPropPageClass()
|
||||
{
|
||||
// Free the rotation arrays
|
||||
SAFE_DELETE_ARRAY (m_Rotations.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_Rotations.Values);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void EmitterRotationPropPageClass::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(EmitterRotationPropPageClass)
|
||||
DDX_Control(pDX, IDC_INITIAL_ORIENTATION_RANDOM_SPIN, m_InitialOrientationRandomSpin);
|
||||
DDX_Control(pDX, IDC_ROTATION_RANDOM_SPIN, m_RotationRandomSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(EmitterRotationPropPageClass, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(EmitterRotationPropPageClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterRotationPropPageClass message handlers
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void EmitterRotationPropPageClass::Initialize (void)
|
||||
{
|
||||
SAFE_DELETE_ARRAY (m_Rotations.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_Rotations.Values);
|
||||
|
||||
if (m_pEmitterList != NULL) {
|
||||
m_Lifetime = m_pEmitterList->Get_Lifetime ();
|
||||
m_pEmitterList->Get_Rotation_Keyframes (m_Rotations);
|
||||
m_InitialOrientationRandom = m_pEmitterList->Get_Initial_Orientation_Random();
|
||||
|
||||
//
|
||||
// Determine what the min and max rotations are
|
||||
//
|
||||
m_MaxRotation = WWMath::Max(m_Rotations.Start,1.0f);
|
||||
m_MinRotation = WWMath::Min(m_Rotations.Start,0.0f);
|
||||
|
||||
for (UINT index = 0; index < m_Rotations.NumKeyFrames; index ++) {
|
||||
if (m_Rotations.Values[index] > m_MaxRotation) {
|
||||
m_MaxRotation = m_Rotations.Values[index];
|
||||
}
|
||||
if (m_Rotations.Values[index] < m_MinRotation) {
|
||||
m_MinRotation = m_Rotations.Values[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterRotationPropPageClass::OnInitDialog()
|
||||
{
|
||||
CPropertyPage::OnInitDialog();
|
||||
|
||||
//
|
||||
// Create the keyframe control
|
||||
//
|
||||
m_RotationBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_ROTATION_BAR));
|
||||
|
||||
//
|
||||
// Setup the spinners
|
||||
//
|
||||
Initialize_Spinner (m_RotationRandomSpin, m_Rotations.Rand, 0, 10000);
|
||||
Initialize_Spinner (m_InitialOrientationRandomSpin, m_InitialOrientationRandom, 0, 10000);
|
||||
|
||||
//
|
||||
// Reset the color bars
|
||||
//
|
||||
m_RotationBar->Set_Range (0, 1);
|
||||
m_RotationBar->Clear_Points ();
|
||||
m_RotationBar->Modify_Point (0, 0, 0, 0, 0);
|
||||
m_RotationBar->Set_Graph_Percent (0, Normalize_Rotation(m_Rotations.Start));
|
||||
|
||||
//
|
||||
// Load the current set of frame keyframes into the control
|
||||
//
|
||||
for (UINT index = 0; index < m_Rotations.NumKeyFrames; index ++) {
|
||||
m_RotationBar->Modify_Point (index + 1,
|
||||
m_Rotations.KeyTimes[index] / m_Lifetime,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
m_RotationBar->Set_Graph_Percent (index + 1, Normalize_Rotation(m_Rotations.Values[index]));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL EmitterRotationPropPageClass::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
||||
{
|
||||
CBR_NMHDR *color_bar_hdr = (CBR_NMHDR *)lParam;
|
||||
|
||||
//
|
||||
// Update the spinner controls if necessary
|
||||
//
|
||||
NMHDR *pheader = (NMHDR *)lParam;
|
||||
if ((pheader != NULL) && (pheader->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN pupdown = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (pheader->hwndFrom, pupdown->iDelta);
|
||||
}
|
||||
|
||||
//
|
||||
// Which control sent the notification?
|
||||
//
|
||||
switch (color_bar_hdr->hdr.idFrom)
|
||||
{
|
||||
case IDC_ROTATION_BAR:
|
||||
{
|
||||
if (color_bar_hdr->hdr.code == CBRN_DBLCLK_POINT) {
|
||||
|
||||
//
|
||||
// Allow the user to edit the keyframe
|
||||
//
|
||||
float rotation = Denormalize_Rotation(m_RotationBar->Get_Graph_Percent (color_bar_hdr->key_index));
|
||||
|
||||
ParticleRotationKeyDialogClass dialog (rotation, this);
|
||||
if (dialog.DoModal () == IDOK) {
|
||||
rotation = dialog.Get_Rotation ();
|
||||
float norm_val = Normalize_Rotation(rotation);
|
||||
|
||||
m_RotationBar->Set_Redraw (false);
|
||||
m_RotationBar->Set_Graph_Percent (color_bar_hdr->key_index, norm_val);
|
||||
|
||||
//
|
||||
// Determine if the user changed the 'max' or 'min' rotation
|
||||
//
|
||||
float new_max = WWMath::Max(rotation,1.0f);
|
||||
float new_min = WWMath::Min(rotation,0.0f);
|
||||
|
||||
int count = m_RotationBar->Get_Point_Count ();
|
||||
for (int index = 0; index < count; index ++) {
|
||||
float tmp = Denormalize_Rotation(m_RotationBar->Get_Graph_Percent (index) );
|
||||
if (tmp > new_max) {
|
||||
new_max = tmp;
|
||||
}
|
||||
if (tmp < new_min) {
|
||||
new_min = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Renormalize the RotationBar key frame points if necessary
|
||||
//
|
||||
if ((new_max != m_MaxRotation) || (new_min != m_MinRotation)) {
|
||||
|
||||
int count = m_RotationBar->Get_Point_Count ();
|
||||
for (int index = 0; index < count; index ++) {
|
||||
|
||||
float rotation = Denormalize_Rotation(m_RotationBar->Get_Graph_Percent (index));
|
||||
float new_norm = Normalize_Rotation(rotation,new_min,new_max);
|
||||
|
||||
m_RotationBar->Set_Graph_Percent (index, new_norm);
|
||||
}
|
||||
|
||||
// Remember the new min and max
|
||||
m_MinRotation = new_min;
|
||||
m_MaxRotation = new_max;
|
||||
}
|
||||
m_RotationBar->Set_Redraw (true);
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
Update_Rotations ();
|
||||
m_pEmitterList->Set_Rotation_Keyframes (m_Rotations, m_InitialOrientationRandom);
|
||||
SetModified ();
|
||||
}
|
||||
} else if ((color_bar_hdr->hdr.code == CBRN_MOVING_POINT) ||
|
||||
(color_bar_hdr->hdr.code == CBRN_DELETED_POINT)) {
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
Update_Rotations ();
|
||||
m_pEmitterList->Set_Rotation_Keyframes (m_Rotations, m_InitialOrientationRandom);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_ROTATION_RANDOM_SPIN:
|
||||
{
|
||||
// Update the emitter
|
||||
m_Rotations.Rand = ::GetDlgItemFloat (m_hWnd, IDC_ROTATION_RANDOM_EDIT);
|
||||
m_pEmitterList->Set_Rotation_Keyframes (m_Rotations, m_InitialOrientationRandom);
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_INITIAL_ORIENTATION_RANDOM_SPIN:
|
||||
{
|
||||
// Update the emitter
|
||||
m_InitialOrientationRandom = ::GetDlgItemFloat (m_hWnd, IDC_INITIAL_ORIENTATION_RANDOM_EDIT);
|
||||
m_pEmitterList->Set_Rotation_Keyframes (m_Rotations, m_InitialOrientationRandom);
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return CPropertyPage::OnNotify (wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Rotations
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterRotationPropPageClass::Update_Rotations (void)
|
||||
{
|
||||
float position = 0;
|
||||
float red = 0;
|
||||
float green = 0;
|
||||
float blue = 0;
|
||||
|
||||
//
|
||||
// Setup the initial or 'starting' size
|
||||
//
|
||||
m_Rotations.Start = Denormalize_Rotation(m_RotationBar->Get_Graph_Percent (0));
|
||||
|
||||
//
|
||||
// Free the current setting arrays
|
||||
//
|
||||
SAFE_DELETE_ARRAY (m_Rotations.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_Rotations.Values);
|
||||
|
||||
//
|
||||
// Determine if we need to build the array of key frames or not
|
||||
//
|
||||
int count = m_RotationBar->Get_Point_Count ();
|
||||
m_Rotations.NumKeyFrames = count - 1;
|
||||
if (count > 1) {
|
||||
m_Rotations.KeyTimes = new float[count - 1];
|
||||
m_Rotations.Values = new float[count - 1];
|
||||
|
||||
//
|
||||
// Get all the rotation key frames and add them to our structure
|
||||
//
|
||||
for (int index = 1; index < count; index ++) {
|
||||
m_RotationBar->Get_Point (index, &position, &red, &green, &blue);
|
||||
m_Rotations.KeyTimes[index - 1] = position * m_Lifetime;
|
||||
m_Rotations.Values[index - 1] = Denormalize_Rotation(m_RotationBar->Get_Graph_Percent (index) );
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCommand
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterRotationPropPageClass::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (LOWORD (wParam))
|
||||
{
|
||||
case IDC_ROTATION_RANDOM_EDIT:
|
||||
{
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY)) {
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
|
||||
m_Rotations.Rand = ::GetDlgItemFloat (m_hWnd, IDC_ROTATION_RANDOM_EDIT);
|
||||
m_pEmitterList->Set_Rotation_Keyframes (m_Rotations, m_InitialOrientationRandom);
|
||||
SetModified ();
|
||||
} else if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_INITIAL_ORIENTATION_RANDOM_EDIT:
|
||||
{
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY)) {
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
|
||||
m_InitialOrientationRandom = ::GetDlgItemFloat (m_hWnd, IDC_INITIAL_ORIENTATION_RANDOM_EDIT);
|
||||
m_pEmitterList->Set_Rotation_Keyframes (m_Rotations, m_InitialOrientationRandom);
|
||||
SetModified ();
|
||||
} else if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return CPropertyPage::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// On_Lifetime_Changed
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterRotationPropPageClass::On_Lifetime_Changed (float lifetime)
|
||||
{
|
||||
if (m_Lifetime != lifetime) {
|
||||
float conversion = lifetime / m_Lifetime;
|
||||
|
||||
//
|
||||
// Rescale the sizes
|
||||
//
|
||||
for (UINT index = 0; index < m_Rotations.NumKeyFrames; index ++) {
|
||||
m_Rotations.KeyTimes[index] *= conversion;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
m_pEmitterList->Set_Rotation_Keyframes (m_Rotations, m_InitialOrientationRandom);
|
||||
m_Lifetime = lifetime;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
143
Code/Tools/W3DView/EmitterRotationPropPage.h
Normal file
143
Code/Tools/W3DView/EmitterRotationPropPage.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
** 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_EMITTERROTATIONPROPPAGE_H__35F8A2F6_C91C_4750_BF06_100433C1ECBB__INCLUDED_)
|
||||
#define AFX_EMITTERROTATIONPROPPAGE_H__35F8A2F6_C91C_4750_BF06_100433C1ECBB__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// EmitterRotationPropPage.h : header file
|
||||
//
|
||||
|
||||
#include "ColorBar.H"
|
||||
#include "Part_Emt.H"
|
||||
|
||||
// Forward delcarations
|
||||
class EmitterInstanceListClass;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterRotationPropPageClass dialog
|
||||
|
||||
class EmitterRotationPropPageClass : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(EmitterRotationPropPageClass)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
EmitterRotationPropPageClass();
|
||||
~EmitterRotationPropPageClass();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(EmitterRotationPropPageClass)
|
||||
enum { IDD = IDD_PROP_PAGE_EMITTER_ROTATION };
|
||||
CSpinButtonCtrl m_InitialOrientationRandomSpin;
|
||||
CSpinButtonCtrl m_RotationRandomSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(EmitterRotationPropPageClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(EmitterRotationPropPageClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
//
|
||||
// Inline accessors
|
||||
//
|
||||
EmitterInstanceListClass * Get_Emitter (void) const { return m_pEmitterList; }
|
||||
void Set_Emitter (EmitterInstanceListClass *pemitter_list) { m_pEmitterList = pemitter_list; Initialize (); }
|
||||
bool Is_Data_Valid (void) const { return m_bValid; }
|
||||
|
||||
void Get_Rotation_Keyframes (ParticlePropertyStruct<float> &rotations) { rotations = m_Rotations; }
|
||||
void On_Lifetime_Changed (float lifetime);
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Initialize (void);
|
||||
void Update_Rotations (void);
|
||||
|
||||
private:
|
||||
|
||||
float Normalize_Rotation(float rot);
|
||||
float Normalize_Rotation(float rot,float min,float max);
|
||||
float Denormalize_Rotation(float normalized_val);
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
EmitterInstanceListClass * m_pEmitterList;
|
||||
bool m_bValid;
|
||||
ColorBarClass * m_RotationBar;
|
||||
|
||||
ParticlePropertyStruct<float> m_Rotations;
|
||||
|
||||
float m_Lifetime;
|
||||
float m_MinRotation;
|
||||
float m_MaxRotation;
|
||||
float m_InitialOrientationRandom;
|
||||
|
||||
};
|
||||
|
||||
inline float EmitterRotationPropPageClass::Normalize_Rotation(float rot)
|
||||
{
|
||||
return (rot - m_MinRotation) / (m_MaxRotation - m_MinRotation);
|
||||
}
|
||||
|
||||
inline float EmitterRotationPropPageClass::Normalize_Rotation(float rot,float min,float max)
|
||||
{
|
||||
return (rot - min) / (max - min);
|
||||
}
|
||||
|
||||
inline float EmitterRotationPropPageClass::Denormalize_Rotation(float normalized_val)
|
||||
{
|
||||
return normalized_val * (m_MaxRotation - m_MinRotation) + m_MinRotation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EMITTERROTATIONPROPPAGE_H__35F8A2F6_C91C_4750_BF06_100433C1ECBB__INCLUDED_)
|
||||
416
Code/Tools/W3DView/EmitterSizePropPage.cpp
Normal file
416
Code/Tools/W3DView/EmitterSizePropPage.cpp
Normal file
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// EmitterSizePropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "Stdafx.H"
|
||||
#include "W3dview.H"
|
||||
#include "EmitterSizePropPage.H"
|
||||
#include "Utils.H"
|
||||
#include "ParticleSizeDialog.H"
|
||||
#include "EmitterInstanceList.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterSizePropPageClass property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(EmitterSizePropPageClass, CPropertyPage)
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterSizePropPageClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
EmitterSizePropPageClass::EmitterSizePropPageClass (EmitterInstanceListClass *pemitter)
|
||||
: m_pEmitterList (NULL),
|
||||
m_bValid (true),
|
||||
m_SizeBar (NULL),
|
||||
m_Lifetime (0),
|
||||
CPropertyPage(EmitterSizePropPageClass::IDD)
|
||||
{
|
||||
::memset (&m_OrigSizes, 0, sizeof (m_OrigSizes));
|
||||
::memset (&m_CurrentSizes, 0, sizeof (m_CurrentSizes));
|
||||
|
||||
//{{AFX_DATA_INIT(EmitterSizePropPageClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
Initialize ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~EmitterSizePropPageClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
EmitterSizePropPageClass::~EmitterSizePropPageClass (void)
|
||||
{
|
||||
// Free the original setting arrays
|
||||
SAFE_DELETE_ARRAY (m_OrigSizes.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_OrigSizes.Values);
|
||||
|
||||
// Free the current setting arrays
|
||||
SAFE_DELETE_ARRAY (m_CurrentSizes.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_CurrentSizes.Values);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterSizePropPageClass::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(EmitterSizePropPageClass)
|
||||
DDX_Control(pDX, IDC_SIZE_RANDOM_SPIN, m_SizeRandomSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(EmitterSizePropPageClass, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(EmitterSizePropPageClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterSizePropPageClass::Initialize (void)
|
||||
{
|
||||
SAFE_DELETE_ARRAY (m_OrigSizes.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_OrigSizes.Values);
|
||||
SAFE_DELETE_ARRAY (m_CurrentSizes.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_CurrentSizes.Values);
|
||||
|
||||
if (m_pEmitterList != NULL) {
|
||||
m_Lifetime = m_pEmitterList->Get_Lifetime ();
|
||||
m_pEmitterList->Get_Size_Keyframes (m_OrigSizes);
|
||||
m_pEmitterList->Get_Size_Keyframes (m_CurrentSizes);
|
||||
|
||||
//
|
||||
// Determine what the largest size is
|
||||
//
|
||||
m_MaxSize = m_OrigSizes.Start;
|
||||
for (UINT index = 0; index < m_OrigSizes.NumKeyFrames; index ++) {
|
||||
if (m_OrigSizes.Values[index] > m_MaxSize) {
|
||||
m_MaxSize = m_OrigSizes.Values[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterSizePropPageClass::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::OnInitDialog ();
|
||||
|
||||
m_SizeBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_SIZE_BAR));
|
||||
m_SizeBar->Set_Range (0, 1);
|
||||
|
||||
//
|
||||
// Setup the spinners
|
||||
//
|
||||
Initialize_Spinner (m_SizeRandomSpin, m_OrigSizes.Rand, 0, 10000);
|
||||
|
||||
//
|
||||
// Reset the color bars
|
||||
//
|
||||
m_SizeBar->Set_Range (0, 1);
|
||||
m_SizeBar->Clear_Points ();
|
||||
m_SizeBar->Modify_Point (0, 0, 0, 0, 0);
|
||||
m_SizeBar->Set_Graph_Percent (0, m_OrigSizes.Start / m_MaxSize);
|
||||
|
||||
//
|
||||
// Set-up the color bar
|
||||
//
|
||||
for (UINT index = 0; index < m_OrigSizes.NumKeyFrames; index ++) {
|
||||
m_SizeBar->Modify_Point (index + 1,
|
||||
m_OrigSizes.KeyTimes[index] / m_Lifetime,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
m_SizeBar->Set_Graph_Percent (index + 1, m_OrigSizes.Values[index] / m_MaxSize);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnApply
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterSizePropPageClass::OnApply (void)
|
||||
{
|
||||
/*SAFE_DELETE_ARRAY (m_OrigSizes.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_OrigSizes.Values);
|
||||
|
||||
//
|
||||
// Make the current values from the emitter the default values.
|
||||
//
|
||||
m_pEmitterList->Get_Size_Key_Frames (m_OrigSizes);*/
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertyPage::OnApply ();
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterSizePropPageClass::OnNotify
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
LRESULT *pResult
|
||||
)
|
||||
{
|
||||
CBR_NMHDR *color_bar_hdr = (CBR_NMHDR *)lParam;
|
||||
|
||||
//
|
||||
// Update the spinner controls if necessary
|
||||
//
|
||||
NMHDR *pheader = (NMHDR *)lParam;
|
||||
if ((pheader != NULL) && (pheader->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN pupdown = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (pheader->hwndFrom, pupdown->iDelta);
|
||||
}
|
||||
|
||||
//
|
||||
// Which control sent the notification?
|
||||
//
|
||||
switch (color_bar_hdr->hdr.idFrom)
|
||||
{
|
||||
case IDC_SIZE_BAR:
|
||||
{
|
||||
if (color_bar_hdr->hdr.code == CBRN_DBLCLK_POINT) {
|
||||
|
||||
//
|
||||
// Allow the user to edit the keyframe
|
||||
//
|
||||
float size = m_SizeBar->Get_Graph_Percent (color_bar_hdr->key_index) * m_MaxSize;
|
||||
ParticleSizeDialogClass dialog (size, this);
|
||||
if (dialog.DoModal () == IDOK) {
|
||||
size = dialog.Get_Size ();
|
||||
|
||||
m_SizeBar->Set_Redraw (false);
|
||||
m_SizeBar->Set_Graph_Percent (color_bar_hdr->key_index, size / m_MaxSize);
|
||||
|
||||
//
|
||||
// Determine if the user changed the 'max' size
|
||||
//
|
||||
float new_max = size;
|
||||
int count = m_SizeBar->Get_Point_Count ();
|
||||
for (int index = 0; index < count; index ++) {
|
||||
float size = m_SizeBar->Get_Graph_Percent (index) * m_MaxSize;
|
||||
if (size > new_max) {
|
||||
new_max = size;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Rescale the key frame points if necessary
|
||||
//
|
||||
if (new_max != m_MaxSize) {
|
||||
int count = m_SizeBar->Get_Point_Count ();
|
||||
for (int index = 0; index < count; index ++) {
|
||||
float percent = m_SizeBar->Get_Graph_Percent (index);
|
||||
m_SizeBar->Set_Graph_Percent (index, (percent * m_MaxSize) / new_max);
|
||||
}
|
||||
|
||||
// Remember the new size maximum
|
||||
m_MaxSize = new_max;
|
||||
}
|
||||
m_SizeBar->Set_Redraw (true);
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
Update_Sizes ();
|
||||
m_pEmitterList->Set_Size_Keyframes (m_CurrentSizes);
|
||||
SetModified ();
|
||||
}
|
||||
} else if ((color_bar_hdr->hdr.code == CBRN_MOVING_POINT) ||
|
||||
(color_bar_hdr->hdr.code == CBRN_DELETED_POINT)) {
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
Update_Sizes ();
|
||||
m_pEmitterList->Set_Size_Keyframes (m_CurrentSizes);
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_SIZE_RANDOM_SPIN:
|
||||
{
|
||||
// Update the emitter
|
||||
m_CurrentSizes.Rand = ::GetDlgItemFloat (m_hWnd, IDC_SIZE_RANDOM_EDIT);
|
||||
m_pEmitterList->Set_Size_Keyframes (m_CurrentSizes);
|
||||
SetModified ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CPropertyPage::OnNotify (wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Sizes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterSizePropPageClass::Update_Sizes (void)
|
||||
{
|
||||
float position = 0;
|
||||
float red = 0;
|
||||
float green = 0;
|
||||
float blue = 0;
|
||||
|
||||
//
|
||||
// Setup the initial or 'starting' size
|
||||
//
|
||||
m_CurrentSizes.Start = m_SizeBar->Get_Graph_Percent (0) * m_MaxSize;
|
||||
|
||||
//
|
||||
// Free the current setting arrays
|
||||
//
|
||||
SAFE_DELETE_ARRAY (m_CurrentSizes.KeyTimes);
|
||||
SAFE_DELETE_ARRAY (m_CurrentSizes.Values);
|
||||
|
||||
//
|
||||
// Determine if we need to build the array of key frames or not
|
||||
//
|
||||
int count = m_SizeBar->Get_Point_Count ();
|
||||
m_CurrentSizes.NumKeyFrames = count - 1;
|
||||
if (count > 1) {
|
||||
m_CurrentSizes.KeyTimes = new float[count - 1];
|
||||
m_CurrentSizes.Values = new float[count - 1];
|
||||
|
||||
//
|
||||
// Get all the size key frames and add them to our structure
|
||||
//
|
||||
for (int index = 1; index < count; index ++) {
|
||||
m_SizeBar->Get_Point (index, &position, &red, &green, &blue);
|
||||
m_CurrentSizes.KeyTimes[index - 1] = position * m_Lifetime;
|
||||
m_CurrentSizes.Values[index - 1] = m_SizeBar->Get_Graph_Percent (index) * m_MaxSize;
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCommand
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
EmitterSizePropPageClass::OnCommand
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
switch (LOWORD (wParam))
|
||||
{
|
||||
case IDC_SIZE_RANDOM_EDIT:
|
||||
{
|
||||
// Update the emitter
|
||||
if ((HIWORD (wParam) == EN_KILLFOCUS) &&
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_GETMODIFY)) {
|
||||
SendDlgItemMessage (LOWORD (wParam), EM_SETMODIFY, (WPARAM)0);
|
||||
|
||||
m_CurrentSizes.Rand = ::GetDlgItemFloat (m_hWnd, IDC_SIZE_RANDOM_EDIT);
|
||||
m_pEmitterList->Set_Size_Keyframes (m_CurrentSizes);
|
||||
SetModified ();
|
||||
} else if (HIWORD (wParam) == EN_CHANGE) {
|
||||
SetModified ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CPropertyPage::OnCommand (wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// On_Lifetime_Changed
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
void
|
||||
EmitterSizePropPageClass::On_Lifetime_Changed (float lifetime)
|
||||
{
|
||||
if (m_Lifetime != lifetime) {
|
||||
float conversion = lifetime / m_Lifetime;
|
||||
|
||||
//
|
||||
// Rescale the sizes
|
||||
//
|
||||
for (UINT index = 0; index < m_CurrentSizes.NumKeyFrames; index ++) {
|
||||
m_CurrentSizes.KeyTimes[index] *= conversion;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the emitter
|
||||
//
|
||||
m_pEmitterList->Set_Size_Keyframes (m_CurrentSizes);
|
||||
m_Lifetime = lifetime;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
119
Code/Tools/W3DView/EmitterSizePropPage.h
Normal file
119
Code/Tools/W3DView/EmitterSizePropPage.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
** 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_EMITTERSIZEPROPPAGE_H__0CD2CBA3_1219_11D3_A034_00104B791122__INCLUDED_)
|
||||
#define AFX_EMITTERSIZEPROPPAGE_H__0CD2CBA3_1219_11D3_A034_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// EmitterSizePropPage.h : header file
|
||||
//
|
||||
|
||||
#include "ColorBar.H"
|
||||
#include "Part_Emt.H"
|
||||
|
||||
// Forward delcarations
|
||||
class EmitterInstanceListClass;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterSizePropPageClass dialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
class EmitterSizePropPageClass : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(EmitterSizePropPageClass)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
EmitterSizePropPageClass(EmitterInstanceListClass *pemitter = NULL);
|
||||
~EmitterSizePropPageClass();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(EmitterSizePropPageClass)
|
||||
enum { IDD = IDD_PROP_PAGE_EMITTER_SIZE };
|
||||
CSpinButtonCtrl m_SizeRandomSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(EmitterSizePropPageClass)
|
||||
public:
|
||||
virtual BOOL OnApply();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(EmitterSizePropPageClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
//
|
||||
// Inline accessors
|
||||
//
|
||||
EmitterInstanceListClass * Get_Emitter (void) const { return m_pEmitterList; }
|
||||
void Set_Emitter (EmitterInstanceListClass *pemitter_list) { m_pEmitterList = pemitter_list; Initialize (); }
|
||||
bool Is_Data_Valid (void) const { return m_bValid; }
|
||||
|
||||
void Get_Size_Keyframes (ParticlePropertyStruct<float> &sizes) { sizes = m_CurrentSizes; }
|
||||
|
||||
void On_Lifetime_Changed (float lifetime);
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Initialize (void);
|
||||
void Update_Sizes (void);
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
EmitterInstanceListClass * m_pEmitterList;
|
||||
bool m_bValid;
|
||||
ColorBarClass * m_SizeBar;
|
||||
ParticlePropertyStruct<float> m_OrigSizes;
|
||||
ParticlePropertyStruct<float> m_CurrentSizes;
|
||||
float m_Lifetime;
|
||||
float m_MaxSize;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EMITTERSIZEPROPPAGE_H__0CD2CBA3_1219_11D3_A034_00104B791122__INCLUDED_)
|
||||
177
Code/Tools/W3DView/EmitterUserPropPage.cpp
Normal file
177
Code/Tools/W3DView/EmitterUserPropPage.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// EmitterUserPropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "EmitterUserPropPage.h"
|
||||
#include "W3D_File.H"
|
||||
#include "Part_Emt.H"
|
||||
#include "EmitterInstanceList.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterUserPropPageClass property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(EmitterUserPropPageClass, CPropertyPage)
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EmitterUserPropPageClass
|
||||
//
|
||||
EmitterUserPropPageClass::EmitterUserPropPageClass (EmitterInstanceListClass *pemitter)
|
||||
: m_pEmitterList (NULL),
|
||||
m_bValid (true),
|
||||
m_iType (EMITTER_TYPEID_DEFAULT),
|
||||
CPropertyPage(EmitterUserPropPageClass::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(EmitterUserPropPageClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
Initialize ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~EmitterUserPropPageClass
|
||||
//
|
||||
EmitterUserPropPageClass::~EmitterUserPropPageClass (void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
EmitterUserPropPageClass::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(EmitterUserPropPageClass)
|
||||
DDX_Control(pDX, IDC_TYPE_COMBO, m_TypeCombo);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(EmitterUserPropPageClass, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(EmitterUserPropPageClass)
|
||||
ON_EN_CHANGE(IDC_PROGRAMMER_SETTINGS_EDIT, OnChangeProgrammerSettingsEdit)
|
||||
ON_CBN_SELCHANGE(IDC_TYPE_COMBO, OnSelchangeTypeCombo)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
void
|
||||
EmitterUserPropPageClass::Initialize (void)
|
||||
{
|
||||
if (m_pEmitterList != NULL) {
|
||||
|
||||
// Record the user information from the emitter (if it exists)
|
||||
m_iType = m_pEmitterList->Get_User_Type ();
|
||||
m_UserString = m_pEmitterList->Get_User_String ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
EmitterUserPropPageClass::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::OnInitDialog ();
|
||||
|
||||
// Add the list of user-types to the combobox
|
||||
for (int index = 0; index < EMITTER_TYPEID_COUNT; index ++) {
|
||||
m_TypeCombo.AddString (EMITTER_TYPE_NAMES[index]);
|
||||
}
|
||||
|
||||
// Select the correct entry in the combobox
|
||||
m_TypeCombo.SetCurSel (m_iType);
|
||||
|
||||
// Fill in the user-box
|
||||
SetDlgItemText (IDC_PROGRAMMER_SETTINGS_EDIT, m_UserString);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnApply
|
||||
//
|
||||
BOOL
|
||||
EmitterUserPropPageClass::OnApply (void)
|
||||
{
|
||||
// Get the settings from the controls
|
||||
m_iType = m_TypeCombo.GetCurSel ();
|
||||
GetDlgItemText (IDC_PROGRAMMER_SETTINGS_EDIT, m_UserString);
|
||||
|
||||
//
|
||||
// Pass the new settings onto the emitter
|
||||
//
|
||||
m_pEmitterList->Set_User_Type (m_iType);
|
||||
m_pEmitterList->Set_User_String (m_UserString);
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CPropertyPage::OnApply ();
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnChangeProgrammerSettingsEdit
|
||||
//
|
||||
void
|
||||
EmitterUserPropPageClass::OnChangeProgrammerSettingsEdit (void)
|
||||
{
|
||||
SetModified ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSelchangeTypeCombo
|
||||
//
|
||||
void
|
||||
EmitterUserPropPageClass::OnSelchangeTypeCombo (void)
|
||||
{
|
||||
SetModified ();
|
||||
return ;
|
||||
}
|
||||
115
Code/Tools/W3DView/EmitterUserPropPage.h
Normal file
115
Code/Tools/W3DView/EmitterUserPropPage.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
** 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_EMITTERUSERPROPPAGE_H__83A8B840_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
#define AFX_EMITTERUSERPROPPAGE_H__83A8B840_BA3B_11D2_9FFA_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// EmitterUserPropPage.h : header file
|
||||
//
|
||||
|
||||
#include "Resource.H"
|
||||
|
||||
// Forward delcarations
|
||||
class EmitterInstanceListClass;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// EmitterUserPropPageClass dialog
|
||||
|
||||
class EmitterUserPropPageClass : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(EmitterUserPropPageClass)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
EmitterUserPropPageClass (EmitterInstanceListClass *pemitter_list = NULL);
|
||||
~EmitterUserPropPageClass ();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(EmitterUserPropPageClass)
|
||||
enum { IDD = IDD_PROP_PAGE_EMITTER_USER };
|
||||
CComboBox m_TypeCombo;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(EmitterUserPropPageClass)
|
||||
public:
|
||||
virtual BOOL OnApply();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(EmitterUserPropPageClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnChangeProgrammerSettingsEdit();
|
||||
afx_msg void OnSelchangeTypeCombo();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
|
||||
//
|
||||
// Inline accessors
|
||||
//
|
||||
EmitterInstanceListClass * Get_Emitter (void) const { return m_pEmitterList; }
|
||||
void Set_Emitter (EmitterInstanceListClass *pemitter_list) { m_pEmitterList = pemitter_list; Initialize (); }
|
||||
bool Is_Data_Valid (void) const { return m_bValid; }
|
||||
|
||||
int Get_Type (void) const { return m_iType; }
|
||||
const CString & Get_String (void) const { return m_UserString; }
|
||||
void Set_Type (int type) { m_iType = type; }
|
||||
void Set_String (LPCTSTR string) { m_UserString = string; }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Initialize (void);
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Private member data
|
||||
//
|
||||
EmitterInstanceListClass * m_pEmitterList;
|
||||
bool m_bValid;
|
||||
|
||||
int m_iType;
|
||||
CString m_UserString;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_EMITTERUSERPROPPAGE_H__83A8B840_BA3B_11D2_9FFA_00104B791122__INCLUDED_)
|
||||
112
Code/Tools/W3DView/GammaDialog.cpp
Normal file
112
Code/Tools/W3DView/GammaDialog.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// GammaDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "GammaDialog.h"
|
||||
#include "dx8wrapper.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GammaDialogClass dialog
|
||||
|
||||
|
||||
GammaDialogClass::GammaDialogClass(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(GammaDialogClass::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(GammaDialogClass)
|
||||
m_gamma = 0;
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void GammaDialogClass::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(GammaDialogClass)
|
||||
DDX_Control(pDX, IDC_GAMMA_SLIDER, m_gammaslider);
|
||||
DDX_Slider(pDX, IDC_GAMMA_SLIDER, m_gamma);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(GammaDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(GammaDialogClass)
|
||||
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_GAMMA_SLIDER, OnReleasedcaptureGammaSlider)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GammaDialogClass message handlers
|
||||
|
||||
BOOL GammaDialogClass::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// TODO: Add extra initialization here
|
||||
m_gamma=AfxGetApp()->GetProfileInt("Config","Gamma",10);
|
||||
if (m_gamma<10) m_gamma=10;
|
||||
if (m_gamma>30) m_gamma=30;
|
||||
m_gammaslider.SetRange(10,30);
|
||||
m_gammaslider.SetPos(m_gamma);
|
||||
CString string;
|
||||
string.Format("%3.2f",m_gamma/10.0f);
|
||||
SetDlgItemText(IDC_GAMMA_DISPLAY,string);
|
||||
string.Format("Calibration instructions\n");
|
||||
string+="A. Set Gamma to 1.0 and Monitor Contrast and Brightness to maximum\n";
|
||||
string+="B. Adjust Monitor Brightness down so Bar 3 is barely visible\n";
|
||||
string+="C. Adjust Monitor Contrast as preferred but Bars 1,2,3,4 must be distinguishable from each other\n";
|
||||
string+="D. Set the Gamma using the Slider below so the gray box on the left matches it's checkered surroundings\n";
|
||||
string+="E. Press OK to save settings";
|
||||
SetDlgItemText(IDC_INSTRUCTIONS,string);
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
void GammaDialogClass::OnOK()
|
||||
{
|
||||
// TODO: Add extra validation here
|
||||
m_gamma=m_gammaslider.GetPos();
|
||||
if (m_gamma<10) m_gamma=10;
|
||||
if (m_gamma>30) m_gamma=30;
|
||||
::AfxGetApp()->WriteProfileInt("Config","Gamma",m_gamma);
|
||||
DX8Wrapper::Set_Gamma(m_gamma/10.0f,0.0f,1.0f);
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void GammaDialogClass::OnReleasedcaptureGammaSlider(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
m_gamma=m_gammaslider.GetPos();
|
||||
DX8Wrapper::Set_Gamma(m_gamma/10.0f,0.0f,1.0f);
|
||||
CString string;
|
||||
string.Format("%3.2f",m_gamma/10.0f);
|
||||
SetDlgItemText(IDC_GAMMA_DISPLAY,string);
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
67
Code/Tools/W3DView/GammaDialog.h
Normal file
67
Code/Tools/W3DView/GammaDialog.h
Normal 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/>.
|
||||
*/
|
||||
|
||||
#if !defined(AFX_GAMMADIALOG_H__DA25161A_E783_44DE_8398_B311C20C3BE9__INCLUDED_)
|
||||
#define AFX_GAMMADIALOG_H__DA25161A_E783_44DE_8398_B311C20C3BE9__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// GammaDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// GammaDialogClass dialog
|
||||
|
||||
class GammaDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
GammaDialogClass(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(GammaDialogClass)
|
||||
enum { IDD = IDD_GAMMA_DIALOG };
|
||||
CSliderCtrl m_gammaslider;
|
||||
int m_gamma;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(GammaDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(GammaDialogClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnReleasedcaptureGammaSlider(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_GAMMADIALOG_H__DA25161A_E783_44DE_8398_B311C20C3BE9__INCLUDED_)
|
||||
40
Code/Tools/W3DView/Globals.cpp
Normal file
40
Code/Tools/W3DView/Globals.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Globals.CPP
|
||||
//
|
||||
// Module containing global variable initialization.
|
||||
//
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "assetmgr.h"
|
||||
#include "viewerassetmgr.h"
|
||||
|
||||
// Main asset manager for the application.
|
||||
ViewerAssetMgrClass *_TheAssetMgr = NULL;
|
||||
|
||||
|
||||
int g_iDeviceIndex = -1;//DEFAULT_DEVICEINDEX;
|
||||
int g_iBitsPerPixel = -1;//DEFAULT_BITSPERPIX;
|
||||
int g_iWidth = 640;
|
||||
int g_iHeight = 480;
|
||||
50
Code/Tools/W3DView/Globals.h
Normal file
50
Code/Tools/W3DView/Globals.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Globals.H
|
||||
//
|
||||
// Module containing global variable definitions.
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __GLOBALS_H
|
||||
#define __GLOBALS_H
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Externs
|
||||
//////////////////////////////////////////////////////
|
||||
extern class ViewerAssetMgrClass *_TheAssetMgr;
|
||||
extern class CW3DViewApp theApp;
|
||||
extern int g_iDeviceIndex;
|
||||
extern int g_iBitsPerPixel;
|
||||
extern int g_iWidth;
|
||||
extern int g_iHeight;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Contants
|
||||
//////////////////////////////////////////////////////
|
||||
const int DEFAULT_DEVICEINDEX = 1;
|
||||
const int DEFAULT_BITSPERPIX = 16;
|
||||
|
||||
|
||||
#endif //__GLOBALS_H
|
||||
1792
Code/Tools/W3DView/GraphicView.cpp
Normal file
1792
Code/Tools/W3DView/GraphicView.cpp
Normal file
File diff suppressed because it is too large
Load Diff
263
Code/Tools/W3DView/GraphicView.h
Normal file
263
Code/Tools/W3DView/GraphicView.h
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
** 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_GRAPHICVIEW_H__2BB39E41_5D3A_11D2_9FC6_00104B791122__INCLUDED_)
|
||||
#define AFX_GRAPHICVIEW_H__2BB39E41_5D3A_11D2_9FC6_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// GraphicView.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
#define ROTATION_X 0x01
|
||||
#define ROTATION_Y 0x02
|
||||
#define ROTATION_Z 0x04
|
||||
#define ROTATION_X_BACK 0x08
|
||||
#define ROTATION_Y_BACK 0x10
|
||||
#define ROTATION_Z_BACK 0x20
|
||||
|
||||
|
||||
// Forward declarations
|
||||
class ParticleEmitterClass;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGraphicView view
|
||||
|
||||
#include "Camera.H"
|
||||
|
||||
class CGraphicView : public CView
|
||||
{
|
||||
protected:
|
||||
CGraphicView(); // protected constructor used by dynamic creation
|
||||
DECLARE_DYNCREATE(CGraphicView)
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CGraphicView)
|
||||
public:
|
||||
virtual void OnInitialUpdate();
|
||||
protected:
|
||||
virtual void OnDraw(CDC* pDC); // overridden to draw this view
|
||||
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
virtual ~CGraphicView();
|
||||
#ifdef _DEBUG
|
||||
virtual void AssertValid() const;
|
||||
virtual void Dump(CDumpContext& dc) const;
|
||||
#endif
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CGraphicView)
|
||||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||||
afx_msg void OnSize(UINT nType, int cx, int cy);
|
||||
afx_msg void OnDestroy();
|
||||
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
|
||||
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
|
||||
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
|
||||
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
|
||||
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
|
||||
afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
//
|
||||
// Public Data Types
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
AnimInvalid = -1,
|
||||
AnimPlaying = 0,
|
||||
AnimStopped = 1,
|
||||
AnimPaused = 2
|
||||
} ANIMATION_STATE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CameraFront = -1,
|
||||
CameraBack = 0,
|
||||
CameraTop = 1,
|
||||
CameraBottom = 2,
|
||||
CameraLeft = 3,
|
||||
CameraRight = 4
|
||||
} CAMERA_POS;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NoRotation = 0,
|
||||
RotateX = ROTATION_X,
|
||||
RotateY = ROTATION_Y,
|
||||
RotateZ = ROTATION_Z,
|
||||
RotateXBack = ROTATION_X_BACK,
|
||||
RotateYBack = ROTATION_Y_BACK,
|
||||
RotateZBack = ROTATION_Z_BACK
|
||||
} OBJECT_ROTATION;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FreeRotation = 0,
|
||||
OnlyRotateX = ROTATION_X,
|
||||
OnlyRotateY = ROTATION_Y,
|
||||
OnlyRotateZ = ROTATION_Z
|
||||
} CAMERA_ROTATION;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
//
|
||||
// Public Methods
|
||||
//
|
||||
|
||||
BOOL InitializeGraphicView (void);
|
||||
|
||||
//
|
||||
// Initial display methods
|
||||
//
|
||||
void Reset_Camera_To_Display_Sphere (SphereClass &sphere);
|
||||
void Reset_Camera_To_Display_Object (RenderObjClass &physObject);
|
||||
void Reset_Camera_To_Display_Emitter (ParticleEmitterClass &emitter);
|
||||
void Load_Default_Dat (void);
|
||||
|
||||
void UpdateDisplay (void);
|
||||
void RepaintView (BOOL bUpdateAnimation = TRUE, DWORD ticks_to_use = 0);
|
||||
void SetActiveUpdate (BOOL bActive)
|
||||
{ m_bActive = bActive;
|
||||
if (!m_bActive) { ::SetProp (m_hWnd, "Inactive", (HANDLE)1); }
|
||||
else { RemoveProp (m_hWnd, "Inactive"); m_dwLastFrameUpdate = ::GetTickCount (); }
|
||||
}
|
||||
|
||||
void Allow_Update (bool onoff);
|
||||
|
||||
//
|
||||
// Animation methods
|
||||
//
|
||||
float GetAnimationSpeed (void) const { return m_animationSpeed; }
|
||||
void SetAnimationSpeed (float animationSpeed) { m_animationSpeed = animationSpeed; }
|
||||
ANIMATION_STATE GetAnimationState (void) const { return m_animationState; }
|
||||
void SetAnimationState (ANIMATION_STATE animationState);
|
||||
|
||||
//
|
||||
// Camera Methods
|
||||
//
|
||||
void SetAllowedCameraRotation (CAMERA_ROTATION cameraRotation);
|
||||
CAMERA_ROTATION GetAllowedCameraRotation () const { return m_allowedCameraRotation; }
|
||||
void SetCameraPos (CAMERA_POS cameraPos);
|
||||
class CameraClass *GetCamera (void) const { return m_pCamera; }
|
||||
|
||||
float Get_Camera_Distance (void) const { return m_CameraDistance; }
|
||||
void Set_Camera_Distance (float dist);
|
||||
|
||||
void Set_Camera_Bone_Pos_X (bool onoff) { m_CameraBonePosX = onoff; }
|
||||
BOOL Is_Camera_Bone_Pos_X (void) const { return m_CameraBonePosX; }
|
||||
|
||||
//
|
||||
// Object rotation methods
|
||||
//
|
||||
void ResetObject (void);
|
||||
void RotateObject (OBJECT_ROTATION rotation);
|
||||
OBJECT_ROTATION GetObjectRotation (void) const { return m_objectRotation; }
|
||||
|
||||
//
|
||||
// Light rotation methods
|
||||
//
|
||||
void Rotate_Light (OBJECT_ROTATION rotation) { m_LightRotation = rotation; }
|
||||
OBJECT_ROTATION Get_Light_Rotation (void) const { return m_LightRotation; }
|
||||
|
||||
//
|
||||
// Fullscreen mode
|
||||
//
|
||||
BOOL Is_Fullscreen (void) const { return !(BOOL)m_iWindowed; }
|
||||
void Set_Fullscreen (bool fullscreen) { m_iWindowed = fullscreen ? 0 : 1; InitializeGraphicView (); }
|
||||
|
||||
//
|
||||
// Misc
|
||||
//
|
||||
RenderObjClass * Get_Light_Mesh (void) const { return m_pLightMesh; }
|
||||
Vector3 & Get_Object_Center (void) { return m_ObjectCenter; }
|
||||
|
||||
//
|
||||
// FOV methods
|
||||
//
|
||||
void Set_FOV (double hfov, double vfov, bool force = false);
|
||||
void Reset_FOV (void);
|
||||
|
||||
protected:
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
//
|
||||
// Protected methods
|
||||
//
|
||||
void Rotate_Object (void);
|
||||
void Rotate_Light (void);
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
//
|
||||
// Private Member Data
|
||||
//
|
||||
BOOL m_bInitialized;
|
||||
BOOL m_bActive;
|
||||
UINT m_TimerID;
|
||||
CameraClass * m_pCamera;
|
||||
RenderObjClass * m_pLightMesh;
|
||||
bool m_bLightMeshInScene;
|
||||
Vector3 m_ObjectCenter;
|
||||
SphereClass m_ViewedSphere;
|
||||
|
||||
BOOL m_bMouseDown;
|
||||
BOOL m_bRMouseDown;
|
||||
POINT m_lastPoint;
|
||||
int m_iWindowed;
|
||||
int m_UpdateCounter;
|
||||
float m_CameraDistance;
|
||||
DWORD m_ParticleCountUpdate;
|
||||
BOOL m_CameraBonePosX;
|
||||
|
||||
// Animation data
|
||||
DWORD m_dwLastFrameUpdate;
|
||||
float m_animationSpeed;
|
||||
ANIMATION_STATE m_animationState;
|
||||
OBJECT_ROTATION m_objectRotation;
|
||||
OBJECT_ROTATION m_LightRotation;
|
||||
CAMERA_ROTATION m_allowedCameraRotation;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_GRAPHICVIEW_H__2BB39E41_5D3A_11D2_9FC6_00104B791122__INCLUDED_)
|
||||
182
Code/Tools/W3DView/HierarchyPropPage.cpp
Normal file
182
Code/Tools/W3DView/HierarchyPropPage.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// HierarchyPropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "W3DView.h"
|
||||
#include "HierarchyPropPage.h"
|
||||
#include "AssetMgr.H"
|
||||
#include "RendObj.H"
|
||||
#include "AssetPropertySheet.H"
|
||||
#include "MeshPropPage.H"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CHierarchyPropPage property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(CHierarchyPropPage, CPropertyPage)
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHierarchyPropPage
|
||||
//
|
||||
CHierarchyPropPage::CHierarchyPropPage (const CString &stringHierarchyName)
|
||||
: CPropertyPage(CHierarchyPropPage::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CHierarchyPropPage)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
m_stringHierarchyName = stringHierarchyName;
|
||||
return ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHierarchyPropPage
|
||||
//
|
||||
CHierarchyPropPage::~CHierarchyPropPage (void)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
CHierarchyPropPage::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CHierarchyPropPage)
|
||||
DDX_Control(pDX, IDC_SUBOBJECT_LIST, m_subObjectListCtrl);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CHierarchyPropPage, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(CHierarchyPropPage)
|
||||
ON_NOTIFY(NM_DBLCLK, IDC_SUBOBJECT_LIST, OnDblclkSubObjectList)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CHierarchyPropPage message handlers
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
CHierarchyPropPage::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::OnInitDialog();
|
||||
|
||||
if (m_stringHierarchyName.GetLength () > 0)
|
||||
{
|
||||
// Get a pointer to the hierarchy object from the asset manager
|
||||
RenderObjClass *pCHierarchy = WW3DAssetManager::Get_Instance()->Create_Render_Obj (m_stringHierarchyName);
|
||||
|
||||
ASSERT (pCHierarchy);
|
||||
if (pCHierarchy)
|
||||
{
|
||||
CString stringDesc;
|
||||
stringDesc.Format (IDS_HIERARCHY_PROP_DESC, m_stringHierarchyName);
|
||||
|
||||
// Put the description onto the dialog
|
||||
SetDlgItemText (IDC_DESCRIPTION, stringDesc);
|
||||
|
||||
// Put the polygon count onto the dialog
|
||||
SetDlgItemInt (IDC_TOTAL_POLYGONS, pCHierarchy->Get_Num_Polys ());
|
||||
|
||||
// Put the subobject count onto the dialog
|
||||
int iSubObjects = pCHierarchy->Get_Num_Sub_Objects ();
|
||||
SetDlgItemInt (IDC_SUBOBJECTS, iSubObjects);
|
||||
|
||||
// Add the name column to the list control
|
||||
m_subObjectListCtrl.InsertColumn (0, "Name");
|
||||
|
||||
// Loop through all the subobjects and add them to the list control
|
||||
for (int iObject = 0;
|
||||
iObject < iSubObjects;
|
||||
iObject ++)
|
||||
{
|
||||
// Get this subobject
|
||||
RenderObjClass *pCSubObject = pCHierarchy->Get_Sub_Object (iObject);
|
||||
if (pCSubObject)
|
||||
{
|
||||
// Add this object to the list
|
||||
m_subObjectListCtrl.InsertItem (0, pCSubObject->Get_Name ());
|
||||
|
||||
// Free this object
|
||||
pCSubObject->Release_Ref ();
|
||||
pCSubObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Resize the column so it is wide enough to display the largest string
|
||||
m_subObjectListCtrl.SetColumnWidth (0, LVSCW_AUTOSIZE);
|
||||
|
||||
// Free the object
|
||||
pCHierarchy->Release_Ref ();
|
||||
pCHierarchy = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GetParent ()->GetDlgItem (IDOK)->ShowWindow (SW_HIDE);
|
||||
GetParent ()->GetDlgItem (IDCANCEL)->SetWindowText ("Close");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnDblclkSubObjectList
|
||||
//
|
||||
void
|
||||
CHierarchyPropPage::OnDblclkSubObjectList
|
||||
(
|
||||
NMHDR* pNMHDR,
|
||||
LRESULT* pResult
|
||||
)
|
||||
{
|
||||
// Get the currently selected item
|
||||
int iIndex = m_subObjectListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
|
||||
if (iIndex != -1)
|
||||
{
|
||||
// Create a one-page property sheet that will display property information
|
||||
// for the mesh
|
||||
CMeshPropPage meshPropPage (m_subObjectListCtrl.GetItemText (iIndex, 0));
|
||||
CAssetPropertySheet propertySheet (IDS_MESH_PROP_TITLE, &meshPropPage, this);
|
||||
|
||||
// Show the property sheet
|
||||
propertySheet.DoModal ();
|
||||
}
|
||||
|
||||
(*pResult) = 0;
|
||||
return ;
|
||||
}
|
||||
74
Code/Tools/W3DView/HierarchyPropPage.h
Normal file
74
Code/Tools/W3DView/HierarchyPropPage.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
** 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_HIERARCHYPROPPAGE_H__FB40246E_5DFB_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
#define AFX_HIERARCHYPROPPAGE_H__FB40246E_5DFB_11D2_9FC7_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// HierarchyPropPage.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CHierarchyPropPage dialog
|
||||
|
||||
class CHierarchyPropPage : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(CHierarchyPropPage)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CHierarchyPropPage (const CString &stringHierarchyName);
|
||||
~CHierarchyPropPage ();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CHierarchyPropPage)
|
||||
enum { IDD = IDD_PROP_PAGE_HIERARCHY };
|
||||
CListCtrl m_subObjectListCtrl;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(CHierarchyPropPage)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CHierarchyPropPage)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnDblclkSubObjectList(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
// Private constructor that shouldn't be called
|
||||
CHierarchyPropPage () {};
|
||||
|
||||
CString m_stringHierarchyName;
|
||||
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_HIERARCHYPROPPAGE_H__FB40246E_5DFB_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
108
Code/Tools/W3DView/LODDefs.h
Normal file
108
Code/Tools/W3DView/LODDefs.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : W3DView *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/W3DView/LODDefs.h $*
|
||||
* *
|
||||
* Author:: Patrick Smith *
|
||||
* *
|
||||
* $Modtime:: 3/03/99 7:26p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#ifndef __LODDEFS_H
|
||||
#define __LODDEFS_H
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
TYPE_COMMANDO = 0,
|
||||
TYPE_G,
|
||||
TYPE_COUNT
|
||||
} LOD_NAMING_TYPE;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Inline functions
|
||||
//
|
||||
__inline bool Is_LOD_Name_Valid (LPCTSTR name, LOD_NAMING_TYPE &type)
|
||||
{
|
||||
bool retval = false;
|
||||
|
||||
// Does this name fit with the format expected?
|
||||
LPCTSTR last_2_chars = name + (::lstrlen (name)-2);
|
||||
if (((last_2_chars[0] == 'L') || (last_2_chars[0] == 'l')) &&
|
||||
((last_2_chars[1] >= '0') && (last_2_chars[1] <= '9'))) {
|
||||
type = TYPE_COMMANDO;
|
||||
retval = true;
|
||||
} else if ((last_2_chars[1] >= 'a' && last_2_chars[1] <= 'z') ||
|
||||
(last_2_chars[1] >= 'A' && last_2_chars[1] <= 'Z')) {
|
||||
type = TYPE_G;
|
||||
retval = true;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
__inline bool Is_Model_Part_of_LOD (LPCTSTR name, LPCTSTR base, LOD_NAMING_TYPE &type)
|
||||
{
|
||||
// Assume failure
|
||||
bool retval = false;
|
||||
|
||||
// Does the name start with the base?
|
||||
if (::strstr (name, base) == name) {
|
||||
|
||||
// Get the remaining characters in the name (after the base)
|
||||
LPCTSTR extension = name + ::lstrlen (base);
|
||||
|
||||
// What naming convention are we using?
|
||||
if (type == TYPE_COMMANDO) {
|
||||
if (((extension[0] == 'L') || (extension[0] == 'l')) &&
|
||||
((extension[1] >= '0') && (extension[1] <= '9'))) {
|
||||
retval = (extension[2] == 0);
|
||||
}
|
||||
} else if (type == TYPE_G) {
|
||||
if ((extension[0] >= 'a' && extension[0] <= 'z') ||
|
||||
(extension[0] >= 'A' && extension[0] <= 'Z')) {
|
||||
retval = (extension[1] == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the true/false result ccde
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
#endif //__LODDEFS_H
|
||||
|
||||
4464
Code/Tools/W3DView/MainFrm.cpp
Normal file
4464
Code/Tools/W3DView/MainFrm.cpp
Normal file
File diff suppressed because it is too large
Load Diff
292
Code/Tools/W3DView/MainFrm.h
Normal file
292
Code/Tools/W3DView/MainFrm.h
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// MainFrm.h : interface of the CMainFrame class
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_MAINFRM_H__2BB39E2F_5D3A_11D2_9FC6_00104B791122__INCLUDED_)
|
||||
#define AFX_MAINFRM_H__2BB39E2F_5D3A_11D2_9FC6_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#include "DataTreeView.H"
|
||||
#include "Toolbar.H"
|
||||
|
||||
class CMainFrame : public CFrameWnd
|
||||
{
|
||||
protected: // create from serialization only
|
||||
CMainFrame();
|
||||
DECLARE_DYNCREATE(CMainFrame)
|
||||
|
||||
// Attributes
|
||||
protected:
|
||||
CSplitterWnd m_wndSplitter;
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CMainFrame)
|
||||
public:
|
||||
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
|
||||
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
|
||||
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
|
||||
protected:
|
||||
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
virtual ~CMainFrame();
|
||||
#ifdef _DEBUG
|
||||
virtual void AssertValid() const;
|
||||
virtual void Dump(CDumpContext& dc) const;
|
||||
#endif
|
||||
|
||||
protected: // control bar embedded members
|
||||
CStatusBar m_wndStatusBar;
|
||||
CToolBar m_wndToolBar;
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
//{{AFX_MSG(CMainFrame)
|
||||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||||
afx_msg void OnObjectProperties();
|
||||
afx_msg void OnUpdateObjectProperties(CCmdUI* pCmdUI);
|
||||
afx_msg void OnLodGenerate();
|
||||
afx_msg void OnActivateApp(BOOL bActive, HTASK hTask);
|
||||
afx_msg void OnFileOpen();
|
||||
afx_msg void OnAniSpeed();
|
||||
afx_msg void OnAniStop();
|
||||
afx_msg void OnAniStart();
|
||||
afx_msg void OnAniPause();
|
||||
afx_msg void OnCameraBack();
|
||||
afx_msg void OnCameraBottom();
|
||||
afx_msg void OnCameraFront();
|
||||
afx_msg void OnCameraLeft();
|
||||
afx_msg void OnCameraReset();
|
||||
afx_msg void OnCameraRight();
|
||||
afx_msg void OnCameraTop();
|
||||
afx_msg void OnObjectRotateZ();
|
||||
afx_msg void OnObjectRotateY();
|
||||
afx_msg void OnObjectRotateX();
|
||||
afx_msg void OnLightAmbient();
|
||||
afx_msg void OnLightScene();
|
||||
afx_msg void OnBackgroundColor();
|
||||
afx_msg void OnBackgroundBMP();
|
||||
afx_msg void OnSaveSettings();
|
||||
afx_msg void OnLoadSettings();
|
||||
afx_msg void OnLODSetSwitch();
|
||||
afx_msg void OnLODSave();
|
||||
afx_msg void OnLODSaveAll();
|
||||
afx_msg void OnBackgroundObject();
|
||||
afx_msg void OnUpdateViewAnimationBar(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateViewObjectBar(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewAnimationBar();
|
||||
afx_msg void OnViewObjectBar();
|
||||
afx_msg void OnAniStepFwd();
|
||||
afx_msg void OnAniStepBkwd();
|
||||
afx_msg void OnObjectReset();
|
||||
afx_msg void OnCameraAllowRotateX();
|
||||
afx_msg void OnCameraAllowRotateY();
|
||||
afx_msg void OnCameraAllowRotateZ();
|
||||
afx_msg void OnUpdateCameraAllowRotateX(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateCameraAllowRotateY(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateCameraAllowRotateZ(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateObjectRotateX(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateObjectRotateY(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateObjectRotateZ(CCmdUI* pCmdUI);
|
||||
afx_msg void OnDeviceChange();
|
||||
afx_msg void OnViewFullscreen();
|
||||
afx_msg void OnUpdateViewFullscreen(CCmdUI* pCmdUI);
|
||||
afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);
|
||||
afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
|
||||
afx_msg void OnCreateEmitter();
|
||||
afx_msg void OnEditEmitter();
|
||||
afx_msg void OnUpdateEditEmitter(CCmdUI* pCmdUI);
|
||||
afx_msg void OnSaveEmitter();
|
||||
afx_msg void OnUpdateSaveEmitter(CCmdUI* pCmdUI);
|
||||
afx_msg void OnBoneAutoAssign();
|
||||
afx_msg void OnBoneManagement();
|
||||
afx_msg void OnSaveAggregate();
|
||||
afx_msg void OnCameraAnimate();
|
||||
afx_msg void OnUpdateCameraAnimate(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateLodSave(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateSaveAggregate(CCmdUI* pCmdUI);
|
||||
afx_msg void OnCameraResetOnLoad();
|
||||
afx_msg void OnUpdateCameraResetOnLoad(CCmdUI* pCmdUI);
|
||||
afx_msg void OnObjectRotateYBack();
|
||||
afx_msg void OnObjectRotateZBack();
|
||||
afx_msg void OnLightRotateY();
|
||||
afx_msg void OnLightRotateYBack();
|
||||
afx_msg void OnLightRotateZ();
|
||||
afx_msg void OnLightRotateZBack();
|
||||
afx_msg void OnDestroy();
|
||||
afx_msg void OnDecLight();
|
||||
afx_msg void OnIncLight();
|
||||
afx_msg void OnDecAmbientLight();
|
||||
afx_msg void OnIncAmbientLight();
|
||||
afx_msg void OnMakeAggregate();
|
||||
afx_msg void OnRenameAggregate();
|
||||
afx_msg void OnCrashApp();
|
||||
afx_msg void OnLODRecordScreenArea();
|
||||
afx_msg void OnLODIncludeNull();
|
||||
afx_msg void OnUpdateLODIncludeNull(CCmdUI* pCmdUI);
|
||||
afx_msg void OnLodPrevLevel();
|
||||
afx_msg void OnUpdateLodPrevLevel(CCmdUI* pCmdUI);
|
||||
afx_msg void OnLodNextLevel();
|
||||
afx_msg void OnUpdateLodNextLevel(CCmdUI* pCmdUI);
|
||||
afx_msg void OnLodAutoswitch();
|
||||
afx_msg void OnUpdateLodAutoswitch(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateMakeMovie(CCmdUI* pCmdUI);
|
||||
afx_msg void OnMakeMovie();
|
||||
afx_msg void OnSaveScreenshot();
|
||||
afx_msg void OnSlideshowDown();
|
||||
afx_msg void OnSlideshowUp();
|
||||
afx_msg void OnAdvancedAnim();
|
||||
afx_msg void OnUpdateAdvancedAnim(CCmdUI* pCmdUI);
|
||||
afx_msg void OnCameraSettings();
|
||||
afx_msg void OnCopyScreenSize();
|
||||
afx_msg void OnListMissingTextures();
|
||||
afx_msg void OnCopyAssets();
|
||||
afx_msg void OnUpdateCopyAssets(CCmdUI* pCmdUI);
|
||||
afx_msg void OnLightingExpose();
|
||||
afx_msg void OnUpdateLightingExpose(CCmdUI* pCmdUI);
|
||||
afx_msg void OnTexturePath();
|
||||
afx_msg void OnChangeResolution();
|
||||
afx_msg void OnCreateSphere();
|
||||
afx_msg void OnCreateRing();
|
||||
afx_msg void OnUpdateEditPrimitive(CCmdUI* pCmdUI);
|
||||
afx_msg void OnEditPrimitive();
|
||||
afx_msg void OnExportPrimitive();
|
||||
afx_msg void OnUpdateExportPrimitive(CCmdUI* pCmdUI);
|
||||
afx_msg void OnKillSceneLight();
|
||||
afx_msg void OnPrelitMultipass();
|
||||
afx_msg void OnUpdatePrelitMultipass(CCmdUI* pCmdUI);
|
||||
afx_msg void OnPrelitMultitex();
|
||||
afx_msg void OnUpdatePrelitMultitex(CCmdUI* pCmdUI);
|
||||
afx_msg void OnPrelitVertex();
|
||||
afx_msg void OnUpdatePrelitVertex(CCmdUI* pCmdUI);
|
||||
afx_msg void OnAddToLineup();
|
||||
afx_msg void OnUpdateAddToLineup(CCmdUI* pCmdUI);
|
||||
afx_msg void OnImportFacialAnims();
|
||||
afx_msg void OnUpdateImportFacialAnims(CCmdUI* pCmdUI);
|
||||
afx_msg void OnRestrictAnims();
|
||||
afx_msg void OnUpdateRestrictAnims(CCmdUI* pCmdUI);
|
||||
afx_msg void OnBindSubobjectLod();
|
||||
afx_msg void OnUpdateBindSubobjectLod(CCmdUI* pCmdUI);
|
||||
afx_msg void OnSetCameraDistance();
|
||||
afx_msg void OnObjectAlternateMaterials();
|
||||
afx_msg void OnCreateSoundObject();
|
||||
afx_msg void OnEditSoundObject();
|
||||
afx_msg void OnUpdateEditSoundObject(CCmdUI* pCmdUI);
|
||||
afx_msg void OnExportSoundObj();
|
||||
afx_msg void OnUpdateExportSoundObj(CCmdUI* pCmdUI);
|
||||
afx_msg void OnWireframeMode();
|
||||
afx_msg void OnUpdateWireframeMode(CCmdUI* pCmdUI);
|
||||
afx_msg void OnUpdateBackgroundFog(CCmdUI* pCmdUI);
|
||||
afx_msg void OnBackgroundFog();
|
||||
afx_msg void OnUpdateScaleEmitter(CCmdUI* pCmdUI);
|
||||
afx_msg void OnScaleEmitter();
|
||||
afx_msg void OnUpdateToggleSorting(CCmdUI* pCmdUI);
|
||||
afx_msg void OnToggleSorting();
|
||||
afx_msg void OnCameraBonePosX();
|
||||
afx_msg void OnUpdateCameraBonePosX(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewPatchGapFill();
|
||||
afx_msg void OnUpdateViewPatchGapFill(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewSubdivision1();
|
||||
afx_msg void OnUpdateViewSubdivision1(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewSubdivision2();
|
||||
afx_msg void OnUpdateViewSubdivision2(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewSubdivision3();
|
||||
afx_msg void OnUpdateViewSubdivision3(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewSubdivision4();
|
||||
afx_msg void OnUpdateViewSubdivision4(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewSubdivision5();
|
||||
afx_msg void OnUpdateViewSubdivision5(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewSubdivision6();
|
||||
afx_msg void OnUpdateViewSubdivision6(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewSubdivision7();
|
||||
afx_msg void OnUpdateViewSubdivision7(CCmdUI* pCmdUI);
|
||||
afx_msg void OnViewSubdivision8();
|
||||
afx_msg void OnUpdateViewSubdivision8(CCmdUI* pCmdUI);
|
||||
afx_msg void OnMungeSortOnLoad();
|
||||
afx_msg void OnUpdateMungeSortOnLoad(CCmdUI* pCmdUI);
|
||||
afx_msg void OnEnableGammaCorrection();
|
||||
afx_msg void OnUpdateEnableGammaCorrection(CCmdUI* pCmdUI);
|
||||
afx_msg void OnSetGamma();
|
||||
afx_msg void OnEditAnimatedSoundsOptions();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
CView *GetPane (int iRow, int iCol) const
|
||||
{ return (CView *)m_wndSplitter.GetPane (iRow, iCol); }
|
||||
|
||||
void ShowObjectProperties (void);
|
||||
|
||||
void OnSelectionChanged (ASSET_TYPE newAssetType);
|
||||
|
||||
void Update_Frame_Time (DWORD milliseconds);
|
||||
void UpdatePolygonCount (int iPolygons);
|
||||
void Update_Particle_Count (int particles);
|
||||
void UpdateCameraDistance (float cameraDistance);
|
||||
void UpdateFrameCount (int iCurrentFrame, int iTotalFrames, float frame_rate);
|
||||
void RestoreOriginalSize (void);
|
||||
void Select_Device (bool show_dlg = true);
|
||||
|
||||
HMENU Get_Emitters_List_Menu (void) const { return m_hEmittersSubMenu; }
|
||||
void Update_Emitters_List (void);
|
||||
|
||||
protected:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Protected methods
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
void Restore_Window_State (void);
|
||||
|
||||
private:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Private member data
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
ASSET_TYPE m_currentAssetType;
|
||||
CFancyToolbar m_objectToolbar;
|
||||
CFancyToolbar m_animationToolbar;
|
||||
BOOL m_bShowAnimationBar;
|
||||
RECT m_OrigRect;
|
||||
HMENU m_hEmittersSubMenu;
|
||||
BOOL m_bInitialized;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_MAINFRM_H__2BB39E2F_5D3A_11D2_9FC6_00104B791122__INCLUDED_)
|
||||
188
Code/Tools/W3DView/MeshPropPage.cpp
Normal file
188
Code/Tools/W3DView/MeshPropPage.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// MeshPropPage.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "W3DView.h"
|
||||
#include "MeshPropPage.h"
|
||||
#include "RendObj.H"
|
||||
#include "AssetMgr.H"
|
||||
#include "Mesh.H"
|
||||
#include "MeshMdl.H"
|
||||
#include "w3d_file.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMeshPropPage property page
|
||||
|
||||
IMPLEMENT_DYNCREATE(CMeshPropPage, CPropertyPage)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMeshPropPage
|
||||
//
|
||||
CMeshPropPage::CMeshPropPage (const CString &stringMeshName)
|
||||
: CPropertyPage(CMeshPropPage::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CMeshPropPage)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
m_stringMeshName = stringMeshName;
|
||||
return ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~CMeshPropPage
|
||||
//
|
||||
CMeshPropPage::~CMeshPropPage (void)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
void
|
||||
CMeshPropPage::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
CPropertyPage::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CMeshPropPage)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CMeshPropPage, CPropertyPage)
|
||||
//{{AFX_MSG_MAP(CMeshPropPage)
|
||||
ON_WM_CLOSE()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMeshPropPage message handlers
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
BOOL
|
||||
CMeshPropPage::OnInitDialog (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CPropertyPage::OnInitDialog();
|
||||
|
||||
if (m_stringMeshName.GetLength () > 0)
|
||||
{
|
||||
// Get a pointer to the mesh object from the asset manager
|
||||
MeshClass *pCMesh = (MeshClass *)WW3DAssetManager::Get_Instance()->Create_Render_Obj (m_stringMeshName);
|
||||
|
||||
ASSERT (pCMesh);
|
||||
if (pCMesh)
|
||||
{
|
||||
CString stringDesc;
|
||||
stringDesc.Format (IDS_MESH_PROP_DESC, m_stringMeshName);
|
||||
|
||||
// Put the description onto the dialog
|
||||
SetDlgItemText (IDC_DESCRIPTION, stringDesc);
|
||||
|
||||
// Put the polygon count onto the dialog
|
||||
SetDlgItemInt (IDC_POLYGON_COUNT, pCMesh->Get_Num_Polys ());
|
||||
|
||||
MeshModelClass *pmeshmodel = pCMesh->Get_Model ();
|
||||
ASSERT (pmeshmodel);
|
||||
if (pmeshmodel)
|
||||
{
|
||||
// Put the vertex count onto the dialog
|
||||
SetDlgItemInt (IDC_VERTEX_COUNT, pmeshmodel->Get_Vertex_Count ());
|
||||
}
|
||||
|
||||
// Put the user text onto the dialog
|
||||
SetDlgItemText (IDC_USER_TEXT, pCMesh->Get_User_Text ());
|
||||
|
||||
// Get the flags for the mesh
|
||||
DWORD dwFlags = pCMesh->Get_W3D_Flags ();
|
||||
|
||||
// Determine what type of mesh this is
|
||||
if ((dwFlags & W3D_MESH_FLAG_COLLISION_BOX) == W3D_MESH_FLAG_COLLISION_BOX)
|
||||
{
|
||||
SendDlgItemMessage (IDC_MESH_TYPE_COLLISION_BOX, BM_SETCHECK, (WPARAM)TRUE);
|
||||
}
|
||||
else if ((dwFlags & W3D_MESH_FLAG_SKIN) == W3D_MESH_FLAG_SKIN)
|
||||
{
|
||||
SendDlgItemMessage (IDC_MESH_TYPE_SKIN, BM_SETCHECK, (WPARAM)TRUE);
|
||||
}
|
||||
else if ((dwFlags & W3D_MESH_FLAG_SHADOW) == W3D_MESH_FLAG_SHADOW)
|
||||
{
|
||||
SendDlgItemMessage (IDC_MESH_TYPE_SHADOW, BM_SETCHECK, (WPARAM)TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendDlgItemMessage (IDC_MESH_TYPE_NORMAL, BM_SETCHECK, (WPARAM)TRUE);
|
||||
}
|
||||
|
||||
|
||||
// Is this collision type physical?
|
||||
DWORD dwCollisionFlags = dwFlags & W3D_MESH_FLAG_COLLISION_TYPE_MASK;
|
||||
if ((dwCollisionFlags & W3D_MESH_FLAG_COLLISION_TYPE_PHYSICAL) == W3D_MESH_FLAG_COLLISION_TYPE_PHYSICAL)
|
||||
{
|
||||
SendDlgItemMessage (IDC_COLLISION_TYPE_PHYSICAL, BM_SETCHECK, (WPARAM)TRUE);
|
||||
}
|
||||
|
||||
// Is this collision type projectile?
|
||||
if ((dwCollisionFlags & W3D_MESH_FLAG_COLLISION_TYPE_PROJECTILE) == W3D_MESH_FLAG_COLLISION_TYPE_PROJECTILE)
|
||||
{
|
||||
SendDlgItemMessage (IDC_COLLISION_TYPE_PROJECTILE, BM_SETCHECK, (WPARAM)TRUE);
|
||||
}
|
||||
|
||||
// Is this a hidden mesh?
|
||||
if ((dwFlags & W3D_MESH_FLAG_HIDDEN) == W3D_MESH_FLAG_HIDDEN)
|
||||
{
|
||||
SendDlgItemMessage (IDC_HIDDEN, BM_SETCHECK, (WPARAM)TRUE);
|
||||
}
|
||||
|
||||
// Free the object
|
||||
pCMesh->Release_Ref ();
|
||||
pCMesh = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GetParent ()->GetDlgItem (IDOK)->ShowWindow (SW_HIDE);
|
||||
GetParent ()->GetDlgItem (IDCANCEL)->SetWindowText ("Close");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void CMeshPropPage::OnClose()
|
||||
{
|
||||
// TODO: Add your message handler code here and/or call default
|
||||
|
||||
CPropertyPage::OnClose();
|
||||
return ;
|
||||
}
|
||||
74
Code/Tools/W3DView/MeshPropPage.h
Normal file
74
Code/Tools/W3DView/MeshPropPage.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
** 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_MESHPROPPAGE_H__FB40246F_5DFB_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
#define AFX_MESHPROPPAGE_H__FB40246F_5DFB_11D2_9FC7_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
// MeshPropPage.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMeshPropPage dialog
|
||||
|
||||
class CMeshPropPage : public CPropertyPage
|
||||
{
|
||||
DECLARE_DYNCREATE(CMeshPropPage)
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CMeshPropPage (const CString &stringMeshName);
|
||||
~CMeshPropPage ();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CMeshPropPage)
|
||||
enum { IDD = IDD_PROP_PAGE_MESH };
|
||||
// NOTE - ClassWizard will add data members here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generate virtual function overrides
|
||||
//{{AFX_VIRTUAL(CMeshPropPage)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CMeshPropPage)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnClose();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
CMeshPropPage () {};
|
||||
|
||||
CString m_stringMeshName;
|
||||
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_MESHPROPPAGE_H__FB40246F_5DFB_11D2_9FC7_00104B791122__INCLUDED_)
|
||||
120
Code/Tools/W3DView/OpacitySettingsDialog.cpp
Normal file
120
Code/Tools/W3DView/OpacitySettingsDialog.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : W3DView *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/W3DView/OpacitySettingsDialog.cpp $Modtime:: $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "OpacitySettingsDialog.h"
|
||||
#include "ColorBar.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OpacitySettingsDialogClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
OpacitySettingsDialogClass::OpacitySettingsDialogClass (float opacity, CWnd *pParent)
|
||||
: m_OpacityBar (NULL),
|
||||
m_Opacity (opacity),
|
||||
CDialog(OpacitySettingsDialogClass::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(OpacitySettingsDialogClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
OpacitySettingsDialogClass::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(OpacitySettingsDialogClass)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(OpacitySettingsDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(OpacitySettingsDialogClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
OpacitySettingsDialogClass::OnInitDialog (void)
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
m_OpacityBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_OPACITY_BAR));
|
||||
ASSERT (m_OpacityBar);
|
||||
|
||||
//
|
||||
// Setup the opacity bar
|
||||
//
|
||||
m_OpacityBar->Set_Range (0, 1);
|
||||
m_OpacityBar->Modify_Point (0, 0, 0, 0, 0);
|
||||
m_OpacityBar->Insert_Point (1, 1, 255, 255, 255);
|
||||
m_OpacityBar->Set_Selection_Pos (m_Opacity);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnOK
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
OpacitySettingsDialogClass::OnOK (void)
|
||||
{
|
||||
m_Opacity = m_OpacityBar->Get_Selection_Pos ();
|
||||
CDialog::OnOK ();
|
||||
return ;
|
||||
}
|
||||
83
Code/Tools/W3DView/OpacitySettingsDialog.h
Normal file
83
Code/Tools/W3DView/OpacitySettingsDialog.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
** 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_OPACITYSETTINGSDIALOG_H__52B0C804_0D48_11D3_A031_00104B791122__INCLUDED_)
|
||||
#define AFX_OPACITYSETTINGSDIALOG_H__52B0C804_0D48_11D3_A031_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// OpacitySettingsDialog.h : header file
|
||||
//
|
||||
|
||||
// Forward declarations
|
||||
class ColorBarClass;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// OpacitySettingsDialogClass dialog
|
||||
|
||||
class OpacitySettingsDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
OpacitySettingsDialogClass(float opacity, CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(OpacitySettingsDialogClass)
|
||||
enum { IDD = IDD_OPACITY };
|
||||
// NOTE: the ClassWizard will add data members here
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(OpacitySettingsDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(OpacitySettingsDialogClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
////////////////////////////////////////////////////////////////
|
||||
float Get_Opacity (void) const { return m_Opacity; }
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Private member data
|
||||
////////////////////////////////////////////////////////////////
|
||||
ColorBarClass * m_OpacityBar;
|
||||
float m_Opacity;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_OPACITYSETTINGSDIALOG_H__52B0C804_0D48_11D3_A031_00104B791122__INCLUDED_)
|
||||
340
Code/Tools/W3DView/OpacityVectorDialog.cpp
Normal file
340
Code/Tools/W3DView/OpacityVectorDialog.cpp
Normal file
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// OpacityVectorDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "OpacityVectorDialog.h"
|
||||
#include "wwmath.h"
|
||||
#include "vector3.h"
|
||||
#include "sphereobj.h"
|
||||
#include "ringobj.h"
|
||||
#include "colorbar.h"
|
||||
#include "euler.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OpacityVectorDialogClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
OpacityVectorDialogClass::OpacityVectorDialogClass(CWnd* pParent /*=NULL*/)
|
||||
: m_OpacityBar (NULL),
|
||||
m_RenderObj (NULL),
|
||||
m_KeyIndex (0),
|
||||
CDialog(OpacityVectorDialogClass::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(OpacityVectorDialogClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DoDataExchange
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
OpacityVectorDialogClass::DoDataExchange (CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(OpacityVectorDialogClass)
|
||||
DDX_Control(pDX, IDC_SLIDER_Z, m_SliderZ);
|
||||
DDX_Control(pDX, IDC_SLIDER_Y, m_SliderY);
|
||||
//}}AFX_DATA_MAP
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(OpacityVectorDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(OpacityVectorDialogClass)
|
||||
ON_WM_HSCROLL()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitDialog
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
OpacityVectorDialogClass::OnInitDialog (void)
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
m_OpacityBar = ColorBarClass::Get_Color_Bar (::GetDlgItem (m_hWnd, IDC_OPACITY_BAR));
|
||||
ASSERT (m_OpacityBar);
|
||||
|
||||
//
|
||||
// Setup the opacity bar
|
||||
//
|
||||
m_OpacityBar->Set_Range (0, 10);
|
||||
m_OpacityBar->Modify_Point (0, 0, 255, 255, 255);
|
||||
m_OpacityBar->Insert_Point (1, 10, 0, 0, 0);
|
||||
|
||||
float value = ::atan (((m_Value.intensity / 10.0F) * 11.0F)) / DEG_TO_RAD (84.5) * 10.0F;
|
||||
m_OpacityBar->Set_Selection_Pos (value);
|
||||
|
||||
//
|
||||
// Setup the sliders
|
||||
//
|
||||
m_SliderY.SetRange (0, 179);
|
||||
m_SliderZ.SetRange (0, 179);
|
||||
|
||||
float log_test = ::log (8.0F);
|
||||
float log_test2 = ::_logb (log_test);
|
||||
float log_test3 = ::exp (log_test);
|
||||
|
||||
//
|
||||
// Convert the normalized vector to Euler angles...
|
||||
//
|
||||
|
||||
|
||||
/*Vector3 dir_vector (m_Value.X, m_Value.Y, m_Value.Z);
|
||||
|
||||
float x_rot = ::acos (dir_vector * Vector3 (1, 0, 0));
|
||||
float y_rot = ::acos (dir_vector * Vector3 (0, 1, 0));
|
||||
float z_rot = ::acos (dir_vector * Vector3 (0, 0, 1));
|
||||
x_rot = RAD_TO_DEG (x_rot);
|
||||
y_rot = RAD_TO_DEG (y_rot);
|
||||
z_rot = RAD_TO_DEG (z_rot);
|
||||
x_rot = WWMath::Wrap (x_rot, -180, 180);
|
||||
y_rot = WWMath::Wrap (y_rot, -180, 180);
|
||||
z_rot = WWMath::Wrap (z_rot, -180, 180);*/
|
||||
|
||||
/*Matrix3D rot_90 (1);
|
||||
rot_90.Rotate_Z (DEG_TO_RADF (90));
|
||||
|
||||
Vector3 x_axis (m_Value.X, m_Value.Y, m_Value.Z);
|
||||
x_axis.Normalize ();
|
||||
|
||||
Vector3 y_axis = rot_90 * x_axis;
|
||||
Vector3 z_axis;
|
||||
Vector3::Cross_Product (x_axis, y_axis, &z_axis);
|
||||
Matrix3D orientation (x_axis, y_axis, z_axis, Vector3 (0, 0, 0));
|
||||
|
||||
EulerAnglesClass euler_angle (orientation, EulerOrderXYZr);
|
||||
float x_rot = RAD_TO_DEG (euler_angle.Get_Angle (0));
|
||||
float y_rot = RAD_TO_DEG (euler_angle.Get_Angle (1));
|
||||
float z_rot = RAD_TO_DEG (euler_angle.Get_Angle (2));
|
||||
|
||||
x_rot = WWMath::Wrap (x_rot, 0, 360);
|
||||
y_rot = WWMath::Wrap (y_rot, 0, 360);
|
||||
z_rot = WWMath::Wrap (z_rot, 0, 360);*/
|
||||
|
||||
|
||||
Matrix3D rotation = Build_Matrix3D (m_Value.angle);
|
||||
//Vector3 point = m_Value.angle.Rotate_Vector (Vector3 (1, 0, 0));
|
||||
|
||||
EulerAnglesClass euler_angle (rotation, EulerOrderXYZr);
|
||||
//float x_rot = RAD_TO_DEG (euler_angle.Get_Angle (0));
|
||||
float y_rot = RAD_TO_DEG (euler_angle.Get_Angle (1));
|
||||
float z_rot = RAD_TO_DEG (euler_angle.Get_Angle (2));
|
||||
|
||||
//float y_rot = RAD_TO_DEG (rotation.Get_Y_Rotation ());
|
||||
//float z_rot = RAD_TO_DEG (rotation.Get_Z_Rotation ());
|
||||
|
||||
y_rot = WWMath::Wrap (y_rot, 0, 360);
|
||||
z_rot = WWMath::Wrap (z_rot, 0, 360);
|
||||
|
||||
m_SliderY.SetPos ((int)y_rot);
|
||||
m_SliderZ.SetPos ((int)z_rot);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnOK
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
OpacityVectorDialogClass::OnOK (void)
|
||||
{
|
||||
m_Value = Update_Value ();
|
||||
CDialog::OnOK ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Object
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
OpacityVectorDialogClass::Update_Object (void)
|
||||
{
|
||||
Update_Object (Update_Value ());
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Value
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
AlphaVectorStruct
|
||||
OpacityVectorDialogClass::Update_Value (void)
|
||||
{
|
||||
AlphaVectorStruct value;
|
||||
|
||||
int y_pos = m_SliderY.GetPos ();
|
||||
int z_pos = m_SliderZ.GetPos ();
|
||||
|
||||
//float x_rot = DEG_TO_RADF ((float)x_pos);
|
||||
float y_rot = DEG_TO_RADF ((float)y_pos);
|
||||
float z_rot = DEG_TO_RADF ((float)z_pos);
|
||||
|
||||
Matrix3 rot_mat (true);
|
||||
//rot_mat.Rotate_X (x_rot);
|
||||
rot_mat.Rotate_Y (y_rot);
|
||||
rot_mat.Rotate_Z (z_rot);
|
||||
|
||||
value.angle = ::Build_Quaternion (rot_mat);
|
||||
|
||||
float percent = ::tan ((m_OpacityBar->Get_Selection_Pos () / 10.0F) * DEG_TO_RAD (84.5)) / 11.0F;
|
||||
percent = min (1.0F, percent);
|
||||
percent = max (0.0F, percent);
|
||||
|
||||
value.intensity = 10.0F * percent;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Update_Object
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
OpacityVectorDialogClass::Update_Object (const AlphaVectorStruct &value)
|
||||
{
|
||||
if (m_RenderObj != NULL) {
|
||||
|
||||
//
|
||||
// Determine what type of object this is
|
||||
//
|
||||
switch (m_RenderObj->Class_ID ())
|
||||
{
|
||||
case RenderObjClass::CLASSID_SPHERE:
|
||||
{
|
||||
//
|
||||
// Update the key with the new vector
|
||||
//
|
||||
|
||||
SphereVectorChannelClass &vector_channel = ((SphereRenderObjClass *)m_RenderObj)->Get_Vector_Channel ();
|
||||
vector_channel.Set_Key_Value (m_KeyIndex, value);
|
||||
|
||||
//
|
||||
// Force the animation to restart
|
||||
//
|
||||
((SphereRenderObjClass *)m_RenderObj)->Restart_Animation ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCancel
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
OpacityVectorDialogClass::OnCancel (void)
|
||||
{
|
||||
Update_Object (m_Value);
|
||||
CDialog::OnCancel ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnHScroll
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
OpacityVectorDialogClass::OnHScroll
|
||||
(
|
||||
UINT nSBCode,
|
||||
UINT nPos,
|
||||
CScrollBar * pScrollBar
|
||||
)
|
||||
{
|
||||
//
|
||||
// Update the object
|
||||
//
|
||||
Update_Object ();
|
||||
|
||||
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnNotify
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
OpacityVectorDialogClass::OnNotify
|
||||
(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
LRESULT *pResult
|
||||
)
|
||||
{
|
||||
CBR_NMHDR *color_bar_hdr = (CBR_NMHDR *)lParam;
|
||||
|
||||
//
|
||||
// Which control sent the notification?
|
||||
//
|
||||
switch (color_bar_hdr->hdr.idFrom)
|
||||
{
|
||||
case IDC_OPACITY_BAR:
|
||||
{
|
||||
//
|
||||
// Update the object
|
||||
//
|
||||
if (color_bar_hdr->hdr.code == CBRN_SEL_CHANGED) {
|
||||
Update_Object ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CDialog::OnNotify (wParam, lParam, pResult);
|
||||
}
|
||||
105
Code/Tools/W3DView/OpacityVectorDialog.h
Normal file
105
Code/Tools/W3DView/OpacityVectorDialog.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
** 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_OPACITYVECTORDIALOG_H__E86BBE8C_F527_11D3_A08F_00104B791122__INCLUDED_)
|
||||
#define AFX_OPACITYVECTORDIALOG_H__E86BBE8C_F527_11D3_A08F_00104B791122__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "resource.h"
|
||||
#include "sphereobj.h"
|
||||
|
||||
// Forward declarations
|
||||
class ColorBarClass;
|
||||
class RenderObjClass;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OpacityVectorDialogClass
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
class OpacityVectorDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
OpacityVectorDialogClass(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(OpacityVectorDialogClass)
|
||||
enum { IDD = IDD_OPACITY_VECTOR };
|
||||
CSliderCtrl m_SliderZ;
|
||||
CSliderCtrl m_SliderY;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(OpacityVectorDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(OpacityVectorDialogClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
virtual void OnCancel();
|
||||
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
////////////////////////////////////////////////////////////////
|
||||
void Set_Render_Obj (RenderObjClass *render_obj) { m_RenderObj = render_obj; }
|
||||
void Set_Vector (const AlphaVectorStruct &def_vector) { m_Value = def_vector; }
|
||||
const AlphaVectorStruct & Get_Vector (void) const { return m_Value; }
|
||||
void Set_Key_Index (int index) { m_KeyIndex = index; }
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Protected methods
|
||||
////////////////////////////////////////////////////////////////
|
||||
void Update_Object (const AlphaVectorStruct &value);
|
||||
void Update_Object (void);
|
||||
AlphaVectorStruct Update_Value (void);
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Private member data
|
||||
////////////////////////////////////////////////////////////////
|
||||
ColorBarClass * m_OpacityBar;
|
||||
RenderObjClass * m_RenderObj;
|
||||
AlphaVectorStruct m_Value;
|
||||
int m_KeyIndex;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_OPACITYVECTORDIALOG_H__E86BBE8C_F527_11D3_A08F_00104B791122__INCLUDED_)
|
||||
93
Code/Tools/W3DView/ParticleBlurTimeKeyDialog.cpp
Normal file
93
Code/Tools/W3DView/ParticleBlurTimeKeyDialog.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// ParticleBlurTimeKeyDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "ParticleBlurTimeKeyDialog.h"
|
||||
#include "Utils.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ParticleBlurTimeKeyDialogClass dialog
|
||||
|
||||
|
||||
ParticleBlurTimeKeyDialogClass::ParticleBlurTimeKeyDialogClass(float blur_time, CWnd* pParent) :
|
||||
CDialog(ParticleBlurTimeKeyDialogClass::IDD, pParent),
|
||||
m_BlurTime(blur_time)
|
||||
{
|
||||
//{{AFX_DATA_INIT(ParticleBlurTimeKeyDialogClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void ParticleBlurTimeKeyDialogClass::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(ParticleBlurTimeKeyDialogClass)
|
||||
DDX_Control(pDX, IDC_BLUR_TIME_SPIN, m_BlurTimeSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(ParticleBlurTimeKeyDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(ParticleBlurTimeKeyDialogClass)
|
||||
ON_BN_CLICKED(IDOK2, OnOk2)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ParticleBlurTimeKeyDialogClass message handlers
|
||||
|
||||
BOOL ParticleBlurTimeKeyDialogClass::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
Initialize_Spinner (m_BlurTimeSpin, m_BlurTime, -1024, 1024);
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
BOOL ParticleBlurTimeKeyDialogClass::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
||||
{
|
||||
//
|
||||
// Update the spinner control if necessary
|
||||
//
|
||||
NMHDR *pheader = (NMHDR *)lParam;
|
||||
if ((pheader != NULL) && (pheader->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN pupdown = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (pheader->hwndFrom, pupdown->iDelta);
|
||||
}
|
||||
|
||||
return CDialog::OnNotify(wParam, lParam, pResult);
|
||||
}
|
||||
|
||||
void ParticleBlurTimeKeyDialogClass::OnOk2()
|
||||
{
|
||||
m_BlurTime = GetDlgItemFloat(m_hWnd,IDC_BLUR_TIME_EDIT);
|
||||
CDialog::OnOK();
|
||||
}
|
||||
80
Code/Tools/W3DView/ParticleBlurTimeKeyDialog.h
Normal file
80
Code/Tools/W3DView/ParticleBlurTimeKeyDialog.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
** 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_PARTICLEBLURTIMEKEYDIALOG_H__FCCD7E5F_E09A_450E_A1A4_0E401CC00C3B__INCLUDED_)
|
||||
#define AFX_PARTICLEBLURTIMEKEYDIALOG_H__FCCD7E5F_E09A_450E_A1A4_0E401CC00C3B__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// ParticleBlurTimeKeyDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ParticleBlurTimeKeyDialogClass dialog
|
||||
|
||||
class ParticleBlurTimeKeyDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
ParticleBlurTimeKeyDialogClass(float blur_time, CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(ParticleBlurTimeKeyDialogClass)
|
||||
enum { IDD = IDD_PARTICLE_BLUR_TIME_KEY };
|
||||
CSpinButtonCtrl m_BlurTimeSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(ParticleBlurTimeKeyDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(ParticleBlurTimeKeyDialogClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnOk2();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
/////////////////////////////////////////////////////////////
|
||||
float Get_Blur_Time (void) const { return m_BlurTime; }
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Private member data
|
||||
/////////////////////////////////////////////////////////////
|
||||
float m_BlurTime;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_PARTICLEBLURTIMEKEYDIALOG_H__FCCD7E5F_E09A_450E_A1A4_0E401CC00C3B__INCLUDED_)
|
||||
94
Code/Tools/W3DView/ParticleFrameKeyDialog.cpp
Normal file
94
Code/Tools/W3DView/ParticleFrameKeyDialog.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// ParticleFrameKeyDialog.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "w3dview.h"
|
||||
#include "ParticleFrameKeyDialog.h"
|
||||
#include "Utils.H"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ParticleFrameKeyDialogClass dialog
|
||||
|
||||
|
||||
ParticleFrameKeyDialogClass::ParticleFrameKeyDialogClass(float frame,CWnd* pParent /*=NULL*/) :
|
||||
CDialog(ParticleFrameKeyDialogClass::IDD, pParent),
|
||||
m_Frame(frame)
|
||||
{
|
||||
//{{AFX_DATA_INIT(ParticleFrameKeyDialogClass)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void ParticleFrameKeyDialogClass::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(ParticleFrameKeyDialogClass)
|
||||
DDX_Control(pDX, IDC_FRAME_SPIN, m_FrameSpin);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(ParticleFrameKeyDialogClass, CDialog)
|
||||
//{{AFX_MSG_MAP(ParticleFrameKeyDialogClass)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ParticleFrameKeyDialogClass message handlers
|
||||
|
||||
|
||||
BOOL ParticleFrameKeyDialogClass::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
Initialize_Spinner (m_FrameSpin, m_Frame, -1024, 1024);
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
|
||||
void ParticleFrameKeyDialogClass::OnOK()
|
||||
{
|
||||
m_Frame = GetDlgItemFloat(m_hWnd,IDC_FRAME_EDIT);
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
BOOL ParticleFrameKeyDialogClass::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
||||
{
|
||||
//
|
||||
// Update the spinner control if necessary
|
||||
//
|
||||
NMHDR *pheader = (NMHDR *)lParam;
|
||||
if ((pheader != NULL) && (pheader->code == UDN_DELTAPOS)) {
|
||||
LPNMUPDOWN pupdown = (LPNMUPDOWN)lParam;
|
||||
::Update_Spinner_Buddy (pheader->hwndFrom, pupdown->iDelta);
|
||||
}
|
||||
|
||||
return CDialog::OnNotify(wParam, lParam, pResult);
|
||||
}
|
||||
81
Code/Tools/W3DView/ParticleFrameKeyDialog.h
Normal file
81
Code/Tools/W3DView/ParticleFrameKeyDialog.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
** 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_PARTICLEFRAMEKEYDIALOG_H__43470F6A_86E2_44CF_8ED9_EE9B74D35908__INCLUDED_)
|
||||
#define AFX_PARTICLEFRAMEKEYDIALOG_H__43470F6A_86E2_44CF_8ED9_EE9B74D35908__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// ParticleFrameKeyDialog.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ParticleFrameKeyDialogClass dialog
|
||||
|
||||
class ParticleFrameKeyDialogClass : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
ParticleFrameKeyDialogClass(float frame,CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(ParticleFrameKeyDialogClass)
|
||||
enum { IDD = IDD_PARTICLE_FRAME_KEY };
|
||||
CSpinButtonCtrl m_FrameSpin;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(ParticleFrameKeyDialogClass)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(ParticleFrameKeyDialogClass)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
/////////////////////////////////////////////////////////////
|
||||
float Get_Frame (void) const { return m_Frame; }
|
||||
|
||||
private:
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Private member data
|
||||
/////////////////////////////////////////////////////////////
|
||||
float m_Frame;
|
||||
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_PARTICLEFRAMEKEYDIALOG_H__43470F6A_86E2_44CF_8ED9_EE9B74D35908__INCLUDED_)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user