SCORE.CPP (65824B)
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/SCORE.CPP 3 3/14/97 12:02a 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 : SCORE.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : April 19, 1994 * 28 * * 29 * Last Update : May 3, 1995 [BWG] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * Call_Back_Delay -- Combines Call_Back() and Delay() functions * 34 * Draw_Bar_Graphs -- Draw "Casualties" bar graphs * 35 * Draw_InfantryMan -- Draw one guy in score screen, update animation * 36 * Draw_Infantrymen -- Draw all the guys on the score screen * 37 * New_Infantry_Anim -- Start up a new animation for one of the infantrymen * 38 * ScoreClass::Count_Up_Print -- Prints a number (up to its max) into a string, cleanly * 39 * ScoreClass::DO_GDI_GRAPH -- Show # of people or buildings killed on GDI score screen * 40 * ScoreClass::Delay -- Pauses waiting for keypress. * 41 * ScoreClass::Presentation -- Main routine to display score screen. * 42 * ScoreClass::Print_Graph_Title -- Prints title on score screen. * 43 * ScoreClass::Print_Minutes -- Print out hours/minutes up to max * 44 * ScoreClass::Pulse_Bar_Graph -- Pulses the bargraph color. * 45 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 46 47 #ifndef WIN32 48 extern short StreamLowImpact; 49 #endif 50 51 #include "function.h" 52 53 #define SCORETEXT_X 184 54 #define SCORETEXT_Y 8 55 #define CASUALTY_Y 88 56 #define BUILDING_X 256 57 #define BUILDING_Y 128 58 #define BARGRAPH_X 266 59 #define MAX_BAR_X 318 // max possible is 319 because of bar's right shadow 60 #define SIZEGBAR 118 61 #define HALLFAME_X 11 62 #define HALLFAME_Y 120 63 64 #define MULTISCOREX 30 65 66 #define TEDIT_FAME 1 67 #define NUMINFANTRYMEN 10 68 #define NUMFAMENAMES 7 69 #define MAX_FAMENAME_LENGTH 11 70 71 #ifndef WIN32 72 extern short StreamLowImpact; 73 #endif //WIN32 74 75 GraphicBufferClass *PseudoSeenBuff; 76 77 struct InfantryAnim { 78 int xpos; 79 int ypos; 80 void const *shapefile; 81 void const *remap; 82 int anim; 83 int stage; 84 char delay; 85 InfantryTypeClass const *Class; 86 } InfantryMan[NUMINFANTRYMEN]; 87 void Draw_InfantryMen(void); 88 void Draw_InfantryMan(int index); 89 void New_Infantry_Anim(int index, int anim); 90 void Draw_Bar_Graphs(int i, int gkilled, int nkilled); 91 void Animate_Cursor(int pos, int ypos); 92 void Animate_Score_Objs(void); 93 void Cycle_Wait_Click(bool cycle=true); 94 95 #ifdef FIXIT_SCORE_CRASH 96 //void Disable_Uncompressed_Shapes (void); 97 //void Enable_Uncompressed_Shapes (void); 98 #endif //FIXIT 99 100 void const * Beepy6; 101 int ControlQ; // cheat key to skip past score/mapsel screens 102 bool StillUpdating; 103 104 #ifdef WIN32 105 char *ScreenNames[2]={"ALIBACKH.PCX", "SOVBACKH.PCX"}; 106 #else 107 char *ScreenNames[2]={"ALI-TRAN.WSA", "SOV-TRAN.WSA"}; 108 #endif 109 110 //#ifdef WIN32 111 //TextBlitClass BlitList; 112 //#endif 113 114 115 struct Fame { 116 char name[MAX_FAMENAME_LENGTH]; 117 int score; 118 int level; 119 int side; 120 }; 121 122 ScoreAnimClass *ScoreObjs[MAXSCOREOBJS]; 123 124 125 ScoreAnimClass::ScoreAnimClass(int x, int y, void const * data) 126 { 127 XPos = x * RESFACTOR; 128 YPos = y * RESFACTOR; 129 Timer = 0; 130 DataPtr = data; 131 } 132 133 134 ScoreTimeClass::ScoreTimeClass(int xpos, int ypos, void const * data, int maxval, int xtimer) : 135 ScoreAnimClass(xpos, ypos, data) 136 { 137 Stage = 0; 138 MaxStage = maxval; 139 TimerReset = xtimer; 140 } 141 142 void ScoreTimeClass::Update(void) 143 { 144 #ifdef WIN32 145 GraphicViewPortClass *oldpage; 146 #else 147 GraphicBufferClass *oldpage; 148 #endif 149 if (!Timer) { 150 Timer = TimerReset; 151 if (++Stage >= MaxStage) Stage = 0; 152 oldpage = LogicPage; 153 Set_Logic_Page(SeenBuff); 154 CC_Draw_Shape(DataPtr, Stage, XPos, YPos, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 155 #ifdef WIN32 156 Set_Logic_Page(*PseudoSeenBuff); 157 CC_Draw_Shape(DataPtr, Stage, XPos, YPos, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 158 #endif 159 Set_Logic_Page(oldpage); 160 } 161 } 162 163 ScoreCredsClass::ScoreCredsClass(int xpos, int ypos, void const * data, int maxval, int xtimer) : 164 ScoreAnimClass(xpos, ypos, data) 165 { 166 Stage = 0; 167 MaxStage = maxval; 168 TimerReset = xtimer; 169 Clock1 = MFCD::Retrieve("CLOCK1.AUD"); 170 CashTurn = MFCD::Retrieve("CASHTURN.AUD"); 171 } 172 173 174 void ScoreCredsClass::Update(void) 175 { 176 #ifdef WIN32 177 GraphicViewPortClass *oldpage; 178 #else 179 GraphicBufferClass *oldpage; 180 #endif 181 if (!Timer) { 182 Timer = TimerReset; 183 if (++Stage >= MaxStage) Stage = 0; 184 oldpage = LogicPage; 185 Set_Logic_Page(SeenBuff); 186 #ifdef WIN32 187 Play_Sample(Clock1, 255, Options.Normalize_Volume(130)); 188 #else 189 Play_Sample(Clock1, 255, Options.Normalize_Volume(50)); 190 #endif 191 CC_Draw_Shape(DataPtr, Stage, XPos, YPos, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 192 #ifdef WIN32 193 Set_Logic_Page(*PseudoSeenBuff); 194 CC_Draw_Shape(DataPtr, Stage, XPos, YPos, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 195 #endif 196 Set_Logic_Page(oldpage); 197 } 198 } 199 200 201 ScorePrintClass::ScorePrintClass(int string, int xpos, int ypos, void const * palette, int background) : 202 ScoreAnimClass(xpos, ypos, Text_String(string)) 203 { 204 Background = background; 205 PrimaryPalette = palette; 206 Stage = 0; 207 } 208 209 210 ScorePrintClass::ScorePrintClass(void const * string, int xpos, int ypos, void const * palette, int background) : 211 ScoreAnimClass(xpos, ypos, string) 212 { 213 Background = background; 214 PrimaryPalette = palette; 215 Stage = 0; 216 } 217 218 219 void ScorePrintClass::Update(void) 220 { 221 static char localstr[2]={0,0}; 222 static char _whitepal[]={0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F}; 223 224 if (Stage && (((char *)DataPtr)[Stage-1]==0) ) { 225 for (int i = 0; i < MAXSCOREOBJS; i++) { 226 if (ScoreObjs[i] == this) { 227 ScoreObjs[i] = 0; 228 } 229 } 230 delete this; 231 return; 232 } 233 234 #ifdef WIN32 235 StillUpdating = true; 236 #endif 237 if (!Timer) { 238 Timer = 1; 239 240 int pos = XPos+(Stage*(6*RESFACTOR)); 241 // print the letter properly 242 if (Stage) { 243 Set_Font_Palette(PrimaryPalette); 244 localstr[0]=((char *)DataPtr)[Stage-1]; 245 HidPage.Print(localstr, pos-6*RESFACTOR, YPos, TBLACK, TBLACK); 246 HidPage.Blit(SeenPage, pos-6*RESFACTOR, YPos-1*RESFACTOR, pos-6*RESFACTOR, YPos-1*RESFACTOR, 7*RESFACTOR, 8*RESFACTOR); 247 #ifdef WIN32 248 HidPage.Blit(*PseudoSeenBuff, pos-6*RESFACTOR, YPos-1*RESFACTOR, pos-6*RESFACTOR, YPos-1*RESFACTOR, 7*RESFACTOR, 8*RESFACTOR); 249 PseudoSeenBuff->Print(localstr, pos-6*RESFACTOR, YPos, TBLACK, TBLACK); 250 #endif 251 } 252 if (((char *)DataPtr)[Stage]) { 253 localstr[0]=((char *)DataPtr)[Stage]; 254 Set_Font_Palette(_whitepal); 255 SeenPage.Print(localstr, pos, YPos-1, TBLACK, TBLACK); 256 SeenPage.Print(localstr, pos, YPos+1, TBLACK, TBLACK); 257 SeenPage.Print(localstr, pos+1, YPos , TBLACK, TBLACK); 258 #ifdef WIN32 259 PseudoSeenBuff->Print(localstr, pos, YPos-1, TBLACK, TBLACK); 260 PseudoSeenBuff->Print(localstr, pos, YPos+1, TBLACK, TBLACK); 261 PseudoSeenBuff->Print(localstr, pos+1, YPos , TBLACK, TBLACK); 262 #endif 263 } 264 Stage++; 265 } 266 } 267 268 269 ScoreScaleClass::ScoreScaleClass(void const * string, int xpos, int ypos, char const palette[]) : 270 ScoreAnimClass(xpos, ypos, string) 271 { 272 Palette = &palette[0]; 273 #ifdef WIN32 274 Stage = 0; 275 #else 276 Stage = 5; 277 #endif 278 } 279 280 281 void ScoreScaleClass::Update(void) 282 { 283 static int _destx[]={0,80,107,134,180,228}; 284 static int _destw[]={6,20, 30, 40, 60, 80}; 285 286 /* 287 ** Restore the background for the scaled-up letter 288 */ 289 if (!Timer) { 290 Timer = 1; 291 #ifndef WIN32 292 if (Stage != 5) { 293 int destx = _destx[Stage+1]*RESFACTOR; 294 int destw = _destw[Stage+1]*RESFACTOR; 295 HidPage.Blit(SeenPage, destx, YPos, destx, YPos, (destx + destw) <= 320 * RESFACTOR ? destw : (320 * RESFACTOR) - destx, (YPos + destw) <= 200 * RESFACTOR ? destw : (200 * RESFACTOR) - YPos); 296 } 297 #endif 298 if (Stage) { 299 Set_Font_Palette(Palette); 300 HidPage.Fill_Rect(0, 0, 7*RESFACTOR, 7*RESFACTOR, TBLACK); 301 HidPage.Print((char *)DataPtr, 0, 0, TBLACK, TBLACK); 302 HidPage.Scale(SeenPage, 0, 0, _destx[Stage]*RESFACTOR, YPos, 5*RESFACTOR, 6*RESFACTOR, _destw[Stage]*RESFACTOR, _destw[Stage]*RESFACTOR, true); 303 Stage--; 304 } else { 305 Set_Font_Palette(Palette); 306 for (int i = 0; i < MAXSCOREOBJS; i++) { 307 if (ScoreObjs[i]==this) ScoreObjs[i] = 0; 308 } 309 HidPage.Print((char *)DataPtr, XPos, YPos, TBLACK, TBLACK); 310 HidPage.Blit(SeenPage, XPos, YPos, XPos, YPos, 6*RESFACTOR, 6*RESFACTOR); 311 #ifdef WIN32 312 HidPage.Blit(*PseudoSeenBuff, XPos, YPos, XPos, YPos, 6*RESFACTOR, 6*RESFACTOR); 313 #endif 314 delete this; 315 return; 316 } 317 } 318 } 319 320 int Alloc_Object(ScoreAnimClass *obj) 321 { 322 int i,ret; 323 324 for (i = ret = 0; i < MAXSCOREOBJS; i++) { 325 if (!ScoreObjs[i]) { 326 ScoreObjs[i] = obj; 327 ret = i; 328 break; 329 } 330 } 331 return(ret); 332 } 333 334 335 336 /*********************************************************************************************** 337 * ScoreClass::Presentation -- Main routine to display score screen. * 338 * * 339 * This is the main routine that displays the score screen graphics. * 340 * It gets called at the end of each scenario and is used to present * 341 * the results and a rating of the player's battle. * 342 * * 343 * INPUT: none * 344 * * 345 * OUTPUT: none * 346 * * 347 * WARNINGS: none * 348 * * 349 * HISTORY: * 350 * 05/02/1994 : Created. * 351 *=============================================================================================*/ 352 static unsigned char const _bluepal[]={0xC0,0xC1,0xC1,0xC3,0xC2,0xC5,0xC3,0xC7,0xC4,0xC9,0xCA,0xCB,0xCC,0xCD,0xC0,0xCF}; 353 static unsigned char const _greenpal[]={0x70,0x71,0x7C,0x73,0x7D,0x75,0x7E,0x77,0x7F,0x79,0x7A,0x7B,0x7C,0x7D,0x7C,0x7F}; 354 static unsigned char const _redpal[]={0xD0,0xD1,0xD7,0xD3,0xD9,0xD5,0xDA,0xD7,0xDB,0xD9,0xDA,0xDB,0xDC,0xDD,0xD6,0xDF}; 355 static unsigned char const _yellowpal[]={0x0,0x0,0xEC,0x0,0xEB,0x0,0xEA,0x0,0xE9,0x0,0x0,0x0,0x0,0x0,0xED,0x0}; 356 void ScoreClass::Presentation(void) 357 { 358 #if (0)//PG 359 #ifdef WIN32 360 // if (Keyboard != NULL) return; 361 #endif 362 static int const _casuax[2]={144,150}; 363 static int const _casuay[2]={ 78, 78}; 364 static int const _gditxy[2]={ 90, 90}; 365 366 #if defined(FRENCH) || defined(GERMAN) 367 static int const _gditxx[2]={130,150}; 368 static int const _nodtxx[2]={130,150}; 369 #else 370 static int const _gditxx[2]={135,150}; 371 static int const _nodtxx[2]={135,150}; 372 #endif 373 static int const _nodtxy[2]={102,102}; 374 static int const _bldggy[2]={138,138}; 375 static int const _bldgny[2]={150,150}; 376 377 #ifdef WIN32 378 #ifdef FIXIT_SCORE_CRASH 379 /* 380 ** Fix for the score screen crash due to uncompressed shape buffer overflow. 381 */ 382 Disable_Uncompressed_Shapes(); 383 #endif //FIXIT 384 PseudoSeenBuff = new GraphicBufferClass(SeenBuff.Get_Width(),SeenBuff.Get_Height(),(void*)NULL); 385 #endif 386 int i; 387 void const * yellowptr; 388 void const * redptr; 389 CCFileClass file(FAME_FILE_NAME); 390 struct Fame hallfame[NUMFAMENAMES]; 391 void *oldfont; 392 int oldfontxspacing = FontXSpacing; 393 int house = (PlayerPtr->Class->House == HOUSE_USSR || PlayerPtr->Class->House == HOUSE_UKRAINE); // 0 or 1 394 #ifdef WIN32 395 char inter_pal[15]; 396 sprintf(inter_pal, "SCORPAL1.PAL"); 397 #endif 398 399 ControlQ = 0; 400 FontXSpacing = 0; 401 Map.Override_Mouse_Shape(MOUSE_NORMAL); 402 Theme.Queue_Song(THEME_SCORE); 403 404 #ifdef WIN32 405 VisiblePage.Clear(); 406 SysMemPage.Clear(); 407 WWMouse->Erase_Mouse(&HidPage, TRUE); 408 HiddenPage.Clear(); 409 Set_Logic_Page(SysMemPage); 410 #else 411 SeenPage.Clear(); 412 HidPage.Clear(); 413 Set_Logic_Page(HidPage); 414 #endif 415 BlackPalette.Set(); 416 417 418 void const * country4 = MFCD::Retrieve("COUNTRY4.AUD"); 419 void const * sfx4 = MFCD::Retrieve("SFX4.AUD"); 420 Beepy6 = MFCD::Retrieve("BEEPY6.AUD"); 421 422 /* 423 ** Load the background for the score screen 424 */ 425 #ifndef WIN32 426 void *anim = Open_Animation(ScreenNames[house], NULL, 0L, (WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE), ScorePalette); 427 #endif 428 429 unsigned minutes = (unsigned)((ElapsedTime / (long)TIMER_MINUTE))+1; 430 431 // Load up the shapes for the Nod score screen 432 #ifdef WIN32 433 yellowptr = MFCD::Retrieve("BAR3BHR.SHP"); 434 redptr = MFCD::Retrieve("BAR3RHR.SHP"); 435 #else 436 if (!house) { 437 yellowptr = MFCD::Retrieve("BAR3BLU.SHP"); 438 redptr = MFCD::Retrieve("BAR3RED.SHP"); 439 } 440 #endif 441 442 /* Change to the six-point font for Text_Print */ 443 oldfont = Set_Font(ScoreFontPtr); 444 Call_Back(); 445 446 /* --- Now display the background animation --- */ 447 Hide_Mouse(); 448 #ifdef WIN32 449 Load_Title_Screen(ScreenNames[house], &HidPage, ScorePalette); 450 Increase_Palette_Luminance (ScorePalette , 30, 30, 30, 63); 451 HidPage.Blit(SeenPage); 452 HidPage.Blit(*PseudoSeenBuff); 453 #else 454 Animate_Frame(anim, HidPage, 1); 455 HidPage.Blit(SeenPage); 456 #endif 457 ScorePalette.Set(FADE_PALETTE_FAST, Call_Back); 458 #ifdef WIN32 459 Play_Sample(country4, 255, Options.Normalize_Volume(150)); 460 #else 461 Play_Sample(country4, 255, Options.Normalize_Volume(60)); 462 #endif 463 464 #ifndef WIN32 465 int frame = 1; 466 StreamLowImpact = true; 467 while (frame < Get_Animation_Frame_Count(anim)) { 468 Animate_Frame(anim, SeenPage, frame++); 469 Call_Back_Delay(2); 470 } 471 StreamLowImpact = false; 472 Call_Back(); 473 Close_Animation(anim); 474 #endif 475 476 /* 477 ** Background's up, so now load various shapes and animations 478 */ 479 #ifdef WIN32 480 void const * timeshape = MFCD::Retrieve("TIMEHR.SHP"); 481 void const * hiscore1shape = MFCD::Retrieve("HISC1-HR.SHP"); 482 void const * hiscore2shape = MFCD::Retrieve("HISC2-HR.SHP"); 483 #else 484 void const * timeshape = MFCD::Retrieve("TIME.SHP"); 485 void const * hiscore1shape = MFCD::Retrieve("HISCORE1.SHP"); 486 void const * hiscore2shape = MFCD::Retrieve("HISCORE2.SHP"); 487 #endif 488 ScoreObjs[0] = new ScoreTimeClass(238, 2, timeshape, 30, 4); 489 ScoreObjs[1] = new ScoreTimeClass(4, 89, hiscore1shape, 10, 4); 490 ScoreObjs[2] = new ScoreTimeClass(4, 180, hiscore2shape, 10, 4); 491 492 /* Now display the stuff */ 493 #ifdef WIN32 494 #else 495 SeenPage.Blit(HidPage); 496 #endif 497 Set_Logic_Page(SeenBuff); 498 499 500 #ifdef FRENCH 501 Alloc_Object(new ScorePrintClass(TXT_SCORE_TIME, 198, 9, _greenpal)); 502 #else 503 Alloc_Object(new ScorePrintClass(TXT_SCORE_TIME, 204, 9, _greenpal)); 504 #endif 505 Alloc_Object(new ScorePrintClass(TXT_SCORE_LEAD, 164, 26, _greenpal)); 506 Alloc_Object(new ScorePrintClass(TXT_SCORE_EFFI, 164, 38, _greenpal)); 507 Alloc_Object(new ScorePrintClass(TXT_SCORE_TOTA, 164, 50, _greenpal)); 508 #ifdef WIN32 509 Play_Sample(sfx4, 255, Options.Normalize_Volume(150)); 510 #else 511 Play_Sample(sfx4, 255, Options.Normalize_Volume(60)); 512 #endif 513 Call_Back_Delay(13); 514 515 int scorecounter = 0; 516 517 Keyboard->Clear(); 518 519 /* 520 ** Determine leadership rating. 521 */ 522 int leadership = 0; 523 for (int index = 0; index < Logic.Count(); index++) { 524 ObjectClass * object = Logic[index]; 525 HousesType owner = object->Owner(); 526 if ( (house) && (owner == HOUSE_USSR || owner == HOUSE_BAD || owner == HOUSE_UKRAINE) ) { 527 leadership++; 528 } else { 529 if ( (!house) && (object->Owner() == HOUSE_GREECE) ) { 530 leadership++; 531 } 532 } 533 } 534 int uspoints = 0; 535 536 for (HousesType hous = HOUSE_SPAIN; hous <= HOUSE_BAD; hous++) { 537 HouseClass *hows = HouseClass::As_Pointer(hous); 538 if (hous == HOUSE_USSR || hous == HOUSE_BAD || hous == HOUSE_UKRAINE) { 539 NKilled += hows->UnitsLost; 540 NBKilled += hows->BuildingsLost; 541 } else { 542 GKilled += hows->UnitsLost; 543 GBKilled += hows->BuildingsLost; 544 } 545 if (PlayerPtr->Is_Ally(hous) ) { 546 uspoints += hows->PointTotal; 547 } 548 } 549 // if(uspoints < 0) uspoints = 0; 550 // uspoints += 1000; //BG 1000 bonus points for winning mission 551 552 /* 553 ** Bias the base score upward according to the difficulty level. 554 */ 555 switch (PlayerPtr->Difficulty) { 556 case DIFF_EASY: 557 uspoints += 500; 558 break; 559 560 case DIFF_NORMAL: 561 uspoints += 1500; 562 break; 563 564 case DIFF_HARD: 565 uspoints += 3500; 566 break; 567 } 568 569 570 if (!leadership) leadership++; 571 leadership = 100*fixed(leadership, (house ? NKilled+NBKilled+leadership : GKilled+GBKilled+leadership)); 572 leadership = min(150,leadership); 573 574 /* 575 ** Determine economy rating. 576 */ 577 int init = PlayerPtr->Control.InitialCredits; 578 int cred = PlayerPtr->Available_Money(); 579 580 int economy = 100*fixed((unsigned)PlayerPtr->Available_Money()+1+PlayerPtr->StolenBuildingsCredits, PlayerPtr->HarvestedCredits + (unsigned)PlayerPtr->Control.InitialCredits+1); 581 economy=min(economy,150); 582 583 int total = ((uspoints * leadership) / 100) + ((uspoints * economy) / 100); 584 if (total < -9999) total = -9999; 585 total = min(total, 99999); 586 587 Keyboard->Clear(); 588 for (i = 0; i <= 130; i++) { 589 Set_Font_Palette(_greenpal); 590 int lead = (leadership * i) / 100; 591 Count_Up_Print("%3d%%", lead, leadership, 244, 26); 592 if (i>=30) { 593 int econo = (economy * (i-30)) / 100; 594 Count_Up_Print("%3d%%", econo, economy, 244, 38); 595 } 596 Print_Minutes(minutes); 597 Call_Back_Delay(1); 598 #ifdef WIN32 599 Play_Sample(Beepy6, 255, Options.Normalize_Volume(100)); 600 #else 601 Play_Sample(Beepy6, 255, Options.Normalize_Volume(40)); 602 #endif 603 if ( (i >= 30) && (i >= leadership) && ((i-30) >= economy) ) break; 604 //BG if (Keyboard->Check()) break; 605 } 606 Count_Up_Print("%3d%%", leadership, leadership, 244, 26); 607 Count_Up_Print("%3d%%", economy, economy, 244, 38); 608 609 char buffer[16]; 610 sprintf(buffer, "x %5d",uspoints); 611 Alloc_Object(new ScorePrintClass(buffer, 274, 26, _greenpal)); 612 Alloc_Object(new ScorePrintClass(buffer, 274, 38, _greenpal)); 613 Call_Back_Delay(8); 614 SeenBuff.Draw_Line(274*RESFACTOR, 48*RESFACTOR, 313*RESFACTOR, 48*RESFACTOR, WHITE); 615 Call_Back_Delay(1); 616 SeenBuff.Draw_Line(274*RESFACTOR, 48*RESFACTOR, 313*RESFACTOR, 48*RESFACTOR, GREEN); 617 618 sprintf(buffer,"%5d", total); 619 Alloc_Object(new ScorePrintClass(buffer, 286, 50, _greenpal)); 620 621 //BG if (!Keyboard->Check()) { 622 Call_Back_Delay(60); 623 //BG } 624 625 if (house) Show_Credits(house, _greenpal); 626 627 /*BG if (!Keyboard->Check()) */ Call_Back_Delay(60); 628 629 /* 630 ** Show stats on # of units killed 631 */ 632 Set_Logic_Page(SeenBuff); 633 #ifdef WIN32 634 Play_Sample(sfx4, 255, Options.Normalize_Volume(150)); 635 #else 636 Play_Sample(sfx4, 255, Options.Normalize_Volume(60)); 637 #endif 638 int indx = house; 639 #ifdef WIN32 640 indx = 0; 641 #endif 642 Alloc_Object(new ScorePrintClass(TXT_SCORE_CASU, _casuax[indx], _casuay[indx], _greenpal)); 643 Call_Back_Delay(9); 644 if (house) { 645 Alloc_Object(new ScorePrintClass(TXT_SOVIET, _nodtxx[indx], _gditxy[indx], _redpal)); 646 Alloc_Object(new ScorePrintClass(TXT_ALLIES, _gditxx[indx], _nodtxy[indx], _bluepal)); 647 } else { 648 Alloc_Object(new ScorePrintClass(TXT_ALLIES, _gditxx[indx], _gditxy[indx], _bluepal)); 649 Alloc_Object(new ScorePrintClass(TXT_SOVIET, _nodtxx[indx], _nodtxy[indx], _redpal)); 650 } 651 Call_Back_Delay(6); 652 653 Set_Font_Palette(_redpal); 654 #ifdef WIN32 655 Do_GDI_Graph(yellowptr, redptr, GKilled + CKilled, NKilled, 89); 656 #else 657 if (house) { 658 Do_Nod_Casualties_Graph(); 659 } else { 660 Do_GDI_Graph(yellowptr, redptr, GKilled + CKilled, NKilled, 89); 661 } 662 #endif 663 664 Set_Logic_Page(SeenBuff); 665 666 /* 667 ** Print out stats on buildings destroyed 668 */ 669 #ifdef WIN32 670 Play_Sample(sfx4, 255, Options.Normalize_Volume(150)); 671 #else 672 Play_Sample(sfx4, 255, Options.Normalize_Volume(60)); 673 #endif 674 #ifdef WIN32 675 Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL, 144, 126, _greenpal)); 676 Call_Back_Delay(9); 677 #else 678 if (!house) { 679 Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL, 144, 126, _greenpal)); 680 Call_Back_Delay(9); 681 } else { 682 Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL1, 150, 118, _greenpal)); 683 Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL2, 150, 126, _greenpal)); 684 Call_Back_Delay(13); 685 } 686 #endif 687 if(house) { 688 Alloc_Object(new ScorePrintClass(TXT_SOVIET, _gditxx[indx], _bldggy[indx], _redpal)); 689 Alloc_Object(new ScorePrintClass(TXT_ALLIES, _gditxx[indx], _bldgny[indx], _bluepal)); 690 } else { 691 Alloc_Object(new ScorePrintClass(TXT_ALLIES, _gditxx[indx], _bldggy[indx], _bluepal)); 692 Alloc_Object(new ScorePrintClass(TXT_SOVIET, _gditxx[indx], _bldgny[indx], _redpal)); 693 } 694 Call_Back_Delay(7); 695 #ifdef WIN32 696 Do_GDI_Graph(yellowptr, redptr, GBKilled + CBKilled, NBKilled, 137); 697 #else 698 if (house) { 699 Call_Back_Delay(6); 700 Set_Font_Palette(_greenpal); 701 Do_Nod_Buildings_Graph(); 702 } else { 703 Do_GDI_Graph(yellowptr, redptr, GBKilled + CBKilled, NBKilled, 137); 704 } 705 #endif 706 707 #ifdef WIN32 708 // Wait for text printing to complete 709 while (StillUpdating) { 710 Call_Back_Delay(1); 711 } 712 #endif 713 714 Keyboard->Clear(); 715 716 if (!house) Show_Credits(house, _greenpal); 717 /* 718 ** Hall of fame display and processing 719 */ 720 #ifdef WIN32 721 Play_Sample(sfx4, 255, Options.Normalize_Volume(150)); 722 #else 723 Play_Sample(sfx4, 255, Options.Normalize_Volume(60)); 724 #endif 725 Alloc_Object(new ScorePrintClass(TXT_SCORE_TOP, 28, 110, _greenpal)); 726 Call_Back_Delay(9); 727 728 /* 729 ** First check for the existence of the file, and if there isn't one, 730 ** make a new one filled with blanks. 731 */ 732 if (!file.Is_Available()) { 733 734 // hall of fame doesn't exist, so blank it out & write it 735 file.Open(WRITE); 736 737 for (i = 0; i < NUMFAMENAMES; i++) { 738 hallfame[i].name[0] = 739 hallfame[i].score = 740 hallfame[i].level = 0; 741 hallfame[i].side = 0; 742 file.Write(&hallfame[i], sizeof(struct Fame)); 743 } 744 745 file.Close(); 746 } 747 748 file.Open(READ); 749 for (i = 0; i < NUMFAMENAMES; i++) { 750 file.Read(&hallfame[i], sizeof(struct Fame)); 751 } 752 file.Close(); 753 754 /* 755 ** If the player's score is good enough to bump someone off the list, 756 ** remove their data, move everyone down a notch, and set index = where 757 ** their info goes 758 */ 759 if (hallfame[NUMFAMENAMES-1].score >= total) 760 hallfame[NUMFAMENAMES-1].score = 0; 761 int index; 762 for (index = 0; index < NUMFAMENAMES; index++) { 763 if (total > hallfame[index].score) { 764 if (index < (NUMFAMENAMES-1)) for (i = (NUMFAMENAMES-1); i > index; i--) hallfame[i] = hallfame[i-1]; 765 hallfame[index].score = total; 766 hallfame[index].level = Scen.Scenario; 767 hallfame[index].name[0] = 0; // blank out the name 768 hallfame[index].side = house; 769 break; 770 } 771 } 772 773 /* 774 ** Now display the hall of fame 775 */ 776 Set_Logic_Page(SeenBuff); 777 778 #ifdef WIN32 779 char maststr[NUMFAMENAMES*32]; 780 #endif 781 char const *pal; 782 for (i = 0; i < NUMFAMENAMES; i++) { 783 pal = hallfame[i].side ? _redpal : _bluepal; 784 Alloc_Object(new ScorePrintClass(hallfame[i].name, HALLFAME_X, HALLFAME_Y + (i*8), pal)); 785 if (hallfame[i].score) { 786 #ifdef WIN32 787 char *str = maststr + i*32; 788 #else 789 char *str = (char *)(HidPage.Get_Buffer()) + i*32; 790 #endif 791 sprintf(str, "%d", hallfame[i].score); 792 Alloc_Object(new ScorePrintClass(str, HALLFAME_X+(6*14), HALLFAME_Y + (i*8), pal, BLACK)); 793 if (hallfame[i].level < 20) { 794 sprintf(str+16, "%d", hallfame[i].level); 795 } else { 796 strcpy(str+16, "**"); 797 } 798 Alloc_Object(new ScorePrintClass(str+16, HALLFAME_X+(6*11), HALLFAME_Y + (i*8), pal, BLACK)); 799 Call_Back_Delay(13); 800 } 801 } 802 #ifdef WIN32 803 // Wait for text printing to complete 804 while (StillUpdating) { 805 Call_Back_Delay(1); 806 } 807 #endif 808 /* 809 ** If the player's on the hall of fame, have him enter his name now 810 */ 811 Keyboard->Clear(); 812 813 if (index < NUMFAMENAMES) { 814 pal = hallfame[index].side ? _redpal : _bluepal; 815 Input_Name(hallfame[index].name, HALLFAME_X, HALLFAME_Y + (index*8), pal); 816 817 file.Open(WRITE); 818 for (i = 0; i < NUMFAMENAMES; i++) { 819 file.Write(&hallfame[i], sizeof(struct Fame)); 820 } 821 file.Close(); 822 } else { 823 Alloc_Object(new ScorePrintClass(TXT_CLICK_CONTINUE, 149, 190, _yellowpal)); 824 ControlQ = false; 825 Cycle_Wait_Click(); 826 } 827 828 Keyboard->Clear(); 829 830 /* get rid of all the animating objects */ 831 for (i = 0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) { 832 delete ScoreObjs[i]; 833 ScoreObjs[i] = 0; 834 } 835 BlackPalette.Set(FADE_PALETTE_FAST, NULL); 836 #ifdef WIN32 837 VisiblePage.Clear(); 838 #else 839 SeenPage.Clear(); 840 #endif 841 Show_Mouse(); 842 // Map_Selection(); 843 // Scen.ScenVar = SCEN_VAR_A; 844 // Scen.ScenDir = SCEN_DIR_EAST; 845 846 Theme.Queue_Song(THEME_NONE); 847 848 BlackPalette.Set(FADE_PALETTE_FAST, NULL); 849 #ifdef WIN32 850 VisiblePage.Clear(); 851 #else 852 SeenPage.Clear(); 853 #endif 854 GamePalette.Set(); 855 856 Set_Font(oldfont); 857 FontXSpacing = oldfontxspacing; 858 ControlQ = 0; 859 860 #ifdef WIN32 861 delete PseudoSeenBuff; 862 #ifdef FIXIT_SCORE_CRASH 863 /* 864 ** Fix for the score screen crash due to uncompressed shape buffer overflow. 865 */ 866 Enable_Uncompressed_Shapes(); 867 #endif //FIXIT 868 869 #endif 870 #endif 871 } 872 873 874 void Cycle_Wait_Click(bool cycle) 875 { 876 int counter = 0; 877 int minclicks = 20; 878 unsigned long timingtime = TickCount; 879 //PG SerialPacketType sendpacket; 880 //PG SerialPacketType receivepacket; 881 //PG int packetlen; 882 883 884 Keyboard->Clear(); 885 while (minclicks || (!Keyboard->Check() && !ControlQ) ) { 886 #if (0) //PG 887 if (Session.Type == GAME_NULL_MODEM || 888 Session.Type == GAME_MODEM) { 889 890 // 891 // send a timing packet if enough time has gone by. 892 // 893 if ( (TickCount - timingtime) > PACKET_TIMING_TIMEOUT) { 894 memset (&sendpacket, 0, sizeof(SerialPacketType)); 895 sendpacket.Command = SERIAL_SCORE_SCREEN; 896 sendpacket.ScenarioInfo.ResponseTime = NullModem.Response_Time(); 897 sendpacket.ID = Session.ModemType; 898 899 NullModem.Send_Message (&sendpacket, sizeof(sendpacket), 0); 900 timingtime = TickCount; 901 } 902 903 if (NullModem.Get_Message (&receivepacket, &packetlen) > 0) { 904 // throw packet away 905 packetlen = packetlen; 906 } 907 908 NullModem.Service(); 909 } 910 #endif 911 Call_Back_Delay(1); 912 if (minclicks) { 913 minclicks--; 914 Keyboard->Clear(); 915 } 916 917 if(cycle) { 918 counter = ((++counter) & 7); 919 if (counter == 0 && Options.IsPaletteScroll) { 920 RGBClass rgb = ScorePalette[233]; 921 for (int i = 233; i < 237; i++) { 922 ScorePalette[i] = ScorePalette[i+1]; 923 } 924 ScorePalette[237] = rgb; 925 ScorePalette.Set(); 926 } 927 } 928 } 929 Keyboard->Clear(); 930 } 931 932 void ScoreClass::Do_Nod_Buildings_Graph(void) 933 { 934 int shapenum; 935 InfantryTypeClass const *ramboclass; 936 937 void const * factptr = MFCD::Retrieve("POWR.SHP"); 938 void const * rmboptr = MFCD::Retrieve("E7.SHP"); 939 void const * fball1ptr = MFCD::Retrieve("FBALL1.SHP"); 940 ramboclass = &InfantryTypeClass::As_Reference(INFANTRY_TANYA); 941 942 /* 943 ** Print the # of buildings on the hidpage so we only need to do it once 944 */ 945 SeenPage.Blit(HidPage); 946 Set_Logic_Page(HidPage); 947 Call_Back_Delay(30); 948 Set_Font_Palette(_redpal); 949 HidPage.Print( 0, BUILDING_X + 16, BUILDING_Y + 10, TBLACK, TBLACK); 950 Set_Font_Palette(_bluepal); 951 HidPage.Print( 0, BUILDING_X + 16, BUILDING_Y + 22, TBLACK, TBLACK); 952 953 /* 954 ** Here's the animation/draw loop for blowing up the factory 955 */ 956 int i; 957 for (i=0; i<98; i++) { 958 HidPage.Blit(HidPage, BUILDING_X, BUILDING_Y, 0, 0, 320-BUILDING_X, 48); 959 shapenum = 0; // no damage 960 if (i >= 60) { 961 shapenum = Extract_Shape_Count(factptr) - 2; // some damage 962 if (i == 60) { 963 Shake_The_Screen(6); 964 Sound_Effect(VOC_CRUMBLE); 965 } 966 if (i > 65) { 967 shapenum = Extract_Shape_Count(factptr) - 1; // mega damage 968 } 969 } 970 971 /* 972 ** Draw the building before Rambo 973 */ 974 if (i < 68) { 975 CC_Draw_Shape(factptr, shapenum, 0, 0, WINDOW_MAIN, 976 SHAPE_GHOST|SHAPE_FADING|SHAPE_WIN_REL, ColorRemaps[PCOLOR_GOLD].RemapTable, DisplayClass::UnitShadow); 977 978 } 979 980 /* 981 ** Now draw some fires, if appropriate 982 */ 983 if (i >= 61) { 984 int firecount = Extract_Shape_Count(fball1ptr); 985 int shapeindex = (i-61) / 2; 986 if (shapeindex < firecount) { 987 CC_Draw_Shape(fball1ptr, shapeindex, 10, 10, WINDOW_MAIN, 988 SHAPE_CENTER|SHAPE_WIN_REL); 989 } 990 if (i > 64) { 991 shapeindex = (i-64) / 2; 992 if (shapeindex < firecount) { 993 CC_Draw_Shape(fball1ptr, shapeindex, 50, 30, WINDOW_MAIN, 994 SHAPE_CENTER|SHAPE_WIN_REL); 995 } 996 } 997 } 998 /* 999 ** Draw the Tanya character running away from the building 1000 */ 1001 CC_Draw_Shape(rmboptr, (ramboclass->DoControls[DO_WALK].Frame + ramboclass->DoControls[DO_WALK].Jump*6) + ((unsigned(i)>>1)%ramboclass->DoControls[DO_WALK].Count), 1002 i+32, 40, WINDOW_MAIN, 1003 SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_GHOST, 1004 ColorRemaps[PCOLOR_RED].RemapTable, DisplayClass::UnitShadow); 1005 HidPage.Blit(SeenPage, 0, 0, BUILDING_X, BUILDING_Y, 320-BUILDING_X, 48); 1006 /*BG if (!Keyboard->Check()) */ Call_Back_Delay(1); 1007 } 1008 1009 i = max(GBKilled, NBKilled); 1010 for (int q = 0; q <= i; q++) { 1011 Set_Font_Palette(_redpal); 1012 Count_Up_Print( "%d", q, NBKilled, BUILDING_X + 16, BUILDING_Y + 10); 1013 Set_Font_Palette(_bluepal); 1014 Count_Up_Print( "%d", q, GBKilled, BUILDING_X + 16, BUILDING_Y + 22); 1015 //BG if (!Keyboard->Check()) { 1016 #ifdef WIN32 1017 Play_Sample(Beepy6, 255, Options.Normalize_Volume(150)); 1018 #else 1019 Play_Sample(Beepy6, 255, Options.Normalize_Volume(60)); 1020 #endif 1021 Call_Back_Delay(1); 1022 //BG } 1023 } 1024 Set_Font_Palette(_redpal); 1025 Count_Up_Print( "%d", NBKilled, NBKilled, BUILDING_X + 16, BUILDING_Y + 10); 1026 Set_Font_Palette(_bluepal); 1027 Count_Up_Print( "%d", GBKilled, GBKilled, BUILDING_X + 16, BUILDING_Y + 22); 1028 } 1029 1030 1031 /*************************************************************************** 1032 * DO_GDI_GRAPH -- Show # of people or buildings killed on GDI score screen* 1033 * * 1034 * * 1035 * * 1036 * INPUT: yellowptr, redptr = pointers to shape file for graphs * 1037 * * 1038 * OUTPUT: * 1039 * * 1040 * WARNINGS: * 1041 * * 1042 * HISTORY: * 1043 * 05/03/1995 BWG : Created. * 1044 *=========================================================================*/ 1045 1046 void ScoreClass::Do_GDI_Graph(void const * yellowptr, void const * redptr, int gkilled, int nkilled, int ypos) 1047 { 1048 int i, maxval; 1049 #ifdef WIN32 1050 int xpos = 174; 1051 int house = (PlayerPtr->Class->House == HOUSE_USSR || PlayerPtr->Class->House == HOUSE_UKRAINE); // 0 or 1 1052 if(house) { 1053 int temp = gkilled; 1054 gkilled = nkilled; 1055 nkilled = temp; 1056 void const *tempptr = yellowptr; 1057 yellowptr = redptr; 1058 redptr = tempptr; 1059 } 1060 #else 1061 int xpos = 173; 1062 #endif 1063 int gdikilled = gkilled, nodkilled=nkilled; 1064 1065 maxval = max(gdikilled, nodkilled); 1066 if (!maxval) maxval=1; 1067 1068 gdikilled = (gdikilled * SIZEGBAR) / maxval; 1069 nodkilled = (nodkilled * SIZEGBAR) / maxval; 1070 if (maxval < 20) { 1071 gdikilled = gkilled * 5; 1072 nodkilled = nkilled * 5; 1073 } 1074 1075 maxval = max(gdikilled, nodkilled); 1076 if (!maxval) maxval=1; 1077 1078 // Draw the white-flash shape on the hidpage 1079 Set_Logic_Page(HidPage); 1080 HidPage.Fill_Rect(0, 0, 124*RESFACTOR, 9*RESFACTOR, TBLACK); 1081 CC_Draw_Shape(redptr, 119, 0, 0, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 1082 Set_Logic_Page(SeenBuff); 1083 #ifdef WIN32 1084 Set_Font_Palette(house ? _redpal : _bluepal); 1085 #else 1086 Set_Font_Palette(_bluepal); 1087 #endif 1088 1089 for (i = 1; i <= gdikilled; i++) { 1090 if (i != gdikilled) { 1091 #ifdef WIN32 1092 Set_Logic_Page(*PseudoSeenBuff); 1093 CC_Draw_Shape(yellowptr, i, xpos*RESFACTOR, ypos*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 1094 Set_Logic_Page(SeenBuff); 1095 #endif 1096 CC_Draw_Shape(yellowptr, i, xpos*RESFACTOR, ypos*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 1097 } else { 1098 HidPage.Blit(SeenPage, 0, 0, xpos*RESFACTOR, ypos*RESFACTOR, (3+gdikilled)*RESFACTOR, 8*RESFACTOR); 1099 #ifdef WIN32 1100 HidPage.Blit(*PseudoSeenBuff, 0, 0, xpos*RESFACTOR, ypos*RESFACTOR, (3+gdikilled)*RESFACTOR, 8*RESFACTOR); 1101 #endif 1102 } 1103 1104 Count_Up_Print("%d", (i*gkilled) / maxval, gkilled, 297, ypos+2); 1105 //BG if (!Keyboard->Check()) { 1106 #ifdef WIN32 1107 Play_Sample(Beepy6, 255, Options.Normalize_Volume(150)); 1108 #else 1109 Play_Sample(Beepy6, 255, Options.Normalize_Volume(60)); 1110 #endif 1111 Call_Back_Delay(2); 1112 //BG } 1113 } 1114 CC_Draw_Shape(yellowptr, gdikilled, xpos*RESFACTOR, ypos*RESFACTOR , WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 1115 #ifdef WIN32 1116 Set_Logic_Page(*PseudoSeenBuff); 1117 CC_Draw_Shape(yellowptr, gdikilled, xpos*RESFACTOR, ypos*RESFACTOR , WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 1118 Set_Logic_Page(SeenBuff); 1119 #endif 1120 Count_Up_Print("%d", gkilled, gkilled, 297, ypos+ 2); 1121 /*BG if (!Keyboard->Check()) */ Call_Back_Delay(40); 1122 1123 #ifdef WIN32 1124 Set_Font_Palette(house ? _bluepal : _redpal); 1125 #else 1126 Set_Font_Palette(_redpal); 1127 #endif 1128 for (i = 1; i <= nodkilled; i++) { 1129 if (i != nodkilled) { 1130 #ifdef WIN32 1131 Set_Logic_Page(*PseudoSeenBuff); 1132 CC_Draw_Shape(redptr, i, xpos*RESFACTOR, (ypos+12)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 1133 Set_Logic_Page(SeenBuff); 1134 #endif 1135 CC_Draw_Shape(redptr, i, xpos*RESFACTOR, (ypos+12)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 1136 } else { 1137 HidPage.Blit(SeenPage, 0, 0, xpos*RESFACTOR, (ypos+12)*RESFACTOR, (3+nodkilled)*RESFACTOR, 8*RESFACTOR); 1138 #ifdef WIN32 1139 HidPage.Blit(*PseudoSeenBuff, 0, 0, xpos*RESFACTOR, (ypos+12)*RESFACTOR, (3+nodkilled)*RESFACTOR, 8*RESFACTOR); 1140 #endif 1141 } 1142 1143 Count_Up_Print("%d", (i*nkilled) / maxval, nkilled, 297, ypos+14); 1144 //BG if (!Keyboard->Check()) { 1145 #ifdef WIN32 1146 Play_Sample(Beepy6, 255, Options.Normalize_Volume(150)); 1147 #else 1148 Play_Sample(Beepy6, 255, Options.Normalize_Volume(60)); 1149 #endif 1150 Call_Back_Delay(2); 1151 //BG } 1152 } 1153 1154 // if (Keyboard::Check()) Keyboard::Clear(); 1155 1156 /* 1157 ** Make sure accurate count is printed at end 1158 */ 1159 #ifdef WIN32 1160 Set_Logic_Page(*PseudoSeenBuff); 1161 CC_Draw_Shape( redptr, nodkilled, xpos*RESFACTOR, (ypos+12)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 1162 Set_Logic_Page(SeenBuff); 1163 #endif 1164 CC_Draw_Shape( redptr, nodkilled, xpos*RESFACTOR, (ypos+12)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0); 1165 Count_Up_Print("%d", nkilled, nkilled, 297, ypos+14); 1166 /*BG if (!Keyboard->Check()) */ Call_Back_Delay(40); 1167 } 1168 1169 1170 void ScoreClass::Do_Nod_Casualties_Graph(void) 1171 { 1172 int i, gdikilled, nodkilled, maxval; 1173 1174 void const * e1ptr = MFCD::Retrieve("E1.SHP"); 1175 1176 gdikilled = GKilled; 1177 nodkilled = NKilled; 1178 maxval = max(gdikilled, nodkilled); 1179 1180 if (!maxval) maxval=1; 1181 if ((gdikilled > (MAX_BAR_X - BARGRAPH_X)) || (nodkilled > (MAX_BAR_X - BARGRAPH_X)) ) { 1182 gdikilled = (gdikilled * (MAX_BAR_X - BARGRAPH_X)) / maxval; 1183 nodkilled = (nodkilled * (MAX_BAR_X - BARGRAPH_X)) / maxval; 1184 } 1185 1186 maxval = max(gdikilled, nodkilled); 1187 if (!maxval) maxval=1; 1188 1189 /* 1190 ** Initialize a bunch of objects for the infantrymen who pose for the bar 1191 ** graphs of casualties. 1192 */ 1193 int r = NUMINFANTRYMEN/2; 1194 for (i = 0; i < NUMINFANTRYMEN/2; i++) { 1195 InfantryMan[i+0].xpos = 1196 InfantryMan[i+r].xpos = (i*10) + 7; 1197 InfantryMan[i+0].ypos = 11; 1198 InfantryMan[i+r].ypos = 21; 1199 InfantryMan[i+0].shapefile = 1200 InfantryMan[i+r].shapefile = e1ptr; 1201 InfantryMan[i+0].remap = ColorRemaps[PCOLOR_RED].RemapTable; 1202 InfantryMan[i+r].remap = ColorRemaps[PCOLOR_BLUE].RemapTable; 1203 InfantryMan[i+0].anim = 1204 InfantryMan[i+r].anim = 0; 1205 InfantryMan[i+0].stage = 1206 InfantryMan[i+r].stage = 0; 1207 InfantryMan[i+0].delay = 1208 InfantryMan[i+r].delay = NonCriticalRandomNumber & 0x1F; 1209 InfantryMan[i+0].Class = 1210 InfantryMan[i+r].Class = &InfantryTypeClass::As_Reference(INFANTRY_E1); 1211 } 1212 1213 /* 1214 ** Draw the infantrymen and pause briefly before running the graph 1215 */ 1216 Draw_InfantryMen(); 1217 HidPage.Blit(SeenPage, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34); 1218 Call_Back_Delay(40); 1219 1220 for (i = 1; i <= maxval; i++) { 1221 // Draw & update infantrymen 3 times for every tick on the graph (i) 1222 for (int index = 0; index < 3; index++) { 1223 Draw_InfantryMen(); 1224 Draw_Bar_Graphs(i, nodkilled, gdikilled); 1225 HidPage.Blit(SeenPage, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34); 1226 1227 Set_Font_Palette(_redpal); 1228 Count_Up_Print("%d", (i*NKilled) / maxval, NKilled, SCORETEXT_X+64, CASUALTY_Y + 2); 1229 Set_Font_Palette(_bluepal); 1230 Count_Up_Print("%d", (i*GKilled) / maxval, GKilled, SCORETEXT_X+64, CASUALTY_Y + 14); 1231 /*BG if (!Keyboard->Check()) */ Call_Back_Delay(3); 1232 } 1233 #ifdef WIN32 1234 Play_Sample(Beepy6, 255, Options.Normalize_Volume(150)); 1235 #else 1236 Play_Sample(Beepy6, 255, Options.Normalize_Volume(60)); 1237 #endif 1238 } 1239 //BG if (Keyboard->Check()) Keyboard->Clear(); 1240 1241 /* 1242 ** Make sure accurate count is printed at end 1243 */ 1244 Set_Font_Palette(_redpal); 1245 Count_Up_Print("%d", NKilled, NKilled, SCORETEXT_X+64, CASUALTY_Y + 2); 1246 Set_Font_Palette(_bluepal); 1247 Count_Up_Print("%d", GKilled, GKilled, SCORETEXT_X+64, CASUALTY_Y + 14); 1248 1249 /* 1250 ** Finish up death animations, if there are any active 1251 */ 1252 int k = 1; 1253 while (k) { 1254 for (i=k=0; i<NUMINFANTRYMEN; i++) { 1255 if (InfantryMan[i].anim >= DO_GUN_DEATH) { 1256 k=1; 1257 } 1258 } 1259 if (k) { 1260 Draw_InfantryMen(); 1261 } 1262 Draw_Bar_Graphs(maxval, nodkilled, gdikilled); 1263 HidPage.Blit(SeenPage, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34); 1264 Call_Back_Delay(1); 1265 } 1266 } 1267 1268 1269 void ScoreClass::Show_Credits(int house, char const pal[]) 1270 { 1271 static int _credsx[2]={276,276}; 1272 static int _credsy[2]={173,58}; 1273 static int _credpx[2]={228,236}; 1274 #ifdef GERMAN 1275 static int _credpy[2]={181, 74}; 1276 static int _credtx[2]={162,162}; 1277 static int _credty[2]={173, 62}; 1278 #else 1279 static int _credpy[2]={189-12, 74}; 1280 static int _credtx[2]={182,182}; 1281 static int _credty[2]={179-12, 62}; 1282 #endif 1283 1284 int credobj,i; 1285 int minval,add; 1286 1287 #ifdef WIN32 1288 void const * credshape = MFCD::Retrieve(house ? "CREDSUHR.SHP" : "CREDSAHR.SHP"); 1289 #else 1290 void const * credshape = MFCD::Retrieve(house ? "CREDSU.SHP" : "CREDSA.SHP"); 1291 #endif 1292 1293 Alloc_Object(new ScorePrintClass(TXT_SCORE_ENDCRED, _credtx[house], _credty[house], pal)); 1294 Call_Back_Delay(15); 1295 1296 credobj = Alloc_Object(new ScoreCredsClass(_credsx[house], _credsy[house], credshape, 32, 2)); 1297 minval = PlayerPtr->Available_Money() / 100; 1298 1299 /* 1300 ** Print out total credits left at end of scenario 1301 */ 1302 i = -50; 1303 1304 do { 1305 add = 5; 1306 if ((PlayerPtr->Available_Money() - i) > 100 ) add += 15; 1307 if ((PlayerPtr->Available_Money() - i) > 500 ) add += 30; 1308 if ((PlayerPtr->Available_Money() - i) > 1000) add += PlayerPtr->Available_Money() / 40; 1309 if (add < minval) add = minval; 1310 i += add; 1311 1312 if (i < 0) i=0; 1313 1314 Set_Font_Palette(pal); 1315 Count_Up_Print("%d", i, PlayerPtr->Available_Money(), _credpx[house], _credpy[house]); 1316 Call_Back_Delay(2); 1317 /*BG if (Keyboard->Check()) { 1318 Count_Up_Print("%d", PlayerPtr->Available_Money(), PlayerPtr->Available_Money(), _credpx[house], _credpy[house]); 1319 Keyboard->Clear(); 1320 break; 1321 }*/ 1322 } while (i < PlayerPtr->Available_Money()) ; 1323 1324 delete ScoreObjs[credobj]; 1325 ScoreObjs[credobj] = 0; 1326 } 1327 1328 1329 /*************************************************************************** 1330 * SCORECLASS::PRINT_MINUTES -- Print out hours/minutes up to max * 1331 * * 1332 * Same as count-up-print, but for the time * 1333 * * 1334 * INPUT: current minute count and maximum * 1335 * * 1336 * OUTPUT: * 1337 * * 1338 * WARNINGS: * 1339 * * 1340 * HISTORY: * 1341 * 04/13/1995 BWG : Created. * 1342 *=========================================================================*/ 1343 void ScoreClass::Print_Minutes(int minutes) 1344 { 1345 char str[20]; 1346 if (minutes >= 60) { 1347 if ((minutes/60) > 9) minutes = (9*60 + 59); 1348 sprintf(str, Text_String(TXT_SCORE_TIMEFORMAT1), (minutes / 60), (minutes % 60)); 1349 } else { 1350 sprintf(str, Text_String(TXT_SCORE_TIMEFORMAT2), minutes); 1351 } 1352 SeenPage.Print(str, 275*RESFACTOR, 9*RESFACTOR, TBLACK, TBLACK); 1353 #ifdef WIN32 1354 PseudoSeenBuff->Print(str, 275*RESFACTOR, 9*RESFACTOR, TBLACK, TBLACK); 1355 #endif 1356 } 1357 1358 1359 /*********************************************************************************************** 1360 * ScoreClass::Count_Up_Print -- Prints a number (up to its max) into a string, cleanly. * 1361 * * 1362 * This routine prints out a number (like 70) or its maximum number, into a string, onto * 1363 * the screen, on a clean section of the screen, and blits it forward to the seenpage so you* 1364 * can print without flashing and can print over something (to count up %'s). * 1365 * * 1366 * INPUT: str = string to print into * 1367 * percent = # to print * 1368 * max = # to print if percent > max * 1369 * xpos = x pixel coord * 1370 * ypos = y pixel coord * 1371 * * 1372 * OUTPUT: none * 1373 * * 1374 * WARNINGS: none * 1375 * * 1376 * HISTORY: * 1377 * 04/07/1995 BWG : Created. * 1378 *=============================================================================================*/ 1379 void ScoreClass::Count_Up_Print(char *str, int percent, int maxval, int xpos, int ypos) 1380 { 1381 char destbuf[64]; 1382 1383 sprintf(destbuf, str, percent <= maxval ? percent : maxval); 1384 SeenPage.Print( destbuf, xpos * RESFACTOR, ypos * RESFACTOR, TBLACK, BLACK); 1385 #ifdef WIN32 1386 PseudoSeenBuff->Print( destbuf, xpos * RESFACTOR, ypos * RESFACTOR, TBLACK, BLACK); 1387 #endif 1388 } 1389 1390 1391 /*********************************************************************************************** 1392 * ScoreClass::Input_Name -- Gets the name from the keyboard * 1393 * * 1394 * This routine handles keyboard input, and does a nifty zooming letter effect too. * 1395 * * 1396 * INPUT: str = string to put user's typing into * 1397 * xpos = x pixel coord * 1398 * ypos = y pixel coord * 1399 * pal = text remapping palette to print using * 1400 * * 1401 * OUTPUT: none * 1402 * * 1403 * WARNINGS: none * 1404 * * 1405 * HISTORY: * 1406 * 05/15/1995 BWG : Created. * 1407 *=============================================================================================*/ 1408 void ScoreClass::Input_Name(char str[], int xpos, int ypos, char const pal[]) 1409 { 1410 int key = 0; 1411 int ascii, index=0; 1412 1413 void const * keystrok = MFCD::Retrieve("KEYSTROK.AUD"); 1414 1415 /* 1416 ** Ready the hidpage so it can restore background under zoomed letters 1417 */ 1418 SeenPage.Blit(HidPage); 1419 1420 /* 1421 ** Put a copy of the high score area on a spare area of the hidpage, so 1422 ** we can use it to restore the letter's background instead of filling 1423 ** with black. 1424 */ 1425 HidPage.Blit(HidPage, 0, 100*RESFACTOR, 0, 0, 100*RESFACTOR, 100*RESFACTOR); 1426 1427 do { 1428 Call_Back(); 1429 Animate_Score_Objs(); 1430 Animate_Cursor(index, ypos); 1431 if (Keyboard->Check()) { 1432 key = Keyboard->To_ASCII(Keyboard->Get()) & 0xFF; 1433 Call_Back(); 1434 1435 if (index == MAX_FAMENAME_LENGTH-2) { 1436 while (Keyboard->Check()) { 1437 Keyboard->Get(); 1438 } 1439 } 1440 1441 /* 1442 ** If they hit 'backspace' when they're on the last letter, 1443 ** turn it into a space instead. 1444 */ 1445 if ((key == KA_BACKSPACE) && (index == MAX_FAMENAME_LENGTH-2) ) { 1446 if (str[index] && str[index]!=32) key = 32; 1447 } 1448 if (key == KA_BACKSPACE) { //if (key == KN_BACKSPACE) { 1449 if (index) { 1450 str[--index] = 0; 1451 1452 int xposindex6 = (xpos+(index*6))*RESFACTOR; 1453 HidPage.Blit(SeenPage, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); 1454 #ifdef WIN32 1455 HidPage.Blit(*PseudoSeenBuff, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); 1456 #endif 1457 HidPage.Blit(HidPage, xposindex6, (ypos-100)*RESFACTOR, xposindex6, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); 1458 } 1459 1460 } else if (key != KA_RETURN) { //else if (key != KN_RETURN && key!=KN_KEYPAD_RETURN) { 1461 ascii = key; //ascii = KN_To_KA(key); 1462 if (ascii >= 'a' && ascii <= 'z') ascii -= ('a' - 'A'); 1463 if ( (ascii >= '!' && ascii <= KA_TILDA) || ascii == ' ') { 1464 HidPage.Blit(SeenPage, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); 1465 #ifdef WIN32 1466 HidPage.Blit(*PseudoSeenBuff, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); 1467 #endif 1468 HidPage.Blit(HidPage, (xpos + (index*6))*RESFACTOR, (ypos-100)*RESFACTOR, (xpos + (index*6))*RESFACTOR, ypos*RESFACTOR, 6*RESFACTOR, 6*RESFACTOR); 1469 str[index] = ascii; 1470 str[index+1] = 0; 1471 1472 int objindex; 1473 #ifdef WIN32 1474 Play_Sample(keystrok, 255, Options.Normalize_Volume(150)); 1475 #else 1476 Play_Sample(keystrok, 255, Options.Normalize_Volume(105)); 1477 #endif 1478 objindex = Alloc_Object(new ScoreScaleClass(str+index, xpos+(index*6), ypos, pal)); 1479 while (ScoreObjs[objindex]) Call_Back_Delay(1); 1480 1481 if (index < (MAX_FAMENAME_LENGTH-2) ) index++; 1482 } 1483 } 1484 } 1485 } while (key != KA_RETURN); // } while(key != KN_RETURN && key!=KN_KEYPAD_RETURN); 1486 } 1487 1488 1489 void Animate_Cursor(int pos, int ypos) 1490 { 1491 static int _lastpos = 0, _state; 1492 static CDTimerClass<SystemTimerClass> _timer; 1493 1494 ypos += 6; // move cursor to bottom of letter 1495 1496 ypos *= RESFACTOR; 1497 1498 // If they moved the cursor, erase old one and force state=0, to make green draw right away 1499 if (pos != _lastpos) { 1500 HidPage.Blit(SeenPage, (HALLFAME_X + (_lastpos*6))*RESFACTOR, ypos-100*RESFACTOR, (HALLFAME_X + (_lastpos*6))*RESFACTOR, ypos, 6*RESFACTOR, 1*RESFACTOR); 1501 #ifdef WIN32 1502 HidPage.Blit(*PseudoSeenBuff, (HALLFAME_X + (_lastpos*6))*RESFACTOR, ypos-100*RESFACTOR, (HALLFAME_X + (_lastpos*6))*RESFACTOR, ypos, 6*RESFACTOR, 1*RESFACTOR); 1503 #endif 1504 _lastpos = pos; 1505 _state = 0; 1506 } 1507 SeenBuff.Draw_Line((HALLFAME_X + (pos*6))*RESFACTOR, ypos, (HALLFAME_X + (pos*6)+5)*RESFACTOR, ypos, _state ? LTBLUE : TBLACK); 1508 #ifdef WIN32 1509 PseudoSeenBuff->Draw_Line((HALLFAME_X + (pos*6))*RESFACTOR, ypos, (HALLFAME_X + (pos*6)+5)*RESFACTOR, ypos, _state ? LTBLUE : TBLACK); 1510 #endif 1511 /* 1512 ** Toggle the color of the cursor, green or black, if it's time to do so. 1513 */ 1514 if (!_timer) { 1515 _state ^= 1; 1516 _timer = 5; 1517 } 1518 } 1519 1520 1521 /*************************************************************************** 1522 * Draw_InfantryMen -- Draw all the guys on the score screen * 1523 * * 1524 * * 1525 * * 1526 * INPUT: * 1527 * * 1528 * OUTPUT: * 1529 * * 1530 * WARNINGS: * 1531 * * 1532 * HISTORY: * 1533 * 04/13/1995 BWG : Created. * 1534 *=========================================================================*/ 1535 void Draw_InfantryMen() 1536 { 1537 int k; 1538 1539 // Only draw the infantrymen if we're playing USSR... Allies wouldn't execute 1540 // people like that. 1541 1542 /* 1543 ** First restore the background 1544 */ 1545 HidPage.Blit(HidPage, BARGRAPH_X, CASUALTY_Y, 0, 0, 320-BARGRAPH_X, 34); 1546 Set_Logic_Page(HidPage); 1547 1548 /* 1549 ** Then draw all the infantrymen on the clean hidpage 1550 */ 1551 for (k = 0; k < NUMINFANTRYMEN; k++) Draw_InfantryMan(k); 1552 /* 1553 ** They'll all be blitted over to the seenpage after the graphs are drawn 1554 */ 1555 } 1556 1557 /*************************************************************************** 1558 * Draw_InfantryMan -- Draw one guy in score screen, update animation * 1559 * * 1560 * This routine draws one of the infantrymen in the "Casualties" area * 1561 * * 1562 * INPUT: * 1563 * * 1564 * OUTPUT: * 1565 * * 1566 * WARNINGS: * 1567 * * 1568 * HISTORY: * 1569 * 04/13/1995 BWG : Created. * 1570 *=========================================================================*/ 1571 void Draw_InfantryMan(int index) 1572 { 1573 int stage; 1574 1575 /* If the infantryman's dead, just abort this function */ 1576 if (InfantryMan[index].anim == -1) return; 1577 1578 stage = InfantryMan[index].stage + InfantryMan[index].Class->DoControls[InfantryMan[index].anim].Frame; 1579 1580 CC_Draw_Shape(InfantryMan[index].shapefile, 1581 stage, 1582 InfantryMan[index].xpos, 1583 InfantryMan[index].ypos, 1584 WINDOW_MAIN, 1585 SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_GHOST, 1586 InfantryMan[index].remap, 1587 DisplayClass::UnitShadow); 1588 /* 1589 ** see if it's time to run a new anim 1590 */ 1591 if (--InfantryMan[index].delay <= 0) { 1592 InfantryMan[index].delay = 3; 1593 if (++InfantryMan[index].stage >= InfantryMan[index].Class->DoControls[InfantryMan[index].anim].Count) { 1594 1595 /* 1596 ** was he playing a death anim? If so, and it's done, erase him 1597 */ 1598 if (InfantryMan[index].anim >= DO_GUN_DEATH) { 1599 InfantryMan[index].anim = -1; 1600 } else { 1601 New_Infantry_Anim(index, DO_STAND_READY); 1602 } 1603 } 1604 } 1605 } 1606 1607 1608 /*************************************************************************** 1609 * New_Infantry_Anim -- Start up a new animation for one of the infantrymen* 1610 * * 1611 * * 1612 * * 1613 * INPUT: index: which of the 30 infantrymen to affect * 1614 * anim: which animation sequence to start him into * 1615 * OUTPUT: * 1616 * * 1617 * WARNINGS: * 1618 * * 1619 * HISTORY: * 1620 * 04/13/1995 BWG : Created. * 1621 *=========================================================================*/ 1622 void New_Infantry_Anim(int index, int anim) 1623 { 1624 InfantryMan[index].anim = anim; 1625 InfantryMan[index].stage = 0; 1626 if (anim >= DO_GUN_DEATH) { 1627 InfantryMan[index].delay = 1; // start right away 1628 } else { 1629 InfantryMan[index].delay = NonCriticalRandomNumber & 15; 1630 } 1631 } 1632 1633 1634 /*************************************************************************** 1635 * Draw_Bar_Graphs -- Draw "Casualties" bar graphs * 1636 * * 1637 * * 1638 * * 1639 * INPUT: i = current count of how far to draw graph * 1640 * gkilled = # of GDI forces killed (adjusted to fit in space) * 1641 * nkilled = # of Nod forces killed (adjusted to fit in space) * 1642 * OUTPUT: * 1643 * * 1644 * WARNINGS: * 1645 * * 1646 * HISTORY: * 1647 * 04/13/1995 BWG : Created. * 1648 * 07/02/1996 BWG : Removed references to civilians. * 1649 *=========================================================================*/ 1650 void Draw_Bar_Graphs(int i, int gkilled, int nkilled) 1651 { 1652 1653 if (gkilled) { 1654 LogicPage->Fill_Rect(0, 0+4*RESFACTOR, 0+min(i, gkilled)*RESFACTOR, 0+5*RESFACTOR, RED); 1655 LogicPage->Draw_Line(0+1*RESFACTOR, 0+6*RESFACTOR, (0+min(i, gkilled)+1)*RESFACTOR, 0+6*RESFACTOR, TBLACK); 1656 LogicPage->Draw_Line((0+MIN(i, gkilled)+1)*RESFACTOR, 0+5*RESFACTOR, (0+min(i, gkilled)+1)*RESFACTOR, 0+5*RESFACTOR, TBLACK); 1657 if (i <= gkilled) { 1658 int anim = InfantryMan[i/11].anim; 1659 if (anim!=-1 && anim < DO_GUN_DEATH) { 1660 if (i/11) { 1661 New_Infantry_Anim(i/11, DO_GUN_DEATH + (NonCriticalRandomNumber & 3)); 1662 } else { 1663 New_Infantry_Anim(i/11, DO_GUN_DEATH); 1664 } 1665 // Sound_Effect(Random_Pick(VOC_SCREAM1, VOC_SCREAM5)); 1666 } 1667 } 1668 } 1669 if (nkilled) { 1670 LogicPage->Fill_Rect( 0, 0+16*RESFACTOR, 0+min(i, nkilled)*RESFACTOR, 0+17*RESFACTOR, LTCYAN); 1671 LogicPage->Draw_Line( 0+1*RESFACTOR, 0+18*RESFACTOR, (0+min(i, nkilled)+1)*RESFACTOR, 0+18*RESFACTOR, TBLACK); 1672 LogicPage->Draw_Line((0+MIN(i, nkilled)+1)*RESFACTOR, 0+17*RESFACTOR, (0+min(i, nkilled)+1)*RESFACTOR, 0+17*RESFACTOR, TBLACK); 1673 if (i <= nkilled) { 1674 int anim = InfantryMan[(NUMINFANTRYMEN/2)+(i/11)].anim; 1675 if (anim!=-1 && anim < DO_GUN_DEATH) { 1676 if (i/11) { 1677 New_Infantry_Anim((NUMINFANTRYMEN/2)+(i/11), DO_GUN_DEATH + (NonCriticalRandomNumber & 3)); 1678 } else { 1679 New_Infantry_Anim((NUMINFANTRYMEN/2)+(i/11), DO_GUN_DEATH); 1680 } 1681 // Sound_Effect(Random_Pick(VOC_SCREAM1, VOC_SCREAM5)); 1682 } 1683 } 1684 } 1685 } 1686 1687 1688 /*************************************************************************** 1689 * Call_Back_Delay -- Combines Call_Back() and Delay() functions * 1690 * * 1691 * This is just to cut down on code size and typing a little. * 1692 * * 1693 * INPUT: * 1694 * * 1695 * OUTPUT: * 1696 * * 1697 * WARNINGS: * 1698 * * 1699 * HISTORY: * 1700 * 04/13/1995 BWG : Created. * 1701 *=========================================================================*/ 1702 void Call_Back_Delay(int time) 1703 { 1704 time; 1705 #if (0)//PG 1706 if (time < 0 ) time = 0; 1707 if (time > 60) time = 60; 1708 CDTimerClass<SystemTimerClass> cd; 1709 CDTimerClass<SystemTimerClass> callbackcd = 0; 1710 1711 if (!ControlQ) { 1712 if (Keyboard->Down(KN_LCTRL) && Keyboard->Down(KN_Q)) { 1713 ControlQ = 1; 1714 Keyboard->Clear(); 1715 } 1716 } 1717 if (ControlQ) time=0; 1718 1719 cd = time; 1720 StreamLowImpact = true; 1721 do { 1722 if (callbackcd == 0) { 1723 Call_Back(); 1724 callbackcd = TIMER_SECOND/4; 1725 } 1726 Animate_Score_Objs(); 1727 } while (cd); 1728 StreamLowImpact = false; 1729 #endif 1730 } 1731 1732 1733 void Animate_Score_Objs() 1734 { 1735 #ifdef WIN32 1736 StillUpdating = false; 1737 /* 1738 ** If we have just received input focus again after running in the background then 1739 ** we need to redraw. 1740 */ 1741 if (AllSurfaces.SurfacesRestored) { 1742 AllSurfaces.SurfacesRestored=FALSE; 1743 PseudoSeenBuff->Blit(SeenPage); 1744 } 1745 #endif 1746 for (int i = 0; i < MAXSCOREOBJS; i++) { 1747 if (ScoreObjs[i]) { 1748 ScoreObjs[i]->Update(); 1749 } 1750 } 1751 } 1752 1753 char *Int_Print(int a) 1754 { 1755 static char str[10]; 1756 1757 sprintf(str, "%d", a); 1758 return str; 1759 } 1760 1761 1762 /*********************************************************************************************** 1763 * Multi_Score_Presentation -- Multiplayer routine to display score screen. * 1764 * * 1765 * * 1766 * INPUT: none * 1767 * * 1768 * OUTPUT: none * 1769 * * 1770 * WARNINGS: none * 1771 * * 1772 * HISTORY: * 1773 * 06/11/1995 BWG: Created. * 1774 *=============================================================================================*/ 1775 extern int CopyType; 1776 1777 void Multi_Score_Presentation(void) 1778 { 1779 #if (0)//PG 1780 char remap[16]; 1781 #ifdef WIN32 1782 GraphicBufferClass *pseudoseenbuff = new GraphicBufferClass(320, 200, (void*)NULL); 1783 PseudoSeenBuff = new GraphicBufferClass(SeenBuff.Get_Width(),SeenBuff.Get_Height(),(void*)NULL); 1784 #endif 1785 1786 int i,k; 1787 void *oldfont; 1788 int oldfontxspacing = FontXSpacing; 1789 1790 FontXSpacing = 0; 1791 Map.Override_Mouse_Shape(MOUSE_NORMAL); 1792 // Theme.Queue_Song(THEME_WIN); 1793 1794 BlackPalette.Set(); 1795 SeenPage.Clear(); 1796 HidPage.Clear(); 1797 Hide_Mouse(); 1798 void *anim = Open_Animation("MLTIPLYR.WSA", NULL, 0L, (WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE), ScorePalette); 1799 /* 1800 ** Display the background animation 1801 */ 1802 #ifdef WIN32 1803 pseudoseenbuff->Clear(); 1804 Animate_Frame(anim, *pseudoseenbuff, 1); 1805 for(int x=0; x<256; x++) memset(&PaletteInterpolationTable[x][0],x,256); 1806 CopyType = 1; 1807 Interpolate_2X_Scale(pseudoseenbuff , &SeenBuff , 0); 1808 #else 1809 Animate_Frame(anim, HidPage, 1); 1810 HidPage.Blit(SeenPage); 1811 #endif 1812 ScorePalette.Set(FADE_PALETTE_FAST, Call_Back); 1813 1814 int frame = 1; 1815 while (frame < Get_Animation_Frame_Count(anim)) { 1816 #ifdef WIN32 1817 Animate_Frame(anim, *pseudoseenbuff, frame++); 1818 CopyType = 1; 1819 Interpolate_2X_Scale(pseudoseenbuff , &SeenBuff , NULL); 1820 CopyType = 0; 1821 #else 1822 Animate_Frame(anim, SeenPage, frame++); 1823 #endif 1824 Call_Back_Delay(2); 1825 } 1826 Close_Animation(anim); 1827 1828 #ifdef WIN32 1829 CopyType = 1; 1830 Interpolate_2X_Scale(pseudoseenbuff , PseudoSeenBuff , NULL); 1831 CopyType = 0; 1832 #endif 1833 1834 /* Change to the six-point font for Text_Print */ 1835 oldfont = Set_Font(ScoreFontPtr); 1836 Call_Back(); 1837 1838 Set_Logic_Page(SeenBuff); 1839 1840 #ifdef FRENCH 1841 Alloc_Object(new ScorePrintClass(TXT_SCORE_TOP, 113, 13, _greenpal)); 1842 #else 1843 Alloc_Object(new ScorePrintClass(TXT_SCORE_TOP, 130, 13, _greenpal)); 1844 #endif 1845 Call_Back_Delay(5); 1846 Alloc_Object(new ScorePrintClass(TXT_COMMANDER, 27, 31, _greenpal)); 1847 Call_Back_Delay(10); 1848 #ifdef FRENCH 1849 Alloc_Object(new ScorePrintClass(TXT_BATTLES_WON, 113, 31, _greenpal)); 1850 #endif 1851 #ifdef GERMAN 1852 Alloc_Object(new ScorePrintClass(TXT_BATTLES_WON, 118, 31, _greenpal)); 1853 #endif 1854 #ifdef ENGLISH 1855 Alloc_Object(new ScorePrintClass(TXT_BATTLES_WON, 126, 31, _greenpal)); 1856 #endif 1857 Call_Back_Delay(13); 1858 Alloc_Object(new ScorePrintClass(TXT_KILLS_COLON, 249, 31, _greenpal)); 1859 Call_Back_Delay(6); 1860 1861 /* 1862 ** Move all the scores over a notch if there's more games than can be 1863 ** shown (which is known by Session.CurGame == MAX_MULTI_GAMES-1); 1864 */ 1865 if (Session.CurGame == MAX_MULTI_GAMES-1) { 1866 for (i = 0; i < MAX_MULTI_NAMES; i++) { 1867 for (k = 0; k < MAX_MULTI_GAMES-1; k++) { 1868 Session.Score[i].Kills[k] = Session.Score[i].Kills[k+1]; 1869 } 1870 } 1871 } 1872 1873 int y = 41; 1874 for (i = 0; i < MAX_MULTI_NAMES; i++) { 1875 if (strlen(Session.Score[i].Name)) { 1876 int color = Session.Score[i].Color; 1877 remap[ 8] = ColorRemaps[color].FontRemap[11]; 1878 remap[ 6] = ColorRemaps[color].FontRemap[12]; 1879 remap[ 4] = ColorRemaps[color].FontRemap[13]; 1880 remap[ 2] = ColorRemaps[color].FontRemap[14]; 1881 remap[14] = ColorRemaps[color].FontRemap[15]; 1882 1883 Alloc_Object(new ScorePrintClass(Session.Score[i].Name, 15, y, remap)); 1884 Call_Back_Delay(20); 1885 1886 Alloc_Object(new ScorePrintClass(Int_Print(Session.Score[i].Wins), 118, y, remap)); 1887 Call_Back_Delay(6); 1888 1889 for (k = 0; k <= min(Session.CurGame, MAX_MULTI_GAMES-2); k++) { 1890 if (Session.Score[i].Kills[k] >= 0) { 1891 Alloc_Object(new ScorePrintClass(Int_Print(Session.Score[i].Kills[k]), 225+(24*k), y, remap)); 1892 Call_Back_Delay(6); 1893 } 1894 } 1895 y += 12; 1896 } 1897 } 1898 1899 #if defined(GERMAN) || defined(FRENCH) 1900 Alloc_Object(new ScorePrintClass(TXT_CLICK_CONTINUE, 95 /*(320-strlen(Text_String(TXT_MAP_CLICK2)))/2*/, 190, _yellowpal)); 1901 #else 1902 Alloc_Object(new ScorePrintClass(TXT_CLICK_CONTINUE, 109 /*(320-strlen(Text_String(TXT_MAP_CLICK2)))/2*/, 190, _yellowpal)); 1903 #endif 1904 Cycle_Wait_Click(false); 1905 1906 /* get rid of all the animating objects */ 1907 for (i = 0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) { 1908 delete ScoreObjs[i]; 1909 ScoreObjs[i] = 0; 1910 } 1911 1912 Theme.Queue_Song(THEME_NONE); 1913 1914 BlackPalette.Set(FADE_PALETTE_FAST, NULL); 1915 SeenPage.Clear(); 1916 GamePalette.Set(); 1917 #ifdef WIN32 1918 delete PseudoSeenBuff; 1919 #endif 1920 Set_Font(oldfont); 1921 FontXSpacing = oldfontxspacing; 1922 ControlQ = 0; 1923 Show_Mouse(); 1924 #endif 1925 } 1926 1927 void ScoreClass::Init(void) 1928 { 1929 Score = 0; 1930 NKilled = 0; 1931 GKilled = 0; 1932 CKilled = 0; 1933 NBKilled = 0; 1934 GBKilled = 0; 1935 CBKilled = 0; 1936 NHarvested = 0; 1937 GHarvested = 0; 1938 CHarvested = 0; 1939 ElapsedTime = 0; 1940 RealTime = 0; 1941 ChangingGun = 0; 1942 }