1250 lines
44 KiB
C++
1250 lines
44 KiB
C++
/*
|
|
** Command & Conquer Red Alert(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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/* $Header: /CounterStrike/MPLAYER.CPP 3 3/13/97 2:06p Steve_tall $ */
|
|
/***********************************************************************************************
|
|
*** 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 : Command & Conquer *
|
|
* *
|
|
* File Name : MPLAYER.CPP *
|
|
* *
|
|
* Programmer : Bill Randolph *
|
|
* *
|
|
* Start Date : April 14, 1995 *
|
|
* *
|
|
* Last Update : November 30, 1995 [BRR] *
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* Select_MPlayer_Game -- prompts user for NULL-Modem, Modem, or Network game *
|
|
* Clear_Listbox -- clears the given list box *
|
|
* Clear_Vector -- clears the given NodeNameType vector *
|
|
* Computer_Message -- "sends" a message from the computer *
|
|
* Garble_Message -- "garbles" a message *
|
|
* Surrender_Dialog -- Prompts user for surrendering *
|
|
* Abort_Dialog -- Prompts user for confirmation on aborting the mission *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
#include "function.h"
|
|
|
|
extern bool Is_Mission_Counterstrike (char *file_name);
|
|
|
|
#ifdef WOLAPI_INTEGRATION
|
|
#include "WolStrng.h"
|
|
#endif
|
|
|
|
/***********************************************************************************************
|
|
* Select_MPlayer_Game -- prompts user for NULL-Modem, Modem, or Network game *
|
|
* *
|
|
* INPUT: *
|
|
* none. *
|
|
* *
|
|
* OUTPUT: *
|
|
* GAME_NORMAL, GAME_MODEM, etc. *
|
|
* *
|
|
* WARNINGS: *
|
|
* none. *
|
|
* *
|
|
* HISTORY: *
|
|
* 02/14/1995 BR : Created. *
|
|
*=============================================================================================*/
|
|
GameType Select_MPlayer_Game (void)
|
|
{
|
|
//------------------------------------------------------------------------
|
|
// Dialog & button dimensions
|
|
//------------------------------------------------------------------------
|
|
int d_dialog_w = 190 *RESFACTOR;
|
|
#ifdef WOLAPI_INTEGRATION
|
|
int d_dialog_h = 89 * RESFACTOR; // ajw
|
|
int d_dialog_y = (((255 * RESFACTOR) - d_dialog_h) / 2);
|
|
#else
|
|
int d_dialog_h = 78 *RESFACTOR;
|
|
int d_dialog_y = 90 * RESFACTOR;
|
|
#endif
|
|
int d_dialog_x = (((320*RESFACTOR) - d_dialog_w) / 2);
|
|
int d_dialog_cx = d_dialog_x + (d_dialog_w / 2);
|
|
|
|
int d_txt6_h = 7 *RESFACTOR;
|
|
int d_margin = 7 *RESFACTOR;
|
|
|
|
int d_modemserial_w = 80 *RESFACTOR;
|
|
int d_modemserial_h = 9 *RESFACTOR;
|
|
int d_modemserial_x = d_dialog_cx - d_modemserial_w / 2;
|
|
int d_modemserial_y = d_dialog_y + d_margin + d_txt6_h + d_margin;
|
|
|
|
int d_skirmish_w = 80 *RESFACTOR;
|
|
int d_skirmish_h = 9 *RESFACTOR;
|
|
int d_skirmish_x = d_dialog_cx - d_skirmish_w / 2;
|
|
int d_skirmish_y = d_modemserial_y + d_modemserial_h + 2*RESFACTOR;
|
|
|
|
int d_ipx_w = 80 *RESFACTOR;
|
|
int d_ipx_h = 9 *RESFACTOR;
|
|
int d_ipx_x = d_dialog_cx - d_ipx_w / 2;
|
|
int d_ipx_y = d_skirmish_y + d_skirmish_h + 2*RESFACTOR;
|
|
|
|
#ifdef WOLAPI_INTEGRATION
|
|
// ajw 7/2/98 - added button
|
|
int d_wol_w = 80 * RESFACTOR;
|
|
int d_wol_h = 9 * RESFACTOR;
|
|
int d_wol_x = d_dialog_cx - d_wol_w / 2;
|
|
int d_wol_y = d_ipx_y + d_ipx_h + 2*RESFACTOR;
|
|
#endif
|
|
|
|
int d_cancel_w = 60 *RESFACTOR;
|
|
int d_cancel_h = 9 *RESFACTOR;
|
|
int d_cancel_x = d_dialog_cx - d_cancel_w / 2;
|
|
#ifdef WOLAPI_INTEGRATION
|
|
int d_cancel_y = d_wol_y + d_wol_h + d_margin;
|
|
#else
|
|
int d_cancel_y = d_ipx_y + d_ipx_h + d_margin;
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
GraphicBufferClass seen_buff_save(VisiblePage.Get_Width(), VisiblePage.Get_Height(), (void*)NULL);
|
|
#endif
|
|
|
|
//------------------------------------------------------------------------
|
|
// Button enumerations:
|
|
//------------------------------------------------------------------------
|
|
enum {
|
|
BUTTON_MODEMSERIAL = 100,
|
|
BUTTON_SKIRMISH,
|
|
BUTTON_IPX,
|
|
#ifdef WOLAPI_INTEGRATION
|
|
BUTTON_WOL, // ajw
|
|
#endif
|
|
BUTTON_CANCEL,
|
|
|
|
#ifdef WOLAPI_INTEGRATION
|
|
NUM_OF_BUTTONS = 5, // ajw
|
|
#else
|
|
NUM_OF_BUTTONS = 4,
|
|
#endif
|
|
};
|
|
|
|
int num_of_buttons = NUM_OF_BUTTONS - (Ipx.Is_IPX() ? 0 : 1);
|
|
//------------------------------------------------------------------------
|
|
// Redraw values: in order from "top" to "bottom" layer of the dialog
|
|
//------------------------------------------------------------------------
|
|
typedef enum {
|
|
REDRAW_NONE = 0,
|
|
REDRAW_BUTTONS, // includes map interior & coord values
|
|
REDRAW_BACKGROUND, // includes box, map bord, key, coord labels, btns
|
|
REDRAW_ALL = REDRAW_BACKGROUND
|
|
} RedrawType;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Dialog variables:
|
|
//------------------------------------------------------------------------
|
|
KeyNumType input; // input from user
|
|
bool process; // loop while true
|
|
RedrawType display; // true = re-draw everything
|
|
GameType retval; // return value
|
|
int selection;
|
|
bool pressed;
|
|
int curbutton;
|
|
TextButtonClass * buttons[NUM_OF_BUTTONS];
|
|
|
|
//------------------------------------------------------------------------
|
|
// Buttons
|
|
//------------------------------------------------------------------------
|
|
ControlClass * commands = NULL; // the button list
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
// If IPX not active then do only the modem serial dialog
|
|
//------------------------------------------------------------------------
|
|
// if ( !Ipx.Is_IPX() ) {
|
|
// return( Select_Serial_Dialog() );
|
|
// }
|
|
|
|
|
|
TextButtonClass modemserialbtn (BUTTON_MODEMSERIAL, TXT_MODEM_SERIAL, TPF_BUTTON,
|
|
d_modemserial_x, d_modemserial_y, d_modemserial_w, d_modemserial_h);
|
|
|
|
TextButtonClass skirmishbtn (BUTTON_SKIRMISH, TXT_SKIRMISH, TPF_BUTTON,
|
|
d_skirmish_x, d_skirmish_y, d_skirmish_w, d_skirmish_h);
|
|
|
|
TextButtonClass ipxbtn (BUTTON_IPX, TXT_NETWORK, TPF_BUTTON,
|
|
d_ipx_x, d_ipx_y, d_ipx_w, d_ipx_h);
|
|
|
|
#ifdef WOLAPI_INTEGRATION
|
|
// ajw
|
|
TextButtonClass wolbtn(BUTTON_WOL, TXT_WOL_INTERNETBUTTON, TPF_BUTTON,
|
|
d_wol_x, d_wol_y, d_wol_w, d_wol_h);
|
|
#endif
|
|
|
|
if(!Ipx.Is_IPX()) {
|
|
d_cancel_y = d_ipx_y;
|
|
d_dialog_h -= d_cancel_h;
|
|
}
|
|
|
|
TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON,
|
|
d_cancel_x, d_cancel_y, d_cancel_w, d_cancel_h);
|
|
|
|
//------------------------------------------------------------------------
|
|
// Initialize
|
|
//------------------------------------------------------------------------
|
|
Set_Logic_Page(SeenBuff);
|
|
#ifdef WIN32
|
|
VisiblePage.Blit(seen_buff_save);
|
|
#endif
|
|
//------------------------------------------------------------------------
|
|
// Create the list
|
|
//------------------------------------------------------------------------
|
|
commands = &modemserialbtn;
|
|
skirmishbtn.Add_Tail(*commands);
|
|
if(Ipx.Is_IPX()) {
|
|
ipxbtn.Add_Tail(*commands);
|
|
}
|
|
#ifdef WOLAPI_INTEGRATION
|
|
wolbtn.Add_Tail(*commands); // ajw
|
|
#endif
|
|
cancelbtn.Add_Tail(*commands);
|
|
|
|
//------------------------------------------------------------------------
|
|
// Fill array of button ptrs
|
|
//------------------------------------------------------------------------
|
|
curbutton = 0;
|
|
buttons[0] = &modemserialbtn;
|
|
buttons[1] = &skirmishbtn;
|
|
if(Ipx.Is_IPX()) {
|
|
buttons[2] = &ipxbtn;
|
|
#ifdef WOLAPI_INTEGRATION
|
|
buttons[3] = &wolbtn; // ajw
|
|
buttons[4] = &cancelbtn;
|
|
#else
|
|
buttons[3] = &cancelbtn;
|
|
#endif
|
|
} else {
|
|
#ifdef WOLAPI_INTEGRATION
|
|
buttons[2] = &wolbtn; // ajw
|
|
buttons[3] = &cancelbtn;
|
|
#else
|
|
buttons[2] = &cancelbtn;
|
|
#endif
|
|
}
|
|
buttons[curbutton]->Turn_On();
|
|
|
|
Keyboard->Clear();
|
|
|
|
Fancy_Text_Print(TXT_NONE, 0, 0, GadgetClass::Get_Color_Scheme(), TBLACK,
|
|
TPF_CENTER | TPF_TEXT);
|
|
|
|
//------------------------------------------------------------------------
|
|
// Main Processing Loop
|
|
//------------------------------------------------------------------------
|
|
display = REDRAW_ALL;
|
|
process = true;
|
|
pressed = false;
|
|
while (process) {
|
|
#ifdef WIN32
|
|
/*
|
|
** If we have just received input focus again after running in the background then
|
|
** we need to redraw.
|
|
*/
|
|
if (AllSurfaces.SurfacesRestored) {
|
|
AllSurfaces.SurfacesRestored=FALSE;
|
|
seen_buff_save.Blit(VisiblePage);
|
|
display = REDRAW_ALL;
|
|
}
|
|
#endif
|
|
|
|
//.....................................................................
|
|
// Invoke game callback
|
|
//.....................................................................
|
|
Call_Back();
|
|
|
|
//.....................................................................
|
|
// Refresh display if needed
|
|
//.....................................................................
|
|
if (display) {
|
|
Hide_Mouse();
|
|
if (display >= REDRAW_BACKGROUND) {
|
|
|
|
//...............................................................
|
|
// Refresh the backdrop
|
|
//...............................................................
|
|
Load_Title_Page(true);
|
|
CCPalette.Set();
|
|
|
|
//...............................................................
|
|
// Draw the background
|
|
//...............................................................
|
|
Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
|
|
Draw_Caption (TXT_SELECT_MPLAYER_GAME, d_dialog_x, d_dialog_y, d_dialog_w);
|
|
}
|
|
|
|
//..................................................................
|
|
// Redraw buttons
|
|
//..................................................................
|
|
if (display >= REDRAW_BUTTONS) {
|
|
commands->Flag_List_To_Redraw();
|
|
}
|
|
Show_Mouse();
|
|
display = REDRAW_NONE;
|
|
}
|
|
|
|
//.....................................................................
|
|
// Get user input
|
|
//.....................................................................
|
|
input = commands->Input();
|
|
|
|
//.....................................................................
|
|
// Process input
|
|
//.....................................................................
|
|
switch (input) {
|
|
case (BUTTON_MODEMSERIAL | KN_BUTTON):
|
|
selection = BUTTON_MODEMSERIAL;
|
|
pressed = true;
|
|
break;
|
|
|
|
case (BUTTON_SKIRMISH | KN_BUTTON):
|
|
selection = BUTTON_SKIRMISH;
|
|
pressed = true;
|
|
break;
|
|
|
|
case (BUTTON_IPX | KN_BUTTON):
|
|
selection = BUTTON_IPX;
|
|
pressed = true;
|
|
break;
|
|
|
|
#ifdef WOLAPI_INTEGRATION
|
|
case (BUTTON_WOL | KN_BUTTON): // ajw
|
|
selection = BUTTON_WOL;
|
|
pressed = true;
|
|
break;
|
|
#endif
|
|
|
|
case (KN_ESC):
|
|
case (BUTTON_CANCEL | KN_BUTTON):
|
|
selection = BUTTON_CANCEL;
|
|
pressed = true;
|
|
break;
|
|
|
|
case KN_UP:
|
|
buttons[curbutton]->Turn_Off();
|
|
buttons[curbutton]->Flag_To_Redraw();
|
|
curbutton--;
|
|
if (curbutton < 0)
|
|
curbutton = (num_of_buttons - 1);
|
|
buttons[curbutton]->Turn_On();
|
|
buttons[curbutton]->Flag_To_Redraw();
|
|
break;
|
|
|
|
case KN_DOWN:
|
|
buttons[curbutton]->Turn_Off();
|
|
buttons[curbutton]->Flag_To_Redraw();
|
|
curbutton++;
|
|
if (curbutton > (num_of_buttons - 1) )
|
|
curbutton = 0;
|
|
buttons[curbutton]->Turn_On();
|
|
buttons[curbutton]->Flag_To_Redraw();
|
|
break;
|
|
|
|
case KN_RETURN:
|
|
selection = curbutton + BUTTON_MODEMSERIAL;
|
|
pressed = true;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (pressed) {
|
|
|
|
//..................................................................
|
|
// to make sure the selection is correct in case they used the mouse
|
|
//..................................................................
|
|
buttons[curbutton]->Turn_Off();
|
|
buttons[curbutton]->Flag_To_Redraw();
|
|
curbutton = selection - BUTTON_MODEMSERIAL;
|
|
if(selection == BUTTON_CANCEL && !Ipx.Is_IPX()) curbutton--;
|
|
buttons[curbutton]->Turn_On();
|
|
buttons[curbutton]->IsPressed = true;
|
|
buttons[curbutton]->Draw_Me(true);
|
|
|
|
switch (selection) {
|
|
case (BUTTON_MODEMSERIAL):
|
|
|
|
//............................................................
|
|
// Pop up the modem/serial/com port dialog
|
|
//............................................................
|
|
retval = Select_Serial_Dialog();
|
|
|
|
if (retval != GAME_NORMAL) {
|
|
process = false;
|
|
} else {
|
|
buttons[curbutton]->IsPressed = false;
|
|
display = REDRAW_ALL;
|
|
}
|
|
break;
|
|
|
|
case (BUTTON_SKIRMISH):
|
|
Session.Type = GAME_SKIRMISH;
|
|
if (Com_Scenario_Dialog(true)) {
|
|
retval = GAME_SKIRMISH;
|
|
process = false;
|
|
#ifdef FIXIT_VERSION_3
|
|
bAftermathMultiplayer = Is_Aftermath_Installed();
|
|
// ajw I'll bet this was needed before also...
|
|
Session.ScenarioIsOfficial = Session.Scenarios[Session.Options.ScenarioIndex]->Get_Official();
|
|
#endif
|
|
} else {
|
|
buttons[curbutton]->IsPressed = false;
|
|
Session.Type = GAME_NORMAL;
|
|
display = REDRAW_ALL;
|
|
}
|
|
break;
|
|
|
|
case (BUTTON_IPX):
|
|
retval = GAME_IPX;
|
|
process = false;
|
|
break;
|
|
|
|
#ifdef WOLAPI_INTEGRATION
|
|
case (BUTTON_WOL): // ajw
|
|
retval = GAME_INTERNET;
|
|
process = false;
|
|
break;
|
|
#endif
|
|
|
|
case (BUTTON_CANCEL):
|
|
retval = GAME_NORMAL;
|
|
process = false;
|
|
break;
|
|
}
|
|
|
|
pressed = false;
|
|
}
|
|
}
|
|
return(retval);
|
|
|
|
} /* end of Select_MPlayer_Game */
|
|
|
|
|
|
/***************************************************************************
|
|
* Clear_Listbox -- clears the given list box *
|
|
* *
|
|
* This routine assumes the items in the given list box are character *
|
|
* buffers; it deletes each item in the list, then clears the list. *
|
|
* *
|
|
* INPUT: *
|
|
* list ptr to listbox *
|
|
* *
|
|
* OUTPUT: *
|
|
* none. *
|
|
* *
|
|
* WARNINGS: *
|
|
* none. *
|
|
* *
|
|
* HISTORY: *
|
|
* 11/29/1995 BRR : Created. *
|
|
*=========================================================================*/
|
|
void Clear_Listbox(ListClass * list)
|
|
{
|
|
char * item;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Clear the list box
|
|
//------------------------------------------------------------------------
|
|
while (list->Count()) {
|
|
item = (char *)(list->Get_Item(0));
|
|
list->Remove_Item(item);
|
|
delete [] item;
|
|
}
|
|
list->Flag_To_Redraw();
|
|
|
|
} // end of Clear_Listbox
|
|
|
|
|
|
/***************************************************************************
|
|
* Clear_Vector -- clears the given NodeNameType vector *
|
|
* *
|
|
* INPUT: *
|
|
* vector ptr to vector to clear *
|
|
* *
|
|
* OUTPUT: *
|
|
* none. *
|
|
* *
|
|
* WARNINGS: *
|
|
* none. *
|
|
* *
|
|
* HISTORY: *
|
|
* 11/29/1995 BRR : Created. *
|
|
*=========================================================================*/
|
|
void Clear_Vector(DynamicVectorClass <NodeNameType *> * vector)
|
|
{
|
|
int i;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Clear the 'Players' Vector
|
|
//------------------------------------------------------------------------
|
|
for (i = 0; i < vector->Count(); i++) {
|
|
delete (*vector)[i];
|
|
}
|
|
vector->Clear();
|
|
|
|
} // end of Clear_Vector
|
|
|
|
|
|
/***************************************************************************
|
|
* Computer_Message -- "sends" a message from the computer *
|
|
* *
|
|
* INPUT: *
|
|
* none. *
|
|
* *
|
|
* OUTPUT: *
|
|
* none. *
|
|
* *
|
|
* WARNINGS: *
|
|
* none. *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/06/1995 BRR : Created. *
|
|
*=========================================================================*/
|
|
void Computer_Message(void)
|
|
{
|
|
#ifdef NEVER
|
|
int color;
|
|
HousesType house;
|
|
HouseClass * ptr;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Find the computer house that the message will be from
|
|
//------------------------------------------------------------------------
|
|
for (house = HOUSE_MULTI1; house < (HOUSE_MULTI1 + Session.MaxPlayers); house++) {
|
|
ptr = HouseClass::As_Pointer(house);
|
|
|
|
if (!ptr || ptr->IsHuman || ptr->IsDefeated) {
|
|
continue;
|
|
}
|
|
|
|
//.....................................................................
|
|
// Decode this house's color
|
|
//.....................................................................
|
|
color = ptr->RemapColor;
|
|
|
|
//.....................................................................
|
|
// We now have a 1/4 chance of echoing one of the human players'
|
|
// messages back.
|
|
//.....................................................................
|
|
if (Percent_Chance(25)) {
|
|
|
|
//..................................................................
|
|
// Now we have a 1/3 chance of garbling the human message.
|
|
//..................................................................
|
|
if (Percent_Chance(33)) {
|
|
Garble_Message(Session.LastMessage);
|
|
}
|
|
|
|
//..................................................................
|
|
// Only add the message if there is one to add.
|
|
//..................................................................
|
|
if (strlen(Session.LastMessage)) {
|
|
Session.Messages.Add_Message(Text_String(TXT_COMPUTER), 0,
|
|
Session.LastMessage,
|
|
color, TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, Rule.MessageDelay * TICKS_PER_MINUTE);
|
|
}
|
|
}
|
|
else {
|
|
Session.Messages.Add_Message(Text_String(TXT_COMPUTER), 0,
|
|
Text_String(TXT_COMP_MSG1 + Random_Pick(0, 12)),
|
|
color, TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW, Rule.MessageDelay * TICKS_PER_MINUTE);
|
|
}
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
} /* end of Computer_Message */
|
|
|
|
|
|
#ifdef NEVER
|
|
/***************************************************************************
|
|
* Garble_Message -- "garbles" a message *
|
|
* *
|
|
* INPUT: *
|
|
* buf buffer to garble; stores output message *
|
|
* *
|
|
* OUTPUT: *
|
|
* none. *
|
|
* *
|
|
* WARNINGS: *
|
|
* none. *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/06/1995 BRR : Created. *
|
|
*=========================================================================*/
|
|
static void Garble_Message(char * buf)
|
|
{
|
|
char txt[80];
|
|
char punct[20]; // for punctuation
|
|
char * p; // working ptr
|
|
int numwords; // # words in the phrase
|
|
char * words[40]; // ptrs to various words in the phrase
|
|
int i,j;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Pull off any trailing punctuation
|
|
//------------------------------------------------------------------------
|
|
p = buf + strlen(buf) - 1;
|
|
while (1) {
|
|
if (p < buf)
|
|
break;
|
|
if (p[0]=='!' || p[0]=='.' || p[0]=='?') {
|
|
p--;
|
|
}
|
|
else {
|
|
p++;
|
|
break;
|
|
}
|
|
if (strlen(p) >= (sizeof(punct) - 1) ) {
|
|
break;
|
|
}
|
|
}
|
|
strcpy (punct, p);
|
|
p[0] = 0;
|
|
|
|
for (i = 0; i < 40; i++) {
|
|
words[i] = NULL;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// Copy the original buffer
|
|
//------------------------------------------------------------------------
|
|
strcpy(txt, buf);
|
|
|
|
//------------------------------------------------------------------------
|
|
// Split it up into words
|
|
//------------------------------------------------------------------------
|
|
p = strtok (txt, " ");
|
|
numwords = 0;
|
|
while (p) {
|
|
words[numwords] = p;
|
|
numwords++;
|
|
p = strtok (NULL, " ");
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// Now randomly put the words back. Don't use the real random-number
|
|
// generator, since different machines will have different LastMessage's,
|
|
// and will go out of sync.
|
|
//------------------------------------------------------------------------
|
|
buf[0] = 0;
|
|
for (i = 0; i < numwords; i++) {
|
|
j = Sim_IRandom(0, numwords);
|
|
if (words[j] == NULL) { // this word has been used already
|
|
i--;
|
|
continue;
|
|
}
|
|
strcat(buf, words[j]);
|
|
words[j] = NULL;
|
|
if (i < numwords-1)
|
|
strcat(buf, " ");
|
|
}
|
|
strcat(buf, punct);
|
|
|
|
} /* end of Garble_Message */
|
|
#endif
|
|
|
|
|
|
/***************************************************************************
|
|
* Surrender_Dialog -- Prompts user for surrendering *
|
|
* *
|
|
* INPUT: *
|
|
* none. *
|
|
* *
|
|
* OUTPUT: *
|
|
* 0 = user cancels, 1 = user wants to surrender. *
|
|
* *
|
|
* WARNINGS: *
|
|
* none. *
|
|
* *
|
|
* HISTORY: *
|
|
* 07/05/1995 BRR : Created. *
|
|
*=========================================================================*/
|
|
#ifdef FIXIT_VERSION_3 // Stalemate games.
|
|
int Surrender_Dialog(int text)
|
|
{
|
|
return Surrender_Dialog( Text_String( text ) );
|
|
}
|
|
#endif
|
|
|
|
#ifdef FIXIT_VERSION_3 // Stalemate games.
|
|
int Surrender_Dialog(const char* text)
|
|
#else
|
|
int Surrender_Dialog(int text)
|
|
#endif
|
|
{
|
|
//------------------------------------------------------------------------
|
|
// Dialog & button dimensions
|
|
//------------------------------------------------------------------------
|
|
enum {
|
|
D_DIALOG_W = 240*RESFACTOR, // dialog width
|
|
D_DIALOG_H = 63*RESFACTOR, // dialog height
|
|
D_DIALOG_X = ((320*RESFACTOR - D_DIALOG_W) / 2),// centered x-coord
|
|
D_DIALOG_Y = ((200*RESFACTOR - D_DIALOG_H) / 2),// centered y-coord
|
|
D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), // coord of x-center
|
|
|
|
D_TXT6_H = 7*RESFACTOR, // ht of 6-pt text
|
|
D_MARGIN = 5*RESFACTOR, // margin width/height
|
|
D_TOPMARGIN = 20*RESFACTOR, // top margin
|
|
|
|
D_OK_W = 45*RESFACTOR, // OK width
|
|
D_OK_H = 9*RESFACTOR, // OK height
|
|
D_OK_X = D_DIALOG_CX - D_OK_W - 5*RESFACTOR, // OK x
|
|
D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN*2, // OK y
|
|
|
|
D_CANCEL_W = 45*RESFACTOR, // Cancel width
|
|
D_CANCEL_H = 9*RESFACTOR, // Cancel height
|
|
D_CANCEL_X = D_DIALOG_CX + 5*RESFACTOR, // Cancel x
|
|
D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN*2, // Cancel y
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
// Button enumerations
|
|
//------------------------------------------------------------------------
|
|
enum {
|
|
BUTTON_OK = 100,
|
|
BUTTON_CANCEL,
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
// Buttons
|
|
//------------------------------------------------------------------------
|
|
ControlClass * commands = NULL; // the button list
|
|
|
|
TextButtonClass okbtn(BUTTON_OK, TXT_OK, TPF_BUTTON, D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
|
|
|
|
TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON, D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
|
|
|
|
int curbutton;
|
|
TextButtonClass * buttons[2];
|
|
curbutton = 0;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Initialize
|
|
//------------------------------------------------------------------------
|
|
Set_Logic_Page(SeenBuff);
|
|
|
|
//------------------------------------------------------------------------
|
|
// Create the button list
|
|
//------------------------------------------------------------------------
|
|
commands = &okbtn;
|
|
cancelbtn.Add_Tail(*commands);
|
|
|
|
buttons[0] = &okbtn;
|
|
buttons[1] = &cancelbtn;
|
|
buttons[curbutton]->Turn_On();
|
|
|
|
//------------------------------------------------------------------------
|
|
// Main Processing Loop
|
|
//------------------------------------------------------------------------
|
|
int retcode = 0;
|
|
bool display = true;
|
|
bool process = true;
|
|
while (process) {
|
|
|
|
//.....................................................................
|
|
// Invoke game callback
|
|
//.....................................................................
|
|
if (Session.Type != GAME_SKIRMISH) {
|
|
if (Main_Loop()) {
|
|
retcode = 0;
|
|
process = false;
|
|
}
|
|
}
|
|
|
|
//.....................................................................
|
|
// Refresh display if needed
|
|
//.....................................................................
|
|
if (display) {
|
|
display = false;
|
|
|
|
//..................................................................
|
|
// Display the dialog box
|
|
//..................................................................
|
|
Hide_Mouse();
|
|
Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
|
|
Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
|
|
|
|
//...............................................................
|
|
// Draw the captions
|
|
//...............................................................
|
|
#ifdef FIXIT_VERSION_3 // Stalemate games.
|
|
Fancy_Text_Print(text,
|
|
D_DIALOG_CX, D_DIALOG_Y + D_TOPMARGIN,
|
|
GadgetClass::Get_Color_Scheme(), TBLACK,
|
|
TPF_CENTER | TPF_TEXT);
|
|
#else
|
|
Fancy_Text_Print(Text_String(text),
|
|
D_DIALOG_CX, D_DIALOG_Y + D_TOPMARGIN,
|
|
GadgetClass::Get_Color_Scheme(), TBLACK,
|
|
TPF_CENTER | TPF_TEXT);
|
|
#endif
|
|
|
|
//..................................................................
|
|
// Redraw the buttons
|
|
//..................................................................
|
|
commands->Flag_List_To_Redraw();
|
|
Show_Mouse();
|
|
}
|
|
|
|
//.....................................................................
|
|
// Get user input
|
|
//.....................................................................
|
|
KeyNumType input = commands->Input();
|
|
|
|
//.....................................................................
|
|
// Process input
|
|
//.....................................................................
|
|
switch (input) {
|
|
case (BUTTON_OK | KN_BUTTON):
|
|
retcode = 1;
|
|
process = false;
|
|
break;
|
|
|
|
case (BUTTON_CANCEL | KN_BUTTON):
|
|
retcode = 0;
|
|
process = false;
|
|
break;
|
|
|
|
case (KN_RETURN):
|
|
if (curbutton == 0) {
|
|
retcode = 1;
|
|
} else {
|
|
retcode = 0;
|
|
}
|
|
process = false;
|
|
break;
|
|
|
|
case (KN_ESC):
|
|
retcode = 0;
|
|
process = false;
|
|
break;
|
|
|
|
case (KN_RIGHT):
|
|
buttons[curbutton]->Turn_Off();
|
|
curbutton++;
|
|
if (curbutton > 1) {
|
|
curbutton = 0;
|
|
}
|
|
buttons[curbutton]->Turn_On();
|
|
break;
|
|
|
|
case (KN_LEFT):
|
|
buttons[curbutton]->Turn_Off();
|
|
curbutton--;
|
|
if (curbutton < 0) {
|
|
curbutton = 1;
|
|
}
|
|
buttons[curbutton]->Turn_On();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// Redraw the display
|
|
//------------------------------------------------------------------------
|
|
HidPage.Clear();
|
|
Map.Flag_To_Redraw(true);
|
|
Map.Render();
|
|
|
|
return (retcode);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
* Abort_Dialog -- Prompts user for confirmation on aborting the mission *
|
|
* *
|
|
* INPUT: *
|
|
* none. *
|
|
* *
|
|
* OUTPUT: *
|
|
* 1 = user confirms abort, 0 = user cancels *
|
|
* *
|
|
* WARNINGS: *
|
|
* none. *
|
|
* *
|
|
* HISTORY: *
|
|
* 07/05/1995 BRR : Created. *
|
|
*=========================================================================*/
|
|
int Abort_Dialog(void)
|
|
{
|
|
//------------------------------------------------------------------------
|
|
// Dialog & button dimensions
|
|
//------------------------------------------------------------------------
|
|
enum {
|
|
D_DIALOG_W = 170*RESFACTOR, // dialog width
|
|
D_DIALOG_H = 63*RESFACTOR, // dialog height
|
|
D_DIALOG_X = ((320*RESFACTOR - D_DIALOG_W) / 2),// centered x-coord
|
|
D_DIALOG_Y = ((200*RESFACTOR - D_DIALOG_H) / 2),// centered y-coord
|
|
D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), // coord of x-center
|
|
|
|
D_TXT6_H = 7*RESFACTOR, // ht of 6-pt text
|
|
D_MARGIN = 5*RESFACTOR, // margin width/height
|
|
D_TOPMARGIN = 20*RESFACTOR, // top margin
|
|
|
|
D_YES_W = 45*RESFACTOR, // YES width
|
|
D_YES_H = 9*RESFACTOR, // YES height
|
|
D_YES_X = D_DIALOG_CX - D_YES_W - 5*RESFACTOR, // YES x
|
|
D_YES_Y = D_DIALOG_Y + D_DIALOG_H - D_YES_H - D_MARGIN*2, // YES y
|
|
|
|
D_NO_W = 45*RESFACTOR, // Cancel width
|
|
D_NO_H = 9*RESFACTOR, // Cancel height
|
|
D_NO_X = D_DIALOG_CX + 5*RESFACTOR, // Cancel x
|
|
D_NO_Y = D_DIALOG_Y + D_DIALOG_H - D_NO_H - D_MARGIN*2, // Cancel y
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
// Button enumerations
|
|
//------------------------------------------------------------------------
|
|
enum {
|
|
BUTTON_YES = 100,
|
|
BUTTON_NO,
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
// Buttons
|
|
//------------------------------------------------------------------------
|
|
ControlClass * commands = NULL; // the button list
|
|
|
|
TextButtonClass yesbtn(BUTTON_YES, TXT_YES, TPF_BUTTON, D_YES_X, D_YES_Y, D_YES_W, D_YES_H);
|
|
|
|
TextButtonClass nobtn(BUTTON_NO, TXT_NO, TPF_BUTTON, D_NO_X, D_NO_Y, D_NO_W, D_NO_H);
|
|
|
|
int curbutton;
|
|
TextButtonClass * buttons[2];
|
|
curbutton = 0;
|
|
|
|
//------------------------------------------------------------------------
|
|
// Initialize
|
|
//------------------------------------------------------------------------
|
|
Set_Logic_Page(SeenBuff);
|
|
|
|
//------------------------------------------------------------------------
|
|
// Create the button list
|
|
//------------------------------------------------------------------------
|
|
commands = &yesbtn;
|
|
nobtn.Add_Tail(*commands);
|
|
|
|
buttons[0] = &yesbtn;
|
|
buttons[1] = &nobtn;
|
|
buttons[curbutton]->Turn_On();
|
|
|
|
//------------------------------------------------------------------------
|
|
// Main Processing Loop
|
|
//------------------------------------------------------------------------
|
|
int retcode = 0;
|
|
bool display = true;
|
|
bool process = true;
|
|
while (process) {
|
|
|
|
//.....................................................................
|
|
// Invoke game callback
|
|
//.....................................................................
|
|
if (Session.Type != GAME_SKIRMISH) {
|
|
if (Main_Loop()) {
|
|
retcode = 0;
|
|
process = false;
|
|
}
|
|
}
|
|
|
|
//.....................................................................
|
|
// Refresh display if needed
|
|
//.....................................................................
|
|
if (display) {
|
|
display = false;
|
|
|
|
//..................................................................
|
|
// Display the dialog box
|
|
//..................................................................
|
|
Hide_Mouse();
|
|
Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
|
|
Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
|
|
|
|
//...............................................................
|
|
// Draw the captions
|
|
//...............................................................
|
|
Fancy_Text_Print(Text_String(TXT_CONFIRM_EXIT),
|
|
D_DIALOG_CX, D_DIALOG_Y + D_TOPMARGIN,
|
|
GadgetClass::Get_Color_Scheme(), TBLACK,
|
|
TPF_CENTER | TPF_TEXT);
|
|
|
|
//..................................................................
|
|
// Redraw the buttons
|
|
//..................................................................
|
|
commands->Flag_List_To_Redraw();
|
|
Show_Mouse();
|
|
}
|
|
|
|
//.....................................................................
|
|
// Get user input
|
|
//.....................................................................
|
|
KeyNumType input = commands->Input();
|
|
|
|
//.....................................................................
|
|
// Process input
|
|
//.....................................................................
|
|
switch (input) {
|
|
case (BUTTON_YES | KN_BUTTON):
|
|
retcode = 1;
|
|
process = false;
|
|
break;
|
|
|
|
case (BUTTON_NO | KN_BUTTON):
|
|
retcode = 0;
|
|
process = false;
|
|
break;
|
|
|
|
case (KN_RETURN):
|
|
if (curbutton == 0) {
|
|
retcode = 1;
|
|
} else {
|
|
retcode = 0;
|
|
}
|
|
process = false;
|
|
break;
|
|
|
|
case (KN_ESC):
|
|
retcode = 0;
|
|
process = false;
|
|
break;
|
|
|
|
case (KN_RIGHT):
|
|
buttons[curbutton]->Turn_Off();
|
|
curbutton++;
|
|
if (curbutton > 1) {
|
|
curbutton = 0;
|
|
}
|
|
buttons[curbutton]->Turn_On();
|
|
break;
|
|
|
|
case (KN_LEFT):
|
|
buttons[curbutton]->Turn_Off();
|
|
curbutton--;
|
|
if (curbutton < 0) {
|
|
curbutton = 1;
|
|
}
|
|
buttons[curbutton]->Turn_On();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// Redraw the display
|
|
//------------------------------------------------------------------------
|
|
HidPage.Clear();
|
|
Map.Flag_To_Redraw(true);
|
|
Map.Render();
|
|
|
|
return (retcode);
|
|
}
|
|
|
|
|
|
#if(TEN)
|
|
/***************************************************************************
|
|
* Read_TEN_Game_Options -- reads multiplayer game options from disk *
|
|
* *
|
|
* This routine is used for multiplayer games which read the game options *
|
|
* from disk, rather than through a connection dialog. *
|
|
* *
|
|
* INPUT: *
|
|
* none. *
|
|
* *
|
|
* OUTPUT: *
|
|
* 1 = OK, 0 = error *
|
|
* *
|
|
* WARNINGS: *
|
|
* none. *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/11/1996 BRR : Created. *
|
|
*=========================================================================*/
|
|
int Read_TEN_Game_Options(void)
|
|
{
|
|
INIClass ini;
|
|
if (!ini.Load(RawFileClass(Session.OptionsFile))) {
|
|
return (0);
|
|
}
|
|
|
|
ini.Get_String("Options", "Handle", "Noname", Session.Handle,
|
|
sizeof(Session.Handle));
|
|
if (Session.TenPlayerID == -1) {
|
|
return (0);
|
|
}
|
|
Session.ColorIdx = (PlayerColorType)Session.TenPlayerID;
|
|
Session.House = (HousesType)
|
|
((int)HOUSE_USSR + ini.Get_Int("Options", "Side", 0));
|
|
Session.Options.Credits = ini.Get_Int("Options", "Credits", 3000);
|
|
Session.Options.Bases = ini.Get_Int("Options", "Bases", 1);
|
|
Session.Options.Tiberium = ini.Get_Int("Options", "Tiberium", 1);
|
|
Session.Options.Goodies = ini.Get_Int("Options", "Crates", 1);
|
|
Special.IsShadowGrow = ini.Get_Int ("Options", "Shadow", 0);
|
|
BuildLevel = ini.Get_Int("Options", "BuildLevel", 3);
|
|
Session.Options.UnitCount = ini.Get_Int("Options", "UnitCount", 5);
|
|
Seed = ini.Get_Int("Options", "Seed", 0);
|
|
Special.IsCaptureTheFlag = ini.Get_Int("Options", "CapFlag", 0);
|
|
Session.Options.AIPlayers = ini.Get_Int("Options", "AI", 0);
|
|
Session.NumPlayers = ini.Get_Int("Options", "Players", 2);
|
|
|
|
if (Session.Options.AIPlayers){
|
|
Session.Options.Ghosts = 1;
|
|
}
|
|
|
|
if (Session.Options.Tiberium) {
|
|
Special.IsTGrowth = 1;
|
|
Special.IsTSpread = 1;
|
|
} else {
|
|
Special.IsTGrowth = 0;
|
|
Special.IsTSpread = 0;
|
|
}
|
|
|
|
/*
|
|
** Read the scenario name from the .INI and try to match it with a scenario file in our list.
|
|
*/
|
|
ini.Get_String("Options", "Scenario", "Black Acres",
|
|
Session.Options.ScenarioDescription,
|
|
sizeof (Session.Options.ScenarioDescription));
|
|
|
|
Session.Options.ScenarioIndex = -1;
|
|
for (int i = 0; i < Session.Scenarios.Count(); i++) {
|
|
if (!strcmp (Session.Scenarios[i]->Description(),
|
|
Session.Options.ScenarioDescription) ) {
|
|
Session.Options.ScenarioIndex = i;
|
|
strcpy(Session.ScenarioFileName, Session.Scenarios[i]->Get_Filename());
|
|
strcpy(Scen.ScenarioName, Session.Scenarios[i]->Get_Filename());
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (Session.Options.ScenarioIndex == -1) {
|
|
WWMessageBox().Process("Scenario not found!");
|
|
//Prog_End();
|
|
Emergency_Exit(0);
|
|
}
|
|
|
|
Options.GameSpeed = 0;
|
|
|
|
Session.MaxAhead = ini.Get_Int("Timing", "MaxAhead", 9);
|
|
Session.FrameSendRate = ini.Get_Int("Timing", "SendRate", 3);
|
|
Session.NetResponseTime = ini.Get_Int("Timing","Latency",600);
|
|
|
|
return (1);
|
|
}
|
|
#endif // TEN
|
|
|
|
|
|
#if(MPATH)
|
|
/***************************************************************************
|
|
* Read_MPATH_Game_Options -- reads multiplayer game options from disk *
|
|
* *
|
|
* This routine is used for multiplayer games which read the game options *
|
|
* from disk, rather than through a connection dialog. *
|
|
* *
|
|
* INPUT: *
|
|
* none. *
|
|
* *
|
|
* OUTPUT: *
|
|
* 1 = OK, 0 = error *
|
|
* *
|
|
* WARNINGS: *
|
|
* none. *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/11/1996 BRR : Created. *
|
|
*=========================================================================*/
|
|
int Read_MPATH_Game_Options(void)
|
|
{
|
|
INIClass ini;
|
|
if (!ini.Load(RawFileClass(Session.OptionsFile))) {
|
|
return (0);
|
|
}
|
|
|
|
ini.Get_String("Options", "Handle", "Noname", Session.Handle,
|
|
sizeof(Session.Handle));
|
|
Session.ColorIdx = (PlayerColorType)ini.Get_Int("Options", "Color", 0);
|
|
Session.House = (HousesType)
|
|
((int)HOUSE_USSR + ini.Get_Int("Options", "Side", 0));
|
|
Session.Options.Credits = ini.Get_Int("Options", "Credits", 3000);
|
|
Session.Options.Bases = ini.Get_Int("Options", "Bases", 1);
|
|
Session.Options.Tiberium = ini.Get_Int("Options", "Tiberium", 1);
|
|
Session.Options.Goodies = ini.Get_Int("Options", "Crates", 1);
|
|
Special.IsShadowGrow = ini.Get_Int ("Options", "Shadow", 0);
|
|
BuildLevel = ini.Get_Int("Options", "BuildLevel", 3);
|
|
Session.Options.UnitCount = ini.Get_Int("Options", "UnitCount", 5);
|
|
Seed = ini.Get_Int("Options", "Seed", 0);
|
|
Special.IsCaptureTheFlag = ini.Get_Int("Options", "CapFlag", 0);
|
|
Session.Options.AIPlayers = ini.Get_Int("Options", "AI", 0);
|
|
|
|
if (Session.Options.AIPlayers){
|
|
Session.Options.Ghosts = 1;
|
|
}
|
|
|
|
if (Session.Options.Tiberium) {
|
|
Special.IsTGrowth = 1;
|
|
Special.IsTSpread = 1;
|
|
} else {
|
|
Special.IsTGrowth = 0;
|
|
Special.IsTSpread = 0;
|
|
}
|
|
|
|
/*
|
|
** Read the scenario name from the .INI and try to match it with a scenario file in our list.
|
|
*/
|
|
ini.Get_String("Options", "Scenario", "Black Acres",
|
|
Session.Options.ScenarioDescription,
|
|
sizeof (Session.Options.ScenarioDescription));
|
|
|
|
Session.Options.ScenarioIndex = -1;
|
|
for (int i = 0; i < Session.Scenarios.Count(); i++) {
|
|
if (!strcmp (Session.Scenarios[i]->Description(),
|
|
Session.Options.ScenarioDescription) ) {
|
|
Session.Options.ScenarioIndex = i;
|
|
strcpy(Session.ScenarioFileName, Session.Scenarios[i]->Get_Filename());
|
|
strcpy(Scen.ScenarioName, Session.Scenarios[i]->Get_Filename());
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (Session.Options.ScenarioIndex == -1) {
|
|
WWMessageBox().Process("Scenario not found!");
|
|
//Prog_End();
|
|
Emergency_Exit(0);
|
|
}
|
|
|
|
Options.GameSpeed = 0;
|
|
|
|
Session.MaxAhead = ini.Get_Int("Timing", "MaxAhead", 9);
|
|
Session.FrameSendRate = ini.Get_Int("Timing", "SendRate", 3);
|
|
Session.NetResponseTime = ini.Get_Int("Timing","Latency",600);
|
|
|
|
return (1);
|
|
}
|
|
#endif // MPATH
|
|
|
|
/************************** end of mplayer.cpp *****************************/
|