GeneratingEdgeSampledVisDialog.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  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. /***********************************************************************************************
  19. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : LevelEdit *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/LevelEdit/GeneratingEdgeSampledVisDialog.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 8/02/00 8:14p $*
  29. * *
  30. * $Revision:: 5 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "stdafx.h"
  36. #include "leveledit.h"
  37. #include "generatingedgesampledvisdialog.h"
  38. #include "visgenprogress.h"
  39. #include "utils.h"
  40. #ifdef _DEBUG
  41. #define new DEBUG_NEW
  42. #undef THIS_FILE
  43. static char THIS_FILE[] = __FILE__;
  44. #endif
  45. /////////////////////////////////////////////////////////////////////////////
  46. // Constants
  47. /////////////////////////////////////////////////////////////////////////////
  48. static const float MILLISECONDS = 1000.0F;
  49. static const float SECONDS_PER_MINUTE = 60.0F;
  50. static const float TICKS_PER_MINUTE = SECONDS_PER_MINUTE * MILLISECONDS;
  51. static const float MINUTES_PER_TICK = 1.0f / TICKS_PER_MINUTE;
  52. //////////////////////////////////////////////////////////////////////////
  53. // Local Prototypes
  54. //////////////////////////////////////////////////////////////////////////
  55. static UINT fnGeneratingVisDialogThread (DWORD dwparam1, DWORD dwparam2, DWORD, HRESULT *, HWND *);
  56. /////////////////////////////////////////////////////////////////////////////
  57. //
  58. // GeneratingEdgeSampledVisDialogClass
  59. //
  60. /////////////////////////////////////////////////////////////////////////////
  61. GeneratingEdgeSampledVisDialogClass::GeneratingEdgeSampledVisDialogClass(CWnd* pParent /*=NULL*/)
  62. : m_IsCancelled (false),
  63. m_IsFinished (false),
  64. m_ProgressObj (NULL),
  65. m_StartTime (0),
  66. m_FarmMode (false),
  67. CDialog(GeneratingEdgeSampledVisDialogClass::IDD, pParent)
  68. {
  69. //{{AFX_DATA_INIT(GeneratingEdgeSampledVisDialogClass)
  70. // NOTE: the ClassWizard will add member initialization here
  71. //}}AFX_DATA_INIT
  72. Create (GeneratingEdgeSampledVisDialogClass::IDD, NULL);
  73. //
  74. // Determine the section of the status file
  75. //
  76. DWORD process_id = ::GetCurrentProcessId ();
  77. m_StatusSection.Format ("%d", process_id);
  78. //
  79. // Get the installation directory of this application
  80. //
  81. TCHAR exe_path[MAX_PATH] = { 0 };
  82. ::GetModuleFileName (::AfxGetInstanceHandle (), exe_path, sizeof (exe_path));
  83. CString path = ::Strip_Filename_From_Path (exe_path);
  84. if (path[::lstrlen(path)-1] != '\\') {
  85. path += "\\";
  86. }
  87. m_StatusFilename = path + "status.vis";
  88. ::WritePrivateProfileString ("Status", m_StatusSection, "", m_StatusFilename);
  89. return ;
  90. }
  91. /////////////////////////////////////////////////////////////////////////////
  92. //
  93. // DoDataExchange
  94. //
  95. /////////////////////////////////////////////////////////////////////////////
  96. void
  97. GeneratingEdgeSampledVisDialogClass::DoDataExchange (CDataExchange* pDX)
  98. {
  99. CDialog::DoDataExchange(pDX);
  100. //{{AFX_DATA_MAP(GeneratingEdgeSampledVisDialogClass)
  101. DDX_Control(pDX, IDC_PROGRESS_CTRL, m_ProgressCtrl);
  102. //}}AFX_DATA_MAP
  103. return ;
  104. }
  105. BEGIN_MESSAGE_MAP(GeneratingEdgeSampledVisDialogClass, CDialog)
  106. //{{AFX_MSG_MAP(GeneratingEdgeSampledVisDialogClass)
  107. ON_WM_TIMER()
  108. //}}AFX_MSG_MAP
  109. END_MESSAGE_MAP()
  110. /////////////////////////////////////////////////////////////////////////////
  111. //
  112. // DoDataExchange
  113. //
  114. /////////////////////////////////////////////////////////////////////////////
  115. BOOL
  116. GeneratingEdgeSampledVisDialogClass::OnInitDialog (void)
  117. {
  118. CDialog::OnInitDialog();
  119. //
  120. // Configure the progress control
  121. //
  122. m_ProgressCtrl.SetRange (0, 100);
  123. m_ProgressCtrl.SetPos (0);
  124. //
  125. // Start the timer
  126. //
  127. SetTimer (777, 1000, NULL);
  128. //
  129. // Record the time at operation start
  130. //
  131. m_StartTime = ::GetTickCount ();
  132. Update_Stats ();
  133. return TRUE;
  134. }
  135. /////////////////////////////////////////////////////////////////////////////
  136. //
  137. // OnTimer
  138. //
  139. /////////////////////////////////////////////////////////////////////////////
  140. void
  141. GeneratingEdgeSampledVisDialogClass::OnTimer (UINT nIDEvent)
  142. {
  143. //
  144. // Refresh the dialog
  145. //
  146. if (nIDEvent == 777) {
  147. Update_Stats ();
  148. }
  149. CDialog::OnTimer (nIDEvent);
  150. return ;
  151. }
  152. /////////////////////////////////////////////////////////////////////////////
  153. //
  154. // OnCancel
  155. //
  156. /////////////////////////////////////////////////////////////////////////////
  157. void
  158. GeneratingEdgeSampledVisDialogClass::OnCancel (void)
  159. {
  160. m_IsCancelled = true;
  161. //
  162. // Stop the vis generation process
  163. //
  164. if (m_ProgressObj != NULL) {
  165. m_ProgressObj->Request_Cancel ();
  166. Update_Stats ();
  167. }
  168. //
  169. // Gray out the cancel button for some feedback to the user
  170. //
  171. ::EnableWindow (::GetDlgItem (m_hWnd, IDCANCEL), false);
  172. return ;
  173. }
  174. /////////////////////////////////////////////////////////////////////////////
  175. //
  176. // Update_Stats
  177. //
  178. /////////////////////////////////////////////////////////////////////////////
  179. void
  180. GeneratingEdgeSampledVisDialogClass::Update_Stats (void)
  181. {
  182. if (m_ProgressObj != NULL) {
  183. //
  184. // Update the simple text controls
  185. //
  186. SetDlgItemInt (IDC_TOTAL_EDGE_COUNT, m_ProgressObj->Get_Total_Edge_Count ());
  187. SetDlgItemInt (IDC_TOTAL_SAMPLE_COUNT, m_ProgressObj->Get_Total_Sample_Count ());
  188. SetDlgItemInt (IDC_AVG_SAMPLES_PER_NODE, m_ProgressObj->Get_Average_Samples_Per_Node ());
  189. SetDlgItemInt (IDC_EDGE_COUNT, m_ProgressObj->Get_Current_Node_Edge_Count ());
  190. SetDlgItemInt (IDC_SAMPLE_COUNT, m_ProgressObj->Get_Current_Node_Sample_Count ());
  191. //
  192. // Update the progress bar
  193. //
  194. int processed = m_ProgressObj->Get_Processed_Node_Count ();
  195. int total = m_ProgressObj->Get_Node_Count ();
  196. float percent = static_cast<float>(processed) / static_cast<float>(total);
  197. m_ProgressCtrl.SetPos (percent * 100);
  198. //
  199. // Update the status text
  200. //
  201. if (m_IsCancelled == false) {
  202. //
  203. // Make a rough estimate of the time we have remaining
  204. //
  205. DWORD elapsed_ticks = ::GetTickCount () - m_StartTime;
  206. DWORD avg_ticks = elapsed_ticks / max(processed,1);
  207. DWORD remaining_ticks = avg_ticks * (total - processed);
  208. float elapsed_minutes = MINUTES_PER_TICK * (float)elapsed_ticks;
  209. float remaining_minutes = MINUTES_PER_TICK * (float)remaining_ticks;
  210. CString status_text;
  211. status_text.Format ("Nodes processed %d of %d.",processed,total);
  212. SetDlgItemText (IDC_STATUS_TEXT, status_text);
  213. CString elapsed_text;
  214. elapsed_text.Format ("Elapsed: %.1f min Remaining: %.1f min.",elapsed_minutes, remaining_minutes);
  215. SetDlgItemText (IDC_ELAPSED_TIME_TEXT, elapsed_text);
  216. } else {
  217. CString status_text;
  218. status_text.Format ("Nodes processed %d of %d.",processed,total);
  219. SetDlgItemText (IDC_STATUS_TEXT, status_text);
  220. SetDlgItemText (IDC_ELAPSED_TIME_TEXT,"Cancelled!");
  221. }
  222. //
  223. // Output our current status to the status file
  224. //
  225. if (m_FarmMode) {
  226. CString status;
  227. status.Format ("Sector Vis: %d%%", int(percent * 100));
  228. ::WritePrivateProfileString ("Status", m_StatusSection, status, m_StatusFilename);
  229. }
  230. }
  231. return ;
  232. }
  233. /////////////////////////////////////////////////////////////////////////////
  234. //
  235. // Set_Progress_Obj
  236. //
  237. /////////////////////////////////////////////////////////////////////////////
  238. void
  239. GeneratingEdgeSampledVisDialogClass::Set_Progress_Obj (VisGenProgressClass *obj)
  240. {
  241. m_ProgressObj = obj;
  242. return ;
  243. }
  244. /////////////////////////////////////////////////////////////////////////////
  245. //
  246. // Display
  247. //
  248. /////////////////////////////////////////////////////////////////////////////
  249. GeneratingEdgeSampledVisDialogClass *
  250. GeneratingEdgeSampledVisDialogClass::Display (void)
  251. {
  252. //
  253. // Create the dialog on a separate thread
  254. //
  255. GeneratingEdgeSampledVisDialogClass *dialog = NULL;
  256. ::Create_UI_Thread (fnGeneratingVisDialogThread, 0, (DWORD)&dialog, 0, NULL, NULL);
  257. return dialog;
  258. }
  259. /////////////////////////////////////////////////////////////////////////////
  260. //
  261. // End_Dialog
  262. //
  263. /////////////////////////////////////////////////////////////////////////////
  264. void
  265. GeneratingEdgeSampledVisDialogClass::End_Dialog (void)
  266. {
  267. ::DestroyWindow (m_hWnd);
  268. ::PostQuitMessage (0);
  269. return ;
  270. }
  271. /////////////////////////////////////////////////////////////////////////////
  272. //
  273. // Set_Finished
  274. //
  275. /////////////////////////////////////////////////////////////////////////////
  276. void
  277. GeneratingEdgeSampledVisDialogClass::Set_Finished (bool is_finished)
  278. {
  279. m_IsFinished = is_finished;
  280. End_Dialog();
  281. return ;
  282. }
  283. /////////////////////////////////////////////////////////////////////////////
  284. //
  285. // fnGeneratingVisDialogThread
  286. //
  287. ////////////////////////////////////////////////////////////////////////////
  288. UINT
  289. fnGeneratingVisDialogThread
  290. (
  291. DWORD dwparam1,
  292. DWORD dwparam2,
  293. DWORD /*dwparam3*/,
  294. HRESULT* /*presult*/,
  295. HWND* /*phmain_wnd*/
  296. )
  297. {
  298. GeneratingEdgeSampledVisDialogClass *dialog = new GeneratingEdgeSampledVisDialogClass ();
  299. dialog->ShowWindow (SW_SHOW);
  300. //
  301. // Return the dialog object to the caller
  302. //
  303. GeneratingEdgeSampledVisDialogClass **return_val = (GeneratingEdgeSampledVisDialogClass **)dwparam2;
  304. if (return_val != NULL) {
  305. (*return_val) = dialog;
  306. }
  307. return 1;
  308. }