VisStatsDialog.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. // VisStatsDialog.cpp : implementation file
  19. //
  20. #include "stdafx.h"
  21. #include "leveledit.h"
  22. #include "VisStatsDialog.h"
  23. #include "cameramgr.h"
  24. #include "utils.h"
  25. #include "pscene.h"
  26. #include "staticphys.h"
  27. #ifdef _DEBUG
  28. #define new DEBUG_NEW
  29. #undef THIS_FILE
  30. static char THIS_FILE[] = __FILE__;
  31. #endif
  32. /////////////////////////////////////////////////////////////////////////////
  33. // Constants
  34. /////////////////////////////////////////////////////////////////////////////
  35. enum
  36. {
  37. COL_NAME = 0,
  38. COL_POLY_COUNT,
  39. COL_TEXTURE_COUNT,
  40. COL_TEXTURE_KB,
  41. };
  42. /////////////////////////////////////////////////////////////////////////////
  43. // Local prototypes
  44. /////////////////////////////////////////////////////////////////////////////
  45. static int CALLBACK VisSectorSortCompareFn (LPARAM param1, LPARAM param2, LPARAM column_id);
  46. /////////////////////////////////////////////////////////////////////////////
  47. //
  48. // VisStatsDialogClass
  49. //
  50. /////////////////////////////////////////////////////////////////////////////
  51. VisStatsDialogClass::VisStatsDialogClass(CWnd* pParent /*=NULL*/)
  52. : m_CurrentColSort (COL_NAME),
  53. m_AscendingSort (true),
  54. CDialog(VisStatsDialogClass::IDD, pParent)
  55. {
  56. //{{AFX_DATA_INIT(VisStatsDialogClass)
  57. // NOTE: the ClassWizard will add member initialization here
  58. //}}AFX_DATA_INIT
  59. return ;
  60. }
  61. /////////////////////////////////////////////////////////////////////////////
  62. //
  63. // DoDataExchange
  64. //
  65. /////////////////////////////////////////////////////////////////////////////
  66. void
  67. VisStatsDialogClass::DoDataExchange (CDataExchange *pDX)
  68. {
  69. CDialog::DoDataExchange(pDX);
  70. //{{AFX_DATA_MAP(VisStatsDialogClass)
  71. DDX_Control(pDX, IDC_SECTOR_LIST, m_SectorList);
  72. //}}AFX_DATA_MAP
  73. return ;
  74. }
  75. BEGIN_MESSAGE_MAP(VisStatsDialogClass, CDialog)
  76. //{{AFX_MSG_MAP(VisStatsDialogClass)
  77. ON_NOTIFY(NM_DBLCLK, IDC_SECTOR_LIST, OnDblclkSectorList)
  78. ON_NOTIFY(LVN_DELETEITEM, IDC_SECTOR_LIST, OnDeleteitemSectorList)
  79. ON_NOTIFY(LVN_COLUMNCLICK, IDC_SECTOR_LIST, OnColumnclickSectorList)
  80. //}}AFX_MSG_MAP
  81. END_MESSAGE_MAP()
  82. /////////////////////////////////////////////////////////////////////////////
  83. //
  84. // OnInitDialog
  85. //
  86. /////////////////////////////////////////////////////////////////////////////
  87. BOOL
  88. VisStatsDialogClass::OnInitDialog (void)
  89. {
  90. CDialog::OnInitDialog ();
  91. //
  92. // Setup the columns
  93. //
  94. m_SectorList.InsertColumn (COL_NAME, "Name");
  95. m_SectorList.InsertColumn (COL_POLY_COUNT, "Polys");
  96. m_SectorList.InsertColumn (COL_TEXTURE_COUNT, "Textures");
  97. m_SectorList.InsertColumn (COL_TEXTURE_KB, "Texture KB");
  98. //
  99. // Size the columns
  100. //
  101. CRect rect;
  102. m_SectorList.GetClientRect (&rect);
  103. int width1 = rect.Width () / 2;
  104. int width2 = width1 / 3;
  105. m_SectorList.SetColumnWidth (COL_NAME, width1);
  106. m_SectorList.SetColumnWidth (COL_POLY_COUNT, width2);
  107. m_SectorList.SetColumnWidth (COL_TEXTURE_COUNT, width2);
  108. m_SectorList.SetColumnWidth (COL_TEXTURE_KB, width2);
  109. //
  110. // Build a list of vis statistics
  111. //
  112. DynamicVectorClass<VisSectorStatsClass> stats_list;
  113. PhysicsSceneClass::Get_Instance ()->Generate_Vis_Statistics_Report (stats_list);
  114. //
  115. // Populate the list control with the vis statistics
  116. //
  117. for (int index = 0; index < stats_list.Count (); index ++) {
  118. VisSectorStatsClass &sector_stats = stats_list[index];
  119. LPCTSTR name = sector_stats.Get_Name ();
  120. if (name != NULL) {
  121. //
  122. // Add this sector to the list
  123. //
  124. int item_index = m_SectorList.InsertItem (0, name);
  125. if (item_index >= 0) {
  126. //
  127. // Set the columns of information for this sector
  128. //
  129. CString poly_count;
  130. poly_count.Format ("%d polys", sector_stats.Get_Polygon_Count ());
  131. m_SectorList.SetItemText (item_index, COL_POLY_COUNT, poly_count);
  132. CString texture_count;
  133. texture_count.Format ("%d textures", sector_stats.Get_Texture_Count ());
  134. m_SectorList.SetItemText (item_index, COL_TEXTURE_COUNT, texture_count);
  135. CString texture_size;
  136. texture_size.Format ("%d KB", sector_stats.Get_Texture_Bytes () / 1024);
  137. m_SectorList.SetItemText (item_index, COL_TEXTURE_KB, texture_size);
  138. //
  139. // Add the goto-point to the item
  140. //
  141. m_SectorList.SetItemData (item_index, (DWORD)(new VisSectorStatsClass(sector_stats)));
  142. }
  143. }
  144. }
  145. return TRUE;
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. //
  149. // OnDblclkSectorList
  150. //
  151. /////////////////////////////////////////////////////////////////////////////
  152. void
  153. VisStatsDialogClass::OnDblclkSectorList
  154. (
  155. NMHDR* pNMHDR,
  156. LRESULT* pResult
  157. )
  158. {
  159. (*pResult) = 0;
  160. //
  161. // Determine what client-coord location was double-clicked on
  162. //
  163. DWORD mouse_pos = ::GetMessagePos ();
  164. POINT hit_point = { GET_X_LPARAM (mouse_pos), GET_Y_LPARAM (mouse_pos) };
  165. m_SectorList.ScreenToClient (&hit_point);
  166. //
  167. // Goto the sector that was double-clicked on (if possible)
  168. //
  169. UINT flags = 0;
  170. int index = m_SectorList.HitTest (hit_point, &flags);
  171. if ((index >= 0) && ((flags & LVHT_ONITEMLABEL) || (flags & LVHT_ONITEMICON))) {
  172. //
  173. // Snap the camera to the point
  174. //
  175. VisSectorStatsClass *stats = (VisSectorStatsClass *)m_SectorList.GetItemData (index);
  176. if (stats != NULL) {
  177. ::Get_Camera_Mgr ()->Set_Position (stats->Get_Position ());
  178. ::Refresh_Main_View ();
  179. }
  180. }
  181. return ;
  182. }
  183. /////////////////////////////////////////////////////////////////////////////
  184. //
  185. // OnDeleteitemSectorList
  186. //
  187. /////////////////////////////////////////////////////////////////////////////
  188. void
  189. VisStatsDialogClass::OnDeleteitemSectorList
  190. (
  191. NMHDR * pNMHDR,
  192. LRESULT* pResult
  193. )
  194. {
  195. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  196. (*pResult) = 0;
  197. //
  198. // Free the vector3 we kept around for this sector
  199. //
  200. VisSectorStatsClass *stats = NULL;
  201. stats = (VisSectorStatsClass *)m_SectorList.GetItemData (pNMListView->iItem);
  202. SAFE_DELETE (stats);
  203. m_SectorList.SetItemData (pNMListView->iItem, NULL);
  204. return ;
  205. }
  206. /////////////////////////////////////////////////////////////////////////////
  207. //
  208. // OnColumnclickSectorList
  209. //
  210. /////////////////////////////////////////////////////////////////////////////
  211. void
  212. VisStatsDialogClass::OnColumnclickSectorList
  213. (
  214. NMHDR* pNMHDR,
  215. LRESULT* pResult
  216. )
  217. {
  218. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  219. (*pResult) = 0;
  220. if (m_CurrentColSort == pNMListView->iSubItem) {
  221. m_AscendingSort = !m_AscendingSort;
  222. } else {
  223. m_CurrentColSort = pNMListView->iSubItem;
  224. m_AscendingSort = true;
  225. }
  226. m_SectorList.SortItems (VisSectorSortCompareFn, MAKELONG (m_CurrentColSort, m_AscendingSort));
  227. return ;
  228. }
  229. /////////////////////////////////////////////////////////////////////////////
  230. //
  231. // VisSectorSortCompareFn
  232. //
  233. /////////////////////////////////////////////////////////////////////////////
  234. int CALLBACK
  235. VisSectorSortCompareFn (LPARAM param1, LPARAM param2, LPARAM sort_info)
  236. {
  237. int retval = 0;
  238. VisSectorStatsClass *stats1 = (VisSectorStatsClass *)param1;
  239. VisSectorStatsClass *stats2 = (VisSectorStatsClass *)param2;
  240. LONG column_id = LOWORD (sort_info);
  241. BOOL ascending = HIWORD (sort_info);
  242. if (stats1 != NULL && stats2 != NULL) {
  243. //
  244. // Determine the order based on which column the user clicked on
  245. //
  246. if (column_id == COL_NAME) {
  247. retval = ::strcmpi (stats1->Get_Name (), stats2->Get_Name ());
  248. } else if (column_id == COL_POLY_COUNT) {
  249. retval = stats1->Get_Polygon_Count () - stats2->Get_Polygon_Count ();
  250. } else if (column_id == COL_TEXTURE_COUNT) {
  251. retval = stats1->Get_Texture_Count () - stats2->Get_Texture_Count ();
  252. } else if (column_id == COL_TEXTURE_KB) {
  253. retval = stats1->Get_Texture_Bytes () - stats2->Get_Texture_Bytes ();
  254. }
  255. }
  256. //
  257. // Invert the sort if necessary
  258. //
  259. if (ascending != TRUE) {
  260. retval = -retval;
  261. }
  262. return retval;
  263. }