CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

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 }