/* ** 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 . */ // VisStatsDialog.cpp : implementation file // #include "stdafx.h" #include "leveledit.h" #include "VisStatsDialog.h" #include "cameramgr.h" #include "utils.h" #include "pscene.h" #include "staticphys.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // Constants ///////////////////////////////////////////////////////////////////////////// enum { COL_NAME = 0, COL_POLY_COUNT, COL_TEXTURE_COUNT, COL_TEXTURE_KB, }; ///////////////////////////////////////////////////////////////////////////// // Local prototypes ///////////////////////////////////////////////////////////////////////////// static int CALLBACK VisSectorSortCompareFn (LPARAM param1, LPARAM param2, LPARAM column_id); ///////////////////////////////////////////////////////////////////////////// // // VisStatsDialogClass // ///////////////////////////////////////////////////////////////////////////// VisStatsDialogClass::VisStatsDialogClass(CWnd* pParent /*=NULL*/) : m_CurrentColSort (COL_NAME), m_AscendingSort (true), CDialog(VisStatsDialogClass::IDD, pParent) { //{{AFX_DATA_INIT(VisStatsDialogClass) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT return ; } ///////////////////////////////////////////////////////////////////////////// // // DoDataExchange // ///////////////////////////////////////////////////////////////////////////// void VisStatsDialogClass::DoDataExchange (CDataExchange *pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(VisStatsDialogClass) DDX_Control(pDX, IDC_SECTOR_LIST, m_SectorList); //}}AFX_DATA_MAP return ; } BEGIN_MESSAGE_MAP(VisStatsDialogClass, CDialog) //{{AFX_MSG_MAP(VisStatsDialogClass) ON_NOTIFY(NM_DBLCLK, IDC_SECTOR_LIST, OnDblclkSectorList) ON_NOTIFY(LVN_DELETEITEM, IDC_SECTOR_LIST, OnDeleteitemSectorList) ON_NOTIFY(LVN_COLUMNCLICK, IDC_SECTOR_LIST, OnColumnclickSectorList) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // // OnInitDialog // ///////////////////////////////////////////////////////////////////////////// BOOL VisStatsDialogClass::OnInitDialog (void) { CDialog::OnInitDialog (); // // Setup the columns // m_SectorList.InsertColumn (COL_NAME, "Name"); m_SectorList.InsertColumn (COL_POLY_COUNT, "Polys"); m_SectorList.InsertColumn (COL_TEXTURE_COUNT, "Textures"); m_SectorList.InsertColumn (COL_TEXTURE_KB, "Texture KB"); // // Size the columns // CRect rect; m_SectorList.GetClientRect (&rect); int width1 = rect.Width () / 2; int width2 = width1 / 3; m_SectorList.SetColumnWidth (COL_NAME, width1); m_SectorList.SetColumnWidth (COL_POLY_COUNT, width2); m_SectorList.SetColumnWidth (COL_TEXTURE_COUNT, width2); m_SectorList.SetColumnWidth (COL_TEXTURE_KB, width2); // // Build a list of vis statistics // DynamicVectorClass stats_list; PhysicsSceneClass::Get_Instance ()->Generate_Vis_Statistics_Report (stats_list); // // Populate the list control with the vis statistics // for (int index = 0; index < stats_list.Count (); index ++) { VisSectorStatsClass §or_stats = stats_list[index]; LPCTSTR name = sector_stats.Get_Name (); if (name != NULL) { // // Add this sector to the list // int item_index = m_SectorList.InsertItem (0, name); if (item_index >= 0) { // // Set the columns of information for this sector // CString poly_count; poly_count.Format ("%d polys", sector_stats.Get_Polygon_Count ()); m_SectorList.SetItemText (item_index, COL_POLY_COUNT, poly_count); CString texture_count; texture_count.Format ("%d textures", sector_stats.Get_Texture_Count ()); m_SectorList.SetItemText (item_index, COL_TEXTURE_COUNT, texture_count); CString texture_size; texture_size.Format ("%d KB", sector_stats.Get_Texture_Bytes () / 1024); m_SectorList.SetItemText (item_index, COL_TEXTURE_KB, texture_size); // // Add the goto-point to the item // m_SectorList.SetItemData (item_index, (DWORD)(new VisSectorStatsClass(sector_stats))); } } } return TRUE; } ///////////////////////////////////////////////////////////////////////////// // // OnDblclkSectorList // ///////////////////////////////////////////////////////////////////////////// void VisStatsDialogClass::OnDblclkSectorList ( NMHDR* pNMHDR, LRESULT* pResult ) { (*pResult) = 0; // // Determine what client-coord location was double-clicked on // DWORD mouse_pos = ::GetMessagePos (); POINT hit_point = { GET_X_LPARAM (mouse_pos), GET_Y_LPARAM (mouse_pos) }; m_SectorList.ScreenToClient (&hit_point); // // Goto the sector that was double-clicked on (if possible) // UINT flags = 0; int index = m_SectorList.HitTest (hit_point, &flags); if ((index >= 0) && ((flags & LVHT_ONITEMLABEL) || (flags & LVHT_ONITEMICON))) { // // Snap the camera to the point // VisSectorStatsClass *stats = (VisSectorStatsClass *)m_SectorList.GetItemData (index); if (stats != NULL) { ::Get_Camera_Mgr ()->Set_Position (stats->Get_Position ()); ::Refresh_Main_View (); } } return ; } ///////////////////////////////////////////////////////////////////////////// // // OnDeleteitemSectorList // ///////////////////////////////////////////////////////////////////////////// void VisStatsDialogClass::OnDeleteitemSectorList ( NMHDR * pNMHDR, LRESULT* pResult ) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; (*pResult) = 0; // // Free the vector3 we kept around for this sector // VisSectorStatsClass *stats = NULL; stats = (VisSectorStatsClass *)m_SectorList.GetItemData (pNMListView->iItem); SAFE_DELETE (stats); m_SectorList.SetItemData (pNMListView->iItem, NULL); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnColumnclickSectorList // ///////////////////////////////////////////////////////////////////////////// void VisStatsDialogClass::OnColumnclickSectorList ( NMHDR* pNMHDR, LRESULT* pResult ) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; (*pResult) = 0; if (m_CurrentColSort == pNMListView->iSubItem) { m_AscendingSort = !m_AscendingSort; } else { m_CurrentColSort = pNMListView->iSubItem; m_AscendingSort = true; } m_SectorList.SortItems (VisSectorSortCompareFn, MAKELONG (m_CurrentColSort, m_AscendingSort)); return ; } ///////////////////////////////////////////////////////////////////////////// // // VisSectorSortCompareFn // ///////////////////////////////////////////////////////////////////////////// int CALLBACK VisSectorSortCompareFn (LPARAM param1, LPARAM param2, LPARAM sort_info) { int retval = 0; VisSectorStatsClass *stats1 = (VisSectorStatsClass *)param1; VisSectorStatsClass *stats2 = (VisSectorStatsClass *)param2; LONG column_id = LOWORD (sort_info); BOOL ascending = HIWORD (sort_info); if (stats1 != NULL && stats2 != NULL) { // // Determine the order based on which column the user clicked on // if (column_id == COL_NAME) { retval = ::strcmpi (stats1->Get_Name (), stats2->Get_Name ()); } else if (column_id == COL_POLY_COUNT) { retval = stats1->Get_Polygon_Count () - stats2->Get_Polygon_Count (); } else if (column_id == COL_TEXTURE_COUNT) { retval = stats1->Get_Texture_Count () - stats2->Get_Texture_Count (); } else if (column_id == COL_TEXTURE_KB) { retval = stats1->Get_Texture_Bytes () - stats2->Get_Texture_Bytes (); } } // // Invert the sort if necessary // if (ascending != TRUE) { retval = -retval; } return retval; }