GeneratingManualVisDialog.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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. // GeneratingManualVisDialog.cpp : implementation file
  19. //
  20. #include "stdafx.h"
  21. #include "leveledit.h"
  22. #include "generatingmanualvisdialog.h"
  23. #include "utils.h"
  24. #include "leveleditview.h"
  25. #include "vismgr.h"
  26. #include "sceneeditor.h"
  27. #include "nodemgr.h"
  28. #include "vispointnode.h"
  29. #ifdef _DEBUG
  30. #define new DEBUG_NEW
  31. #undef THIS_FILE
  32. static char THIS_FILE[] = __FILE__;
  33. #endif
  34. /////////////////////////////////////////////////////////////////////////////
  35. //
  36. // GeneratingManualVisDialogClass
  37. //
  38. /////////////////////////////////////////////////////////////////////////////
  39. GeneratingManualVisDialogClass::GeneratingManualVisDialogClass(CWnd* pParent /*=NULL*/)
  40. : m_FarmMode (false),
  41. m_Stop (false),
  42. m_TotalPoints (0),
  43. m_TotalTime (0),
  44. m_CurrentPoint (0),
  45. m_StartTime (0),
  46. m_TotalProcessors (0),
  47. m_ProcessorIndex (0),
  48. CDialog(GeneratingManualVisDialogClass::IDD, pParent)
  49. {
  50. //{{AFX_DATA_INIT(GeneratingManualVisDialogClass)
  51. // NOTE: the ClassWizard will add member initialization here
  52. //}}AFX_DATA_INIT
  53. //
  54. // Determine the section of the status file
  55. //
  56. DWORD process_id = ::GetCurrentProcessId ();
  57. m_StatusSection.Format ("%d", process_id);
  58. //
  59. // Get the installation directory of this application
  60. //
  61. TCHAR exe_path[MAX_PATH] = { 0 };
  62. ::GetModuleFileName (::AfxGetInstanceHandle (), exe_path, sizeof (exe_path));
  63. CString path = ::Strip_Filename_From_Path (exe_path);
  64. if (path[::lstrlen(path)-1] != '\\') {
  65. path += "\\";
  66. }
  67. m_StatusFilename = path + "status.vis";
  68. ::WritePrivateProfileString ("Status", m_StatusSection, "Manual Vis Render", m_StatusFilename);
  69. return ;
  70. }
  71. /////////////////////////////////////////////////////////////////////////////
  72. //
  73. // DoDataExchange
  74. //
  75. /////////////////////////////////////////////////////////////////////////////
  76. void
  77. GeneratingManualVisDialogClass::DoDataExchange (CDataExchange *pDX)
  78. {
  79. CDialog::DoDataExchange(pDX);
  80. //{{AFX_DATA_MAP(GeneratingManualVisDialogClass)
  81. DDX_Control(pDX, IDC_PROGRESS_CTRL, m_ProgressCtrl);
  82. //}}AFX_DATA_MAP
  83. return ;
  84. }
  85. BEGIN_MESSAGE_MAP(GeneratingManualVisDialogClass, CDialog)
  86. //{{AFX_MSG_MAP(GeneratingManualVisDialogClass)
  87. //}}AFX_MSG_MAP
  88. END_MESSAGE_MAP()
  89. /////////////////////////////////////////////////////////////////////////////
  90. //
  91. // OnInitDialog
  92. //
  93. /////////////////////////////////////////////////////////////////////////////
  94. BOOL
  95. GeneratingManualVisDialogClass::OnInitDialog (void)
  96. {
  97. CDialog::OnInitDialog ();
  98. m_ProgressCtrl.SetRange (0, 100);
  99. m_ProgressCtrl.SetPos (0);
  100. ShowWindow (SW_SHOW);
  101. PostMessage (WM_USER + 101);
  102. return TRUE;
  103. }
  104. /////////////////////////////////////////////////////////////////////////////
  105. //
  106. // WindowProc
  107. //
  108. /////////////////////////////////////////////////////////////////////////////
  109. LRESULT
  110. GeneratingManualVisDialogClass::WindowProc
  111. (
  112. UINT message,
  113. WPARAM wParam,
  114. LPARAM lParam
  115. )
  116. {
  117. if (message == WM_USER + 101) {
  118. ::Get_Main_View ()->Allow_Repaint (false);
  119. //
  120. // Set-up the render statistics variables
  121. //
  122. m_TotalPoints = Get_Manual_Point_Count ();
  123. m_CurrentPoint = 0;
  124. m_StartTime = ::GetTickCount();
  125. //
  126. // Render the manual vis points
  127. //
  128. VisMgrClass::Render_Manual_Vis_Points (m_FarmMode, m_ProcessorIndex, m_TotalProcessors, ManualVisPointCallback, (DWORD)this);
  129. ::Get_Main_View ()->Allow_Repaint (true);
  130. EndDialog (IDOK);
  131. }
  132. return CDialog::WindowProc (message, wParam, lParam);
  133. }
  134. //////////////////////////////////////////////////////////////////////////////
  135. //
  136. // On_Manual_Vis_Point_Render
  137. //
  138. //////////////////////////////////////////////////////////////////////////////
  139. bool
  140. GeneratingManualVisDialogClass::On_Manual_Vis_Point_Render (DWORD milliseconds)
  141. {
  142. //
  143. // Update our stats
  144. //
  145. m_CurrentPoint ++;
  146. m_TotalTime += milliseconds;
  147. Update_Time ();
  148. //
  149. // Process window's messages once a second
  150. //
  151. static DWORD last_message_pump = 0;
  152. if (::GetTickCount () - last_message_pump > 1000) {
  153. General_Pump_Messages ();
  154. last_message_pump = ::GetTickCount ();
  155. //
  156. // Output our current status to the status file
  157. //
  158. if (m_FarmMode) {
  159. CString status;
  160. status.Format ("Manual Points: %d%%", int(((m_CurrentPoint + 1) * 100) / m_TotalPoints));
  161. ::WritePrivateProfileString ("Status", m_StatusSection, status, m_StatusFilename);
  162. }
  163. }
  164. return !m_Stop;
  165. }
  166. //////////////////////////////////////////////////////////////////////////////
  167. //
  168. // Get_Manual_Point_Count
  169. //
  170. //////////////////////////////////////////////////////////////////////////////
  171. int
  172. GeneratingManualVisDialogClass::Get_Manual_Point_Count (void)
  173. {
  174. int total = 0;
  175. //
  176. // Count up the total number of manual points in the level
  177. //
  178. VisPointNodeClass *vis_point = NULL;
  179. for ( vis_point = (VisPointNodeClass *)NodeMgrClass::Get_First (NODE_TYPE_VIS_POINT);
  180. vis_point != NULL && !m_Stop;
  181. vis_point = (VisPointNodeClass *)NodeMgrClass::Get_Next (vis_point, NODE_TYPE_VIS_POINT))
  182. {
  183. total ++;
  184. }
  185. return total;
  186. }
  187. //////////////////////////////////////////////////////////////////////////////
  188. //
  189. // ManualVisPointCallback
  190. //
  191. //////////////////////////////////////////////////////////////////////////////
  192. bool
  193. GeneratingManualVisDialogClass::ManualVisPointCallback (DWORD milliseconds, DWORD param)
  194. {
  195. bool retval = true;
  196. //
  197. // Hand this notification onto the dialog
  198. //
  199. if (param != 0) {
  200. retval = ((GeneratingManualVisDialogClass *)param)->On_Manual_Vis_Point_Render (milliseconds);
  201. }
  202. return retval;
  203. }
  204. //////////////////////////////////////////////////////////////////////////////
  205. //
  206. // Update_Time
  207. //
  208. //////////////////////////////////////////////////////////////////////////////
  209. void
  210. GeneratingManualVisDialogClass::Update_Time (void)
  211. {
  212. //
  213. // Compute the elapsed and estimated remaining time
  214. //
  215. DWORD cur_ticks = ::GetTickCount();
  216. DWORD elapsed_ticks;
  217. if (cur_ticks > m_StartTime) {
  218. elapsed_ticks = cur_ticks - m_StartTime;
  219. } else {
  220. elapsed_ticks = 0xFFFFFFFF - m_StartTime + cur_ticks;
  221. }
  222. DWORD avg_ticks = elapsed_ticks / m_CurrentPoint;
  223. DWORD remaining_ticks = (m_TotalPoints - m_CurrentPoint) * avg_ticks;
  224. float elapsed_minutes = (float)elapsed_ticks / 60000.0f;
  225. float remaining_minutes = (float)remaining_ticks / 60000.0f;
  226. //
  227. // Update the UI
  228. //
  229. CString status_text;
  230. status_text.Format ("Rendering %d of %d points.", m_CurrentPoint + 1, m_TotalPoints);
  231. SetDlgItemText (IDC_STATUS_TEXT, status_text);
  232. CString elapsed_time_text;
  233. elapsed_time_text.Format ("Elapsed: %.1f min. Remaining: %.1f min.",elapsed_minutes,remaining_minutes);
  234. SetDlgItemText (IDC_ELAPSED_TIME_TEXT, elapsed_time_text);
  235. m_ProgressCtrl.SetPos (((m_CurrentPoint + 1) * 100) / m_TotalPoints);
  236. General_Pump_Messages ();
  237. return ;
  238. }
  239. //////////////////////////////////////////////////////////////////////////////
  240. //
  241. // OnCancel
  242. //
  243. //////////////////////////////////////////////////////////////////////////////
  244. void
  245. GeneratingManualVisDialogClass::OnCancel (void)
  246. {
  247. m_Stop = true;
  248. ::EnableWindow (::GetDlgItem (m_hWnd, IDCANCEL), false);
  249. CDialog::OnCancel ();
  250. return ;
  251. }