371 lines
18 KiB
C++

/*
** 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 <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 : Buccaneer Bay *
* *
* File name : PS2GameMtlShaderDlg.cpp *
* *
* Programmer : Mike Lytle *
* *
* Start date : 10/12/1999 *
* *
* Last update : 10/12/1999 *
* *
* Taken from GTH's GameMtlShaderDlg.cpp *
*---------------------------------------------------------------------------------------------*
* Functions: *
* PS2GameMtlShaderDlg -- Constructor. *
* PGMSD::Dialog_Proc -- Respond to user selections. *
* PGMSD::ReloadDialog -- Setup the dialog box. *
* PGMSD::Apply_Preset -- Notify the material of the values for the selected setting. *
* PGMSD::Set_Preset -- Sets the dialog to one of the presets or custom. *
* PGMSD::CompareShaderToBlendPreset -- Determine if the settings conform to one of the prese*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "PS2GameMtlShaderDlg.h"
#include "GameMtlDlg.h"
#include "GameMtl.h"
#include "resource.h"
#define NUM_PS2_SHADER_BLEND_PRESETS 7
static char * _PS2ShaderBlendSettingPresetNames[NUM_PS2_SHADER_BLEND_PRESETS + 1] =
{
"Opaque",
"Additive",
"Source Subtracted",
"Destination Subtracted",
"Alpha Blend",
"Alpha Test",
"Alpha Test and Blend",
"------ Custom -----"
};
struct PS2ShaderBlendSettingPreset
{
int A;
int B;
int C;
int D;
bool DepthMask;
bool AlphaTest;
};
// (A - B) * C + D
static const PS2ShaderBlendSettingPreset PS2ShaderBlendSettingPresets[NUM_PS2_SHADER_BLEND_PRESETS] = {
{PSS_SRC, PSS_ZERO, PSS_ONE, PSS_ZERO, true, false}, // Opaque
{PSS_SRC, PSS_ZERO, PSS_ONE, PSS_DEST, false, false}, // Additive
{PSS_DEST, PSS_SRC, PSS_ONE, PSS_ZERO, false, false}, // Src subtracted
{PSS_SRC, PSS_DEST, PSS_ONE, PSS_ZERO, false, false}, // Dest subtracted
{PSS_SRC, PSS_DEST, PSS_SRC_ALPHA, PSS_DEST, false, false}, // Alpha blend
{PSS_SRC, PSS_ZERO, PSS_ONE, PSS_ZERO, true, true}, // Alpha test
{PSS_SRC, PSS_DEST, PSS_SRC_ALPHA, PSS_DEST, true, true}, // Alpha test & blend
};
/***********************************************************************************************
* PS2GameMtlShaderDlg -- Constructor. *
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
PS2GameMtlShaderDlg::PS2GameMtlShaderDlg
(
HWND parent,
IMtlParams * imp,
GameMtl * mtl,
int pass
) : GameMtlFormClass(imp,mtl,pass)
{
Create_Form(parent, IDD_GAMEMTL_PS2_SHADER);
}
/***********************************************************************************************
* PGMSD::Dialog_Proc -- Respond to user selections. *
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
BOOL PS2GameMtlShaderDlg::Dialog_Proc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam)
{
int cursel;
int i;
int id = LOWORD(wparam);
int code = HIWORD(wparam);
switch (message)
{
case WM_INITDIALOG:
for(i = 0; i <= NUM_PS2_SHADER_BLEND_PRESETS; i++) {
SendDlgItemMessage(dlg_wnd,IDC_PS2_PRESET_COMBO,CB_ADDSTRING,0,(LONG)_PS2ShaderBlendSettingPresetNames[i]);
}
SendDlgItemMessage(dlg_wnd,IDC_PS2_PRESET_COMBO,CB_SETCURSEL,0,0);
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
{
IParams->RollupMouseMessage(dlg_wnd,message,wparam,lparam);
}
return FALSE;
case WM_COMMAND:
{
if (code == CBN_SELCHANGE) {
switch (id)
{
// Shared by both shaders.
case IDC_DEPTHCOMPARE_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_DEPTHCOMPARE_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Depth_Compare(PassIndex,cursel);
break;
case IDC_PRIGRADIENT_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_PRIGRADIENT_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Pri_Gradient(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
case IDC_SECGRADIENT_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_SECGRADIENT_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Sec_Gradient(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
case IDC_DETAILCOLOR_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_DETAILCOLOR_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Detail_Color_Func(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
case IDC_DETAILALPHA_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_DETAILALPHA_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_Detail_Alpha_Func(PassIndex,cursel);
TheMtl->Notify_Changed();
break;
// Playstation 2 specific.
case IDC_PS2_PRESET_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_PS2_PRESET_COMBO,CB_GETCURSEL,0,0);
Apply_Preset(cursel);
break;
case IDC_A_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_A_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_PS2_Shader_Param_A(PassIndex,cursel);
TheMtl->Notify_Changed();
Set_Preset();
break;
case IDC_B_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_B_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_PS2_Shader_Param_B(PassIndex,cursel);
TheMtl->Notify_Changed();
Set_Preset();
break;
case IDC_C_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_C_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_PS2_Shader_Param_C(PassIndex,cursel);
TheMtl->Notify_Changed();
Set_Preset();
break;
case IDC_D_COMBO:
cursel = SendDlgItemMessage(dlg_wnd,IDC_D_COMBO,CB_GETCURSEL,0,0);
TheMtl->Set_PS2_Shader_Param_D(PassIndex,cursel);
TheMtl->Notify_Changed();
Set_Preset();
break;
}
} else {
switch(id) {
case IDC_DEPTHMASK_CHECK:
if (SendDlgItemMessage(dlg_wnd,IDC_DEPTHMASK_CHECK,BM_GETCHECK,0,0)) {
TheMtl->Set_Depth_Mask(PassIndex,W3DSHADER_DEPTHMASK_WRITE_ENABLE);
} else {
TheMtl->Set_Depth_Mask(PassIndex,W3DSHADER_DEPTHMASK_WRITE_DISABLE);
}
Set_Preset();
break;
case IDC_ALPHATEST_CHECK:
if (SendDlgItemMessage(dlg_wnd,IDC_ALPHATEST_CHECK,BM_GETCHECK,0,0)) {
TheMtl->Set_Alpha_Test(PassIndex,W3DSHADER_ALPHATEST_ENABLE);
} else {
TheMtl->Set_Alpha_Test(PassIndex,W3DSHADER_ALPHATEST_DISABLE);
}
Set_Preset();
break;
case IDC_SHADER_DEFAULTS_BUTTON:
Set_Advanced_Defaults();
break;
}
}
}
}
return FALSE;
}
/***********************************************************************************************
* PGMSD::ReloadDialog -- Setup the dialog box. *
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
void PS2GameMtlShaderDlg::ReloadDialog(void)
{
DebugPrint("GameMtlShaderDlg::ReloadDialog\n");
SendDlgItemMessage(m_hWnd, IDC_PRIGRADIENT_COMBO, CB_SETCURSEL, TheMtl->Get_Pri_Gradient(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_SECGRADIENT_COMBO, CB_SETCURSEL, TheMtl->Get_Sec_Gradient(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_DEPTHCOMPARE_COMBO, CB_SETCURSEL, TheMtl->Get_Depth_Compare(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_DETAILCOLOR_COMBO, CB_SETCURSEL, TheMtl->Get_Detail_Color_Func(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_DETAILALPHA_COMBO, CB_SETCURSEL, TheMtl->Get_Detail_Alpha_Func(PassIndex), 0 );
SendDlgItemMessage(m_hWnd, IDC_A_COMBO, CB_SETCURSEL, TheMtl->Get_PS2_Shader_Param_A(PassIndex), 0);
SendDlgItemMessage(m_hWnd, IDC_B_COMBO, CB_SETCURSEL, TheMtl->Get_PS2_Shader_Param_B(PassIndex), 0);
SendDlgItemMessage(m_hWnd, IDC_C_COMBO, CB_SETCURSEL, TheMtl->Get_PS2_Shader_Param_C(PassIndex), 0);
SendDlgItemMessage(m_hWnd, IDC_D_COMBO, CB_SETCURSEL, TheMtl->Get_PS2_Shader_Param_D(PassIndex), 0);
Set_Preset();
SetCheckBox(m_hWnd,IDC_DEPTHMASK_CHECK, TheMtl->Get_Depth_Mask(PassIndex));
SetCheckBox(m_hWnd,IDC_ALPHATEST_CHECK, TheMtl->Get_Alpha_Test(PassIndex));
}
/***********************************************************************************************
* PGMSD::Apply_Preset -- Notify the material of the values for the selected setting. *
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
void PS2GameMtlShaderDlg::Apply_Preset(int preset_index)
{
if (preset_index < 0 || preset_index >= NUM_PS2_SHADER_BLEND_PRESETS) return;
const PS2ShaderBlendSettingPreset &preset = PS2ShaderBlendSettingPresets[preset_index];
int depth_mask = preset.DepthMask ? W3DSHADER_DEPTHMASK_WRITE_ENABLE : W3DSHADER_DEPTHMASK_WRITE_DISABLE;
TheMtl->Set_Depth_Mask(PassIndex, depth_mask);
int alpha_test = preset.AlphaTest ? W3DSHADER_ALPHATEST_ENABLE : W3DSHADER_ALPHATEST_DISABLE;
TheMtl->Set_Alpha_Test(PassIndex, alpha_test);
TheMtl->Set_PS2_Shader_Param_A(PassIndex, preset.A);
TheMtl->Set_PS2_Shader_Param_B(PassIndex, preset.B);
TheMtl->Set_PS2_Shader_Param_C(PassIndex, preset.C);
TheMtl->Set_PS2_Shader_Param_D(PassIndex, preset.D);
TheMtl->Notify_Changed();
ReloadDialog();
if (TheMtl->Compute_PC_Shader_From_PS2_Shader(PassIndex))
SetWindowText(GetDlgItem(m_hWnd,IDC_COMPATIBLE), " Compatible");
else
SetWindowText(GetDlgItem(m_hWnd,IDC_COMPATIBLE), " NOT Compatible");
}
/***********************************************************************************************
* PGMSD::Set_Preset -- Sets the dialog to one of the presets or custom. *
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
void PS2GameMtlShaderDlg::Set_Preset(void)
{
for (int i = 0; i < NUM_PS2_SHADER_BLEND_PRESETS; i++) {
if (CompareShaderToBlendPreset(PS2ShaderBlendSettingPresets[i])) break;
}
SendDlgItemMessage(m_hWnd, IDC_PS2_PRESET_COMBO, CB_SETCURSEL, i, 0);
if (TheMtl->Compute_PC_Shader_From_PS2_Shader(PassIndex))
SetWindowText(GetDlgItem(m_hWnd,IDC_COMPATIBLE), " Compatible");
else
SetWindowText(GetDlgItem(m_hWnd,IDC_COMPATIBLE), " NOT Compatible");
}
/***********************************************************************************************
* PGMSD::CompareShaderToBlendPreset -- Determine if the settings conform to one of the presets*
* *
* *
* *
* *
* HISTORY: *
* 10/12/1999MLL: Created. *
*=============================================================================================*/
bool PS2GameMtlShaderDlg::CompareShaderToBlendPreset(const PS2ShaderBlendSettingPreset &blend_preset)
{
bool depthmask = TheMtl->Get_Depth_Mask(PassIndex) != W3DSHADER_DEPTHMASK_WRITE_DISABLE;
if (depthmask != blend_preset.DepthMask) return false;
bool alphatest = TheMtl->Get_Alpha_Test(PassIndex) != W3DSHADER_ALPHATEST_DISABLE;
if (alphatest != blend_preset.AlphaTest) return false;
if (TheMtl->Get_PS2_Shader_Param_A(PassIndex) != blend_preset.A) return false;
if (TheMtl->Get_PS2_Shader_Param_B(PassIndex) != blend_preset.B) return false;
if (TheMtl->Get_PS2_Shader_Param_C(PassIndex) != blend_preset.C) return false;
if (TheMtl->Get_PS2_Shader_Param_D(PassIndex) != blend_preset.D) return false;
return true;
}
/***********************************************************************************************
* GameMtlShaderDlg::Set_Advanced_Defaults -- set advanced settings to defaults *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 02/26/99 NH : Created. *
*=============================================================================================*/
void PS2GameMtlShaderDlg::Set_Advanced_Defaults(void)
{
TheMtl->Set_Pri_Gradient(PassIndex, PSS_PRIGRADIENT_MODULATE);
TheMtl->Set_Depth_Compare(PassIndex, PSS_DEPTHCOMPARE_PASS_LEQUAL);
TheMtl->Set_Detail_Color_Func(PassIndex, W3DSHADER_DETAILCOLORFUNC_DEFAULT);
TheMtl->Set_Detail_Alpha_Func(PassIndex, W3DSHADER_DETAILALPHAFUNC_DEFAULT);
TheMtl->Notify_Changed();
ReloadDialog();
}