EXPAND.CPP (19749B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: /CounterStrike/EXPAND.CPP 7 3/17/97 1:05a Steve_tall $ */ 17 /*********************************************************************************************** 18 *** 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 *** 19 *********************************************************************************************** 20 * * 21 * Project Name : Command & Conquer * 22 * * 23 * File Name : EXPAND.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : 11/03/95 * 28 * * 29 * Last Update : Mar 01, 1997 [V.Grippi] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * EListClass::Draw_Entry -- Draws entry for expansion scenario. * 34 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 35 36 #include "function.h" 37 38 #ifdef FIXIT_VERSION_3 39 #include "WolStrng.h" 40 #endif 41 42 //#define CS_DEBUG 43 44 #define ARRAYOFFSET 20 45 46 47 /*********************************************************************************************** 48 * Expansion_CS_Present -- Is the Counterstrike expansion available? * 49 * * 50 * * 51 * * 52 * INPUT: Nothing * 53 * * 54 * OUTPUT: true if counterstrike installed * 55 * * 56 * WARNINGS: None * 57 * * 58 * HISTORY: * 59 * 3/5/97 1:59PM ST : Fixed to check for EXPAND.MIX * 60 *=============================================================================================*/ 61 bool Expansion_CS_Present(void) 62 { 63 // ajw 9/29/98 64 return Is_Counterstrike_Installed(); 65 // RawFileClass file("EXPAND.MIX"); 66 // return(file.Is_Available()); 67 } 68 #ifdef FIXIT_CSII // checked - ajw 9/28/98 69 /*********************************************************************************************** 70 * Expansion_AM_Present -- Is the Aftermath expansion available? * 71 * * 72 * * 73 * * 74 * INPUT: Nothing * 75 * * 76 * OUTPUT: true if AfterMath is installed * 77 * * 78 * WARNINGS: None * 79 * * 80 * HISTORY: * 81 * 7/9/97 1:59PM BG : Fixed to check for EXPAND2.MIX * 82 *=============================================================================================*/ 83 bool Expansion_AM_Present(void) 84 { 85 // ajw 9/29/98 86 return Is_Aftermath_Installed(); 87 // RawFileClass file("EXPAND2.MIX"); 88 // return(file.Is_Available()); 89 } 90 #endif 91 92 93 const char* ExpandNames[] = { 94 "SCG20EA", 95 "SCG21EA", 96 "SCG22EA", 97 "SCG23EA", 98 "SCG24EA", 99 "SCG26EA", 100 "SCG27EA", 101 "SCG28EA", 102 "SCU31EA", 103 "SCU32EA", 104 "SCU33EA", 105 "SCU34EA", 106 "SCU35EA", 107 "SCU36EA", 108 "SCU37EA", 109 "SCU38EA", 110 #ifdef FIXIT_CSII // checked - ajw 9/28/98 111 "SCG43EA", // Harbor Reclamation 112 "SCG41EA", // In the nick of time 113 "SCG40EA", // Caught in the act 114 "SCG42EA", // Production Disruption 115 "SCG47EA", // Negotiations 116 "SCG45EA", // Monster Tank Madness 117 "SCG44EA", // Time Flies 118 "SCG48EA", // Absolut MADness 119 "SCG46EA", // Pawn 120 121 "SCU43EA", // Testing Grounds 122 "SCU40EA", // Shock Therapy 123 "SCU42EA", // Let's Make a Steal 124 "SCU41EA", // Test Drive 125 "SCU45EA", // Don't Drink The Water 126 "SCU44EA", // Situation Critical 127 "SCU46EA", // Brothers in Arms 128 "SCU47EA", // Deus Ex Machina 129 "SCU48EA", // Grunyev Revolution 130 #endif 131 NULL 132 }; 133 134 const char* TestNames2[] = { 135 "SCG01EA", 136 "SCG02EA", 137 "SCG03EA", 138 "SCG04EA", 139 "SCG05EA", 140 "SCG06EA", 141 "SCG07EA", 142 "SCG08EA", 143 "SCU01EA", 144 "SCU02EA", 145 "SCU03EA", 146 "SCU04EA", 147 "SCU05EA", 148 "SCU06EA", 149 "SCU07EA", 150 "SCU08EA", 151 "SCU09EA", 152 NULL 153 }; 154 155 #ifdef GERMAN 156 const char* XlatNames[] = { 157 "Zusammenstoss", 158 "Unter Tage", 159 "Kontrollierte Verbrennung", 160 "Griechenland 1 - Stavros", 161 "Griechenland 2 - Evakuierung", 162 "Sibirien 1 - Frische Spuren", 163 "Sibirien 2 - In der Falle", 164 "Sibirien 3 - Wildnis", 165 "Das Feld der Ehre", 166 "Belagerung", 167 "Mausefalle", 168 "Teslas Erbe", 169 "Soldat Volkov", 170 "Die Spitze der Welt", 171 "Paradoxe Gleichung", 172 "Nukleare Eskalation", 173 #ifdef FIXIT_CSII // checked - ajw 9/28/98 174 "Ein sicherer Hafen", // "SCG43EA", // Harbor Reclamation 175 "Zeitkritische Routine", // "SCG41EA", // In the nick of time 176 "Auf frischer Tat ertappt", // "SCG40EA", // Caught in the act 177 "Drastischer Baustopp", // "SCG42EA", // Production Disruption 178 "Harte Verhandlungen", // "SCG47EA", // Negotiations 179 "Ferngelenktes Kriegsspielzeug",// "SCG45EA", // Monster Tank Madness 180 "Licht aus", // "SCG44EA", // Time Flies 181 "Molekulare Kriegsfhrung", // "SCG48EA", // Absolut MADness 182 "Bauernopfer", // "SCG46EA", // Pawn 183 184 "Testgel„nde", // "SCU43EA", // Testing Grounds 185 "Schocktherapie", // "SCU40EA", // Shock Therapy 186 "Der Letzte seiner Art", // "SCU42EA", // Let's Make a Steal 187 "Probefahrt", // "SCU41EA", // Test Drive 188 "Schlaftrunk", // "SCU45EA", // Don't Drink The Water 189 "Der jngste Tag", // "SCU44EA", // Situation Critical 190 "Waffenbrder", // "SCU46EA", // Brothers in Arms 191 "Deus Ex Machina", // "SCU47EA", // Deus Ex Machina 192 "Die Replikanten von Grunyev", // "SCU48EA", // Grunyev Revolution 193 194 #endif 195 NULL 196 }; 197 198 #endif 199 200 #ifdef FRENCH 201 const char* XlatNames[] = { 202 "Gaz Sarin 1: Ravitaillement Fatal", 203 "Gaz Sarin 2: En Sous-sol", 204 "Gaz Sarin 3: Attaque Chirurgicale", 205 "GrŠce Occup‚e 1: Guerre Priv‚e", 206 "GrŠce Occup‚e 2: Evacuation", 207 "Conflit Sib‚rien 1: Traces FraŒches", 208 "Conflit Sib‚rien 2: Pris au PiŠge", 209 "Conflit Sib‚rien 3: Terres de Glace", 210 "Mise … l'Epreuve", 211 "Assi‚g‚s", 212 "La SouriciŠre", 213 "L'H‚ritage de Tesla", 214 "Tandem de Choc", 215 "Jusqu'au Sommet du Monde", 216 "Effets Secondaires", 217 "Intensification nucl‚aire", 218 #ifdef FIXIT_CSII // checked - ajw 9/28/98 219 "Le vieux port", // "SCG43EA", // Harbor Reclamation 220 "Juste … temps", // "SCG41EA", // In the nick of time 221 "La main dans le sac", // "SCG40EA", // Caught in the act 222 "Production interrompue", // "SCG42EA", // Production Disruption 223 "N‚gociations", // "SCG47EA", // Negotiations 224 "Tanks en folie!", // "SCG45EA", // Monster Tank Madness 225 "Le temps passe", // "SCG44EA", // Time Flies 226 "D‚mence absolue", // "SCG48EA", // Absolut MADness 227 "Le pion", // "SCG46EA", // Pawn 228 229 "Terrains d'essais", // "SCU43EA", // Testing Grounds 230 "Th‚rapie de choc", // "SCU40EA", // Shock Therapy 231 "Au voleur!", // "SCU42EA", // Let's Make a Steal 232 "Essai de conduite", // "SCU41EA", // Test Drive 233 "Ne buvez pas la tasse", // "SCU45EA", // Don't Drink The Water 234 "Situation critique", // "SCU44EA", // Situation Critical 235 "FrŠres d'armes", // "SCU46EA", // Brothers in Arms 236 "Deus Ex Machina", // "SCU47EA", // Deus Ex Machina 237 "La R‚volution de Grunyev",// "SCU48EA", // Grunyev Revolution 238 239 #endif 240 241 NULL, 242 }; 243 244 #endif 245 246 247 248 #ifndef WIN32 //VG 249 250 #define OPTION_WIDTH 236 251 #ifdef FIXIT_CSII // checked - ajw 9/28/98 252 #error Can never again build without WIN32 defined. 253 #define OPTION_HEIGHT 162 254 #else 255 #define OPTION_HEIGHT 162 256 #endif 257 #define OPTION_X ((320 - OPTION_WIDTH) / 2) 258 #define OPTION_Y (200 - OPTION_HEIGHT) / 2 259 260 #else 261 262 #define OPTION_WIDTH 560 263 #ifdef FIXIT_CSII // checked - ajw 9/28/98 264 #define OPTION_HEIGHT 332 265 #else 266 #define OPTION_HEIGHT 300 267 #endif 268 #define OPTION_X ((640 - OPTION_WIDTH) / 2) 269 #define OPTION_Y (400 - OPTION_HEIGHT) / 2 270 #endif 271 272 struct EObjectClass 273 { 274 HousesType House; 275 int Scenario; 276 char Name[128]; 277 char FullName[128]; 278 }; 279 280 281 /* 282 ** Derived from list class to handle expansion scenario listings. The listings 283 ** are recorded as EObjectClass objects. The data contained specifies the scenario 284 ** number, side, and text description. 285 */ 286 class EListClass : public ListClass 287 { 288 public: 289 EListClass(int id, int x, int y, int w, int h, TextPrintType flags, void const * up, void const * down) : 290 ListClass(id, x, y, w, h, flags, up, down) {}; 291 292 virtual int Add_Object(EObjectClass * obj) { 293 return(ListClass::Add_Item((char const *)obj)); 294 } 295 virtual EObjectClass * Get_Object(int index) const { 296 return((EObjectClass *)ListClass::Get_Item(index)); 297 } 298 virtual EObjectClass * Current_Object(void) { 299 return((EObjectClass *)ListClass::Current_Item()); 300 } 301 302 protected: 303 virtual void Draw_Entry(int index, int x, int y, int width, int selected); 304 305 private: 306 virtual int Add_Item(char const * text) {return(ListClass::Add_Item(text));}; 307 virtual int Add_Item(int text) {return(ListClass::Add_Item(text));}; 308 virtual char const * Current_Item(void) const {return(ListClass::Current_Item());}; 309 virtual char const * Get_Item(int index) const {return(ListClass::Get_Item(index));}; 310 }; 311 312 313 /*********************************************************************************************** 314 * EListClass::Draw_Entry -- Draws entry for expansion scenario. * 315 * * 316 * This overrides the normal list class draw action so that the scenario name will be * 317 * displayed along with the house name. * 318 * * 319 * INPUT: index -- The index of the entry that should be drawn. * 320 * * 321 * x,y -- Coordinate of upper left region to draw the entry into. * 322 * * 323 * width -- Width of region (pixels) to draw the entry. * 324 * * 325 * selected -- Is this entry considered selected? * 326 * * 327 * OUTPUT: none * 328 * * 329 * WARNINGS: none * 330 * * 331 * HISTORY: * 332 * 11/17/1995 JLB : Created. * 333 *=============================================================================================*/ 334 void EListClass::Draw_Entry(int index, int x, int y, int width, int selected) 335 { 336 char buffer[128]; 337 RemapControlType * scheme = GadgetClass::Get_Color_Scheme(); 338 339 int text = TXT_NONE; 340 if (Get_Object(index)->House == HOUSE_GOOD) { 341 text = TXT_ALLIES; 342 } else { 343 text = TXT_SOVIET; 344 } 345 sprintf(buffer, "%s: %s", Text_String(text), Get_Object(index)->Name); 346 347 TextPrintType flags = TextFlags; 348 349 if (selected) { 350 flags = flags | TPF_BRIGHT_COLOR; 351 LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, 1); 352 } else { 353 if (!(flags & TPF_USE_GRAD_PAL)) { 354 flags = flags | TPF_MEDIUM_COLOR; 355 } 356 } 357 358 #ifndef WIN32 359 Conquer_Clip_Text_Print(buffer, x, y, scheme, TBLACK, flags & ~(TPF_CENTER), width, Tabs); 360 #else 361 Conquer_Clip_Text_Print(buffer, x + 100, y, scheme, TBLACK, flags & ~(TPF_CENTER), width, Tabs); 362 #endif 363 } 364 365 #ifdef FIXIT_VERSION_3 366 bool Expansion_Dialog( bool bCounterstrike ) // If not bCounterstrike, then this was called for Aftermath. 367 #else 368 bool Expansion_Dialog(void) 369 #endif 370 { 371 GadgetClass * buttons = NULL; 372 373 #ifndef WIN32 374 TextButtonClass ok(200, TXT_OK, TPF_BUTTON, OPTION_X+40, OPTION_Y+OPTION_HEIGHT-15); 375 TextButtonClass cancel(201, TXT_CANCEL, TPF_BUTTON, OPTION_X+OPTION_WIDTH-85, OPTION_Y+OPTION_HEIGHT-15); 376 #else 377 TextButtonClass ok(200, TXT_OK, TPF_BUTTON, OPTION_X+40, OPTION_Y + OPTION_HEIGHT - 50 ); 378 TextButtonClass cancel(201, TXT_CANCEL, TPF_BUTTON, OPTION_X+OPTION_WIDTH-85, OPTION_Y + OPTION_HEIGHT - 50 ); 379 #endif 380 381 #ifndef WIN32 382 EListClass list(202, OPTION_X + 20, OPTION_Y+20, OPTION_WIDTH-40, OPTION_HEIGHT-40, TPF_BUTTON, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP")); 383 #else 384 EListClass list(202, OPTION_X+35, OPTION_Y + 30, OPTION_WIDTH-70, OPTION_HEIGHT - 85, TPF_BUTTON, MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP")); 385 386 #endif 387 buttons = &ok; 388 cancel.Add(*buttons); 389 list.Add(*buttons); 390 391 /* 392 ** Add in all the expansion scenarios. 393 */ 394 CCFileClass file; 395 char buffer[128], buffer2[128]; 396 char * sbuffer = (char*)_ShapeBuffer; 397 #ifdef FIXIT_CSII // checked - ajw 9/28/98 - Though disgusted. 398 for (int index = 20; index < (36+18); index++) { 399 #else 400 for (int index = 20; index < 36; index++) { 401 #endif 402 403 #ifndef CS_DEBUG 404 strcpy(buffer,ExpandNames[index - 20]); 405 strcpy(buffer2, ExpandNames[index - 20]); 406 #else 407 strcpy(buffer, TestNames2[index]); 408 strcpy(buffer2, TestNames2[index]); 409 #endif 410 if(buffer[0] == NULL) 411 break; 412 413 strcat(buffer, ".INI"); 414 strcat(buffer2, ".INI"); 415 Scen.Set_Scenario_Name(buffer); 416 Scen.Scenario = index; 417 file.Set_Name(buffer); 418 #ifdef FIXIT_VERSION_3 419 bool bOk; 420 if( index < 36 ) 421 bOk = bCounterstrike; 422 else 423 bOk = !bCounterstrike; 424 425 if( bOk && file.Is_Available() ) 426 { 427 #else // FIXIT_VERSION_3 428 if (file.Is_Available()) { 429 #endif // FIXIT_VERSION_3 430 EObjectClass * obj = new EObjectClass; 431 switch(buffer[2]){ 432 433 case 'G': 434 case 'g': 435 file.Read(sbuffer, 2000); 436 sbuffer[2000] = '\r'; 437 sbuffer[2000+1] = '\n'; 438 sbuffer[2000+2] = '\0'; 439 WWGetPrivateProfileString("Basic", "Name", "x", buffer, sizeof(buffer), sbuffer); 440 #if defined(GERMAN) || defined(FRENCH) 441 strcpy(obj->Name, XlatNames[index - ARRAYOFFSET]); 442 #else 443 strcpy(obj->Name, buffer); 444 #endif 445 // strcpy(obj->Name, buffer); 446 strcpy(obj->FullName, buffer2); 447 obj->House = HOUSE_GOOD; 448 obj->Scenario = index; 449 list.Add_Object(obj); 450 break; 451 452 case 'U': 453 case 'u': 454 file.Read(sbuffer, 2000); 455 sbuffer[2000] = '\r'; 456 sbuffer[2000+1] = '\n'; 457 sbuffer[2000+2] = '\0'; 458 WWGetPrivateProfileString("Basic", "Name", "x", buffer, sizeof(buffer), sbuffer); 459 #if defined(GERMAN) || defined(FRENCH) 460 strcpy(obj->Name, XlatNames[index - ARRAYOFFSET]); 461 #else 462 strcpy(obj->Name, buffer); 463 #endif 464 // strcpy(obj->Name, buffer); 465 strcpy(obj->FullName, buffer2); 466 obj->House = HOUSE_BAD; 467 obj->Scenario = index; 468 list.Add_Object(obj); 469 break; 470 471 472 default: 473 break; 474 } 475 } 476 } 477 478 Set_Logic_Page(SeenBuff); 479 bool recalc = true; 480 bool display = true; 481 bool process = true; 482 bool okval = true; 483 484 485 while (process) { 486 487 #ifdef WIN32 488 /* 489 ** If we have just received input focus again after running in the background then 490 ** we need to redraw. 491 */ 492 if (AllSurfaces.SurfacesRestored) { 493 AllSurfaces.SurfacesRestored=FALSE; 494 display = true; 495 } 496 #endif 497 498 Call_Back(); 499 500 if (display) { 501 display = false; 502 503 Hide_Mouse(); 504 505 /* 506 ** Load the background picture. 507 */ 508 Load_Title_Page(); 509 CCPalette.Set(); 510 511 Dialog_Box(OPTION_X, OPTION_Y, OPTION_WIDTH, OPTION_HEIGHT); 512 #ifdef FIXIT_VERSION_3 513 if (bCounterstrike) 514 { 515 //PG Draw_Caption( TXT_WOL_CS_MISSIONS, OPTION_X, OPTION_Y, OPTION_WIDTH); 516 } 517 else 518 { 519 //PG Draw_Caption( TXT_WOL_AM_MISSIONS, OPTION_X, OPTION_Y, OPTION_WIDTH); 520 } 521 #else 522 Draw_Caption(TXT_NEW_MISSIONS, OPTION_X, OPTION_Y, OPTION_WIDTH); 523 #endif 524 buttons->Draw_All(); 525 Show_Mouse(); 526 } 527 528 KeyNumType input = buttons->Input(); 529 switch (input) { 530 case 200|KN_BUTTON: 531 Whom = list.Current_Object()->House; 532 Scen.Scenario = list.Current_Object()->Scenario; 533 strcpy(Scen.ScenarioName, list.Current_Object()->FullName); 534 process = false; 535 okval = true; 536 break; 537 538 case KN_ESC: 539 case 201|KN_BUTTON: 540 process = false; 541 okval = false; 542 break; 543 544 case (KN_RETURN): 545 Whom = list.Current_Object()->House; 546 Scen.Scenario = list.Current_Object()->Scenario; 547 strcpy(Scen.ScenarioName, list.Current_Object()->FullName); 548 process = false; 549 okval = true; 550 break; 551 552 default: 553 break; 554 } 555 } 556 557 /* 558 ** Free up the allocations for the text lines in the list box. 559 */ 560 for (int index = 0; index < list.Count(); index++) { 561 delete list.Get_Object(index); 562 } 563 564 return(okval); 565 566 } 567