/* ** 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 . */ // 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 ; }