/* ** 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 . */ /*********************************************************************************************** *** 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 *** *********************************************************************************************** * * * Project Name : LevelEdit * * * * $Archive:: /Commando/Code/Tools/LevelEdit/GeneratingEdgeSampledVisDialog.cpp $* * * * Author:: Patrick Smith * * * * $Modtime:: 8/02/00 8:14p $* * * * $Revision:: 5 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "stdafx.h" #include "leveledit.h" #include "generatingedgesampledvisdialog.h" #include "visgenprogress.h" #include "utils.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // Constants ///////////////////////////////////////////////////////////////////////////// static const float MILLISECONDS = 1000.0F; static const float SECONDS_PER_MINUTE = 60.0F; static const float TICKS_PER_MINUTE = SECONDS_PER_MINUTE * MILLISECONDS; static const float MINUTES_PER_TICK = 1.0f / TICKS_PER_MINUTE; ////////////////////////////////////////////////////////////////////////// // Local Prototypes ////////////////////////////////////////////////////////////////////////// static UINT fnGeneratingVisDialogThread (DWORD dwparam1, DWORD dwparam2, DWORD, HRESULT *, HWND *); ///////////////////////////////////////////////////////////////////////////// // // GeneratingEdgeSampledVisDialogClass // ///////////////////////////////////////////////////////////////////////////// GeneratingEdgeSampledVisDialogClass::GeneratingEdgeSampledVisDialogClass(CWnd* pParent /*=NULL*/) : m_IsCancelled (false), m_IsFinished (false), m_ProgressObj (NULL), m_StartTime (0), m_FarmMode (false), CDialog(GeneratingEdgeSampledVisDialogClass::IDD, pParent) { //{{AFX_DATA_INIT(GeneratingEdgeSampledVisDialogClass) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT Create (GeneratingEdgeSampledVisDialogClass::IDD, NULL); // // Determine the section of the status file // DWORD process_id = ::GetCurrentProcessId (); m_StatusSection.Format ("%d", process_id); // // Get the installation directory of this application // TCHAR exe_path[MAX_PATH] = { 0 }; ::GetModuleFileName (::AfxGetInstanceHandle (), exe_path, sizeof (exe_path)); CString path = ::Strip_Filename_From_Path (exe_path); if (path[::lstrlen(path)-1] != '\\') { path += "\\"; } m_StatusFilename = path + "status.vis"; ::WritePrivateProfileString ("Status", m_StatusSection, "", m_StatusFilename); return ; } ///////////////////////////////////////////////////////////////////////////// // // DoDataExchange // ///////////////////////////////////////////////////////////////////////////// void GeneratingEdgeSampledVisDialogClass::DoDataExchange (CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(GeneratingEdgeSampledVisDialogClass) DDX_Control(pDX, IDC_PROGRESS_CTRL, m_ProgressCtrl); //}}AFX_DATA_MAP return ; } BEGIN_MESSAGE_MAP(GeneratingEdgeSampledVisDialogClass, CDialog) //{{AFX_MSG_MAP(GeneratingEdgeSampledVisDialogClass) ON_WM_TIMER() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // // DoDataExchange // ///////////////////////////////////////////////////////////////////////////// BOOL GeneratingEdgeSampledVisDialogClass::OnInitDialog (void) { CDialog::OnInitDialog(); // // Configure the progress control // m_ProgressCtrl.SetRange (0, 100); m_ProgressCtrl.SetPos (0); // // Start the timer // SetTimer (777, 1000, NULL); // // Record the time at operation start // m_StartTime = ::GetTickCount (); Update_Stats (); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // // OnTimer // ///////////////////////////////////////////////////////////////////////////// void GeneratingEdgeSampledVisDialogClass::OnTimer (UINT nIDEvent) { // // Refresh the dialog // if (nIDEvent == 777) { Update_Stats (); } CDialog::OnTimer (nIDEvent); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnCancel // ///////////////////////////////////////////////////////////////////////////// void GeneratingEdgeSampledVisDialogClass::OnCancel (void) { m_IsCancelled = true; // // Stop the vis generation process // if (m_ProgressObj != NULL) { m_ProgressObj->Request_Cancel (); Update_Stats (); } // // Gray out the cancel button for some feedback to the user // ::EnableWindow (::GetDlgItem (m_hWnd, IDCANCEL), false); return ; } ///////////////////////////////////////////////////////////////////////////// // // Update_Stats // ///////////////////////////////////////////////////////////////////////////// void GeneratingEdgeSampledVisDialogClass::Update_Stats (void) { if (m_ProgressObj != NULL) { // // Update the simple text controls // SetDlgItemInt (IDC_TOTAL_EDGE_COUNT, m_ProgressObj->Get_Total_Edge_Count ()); SetDlgItemInt (IDC_TOTAL_SAMPLE_COUNT, m_ProgressObj->Get_Total_Sample_Count ()); SetDlgItemInt (IDC_AVG_SAMPLES_PER_NODE, m_ProgressObj->Get_Average_Samples_Per_Node ()); SetDlgItemInt (IDC_EDGE_COUNT, m_ProgressObj->Get_Current_Node_Edge_Count ()); SetDlgItemInt (IDC_SAMPLE_COUNT, m_ProgressObj->Get_Current_Node_Sample_Count ()); // // Update the progress bar // int processed = m_ProgressObj->Get_Processed_Node_Count (); int total = m_ProgressObj->Get_Node_Count (); float percent = static_cast(processed) / static_cast(total); m_ProgressCtrl.SetPos (percent * 100); // // Update the status text // if (m_IsCancelled == false) { // // Make a rough estimate of the time we have remaining // DWORD elapsed_ticks = ::GetTickCount () - m_StartTime; DWORD avg_ticks = elapsed_ticks / max(processed,1); DWORD remaining_ticks = avg_ticks * (total - processed); float elapsed_minutes = MINUTES_PER_TICK * (float)elapsed_ticks; float remaining_minutes = MINUTES_PER_TICK * (float)remaining_ticks; CString status_text; status_text.Format ("Nodes processed %d of %d.",processed,total); SetDlgItemText (IDC_STATUS_TEXT, status_text); CString elapsed_text; elapsed_text.Format ("Elapsed: %.1f min Remaining: %.1f min.",elapsed_minutes, remaining_minutes); SetDlgItemText (IDC_ELAPSED_TIME_TEXT, elapsed_text); } else { CString status_text; status_text.Format ("Nodes processed %d of %d.",processed,total); SetDlgItemText (IDC_STATUS_TEXT, status_text); SetDlgItemText (IDC_ELAPSED_TIME_TEXT,"Cancelled!"); } // // Output our current status to the status file // if (m_FarmMode) { CString status; status.Format ("Sector Vis: %d%%", int(percent * 100)); ::WritePrivateProfileString ("Status", m_StatusSection, status, m_StatusFilename); } } return ; } ///////////////////////////////////////////////////////////////////////////// // // Set_Progress_Obj // ///////////////////////////////////////////////////////////////////////////// void GeneratingEdgeSampledVisDialogClass::Set_Progress_Obj (VisGenProgressClass *obj) { m_ProgressObj = obj; return ; } ///////////////////////////////////////////////////////////////////////////// // // Display // ///////////////////////////////////////////////////////////////////////////// GeneratingEdgeSampledVisDialogClass * GeneratingEdgeSampledVisDialogClass::Display (void) { // // Create the dialog on a separate thread // GeneratingEdgeSampledVisDialogClass *dialog = NULL; ::Create_UI_Thread (fnGeneratingVisDialogThread, 0, (DWORD)&dialog, 0, NULL, NULL); return dialog; } ///////////////////////////////////////////////////////////////////////////// // // End_Dialog // ///////////////////////////////////////////////////////////////////////////// void GeneratingEdgeSampledVisDialogClass::End_Dialog (void) { ::DestroyWindow (m_hWnd); ::PostQuitMessage (0); return ; } ///////////////////////////////////////////////////////////////////////////// // // Set_Finished // ///////////////////////////////////////////////////////////////////////////// void GeneratingEdgeSampledVisDialogClass::Set_Finished (bool is_finished) { m_IsFinished = is_finished; End_Dialog(); return ; } ///////////////////////////////////////////////////////////////////////////// // // fnGeneratingVisDialogThread // //////////////////////////////////////////////////////////////////////////// UINT fnGeneratingVisDialogThread ( DWORD dwparam1, DWORD dwparam2, DWORD /*dwparam3*/, HRESULT* /*presult*/, HWND* /*phmain_wnd*/ ) { GeneratingEdgeSampledVisDialogClass *dialog = new GeneratingEdgeSampledVisDialogClass (); dialog->ShowWindow (SW_SHOW); // // Return the dialog object to the caller // GeneratingEdgeSampledVisDialogClass **return_val = (GeneratingEdgeSampledVisDialogClass **)dwparam2; if (return_val != NULL) { (*return_val) = dialog; } return 1; }