/* ** 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 : commando * * * * $Archive:: /Commando/Code/Commando/radiocommanddisplay.cpp $* * * * Author:: Patrick Smith * * * * $Modtime:: 3/15/02 3:26p $* * * * $Revision:: 5 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "radiocommanddisplay.h" #include "assetmgr.h" #include "texture.h" #include "font3d.h" #include "objectives.h" #include "translatedb.h" #include "wwaudio.h" #include "globalsettings.h" #include "scene.h" #include "evasettings.h" #include "cncmodesettings.h" #include "string_ids.h" #include "rendobj.h" #include "input.h" #include "dinput.h" #include "timemgr.h" #include "gametype.h" #include "combat.h" #include "vehicle.h" #include "soldier.h" //////////////////////////////////////////////////////////////// // Static member initialization //////////////////////////////////////////////////////////////// float RadioCommandDisplayClass::DisplayTimer = 0.0F; bool RadioCommandDisplayClass::IsDisplayed = false; TextWindowClass * RadioCommandDisplayClass::TextWindow = NULL; //////////////////////////////////////////////////////////////// // // Shutdown // //////////////////////////////////////////////////////////////// void RadioCommandDisplayClass::Shutdown (void) { if (TextWindow != NULL) { delete TextWindow; TextWindow = NULL; } IsDisplayed = false; DisplayTimer = 0.0F; return ; } //////////////////////////////////////////////////////////////// // // Initialize // //////////////////////////////////////////////////////////////// void RadioCommandDisplayClass::Initialize (void) { // // Start fresh // if (TextWindow != NULL) { delete TextWindow; TextWindow = NULL; } // // Allocate the new text window // TextWindow = new TextWindowClass; // // Use the same dimensions as the mission objectives in single player // EvaSettingsDefClass *settings = EvaSettingsDefClass::Get_Instance (); // // Local constants // const char *BACKDROP_TGA = "hud_6x4_Messages.tga"; // // Configure the backdrop for the text window // TextWindow->Set_Backdrop (BACKDROP_TGA, settings->Get_Objectives_Screen_Rect (), settings->Get_Objectives_Texture_Size (), settings->Get_Objectives_Endcap_Rect (), settings->Get_Objectives_Fadeout_Rect (), settings->Get_Objectives_Background_Rect ()); // // Configure the area where text can be displayed in the window // TextWindow->Set_Text_Area (settings->Get_Objectives_Text_Rect ()); // // Configure the columns // TextWindow->Add_Column (TRANSLATE (IDS_MENU_RADIO_KEY), 0.3F, Vector3 (0.75F, 1.0F, 0.75F)); TextWindow->Add_Column (TRANSLATE (IDS_MENU_RADIO_KEY_MESSAGE), 0.7F, Vector3 (0.75F, 1.0F, 0.75F)); TextWindow->Display_Columns (true); DisplayTimer = 0.0F; return ; } //////////////////////////////////////////////////////////////// // // Update // //////////////////////////////////////////////////////////////// void RadioCommandDisplayClass::Update (DISPLAY_TYPE type) { CNCModeSettingsDef *cnc_def = CNCModeSettingsDef::Get_Instance (); if (TextWindow == NULL || cnc_def == NULL) { return ; } // // Start fresh // TextWindow->Delete_All_Items (); // // Local constants // const int COMMAND_COUNT = 10; // // Determine what the access key to display these radio commands is. // int range_start_index = 0; WideStringClass access_key; if (type == DISPLAY_CMDS_01) { access_key = TRANSLATE (IDS_MENU_TEXT892); } else if (type == DISPLAY_CMDS_02) { access_key = TRANSLATE (IDS_MENU_TEXT893); range_start_index = 10; } else { access_key.Format (L"%s + %s", TRANSLATE (IDS_MENU_TEXT892), TRANSLATE (IDS_MENU_TEXT893)); range_start_index = 20; } // // Add all the radio commands to the text window // for (int index = 0; index < COMMAND_COUNT; index ++){ int key_id = index + 1; if (key_id >= 10) { key_id -= 10; } WideStringClass command_key (0, true); command_key.Format (L"%s + %d", access_key, key_id); // // Insert an item for this radio command // int item_index = TextWindow->Insert_Item (index, command_key); if (item_index >= 0) { // // Lookup the message that this command displays // int cmd_index = range_start_index + index; int text_id = cnc_def->Get_Radio_Command (cmd_index); // // Display the message // TextWindow->Set_Item_Text (item_index, 1, TRANSLATE (text_id)); } } return ; } //////////////////////////////////////////////////////////////// // // Display // //////////////////////////////////////////////////////////////// void RadioCommandDisplayClass::Display (bool onoff, DISPLAY_TYPE type) { // // Display or hide the window // IsDisplayed = onoff; TextWindow->Display (onoff); // // Update the data in the window as necessary // if (onoff) { Update (type); } // // Play the 'EVA displayed' sound effect // if (IsDisplayed) { int sound_id = GlobalSettingsDef::Get_Global_Settings ()->Get_EVA_Objectives_Sound_ID (); if (sound_id != 0) { WWAudioClass::Get_Instance ()->Create_Instant_Sound (sound_id, Matrix3D (1)); } } return ; } //////////////////////////////////////////////////////////////// // // Render // //////////////////////////////////////////////////////////////// void RadioCommandDisplayClass::Render (void) { // // Don't do this for true single player // if (IS_MISSION) { return ; } Check_Keys (); // // Only render if the window is being displayed // if (IsDisplayed) { TextWindow->Render (); } return ; } //////////////////////////////////////////////////////////////// // // Check_Keys // //////////////////////////////////////////////////////////////// void RadioCommandDisplayClass::Check_Keys (void) { // // Local constants // const float TIMER_DURATION = 2.0F; // ignore left control if star is in a flying vehicle bool ignore_lctrl = ( COMBAT_STAR && COMBAT_STAR->As_SoldierGameObj() && COMBAT_STAR->As_SoldierGameObj()->Get_Vehicle() && COMBAT_STAR->As_SoldierGameObj()->Get_Vehicle()->Is_Aircraft() ); // // Determine which keys (if any) are down // bool is_key_down[DISPLAY_MAX] = { 0 }; if ( ignore_lctrl ) { is_key_down[DISPLAY_CMDS_01] = Input::Is_Button_Down (DIK_RCONTROL); is_key_down[DISPLAY_CMDS_02] = Input::Is_Button_Down (DIK_RMENU); } else { is_key_down[DISPLAY_CMDS_01] = Input::Is_Button_Down (DIK_LCONTROL) || Input::Is_Button_Down (DIK_RCONTROL); is_key_down[DISPLAY_CMDS_02] = Input::Is_Button_Down (DIK_LMENU) || Input::Is_Button_Down (DIK_RMENU); } is_key_down[DISPLAY_CMDS_03] = is_key_down[DISPLAY_CMDS_01] && is_key_down[DISPLAY_CMDS_02]; // // Are any of the buttons being held? // bool is_any_key_down = is_key_down[DISPLAY_CMDS_01] || is_key_down[DISPLAY_CMDS_02]; if (is_any_key_down) { // // Do we need to display the UI or trigger the timer? // if (IsDisplayed == false) { if (DisplayTimer == 0.0F) { DisplayTimer = TIMER_DURATION; } else { // // Is it time to display the UI yet? // DisplayTimer -= TimeManager::Get_Frame_Seconds (); if (DisplayTimer <= 0.0F) { // // Determine which page to display // for (int index = DISPLAY_MAX - 1; index >= 0; index --) { if (is_key_down[index]) { Display (true, (DISPLAY_TYPE)index); DisplayTimer = 0.0F; break; } } } } } } else { // // Turn off the UI if the key is no longer being held // if (IsDisplayed) { Display (false); } DisplayTimer = 0.0F; } return ; }