| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686 |
- /*
- ** 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/>.
- */
- // VideoConfigDialog.cpp : implementation file
- //
- #include "stdafx.h"
- #include "wwconfig.h"
- #include "videoconfigdialog.h"
- #include "ww3d.h"
- #include "assetmgr.h"
- #include "locale_api.h"
- #include "wwconfig_ids.h"
- #include "assetstatus.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- static VideoConfigDialogClass* VideoConfigDialogInstance;
- /////////////////////////////////////////////////////////////////////////////
- // Globals
- /////////////////////////////////////////////////////////////////////////////
- WW3DAssetManager *_TheAssetMgr = NULL;;
- /////////////////////////////////////////////////////////////////////////////
- // Local prototypes
- /////////////////////////////////////////////////////////////////////////////
- int _cdecl ResolutionSortCallback (const void *elem1, const void *elem2);
- /////////////////////////////////////////////////////////////////////////////
- // Constants
- /////////////////////////////////////////////////////////////////////////////
- enum
- {
- COL_DEVICE_NAME = 0
- };
- /////////////////////////////////////////////////////////////////////////////
- //
- // VideoConfigDialogClass
- //
- /////////////////////////////////////////////////////////////////////////////
- VideoConfigDialogClass::VideoConfigDialogClass (CWnd *pParent)
- : CurrentBitDepth (16),
- CurrentWidth (800),
- CurrentHeight (600),
- CurrentDriverIndex (0),
- CurrentIsWindowed (false),
- CDialog(VideoConfigDialogClass::IDD, pParent)
- {
- //{{AFX_DATA_INIT(VideoConfigDialogClass)
- // NOTE: the ClassWizard will add member initialization here
- //}}AFX_DATA_INIT
- WWASSERT(!VideoConfigDialogInstance); // Only one can exist at a time!
- VideoConfigDialogInstance=this;
- CDialog::Create (VideoConfigDialogClass::IDD, pParent);
- return ;
- }
- VideoConfigDialogClass::~VideoConfigDialogClass ()
- {
- VideoConfigDialogInstance=NULL;
- }
- VideoConfigDialogClass* VideoConfigDialogClass::Get_Instance ()
- {
- return VideoConfigDialogInstance;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // DoDataExchange
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::DoDataExchange (CDataExchange *pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(VideoConfigDialogClass)
- DDX_Control(pDX, IDC_RESOLUTION_SLIDER, m_ResSliderCtrl);
- DDX_Control(pDX, IDC_DRIVER_LIST, m_DriverListCtrl);
- //}}AFX_DATA_MAP
- return ;
- }
- BEGIN_MESSAGE_MAP(VideoConfigDialogClass, CDialog)
- //{{AFX_MSG_MAP(VideoConfigDialogClass)
- ON_WM_DESTROY()
- ON_NOTIFY(LVN_ITEMCHANGED, IDC_DRIVER_LIST, OnItemchangedDriverList)
- ON_CBN_SELCHANGE(IDC_BITDEPTH_COMBO, OnSelchangeBitdepthCombo)
- ON_WM_HSCROLL()
- ON_BN_CLICKED(IDC_WINDOWED_CHECK, OnWindowedCheck)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnInitDialog
- //
- // Modified: 12/06/2001 by MML - Retrieving strings from Locomoto file.
- /////////////////////////////////////////////////////////////////////////////
- BOOL
- VideoConfigDialogClass::OnInitDialog (void)
- {
- char string [_MAX_PATH];
- CDialog::OnInitDialog ();
- //
- // Set all the static strings for this dialog.
- //
- Locale_GetString( IDS_DRIVER, string );
- SetDlgItemText( IDC_DRIVER, string );
- Locale_GetString( IDS_DISPLAY, string );
- SetDlgItemText( IDC_STATIC2, string );
- Locale_GetString( IDS_RESOLUTION, string );
- SetDlgItemText( IDC_RESOLUTION, string );
- Locale_GetString( IDS_COLOR_DEPTH, string );
- SetDlgItemText( IDC_BIT_DEPTH, string );
- Locale_GetString( IDS_WINDOWED_MODE, string );
- SetDlgItemText( IDC_WINDOWED_CHECK, string );
- //
- // Initialize the engine
- //
- _TheAssetMgr = new WW3DAssetManager;
- WW3D::Init (m_hWnd);
- AssetStatusClass::Peek_Instance()->Enable_Reporting (false);
- //
- // Load the render device settings from the registry
- //
- char device_name[256] = { 0 };
- int texture_depth = 0;
- int width = 0;
- int height = 0;
- int bit_depth = 0;
- int windowed = 0;
- if (WW3D::Registry_Load_Render_Device (RENEGADE_SUB_KEY_NAME_RENDER, device_name, 256,
- width, height, bit_depth, windowed, texture_depth))
- {
- if (width != -1) {
- CurrentWidth = width;
- }
- if (height != -1) {
- CurrentHeight = height;
- }
- if (bit_depth != -1) {
- CurrentBitDepth = bit_depth;
- }
- if (windowed != -1) {
- CurrentIsWindowed = bool(windowed == 1);
- }
- }
-
- //
- // Set the extended styles for the list control
- //
- m_DriverListCtrl.SetExtendedStyle (m_DriverListCtrl.GetExtendedStyle () | LVS_EX_FULLROWSELECT);
- //
- // Configure the columns
- //
- m_DriverListCtrl.InsertColumn (COL_DEVICE_NAME, "Device Name");
- //
- // Populate the render device list control
- //
- bool found_default_entry = false;
- int driver_count = WW3D::Get_Render_Device_Count ();
- for (int index = 0; index < driver_count; index ++) {
- const RenderDeviceDescClass &device_desc = WW3D::Get_Render_Device_Desc (index);
- //
- // Build a human readable name for this driver
- //
- CString driver_name;
- driver_name.Format ("%s - %s", device_desc.Get_Device_Name (), device_desc.Get_Hardware_Name ());
- //
- // Add this driver to the list control
- //
- int item_index = m_DriverListCtrl.InsertItem (0xFF, driver_name);
- if (item_index >= 0) {
- m_DriverListCtrl.SetItemData (item_index, index);
- }
- //
- // Check to see if this is the default entry
- //
- const char *render_device_name = WW3D::Get_Render_Device_Name (index);
- if (::lstrcmpi (device_name, render_device_name) == 0) {
- m_DriverListCtrl.SetItemState (item_index, LVIS_SELECTED, LVIS_SELECTED);
- found_default_entry = true;
- }
- }
- //
- // Set the "windowed mode" checkbox
- //
- SendDlgItemMessage (IDC_WINDOWED_CHECK, BM_SETCHECK, (WPARAM)CurrentIsWindowed);
- //
- // Select the first entry for deafult (if necessary)
- //
- if (found_default_entry == false) {
- m_DriverListCtrl.SetItemState (0, LVIS_SELECTED, LVIS_SELECTED);
- }
- //
- // Size the columns
- //
- CRect rect;
- m_DriverListCtrl.GetClientRect (&rect);
- int col_width = rect.Width () - ::GetSystemMetrics (SM_CXVSCROLL);
- m_DriverListCtrl.SetColumnWidth (0, col_width);
- //
- // Build the resolution list for the currently selected device
- //
- Update_Display_Settings ();
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnDestroy
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::OnDestroy (void)
- {
- //
- // Shutdown the engine
- //
- WW3D::Shutdown ();
- delete _TheAssetMgr;
- _TheAssetMgr = NULL;
- CDialog::OnDestroy ();
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Update_Display_Settings
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::Update_Display_Settings (void)
- {
- //
- // Get the selected device
- //
- int selected_index = m_DriverListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
- if (selected_index < 0) {
- return ;
- }
- //
- // Lookup the device description for the selected device
- //
- CurrentDriverIndex = (int)m_DriverListCtrl.GetItemData (selected_index);
- const RenderDeviceDescClass &driver_info = WW3D::Get_Render_Device_Desc (CurrentDriverIndex);
- ResolutionList = driver_info.Enumerate_Resolutions ();
- CurrentCaps=driver_info.Get_Caps();
- CurrentAdapterIdentifier=driver_info.Get_Adapter_Identifier();
- //
- // Update the dialog controls
- //
- Update_Color_Combo ();
- Update_Resolution_Slider ();
- Select_Default_Resolution ();
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Update_Resolution_Slider
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::Update_Resolution_Slider (void)
- {
- //
- // Lookup the device description for the selected device
- //
- const RenderDeviceDescClass &driver_info = WW3D::Get_Render_Device_Desc (CurrentDriverIndex);
- ResolutionList = driver_info.Enumerate_Resolutions ();
- //
- // Filter out any resolutions that don't fit the current
- // bit depth
- //
- for (int index = 0; index < ResolutionList.Count (); index ++) {
- const ResolutionDescClass &res_desc = ResolutionList[index];
- //
- // Remove this resolution if it doesn't fit the current
- // bit depth
- //
- if (res_desc.BitDepth != CurrentBitDepth || res_desc.Width < 640 || res_desc.Height < 480) {
- ResolutionList.Delete (index);
- index --;
- }
- }
- //
- // Sort the entries
- //
- if (ResolutionList.Count () > 0) {
- ::qsort (&ResolutionList[0], ResolutionList.Count (), sizeof (ResolutionList[0]), ResolutionSortCallback);
- }
- //
- // Configure the slider control
- //
- m_ResSliderCtrl.ClearTics ();
- m_ResSliderCtrl.SetRange (0, ResolutionList.Count () - 1);
- //
- // Setup the tick marks
- //
- for (index = 0; index < ResolutionList.Count (); index ++) {
- m_ResSliderCtrl.SetTic (index);
- }
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Update_Color_Combo
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::Update_Color_Combo (void)
- {
- //
- // Start fresh
- //
- SendDlgItemMessage (IDC_BITDEPTH_COMBO, CB_RESETCONTENT);
- //
- // Loop over all the resolutions and add the different
- // bit-depths to the combo box
- //
- bool selected = false;
- for (int index = 0; index < ResolutionList.Count (); index ++) {
-
- const ResolutionDescClass &res_desc = ResolutionList[index];
- char string [_MAX_PATH];
- CString color_string;
- //
- // Make a display string out of the bit depth
- //
- Locale_GetString (IDS_BIT, string);
- color_string.Format ("%d %s", res_desc.BitDepth, string);
- //
- // Check to see if this string is already in the combobox
- //
- int item_index = SendDlgItemMessage (IDC_BITDEPTH_COMBO, CB_FINDSTRINGEXACT, 0, (LPARAM)(LPCTSTR)color_string);
- if (item_index == CB_ERR) {
- //
- // Add this entry to the combobox
- //
- int item_index = SendDlgItemMessage (IDC_BITDEPTH_COMBO, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)color_string);
- if (item_index != CB_ERR) {
- SendDlgItemMessage (IDC_BITDEPTH_COMBO, CB_SETITEMDATA, (WPARAM)item_index, (LPARAM)res_desc.BitDepth);
- //
- // Select this entry if its the current bit depth
- //
- if (res_desc.BitDepth == CurrentBitDepth) {
- SendDlgItemMessage (IDC_BITDEPTH_COMBO, CB_SETCURSEL, (WPARAM)item_index);
- selected = true;
- }
- }
- }
- }
- //
- // Select the first entry by default
- //
- if (!selected) {
- SendDlgItemMessage (IDC_BITDEPTH_COMBO, CB_SETCURSEL, 0);
- CurrentBitDepth = SendDlgItemMessage (IDC_BITDEPTH_COMBO, CB_GETITEMDATA, 0);
- if (CurrentBitDepth <= 0) {
- CurrentBitDepth = 16;
- }
- }
-
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Select_Default_Resolution
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::Select_Default_Resolution (void)
- {
- int best_selection = 0;
- float best_width_err = 1000.0F;
- float best_height_err = 1000.0F;
-
- //
- // Loop over all the available resolutions and try to select
- // the one that most closely matches the desired resolution
- //
- for (int index = 0; index < ResolutionList.Count (); index ++) {
- const ResolutionDescClass &res_desc = ResolutionList[index];
- //
- // Calculate how far off this resolution is from the one
- // we want to select
- //
- float width_err = WWMath::Fabs(((float)CurrentWidth / (float)res_desc.Width) - 1.0F);
- float height_err = WWMath::Fabs(((float)CurrentHeight / (float)res_desc.Height) - 1.0F);
- //
- // Is this the closest match so far?
- //
- if (width_err <= best_width_err && height_err <= best_height_err) {
- best_width_err = width_err;
- best_height_err = height_err;
- best_selection = index;
- }
- }
- //
- // Select the closest match
- //
- m_ResSliderCtrl.SetPos (best_selection);
- Update_Resolution_Text ();
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Update_Resolution_Text
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::Update_Resolution_Text (void)
- {
- int res_index = m_ResSliderCtrl.GetPos ();
- if (res_index >= 0) {
-
- //
- // Make a display string for the current resolution
- //
- const ResolutionDescClass &res_desc = ResolutionList[res_index];
- CString res_string;
- res_string.Format ("%d x %d", res_desc.Width, res_desc.Height);
- //
- // Set the text of the dialog control
- //
- SetDlgItemText (IDC_RESOLUTION_STATIC, res_string);
- //
- // Store the current width and height
- //
- CurrentWidth = res_desc.Width;
- CurrentHeight = res_desc.Height;
- }
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnItemchangedDriverList
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::OnItemchangedDriverList
- (
- NMHDR * pNMHDR,
- LRESULT * pResult
- )
- {
- NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
- (*pResult) = 0;
- //
- // If the selection state changed, then update the resolution
- // list for this device
- //
- if (pNMListView->uChanged & LVIF_STATE) {
- Update_Display_Settings ();
- }
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // ResolutionSortCallback
- //
- /////////////////////////////////////////////////////////////////////////////
- int _cdecl
- ResolutionSortCallback (const void *elem1, const void *elem2)
- {
- const ResolutionDescClass *res1 = ((const ResolutionDescClass *)elem1);
- const ResolutionDescClass *res2 = ((const ResolutionDescClass *)elem2);
- int retval = 0;
- //
- // Sort based on bit-depth first
- //
- if (res1->BitDepth < res2->BitDepth) {
- retval = -1;
- } else if (res1->BitDepth > res2->BitDepth) {
- retval = 1;
- } else {
- //
- // Sort based on width next
- //
- if (res1->Width < res2->Width) {
- retval = -1;
- } else if (res1->Width > res2->Width) {
- retval = 1;
- } else {
- //
- // Sort based on height last
- //
- if (res1->Height < res2->Height) {
- retval = -1;
- } else if (res1->Height > res2->Height) {
- retval = 1;
- }
- }
- }
- return retval;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnSelchangeBitdepthCombo
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::OnSelchangeBitdepthCombo (void)
- {
- int index = SendDlgItemMessage (IDC_BITDEPTH_COMBO, CB_GETCURSEL);
- if (index != CB_ERR) {
- //
- // Update the current bit depth
- //
- CurrentBitDepth = SendDlgItemMessage (IDC_BITDEPTH_COMBO, CB_GETITEMDATA, (WPARAM)index);
- if (CurrentBitDepth <= 0) {
- CurrentBitDepth = 16;
- }
- //
- // Update the dialog controls
- //
- Update_Resolution_Slider ();
- Select_Default_Resolution ();
- }
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnHScroll
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::OnHScroll (UINT nSBCode, UINT nPos, CScrollBar *pScrollBar)
- {
- CDialog::OnHScroll (nSBCode, nPos, pScrollBar);
- //
- // Simply update the display text on the dialog to reflect the new resolution
- //
- Update_Resolution_Text ();
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Apply_Changes
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::Apply_Changes (void)
- {
- //
- // Save the changes to the registry
- //
- WW3D::Registry_Save_Render_Device (RENEGADE_SUB_KEY_NAME_RENDER, CurrentDriverIndex,
- CurrentWidth, CurrentHeight, CurrentBitDepth, CurrentIsWindowed, WW3D::Get_Texture_Bitdepth());
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // WindowProc
- //
- /////////////////////////////////////////////////////////////////////////////
- LRESULT
- VideoConfigDialogClass::WindowProc
- (
- UINT message,
- WPARAM wParam,
- LPARAM lParam
- )
- {
- if (message == (WM_USER + 101)) {
- Apply_Changes ();
- }
- return CDialog::WindowProc(message, wParam, lParam);
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnWindowedCheck
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- VideoConfigDialogClass::OnWindowedCheck (void)
- {
- CurrentIsWindowed = (SendDlgItemMessage (IDC_WINDOWED_CHECK, BM_GETCHECK) == 1);
- return ;
- }
|