/* ** 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 . */ // GeneratingManualVisDialog.cpp : implementation file // #include "stdafx.h" #include "leveledit.h" #include "generatingmanualvisdialog.h" #include "utils.h" #include "leveleditview.h" #include "vismgr.h" #include "sceneeditor.h" #include "nodemgr.h" #include "vispointnode.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // // GeneratingManualVisDialogClass // ///////////////////////////////////////////////////////////////////////////// GeneratingManualVisDialogClass::GeneratingManualVisDialogClass(CWnd* pParent /*=NULL*/) : m_FarmMode (false), m_Stop (false), m_TotalPoints (0), m_TotalTime (0), m_CurrentPoint (0), m_StartTime (0), m_TotalProcessors (0), m_ProcessorIndex (0), CDialog(GeneratingManualVisDialogClass::IDD, pParent) { //{{AFX_DATA_INIT(GeneratingManualVisDialogClass) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // // 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, "Manual Vis Render", m_StatusFilename); return ; } ///////////////////////////////////////////////////////////////////////////// // // DoDataExchange // ///////////////////////////////////////////////////////////////////////////// void GeneratingManualVisDialogClass::DoDataExchange (CDataExchange *pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(GeneratingManualVisDialogClass) DDX_Control(pDX, IDC_PROGRESS_CTRL, m_ProgressCtrl); //}}AFX_DATA_MAP return ; } BEGIN_MESSAGE_MAP(GeneratingManualVisDialogClass, CDialog) //{{AFX_MSG_MAP(GeneratingManualVisDialogClass) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // // OnInitDialog // ///////////////////////////////////////////////////////////////////////////// BOOL GeneratingManualVisDialogClass::OnInitDialog (void) { CDialog::OnInitDialog (); m_ProgressCtrl.SetRange (0, 100); m_ProgressCtrl.SetPos (0); ShowWindow (SW_SHOW); PostMessage (WM_USER + 101); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // // WindowProc // ///////////////////////////////////////////////////////////////////////////// LRESULT GeneratingManualVisDialogClass::WindowProc ( UINT message, WPARAM wParam, LPARAM lParam ) { if (message == WM_USER + 101) { ::Get_Main_View ()->Allow_Repaint (false); // // Set-up the render statistics variables // m_TotalPoints = Get_Manual_Point_Count (); m_CurrentPoint = 0; m_StartTime = ::GetTickCount(); // // Render the manual vis points // VisMgrClass::Render_Manual_Vis_Points (m_FarmMode, m_ProcessorIndex, m_TotalProcessors, ManualVisPointCallback, (DWORD)this); ::Get_Main_View ()->Allow_Repaint (true); EndDialog (IDOK); } return CDialog::WindowProc (message, wParam, lParam); } ////////////////////////////////////////////////////////////////////////////// // // On_Manual_Vis_Point_Render // ////////////////////////////////////////////////////////////////////////////// bool GeneratingManualVisDialogClass::On_Manual_Vis_Point_Render (DWORD milliseconds) { // // Update our stats // m_CurrentPoint ++; m_TotalTime += milliseconds; Update_Time (); // // Process window's messages once a second // static DWORD last_message_pump = 0; if (::GetTickCount () - last_message_pump > 1000) { General_Pump_Messages (); last_message_pump = ::GetTickCount (); // // Output our current status to the status file // if (m_FarmMode) { CString status; status.Format ("Manual Points: %d%%", int(((m_CurrentPoint + 1) * 100) / m_TotalPoints)); ::WritePrivateProfileString ("Status", m_StatusSection, status, m_StatusFilename); } } return !m_Stop; } ////////////////////////////////////////////////////////////////////////////// // // Get_Manual_Point_Count // ////////////////////////////////////////////////////////////////////////////// int GeneratingManualVisDialogClass::Get_Manual_Point_Count (void) { int total = 0; // // Count up the total number of manual points in the level // VisPointNodeClass *vis_point = NULL; for ( vis_point = (VisPointNodeClass *)NodeMgrClass::Get_First (NODE_TYPE_VIS_POINT); vis_point != NULL && !m_Stop; vis_point = (VisPointNodeClass *)NodeMgrClass::Get_Next (vis_point, NODE_TYPE_VIS_POINT)) { total ++; } return total; } ////////////////////////////////////////////////////////////////////////////// // // ManualVisPointCallback // ////////////////////////////////////////////////////////////////////////////// bool GeneratingManualVisDialogClass::ManualVisPointCallback (DWORD milliseconds, DWORD param) { bool retval = true; // // Hand this notification onto the dialog // if (param != 0) { retval = ((GeneratingManualVisDialogClass *)param)->On_Manual_Vis_Point_Render (milliseconds); } return retval; } ////////////////////////////////////////////////////////////////////////////// // // Update_Time // ////////////////////////////////////////////////////////////////////////////// void GeneratingManualVisDialogClass::Update_Time (void) { // // Compute the elapsed and estimated remaining time // DWORD cur_ticks = ::GetTickCount(); DWORD elapsed_ticks; if (cur_ticks > m_StartTime) { elapsed_ticks = cur_ticks - m_StartTime; } else { elapsed_ticks = 0xFFFFFFFF - m_StartTime + cur_ticks; } DWORD avg_ticks = elapsed_ticks / m_CurrentPoint; DWORD remaining_ticks = (m_TotalPoints - m_CurrentPoint) * avg_ticks; float elapsed_minutes = (float)elapsed_ticks / 60000.0f; float remaining_minutes = (float)remaining_ticks / 60000.0f; // // Update the UI // CString status_text; status_text.Format ("Rendering %d of %d points.", m_CurrentPoint + 1, m_TotalPoints); SetDlgItemText (IDC_STATUS_TEXT, status_text); CString elapsed_time_text; elapsed_time_text.Format ("Elapsed: %.1f min. Remaining: %.1f min.",elapsed_minutes,remaining_minutes); SetDlgItemText (IDC_ELAPSED_TIME_TEXT, elapsed_time_text); m_ProgressCtrl.SetPos (((m_CurrentPoint + 1) * 100) / m_TotalPoints); General_Pump_Messages (); return ; } ////////////////////////////////////////////////////////////////////////////// // // OnCancel // ////////////////////////////////////////////////////////////////////////////// void GeneratingManualVisDialogClass::OnCancel (void) { m_Stop = true; ::EnableWindow (::GetDlgItem (m_hWnd, IDCANCEL), false); CDialog::OnCancel (); return ; }