311 lines
8.2 KiB
C++
311 lines
8.2 KiB
C++
|
/*
|
||
|
** 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/>.
|
||
|
*/
|
||
|
|
||
|
// 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<VisSectorStatsClass> 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;
|
||
|
}
|