| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592 |
- /*
- ** 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/SPECIAL.CPP 1 3/03/97 10:25a Joe_bostic $ */
- /***********************************************************************************************
- *** 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 : SPECIAL.CPP *
- * *
- * Programmer : Joe L. Bostic *
- * *
- * Start Date : 05/27/95 *
- * *
- * Last Update : August 20, 1996 [JLB] *
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * Fetch_Difficulty -- Fetches the difficulty setting desired. *
- * Fetch_Password -- Prompts for a password entry from client. *
- * PWEditClass::Draw_Text -- Draws password style obscured text. *
- * Special_Dialog -- Handles the special options dialog. *
- * SpecialClass::Init -- Initialize the special class of options. *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "function.h"
- #ifdef WIN32
- #define OPTION_WIDTH 236*2
- #define OPTION_HEIGHT 162*2
- #define OPTION_X ((640 - OPTION_WIDTH) / 2)
- #define OPTION_Y (400 - OPTION_HEIGHT) / 2
- #else
- #define OPTION_WIDTH 236
- #define OPTION_HEIGHT 162
- #define OPTION_X ((320 - OPTION_WIDTH) / 2)
- #define OPTION_Y (200 - OPTION_HEIGHT) / 2
- #endif
- /***********************************************************************************************
- * SpecialClass::Init -- Initialize the special class of options. *
- * *
- * This initialization function is required (as opposed to using a constructor) because *
- * the SpecialClass is declared as part of a union. A union cannot have a member with a *
- * constructor. Other than this anomoly, the function serves the same purpose as a *
- * normal constructor. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 08/20/1996 JLB : Created. *
- *=============================================================================================*/
- void SpecialClass::Init(void)
- {
- IsShadowGrow = false;
- IsSpeedBuild = false;
- IsFromInstall = false;
- IsCaptureTheFlag = false;
- IsInert = false;
- IsThreePoint = false;
- IsTGrowth = true;
- IsTSpread = true;
- }
- /***********************************************************************************************
- * Special_Dialog -- Handles the special options dialog. *
- * *
- * This dialog is used when setting the special game options. It does not appear in the *
- * final version of the game. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 09/21/1995 JLB : Created. *
- *=============================================================================================*/
- void Special_Dialog(bool simple)
- {
- SpecialClass oldspecial = Special;
- GadgetClass * buttons = NULL;
- static struct {
- int Description;
- int Setting;
- CheckBoxClass * Button;
- } _options[] = {
- {TXT_THREE_POINT, 0, 0},
- {TXT_SPEED_BUILD, 0, 0},
- };
- TextButtonClass ok(200, TXT_OK, TPF_BUTTON, OPTION_X+15*RESFACTOR, OPTION_Y+OPTION_HEIGHT-15*RESFACTOR);
- TextButtonClass cancel(201, TXT_CANCEL, TPF_BUTTON, OPTION_X+OPTION_WIDTH-60*RESFACTOR, OPTION_Y+OPTION_HEIGHT-15*RESFACTOR);
- buttons = &ok;
- cancel.Add(*buttons);
- for (int index = 0; index < sizeof(_options)/sizeof(_options[0]); index++) {
- _options[index].Button = new CheckBoxClass(100+index, OPTION_X+17*RESFACTOR, OPTION_Y+20*RESFACTOR+(index*10*RESFACTOR));
- if (_options[index].Button) {
- _options[index].Button->Add(*buttons);
- bool value = false;
- switch (_options[index].Description) {
- case TXT_THREE_POINT:
- value = Special.IsThreePoint;
- break;
- case TXT_SPEED_BUILD:
- value = Special.IsSpeedBuild;
- break;
- }
- _options[index].Setting = value;
- if (value) {
- _options[index].Button->Turn_On();
- } else {
- _options[index].Button->Turn_Off();
- }
- }
- }
- Map.Override_Mouse_Shape(MOUSE_NORMAL);
- Set_Logic_Page(SeenBuff);
- bool recalc = true;
- bool display = true;
- bool process = true;
- while (process) {
- if (Session.Type == GAME_NORMAL) {
- Call_Back();
- } else {
- if (Main_Loop()) {
- process = false;
- }
- }
- if (display) {
- display = false;
- Hide_Mouse();
- Dialog_Box(OPTION_X, OPTION_Y, OPTION_WIDTH, OPTION_HEIGHT);
- Draw_Caption(TXT_SPECIAL_OPTIONS, OPTION_X, OPTION_Y, OPTION_WIDTH);
- for (index = 0; index < sizeof(_options)/sizeof(_options[0]); index++) {
- Fancy_Text_Print(_options[index].Description, _options[index].Button->X+10*RESFACTOR, _options[index].Button->Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
- }
- buttons->Draw_All();
- Show_Mouse();
- }
- KeyNumType input = buttons->Input();
- switch (input) {
- case KN_ESC:
- case 200|KN_BUTTON:
- process = false;
- for (index = 0; index < sizeof(_options)/sizeof(_options[0]); index++) {
- bool setting = _options[index].Setting;
- switch (_options[index].Description) {
- case TXT_THREE_POINT:
- oldspecial.IsThreePoint = setting;
- break;
- case TXT_SPEED_BUILD:
- oldspecial.IsSpeedBuild = setting;
- break;
- }
- }
- if (!simple) {
- OutList.Add(EventClass(oldspecial));
- } else {
- Special = oldspecial;
- }
- break;
- case 201|KN_BUTTON:
- process = false;
- break;
- case KN_NONE:
- break;
- default:
- index = (input & ~KN_BUTTON) - 100;
- if ((unsigned)index < sizeof(_options)/sizeof(_options[0])) {
- _options[index].Setting = _options[index].Button->IsOn;
- }
- break;
- }
- }
- if (!simple) {
- Map.Revert_Mouse_Shape();
- HidPage.Clear();
- Map.Flag_To_Redraw(true);
- Map.Render();
- }
- }
- /*
- ** Derived from the edit class, this class allows entry of passwords style text
- ** as an edit box. This style is characterized by "*" being displayed for every
- ** real character entered.
- */
- class PWEditClass : public EditClass
- {
- public:
- PWEditClass(int id, char * text, int max_len, TextPrintType flags, int x, int y, int w=-1, int h=-1) :
- EditClass(id, text, max_len, flags, x, y, w, h, ALPHANUMERIC) {};
- protected:
- virtual void Draw_Text(char const * text);
- };
- /***********************************************************************************************
- * PWEditClass::Draw_Text -- Draws password style obscured text. *
- * *
- * This routine is used by the password style edit box in order to display the entered *
- * text. The text will be displayed as asterisks instead of the actual characters the *
- * edit box may contain. This is necessary to obscure the password entry from glancing *
- * eyes. *
- * *
- * INPUT: text -- Pointer to the text that is to be rendered. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 10/27/1995 JLB : Created. *
- *=============================================================================================*/
- void PWEditClass::Draw_Text(char const * text)
- {
- char buffer[80];
- memset(buffer, '\0', sizeof(buffer));
- memset(buffer, '*', strlen(text));
- if (FontPtr == GradFont6Ptr) {
- TextPrintType flags;
- if (Has_Focus()) {
- flags = TPF_BRIGHT_COLOR;
- } else {
- flags = (TextPrintType)0;
- }
- Conquer_Clip_Text_Print(buffer, X+1, Y+1, Color, TBLACK, TextFlags | flags, Width-2);
- if (Has_Focus() && strlen(buffer) < MaxLength) {
- Conquer_Clip_Text_Print( "_", X+1+String_Pixel_Width(buffer), Y+1, Color, TBLACK, TextFlags | flags);
- }
- } else {
- Conquer_Clip_Text_Print(buffer, X+1, Y+1, Has_Focus() ?
- &ColorRemaps[PCOLOR_DIALOG_BLUE] : &ColorRemaps[PCOLOR_GREY],
- TBLACK, TextFlags, Width-2);
- if (Has_Focus() && strlen(buffer) < MaxLength) {
- Conquer_Clip_Text_Print("_", X+1+String_Pixel_Width(buffer), Y+1,
- &ColorRemaps[PCOLOR_DIALOG_BLUE], TBLACK, TextFlags);
- }
- }
- }
- /***********************************************************************************************
- * Fetch_Password -- Prompts for a password entry from client. *
- * *
- * This routine will prompt for and return a password entry from the player. *
- * *
- * INPUT: caption -- The caption to use for the top of the prompt dialog. *
- * *
- * message -- The body of the message to display in the dialog. *
- * *
- * btext -- The button text to use to finish the dialog box entry. *
- * *
- * OUTPUT: Returns with a pointer to the password text entered. This pointer is valid *
- * only until the next time that this routine is called. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 10/27/1995 JLB : Created. *
- *=============================================================================================*/
- #define BUFFSIZE (511)
- char const * Fetch_Password(int caption, int message, int btext)
- {
- char buffer[BUFFSIZE];
- bool process; // loop while true
- KeyNumType input; // user input
- bool pressed;
- int curbutton;
- TextButtonClass ok;
- if (btext == TXT_NONE) btext = TXT_OK;
- Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_6PT_GRAD|TPF_NOSHADOW);
- /*
- ** Examine the optional button parameters. Fetch the width and starting
- ** characters for each.
- */
- int bwidth, bheight; // button width and height
- /*
- ** Build the button list.
- */
- bheight = FontHeight + FontYSpacing + 2*RESFACTOR;
- bwidth = max((String_Pixel_Width(Text_String(btext)) + 8*RESFACTOR), 30*RESFACTOR);
- /*
- ** Determine the dimensions of the text to be used for the dialog box.
- ** These dimensions will control how the dialog box looks.
- */
- buffer[BUFFSIZE-1] = 0;
- strncpy(buffer, Text_String(message), BUFFSIZE-1);
- Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_6PT_GRAD|TPF_NOSHADOW);
- int width;
- int height;
- Format_Window_String(buffer, 255, width, height);
- width = max(width, 50*RESFACTOR);
- width += 40*RESFACTOR;
- height += (60+25)*RESFACTOR;
- int x = (SeenBuff.Get_Width() - width) / 2;
- int y = (SeenBuff.Get_Height() - height) / 2;
- /*
- ** Create the "ok" and password edit buttons.
- */
- TextButtonClass button1(1, btext, TPF_BUTTON,
- x + ((width - bwidth) >> 1), y + height - (bheight + 5*RESFACTOR), bwidth);
- static char pbuffer[45];
- memset(pbuffer, '\0', sizeof(pbuffer));
- int editx = x+26*RESFACTOR;
- int editwidth = (SeenBuff.Get_Width()/2 - editx) * 2;
- PWEditClass button2(2, &pbuffer[0], sizeof(pbuffer), TPF_6PT_GRAD|TPF_NOSHADOW, editx, (y+height)-35*RESFACTOR, editwidth, 10*RESFACTOR);
- TextButtonClass * buttonlist = 0;
- curbutton = 0;
- /*
- ** Add and initialize the buttons to the button list.
- */
- buttonlist = &button1;
- button2.Add(*buttonlist);
- /*
- ** Draw the background of the dialog.
- */
- Hide_Mouse();
- Set_Logic_Page(SeenBuff);
- Dialog_Box(x, y, width, height);
- Draw_Caption(caption, x, y, width);
- /*
- ** Draw the body of the message box.
- */
- Fancy_Text_Print(buffer, x + 20*RESFACTOR, y + 25*RESFACTOR, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
- /*
- ** Redraw the buttons.
- */
- if (buttonlist) {
- buttonlist->Draw_All();
- }
- Show_Mouse();
- /*
- ** Main Processing Loop.
- */
- process = true;
- pressed = false;
- bool first = true;
- while (process) {
- /*
- ** Invoke game callback.
- */
- Call_Back();
- #ifdef WIN32
- /*
- ** Handle possible surface loss due to a focus switch
- */
- if (AllSurfaces.SurfacesRestored) {
- AllSurfaces.SurfacesRestored=FALSE;
- process = false;
- break;
- }
- #endif //WIN32
- /*
- ** Fetch and process input.
- */
- input = buttonlist->Input();
- if (first) {
- button2.Set_Focus();
- button2.Flag_To_Redraw();
- first = false;
- }
- switch (input) {
- case (1|BUTTON_FLAG):
- process = false;
- break;
- case (KN_ESC):
- case (2|BUTTON_FLAG):
- process = false;
- break;
- case (KN_RETURN):
- process = false;
- break;
- default:
- break;
- }
- }
- return(pbuffer);
- }
- /***********************************************************************************************
- * Fetch_Difficulty -- Fetches the difficulty setting desired. *
- * *
- * This will display a dialog box that requests the player to specify a difficulty *
- * setting. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: Returns with a difficulty setting of 0 for easiest and 4 for hardest. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 08/13/1996 JLB : Created. *
- *=============================================================================================*/
- #ifdef FIXIT_CSII // checked - ajw 9/28/98
- int Fetch_Difficulty(bool amath)
- #else
- int Fetch_Difficulty(void)
- #endif
- {
- int const w = 250 * RESFACTOR;
- int const h = 80 * RESFACTOR;
- int const x = ((320 * RESFACTOR)/2) - w/2;
- int const y = ((200 * RESFACTOR)/2) - h/2;
- int const bwidth = 30 * RESFACTOR;
- /*
- ** Fill the description buffer with the description text. Break
- ** the text into appropriate spacing.
- */
- char buffer[512];
- strncpy(buffer, Text_String(TXT_DIFFICULTY), sizeof(buffer)-1);
- buffer[sizeof(buffer)-1] = '\0';
- #ifdef FIXIT_CSII // checked - ajw 9/28/98
- // If it's an aftermath mission, trim the sentence to get rid of the campaign stuff.
- if (amath) {
- int index=0;
- while (buffer[index] && buffer[index]!='.') index++;
- if (buffer[index]=='.') {
- buffer[index+1]=0;
- }
- }
- #endif
- Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_6PT_GRAD|TPF_NOSHADOW);
- int width;
- int height;
- Format_Window_String(buffer, w-60*RESFACTOR, width, height);
- /*
- ** Create the OK button.
- */
- TextButtonClass okbutton(1, TXT_OK, TPF_BUTTON, (x+w) - (bwidth+20*RESFACTOR) , (y+h) - (18*RESFACTOR), bwidth);
- GadgetClass * buttonlist = &okbutton;
- /*
- ** Create the slider button.
- */
- SliderClass slider(2, x+20*RESFACTOR, y+h - 29*RESFACTOR, w - 40*RESFACTOR, 8*RESFACTOR, true);
- if (Rule.IsFineDifficulty) {
- slider.Set_Maximum(5);
- slider.Set_Value(2);
- } else {
- slider.Set_Maximum(3);
- slider.Set_Value(1);
- }
- slider.Add(*buttonlist);
- /*
- ** Main Processing Loop.
- */
- Set_Logic_Page(SeenBuff);
- bool redraw = true;
- bool process = true;
- while (process) {
- if (redraw) {
- redraw = false;
- /*
- ** Draw the background of the dialog.
- */
- Hide_Mouse();
- Dialog_Box(x, y, w, h);
- /*
- ** Draw the body of the message.
- */
- // Fancy_Text_Print(buffer, x + 20*RESFACTOR, y + 15*RESFACTOR, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
- Fancy_Text_Print(buffer, x + 20*RESFACTOR, y + 15*RESFACTOR, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_6PT_GRAD|TPF_NOSHADOW);
- /*
- ** Display the descripton of the slider range.
- */
- Fancy_Text_Print(TXT_HARD, slider.X+slider.Width, slider.Y-9*RESFACTOR, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_RIGHT|TPF_6PT_GRAD|TPF_DROPSHADOW);
- Fancy_Text_Print(TXT_EASY, slider.X, slider.Y-9*RESFACTOR, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_6PT_GRAD|TPF_DROPSHADOW);
- Fancy_Text_Print(TXT_NORMAL, slider.X + (slider.Width/2), slider.Y-9*RESFACTOR, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_CENTER|TPF_6PT_GRAD|TPF_DROPSHADOW);
- /*
- ** Redraw the buttons.
- */
- if (buttonlist) {
- buttonlist->Draw_All();
- }
- Show_Mouse();
- }
- /*
- ** Invoke game callback.
- */
- Call_Back();
- #ifdef WIN32
- /*
- ** Handle possible surface loss due to a focus switch
- */
- if (AllSurfaces.SurfacesRestored) {
- AllSurfaces.SurfacesRestored=FALSE;
- redraw = true;
- continue;
- }
- #endif //WIN32
- /*
- ** Fetch and process input.
- */
- KeyNumType input = buttonlist->Input();
- switch (input) {
- case KN_RETURN:
- case (1|BUTTON_FLAG):
- process = false;
- break;
- default:
- break;
- }
- }
- return(slider.Get_Value() * (Rule.IsFineDifficulty ? 1 : 2));
- }
|