CnC_Remastered_Collection

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

SCORE.CPP (86578B)


      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:   F:\projects\c&c\vcs\code\score.cpv   2.17   16 Oct 1995 16:49:54   JOE_BOSTIC  $ */
     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::Delay -- Pauses waiting for keypress.                                         *
     40  *   ScoreClass::DO_GDI_GRAPH -- Show # of people or buildings killed on GDI score screen      *
     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 #include	"function.h"
     48 #include  "textblit.h"
     49 #define SCORETEXT_X		184
     50 #define SCORETEXT_Y		8
     51 #define CASUALTY_Y		88
     52 #define BUILDING_X		256
     53 #define BUILDING_Y		128
     54 #define BARGRAPH_X		266
     55 #define MAX_BAR_X			318		// max possible is 319 because of bar's right shadow
     56 #define SIZEGBAR			119
     57 #define HALLFAME_X		19
     58 #define HALLFAME_Y		120
     59 
     60 #define	MULTISCOREX		30
     61 
     62 #define TEDIT_FAME				1
     63 #define NUMINFANTRYMEN			15
     64 #define NUMFAMENAMES				7
     65 #define MAX_FAMENAME_LENGTH	12
     66 
     67 struct InfantryAnim {
     68 	int xpos;
     69 	int ypos;
     70 	void const *shapefile;
     71 	void const *remap;
     72 	int anim;
     73 	int stage;
     74 	char delay;
     75 	InfantryTypeClass const *Class;
     76 } InfantryMan[NUMINFANTRYMEN];
     77 void Draw_InfantryMen(void);
     78 void Draw_InfantryMan(int index);
     79 void New_Infantry_Anim(int index, int anim);
     80 void Draw_Bar_Graphs(int i, int gkilled, int nkilled, int ckilled);
     81 void Animate_Cursor(int pos, int ypos);
     82 void Animate_Score_Objs(void);
     83 void Cycle_Wait_Click(void);
     84 int  ScorePass;
     85 
     86 void const * Beepy6;
     87 int ControlQ;	// cheat key to skip past score/mapsel screens
     88 bool StillUpdating;
     89 
     90 GraphicBufferClass *PseudoSeenBuff;
     91 GraphicBufferClass *TextPrintBuffer;
     92 
     93 #ifdef WRITE_LBM
     94 PUBLIC bool CCWrite_LBM_File(CCFileClass &lbmhandle, BufferClass& buff, short bitplanes, unsigned char *palette);
     95 #endif
     96 
     97 unsigned char RemapCiv[256]={
     98 	0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
     99 	0x10,0x11,0x12,0x13,0x14,0x15,0x16,0xD0,0x18,0x19,0xD1,0xD2,0xD3,0xD4,0x1E,0xD5,
    100 	0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
    101 	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
    102 	0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
    103 	0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
    104 	0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
    105 	0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0xD6,0xD7,0xD8,0xD9,0x7E,0xDA,
    106 	0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
    107 	0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
    108 	0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
    109 	0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
    110 	0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
    111 	0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xDB,0xDC,0xDD,0xDE,0xDB,0xDC,0xDD,0xDE,0xDF,
    112 	0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
    113 	0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF};
    114 
    115 unsigned char const ScoreRemapGrey[256] = {
    116 	  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,	// 0..15
    117 	 16, 17, 18, 19, 20,176, 22,208, 24, 25,209,210,211,212, 30,213,	// 16..31
    118 	 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,	// 32..47
    119 	 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,	// 48..63
    120 	 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,	// 64..79
    121 	 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,	// 80..95
    122 	 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,	// 96..111
    123 	112,113,114,115,116,117,118,119,120,121,214,215,216,217,149,218,	// 112..127
    124 	128,129,130,131,132,133,134,135,136,137,138,108,140,141,142,143,	// 128..143
    125 	144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,	// 144..159
    126 	160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,	// 160..175
    127 	192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,	// 176..191
    128 	192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,	// 192..207
    129 	208,209,210,211,212,213,214,219,220,221,222,219,220,221,222,223,	// 208..223
    130 	224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,	// 224..239
    131 	240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255	// 240..255
    132 };
    133 
    134 unsigned char const ScoreRemapYellow[256] = {
    135 	  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,	// 0..15
    136 	 16, 17, 18, 19, 20,176, 22,208, 24, 25,209,210,211,212, 30,213,	// 16..31
    137 	 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,	// 32..47
    138 	 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,	// 48..63
    139 	 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,	// 64..79
    140 	 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,	// 80..95
    141 	 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,	// 96..111
    142 	112,113,114,115,116,117,118,119,120,121,214,215,216,217,149,218,	// 112..127
    143 	128,129,130,131,132,133,134,135,136,137,138,108,140,141,142,143,	// 128..143
    144 	144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,	// 144..159
    145 	160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,	// 160..175
    146 	176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,	// 176..191
    147 	192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,	// 192..207
    148 	208,209,210,211,212,213,214,219,220,221,222,219,220,221,222,223,	// 208..223
    149 	224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,	// 224..239
    150 	240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255	// 240..255
    151 };
    152 
    153 unsigned char const ScoreRemapBldg[256]={
    154 	0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
    155 	0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
    156 	0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
    157 	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
    158 	0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
    159 	0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
    160 	0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
    161 	0x70,0x71,0xCE,0xC5,0x49,0x48,0x47,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
    162 	0x80,0x81,0xB8,0x83,0x7C,0x7A,0x76,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
    163 	0x74,0x91,0x92,0x93,0x94,0x95,0xB5,0x97,0x98,0xCF,0x4B,0x7F,0x9C,0x9D,0x9E,0x9F,
    164 	0xA0,0xA1,0xA2,0x83,0x79,0xA5,0xA6,0xA7,0x43,0x99,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
    165 	0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
    166 	0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
    167 	0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xBB,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
    168 	0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
    169 	0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
    170 };
    171 unsigned char const ScoreRemapFBall[256]={
    172 	0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
    173 	0xB0,0xE5,0x82,0xE4,0xE3,0xE2,0xB1,0xD0,0xE1,0xE0,0xD1,0xD2,0xD3,0xD4,0xDF,0xD5,
    174 	0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0xE6,0xE7,0xA0,0xE8,0x2E,0x2F,
    175 	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
    176 	0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
    177 	0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
    178 	0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
    179 	0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
    180 	0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
    181 	0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
    182 	0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
    183 	0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
    184 	0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
    185 	0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
    186 	0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
    187 	0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
    188 };
    189 
    190 TextBlitClass BlitList;
    191 
    192 
    193 char *ScreenNames[2]={"S-GDIIN2.WSA","SCRSCN1.WSA"};
    194 
    195 //extern short StreamLowImpact;
    196 
    197 // ST - 1/3/2019 10:38AM
    198 int StreamLowImpact = FALSE;
    199 
    200 struct Fame {
    201 	char	name[MAX_FAMENAME_LENGTH];
    202 	int	score;
    203 	int	level;
    204 };
    205 
    206 ScoreAnimClass *ScoreObjs[MAXSCOREOBJS];
    207 
    208 
    209 ScoreAnimClass::ScoreAnimClass(int x, int y, void const * data)
    210 {
    211 	BlitList.Add (x*2, y*2, x*2, y*2, 2* String_Pixel_Width ( (char*)data ) , 16);
    212 	XPos = x;
    213 	YPos = y;
    214 	Timer.Set(0);
    215 	Timer.Start();
    216 	DataPtr = data;
    217 }
    218 
    219 
    220 ScoreTimeClass::ScoreTimeClass(int xpos, int ypos, void const * data, int max, int timer) :
    221 	ScoreAnimClass(xpos, ypos, data)
    222 {
    223 	Stage = 0;
    224 	MaxStage = max;
    225 	TimerReset = timer;
    226 }
    227 
    228 void ScoreTimeClass::Update(void)
    229 {
    230 	GraphicViewPortClass *oldpage;
    231 	if (!Timer.Time()) {
    232 		Timer.Set(TimerReset);
    233 		if (++Stage >= MaxStage) Stage = 0;
    234 		oldpage = LogicPage;
    235 		Set_Logic_Page(PseudoSeenBuff);
    236 		CC_Draw_Shape(DataPtr, Stage, XPos, YPos, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
    237 		Set_Logic_Page(oldpage);
    238 	}
    239 }
    240 
    241 ScoreCredsClass::ScoreCredsClass(int xpos, int ypos, void const * data, int max, int timer) :
    242 	ScoreAnimClass(xpos, ypos, data)
    243 {
    244 	Stage = 0;
    245 	MaxStage = max;
    246 	TimerReset = timer;
    247 	Clock1 = MixFileClass::Retrieve("CLOCK1.AUD");
    248 	CashTurn = MixFileClass::Retrieve("CASHTURN.AUD");
    249 }
    250 
    251 
    252 void ScoreCredsClass::Update(void)
    253 {
    254 	GraphicViewPortClass *oldpage;
    255 	if (!Timer.Time()) {
    256 		Timer.Set(TimerReset);
    257 		if (++Stage >= MaxStage) Stage = 0;
    258 		oldpage = LogicPage;
    259 		Set_Logic_Page(PseudoSeenBuff);
    260 		if (Stage <22) {
    261 			Play_Sample(Clock1, 255, Options.Normalize_Sound(70));
    262 		} else {
    263 			if (Stage==24) {
    264 				Play_Sample(CashTurn, 255, Options.Normalize_Sound(70));
    265 			}
    266 		}
    267 		CC_Draw_Shape(DataPtr,Stage, XPos, YPos, WINDOW_MAIN,SHAPE_WIN_REL, 0, 0);
    268 		Set_Logic_Page(oldpage);
    269 	}
    270 }
    271 
    272 
    273 ScorePrintClass::ScorePrintClass(int string, int xpos, int ypos, void const * palette, int background) :
    274 	ScoreAnimClass(xpos, ypos, Text_String(string))
    275 {
    276 	Background = background;
    277 	PrimaryPalette = palette;
    278 	Stage = 0;
    279 }
    280 
    281 
    282 ScorePrintClass::ScorePrintClass(void const * string, int xpos, int ypos, void const * palette, int background) :
    283 	ScoreAnimClass(xpos, ypos, string)
    284 {
    285 	Background = background;
    286 	PrimaryPalette = palette;
    287 	Stage = 0;
    288 }
    289 
    290 
    291 void ScorePrintClass::Update(void)
    292 {
    293 	static char localstr[2]={0,0};
    294 	static char _whitepal[]={0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F};
    295 
    296 	if (Stage && (((char *)DataPtr)[Stage-1]==0) ) {
    297 		for (int i = 0; i < MAXSCOREOBJS; i++) {
    298 			if (ScoreObjs[i] == this) {
    299 				ScoreObjs[i] = 0;
    300 			}
    301 		}
    302 		BlitList.Add (XPos*2, YPos*2, XPos*2, YPos*2,(Stage*6)+14, 8*2);
    303 		delete this;
    304 		return;
    305 	}
    306 
    307 	StillUpdating = true;
    308 
    309 	if (!Timer.Time()) {
    310 		Timer.Set(1);
    311 
    312 		int pos = XPos+(Stage*6);
    313 		if (Stage) {
    314 
    315 			localstr[0]=((char *)DataPtr)[Stage-1];
    316 
    317 			/*
    318 			** Clear out the white letter overlay
    319 			*/
    320 			static char const _blackpal[]={BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK};
    321 			Set_Font_Palette(_blackpal);
    322 			TextPrintBuffer->Print(localstr, 2*(pos-6),2*(YPos-1),   TBLACK, TBLACK);
    323 			TextPrintBuffer->Print(localstr, 2*(pos-6),2*(YPos+1),   TBLACK, TBLACK);
    324 			TextPrintBuffer->Print(localstr, 2*(pos-6+1),2*(YPos),   TBLACK, TBLACK);
    325 
    326 			Set_Font_Palette(PrimaryPalette);
    327 			TextPrintBuffer->Print(localstr, 2*(pos-6),2*YPos,   TBLACK, TBLACK);
    328 		}
    329 		if (((char *)DataPtr)[Stage]) {
    330 			localstr[0]=((char *)DataPtr)[Stage];
    331 			Set_Font_Palette(_whitepal);
    332 			TextPrintBuffer->Print(localstr, pos*2,  2*(YPos-1), TBLACK, TBLACK);
    333 			TextPrintBuffer->Print(localstr, pos*2,  2*(YPos+1), TBLACK, TBLACK);
    334 			TextPrintBuffer->Print(localstr, (pos+1)*2,2*YPos  , TBLACK, TBLACK);
    335 		}
    336 		Stage++;
    337 	}
    338 }
    339 
    340 
    341 
    342 
    343 
    344 
    345 
    346 
    347 
    348 
    349 
    350 MultiStagePrintClass::MultiStagePrintClass(int string, int xpos, int ypos, void const * palette, int background) :
    351 	ScoreAnimClass(xpos, ypos, Text_String(string))
    352 {
    353 	Background = background;
    354 	PrimaryPalette = palette;
    355 	Stage = 0;
    356 }
    357 
    358 
    359 MultiStagePrintClass::MultiStagePrintClass(void const * string, int xpos, int ypos, void const * palette, int background) :
    360 	ScoreAnimClass(xpos, ypos, string)
    361 {
    362 	Background = background;
    363 	PrimaryPalette = palette;
    364 	Stage = 0;
    365 }
    366 
    367 
    368 void MultiStagePrintClass::Update(void)
    369 {
    370 	static char localstr[2]={0,0};
    371 	static char _whitepal[]={0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F};
    372 
    373 	if (Stage && (((char *)DataPtr)[Stage-1]==0) ) {
    374 		for (int i = 0; i < MAXSCOREOBJS; i++) {
    375 			if (ScoreObjs[i] == this) {
    376 				ScoreObjs[i] = 0;
    377 			}
    378 		}
    379 		BlitList.Add (XPos*2, YPos*2, XPos*2, YPos*2,(Stage*6)+14, 8*2);
    380 		delete this;
    381 		return;
    382 	}
    383 
    384 	StillUpdating = true;
    385 
    386 	if (!Timer.Time()) {
    387 		Timer.Set(1);
    388 
    389 		/*
    390 		** Do 10 stages at once
    391 		*/
    392 		for (int wibble = 0 ; wibble < 10 ; wibble ++){
    393 
    394 			int pos = XPos+(Stage*6);
    395 			if (Stage) {
    396 
    397 				localstr[0]=((char *)DataPtr)[Stage-1];
    398 
    399 				/*
    400 				** Clear out the white letter overlay
    401 				*/
    402 				static char const _blackpal[]={BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK,BLACK};
    403 				Set_Font_Palette(_blackpal);
    404 				TextPrintBuffer->Print(localstr, 2*(pos-6),2*(YPos-1),   TBLACK, TBLACK);
    405 				TextPrintBuffer->Print(localstr, 2*(pos-6),2*(YPos+1),   TBLACK, TBLACK);
    406 				TextPrintBuffer->Print(localstr, 2*(pos-6+1),2*(YPos),   TBLACK, TBLACK);
    407 
    408 				Set_Font_Palette(PrimaryPalette);
    409 				TextPrintBuffer->Print(localstr, 2*(pos-6),2*YPos,   TBLACK, TBLACK);
    410 			}
    411 			if (((char *)DataPtr)[Stage]) {
    412 				localstr[0]=((char *)DataPtr)[Stage];
    413 				Set_Font_Palette(_whitepal);
    414 				TextPrintBuffer->Print(localstr, pos*2,  2*(YPos-1), TBLACK, TBLACK);
    415 				TextPrintBuffer->Print(localstr, pos*2,  2*(YPos+1), TBLACK, TBLACK);
    416 				TextPrintBuffer->Print(localstr, (pos+1)*2,2*YPos  , TBLACK, TBLACK);
    417 			}
    418 			Stage++;
    419 
    420 			if ( ( (char *) DataPtr) [Stage-1] == 0 ) break;
    421 		}
    422 	}
    423 }
    424 
    425 
    426 
    427 
    428 
    429 
    430 ScoreScaleClass::ScoreScaleClass(void const * string, int xpos, int ypos, char const palette[]) :
    431 	ScoreAnimClass(xpos, ypos, string)
    432 {
    433 	Palette = &palette[0];
    434 	Stage = 5;
    435 }
    436 
    437 
    438 void ScoreScaleClass::Update(void)
    439 {
    440 	static int _destx[]={0,80,107,134,180,228};
    441 	static int _destw[]={6,20, 30, 40, 60, 80};
    442 
    443 	/*
    444 	** Restore the background for the scaled-up letter
    445 	*/
    446 	if (!Timer.Time()) {
    447 		Timer.Set(1);
    448 		if (Stage != 5) {
    449 			TextPrintBuffer->Blit(HidPage, _destx[Stage+1]*2, YPos*2, _destx[Stage+1]*2, YPos*2, _destw[Stage+1]*2, _destw[Stage+1]*2);
    450 			//SysMemPage.Blit(*PseudoSeenBuff, _destx[Stage+1], YPos, _destx[Stage+1], YPos, _destw[Stage+1], _destw[Stage+1]);
    451 		}
    452 		if (Stage) {
    453 			Set_Font_Palette(Palette);
    454 			TextPrintBuffer->Fill_Rect(0,0, 7*2,7*2, TBLACK);
    455 			TextPrintBuffer->Print((char *)DataPtr, 0,0,   TBLACK, TBLACK);
    456 			TextPrintBuffer->Scale(HidPage, 0,0, _destx[Stage]*2, YPos*2, 5*2,5*2, _destw[Stage]*2, _destw[Stage]*2, true);
    457 
    458 			//SysMemPage.Fill_Rect(0,0, 7,7, TBLACK);
    459 			//SysMemPage.Print((char *)DataPtr, 0,0,   TBLACK, TBLACK);
    460 			//SysMemPage.Scale(*PseudoSeenBuff, 0,0, _destx[Stage], YPos, 5,5, _destw[Stage], _destw[Stage], true);
    461 			Stage--;
    462 		} else {
    463 			Set_Font_Palette(Palette);
    464 			for (int i = 0; i < MAXSCOREOBJS; i++) {
    465 				if (ScoreObjs[i]==this) ScoreObjs[i] = 0;
    466 			}
    467 			TextPrintBuffer->Print((char *)DataPtr, XPos*2,YPos*2,   TBLACK, TBLACK);
    468 			//TextPrintBuffer->Blit(HidPage, XPos*2, YPos*2, XPos*2, YPos*2,2*6,2*6);
    469 			//BlitList.Add (XPos, YPos, XPos, YPos, 6,6);
    470 
    471 			//SysMemPage.Print((char *)DataPtr, XPos,YPos,   TBLACK, TBLACK);
    472 			//SysMemPage.Blit(*PseudoSeenBuff, XPos,YPos, XPos, YPos, 6,6);
    473 			delete this;
    474 			return;
    475 		}
    476 	}
    477 }
    478 
    479 int Alloc_Object(ScoreAnimClass *obj)
    480 {
    481 	int i,ret;
    482 
    483 	for (i = ret = 0; i < MAXSCOREOBJS; i++) {
    484 		if (!ScoreObjs[i]) {
    485 			ScoreObjs[i] = obj;
    486 			ret = i;
    487 			break;
    488 		}
    489 	}
    490 	return(ret);
    491 }
    492 
    493 
    494 
    495 
    496 
    497 TextBlitClass::TextBlitClass (void)
    498 {
    499 	Clear();
    500 }
    501 
    502 
    503 
    504 void TextBlitClass::Add (int x, int y, int dx, int dy, int w, int h)
    505 {
    506 	if ( Count < MAX_ENTRIES ){
    507 
    508 		BlitListo [Count].SourceX	= x;
    509 		BlitListo [Count].SourceY	= y;
    510 		BlitListo [Count].DestX 	= dx;
    511 		BlitListo [Count].DestY 	= dy;
    512 		BlitListo [Count].Width		= w;
    513 		BlitListo [Count].Height	= h;
    514 
    515 		Count++;
    516 	}
    517 }
    518 
    519 
    520 void TextBlitClass::Clear(void)
    521 {
    522 	Count = 0;
    523 }
    524 
    525 
    526 
    527 
    528 void TextBlitClass::Update(void)
    529 {
    530 	if (TextPrintBuffer){
    531 
    532 		if (HidPage.Lock()){
    533 
    534 			for (int i=0 ; i<Count ; i++){
    535 
    536 				TextPrintBuffer->Blit (HidPage, BlitListo[i].SourceX,
    537 													BlitListo[i].SourceY,
    538 													BlitListo[i].DestX,
    539 													BlitListo[i].DestY,
    540 													BlitListo[i].Width,
    541 													BlitListo[i].Height,
    542 													true);
    543 			}
    544 
    545 			HidPage.Unlock();
    546 		}
    547 	}
    548 }
    549 
    550 
    551 
    552 void Disable_Uncompressed_Shapes (void);
    553 void Enable_Uncompressed_Shapes (void);
    554 
    555 /***********************************************************************************************
    556  * ScoreClass::Presentation -- Main routine to display score screen.                           *
    557  *                                                                                             *
    558  *    This is the main routine that displays the score screen graphics.                        *
    559  *    It gets called at the end of each scenario and is used to present                        *
    560  *    the results and a rating of the player's battle.                                         *
    561  *                                                                                             *
    562  * INPUT:   none                                                                               *
    563  *                                                                                             *
    564  * OUTPUT:  none                                                                               *
    565  *                                                                                             *
    566  * WARNINGS:   none                                                                            *
    567  *                                                                                             *
    568  * HISTORY:                                                                                    *
    569  *   05/02/1994     : Created.                                                                 *
    570  *=============================================================================================*/
    571 void ScoreClass::Presentation(void)
    572 {
    573 	//static char const _redpal[]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x21,0x2F};
    574 	static char const _redpal[]={0x20,0x22,0x24,0x26,0x28,0x28,0x28,0x28,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x21,0x2F};
    575 	static char const _greenpal[]={0x10,0x12,0x14,0x16,0x18,0x18,0x18,0x18,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x10,0x1F};
    576 	static char const _bluepal[]={0x60,0x62,0x64,0x66,0x68,0x68,0x68,0x68,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x61,0x6F};
    577 	//static char const _bluepal[]={0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x61,0x6F};
    578 	static unsigned char const _yellowpal[]={0x0,0x0,0xEC,0x0,0xEB,0x0,0xEA,0x0,0xE9,0x0,0x0,0x0,0x0,0x0,0xED,0x0};
    579 	static int const _casuax[2]={144,146};
    580 	static int const _casuay[2]={ 78, 90};
    581 	static int const _gditxx[2]={150,224};
    582 	static int const _gditxy[2]={ 90, 90};
    583 	static int const _nodtxx[2]={150,224};
    584 	static int const _nodtxy[2]={102,102};
    585 //	static int _bargrx[2]={297,SCORETEXT_X+64};
    586 //	static int _bargry[2]={ 90,CASUALTY_Y + 2};
    587 	static int const _bldggy[2]={138,128};
    588 	static int const _bldgny[2]={150,140};
    589 
    590 //	int gdikilled, nodkilled, civkilled, max, i, k, shapenum;
    591 	int i;
    592 	int max;
    593 	void const * yellowptr;
    594 	void const * redptr;
    595 	CCFileClass file(FAME_FILE_NAME);
    596 	struct Fame hallfame[NUMFAMENAMES];
    597 	void *anim, *oldfont;
    598 	int oldfontxspacing = FontXSpacing;
    599 	int house = PlayerPtr->Class->House;		// 0 or 1
    600 	char inter_pal[15];
    601 
    602 	/*
    603 	** Choose an appropriate palette file for the interpolation
    604 	*/
    605 	if (house == HOUSE_GOOD){
    606 		sprintf(inter_pal,"SCORPAL1.PAL");
    607 	}else{
    608 		sprintf(inter_pal,"SNODPAL1.PAL");
    609 	}
    610 
    611 
    612 	if (Special.IsJurassic && AreThingiesEnabled) return;
    613 
    614 	PseudoSeenBuff = new GraphicBufferClass(320,200,(void*)NULL);
    615 	TextPrintBuffer = new GraphicBufferClass(SeenBuff.Get_Width(), SeenBuff.Get_Height(), (void*)NULL);
    616 	TextPrintBuffer->Clear();
    617 	BlitList.Clear();
    618 	Disable_Uncompressed_Shapes ();
    619 
    620 	ControlQ = 0;
    621 	FontXSpacing = 0;
    622 	Map.Override_Mouse_Shape(MOUSE_NORMAL);
    623 	Theme.Queue_Song(THEME_WIN1);
    624 
    625 	VisiblePage.Clear();
    626 	PseudoSeenBuff->Clear();
    627 	SysMemPage.Clear();
    628 	WWMouse->Erase_Mouse(&HidPage, TRUE);
    629 	HiddenPage.Clear();
    630 	Set_Palette(BlackPalette);
    631 
    632 	Set_Logic_Page(SysMemPage);
    633 
    634 	void const * country4 = MixFileClass::Retrieve("COUNTRY4.AUD");
    635 	void const * sfx4 = MixFileClass::Retrieve("SFX4.AUD");
    636 	Beepy6 = MixFileClass::Retrieve("BEEPY6.AUD");
    637 
    638 	/*
    639 	** Load the background for the score screen
    640 	*/
    641 	anim = Open_Animation(ScreenNames[house],NULL,0L,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),Palette);
    642 
    643 	unsigned minutes = (unsigned)((ElapsedTime / (long)TIMER_MINUTE))+1;
    644 
    645 	/*
    646 	**	Determine leadership rating.
    647 	*/
    648 	unsigned leadership = 0;
    649 	int index;
    650 	for (index = 0; index < Logic.Count(); index++) {
    651 		ObjectClass * object = Logic[index];
    652 		if (object->Owner() == house) {
    653 			leadership++;
    654 		}
    655 	}
    656 
    657 	HouseClass *houses[3];
    658 	for (index = 0; index < 3; index++) {
    659 		houses[index] =(HouseClass::As_Pointer((HousesType)(HOUSE_GOOD+index)));
    660 	}
    661 
    662 	GKilled  = (HouseClass::As_Pointer(HOUSE_GOOD))->UnitsLost;
    663 	NKilled  = (HouseClass::As_Pointer(HOUSE_BAD))->UnitsLost;
    664 	CKilled  = (HouseClass::As_Pointer(HOUSE_NEUTRAL))->UnitsLost;
    665 	GBKilled = (HouseClass::As_Pointer(HOUSE_GOOD))->BuildingsLost;
    666 	NBKilled = (HouseClass::As_Pointer(HOUSE_BAD))->BuildingsLost;
    667 	CBKilled = (HouseClass::As_Pointer(HOUSE_NEUTRAL))->BuildingsLost;
    668 
    669 	/*
    670 	** New  - ST 6/12/96 2:40PM
    671 	*/
    672 	GHarvested = (HouseClass::As_Pointer(HOUSE_GOOD))->HarvestedCredits;
    673 	NHarvested = (HouseClass::As_Pointer(HOUSE_BAD))->HarvestedCredits;
    674 
    675 	if (!leadership) leadership++;
    676 	leadership = Cardinal_To_Fixed(GKilled+GBKilled+leadership, leadership);
    677 	leadership = Fixed_To_Cardinal(100, leadership);
    678 	if (leadership > 100) leadership = 100;
    679 
    680 	/*
    681 	**	Determine efficiency rating.
    682 	*/
    683 	int gharv = GHarvested;
    684 	int init = PlayerPtr->InitialCredits;
    685 	int cred = PlayerPtr->Available_Money();
    686 
    687 	unsigned efficiency = Cardinal_To_Fixed( (house == HOUSE_GOOD ? GHarvested : NHarvested) + (unsigned)PlayerPtr->InitialCredits+1, (unsigned)PlayerPtr->Available_Money()+1);
    688 	if (!efficiency) efficiency++;
    689 	efficiency = Fixed_To_Cardinal(100, efficiency);
    690 
    691 	if (efficiency > 100) efficiency = 100;
    692 	/*
    693 	** Calculate total score
    694 	*/
    695 	long total = ((leadership * 40) + (4600) + (efficiency * 14))/100;
    696 	if (!total) total++;
    697 	total *= (BuildLevel+1);
    698 
    699 // Load up the shapes for the Nod score screen
    700 	if (house == HOUSE_GOOD) {
    701 		yellowptr = MixFileClass::Retrieve("BAR3YLW.SHP");
    702 		redptr = MixFileClass::Retrieve("BAR3RED.SHP");
    703 	}
    704 
    705 /* Change to the six-point font for Text_Print */
    706 	oldfont = Set_Font(ScoreFontPtr);
    707 	Call_Back();
    708 
    709 /* --- Now display the background animation --- */
    710 	Hide_Mouse();
    711 	Animate_Frame(anim, SysMemPage, 1);
    712 	SysMemPage.Blit(*PseudoSeenBuff);
    713 	Increase_Palette_Luminance (Palette , 30,30,30,63);
    714 	InterpolationPalette = Palette;
    715 	InterpolationPaletteChanged = TRUE;
    716 	Read_Interpolation_Palette(inter_pal);
    717 	Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff , inter_pal);
    718 	Fade_Palette_To(Palette, FADE_PALETTE_FAST, Call_Back);
    719 
    720 	Play_Sample(country4, 255, Options.Normalize_Sound(90));
    721 
    722 	int frame = 1;
    723 	StreamLowImpact = true;
    724 	while (frame < Get_Animation_Frame_Count(anim)) {
    725 		Animate_Frame(anim, *PseudoSeenBuff, frame++);
    726 		////////////////Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff , NULL);
    727 		Call_Back_Delay(2);
    728 	}
    729 	StreamLowImpact = false;
    730 	Call_Back();
    731 	Close_Animation(anim);
    732 
    733 	/*
    734 	** Background's up, so now load various shapes and animations
    735 	*/
    736 	void const * timeshape = MixFileClass::Retrieve("TIME.SHP");
    737 	ScoreObjs[0] = new ScoreTimeClass(233, 2, timeshape, 30, 4);
    738 
    739 	void const * hiscore1shape = MixFileClass::Retrieve("HISCORE1.SHP");
    740 	void const * hiscore2shape = MixFileClass::Retrieve("HISCORE2.SHP");
    741 	ScoreObjs[1] = new ScoreTimeClass(4, 97, hiscore1shape, 10, 4);
    742 	ScoreObjs[2] = new ScoreTimeClass(8, 172, hiscore2shape, 10, 4);
    743 
    744 	/* Now display the stuff */
    745 	PseudoSeenBuff->Blit(SysMemPage);
    746 
    747 
    748 	if (house == HOUSE_BAD) {
    749 
    750 		/*
    751 		** load the logo
    752 		*/
    753 		void const * logoptr = MixFileClass::Retrieve("LOGOS.SHP");
    754 		CC_Draw_Shape(logoptr, 1, 0, 0, WINDOW_MAIN, SHAPE_WIN_REL, 0, 0);
    755 
    756 		Bit_It_In_Scale(0,0, 128,104-16, &SysMemPage, PseudoSeenBuff, &SeenBuff , 1);
    757 	}
    758 
    759 	Set_Logic_Page(PseudoSeenBuff);
    760 
    761 #ifdef FRENCH
    762 	Alloc_Object(new ScorePrintClass(TXT_SCORE_TIME, 200,  3,_greenpal));
    763 #else
    764 	Alloc_Object(new ScorePrintClass(TXT_SCORE_TIME, 206,  3,_greenpal));
    765 #endif
    766 	Alloc_Object(new ScorePrintClass(TXT_SCORE_LEAD, 182, 26,_greenpal));
    767 	Alloc_Object(new ScorePrintClass(TXT_SCORE_EFFI, 182, 38,_greenpal));
    768 	Alloc_Object(new ScorePrintClass(TXT_SCORE_TOTA, 182, 50,_greenpal));
    769 	Play_Sample(sfx4, 255, Options.Normalize_Sound(120));
    770 	Call_Back_Delay(13);
    771 
    772 	max = MAX((long)leadership, (long)efficiency);
    773 	int scorecounter = 0;
    774 	Keyboard::Clear();
    775 
    776 	BlitList.Add (264*2, 26*2, 264*2, 26*2, 4*12 , 12);
    777 	BlitList.Add (264*2, 38*2, 264*2, 38*2, 4*12 , 12);
    778 	BlitList.Add (264*2, 50*2, 264*2, 50*2, 4*12 , 12);
    779 	BlitList.Add (275*2, 9*2, 275*2, 9*2, 64, 12 );	//Minutes
    780 	for (i = 0; i <= 160; i++) {
    781 		Set_Font_Palette(_greenpal);
    782 		Count_Up_Print("%3d%%", i,    leadership,         264, 26);
    783 		if (i>=30) Count_Up_Print("%3d%%", i-30,    efficiency,         264, 38);
    784 		if (i>=60) {
    785 			Count_Up_Print("%3d",scorecounter, total,         264, 50);
    786 			scorecounter += total/100;
    787 		}
    788 		Print_Minutes(minutes);
    789 		Call_Back_Delay(1);
    790 		Play_Sample(Beepy6, 255, Options.Normalize_Sound(60));
    791 		if (Check_Key() && i < (max-5) ) {
    792 			i=158;
    793 			Keyboard::Clear();
    794 		}
    795 	}
    796 	Count_Up_Print("%3d", total, total, 264, 50);
    797 
    798 	Call_Back_Delay(60);
    799 
    800 	if (house == HOUSE_BAD) Show_Credits(house, _greenpal);
    801 
    802 	Call_Back_Delay(60);
    803 
    804 	/*
    805 	** Show stats on # of units killed
    806 	*/
    807 	Set_Logic_Page(*PseudoSeenBuff);
    808 	Play_Sample(sfx4, 255, Options.Normalize_Sound(90));
    809 	Alloc_Object(new ScorePrintClass(TXT_SCORE_CASU, _casuax[house], _casuay[house],_redpal));
    810 	Call_Back_Delay(9);
    811 	if (house == HOUSE_BAD) {
    812 		Alloc_Object(new ScorePrintClass(TXT_SCORE_NEUT, 200, 114,_redpal));
    813 		Call_Back_Delay(4);
    814 	}
    815 
    816 	Alloc_Object(new ScorePrintClass(TXT_SCORE_GDI, _gditxx[house], _gditxy[house],_redpal));
    817 	Alloc_Object(new ScorePrintClass(TXT_SCORE_NOD, _nodtxx[house], _nodtxy[house],_redpal));
    818 	Call_Back_Delay(6);
    819 
    820 	Set_Font_Palette(_redpal);
    821 	if (house == HOUSE_BAD) {
    822 		Do_Nod_Casualties_Graph();
    823 	} else {
    824 		Do_GDI_Graph(yellowptr, redptr, GKilled + CKilled, NKilled, 88);
    825 	}
    826 
    827 	Set_Logic_Page(*PseudoSeenBuff);
    828 
    829 	/*
    830 	** Print out stats on buildings destroyed
    831 	*/
    832 	Play_Sample(sfx4, 255, Options.Normalize_Sound(90));
    833 	if (house == HOUSE_GOOD) {
    834 		Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL, 144, 126,_greenpal));
    835 		Call_Back_Delay(9);
    836 	} else {
    837 		Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL1, 146, 128,_greenpal));
    838 		Alloc_Object(new ScorePrintClass(TXT_SCORE_BUIL2, 146, 136,_greenpal));
    839 		Call_Back_Delay(9);
    840 		Alloc_Object(new ScorePrintClass(TXT_SCORE_NEUT, 200, 152,_greenpal));
    841 		Call_Back_Delay(4);
    842 	}
    843 	Alloc_Object(new ScorePrintClass(TXT_SCORE_GDI, _gditxx[house], _bldggy[house],_greenpal));
    844 	Alloc_Object(new ScorePrintClass(TXT_SCORE_NOD, _gditxx[house], _bldgny[house],_greenpal));
    845 	Call_Back_Delay(7);
    846 
    847 	if (house==HOUSE_BAD) {
    848 		Call_Back_Delay(6);
    849 		Set_Font_Palette(_greenpal);
    850 		Do_Nod_Buildings_Graph();
    851 	} else {
    852 		Do_GDI_Graph(yellowptr, redptr, GBKilled + CBKilled, NBKilled, 136);
    853 	}
    854 
    855 	// Wait for text printing to complete
    856 	while (StillUpdating){
    857 		Call_Back_Delay(1);
    858 	}
    859 
    860 	if (Keyboard::Check()) Keyboard::Clear();
    861 
    862 	if (house == HOUSE_GOOD) Show_Credits(house, _greenpal);
    863 
    864 	/*
    865 	** Hall of fame display and processing
    866 	*/
    867 	Play_Sample(sfx4, 255, Options.Normalize_Sound(90));
    868 	Alloc_Object(new ScorePrintClass(TXT_SCORE_TOP, 28, 110,_bluepal));
    869 	Call_Back_Delay(9);
    870 
    871 	/*
    872 	** First check for the existence of the file, and if there isn't one,
    873 	** make a new one filled with blanks.
    874 	*/
    875 	if (!file.Is_Available()) {
    876 
    877 		// hall of fame doesn't exist, so blank it out & write it
    878 		file.Open(WRITE);
    879 
    880 		for (i = 0; i < NUMFAMENAMES; i++) {
    881 			hallfame[i].name[0] =
    882 			hallfame[i].score   =
    883 			hallfame[i].level   = 0;
    884 			file.Write(&hallfame[i], sizeof(struct Fame));
    885 		}
    886 
    887 		file.Close();
    888 	}
    889 
    890 	file.Open(READ);
    891 	for (i = 0; i < NUMFAMENAMES; i++) {
    892 		file.Read(&hallfame[i], sizeof(struct Fame));
    893 	}
    894 	file.Close();
    895 
    896 	/*
    897 	** If the player's score is good enough to bump someone off the list,
    898 	** remove their data, move everyone down a notch, and set index = where
    899 	** their info goes
    900 	*/
    901 	if(hallfame[NUMFAMENAMES-1].score >= total)
    902 								hallfame[NUMFAMENAMES-1].score = 0;
    903 	for (index = 0; index < NUMFAMENAMES; index++) {
    904 		if (total > hallfame[index].score) {
    905 			if (index < (NUMFAMENAMES-1)) for (i = (NUMFAMENAMES-1); i > index; i--) hallfame[i] = hallfame[i-1];
    906 			hallfame[index].score = total;
    907 			hallfame[index].level = Scenario;
    908 //			hallfame[index].level = BuildLevel;
    909 			//hallfame[index].name[0] = 0;	// blank out the name
    910 			memset (hallfame[index].name, ' ', sizeof (hallfame[index].name) -1);
    911 			hallfame[index].name[sizeof (hallfame[index].name)-1] = 0;
    912 			break;
    913 		}
    914 	}
    915 
    916 	/*
    917 	** Now display the hall of fame
    918 	*/
    919 	Set_Logic_Page(*PseudoSeenBuff);
    920 	for (i = 0; i < NUMFAMENAMES; i++) {
    921 		Alloc_Object(new ScorePrintClass(hallfame[i].name, HALLFAME_X, HALLFAME_Y + (i*8), _bluepal));
    922 		if (hallfame[i].score) {
    923 			char *str = (char *)(SysMemPage.Get_Buffer()) + i*32;
    924 			sprintf(str,"%d", hallfame[i].score);
    925 			Alloc_Object(new ScorePrintClass(str, HALLFAME_X+(6*15), HALLFAME_Y + (i*8), _bluepal, BLACK));
    926 			if (hallfame[i].level < 20) {
    927 				sprintf(str+16,"%d", hallfame[i].level);
    928 			} else {
    929 				strcpy(str+16, "**");
    930 			}
    931 			Alloc_Object(new ScorePrintClass(str+16, HALLFAME_X+(6*12), HALLFAME_Y + (i*8), _bluepal, BLACK));
    932 			Call_Back_Delay(13);
    933 		}
    934 	}
    935 
    936 	// Wait for text printing to complete
    937 	while (StillUpdating){
    938 		Call_Back_Delay(1);
    939 	}
    940 
    941 	/*
    942 	** If the player's on the hall of fame, have him enter his name now
    943 	*/
    944 	Keyboard::Clear();
    945 	if (index < NUMFAMENAMES) {
    946 		Input_Name(hallfame[index].name, HALLFAME_X, HALLFAME_Y + (index*8), _bluepal);
    947 
    948 		file.Open(WRITE);
    949 		for (i = 0; i < NUMFAMENAMES; i++) {
    950 			file.Write(&hallfame[i], sizeof(struct Fame));
    951 		}
    952 		file.Close();
    953 	} else {
    954 #ifdef FRENCH
    955 		Alloc_Object(new ScorePrintClass(TXT_MAP_CLICK2, 145, 190, _yellowpal));
    956 #else
    957 		Alloc_Object(new ScorePrintClass(TXT_MAP_CLICK2, 149, 190, _yellowpal));
    958 #endif
    959 		Cycle_Wait_Click();
    960 	}
    961 
    962 #ifdef WRITE_LBM
    963 	file.Open("e:scorscrn.lbm",WRITE);
    964 	SeenBuff.Blit(SysMemPage,0,0, 0,0, 320,200);
    965 	CCWrite_LBM_File(file, SysMemPage, 8, Palette);
    966 	file.Close();
    967 #endif
    968 
    969 	Keyboard::Clear();
    970 
    971 /* get rid of all the animating objects */
    972 	for (i = 0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) {
    973 		delete ScoreObjs[i];
    974 		ScoreObjs[i] = 0;
    975 	}
    976 	Fade_Palette_To(BlackPalette, FADE_PALETTE_FAST, NULL);
    977 	VisiblePage.Clear();
    978 
    979 	Show_Mouse();
    980 //	Map_Selection();
    981 
    982 	Theme.Queue_Song(THEME_NONE);
    983 
    984 	Fade_Palette_To(BlackPalette, FADE_PALETTE_FAST, NULL);
    985 	VisiblePage.Clear();
    986 	Set_Palette(GamePalette);
    987 
    988 	Set_Font(oldfont);
    989 	FontXSpacing = oldfontxspacing;
    990 	ControlQ = 0;
    991 
    992 	Set_Logic_Page (SeenBuff);
    993 
    994 	delete PseudoSeenBuff;
    995 	delete TextPrintBuffer;
    996 	TextPrintBuffer = NULL;
    997 	BlitList.Clear();
    998 	Enable_Uncompressed_Shapes();
    999 }
   1000 
   1001 // ST = 12/17/2018 5:44PM
   1002 #ifndef TickCount
   1003 extern TimerClass					TickCount;
   1004 #endif
   1005 
   1006 void Cycle_Wait_Click(void)
   1007 {
   1008 	int counter = 0;
   1009 	int minclicks = 20;
   1010 	unsigned long timingtime = TickCount.Time();
   1011 	//SerialPacketType sendpacket;
   1012 	//SerialPacketType receivepacket;
   1013 	//int packetlen;
   1014 
   1015 
   1016 	Keyboard::Clear();
   1017 	while (minclicks || (!Check_Key() && !ControlQ) ) {
   1018 
   1019 		if (GameToPlay == GAME_NULL_MODEM ||
   1020 			GameToPlay == GAME_MODEM){
   1021 			//GameToPlay == GAME_INTERNET) {
   1022 #if (0)	//PG_TO_FIX
   1023 			//
   1024 			// send a timing packet if enough time has gone by.
   1025 			//
   1026 			if ( (TickCount.Time() - timingtime) > PACKET_TIMING_TIMEOUT) {
   1027 				sendpacket.Command = SERIAL_SCORE_SCREEN;
   1028 				sendpacket.ResponseTime = NullModem.Response_Time();
   1029 				sendpacket.ID = ModemGameToPlay;
   1030 
   1031 				NullModem.Send_Message (&sendpacket, sizeof(sendpacket), 0);
   1032 				timingtime = TickCount.Time();
   1033 			}
   1034 
   1035 			if (NullModem.Get_Message (&receivepacket, &packetlen) > 0) {
   1036 				// throw packet away
   1037 				packetlen = packetlen;
   1038 			}
   1039 
   1040 			NullModem.Service();
   1041 #endif
   1042 		}
   1043 
   1044 		Call_Back_Delay(1);
   1045 		if (minclicks) {
   1046 			minclicks--;
   1047 			Keyboard::Clear();
   1048 		}
   1049 
   1050 		counter = ((++counter) & 7);
   1051 
   1052 		if (!counter) {
   1053 			unsigned char r,g,b;
   1054 
   1055 			r = Palette[233*3+0];
   1056 			g = Palette[233*3+1];
   1057 			b = Palette[233*3+2];
   1058 
   1059 			for (int i = 233; i < 237; i++) {
   1060 				Palette[i*3+0] = Palette[(i+1)*3+0];
   1061 				Palette[i*3+1] = Palette[(i+1)*3+1];
   1062 				Palette[i*3+2] = Palette[(i+1)*3+2];
   1063 			}
   1064 			Palette[237*3+0] = r;
   1065 			Palette[237*3+1] = g;
   1066 			Palette[237*3+2] = b;
   1067 
   1068 			Set_Palette(Palette);
   1069 		}
   1070 	}
   1071 	Keyboard::Clear();
   1072 }
   1073 
   1074 void ScoreClass::Do_Nod_Buildings_Graph(void)
   1075 {
   1076 	int shapenum;
   1077 	InfantryTypeClass const *ramboclass;
   1078 
   1079 	void const * factptr   = MixFileClass::Retrieve("FACT.SHP");
   1080 	void const * rmboptr   = MixFileClass::Retrieve("RMBO.SHP");
   1081 	void const * fball1ptr = MixFileClass::Retrieve("FBALL1.SHP");
   1082 	ramboclass = &InfantryTypeClass::As_Reference(INFANTRY_E5);
   1083 
   1084 	/*
   1085 	** Print the # of buildings on the hidpage so we only need to do it once
   1086 	*/
   1087 	PseudoSeenBuff->Blit(SysMemPage);
   1088 	Set_Logic_Page(SysMemPage);
   1089 	Call_Back_Delay(30);
   1090 	BlitList.Add (2* (BUILDING_X + 8), 2* (BUILDING_Y), 2* (BUILDING_X+8), 2* (BUILDING_Y), 5*12 , 12);
   1091 	BlitList.Add (2* (BUILDING_X + 8), 2* (BUILDING_Y + 12), 2* (BUILDING_X+8), 2* (BUILDING_Y + 12), 5*12 , 12);
   1092 	BlitList.Add (2* (BUILDING_X + 8), 2* (BUILDING_Y + 24), 2* (BUILDING_X+8), 2* (BUILDING_Y + 24), 5*12 , 12);
   1093 
   1094 	TextPrintBuffer->Print( 0, (BUILDING_X + 8)*2, BUILDING_Y*2,      TBLACK, TBLACK);
   1095 	TextPrintBuffer->Print( 0, (BUILDING_X + 8)*2, (BUILDING_Y + 12)*2, TBLACK, TBLACK);
   1096 	TextPrintBuffer->Print( 0, (BUILDING_X + 8)*2, (BUILDING_Y + 24)*2, TBLACK, TBLACK);
   1097 
   1098 	/*
   1099 	** Here's the animation/draw loop for blowing up the factory
   1100 	*/
   1101 	int i;
   1102 	for (i=0; i<98; i++) {
   1103 		SysMemPage.Blit(SysMemPage, BUILDING_X, BUILDING_Y, 0, 0, 320-BUILDING_X,48);
   1104 		shapenum = 0;	// no damage
   1105 		if (i >= 60) {
   1106 			shapenum = Extract_Shape_Count(factptr) - 2;	// some damage
   1107 			if (i == 60) {
   1108 				Shake_The_Screen(6);
   1109 				Sound_Effect(VOC_CRUMBLE, VOL_FULL, 0);
   1110 			}
   1111 			if (i > 65) {
   1112 				shapenum = Extract_Shape_Count(factptr) - 1;	// mega damage
   1113 			}
   1114 		}
   1115 
   1116 		/*
   1117 		** Draw the building before Rambo
   1118 		*/
   1119 		if (i < 68) {
   1120 			CC_Draw_Shape(factptr,shapenum, 0, 0, WINDOW_MAIN,
   1121 					  SHAPE_FADING|SHAPE_WIN_REL, ScoreRemapBldg,Map.UnitShadow);
   1122 
   1123 		}
   1124 
   1125 		/*
   1126 		** Now draw some fires, if appropriate
   1127 		*/
   1128 		if (i >= 61) {
   1129 			int firecount = Extract_Shape_Count(fball1ptr);
   1130 			int shapeindex = (i-61)>>1;
   1131 			if (shapeindex < firecount) {
   1132 				CC_Draw_Shape(fball1ptr, shapeindex, 10, 10, WINDOW_MAIN,
   1133 					  SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL,//|SHAPE_GHOST,
   1134 					  ScoreRemapFBall,0);
   1135 			}
   1136 			if (i > 64) {
   1137 				shapeindex = (i-64)>>1;
   1138 				if (shapeindex < firecount) {
   1139 					CC_Draw_Shape(fball1ptr, shapeindex, 50, 30, WINDOW_MAIN,
   1140 						  SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL,//|SHAPE_GHOST,
   1141 						  ScoreRemapFBall,0);
   1142 				}
   1143 			}
   1144 		}
   1145 		/*
   1146 		** Draw the Rambo character running away from the building
   1147 		*/
   1148 		CC_Draw_Shape(rmboptr, (ramboclass->DoControls[DO_WALK].Frame + ramboclass->DoControls[DO_WALK].Jump*6) + ((i>>1)%ramboclass->DoControls[DO_WALK].Count),
   1149 						  i+32, 40, WINDOW_MAIN,
   1150 						  SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL,//|SHAPE_GHOST,
   1151 						  ScoreRemapYellow,Map.UnitShadow);
   1152 		SysMemPage.Blit(*PseudoSeenBuff, 0, 0, BUILDING_X, BUILDING_Y, 320-BUILDING_X,48);
   1153 
   1154 		/*
   1155 		** Extra font related stuff. ST - 7/29/96 2:22PM
   1156 		*/
   1157 		Interpolate_2X_Scale(PseudoSeenBuff , &HidPage ,NULL);
   1158 		BlitList.Update();
   1159 		WWMouse->Draw_Mouse(&HidPage);
   1160 		Blit_Hid_Page_To_Seen_Buff();
   1161 		WWMouse->Erase_Mouse(&HidPage, TRUE);
   1162 		//Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff , NULL);
   1163 
   1164 		if (!Check_Key()) Call_Back_Delay(1);
   1165 	}
   1166 
   1167 	i = MAX(GBKilled, NBKilled);
   1168 	i = MAX(i, CBKilled);
   1169 
   1170 	for (int q = 0; q <= i; q++) {
   1171 		Count_Up_Print( "%d", q, GBKilled,BUILDING_X + 8,BUILDING_Y     );
   1172 		Count_Up_Print( "%d", q, NBKilled,BUILDING_X + 8,BUILDING_Y + 12);
   1173 		Count_Up_Print( "%d", q, CBKilled,BUILDING_X + 8,BUILDING_Y + 24);
   1174 		if (!Check_Key()) {
   1175 			Play_Sample(Beepy6, 255, Options.Normalize_Sound(110));
   1176 			Call_Back_Delay(1);
   1177 		}
   1178 	}
   1179 }
   1180 
   1181 
   1182 /***************************************************************************
   1183  * DO_GDI_GRAPH -- Show # of people or buildings killed on GDI score screen*
   1184  *                                                                         *
   1185  *                                                                         *
   1186  *                                                                         *
   1187  * INPUT:   yellowptr, redptr = pointers to shape file for graphs          *
   1188  *                                                                         *
   1189  * OUTPUT:                                                                 *
   1190  *                                                                         *
   1191  * WARNINGS:                                                               *
   1192  *                                                                         *
   1193  * HISTORY:                                                                *
   1194  *   05/03/1995 BWG : Created.                                             *
   1195  *=========================================================================*/
   1196 
   1197 void ScoreClass::Do_GDI_Graph(void const * yellowptr, void const * redptr, int gkilled, int nkilled, int ypos)
   1198 {
   1199 	int i, max;
   1200 	int gdikilled = gkilled, nodkilled=nkilled;
   1201 
   1202 	max = MAX(gdikilled, nodkilled);
   1203 	if (!max) max=1;
   1204 
   1205 	gdikilled = (gdikilled * SIZEGBAR) / max;
   1206 	nodkilled = (nodkilled * SIZEGBAR) / max;
   1207 	if (max < 20) {
   1208 		gdikilled = gkilled * 5;
   1209 		nodkilled = nkilled * 5;
   1210 	}
   1211 
   1212 	max = MAX(gdikilled, nodkilled);
   1213 	if (!max) max=1;
   1214 
   1215 	// Draw the white-flash shape on the hidpage
   1216 	Set_Logic_Page(SysMemPage);
   1217 	SysMemPage.Fill_Rect(0,0, 124,9, TBLACK);
   1218 	CC_Draw_Shape(redptr, 120, 0,0, WINDOW_MAIN,SHAPE_WIN_REL, 0, 0);
   1219 	Set_Logic_Page(PseudoSeenBuff);
   1220 
   1221 	BlitList.Add (2* 297, 2* (ypos+2), 2* 297, 2* (ypos+2), 5*12 , 12);
   1222 
   1223 	for (i = 1; i <= gdikilled; i++) {
   1224 		if (i != gdikilled) {
   1225 			CC_Draw_Shape(yellowptr,i, 172, ypos, WINDOW_MAIN,SHAPE_WIN_REL, 0, 0);
   1226 		} else {
   1227 			SysMemPage.Blit(*PseudoSeenBuff,0,0, 172, ypos, 3+gdikilled,9);
   1228 		}
   1229 
   1230 		Count_Up_Print("%d", (i*gkilled) / max, gkilled, 297, ypos+2);
   1231 		if (!Check_Key()) {
   1232 			Play_Sample(Beepy6, 255, Options.Normalize_Sound(110));
   1233 			Call_Back_Delay(2);
   1234 		}
   1235 	}
   1236 	CC_Draw_Shape(yellowptr,gdikilled, 172,ypos   , WINDOW_MAIN,SHAPE_WIN_REL, 0, 0);
   1237 	Count_Up_Print("%d", gkilled, gkilled, 297, ypos+ 2);
   1238 	if (!Check_Key()) Call_Back_Delay(40);
   1239 
   1240 	BlitList.Add (2* 297, 2* (ypos+14), 2* 297, 2* (ypos+14), 5*12 , 12);
   1241 	for (i = 1; i <= nodkilled; i++) {
   1242 		if (i != nodkilled) {
   1243 			CC_Draw_Shape(redptr, i, 172, ypos+12, WINDOW_MAIN,SHAPE_WIN_REL, 0, 0);
   1244 		} else {
   1245 			SysMemPage.Blit(*PseudoSeenBuff,0,0, 172,ypos+12, 3+nodkilled,9);
   1246 		}
   1247 
   1248 		Count_Up_Print("%d", (i*nkilled) / max, nkilled, 297, ypos+14);
   1249 		if (!Check_Key()) {
   1250 			Play_Sample(Beepy6, 255, Options.Normalize_Sound(110));
   1251 			Call_Back_Delay(2);
   1252 		}
   1253 	}
   1254 
   1255 //	if (Keyboard::Check()) Keyboard::Clear();
   1256 
   1257 	/*
   1258 	** Make sure accurate count is printed at end
   1259 	*/
   1260 	CC_Draw_Shape(   redptr,nodkilled, 172,ypos+12, WINDOW_MAIN,SHAPE_WIN_REL, 0, 0);
   1261 	Count_Up_Print("%d", nkilled, nkilled, 297, ypos+14);
   1262 	if (!Check_Key()) Call_Back_Delay(40);
   1263 }
   1264 
   1265 
   1266 void ScoreClass::Do_Nod_Casualties_Graph(void)
   1267 {
   1268 	int i, gdikilled, nodkilled, civkilled, max;
   1269 
   1270 	void const * e1ptr = MixFileClass::Retrieve("E1.SHP");
   1271 	void const * c1ptr = MixFileClass::Retrieve("C1.SHP");
   1272 
   1273 	gdikilled = GKilled;
   1274 	nodkilled = NKilled;
   1275 	civkilled = CKilled;
   1276 	max = MAX(gdikilled, nodkilled);
   1277 	max = MAX(max, civkilled);
   1278 
   1279 	if (!max) max=1;
   1280 	if ((gdikilled > (MAX_BAR_X - BARGRAPH_X)) || (nodkilled > (MAX_BAR_X - BARGRAPH_X)) || (civkilled > (MAX_BAR_X - BARGRAPH_X))) {
   1281 		gdikilled = (gdikilled * (MAX_BAR_X - BARGRAPH_X)) / max;
   1282 		nodkilled = (nodkilled * (MAX_BAR_X - BARGRAPH_X)) / max;
   1283 		civkilled = (civkilled * (MAX_BAR_X - BARGRAPH_X)) / max;
   1284 	}
   1285 
   1286 	max = MAX(gdikilled, nodkilled);
   1287 	max = MAX(max, civkilled);
   1288 	if (!max) max=1;
   1289 
   1290 	/*
   1291 	** Initialize a bunch of objects for the infantrymen who pose for the bar
   1292 	** graphs of casualties.
   1293 	*/
   1294 	int q = NUMINFANTRYMEN/3;
   1295 	int r = q*2;
   1296 	for (i = 0; i < NUMINFANTRYMEN/3; i++) {
   1297 		InfantryMan[i+0].xpos =
   1298 		InfantryMan[i+q].xpos =
   1299 		InfantryMan[i+r].xpos =  (i*10) + 7;
   1300 		InfantryMan[i+0].ypos = 11;
   1301 		InfantryMan[i+q].ypos = 21;
   1302 		InfantryMan[i+r].ypos = 31;
   1303 		InfantryMan[i+0].shapefile =
   1304 		InfantryMan[i+q].shapefile = e1ptr;
   1305 		InfantryMan[i+r].shapefile = c1ptr;
   1306 		InfantryMan[i+0].remap = ScoreRemapYellow;
   1307 		InfantryMan[i+q].remap = ScoreRemapGrey;
   1308 		InfantryMan[i+r].remap = RemapCiv;
   1309 		InfantryMan[i+0].anim  =
   1310 		InfantryMan[i+q].anim  =
   1311 		InfantryMan[i+r].anim  = 0;
   1312 		InfantryMan[i+0].stage =
   1313 		InfantryMan[i+q].stage =
   1314 		InfantryMan[i+r].stage = 0;
   1315 		InfantryMan[i+0].delay =
   1316 		InfantryMan[i+q].delay =
   1317 		InfantryMan[i+r].delay = Random() & 0x1F;
   1318 		InfantryMan[i+0].Class =
   1319 		InfantryMan[i+q].Class = &InfantryTypeClass::As_Reference(INFANTRY_E1);
   1320 		InfantryMan[i+r].Class = &InfantryTypeClass::As_Reference(INFANTRY_C1);
   1321 
   1322 	}
   1323 
   1324 	/*
   1325 	** Draw the infantrymen and pause briefly before running the graph
   1326 	*/
   1327 	Draw_InfantryMen();
   1328 	SysMemPage.Blit(*PseudoSeenBuff, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34);
   1329 	//Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff, NULL);
   1330 	/*
   1331 	** Extra font related stuff. ST - 7/29/96 2:22PM
   1332 	*/
   1333 	Interpolate_2X_Scale(PseudoSeenBuff , &HidPage ,NULL);
   1334 	BlitList.Update();
   1335 	WWMouse->Draw_Mouse(&HidPage);
   1336 	Blit_Hid_Page_To_Seen_Buff();
   1337 	WWMouse->Erase_Mouse(&HidPage, TRUE);
   1338 
   1339 	Call_Back_Delay(40);
   1340 
   1341 	BlitList.Add (2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 2), 2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 2), 5*12 , 12);
   1342 	BlitList.Add (2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 14), 2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 14), 5*12 , 12);
   1343 	BlitList.Add (2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 26), 2* (SCORETEXT_X + 64), 2* (CASUALTY_Y + 26), 5*12 , 12);
   1344 
   1345 	for (i = 1; i <= max; i++) {
   1346 		// Draw & update infantrymen 3 times for every tick on the graph (i)
   1347 		for (int q = 0; q < 3; q++) {
   1348 			Draw_InfantryMen();
   1349 			Draw_Bar_Graphs(i, gdikilled, nodkilled, civkilled);
   1350 			SysMemPage.Blit(*PseudoSeenBuff, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34);
   1351 
   1352 			Count_Up_Print("%d", (i*GKilled) / max, GKilled, SCORETEXT_X+64, CASUALTY_Y +  2);
   1353 			Count_Up_Print("%d", (i*NKilled) / max, NKilled, SCORETEXT_X+64, CASUALTY_Y + 14);
   1354 			Count_Up_Print("%d", (i*CKilled) / max, CKilled, SCORETEXT_X+64, CASUALTY_Y + 26);
   1355 			if (!Check_Key()) Call_Back_Delay(3);
   1356 		}
   1357 		Play_Sample(Beepy6, 255, Options.Normalize_Sound(110));
   1358 	}
   1359 	if (Check_Key()) Keyboard::Clear();
   1360 
   1361 	/*
   1362 	** Make sure accurate count is printed at end
   1363 	*/
   1364 	Count_Up_Print("%d", GKilled, GKilled, SCORETEXT_X+64, CASUALTY_Y +  2);
   1365 	Count_Up_Print("%d", NKilled, NKilled, SCORETEXT_X+64, CASUALTY_Y + 14);
   1366 	Count_Up_Print("%d", CKilled, CKilled, SCORETEXT_X+64, CASUALTY_Y + 26);
   1367 
   1368 	/*
   1369 	** Finish up death animations, if there are any active
   1370 	*/
   1371 	int k = 1;
   1372 	while (k) {
   1373 		for (i=k=0; i<NUMINFANTRYMEN; i++) if (InfantryMan[i].anim >= DO_GUN_DEATH) k=1;
   1374 		if (k) Draw_InfantryMen();
   1375 		Draw_Bar_Graphs(max, gdikilled, nodkilled, civkilled);
   1376 		SysMemPage.Blit(*PseudoSeenBuff, 0, 0, BARGRAPH_X, CASUALTY_Y, 320-BARGRAPH_X, 34);
   1377 		Call_Back_Delay(1);
   1378 	}
   1379 }
   1380 
   1381 
   1382 void ScoreClass::Show_Credits(int house, char const pal[])
   1383 {
   1384 	static int _credsx[2]={276,276};
   1385 	static int _credsy[2]={173,58};
   1386 	static int _credpx[2]={228,236};
   1387 #ifdef GERMAN
   1388 	static int _credpy[2]={181, 74};
   1389 	static int _credtx[2]={162,162};
   1390 	static int _credty[2]={173, 62};
   1391 #else
   1392 	static int _credpy[2]={189-12, 74};
   1393 	static int _credtx[2]={182,182};
   1394 	static int _credty[2]={179-12, 62};
   1395 #endif
   1396 
   1397 	int credobj,i;
   1398 	int min,add;
   1399 
   1400 	void const * credshape = MixFileClass::Retrieve("CREDS.SHP");
   1401 
   1402 	Alloc_Object(new ScorePrintClass(TXT_SCORE_ENDCRED, _credtx[house], _credty[house],pal));
   1403 	Call_Back_Delay(15);
   1404 
   1405 	credobj = Alloc_Object(new ScoreCredsClass(_credsx[house], _credsy[house], credshape, 32, 2));
   1406 	min = PlayerPtr->Available_Money() / 100;
   1407 
   1408 	/*
   1409 	** Print out total credits left at end of scenario
   1410 	*/
   1411 	i = -50;
   1412 
   1413 	BlitList.Add (2* (_credpx[house]), 2* (_credpy[house]), 2* (_credpx[house]), 2* (_credpy[house]), 5*12 , 12);
   1414 
   1415 	do {
   1416 		add = 5;
   1417 		if ((PlayerPtr->Available_Money() - i) > 100 ) add += 15;
   1418 		if ((PlayerPtr->Available_Money() - i) > 1000) add += 30;
   1419 		if (add < min) add = min;
   1420 		i += add;
   1421 
   1422 		if (i < 0) i=0;
   1423 
   1424 		Set_Font_Palette(pal);
   1425 		Count_Up_Print("%d", i, PlayerPtr->Available_Money(), _credpx[house], _credpy[house]);
   1426 		Call_Back_Delay(2);
   1427 		if (Check_Key()) {
   1428 			i=PlayerPtr->Available_Money() - 5;
   1429 			Keyboard::Clear();
   1430 		}
   1431 	} while (i < PlayerPtr->Available_Money()) ;
   1432 
   1433 	// Make sure the credits object doesn't freeze on the white stage
   1434 	while (((ScoreTimeClass *)ScoreObjs[credobj])->Stage >= 20 && !ControlQ) {
   1435 		Call_Back_Delay(1);
   1436 	}
   1437 	delete ScoreObjs[credobj];
   1438 	ScoreObjs[credobj] = 0;
   1439 }
   1440 
   1441 
   1442 /***************************************************************************
   1443  * SCORECLASS::PRINT_MINUTES -- Print out hours/minutes up to max          *
   1444  *                                                                         *
   1445  *    Same as count-up-print, but for the time                             *
   1446  *                                                                         *
   1447  * INPUT:   current minute count and maximum                               *
   1448  *                                                                         *
   1449  * OUTPUT:                                                                 *
   1450  *                                                                         *
   1451  * WARNINGS:                                                               *
   1452  *                                                                         *
   1453  * HISTORY:                                                                *
   1454  *   04/13/1995 BWG : Created.                                             *
   1455  *=========================================================================*/
   1456 void ScoreClass::Print_Minutes(int minutes)
   1457 {
   1458 	char str[20];
   1459 	if (minutes >= 60) {
   1460 		if ((minutes/60) > 9) minutes = (9*60 + 59);
   1461 		sprintf(str,Text_String(TXT_SCORE_TIMEFORMAT1), (minutes / 60),(minutes % 60));
   1462 	} else {
   1463 		sprintf(str,Text_String(TXT_SCORE_TIMEFORMAT2), minutes);
   1464 	}
   1465 	TextPrintBuffer->Print(str, 275*2, 9*2, TBLACK, TBLACK);
   1466 }
   1467 
   1468 
   1469 /***********************************************************************************************
   1470  * ScoreClass::Count_Up_Print -- Prints a number (up to its max) into a string, cleanly.       *
   1471  *                                                                                             *
   1472  *    This routine prints out a number (like 70) or its maximum number, into a string,   onto  *
   1473  *    the screen, on a clean section of the screen, and blits it forward to the seenpage so you*
   1474  *    can print without flashing and can print over something (to count up %'s).               *
   1475  *                                                                                             *
   1476  * INPUT:   str = string to print into                                                         *
   1477  *            percent = # to print                                                             *
   1478  *            max = # to print if percent > max                                                *
   1479  *            xpos = x pixel coord                                                             *
   1480  *            ypos = y pixel coord                                                             *
   1481  *                                                                                             *
   1482  * OUTPUT:  none                                                                               *
   1483  *                                                                                             *
   1484  * WARNINGS:   none                                                                            *
   1485  *                                                                                             *
   1486  * HISTORY:                                                                                    *
   1487  *   04/07/1995 BWG : Created.                                                                 *
   1488  *=============================================================================================*/
   1489 void ScoreClass::Count_Up_Print(char *str, int percent, int max, int xpos, int ypos)
   1490 {
   1491 	char destbuf[64];
   1492 	int width;
   1493 
   1494 	sprintf(destbuf, str, percent <= max ? percent : max);
   1495 	width = strlen(destbuf) * 7;
   1496 
   1497 
   1498 
   1499 
   1500 //	HidPage.Blit(HidPage, xpos, ypos, 0, 0, width, 8);
   1501 //	Set_Logic_Page(HidPage);
   1502 //	LogicPage->Print(	destbuf, 0, 0, WHITE, TBLACK);
   1503 //	HidPage.Blit(SeenBuff, 0, 0, xpos, ypos, width, 8);
   1504 
   1505 	TextPrintBuffer->Fill_Rect (xpos*2, ypos*2, (xpos + width)*2, (ypos+7)*2, BLACK);
   1506 	TextPrintBuffer->Print (destbuf, xpos*2, ypos*2, WHITE, TBLACK);
   1507 
   1508 
   1509 	//TextPrintBuffer->Blit(*TextPrintBuffer, xpos*2, ypos*2, 0, 0, width*2, 8*2);
   1510 	//TextPrintBuffer->Print(destbuf, 0, 0, WHITE, TBLACK);
   1511 	//TextPrintBuffer->Blit(SeenBuff, 0, 0, xpos*2, ypos*2, width*2, 8*2);
   1512 
   1513 //	PseudoSeenBuff->Print(	destbuf, xpos, ypos, TBLACK, BLACK);
   1514 //	Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff , NULL);
   1515 
   1516 }
   1517 
   1518 
   1519 /***********************************************************************************************
   1520  * ScoreClass::Input_Name -- Gets the name from the keyboard                                   *
   1521  *                                                                                             *
   1522  *      This routine handles keyboard input, and does a nifty zooming letter effect too.       *
   1523  *                                                                                             *
   1524  * INPUT:   str = string to put user's typing into                                             *
   1525  *            xpos = x pixel coord                                                             *
   1526  *            ypos = y pixel coord                                                             *
   1527  *            pal  = text remapping palette to print using                                     *
   1528  *                                                                                             *
   1529  * OUTPUT:  none                                                                               *
   1530  *                                                                                             *
   1531  * WARNINGS:   none                                                                            *
   1532  *                                                                                             *
   1533  * HISTORY:                                                                                    *
   1534  *   05/15/1995 BWG : Created.                                                                 *
   1535  *=============================================================================================*/
   1536 void ScoreClass::Input_Name(char str[], int xpos, int ypos, char const pal[])
   1537 {
   1538 	int key, ascii, index=0;
   1539 
   1540 	void const * keystrok = MixFileClass::Retrieve("KEYSTROK.AUD");
   1541 
   1542 	/*
   1543 	** Ready the hidpage so it can restore background under zoomed letters
   1544 	*/
   1545 	PseudoSeenBuff->Blit(SysMemPage);
   1546 
   1547 	do {
   1548 		Call_Back();
   1549 		Animate_Score_Objs();
   1550 		Animate_Cursor(index, ypos);
   1551 		/*
   1552 		** Extra font related stuff. ST - 7/29/96 2:22PM
   1553 		*/
   1554 		Interpolate_2X_Scale (PseudoSeenBuff , &HidPage ,NULL);
   1555 		BlitList.Update();
   1556 		Blit_Hid_Page_To_Seen_Buff();
   1557 
   1558 		if (Check_Key()) {						//if (Keyboard::Check()) {
   1559 			key = Get_Key();						//key = Keyboard::Get();
   1560 
   1561 			if (index == MAX_FAMENAME_LENGTH-2) {
   1562 				while (Check_Key()) {
   1563 					Get_Key();
   1564 				}
   1565 			}
   1566 
   1567 			/*
   1568 			** If they hit 'backspace' when they're on the last letter,
   1569 			** turn it into a space instead.
   1570 			*/
   1571 			if ((key == KA_BACKSPACE) && (index == MAX_FAMENAME_LENGTH-2) ) {
   1572 				if (str[index] && str[index]!=32) key = 32;
   1573 			}
   1574 			if (key == KA_BACKSPACE) {							//if (key == KN_BACKSPACE) {
   1575 				if (index) {
   1576 					str[--index] = 0;
   1577 
   1578 					int xposindex6 = xpos+(index*6);
   1579 
   1580 					PseudoSeenBuff->Fill_Rect(xposindex6,ypos,xposindex6+6,ypos+6,TBLACK);
   1581 					SysMemPage.Fill_Rect(xposindex6,ypos,xposindex6+6,ypos+6,TBLACK);
   1582 					TextPrintBuffer->Fill_Rect(xposindex6*2,ypos*2,(xposindex6+6)*2,(ypos+6)*2, BLACK);
   1583 				}
   1584 
   1585 			} else if (key!=KA_RETURN) {				//else if (key != KN_RETURN && key!=KN_KEYPAD_RETURN) {
   1586 				ascii = key;					//ascii = KN_To_KA(key);
   1587 				if (ascii >= 'a' && ascii <= 'z') ascii -= ('a' - 'A');
   1588 //if (ascii >='A' && ascii<='Z' || ascii == ' ') {
   1589 if ( (ascii >= '!' && ascii <= KA_TILDA) || ascii == ' ') {
   1590 					PseudoSeenBuff->Fill_Rect(xpos + (index*6), ypos, xpos + (index*6)+6, ypos+5, TBLACK);
   1591 					 SysMemPage.Fill_Rect(xpos + (index*6), ypos, xpos + (index*6)+6, ypos+5, TBLACK);
   1592 					TextPrintBuffer->Fill_Rect(2*(xpos + (index*6)), ypos*2, 2*(xpos + (index*6)+6), 2*(ypos+6), BLACK);
   1593 					str[index] = ascii;
   1594 					str[index+1] = 0;
   1595 
   1596 					int objindex;
   1597 					Play_Sample(keystrok, 255, Options.Normalize_Sound(255));
   1598 					objindex = Alloc_Object(new ScoreScaleClass(str+index,xpos+(index*6), ypos, pal));
   1599 					while (ScoreObjs[objindex]) Call_Back_Delay(1);
   1600 
   1601 					if (index < (MAX_FAMENAME_LENGTH-2) ) index++;
   1602 				}
   1603 			}
   1604 		}
   1605 	} while(key!=KA_RETURN);							//	} while(key != KN_RETURN && key!=KN_KEYPAD_RETURN);
   1606 }
   1607 
   1608 
   1609 void Animate_Cursor(int pos, int ypos)
   1610 {
   1611 	static int _lastpos, _state;
   1612 	static CountDownTimerClass _timer;
   1613 
   1614 	ypos += 7;	// move cursor to bottom of letter
   1615 
   1616 	// If they moved the cursor, erase old one and force state=0, to make green draw right away
   1617 	if (pos != _lastpos) {
   1618 		PseudoSeenBuff->Draw_Line(HALLFAME_X + (_lastpos*6),ypos, HALLFAME_X + (_lastpos*6) + 5, ypos, TBLACK);
   1619 		TextPrintBuffer->Fill_Rect(2*(HALLFAME_X + (_lastpos*6)),2*ypos, 2*(HALLFAME_X + (_lastpos*6) + 5), 2*ypos+1, BLACK);
   1620 		_lastpos = pos;
   1621 		_state = 0;
   1622 	}
   1623 
   1624 	PseudoSeenBuff->Draw_Line(HALLFAME_X + (pos*6),ypos, HALLFAME_X + (pos*6)+5, ypos, _state ? LTBLUE : TBLACK);
   1625 	TextPrintBuffer->Fill_Rect(2*(HALLFAME_X + (pos*6)),2*ypos, 2*(HALLFAME_X + (pos*6)+5), 2*ypos+1, _state ? LTBLUE : BLACK);
   1626 
   1627 	/*
   1628 	** Toggle the color of the cursor, green or black, if it's time to do so.
   1629 	*/
   1630 	if (!_timer.Time()) {
   1631 		_state ^= 1;
   1632 		_timer.Set(5);
   1633 	}
   1634 }
   1635 
   1636 
   1637 /***************************************************************************
   1638  * Draw_InfantryMen -- Draw all the guys on the score screen               *
   1639  *                                                                         *
   1640  *                                                                         *
   1641  *                                                                         *
   1642  * INPUT:                                                                  *
   1643  *                                                                         *
   1644  * OUTPUT:                                                                 *
   1645  *                                                                         *
   1646  * WARNINGS:                                                               *
   1647  *                                                                         *
   1648  * HISTORY:                                                                *
   1649  *   04/13/1995 BWG : Created.                                             *
   1650  *=========================================================================*/
   1651 void Draw_InfantryMen()
   1652 {
   1653 	int k;
   1654 
   1655 // Only draw the infantrymen if we're playing Nod... GDI wouldn't execute
   1656 //	people like that.
   1657 
   1658 	/*
   1659 	** First restore the background
   1660 	*/
   1661 	SysMemPage.Blit(SysMemPage, BARGRAPH_X, CASUALTY_Y, 0, 0, 320-BARGRAPH_X, 34);
   1662 	Set_Logic_Page(SysMemPage);
   1663 
   1664 	/*
   1665 	** Then draw all the infantrymen on the clean SysMemPage
   1666 	*/
   1667 	for (k = 0; k < NUMINFANTRYMEN; k++) Draw_InfantryMan(k);
   1668 	/*
   1669 	** They'll all be blitted over to the seenpage after the graphs are drawn
   1670 	*/
   1671 }
   1672 
   1673 /***************************************************************************
   1674  * Draw_InfantryMan -- Draw one guy in score screen, update animation      *
   1675  *                                                                         *
   1676  *    This routine draws one of the infantrymen in the "Casualties" area   *
   1677  *                                                                         *
   1678  * INPUT:                                                                  *
   1679  *                                                                         *
   1680  * OUTPUT:                                                                 *
   1681  *                                                                         *
   1682  * WARNINGS:                                                               *
   1683  *                                                                         *
   1684  * HISTORY:                                                                *
   1685  *   04/13/1995 BWG : Created.                                             *
   1686  *=========================================================================*/
   1687 void Draw_InfantryMan(int index)
   1688 {
   1689 	int stage;
   1690 
   1691 	/* If the infantryman's dead, just abort this function */
   1692 	if (InfantryMan[index].anim == -1) return;
   1693 
   1694 	stage = InfantryMan[index].stage + InfantryMan[index].Class->DoControls[InfantryMan[index].anim].Frame;
   1695 
   1696 	CC_Draw_Shape(InfantryMan[index].shapefile,
   1697 					  stage,
   1698 					  InfantryMan[index].xpos,
   1699 					  InfantryMan[index].ypos,
   1700 					  WINDOW_MAIN,
   1701 					  SHAPE_FADING|SHAPE_CENTER|SHAPE_WIN_REL,//|SHAPE_GHOST,
   1702 					  InfantryMan[index].remap,
   1703 					  Map.UnitShadow);
   1704 	/*
   1705 	** see if it's time to run a new anim
   1706 	*/
   1707 	if (--InfantryMan[index].delay < 0) {
   1708 		InfantryMan[index].delay = 3;
   1709 		if (++InfantryMan[index].stage >= InfantryMan[index].Class->DoControls[InfantryMan[index].anim].Count) {
   1710 
   1711 			/*
   1712 			** was he playing a death anim? If so, and it's done, erase him
   1713 			*/
   1714 			if (InfantryMan[index].anim >= DO_GUN_DEATH) {
   1715 				InfantryMan[index].anim = -1;
   1716 			} else {
   1717 				New_Infantry_Anim(index, DO_STAND_READY);
   1718 			}
   1719 		}
   1720 	}
   1721 }
   1722 
   1723 
   1724 /***************************************************************************
   1725  * New_Infantry_Anim -- Start up a new animation for one of the infantrymen*
   1726  *                                                                         *
   1727  *                                                                         *
   1728  *                                                                         *
   1729  * INPUT:   index: which of the 30 infantrymen to affect                   *
   1730  *          anim:  which animation sequence to start him into              *
   1731  * OUTPUT:                                                                 *
   1732  *                                                                         *
   1733  * WARNINGS:                                                               *
   1734  *                                                                         *
   1735  * HISTORY:                                                                *
   1736  *   04/13/1995 BWG : Created.                                             *
   1737  *=========================================================================*/
   1738 void New_Infantry_Anim(int index, int anim)
   1739 {
   1740 	InfantryMan[index].anim = anim;
   1741 	InfantryMan[index].stage = 0;
   1742 	if (anim >= DO_GUN_DEATH) {
   1743 		InfantryMan[index].delay = 1;	// start right away
   1744 	} else {
   1745 		InfantryMan[index].delay = Random() & 15;
   1746 	}
   1747 }
   1748 
   1749 
   1750 /***************************************************************************
   1751  * Draw_Bar_Graphs -- Draw "Casualties" bar graphs                         *
   1752  *                                                                         *
   1753  *                                                                         *
   1754  *                                                                         *
   1755  * INPUT:   i = current count of how far to draw graph                     *
   1756  *          gkilled = # of GDI forces killed (adjusted to fit in space)    *
   1757  *          nkilled = # of Nod forces killed (adjusted to fit in space)    *
   1758  *          ckilled = # of civilians killed (adjusted to fit in space)     *
   1759  * OUTPUT:                                                                 *
   1760  *                                                                         *
   1761  * WARNINGS:                                                               *
   1762  *                                                                         *
   1763  * HISTORY:                                                                *
   1764  *   04/13/1995 BWG : Created.                                             *
   1765  *=========================================================================*/
   1766 void Draw_Bar_Graphs(int i, int gkilled, int nkilled, int ckilled)
   1767 {
   1768 	if (gkilled) {
   1769 		LogicPage->Fill_Rect(0,   0+4, 0+MIN(i,gkilled),   0+5, LTCYAN);
   1770 		LogicPage->Draw_Line(0+1, 0+6, 0+MIN(i,gkilled)+1, 0+6, TBLACK);
   1771 		LogicPage->Draw_Line(0+MIN(i,gkilled)+1,0+5, 0+MIN(i,gkilled)+1, 0+5, TBLACK);
   1772 		if (i <= gkilled) {
   1773 			int anim = InfantryMan[i/11].anim;
   1774 			if (anim!=-1 && anim < DO_GUN_DEATH) {
   1775 				if (i/11) {
   1776 					New_Infantry_Anim(i/11,DO_GUN_DEATH + (Random() & 3));
   1777 				} else {
   1778 					New_Infantry_Anim(i/11,DO_GUN_DEATH);
   1779 				}
   1780 //				Sound_Effect(Random_Pick(VOC_SCREAM1, VOC_SCREAM5));
   1781 			}
   1782 		}
   1783 	}
   1784 	if (nkilled) {
   1785 		LogicPage->Fill_Rect(0,   0+16, 0+MIN(i,nkilled),   0+17, RED);
   1786 		LogicPage->Draw_Line(0+1, 0+18, 0+MIN(i,nkilled)+1, 0+18, TBLACK);
   1787 		LogicPage->Draw_Line(0+MIN(i,nkilled)+1, 0+17, 0+MIN(i,nkilled)+1, 0+17, TBLACK);
   1788 		if (i <= nkilled) {
   1789 			int anim = InfantryMan[(NUMINFANTRYMEN/3)+(i/11)].anim;
   1790 			if (anim!=-1 && anim < DO_GUN_DEATH) {
   1791 				if (i/11) {
   1792 					New_Infantry_Anim((NUMINFANTRYMEN/3)+(i/11),DO_GUN_DEATH + (Random() & 3));
   1793 				} else {
   1794 					New_Infantry_Anim((NUMINFANTRYMEN/3)+(i/11),DO_GUN_DEATH);
   1795 				}
   1796 //				Sound_Effect(Random_Pick(VOC_SCREAM1, VOC_SCREAM5));
   1797 			}
   1798 		}
   1799 	}
   1800 
   1801 	if (ckilled) {
   1802 		LogicPage->Fill_Rect(0,   0+28, 0+MIN(i,ckilled),   0+29, RED);
   1803 		LogicPage->Draw_Line(0+1, 0+30, 0+MIN(i,ckilled)+1, 0+30, TBLACK);
   1804 		LogicPage->Draw_Line(0+MIN(i,ckilled)+1, 0+29, 0+MIN(i,ckilled)+1, 0+29, TBLACK);
   1805 		if (i <= ckilled) {
   1806 			int anim = InfantryMan[((NUMINFANTRYMEN*2)/3)+(i/11)].anim;
   1807 			if (anim!=-1 && anim < DO_GUN_DEATH) {
   1808 				if (i/11) {
   1809 					New_Infantry_Anim(((NUMINFANTRYMEN*2)/3)+(i/11),DO_GUN_DEATH + (Random() & 3));
   1810 				} else {
   1811 					New_Infantry_Anim(((NUMINFANTRYMEN*2)/3)+(i/11),DO_GUN_DEATH);
   1812 				}
   1813 //				Sound_Effect(Random_Pick(VOC_SCREAM1, VOC_SCREAM5));
   1814 			}
   1815 		}
   1816 	}
   1817 }
   1818 
   1819 
   1820 /***************************************************************************
   1821  * Call_Back_Delay -- Combines Call_Back() and Delay() functions           *
   1822  *                                                                         *
   1823  *    This is just to cut down on code size and typing a little.           *
   1824  *                                                                         *
   1825  * INPUT:                                                                  *
   1826  *                                                                         *
   1827  * OUTPUT:                                                                 *
   1828  *                                                                         *
   1829  * WARNINGS:                                                               *
   1830  *                                                                         *
   1831  * HISTORY:                                                                *
   1832  *   04/13/1995 BWG : Created.                                             *
   1833  *=========================================================================*/
   1834 void Call_Back_Delay(int time)
   1835 {
   1836 	CountDownTimerClass cd;
   1837 
   1838 	if (!ControlQ) {
   1839 		if (Keyboard::Down(KN_LCTRL) && Keyboard::Down(KN_Q)) {
   1840 			ControlQ = 1;
   1841 			Keyboard::Clear();
   1842 		}
   1843 	}
   1844 	if (ControlQ) time=0;
   1845 
   1846 	cd.Set(time);
   1847 	StreamLowImpact = true;
   1848 	do {
   1849 		Call_Back();
   1850 		//Animate_Score_Objs();
   1851 		//Interpolate_2X_Scale(PseudoSeenBuff , &SeenBuff ,NULL);
   1852 
   1853 		//if (Get_Mouse_State()){
   1854 		//	Interpolate_2X_Scale(PseudoSeenBuff , &SeenBuff ,NULL);
   1855 			//BlitList.Update();
   1856 		//}else{
   1857 			Animate_Score_Objs();
   1858 			Interpolate_2X_Scale(PseudoSeenBuff , &HidPage ,NULL);
   1859 			BlitList.Update();
   1860 			WWMouse->Draw_Mouse(&HidPage);
   1861 			Blit_Hid_Page_To_Seen_Buff();
   1862 			WWMouse->Erase_Mouse(&HidPage, TRUE);
   1863 		//}
   1864 	} while(cd.Time());
   1865 	StreamLowImpact = false;
   1866 }
   1867 
   1868 
   1869 void Animate_Score_Objs()
   1870 {
   1871 	StillUpdating = false;
   1872 	for (int i = 0; i < MAXSCOREOBJS; i++) {
   1873 		if (ScoreObjs[i]) {
   1874 			ScoreObjs[i]->Update();
   1875 		}
   1876 	}
   1877 }
   1878 
   1879 char *Int_Print(int a)
   1880 {
   1881 	static char str[10];
   1882 
   1883 	sprintf(str,"%d",a);
   1884 	return str;
   1885 }
   1886 
   1887 
   1888 /***********************************************************************************************
   1889  * Multi_Score_Presentation -- Multiplayer routine to display score screen.                    *
   1890  *                                                                                             *
   1891  *                                                                                             *
   1892  * INPUT:   none                                                                               *
   1893  *                                                                                             *
   1894  * OUTPUT:  none                                                                               *
   1895  *                                                                                             *
   1896  * WARNINGS:   none                                                                            *
   1897  *                                                                                             *
   1898  * HISTORY:                                                                                    *
   1899  *   06/11/1995  BWG: Created.                                                                 *
   1900  *=============================================================================================*/
   1901 void Multi_Score_Presentation(void)
   1902 {
   1903 	static unsigned char const _cycleyellowpal[]={0x0,0xec,0xEb,0xea,0xE9,0xe9,0xE9,0x0,0xE9,0x0,0x0,0x0,0x0,0x0,0xED,0x0};
   1904 
   1905 	static unsigned char const _greenpal[]= {0x0,0x12,0x14,0x16,0x18,0x18,0x18,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x10,0x0};
   1906 	static unsigned char const _redpal[]=   {0x0,0x22,0x24,0x26,0x28,0x28,0x28,0x0,0x28,0x0,0x0,0x0,0x0,0x0,0x20,0x0};
   1907 	static unsigned char const _graypal[]=  {0x0,0xca,0xCb,0xcc,0xCd,0xcd,0xCd,0x0,0xCD,0x0,0x0,0x0,0x0,0x0,0xC8,0x0};
   1908 	static unsigned char const _orangepal[]={0x0,0xd1,0xD2,0xd3,0xD4,0xd4,0xD4,0x0,0xD4,0x0,0x0,0x0,0x0,0x0,0xD0,0x0};
   1909 	static unsigned char const _bluepal[]=  {0x0,0x2,0x0a,0xb,0x0b,0xb,0x0B,0x0,0x0B,0x0,0x0,0x0,0x0,0x0,0x09,0x0};
   1910 	static unsigned char const _yellowpal[]={0x0,0x5,0xee,0xf1,0xf2,0xf2,0xF2,0xf2,0xF2,0x0,0x0,0x0,0x0,0x0,0x7D,0x0};
   1911 
   1912 	//static char const _greenpal[]= {0x0,0x0,0x12,0x0,0x14,0x0,0x16,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x10,0x0};
   1913 	//static char const _redpal[]=   {0x0,0x0,0x22,0x0,0x24,0x0,0x26,0x0,0x28,0x0,0x0,0x0,0x0,0x0,0x20,0x0};
   1914 	//static char const _graypal[]=  {0x0,0x0,0xCA,0x0,0xCB,0x0,0xCC,0x0,0xCD,0x0,0x0,0x0,0x0,0x0,0xC8,0x0};
   1915 	//static char const _orangepal[]={0x0,0x0,0xD1,0x0,0xD2,0x0,0xD3,0x0,0xD4,0x0,0x0,0x0,0x0,0x0,0xD0,0x0};
   1916 	//static char const _bluepal[]=  {0x0,0x0,0x02,0x0,0x0A,0x0,0x0B,0x0,0x0B,0x0,0x0,0x0,0x0,0x0,0x09,0x0};
   1917 	//static char const _yellowpal[]={0x0,0x0,0x05,0x0,0xEE,0x0,0xF1,0x0,0xF2,0x0,0x0,0x0,0x0,0x0,0x7D,0x0};
   1918 
   1919 	static unsigned char const *_colors[]={_yellowpal,_redpal,_bluepal,_orangepal,_greenpal,_graypal};
   1920 
   1921 	int i,k;
   1922 	void *oldfont, *anim;
   1923 	int oldfontxspacing = FontXSpacing;
   1924 	char const *pal;
   1925 
   1926 
   1927 	FontXSpacing = 0;
   1928 	Map.Override_Mouse_Shape(MOUSE_NORMAL);
   1929 	Theme.Queue_Song(THEME_WIN1);
   1930 
   1931 	PseudoSeenBuff = new GraphicBufferClass(320,200,(void*)NULL);
   1932 	TextPrintBuffer = new GraphicBufferClass(SeenBuff.Get_Width(), SeenBuff.Get_Height() ,(void*)NULL);
   1933 	BlitList.Clear();
   1934 
   1935    	SysMemPage.Clear();
   1936 	PseudoSeenBuff->Clear();
   1937 	HiddenPage.Clear();
   1938 	TextPrintBuffer->Clear();
   1939 
   1940 	Set_Palette(BlackPalette);
   1941 
   1942 	anim = Open_Animation("MLTIPLYR.WSA",NULL,0L,(WSAOpenType)(WSA_OPEN_FROM_MEM | WSA_OPEN_TO_PAGE),Palette);
   1943 	Hide_Mouse();
   1944 
   1945 	/*
   1946 	** Display the background animation
   1947 	*/
   1948 	VisiblePage.Clear();
   1949 	InterpolationPaletteChanged = TRUE;
   1950 	InterpolationPalette = Palette;
   1951 	Increase_Palette_Luminance (Palette , 30,30,30,63);
   1952 	Animate_Frame(anim, *PseudoSeenBuff, 1);
   1953 	Interpolate_2X_Scale( PseudoSeenBuff , &SeenBuff , "MULTSCOR.PAL");
   1954 	Fade_Palette_To(Palette, FADE_PALETTE_FAST, Call_Back);
   1955 
   1956 	int frame = 1;
   1957 	while (frame < Get_Animation_Frame_Count(anim)) {
   1958 		Animate_Frame(anim, *PseudoSeenBuff, frame++);
   1959 		Call_Back_Delay(2);
   1960 	}
   1961 	Close_Animation(anim);
   1962 
   1963 	/* Change to the six-point font for Text_Print */
   1964 	oldfont = Set_Font(ScoreFontPtr);
   1965 	Call_Back();
   1966 
   1967 	Set_Logic_Page(*PseudoSeenBuff);
   1968 
   1969 	/*
   1970 	** Move all the scores over a notch if there's more games than can be
   1971 	** shown (which is known by MPlayerCurGame == MAX_MULTI_GAMES-1);
   1972 	*/
   1973 	if (MPlayerCurGame == MAX_MULTI_GAMES-1) {
   1974 		for(i = 0; i < MAX_MULTI_NAMES; i++) {
   1975 			for(k = 0; k < MAX_MULTI_GAMES-1; k++) {
   1976 				MPlayerScore[i].Kills[k] = MPlayerScore[i].Kills[k+1];
   1977 			}
   1978 		}
   1979 	}
   1980 
   1981 	int y = 41;
   1982 	for(i = 0; i < MAX_MULTI_NAMES; i++) {
   1983 		if (strlen(MPlayerScore[i].Name)) {
   1984 			pal = (const char*)_colors[MPlayerScore[i].Color];
   1985 
   1986 			Alloc_Object(new ScorePrintClass(MPlayerScore[i].Name, 15,  y,pal));
   1987 			Call_Back_Delay(20);
   1988 
   1989 			Alloc_Object(new ScorePrintClass(Int_Print(MPlayerScore[i].Wins), 118, y, pal));
   1990 			Call_Back_Delay(6);
   1991 
   1992 			for(k = 0; k <= MIN(MPlayerCurGame, MAX_MULTI_GAMES-2); k++) {
   1993 				if (MPlayerScore[i].Kills[k] >= 0) {
   1994 					Alloc_Object(new ScorePrintClass(Int_Print(MPlayerScore[i].Kills[k]), 225+(24*k), y, pal));
   1995 					Call_Back_Delay(6);
   1996 				}
   1997 			}
   1998 			y += 12;
   1999 		}
   2000 	}
   2001 
   2002 #if (FRENCH)
   2003 	Alloc_Object(new ScorePrintClass(TXT_MAP_CLICK2, 90 /*(320-strlen(Text_String(TXT_MAP_CLICK2)))/2*/, 185, _cycleyellowpal));
   2004 #else
   2005 	Alloc_Object(new ScorePrintClass(TXT_MAP_CLICK2, 109 /*(320-strlen(Text_String(TXT_MAP_CLICK2)))/2*/, 185, _cycleyellowpal));
   2006 #endif
   2007 	Cycle_Wait_Click();
   2008 
   2009 /* get rid of all the animating objects */
   2010 	for (i = 0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) {
   2011 		delete ScoreObjs[i];
   2012 		ScoreObjs[i] = 0;
   2013 	}
   2014 
   2015 	Theme.Queue_Song(THEME_NONE);
   2016 
   2017 	Fade_Palette_To(BlackPalette, FADE_PALETTE_FAST, NULL);
   2018 	VisiblePage.Clear();
   2019 	Set_Palette(GamePalette);
   2020 
   2021 	Set_Logic_Page (SeenBuff);
   2022 
   2023 	delete PseudoSeenBuff;
   2024 	delete TextPrintBuffer;
   2025 	BlitList.Clear();
   2026 
   2027 	Set_Font(oldfont);
   2028 	FontXSpacing = oldfontxspacing;
   2029 	ControlQ = 0;
   2030 	Show_Mouse();
   2031 }
   2032 
   2033 #ifdef WRITE_LBM
   2034 	// A BitMapHeader is stored in a BMHD chunk.  This structure MUST be an even size
   2035 typedef struct {
   2036     unsigned short w, h;							// raster width & height in pixels
   2037     unsigned short x, y;							// position for this image
   2038     unsigned char planes;							// # source bitplanes
   2039     unsigned char masking;						// masking technique
   2040     unsigned char compression;					// compression algoithm
   2041     unsigned char pad1;							// UNUSED.  For consistency, put 0 here.
   2042     unsigned short transcolor;					// transparent "color number"
   2043     unsigned char xaspect, yaspect;			// aspect ratio, a rational number x/y
   2044     unsigned short pagewidth, pageheight;		// source "page" size in pixels
   2045 } BitMapHeaderType;
   2046 
   2047 // All values in LocalHeader are always the same except planes.  This is set in Write_BMHD
   2048 // the WORD values must be in low-high order for compatibility.
   2049 
   2050 static BitMapHeaderType LocalHeader = {
   2051 	0x4001, 0xc800, 0, 0, 0, 0,		// width, height, x, y, planes, mask
   2052 	1,   0, 0xFF00, 5, 6, 				// compress, pad1, transcolor, xasptect, yaspect
   2053 	0x4001,	0xC800 };					// pagewidth, pageheight
   2054 
   2055 #define BM_HEADER_SIZE		(((sizeof(BitMapHeaderType) + 1) & 0xFFFE) + 8L)
   2056 
   2057 /*=========================================================================*/
   2058 /* The following static functions are in this file:                       */
   2059 /*=========================================================================*/
   2060 
   2061 static long CCWrite_BMHD(CCFileClass &lbmhandle, short bitplanes);
   2062 static long CCWrite_CMAP(CCFileClass &lbmhandle, unsigned char * palette, short bitplanes);
   2063 static long CCWrite_BODY(CCFileClass &lbmhandle, BufferClass& buff, short bitplanes);
   2064 static long CCWrite_Row(CCFileClass &lbmhandle, unsigned char *buffer);
   2065 
   2066 
   2067 /*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
   2068 
   2069 /***************************************************************************
   2070  * CCWrite_LBM_File -- Writes out a file in LBM format                     *
   2071  *                                                                         *
   2072  * INPUT:  short lbmhandle -- lbm file handle already opened by caller     *
   2073  *         BufferClass buff -- buff where MCGA picture is                  *
   2074  *         short bitplane -- number of bitplanes to convert to             *
   2075  *         char *palette -- pointer to palette for buff                    *
   2076  *                                                                         *
   2077  * OUTPUT: Returns bool -- successfull or not                              *
   2078  *                                                                         *
   2079  * WARNINGS:                                                               *
   2080  *                                                                         *
   2081  * HISTORY:                                                                *
   2082  *   11/18/1991  SB : Created.                                             *
   2083  *=========================================================================*/
   2084 bool CCWrite_LBM_File(CCFileClass &lbmhandle, BufferClass& buff, short bitplanes, unsigned char *palette)
   2085 {
   2086 	long filesize;
   2087 
   2088 
   2089 	lbmhandle.Seek(0L, SEEK_SET);						// goto beginning of file
   2090 
   2091 	lbmhandle.Write("FORM????ILBM", 12L);			// First 12 bytes of all .lbm files
   2092 																		// size is unkown so write ????
   2093 	filesize = 12L; 												// 4 bytes for "ILBM"
   2094 
   2095 	filesize += CCWrite_BMHD(lbmhandle, bitplanes);		// write out BMHD (fixed size)
   2096 	filesize += CCWrite_CMAP(lbmhandle, palette, bitplanes);	// write out CMAP
   2097 
   2098 		// Write out the body, or compressed picture image.  This size will depend
   2099 		// on the compression, but the value passed back is what the compressor
   2100 		// assumed was written to file
   2101 
   2102 	filesize += CCWrite_BODY(lbmhandle, buff, bitplanes);
   2103 
   2104 		// Verify that we were able to write out the file without running out of space
   2105 	if (lbmhandle.Seek(0L, SEEK_END) != filesize) {
   2106 		return(false);
   2107 	}
   2108 
   2109 	lbmhandle.Seek(4L, SEEK_SET);						// goto beginning of file
   2110 	filesize = Reverse_LONG(filesize - 8L);				// - 8 because of "FORM" + short (size)
   2111 	lbmhandle.Write( (char *) &filesize, 4L);		// patch in filesize
   2112 
   2113 	return(true);
   2114 }
   2115 
   2116 
   2117 /***************************************************************************
   2118  * CCWrite_BMHD -- writes out the bit map header (LocalHeader)             *
   2119  *                                                                         *
   2120  * INPUT:  short lbmhandle -- file handle for lbm file                     *
   2121  *         short pitplanes -- number of bitplanes to write out             *
   2122  *                                                                         *
   2123  * OUTPUT: LONG number of bytes hopefully written out to .LBM file         *
   2124  *                                                                         *
   2125  * WARNINGS:                                                               *
   2126  *                                                                         *
   2127  * HISTORY:                                                                *
   2128  *   11/19/1991  SB : Created.                                             *
   2129  *=========================================================================*/
   2130 static long CCWrite_BMHD(CCFileClass &lbmhandle, short bitplanes)
   2131 {
   2132 	long size;
   2133 
   2134 	lbmhandle.Write("BMHD", 4L);					// write out chunk title
   2135 	size = Reverse_LONG(sizeof(LocalHeader));			// write out size of LocalHeader chunk
   2136 	lbmhandle.Write((char *) &size, 4L);
   2137 
   2138 	LocalHeader.planes	= bitplanes;					// only nonconstant value in LocalHeader
   2139 
   2140 		// Make sure size is even. Return 8 = "BMHD" + size of the bitmap header structure
   2141 
   2142 	return(lbmhandle.Write((char *) &LocalHeader,
   2143 	                 (sizeof(LocalHeader) + 1) & 0xFFFE) + 8L);
   2144 }
   2145 
   2146 
   2147 /***************************************************************************
   2148  * CCWrite_CMAP -- Writes out CMAP (palette) information                   *
   2149  *                                                                         *
   2150  *                                                                         *
   2151  * INPUT:  short lbmhandle -- file handle of lbm file                      *
   2152  *         char * palette -- pointer to paletter information               *
   2153  *         short bitplanes -- used to figure out size of palette           *
   2154  *                                                                         *
   2155  * OUTPUT: long number of bytes that should have been written out to .LBM. *
   2156  *                                                                         *
   2157  * WARNINGS:                                                               *
   2158  *                                                                         *
   2159  * HISTORY:                                                                *
   2160  *   11/19/1991  SB : Created.                                             *
   2161  *=========================================================================*/
   2162 static long CCWrite_CMAP(CCFileClass &lbmhandle, unsigned char * palette, short bitplanes)
   2163 {
   2164 	short color, r, g, b, colors;
   2165 	long size;
   2166 	unsigned char *pal_ptr;
   2167 	char rgb[3];
   2168 
   2169 
   2170 	lbmhandle.Write("CMAP", 4L);						// write out palette info
   2171 	colors = 1 << bitplanes;									// colors = 2 to the bitplanes
   2172 	size = Reverse_LONG(colors * 3L);						// size = colors * 3 guns
   2173 
   2174  	lbmhandle.Write((char *) &size, 4L);
   2175 
   2176 	for (pal_ptr = palette, color = 0; color < colors; color++) { // for each color
   2177 
   2178 		if ((r = *pal_ptr++) != 0) {			// DPaint changes allows 0 - 100 for gun values
   2179 			r = (r << 2) | 0x03;					// this must be converted to 0 - 256 for LBM
   2180 		}												// so LBM_val = (DP_val * 4) | 3 if DP_val != 0
   2181 		if ((g = *pal_ptr++) != 0) {
   2182 			g = (g << 2) | 0x03;
   2183 		}
   2184 		if ((b = *pal_ptr++) != 0) {
   2185 			b = (b << 2) | 0x03;
   2186 		}
   2187 		rgb[0] = r;									// assign gun values to an array to write out
   2188 		rgb[1] = g;
   2189 		rgb[2] = b;
   2190 
   2191 		lbmhandle.Write(rgb, 3L);
   2192 	}
   2193 														// size = colors * 3
   2194 	return(((colors << 1) + colors) + 8L);	// total size of CMAP 8 = "CMAP" + short (size)
   2195 }
   2196 
   2197 
   2198 /***************************************************************************
   2199  * CCWrite_Body -- writes out compressed data in an LBM file               *
   2200  *                                                                         *
   2201  * INPUT: short lbmhandle -- file handle of lbm file                       *
   2202  *                                                                         *
   2203  * OUTPUT: long - number of byte written                                   *
   2204  *  	                                                                     *
   2205  * WARNINGS:                                                               *
   2206  *                                                                         *
   2207  * HISTORY:                                                                *
   2208  *   11/19/1991  SB : Created.                                             *
   2209  *=========================================================================*/
   2210 static long CCWrite_BODY(CCFileClass &lbmhandle, BufferClass& buff, short bitplanes)
   2211 {
   2212 	long bodysize = 0;
   2213 	long actualsize;
   2214 	long size;
   2215 	short planebit;
   2216 	short line, plane;
   2217 	unsigned char buffer[40];
   2218 	unsigned char *buffptr;
   2219 
   2220 	lbmhandle.Write("BODY????", 8L);		// BODY chunk ID, ???? reserved for chuncksize
   2221 
   2222 	buffptr = (unsigned char *) buff.Get_Buffer();						// point to beginning of buff
   2223 
   2224 	for (line = 0; line < 200; line++) {
   2225 		planebit = 1;											// start with bit 1 set
   2226 
   2227 		for (plane = 0; plane < bitplanes; plane++) {
   2228 			Pack_2_Plane(buffer, buffptr, planebit);	// convert to planar
   2229 			bodysize += CCWrite_Row(lbmhandle, buffer); // write to to the BODY in the LBM
   2230 
   2231 			planebit <<= 1;									// set next bit
   2232 		}
   2233 
   2234 		buffptr += 320;										// row size is 320
   2235 	}
   2236 
   2237 	actualsize = bodysize + (bodysize&0x01);
   2238 
   2239 	if (actualsize != bodysize) {
   2240 		lbmhandle.Write(buffer, 1);		// Padd the block.
   2241 	}
   2242 
   2243 	lbmhandle.Seek( -(actualsize + 4L), SEEK_CUR);		// Patch in chunksize
   2244 	size = Reverse_LONG(bodysize);
   2245 	lbmhandle.Write( (char *) &size ,4L);
   2246 
   2247 	return(actualsize + 8L);		// total size of BODY,  "BODY????" = 8 bytes
   2248 }
   2249 
   2250 
   2251 /***************************************************************************
   2252  * CCWrite_Row -- compresses and writes a row plane to .lbm file           *
   2253  *                                                                         *
   2254  * INPUT:  short lbmhandle -- lbm file handle                              *
   2255  *         unsigned char *buffer -- pointer to buffer to be written out    *
   2256  *                                                                         *
   2257  * OUTPUT: long size of chunk that should have been written out            *
   2258  *                                                                         *
   2259  * WARNINGS:                                                               *
   2260  *                                                                         *
   2261  * HISTORY:                                                                *
   2262  *   11/19/1991  SB : Created.                                             *
   2263  *=========================================================================*/
   2264 static long CCWrite_Row(CCFileClass &lbmhandle, unsigned char *buffer)
   2265 {
   2266 	short i;
   2267 	short chunksize = 0;
   2268 	short dataLength = 40;	  					// 320 rows / 8 ( 1 plane per row)
   2269 	unsigned char repCode, current, curr_plus_2;
   2270 	unsigned char *buffptr;
   2271 
   2272 	while (dataLength) {
   2273 
   2274   		// If at least 2 more bytes and they are equal, then replicate
   2275 
   2276 		if ((dataLength >= 2) && (buffer[0] == buffer[1])) {
   2277 			buffptr = buffer;
   2278 			for (i = 0; (i <= 128) &&  (i < (dataLength - 1)); i++) {
   2279 				if (*buffptr != buffptr[1]) {
   2280 					break;
   2281 				}
   2282 				buffptr++;
   2283 			}
   2284 			i++;
   2285 			repCode = -i + 1;
   2286 			lbmhandle.Write(&repCode, 1L);			// Write count as -count+1
   2287 			lbmhandle.Write(buffer,   1L);			// Write byte to replicate
   2288 			buffer += i;
   2289 			dataLength -= i;
   2290 			chunksize  += 2;
   2291 
   2292 		} else { // Copy literally till 3 byte run or two 2 byte runs found
   2293 
   2294 			for (i = 0; (i <= 128) && (i < dataLength); i++) {
   2295 				current     = buffer[i];
   2296 				curr_plus_2 = buffer[i + 2];
   2297 
   2298 				if (i == dataLength - 1)
   2299 					continue;
   2300 				if (current != buffer[i + 1])
   2301 					continue;
   2302 				if (i == dataLength - 2)
   2303 					continue;
   2304 				if (current == curr_plus_2)
   2305 					break;
   2306 				if (i == dataLength - 3)
   2307 					continue;
   2308 				if (curr_plus_2 == buffer[i + 3])
   2309 					 break;
   2310 			}
   2311 			repCode = i - 1;
   2312 			lbmhandle.Write(&repCode, 1L);			// Write count as count-1
   2313 			lbmhandle.Write(buffer, (long) i);		// Write 'count' bytes
   2314 			buffer += i;
   2315 			dataLength -= i;
   2316 			chunksize += i + 1;
   2317 		}
   2318 	}  // end while
   2319 
   2320 	return(chunksize);
   2321 }
   2322 #endif