/* ** Command & Conquer Generals Zero Hour(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 . */ #include "StdAfx.h" #include "Resource.h" #include "ParticleEditorDialog.h" #include "CParticleEditorPage.h" #include "EmissionTypePanels.h" #include "GameClient/ParticleSys.h" #include "ParticleEditorExport.h" #include "ParticleTypePanels.h" #include "VelocityTypePanels.h" #define ARBITRARY_BUFF_SIZE 128 DebugWindowDialog::DebugWindowDialog(UINT nIDTemplate, CWnd* pParentWnd) : CDialog(nIDTemplate, pParentWnd), m_colorAlphaDialog(CColorAlphaDialog::IDD, this), m_switchesDialog(CSwitchesDialog::IDD, this), m_moreParmsDialog(MoreParmsDialog::IDD, this) { mMainWndHWND = ::FindWindow(NULL, "Command & Conquer: Generals"); m_activeEmissionPage = 0; m_activeVelocityPage = 0; m_activeParticlePage = 0; m_particleSystem = NULL; m_changeHasOcurred = false; m_shouldWriteINI = false; m_showColorDlg = false; m_showSwitchesDlg = false; m_showMoreParmsDlg = false; m_shouldBusyWait = false; m_shouldReload = false; m_shouldUpdateParticleCap = false; m_shouldReloadTextures = false; m_shouldKillAllParticleSystems = false; m_emissionTypePanels[0] = new EmissionPanelPoint; m_emissionTypePanels[1] = new EmissionPanelLine; m_emissionTypePanels[2] = new EmissionPanelBox; m_emissionTypePanels[3] = new EmissionPanelSphere; m_emissionTypePanels[4] = new EmissionPanelCylinder; m_velocityTypePanels[0] = new VelocityPanelOrtho; m_velocityTypePanels[1] = new VelocityPanelSphere; m_velocityTypePanels[2] = new VelocityPanelHemisphere; m_velocityTypePanels[3] = new VelocityPanelCylinder; m_velocityTypePanels[4] = new VelocityPanelOutward; m_particleTypePanels[0] = new ParticlePanelParticle; m_particleTypePanels[1] = new ParticlePanelDrawable; m_particleTypePanels[2] = new ParticlePanelStreak; m_particleParmValues.resize(PARM_NumParms); } DebugWindowDialog::~DebugWindowDialog() { int i; for (i = 0; i < NUM_EMISSION_TYPES; ++i) { delete m_emissionTypePanels[i]; } for (i = 0; i < NUM_VELOCITY_TYPES; ++i) { delete m_velocityTypePanels[i]; } for (i = 0; i < NUM_PARTICLE_TYPES; ++i) { delete m_particleTypePanels[i]; } } int DebugWindowDialog::OnCreate(LPCREATESTRUCT lpCreateStruct) { return CDialog::OnCreate(lpCreateStruct); } void DebugWindowDialog::InitPanel( void ) { CComboBox* pCombo; pCombo = (CComboBox*) GetDlgItem(IDC_PSEd_Priority); if (pCombo) { for (int i = 1; ParticlePriorityNames[i]; ++i) { pCombo->AddString(ParticlePriorityNames[i]); } pCombo->SetCurSel(0); } pCombo = (CComboBox*) GetDlgItem(IDC_PSEd_EmissionType); if (pCombo) { for (int i = 1; EmissionVolumeTypeNames[i]; ++i) { pCombo->AddString(EmissionVolumeTypeNames[i]); } pCombo->SetCurSel(0); } pCombo = (CComboBox*) GetDlgItem(IDC_PSEd_VelocityType); if (pCombo) { for (int i = 1; EmissionVelocityTypeNames[i]; ++i) { pCombo->AddString(EmissionVelocityTypeNames[i]); } pCombo->SetCurSel(0); } pCombo = (CComboBox*) GetDlgItem(IDC_PSEd_ParticleType); if (pCombo) { for (int i = 1; ParticleTypeNames[i]; ++i) { pCombo->AddString(ParticleTypeNames[i]); } pCombo->SetCurSel(0); } pCombo = (CComboBox*) GetDlgItem(IDC_PSEd_ShaderType); if (pCombo) { for (int i = 1; ParticleShaderTypeNames[i]; ++i) { pCombo->AddString(ParticleShaderTypeNames[i]); } pCombo->SetCurSel(0); } m_colorAlphaDialog.Create(CColorAlphaDialog::IDD, this); m_colorAlphaDialog.InitPanel(); m_switchesDialog.Create(CSwitchesDialog::IDD, this); m_switchesDialog.InitPanel(); m_moreParmsDialog.Create(MoreParmsDialog::IDD, this); m_moreParmsDialog.InitPanel(); CWnd *pWnd; int j; pWnd = GetDlgItem(IDC_PSEd_EmissionPanel); if (pWnd) { CRect rect; pWnd->GetWindowRect(&rect); ScreenToClient(&rect); for (j = 0; j < NUM_EMISSION_TYPES; ++j) { m_emissionTypePanels[j]->Create(m_emissionTypePanels[j]->GetIDD(), this); m_emissionTypePanels[j]->InitPanel(); m_emissionTypePanels[j]->ShowWindow(SW_HIDE); m_emissionTypePanels[j]->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER); } pWnd->ShowWindow(SW_HIDE); m_emissionTypePanels[0]->ShowWindow(SW_SHOW); } pWnd = GetDlgItem(IDC_PSEd_VelocityPanel); if (pWnd) { CRect rect; pWnd->GetWindowRect(&rect); ScreenToClient(&rect); for (j = 0; j < NUM_VELOCITY_TYPES; ++j) { m_velocityTypePanels[j]->Create(m_velocityTypePanels[j]->GetIDD(), this); m_velocityTypePanels[j]->InitPanel(); m_velocityTypePanels[j]->ShowWindow(SW_HIDE); m_velocityTypePanels[j]->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER); } pWnd->ShowWindow(SW_HIDE); m_velocityTypePanels[0]->ShowWindow(SW_SHOW); } pWnd = GetDlgItem(IDC_PSEd_ParticlePanel); if (pWnd) { CRect rect; pWnd->GetWindowRect(&rect); ScreenToClient(&rect); for (j = 0; j < NUM_PARTICLE_TYPES; ++j) { m_particleTypePanels[j]->Create(m_particleTypePanels[j]->GetIDD(), this); m_particleTypePanels[j]->InitPanel(); m_particleTypePanels[j]->ShowWindow(SW_HIDE); m_particleTypePanels[j]->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER); } pWnd->ShowWindow(SW_HIDE); m_particleTypePanels[0]->ShowWindow(SW_SHOW); } } HWND DebugWindowDialog::GetMainWndHWND(void) { return mMainWndHWND; } void DebugWindowDialog::addParticleSystem(const char *particleSystem) { if (!particleSystem) { return; } std::string particleSystemName = particleSystem; appendParticleSystemToList(particleSystemName); } void DebugWindowDialog::addThingTemplate(const char *thingTemplate) { if (!thingTemplate) { return; } std::string thingTemplateName = thingTemplate; appendThingTemplateToList(thingTemplateName); } void DebugWindowDialog::OnClose() { ShowWindow(SW_MINIMIZE); } void DebugWindowDialog::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); if (nType == SIZE_MINIMIZED) { if (mMainWndHWND) { ::SetFocus(mMainWndHWND); } } } void DebugWindowDialog::clearAllParticleSystems(void) { CComboBox* combo = (CComboBox*) GetDlgItem(IDC_PSEd_ParticleSystem); if (!combo) { return; } m_listOfParticleSystems.clear(); combo->ResetContent(); } void DebugWindowDialog::clearAllThingTemplates( void ) { m_listOfThingTemplates.clear(); // this is a kindof(dirty_hack), because there's no way at runtime to verify that // particleTypePanels[1] is actually a PArticlePanelDrawable ((ParticlePanelDrawable*)m_particleTypePanels[1])->clearAllThingTemplates(); } void DebugWindowDialog::appendParticleSystemToList( const std::string &rString ) { CComboBox* combo = (CComboBox*) GetDlgItem(IDC_PSEd_ParticleSystem); if (!combo) { return; } m_listOfParticleSystems.push_front(rString); combo->AddString(rString.c_str()); } void DebugWindowDialog::appendThingTemplateToList( IN const std::string &rString ) { m_listOfThingTemplates.push_back(rString); } void DebugWindowDialog::OnParticleSystemChange() { m_changeHasOcurred = true; } void DebugWindowDialog::OnPushSave() { m_shouldWriteINI = true; } void DebugWindowDialog::OnReloadTextures() { // First, reload the textures ParticlePanelParticle* pParticle = (ParticlePanelParticle*) m_particleTypePanels[0]; if (!pParticle) { return; } pParticle->InitPanel(); // Then, force an update to the ui, to repick the appropriate texture. performUpdate(true); // Finally, signal a flag to the asset manager to reload the actual textures. m_shouldReloadTextures = true; } Bool DebugWindowDialog::hasSelectionChanged(void) { if (m_changeHasOcurred) { m_changeHasOcurred = false; return true; } return false; } void DebugWindowDialog::getSelectedSystemName(char *bufferToCopyInto) const { if (!bufferToCopyInto) { return; } CComboBox* combo = (CComboBox*) GetDlgItem(IDC_PSEd_ParticleSystem); if (!combo) { bufferToCopyInto[0] = '\0'; return; } int ndx = combo->GetCurSel(); CString string; if (ndx > -1) { combo->GetLBText(ndx, string); strcpy(bufferToCopyInto, string.GetBuffer(0)); } else { combo->GetWindowText(string); strcpy(bufferToCopyInto, string.GetBuffer(0)); } } void DebugWindowDialog::getSelectedParticleAsciiStringParm( IN int parmNum, OUT char *bufferToCopyInto ) const { if (parmNum < 0 || parmNum >= PARM_NumParms || !bufferToCopyInto || !m_particleSystem) { return; } if (m_particleParmValues[parmNum].length()) { strcpy(bufferToCopyInto, m_particleParmValues[parmNum].c_str()); } else { bufferToCopyInto[0] = 0; } } void DebugWindowDialog::updateParticleAsciiStringParm( IN int parmNum, OUT const char *bufferToCopyFrom ) { if (parmNum < 0 || parmNum >= PARM_NumParms || !bufferToCopyFrom) { return; } m_particleParmValues[parmNum] = bufferToCopyFrom; } void DebugWindowDialog::getColorValueFromSystem(IN Int systemNum, OUT RGBColorKeyframe &colorFrame) const { if (systemNum >= MAX_KEYFRAMES || systemNum < 0 || !m_particleSystem) { return; } colorFrame = m_particleSystem->m_colorKey[systemNum]; } void DebugWindowDialog::updateColorValueToSystem(IN Int systemNum, IN const RGBColorKeyframe &colorFrame) { if (systemNum >= MAX_KEYFRAMES || systemNum < 0 || !m_particleSystem) { return; } m_particleSystem->m_colorKey[systemNum] = colorFrame; } void DebugWindowDialog::getAlphaRangeFromSystem(IN Int systemNum, OUT ParticleSystemInfo::RandomKeyframe &randomVar) const { if (systemNum >= MAX_KEYFRAMES || systemNum < 0 || !m_particleSystem) { return; } randomVar = m_particleSystem->m_alphaKey[systemNum]; } void DebugWindowDialog::updateAlphaRangeToSystem(IN Int systemNum, IN const ParticleSystemInfo::RandomKeyframe &randomVar) { if (systemNum >= MAX_KEYFRAMES || systemNum < 0 || !m_particleSystem) { return; } m_particleSystem->m_alphaKey[systemNum] = randomVar; } void DebugWindowDialog::getHalfSizeFromSystem( IN Int coordNum, OUT Real& halfSize) const { if (!m_particleSystem) { return; } switch (coordNum) { case 0: halfSize = m_particleSystem->m_emissionVolume.box.halfSize.x; return; case 1: halfSize = m_particleSystem->m_emissionVolume.box.halfSize.y; return; case 2: halfSize = m_particleSystem->m_emissionVolume.box.halfSize.z; return; default: return; }; } void DebugWindowDialog::updateHalfSizeToSystem( IN Int coordNum, IN const Real& halfSize) { if (!m_particleSystem) { return; } switch (coordNum) { case 0: m_particleSystem->m_emissionVolume.box.halfSize.x = halfSize; return; case 1: m_particleSystem->m_emissionVolume.box.halfSize.y = halfSize; return; case 2: m_particleSystem->m_emissionVolume.box.halfSize.z = halfSize; return; default: return; }; } void DebugWindowDialog::getSphereRadiusFromSystem( OUT Real &radius ) const { if (!m_particleSystem) { return; } radius = m_particleSystem->m_emissionVolume.sphere.radius; } void DebugWindowDialog::updateSphereRadiusToSystem( IN const Real &radius ) { if (!m_particleSystem) { return; } m_particleSystem->m_emissionVolume.sphere.radius = radius; } void DebugWindowDialog::getCylinderRadiusFromSystem( OUT Real &radius ) const { if (!m_particleSystem) { return; } radius = m_particleSystem->m_emissionVolume.cylinder.radius; } void DebugWindowDialog::updateCylinderRadiusToSystem( IN const Real &radius ) { if (!m_particleSystem) { return; } m_particleSystem->m_emissionVolume.cylinder.radius = radius; } void DebugWindowDialog::getCylinderLengthFromSystem( OUT Real &length ) const { if (!m_particleSystem) { return; } length = m_particleSystem->m_emissionVolume.cylinder.length; } void DebugWindowDialog::updateCylinderLengthToSystem( IN const Real &length ) { if (!m_particleSystem) { return; } m_particleSystem->m_emissionVolume.cylinder.length = length; } void DebugWindowDialog::getLineFromSystem( IN Int coordNum, OUT Real& linePoint) const { if (!m_particleSystem) { return; } switch (coordNum) { case 0: linePoint = m_particleSystem->m_emissionVolume.line.start.x; return; case 1: linePoint = m_particleSystem->m_emissionVolume.line.start.y; return; case 2: linePoint = m_particleSystem->m_emissionVolume.line.start.z; return; case 3: linePoint = m_particleSystem->m_emissionVolume.line.end.x; return; case 4: linePoint = m_particleSystem->m_emissionVolume.line.end.y; return; case 5: linePoint = m_particleSystem->m_emissionVolume.line.end.z; return; default: return; }; } void DebugWindowDialog::updateLineToSystem( IN Int coordNum, IN const Real& linePoint) { if (!m_particleSystem) { return; } switch (coordNum) { case 0: m_particleSystem->m_emissionVolume.line.start.x = linePoint; return; case 1: m_particleSystem->m_emissionVolume.line.start.y = linePoint; return; case 2: m_particleSystem->m_emissionVolume.line.start.z = linePoint; return; case 3: m_particleSystem->m_emissionVolume.line.end.x = linePoint; return; case 4: m_particleSystem->m_emissionVolume.line.end.y = linePoint; return; case 5: m_particleSystem->m_emissionVolume.line.end.z = linePoint; return; default: return; }; } void DebugWindowDialog::getVelSphereFromSystem( IN Int velNum, OUT Real &radius) const { if (!m_particleSystem) { return; } switch (velNum) { case 0: radius = m_particleSystem->m_emissionVelocity.spherical.speed.m_low; return; case 1: radius = m_particleSystem->m_emissionVelocity.spherical.speed.m_high; return; default: return; }; } void DebugWindowDialog::updateVelSphereToSystem( IN Int velNum, IN const Real &radius) { if (!m_particleSystem) { return; } switch (velNum) { case 0: m_particleSystem->m_emissionVelocity.spherical.speed.m_low = radius; return; case 1: m_particleSystem->m_emissionVelocity.spherical.speed.m_high = radius; return; default: return; }; } void DebugWindowDialog::getVelHemisphereFromSystem( IN Int velNum, OUT Real &radius) const { if (!m_particleSystem) { return; } switch (velNum) { case 0: radius = m_particleSystem->m_emissionVelocity.hemispherical.speed.m_low; return; case 1: radius = m_particleSystem->m_emissionVelocity.hemispherical.speed.m_high; return; default: return; }; } void DebugWindowDialog::updateVelHemisphereToSystem( IN Int velNum, IN const Real &radius) { if (!m_particleSystem) { return; } switch (velNum) { case 0: m_particleSystem->m_emissionVelocity.hemispherical.speed.m_low = radius; return; case 1: m_particleSystem->m_emissionVelocity.hemispherical.speed.m_high = radius; return; default: return; }; } void DebugWindowDialog::getVelOrthoFromSystem( IN Int coordNum, OUT Real& ortho) const { if (!m_particleSystem) { return; } switch (coordNum) { case 0: ortho = m_particleSystem->m_emissionVelocity.ortho.x.m_low; return; case 1: ortho = m_particleSystem->m_emissionVelocity.ortho.y.m_low; return; case 2: ortho = m_particleSystem->m_emissionVelocity.ortho.z.m_low; return; case 3: ortho = m_particleSystem->m_emissionVelocity.ortho.x.m_high; return; case 4: ortho = m_particleSystem->m_emissionVelocity.ortho.y.m_high; return; case 5: ortho = m_particleSystem->m_emissionVelocity.ortho.z.m_high; return; default: return; }; } void DebugWindowDialog::updateVelOrthoToSystem( IN Int coordNum, IN const Real& ortho) { if (!m_particleSystem) { return; } switch (coordNum) { case 0: m_particleSystem->m_emissionVelocity.ortho.x.m_low = ortho; return; case 1: m_particleSystem->m_emissionVelocity.ortho.y.m_low = ortho; return; case 2: m_particleSystem->m_emissionVelocity.ortho.z.m_low = ortho; return; case 3: m_particleSystem->m_emissionVelocity.ortho.x.m_high = ortho; return; case 4: m_particleSystem->m_emissionVelocity.ortho.y.m_high = ortho; return; case 5: m_particleSystem->m_emissionVelocity.ortho.z.m_high = ortho; return; default: return; }; } void DebugWindowDialog::getVelCylinderFromSystem( IN Int coordNum, OUT Real& cylinder) const { if (!m_particleSystem) { return; } switch (coordNum) { case 0: cylinder = m_particleSystem->m_emissionVelocity.cylindrical.radial.m_low; return; case 1: cylinder = m_particleSystem->m_emissionVelocity.cylindrical.normal.m_low; return; case 2: cylinder = m_particleSystem->m_emissionVelocity.cylindrical.radial.m_high; return; case 3: cylinder = m_particleSystem->m_emissionVelocity.cylindrical.normal.m_high; return; default: return; }; } void DebugWindowDialog::updateVelCylinderToSystem( IN Int coordNum, IN const Real& cylinder) { if (!m_particleSystem) { return; } switch (coordNum) { case 0: m_particleSystem->m_emissionVelocity.cylindrical.radial.m_low = cylinder; return; case 1: m_particleSystem->m_emissionVelocity.cylindrical.normal.m_low = cylinder; return; case 2: m_particleSystem->m_emissionVelocity.cylindrical.radial.m_high = cylinder; return; case 3: m_particleSystem->m_emissionVelocity.cylindrical.normal.m_high = cylinder; return; default: return; }; } void DebugWindowDialog::getVelOutwardFromSystem( IN Int coordNum, OUT Real& cylinder) const { if (!m_particleSystem) { return; } switch (coordNum) { case 0: cylinder = m_particleSystem->m_emissionVelocity.outward.speed.m_low; return; case 1: cylinder = m_particleSystem->m_emissionVelocity.outward.otherSpeed.m_low; return; case 2: cylinder = m_particleSystem->m_emissionVelocity.outward.speed.m_high; return; case 3: cylinder = m_particleSystem->m_emissionVelocity.outward.otherSpeed.m_high; return; default: return; }; } void DebugWindowDialog::updateVelOutwardToSystem( IN Int coordNum, IN const Real& cylinder) { if (!m_particleSystem) { return; } switch (coordNum) { case 0: m_particleSystem->m_emissionVelocity.outward.speed.m_low = cylinder; return; case 1: m_particleSystem->m_emissionVelocity.outward.otherSpeed.m_low = cylinder; return; case 2: m_particleSystem->m_emissionVelocity.outward.speed.m_high = cylinder; return; case 3: m_particleSystem->m_emissionVelocity.outward.otherSpeed.m_high = cylinder; return; default: return; }; } void DebugWindowDialog::getParticleNameFromSystem( OUT char *buffer, IN int buffLen ) const { if (!m_particleSystem) { return; } if (!buffer) { return; } getSelectedParticleAsciiStringParm( PARM_ParticleTypeName, buffer); } void DebugWindowDialog::updateParticleNameToSystem( IN const char *buffer ) { if (!m_particleSystem) { return; } if (!buffer) { return; } updateParticleAsciiStringParm( PARM_ParticleTypeName, buffer); } void DebugWindowDialog::getDrawableNameFromSystem( OUT char *buffer, IN int buffLen ) const { getParticleNameFromSystem(buffer, buffLen); } void DebugWindowDialog::updateDrawableNameToSystem( IN const char* buffer ) { updateParticleNameToSystem(buffer); } void DebugWindowDialog::updateCurrentParticleSystem(ParticleSystemTemplate *particleTemplate ) { m_particleSystem = particleTemplate; performUpdate(true); } void DebugWindowDialog::updateSystemUseParameters(IN ParticleSystemTemplate *particleTemplate ) { m_particleSystem = particleTemplate; performUpdate(false); } void DebugWindowDialog::getInitialDelayFromSystem( IN Int parmNum, OUT Real& initialDelay ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: initialDelay = m_particleSystem->m_initialDelay.m_low; return; case 1: initialDelay = m_particleSystem->m_initialDelay.m_high; return; default: return; }; } void DebugWindowDialog::updateInitialDelayToSystem( IN Int parmNum, IN const Real& initialDelay ) { if (!m_particleSystem) { return; } switch (parmNum) { case 0: m_particleSystem->m_initialDelay.m_low = initialDelay; return; case 1: m_particleSystem->m_initialDelay.m_high = initialDelay; return; default: return; }; } void DebugWindowDialog::getBurstDelayFromSystem( IN Int parmNum, OUT Real& burstDelay ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: burstDelay = m_particleSystem->m_burstDelay.m_low; return; case 1: burstDelay = m_particleSystem->m_burstDelay.m_high; return; default: return; }; } void DebugWindowDialog::updateBurstDelayToSystem( IN Int parmNum, IN const Real& burstDelay ) { if (!m_particleSystem) { return; } switch (parmNum) { case 0: m_particleSystem->m_burstDelay.m_low = burstDelay; return; case 1: m_particleSystem->m_burstDelay.m_high = burstDelay; return; default: return; }; } void DebugWindowDialog::getBurstCountFromSystem( IN Int parmNum, OUT Real& burstCount ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: burstCount = m_particleSystem->m_burstCount.m_low; return; case 1: burstCount = m_particleSystem->m_burstCount.m_high; return; default: return; }; } void DebugWindowDialog::updateBurstCountToSystem( IN Int parmNum, IN const Real& burstCount ) { if (!m_particleSystem) { return; } switch (parmNum) { case 0: m_particleSystem->m_burstCount.m_low = burstCount; return; case 1: m_particleSystem->m_burstCount.m_high = burstCount; return; default: return; }; } void DebugWindowDialog::getColorScaleFromSystem( IN Int parmNum, OUT Real& colorScale ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: colorScale = m_particleSystem->m_colorScale.m_low; return; case 1: colorScale = m_particleSystem->m_colorScale.m_high; return; default: return; }; } void DebugWindowDialog::updateColorScaleToSystem( IN Int parmNum, IN const Real& colorScale ) { if (!m_particleSystem) { return; } switch (parmNum) { case 0: m_particleSystem->m_colorScale.m_low = colorScale; return; case 1: m_particleSystem->m_colorScale.m_high = colorScale; return; default: return; }; } void DebugWindowDialog::getParticleLifetimeFromSystem( IN Int parmNum, OUT Real& particleLifetime ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: particleLifetime = m_particleSystem->m_lifetime.m_low; return; case 1: particleLifetime = m_particleSystem->m_lifetime.m_high; return; default: return; }; } void DebugWindowDialog::updateParticleLifetimeToSystem( IN Int parmNum, IN const Real& particleLifetime ) { if (!m_particleSystem) { return; } switch (parmNum) { case 0: m_particleSystem->m_lifetime.m_low = particleLifetime; return; case 1: m_particleSystem->m_lifetime.m_high = particleLifetime; return; default: return; }; } void DebugWindowDialog::getParticleSizeFromSystem( IN Int parmNum, OUT Real& particleSize ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: particleSize = m_particleSystem->m_startSize.m_low; return; case 1: particleSize = m_particleSystem->m_startSize.m_high; return; default: return; }; } void DebugWindowDialog::updateParticleSizeToSystem( IN Int parmNum, IN const Real& particleSize ) { if (!m_particleSystem) { return; } switch (parmNum) { case 0: m_particleSystem->m_startSize.m_low = particleSize; return; case 1: m_particleSystem->m_startSize.m_high = particleSize; return; default: return; }; } void DebugWindowDialog::getStartSizeRateFromSystem( IN Int parmNum, OUT Real& startSizeRate ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: startSizeRate = m_particleSystem->m_startSizeRate.m_low; return; case 1: startSizeRate = m_particleSystem->m_startSizeRate.m_high; return; default: return; }; } void DebugWindowDialog::updateStartSizeRateToSystem( IN Int parmNum, IN const Real& startSizeRate ) { if (!m_particleSystem) { return; } switch (parmNum) { case 0: m_particleSystem->m_startSizeRate.m_low = startSizeRate; return; case 1: m_particleSystem->m_startSizeRate.m_high = startSizeRate; return; default: return; }; } void DebugWindowDialog::getSizeRateFromSystem( IN Int parmNum, OUT Real& sizeRate ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: sizeRate = m_particleSystem->m_sizeRate.m_low; return; case 1: sizeRate = m_particleSystem->m_sizeRate.m_high; return; default: return; }; } void DebugWindowDialog::updateSizeRateToSystem( IN Int parmNum, IN const Real& sizeRate ) { if (!m_particleSystem) { return; } switch (parmNum) { case 0: m_particleSystem->m_sizeRate.m_low = sizeRate; return; case 1: m_particleSystem->m_sizeRate.m_high = sizeRate; return; default: return; }; } void DebugWindowDialog::getSizeDampingFromSystem( IN Int parmNum, OUT Real& sizeDamping ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: sizeDamping = m_particleSystem->m_sizeRateDamping.m_low; return; case 1: sizeDamping = m_particleSystem->m_sizeRateDamping.m_high; return; default: return; }; } void DebugWindowDialog::updateSizeDampingToSystem( IN Int parmNum, IN const Real& sizeDamping ) { if (!m_particleSystem) { return; } switch (parmNum) { case 0: m_particleSystem->m_sizeRateDamping.m_low = sizeDamping; return; case 1: m_particleSystem->m_sizeRateDamping.m_high = sizeDamping; return; default: return; }; } void DebugWindowDialog::getSystemLifetimeFromSystem( OUT Real& systemLifetime ) const { if (!m_particleSystem) { return; } systemLifetime = m_particleSystem->m_systemLifetime; } void DebugWindowDialog::updateSystemLifetimeToSystem( IN const Real& systemLifetime ) { if (!m_particleSystem) { return; } m_particleSystem->m_systemLifetime = systemLifetime; } void DebugWindowDialog::getSlaveOffsetFromSystem( IN Int parmNum, OUT Real& slaveOffset ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: slaveOffset = m_particleSystem->m_slavePosOffset.x; return; case 1: slaveOffset = m_particleSystem->m_slavePosOffset.y; return; case 2: slaveOffset = m_particleSystem->m_slavePosOffset.z; return; default: return; }; } void DebugWindowDialog::updateSlaveOffsetToSystem( IN Int parmNum, IN const Real& slaveOffset ) { if (!m_particleSystem) { return; } switch (parmNum) { case 0: m_particleSystem->m_slavePosOffset.x = slaveOffset; return; case 1: m_particleSystem->m_slavePosOffset.y = slaveOffset; return; case 2: m_particleSystem->m_slavePosOffset.z = slaveOffset; return; default: return; }; } void DebugWindowDialog::getDriftVelocityFromSystem( IN Int parmNum, OUT Real& driftVelocity ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: driftVelocity = m_particleSystem->m_driftVelocity.x; return; case 1: driftVelocity = m_particleSystem->m_driftVelocity.y; return; case 2: driftVelocity = m_particleSystem->m_driftVelocity.z; return; default: return; }; } void DebugWindowDialog::updateDriftVelocityToSystem( IN Int parmNum, IN const Real& driftVelocity ) { if (!m_particleSystem) { return; } switch (parmNum) { case 0: m_particleSystem->m_driftVelocity.x = driftVelocity; return; case 1: m_particleSystem->m_driftVelocity.y = driftVelocity; return; case 2: m_particleSystem->m_driftVelocity.z = driftVelocity; return; default: return; }; } void DebugWindowDialog::getSlaveSystemFromSystem( OUT char *buffer, IN Int bufferSize) const { if (!m_particleSystem) { return; } getSelectedParticleAsciiStringParm(PARM_SlaveSystemName, buffer); } void DebugWindowDialog::updateSlaveSystemToSystem( IN const char *buffer ) { if (!m_particleSystem) { return; } updateParticleAsciiStringParm(PARM_SlaveSystemName, buffer); } void DebugWindowDialog::getPerParticleSystemFromSystem( OUT char *buffer, IN Int bufferSize) const { if (!m_particleSystem) { return; } getSelectedParticleAsciiStringParm(PARM_AttachedSystemName, buffer); } void DebugWindowDialog::updatePerParticleSystemToSystem( IN const char *buffer ) { if (!m_particleSystem) { return; } updateParticleAsciiStringParm(PARM_AttachedSystemName, buffer); } void DebugWindowDialog::getSwitchFromSystem( IN SwitchType switchType, OUT Bool& switchVal) const { if (!m_particleSystem) { return; } switch (switchType) { case ST_HOLLOW: switchVal = m_particleSystem->m_isEmissionVolumeHollow; break; case ST_ONESHOT: switchVal = m_particleSystem->m_isOneShot; break; case ST_ALIGNXY: switchVal = m_particleSystem->m_isGroundAligned; break; case ST_EMITABOVEGROUNDONLY: switchVal = m_particleSystem->m_isEmitAboveGroundOnly; break; case ST_PARTICLEUPTOWARDSEMITTER: switchVal = m_particleSystem->m_isParticleUpTowardsEmitter; break; }; } void DebugWindowDialog::updateSwitchToSystem( IN SwitchType switchType, IN const Bool& switchVal) { if (!m_particleSystem) { return; } switch (switchType) { case ST_HOLLOW: m_particleSystem->m_isEmissionVolumeHollow = switchVal; break; case ST_ONESHOT: m_particleSystem->m_isOneShot = switchVal; break; case ST_ALIGNXY: m_particleSystem->m_isGroundAligned = switchVal; break; case ST_EMITABOVEGROUNDONLY: m_particleSystem->m_isEmitAboveGroundOnly = switchVal; break; case ST_PARTICLEUPTOWARDSEMITTER: m_particleSystem->m_isParticleUpTowardsEmitter = switchVal; break; }; } // ------------------------------------------------------------------------------------------------ static Real degreeToRadian( Real degree ) { return (degree / 180.0f) * PI; } static Real radianToDegree( Real radian ) { return (180.0f * radian) / PI; } void DebugWindowDialog::getPingPongStartAngleFromSystem( IN Int parmNum, OUT Real& angle ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: angle = m_particleSystem->m_windMotionStartAngleMin; break; case 1: angle = m_particleSystem->m_windMotionStartAngleMax; break; default: return; }; angle = radianToDegree( angle ); } void DebugWindowDialog::updatePingPongStartAngleToSystem( IN Int parmNum, IN const Real& angle ) { if (!m_particleSystem) { return; } Real radian = degreeToRadian( angle ); switch (parmNum) { case 0: m_particleSystem->m_windMotionStartAngleMin = radian; return; case 1: m_particleSystem->m_windMotionStartAngleMax = radian; return; default: return; }; } void DebugWindowDialog::getPingPongEndAngleFromSystem( IN Int parmNum, OUT Real& angle ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: angle = m_particleSystem->m_windMotionEndAngleMin; break; case 1: angle = m_particleSystem->m_windMotionEndAngleMax; break; default: return; }; angle = radianToDegree( angle ); } void DebugWindowDialog::updatePingPongEndAngleToSystem( IN Int parmNum, IN const Real& angle ) { if (!m_particleSystem) { return; } Real radian = degreeToRadian( angle ); switch (parmNum) { case 0: m_particleSystem->m_windMotionEndAngleMin = radian; return; case 1: m_particleSystem->m_windMotionEndAngleMax = radian; return; default: return; }; } void DebugWindowDialog::getWindAngleChangeFromSystem( IN Int parmNum, OUT Real& angle ) const { if (!m_particleSystem) { return; } switch (parmNum) { case 0: angle = m_particleSystem->m_windAngleChangeMin; break; case 1: angle = m_particleSystem->m_windAngleChangeMax; break; default: return; }; angle = radianToDegree( angle ); } void DebugWindowDialog::updateWindAngleChangeToSystem( IN Int parmNum, IN const Real& angle ) { if (!m_particleSystem) { return; } Real radian = degreeToRadian( angle ); switch (parmNum) { case 0: m_particleSystem->m_windAngleChangeMin = radian; return; case 1: m_particleSystem->m_windAngleChangeMax = radian; return; default: return; }; } void DebugWindowDialog::getWindMotionFromSystem( OUT ParticleSystemInfo::WindMotion& windMotion ) const { if (!m_particleSystem) { return; } windMotion = m_particleSystem->m_windMotion; } void DebugWindowDialog::updateWindMotionToSystem( IN const ParticleSystemInfo::WindMotion& windMotion ) { if (!m_particleSystem) { return; } m_particleSystem->m_windMotion = windMotion; } // The reason I'm using this function is to prohibit me from forgetting to add an update // one way or the other. The idea is that when you implement one, you might as well implement // the other, and this way they're in one place. void DebugWindowDialog::performUpdate( IN Bool toUI ) { if (!m_particleSystem) { return; } static char buff[ARBITRARY_BUFF_SIZE]; { // Update the emission type, velocity type, particle type and shader type. CComboBox *pCombo; pCombo = (CComboBox*) GetDlgItem(IDC_PSEd_Priority); if (pCombo) { int selndx; if (toUI) { selndx = pCombo->SelectString(-1, ParticlePriorityNames[(long) m_particleSystem->m_priority]); } else { selndx = pCombo->GetCurSel(); if (selndx >= 0) { m_particleSystem->m_priority = (ParticlePriorityType)(selndx + 1); } } } pCombo = (CComboBox*) GetDlgItem(IDC_PSEd_EmissionType); if (pCombo) { int selndx; if (toUI) { selndx = pCombo->SelectString(-1, EmissionVolumeTypeNames[(long) m_particleSystem->m_emissionVolumeType]); } else { selndx = pCombo->GetCurSel(); if (selndx >= 0) { m_particleSystem->m_emissionVolumeType = (ParticleSystemInfo::EmissionVolumeType) (selndx + 1); } } // do the page swap if (selndx != m_activeEmissionPage && selndx >= 0) { m_emissionTypePanels[m_activeEmissionPage]->ShowWindow(SW_HIDE); m_activeEmissionPage = selndx; m_emissionTypePanels[m_activeEmissionPage]->ShowWindow(SW_SHOW); } } pCombo = (CComboBox*) GetDlgItem(IDC_PSEd_VelocityType); if (pCombo) { int selndx; if (toUI) { selndx = pCombo->SelectString(-1, EmissionVelocityTypeNames[(long) m_particleSystem->m_emissionVelocityType]); } else { selndx = pCombo->GetCurSel(); if (selndx >= 0) { m_particleSystem->m_emissionVelocityType = (ParticleSystemInfo::EmissionVelocityType) (selndx + 1); } } // do the page swap if (selndx != m_activeVelocityPage && selndx >= 0) { m_velocityTypePanels[m_activeVelocityPage]->ShowWindow(SW_HIDE); m_activeVelocityPage = selndx; m_velocityTypePanels[m_activeVelocityPage]->ShowWindow(SW_SHOW); } } pCombo = (CComboBox*) GetDlgItem(IDC_PSEd_ParticleType); if (pCombo) { int selndx; if (toUI) { selndx = pCombo->SelectString(-1, ParticleTypeNames[(long) m_particleSystem->m_particleType]); } else { selndx = pCombo->GetCurSel(); if (selndx >= 0) { m_particleSystem->m_particleType = (ParticleSystemInfo::ParticleType) (selndx + 1); } } // do the swap if (selndx != m_activeParticlePage && selndx >= 0) { m_particleTypePanels[m_activeParticlePage]->ShowWindow(SW_HIDE); m_activeParticlePage = selndx; m_particleTypePanels[m_activeParticlePage]->ShowWindow(SW_SHOW); } } pCombo = (CComboBox*) GetDlgItem(IDC_PSEd_ShaderType); if (pCombo) { if (toUI) { pCombo->SelectString(-1, ParticleShaderTypeNames[(long) m_particleSystem->m_shaderType]); } else { int selndx = pCombo->GetCurSel(); if (selndx >= 0) { m_particleSystem->m_shaderType = (ParticleSystemInfo::ParticleShaderType) (selndx + 1); } } } } { // update the minimum and maximum for Angle X, Y and Z, and Angular X, Y, and Z CWnd *pWnd; pWnd = GetDlgItem(IDC_PSEd_AngleXMin); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, 0.0f); pWnd->SetWindowText(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngleYMin); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, 0.0f); pWnd->SetWindowText(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngleZMin); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, m_particleSystem->m_angleZ.getMinimumValue()); pWnd->SetWindowText(buff); } else { pWnd->GetWindowText(buff, ARBITRARY_BUFF_SIZE - 1); m_particleSystem->m_angleZ.m_low = atof(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngleXMax); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, 0.0f); pWnd->SetWindowText(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngleYMax); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, 0.0f); pWnd->SetWindowText(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngleZMax); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, m_particleSystem->m_angleZ.getMaximumValue()); pWnd->SetWindowText(buff); } else { pWnd->GetWindowText(buff, ARBITRARY_BUFF_SIZE - 1); m_particleSystem->m_angleZ.m_high = atof(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngularRateXMin); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, 0.0f); pWnd->SetWindowText(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngularRateYMin); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, 0.0f); pWnd->SetWindowText(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngularRateZMin); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, m_particleSystem->m_angularRateZ.getMinimumValue()); pWnd->SetWindowText(buff); } else { pWnd->GetWindowText(buff, ARBITRARY_BUFF_SIZE - 1); m_particleSystem->m_angularRateZ.m_low = atof(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngularRateXMax); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, 0.0f); pWnd->SetWindowText(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngularRateYMax); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, 0.0f); pWnd->SetWindowText(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngularRateZMax); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, m_particleSystem->m_angularRateZ.getMaximumValue()); pWnd->SetWindowText(buff); } else { pWnd->GetWindowText(buff, ARBITRARY_BUFF_SIZE - 1); m_particleSystem->m_angularRateZ.m_high = atof(buff); } } } { // update the damping values. CWnd *pWnd; pWnd = GetDlgItem(IDC_PSEd_AngleDampingMin); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, m_particleSystem->m_angularDamping.getMinimumValue()); pWnd->SetWindowText(buff); } else { pWnd->GetWindowText(buff, ARBITRARY_BUFF_SIZE - 1); m_particleSystem->m_angularDamping.m_low = atof(buff); } } pWnd = GetDlgItem(IDC_PSEd_AngleDampingMax); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, m_particleSystem->m_angularDamping.getMaximumValue()); pWnd->SetWindowText(buff); } else { pWnd->GetWindowText(buff, ARBITRARY_BUFF_SIZE - 1); m_particleSystem->m_angularDamping.m_high = atof(buff); } } pWnd = GetDlgItem(IDC_PSEd_VelocityDampingMin); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, m_particleSystem->m_velDamping.getMinimumValue()); pWnd->SetWindowText(buff); } else { pWnd->GetWindowText(buff, ARBITRARY_BUFF_SIZE - 1); m_particleSystem->m_velDamping.m_low = atof(buff); } } pWnd = GetDlgItem(IDC_PSEd_VelocityDampingMax); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, m_particleSystem->m_velDamping.getMaximumValue()); pWnd->SetWindowText(buff); } else { pWnd->GetWindowText(buff, ARBITRARY_BUFF_SIZE - 1); m_particleSystem->m_velDamping.m_high = atof(buff); } } } { // update gravity CWnd *pWnd; pWnd = GetDlgItem(IDC_PSEd_Gravity); if (pWnd) { if (toUI) { sprintf(buff, FORMAT_STRING, m_particleSystem->m_gravity); pWnd->SetWindowText(buff); } else { pWnd->GetWindowText(buff, ARBITRARY_BUFF_SIZE - 1); m_particleSystem->m_gravity = atof(buff); } } } { // all the kids need to update too. m_colorAlphaDialog.performUpdate(toUI); m_switchesDialog.performUpdate(toUI); m_moreParmsDialog.performUpdate(toUI); m_emissionTypePanels[m_activeEmissionPage]->performUpdate(toUI); m_velocityTypePanels[m_activeVelocityPage]->performUpdate(toUI); m_particleTypePanels[m_activeParticlePage]->performUpdate(toUI); } } void DebugWindowDialog::OnParticleSystemEdit() { signalParticleSystemEdit(); } void DebugWindowDialog::signalParticleSystemEdit( void ) { performUpdate(false); } void DebugWindowDialog::OnEditColorAlpha() { CButton *pButton = (CButton*) GetDlgItem(IDC_PSEd_EditColorButton); if (!pButton) { return; } m_showColorDlg = !m_showColorDlg; if (m_showColorDlg) { m_colorAlphaDialog.ShowWindow(SW_SHOW); pButton->SetCheck(TRUE); } else { m_colorAlphaDialog.ShowWindow(SW_HIDE); pButton->SetCheck(FALSE); } } void DebugWindowDialog::OnEditSwitches() { CButton *pButton = (CButton*) GetDlgItem(IDC_PSEd_EditSwitchesButton); if (!pButton) { return; } m_showSwitchesDlg = !m_showSwitchesDlg ; if (m_showSwitchesDlg) { m_switchesDialog.ShowWindow(SW_SHOW); pButton->SetCheck(TRUE); } else { m_switchesDialog.ShowWindow(SW_HIDE); pButton->SetCheck(FALSE); } } // kill all particle systems in the world -- one time effect void DebugWindowDialog::OnKillAllParticleSystems() { m_shouldKillAllParticleSystems = true; } void DebugWindowDialog::OnEditMoreParms() { CButton *pButton = (CButton*) GetDlgItem(IDC_PSEd_Continued); if (!pButton) { return; } m_showMoreParmsDlg = !m_showMoreParmsDlg ; if (m_showMoreParmsDlg ) { m_moreParmsDialog.ShowWindow(SW_SHOW); pButton->SetCheck(TRUE); } else { m_moreParmsDialog.ShowWindow(SW_HIDE); pButton->SetCheck(FALSE); } } Bool DebugWindowDialog::shouldWriteINI( void ) { if (m_shouldWriteINI) { m_shouldWriteINI = false; return true; } return false; } Bool DebugWindowDialog::hasRequestedReload( void ) { if (m_shouldReload) { m_shouldReload = false; return true; } return false; } Bool DebugWindowDialog::shouldBusyWait( void ) { return m_shouldBusyWait; } Bool DebugWindowDialog::shouldUpdateParticleCap( void ) { if (m_shouldUpdateParticleCap) { m_shouldUpdateParticleCap = false; return true; } return false; } Bool DebugWindowDialog::shouldReloadTextures( void ) { if (m_shouldReloadTextures) { m_shouldReloadTextures = false; return true; } return false; } Bool DebugWindowDialog::shouldKillAllParticleSystems( void ) { if (m_shouldKillAllParticleSystems) { m_shouldKillAllParticleSystems = false; return true; } return false; } void DebugWindowDialog::OnSysCommand(UINT nID, LPARAM lParam) { CDialog::OnSysCommand(nID, lParam); } void DebugWindowDialog::OnReloadSystem( void ) { m_shouldReload = true; } void DebugWindowDialog::OnReloadCurrent() { OnReloadSystem(); } void DebugWindowDialog::OnReloadAll() { OnReloadSystem(); } void DebugWindowDialog::OnSaveCurrent() { OnPushSave(); } void DebugWindowDialog::OnSaveAll() { OnPushSave(); } void DebugWindowDialog::OnParticleCapEdit() { m_shouldUpdateParticleCap = true; } void DebugWindowDialog::updateCurrentParticleCap( IN int particleCap ) { static char buff[ARBITRARY_BUFF_SIZE]; CWnd *pWnd = GetDlgItem(IDC_PSEd_CurrentParticleCap); if (!pWnd) { return; } sprintf(buff, "%d", particleCap); pWnd->SetWindowText(buff); } void DebugWindowDialog::updateCurrentNumParticles( IN int particleCount ) { static char buff[ARBITRARY_BUFF_SIZE]; CWnd *pWnd = GetDlgItem(IDC_PSEd_CurrentParticleCount); if (!pWnd) { return; } sprintf(buff, "%d", particleCount); pWnd->SetWindowText(buff); } int DebugWindowDialog::getNewParticleCap( void ) { static char buff[ARBITRARY_BUFF_SIZE]; CWnd *pWnd = GetDlgItem(IDC_PSEd_CurrentParticleCap); if (!pWnd) { return -1; } pWnd->GetWindowText(buff, ARBITRARY_BUFF_SIZE - 1); return atoi(buff); } BEGIN_MESSAGE_MAP(DebugWindowDialog, CDialog) ON_WM_CREATE() ON_WM_CLOSE() ON_WM_SIZE() ON_WM_SYSCOMMAND() ON_CBN_SELCHANGE(IDC_PSEd_ParticleSystem, OnParticleSystemChange) ON_BN_CLICKED(IDC_PSEd_Go, OnParticleSystemChange) ON_BN_CLICKED(IDC_PSEd_EditColorButton, OnEditColorAlpha) ON_BN_CLICKED(IDC_PSEd_Continued, OnEditMoreParms) ON_BN_CLICKED(IDC_PSEd_Save, OnPushSave) ON_BN_CLICKED(IDC_PSEd_EditSwitchesButton, OnEditSwitches) ON_BN_CLICKED(IDC_PSEd_KillAll, OnKillAllParticleSystems) ON_CBN_SELCHANGE(IDC_PSEd_Priority, OnParticleSystemEdit) ON_CBN_SELCHANGE(IDC_PSEd_EmissionType, OnParticleSystemEdit) ON_CBN_SELCHANGE(IDC_PSEd_VelocityType, OnParticleSystemEdit) ON_CBN_SELCHANGE(IDC_PSEd_ParticleType, OnParticleSystemEdit) ON_CBN_SELCHANGE(IDC_PSEd_ShaderType, OnParticleSystemEdit) ON_COMMAND(ID_FILE_RELOADCURRENT, OnReloadCurrent) ON_COMMAND(ID_FILE_RELOADALL, OnReloadAll) ON_COMMAND(ID_FILE_SAVECURRENT, OnSaveCurrent) ON_COMMAND(ID_FILE_SAVEALL, OnSaveAll) ON_COMMAND(ID_FILE_RELOADTEXTURES, OnReloadTextures) ON_EN_KILLFOCUS(IDC_PSEd_CurrentParticleCap, OnParticleCapEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngleXMin, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngleYMin, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngleZMin, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngleXMax, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngleYMax, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngleZMax, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngularRateXMin, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngularRateYMin, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngularRateZMin, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngularRateXMax, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngularRateYMax, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngularRateZMax, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngleDampingMin, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_AngleDampingMax, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_VelocityDampingMin, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_VelocityDampingMax, OnParticleSystemEdit) ON_EN_KILLFOCUS(IDC_PSEd_Gravity, OnParticleSystemEdit) END_MESSAGE_MAP()