GeneratingLightVisDialog.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. // GeneratingLightVisDialog.cpp : implementation file
  19. //
  20. #include "stdafx.h"
  21. #include "leveledit.h"
  22. #include "GeneratingLightVisDialog.h"
  23. #include "Utils.h"
  24. #include "SceneEditor.h"
  25. #include "LevelEditView.h"
  26. #include "rendobj.h"
  27. #include "phys.h"
  28. #ifdef _DEBUG
  29. #define new DEBUG_NEW
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #endif
  33. //////////////////////////////////////////////////////////////////////////////
  34. //
  35. // GeneratingLightVisDialogClass dialog
  36. //
  37. //////////////////////////////////////////////////////////////////////////////
  38. GeneratingLightVisDialogClass::GeneratingLightVisDialogClass(CWnd* pParent /*=NULL*/) :
  39. CDialog(GeneratingLightVisDialogClass::IDD, pParent),
  40. m_IsCancelled(false),
  41. m_StartTicks(0),
  42. m_CurrentLight(0),
  43. m_FirstLight(0),
  44. m_LastLight(0),
  45. m_FarmMode(false),
  46. m_TotalProcessors(1),
  47. m_ProcessorIndex(0)
  48. {
  49. //{{AFX_DATA_INIT(GeneratingLightVisDialogClass)
  50. // NOTE: the ClassWizard will add member initialization here
  51. //}}AFX_DATA_INIT
  52. //
  53. // Determine the section of the status file
  54. //
  55. DWORD process_id = ::GetCurrentProcessId ();
  56. m_StatusSection.Format ("%d", process_id);
  57. //
  58. // Get the installation directory of this application
  59. //
  60. TCHAR exe_path[MAX_PATH] = { 0 };
  61. ::GetModuleFileName (::AfxGetInstanceHandle (), exe_path, sizeof (exe_path));
  62. CString path = ::Strip_Filename_From_Path (exe_path);
  63. if (path[::lstrlen(path)-1] != '\\') {
  64. path += "\\";
  65. }
  66. m_StatusFilename = path + "status.vis";
  67. ::WritePrivateProfileString ("Status", m_StatusSection, "", m_StatusFilename);
  68. return ;
  69. }
  70. //////////////////////////////////////////////////////////////////////////////
  71. //
  72. // DoDataExchange
  73. //
  74. //////////////////////////////////////////////////////////////////////////////
  75. void
  76. GeneratingLightVisDialogClass::DoDataExchange(CDataExchange* pDX)
  77. {
  78. CDialog::DoDataExchange(pDX);
  79. //{{AFX_DATA_MAP(GeneratingLightVisDialogClass)
  80. DDX_Control(pDX, IDC_PROGRESS_CTRL, m_ProgressCtrl);
  81. //}}AFX_DATA_MAP
  82. }
  83. BEGIN_MESSAGE_MAP(GeneratingLightVisDialogClass, CDialog)
  84. //{{AFX_MSG_MAP(GeneratingLightVisDialogClass)
  85. //}}AFX_MSG_MAP
  86. END_MESSAGE_MAP()
  87. //////////////////////////////////////////////////////////////////////////////
  88. //
  89. // OnInitDialog
  90. //
  91. //////////////////////////////////////////////////////////////////////////////
  92. BOOL
  93. GeneratingLightVisDialogClass::OnInitDialog()
  94. {
  95. CDialog::OnInitDialog();
  96. m_ProgressCtrl.SetRange (0, 100);
  97. m_ProgressCtrl.SetPos (0);
  98. ShowWindow (SW_SHOW);
  99. PostMessage (WM_USER+101);
  100. return TRUE;
  101. }
  102. //////////////////////////////////////////////////////////////////////////////
  103. //
  104. // OnCancel
  105. //
  106. //////////////////////////////////////////////////////////////////////////////
  107. void
  108. GeneratingLightVisDialogClass::OnCancel()
  109. {
  110. m_IsCancelled = true;
  111. }
  112. //////////////////////////////////////////////////////////////////////////////
  113. //
  114. // WindowProc
  115. //
  116. //////////////////////////////////////////////////////////////////////////////
  117. LRESULT
  118. GeneratingLightVisDialogClass::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  119. {
  120. if (message == WM_USER+101) {
  121. ::Get_Main_View ()->Allow_Repaint (false);
  122. SceneEditorClass *scene_editor = ::Get_Scene_Editor ();
  123. m_StartTicks = ::GetTickCount ();
  124. /*
  125. ** Generate the start and end index for the lights we're going to vis
  126. */
  127. int light_count = scene_editor->Get_Static_Light_Count();
  128. float lights_per_processor = (float)light_count / (float)m_TotalProcessors;
  129. m_FirstLight = (int)::floor (lights_per_processor * (float)m_ProcessorIndex);
  130. m_LastLight = (int)::ceil (lights_per_processor * (float)(m_ProcessorIndex+1));
  131. m_LastLight = min (light_count, m_LastLight);
  132. /*
  133. ** Prepare to do the actual vis sampling
  134. */
  135. bool restore_vis_point_display = scene_editor->Are_Vis_Points_Displayed ();
  136. scene_editor->Display_Vis_Points (false);
  137. /*
  138. ** Perform a vis sample for each light, updating the UI after each one
  139. */
  140. for (int i=m_FirstLight; (i<m_LastLight) && (m_IsCancelled == false); i++) {
  141. scene_editor->Generate_Vis_For_Light(i);
  142. Update_Status(i);
  143. General_Pump_Messages();
  144. }
  145. /*
  146. ** Restore the scene settings and close this dialog.
  147. */
  148. if (restore_vis_point_display) {
  149. scene_editor->Display_Vis_Points (true);
  150. }
  151. ::Get_Main_View ()->Allow_Repaint (true);
  152. EndDialog (TRUE);
  153. }
  154. return CDialog::WindowProc(message, wParam, lParam);
  155. }
  156. //////////////////////////////////////////////////////////////////////////////
  157. //
  158. // Update_Status
  159. //
  160. //////////////////////////////////////////////////////////////////////////////
  161. void
  162. GeneratingLightVisDialogClass::Update_Status (int cur_light)
  163. {
  164. int light_index = (cur_light - m_FirstLight) + 1;
  165. int light_count = (m_LastLight - m_FirstLight);
  166. //
  167. // Update the light counters
  168. //
  169. CString status_text;
  170. status_text.Format ("Rendering %d of %d points.",light_index,light_count);
  171. SetDlgItemText (IDC_STATUS_TEXT, status_text);
  172. //
  173. // Update the elapsed and estimated remaining time
  174. //
  175. DWORD cur_ticks = ::GetTickCount();
  176. DWORD elapsed_ticks;
  177. if (cur_ticks > m_StartTicks) {
  178. elapsed_ticks = cur_ticks - m_StartTicks;
  179. } else {
  180. elapsed_ticks = 0xFFFFFFFF - m_StartTicks + cur_ticks;
  181. }
  182. DWORD avg_ticks = elapsed_ticks / light_index;
  183. DWORD remaining_ticks = (m_LastLight - cur_light) * avg_ticks;
  184. float elapsed_minutes = (float)elapsed_ticks / 60000.0f;
  185. float remaining_minutes = (float)remaining_ticks / 60000.0f;
  186. CString elapsed_time_text;
  187. elapsed_time_text.Format ("Elapsed: %.1f min. Remaining: %.1f min.",elapsed_minutes,remaining_minutes);
  188. SetDlgItemText (IDC_ELAPSED_TIME_TEXT, elapsed_time_text);
  189. m_ProgressCtrl.SetPos ((light_index * 100) / light_count);
  190. //
  191. // If in farm mode, output our current status to the status file
  192. //
  193. if (m_FarmMode) {
  194. CString status;
  195. status.Format ("Lights: %d%%", int((light_index * 100) / light_count));
  196. ::WritePrivateProfileString ("Status", m_StatusSection, status, m_StatusFilename);
  197. }
  198. return;
  199. }