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