JSHELL.CPP (24518B)
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\jshell.cpv 2.18 16 Oct 1995 16:51:12 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 : JSHELL.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : April 2, 1994 * 28 * * 29 * Last Update : May 11, 1995 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * Build_Translucent_Table -- Creates a translucent control table. * 34 * Translucent_Table_Size -- Determines the size of a translucent table. * 35 * Conquer_Build_Translucent_Table -- Builds fading table for shadow colors only. * 36 * Load_Alloc_Data -- Allocates a buffer and loads the file into it. * 37 * Load_Uncompress -- Loads and uncompresses data to a buffer. * 38 * Fatal -- General purpose fatal error handler. * 39 * Set_Window -- Sets the window dimensions to that specified. * 40 * Small_Icon -- Create a small icon from a big one. * 41 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 42 43 #include "function.h" 44 #include "wwfile.h" 45 46 #include <assert.h> 47 48 /*********************************************************************************************** 49 * Small_Icon -- Create a small icon from a big one. * 50 * * 51 * This routine will extract the specified icon from the icon data file and convert that * 52 * incon into a small (3x3) representation. Typicall use of this mini-icon is for the radar * 53 * map. * 54 * * 55 * INPUT: iconptr -- Pointer to the icon data file. * 56 * * 57 * iconnum -- The embedded icon number to convert into a small image. * 58 * * 59 * OUTPUT: Returns with a pointer to the small icon imagery. This is exactly 9 bytes long. * 60 * * 61 * WARNINGS: none * 62 * * 63 * HISTORY: * 64 * 05/11/1995 JLB : Created. * 65 *=============================================================================================*/ 66 void * Small_Icon(void const * iconptr, int iconnum) 67 { 68 static unsigned char _icon[9]; 69 IControl_Type const * iptr = (IControl_Type const *)iconptr; 70 unsigned char * data; 71 72 if (iconptr) { 73 iconnum = iptr->Map[iconnum]; 74 data = &iptr->Icons[iconnum*(24*24)]; 75 76 for (int index = 0; index < 9; index++) { 77 int _offsets[9] = { 78 4+4*24, 79 12+4*24, 80 20+4*24, 81 4+12*24, 82 12+12*24, 83 20+12*24, 84 4+20*24, 85 12+20*24, 86 20+20*24 87 }; 88 _icon[index] = data[_offsets[index]]; 89 } 90 } 91 92 return(_icon); 93 } 94 95 96 /*********************************************************************************************** 97 * Set_Window -- Sets the window dimensions to that specified. * 98 * * 99 * Use this routine to set the windows dimensions to the coordinates and dimensions * 100 * specified. * 101 * * 102 * INPUT: x -- Window X pixel position. * 103 * * 104 * y -- Window Y pixel position. * 105 * * 106 * w -- Window width in pixels. * 107 * * 108 * h -- Window height in pixels. * 109 * * 110 * OUTPUT: none * 111 * * 112 * WARNINGS: The X and width values are truncated to an even 8 pixel boundary. This is * 113 * the same as stripping off the lower 3 bits. * 114 * * 115 * HISTORY: * 116 * 01/15/1995 JLB : Created. * 117 *=============================================================================================*/ 118 void Set_Window(int window, int x, int y, int w, int h) 119 { 120 WindowList[window][WINDOWWIDTH] = w >> 3; 121 WindowList[window][WINDOWHEIGHT] = h; 122 WindowList[window][WINDOWX] = x >> 3; 123 WindowList[window][WINDOWY] = y; 124 } 125 126 127 /*********************************************************************************************** 128 * Fatal -- General purpose fatal error handler. * 129 * * 130 * This is a very simple general purpose fatal error handler. It goes directly to text * 131 * mode, prints the error, and then aborts with a failure code. * 132 * * 133 * INPUT: message -- The text message to display. * 134 * * 135 * ... -- Any optional parameters that are used in formatting the message. * 136 * * 137 * OUTPUT: none * 138 * * 139 * WARNINGS: This routine never returns. The game exits immediately. * 140 * * 141 * HISTORY: * 142 * 10/17/1994 JLB : Created. * 143 *=============================================================================================*/ 144 void Fatal(char const *message, ...) 145 { 146 va_list va; 147 148 va_start(va, message); 149 Prog_End(); 150 vfprintf(stderr, message, va); 151 Mono_Printf(message); 152 GlyphX_Debug_Print("Fatal"); 153 GlyphX_Debug_Print(message); 154 155 if (!RunningAsDLL) { 156 exit(EXIT_FAILURE); 157 } else { 158 *((int*)0) = 0; 159 } 160 } 161 162 163 #ifdef NEVER 164 void File_Fatal(char const *message) 165 { 166 Prog_End(); 167 perror(message); 168 if (!RunningAsDLL) { 169 exit(EXIT_FAILURE); 170 } 171 } 172 #endif 173 174 175 176 /*********************************************************************************************** 177 * Load_Uncompress -- Loads and uncompresses data to a buffer. * 178 * * 179 * This is the C++ counterpart to the Load_Uncompress function. It will load the file * 180 * specified into the graphic buffer indicated and uncompress it. * 181 * * 182 * INPUT: file -- The file to load and uncompress. * 183 * * 184 * uncomp_buff -- The graphic buffer that initial loading will use. * 185 * * 186 * dest_buff -- The buffer that will hold the uncompressed data. * 187 * * 188 * reserved_data -- This is an optional pointer to a buffer that will hold any * 189 * reserved data the compressed file may contain. This is * 190 * typically a palette. * 191 * * 192 * OUTPUT: Returns with the size of the uncompressed data in the destination buffer. * 193 * * 194 * WARNINGS: none * 195 * * 196 * HISTORY: * 197 * 10/17/1994 JLB : Created. * 198 *=============================================================================================*/ 199 long Load_Uncompress(FileClass &file, BuffType &uncomp_buff, BuffType &dest_buff, void *reserved_data) 200 { 201 unsigned short size; 202 void *sptr = uncomp_buff.Get_Buffer(); 203 void *dptr = dest_buff.Get_Buffer(); 204 int opened = false; 205 CompHeaderType header; 206 207 /* 208 ** The file must be opened in order to be read from. If the file 209 ** isn't opened, then open it. Record this fact so that it can be 210 ** restored to its closed state at the end. 211 */ 212 if (!file.Is_Open()) { 213 if (!file.Open()) { 214 return(0); 215 } 216 opened = true; 217 } 218 219 /* 220 ** Read in the size of the file (supposedly). 221 */ 222 file.Read(&size, sizeof(size)); 223 224 /* 225 ** Read in the header block. This block contains the compression type 226 ** and skip data (among other things). 227 */ 228 file.Read(&header, sizeof(header)); 229 size -= sizeof(header); 230 231 /* 232 ** If there are skip bytes then they must be processed. Either read 233 ** them into the buffer provided or skip past them. No check is made 234 ** to ensure that the reserved data buffer is big enough (watch out!). 235 */ 236 if (header.Skip) { 237 size -= header.Skip; 238 if (reserved_data) { 239 file.Read(reserved_data, header.Skip); 240 } else { 241 file.Seek(header.Skip, SEEK_CUR); 242 } 243 header.Skip = 0; 244 } 245 246 /* 247 ** Determine where is the proper place to load the data. If both buffers 248 ** specified are identical, then the data should be loaded at the end of 249 ** the buffer and decompressed at the beginning. 250 */ 251 if (uncomp_buff.Get_Buffer() == dest_buff.Get_Buffer()) { 252 sptr = Add_Long_To_Pointer(sptr, uncomp_buff.Get_Size()-(size+sizeof(header))); 253 } 254 255 /* 256 ** Read in the bulk of the data. 257 */ 258 Mem_Copy(&header, sptr, sizeof(header)); 259 file.Read(Add_Long_To_Pointer(sptr, sizeof(header)), size); 260 261 /* 262 ** Decompress the data. 263 */ 264 size = (unsigned int) Uncompress_Data(sptr, dptr); 265 266 /* 267 ** Close the file if necessary. 268 */ 269 if (opened) { 270 file.Close(); 271 } 272 return((long)size); 273 } 274 275 276 /*********************************************************************************************** 277 * Load_Alloc_Data -- Allocates a buffer and loads the file into it. * 278 * * 279 * This is the C++ replacement for the Load_Alloc_Data function. It will allocate the * 280 * memory big enough to hold the file and then read the file into it. * 281 * * 282 * INPUT: file -- The file to read. * 283 * * 284 * mem -- The memory system to use for allocation. * 285 * * 286 * OUTPUT: Returns with a pointer to the allocated and filled memory block. * 287 * * 288 * WARNINGS: none * 289 * * 290 * HISTORY: * 291 * 10/17/1994 JLB : Created. * 292 *=============================================================================================*/ 293 void * Load_Alloc_Data(FileClass &file) 294 { 295 void *ptr = 0; 296 long size = file.Size(); 297 298 ptr = new char [size]; 299 if (ptr) { 300 file.Read(ptr, size); 301 } 302 return(ptr); 303 } 304 305 306 /*********************************************************************************************** 307 * Translucent_Table_Size -- Determines the size of a translucent table. * 308 * * 309 * Use this routine to determine how big the translucent table needs * 310 * to be given the specified number of colors. This value is typically * 311 * used when allocating the buffer for the translucent table. * 312 * * 313 * INPUT: count -- The number of colors that are translucent. * 314 * * 315 * OUTPUT: Returns the size of the translucent table. * 316 * * 317 * WARNINGS: none * 318 * * 319 * HISTORY: * 320 * 04/02/1994 JLB : Created. * 321 *=============================================================================================*/ 322 long Translucent_Table_Size(int count) 323 { 324 return(256L + (256L * count)); 325 } 326 327 328 /*********************************************************************************************** 329 * Build_Translucent_Table -- Creates a translucent control table. * 330 * * 331 * The table created by this routine is used by Draw_Shape (GHOST) to * 332 * achieve a translucent affect. The original color of the shape will * 333 * show through. This differs from the fading effect, since that * 334 * affect only alters the background color toward a single destination * 335 * color. * 336 * * 337 * INPUT: palette -- Pointer to the control palette. * 338 * * 339 * control -- Pointer to array of structures that control how * 340 * the translucent table will be built. * 341 * * 342 * count -- The number of entries in the control array. * 343 * * 344 * buffer -- Pointer to buffer to place the translucent table. * 345 * If NULL is passed in, then the buffer will be * 346 * allocated. * 347 * * 348 * OUTPUT: Returns with pointer to the translucent table. * 349 * * 350 * WARNINGS: This routine is exceedingly slow. Use sparingly. * 351 * * 352 * HISTORY: * 353 * 04/02/1994 JLB : Created. * 354 *=============================================================================================*/ 355 void *Build_Translucent_Table(void const *palette, TLucentType const *control, int count, void *buffer) 356 { 357 unsigned char const *table; // Remap table pointer. 358 int index; // Working color index. 359 360 if (count && control && palette) { 361 if (!buffer) { 362 buffer = new char [Translucent_Table_Size(count)]; 363 } 364 365 if (buffer) { 366 memset(buffer, -1, 256); 367 table = (unsigned char*)Add_Long_To_Pointer((void*)buffer, 256); 368 369 /* 370 ** Build the individual remap tables for each translucent color. 371 */ 372 for (index = 0; index < count; index++) { 373 ((unsigned char*)buffer)[control[index].SourceColor] = index; 374 Build_Fading_Table(palette, (void*)table, control[index].DestColor, control[index].Fading); 375 table = (unsigned char*)Add_Long_To_Pointer((void*)table, 256); 376 } 377 } 378 } 379 return(buffer); 380 } 381 382 383 /*********************************************************************************************** 384 * Conquer_Build_Translucent_Table -- Builds fading table for shadow colors only. * 385 * * 386 * This routine will build a translucent (fading) table to remap colors into the shadow * 387 * color region of the palette. Shadow colors are not affected by this translucent table. * 388 * This means that a shape can be overlapped any number of times and the imagery will * 389 * remain deterministic (and constant). * 390 * * 391 * INPUT: palette -- Pointer to the palette to base the translucent process on. * 392 * * 393 * control -- Pointer to special control structure that specifies the * 394 * target color, and percentage of fade. * 395 * * 396 * count -- The number of colors to be remapped (entries in the control array). * 397 * * 398 * buffer -- Pointer to the staging buffer that will hold the translucent table * 399 * data. If this parameter is NULL, then an appropriate sized table * 400 * will be allocated. * 401 * * 402 * OUTPUT: Returns with a pointer to the translucent table data. * 403 * * 404 * WARNINGS: none * 405 * * 406 * HISTORY: * 407 * 06/27/1994 JLB : Created. * 408 *=============================================================================================*/ 409 void *Conquer_Build_Translucent_Table(void const *palette, TLucentType const *control, int count, void *buffer) 410 { 411 unsigned char const *table; // Remap table pointer. 412 int index; // Working color index. 413 414 if (count && control && palette) { 415 if (!buffer) { 416 buffer = new char [Translucent_Table_Size(count)]; 417 } 418 419 if (buffer) { 420 memset(buffer, -1, 256); 421 table = (unsigned char*)Add_Long_To_Pointer((void*)buffer, 256); 422 423 /* 424 ** Build the individual remap tables for each translucent color. 425 */ 426 for (index = 0; index < count; index++) { 427 ((unsigned char*)buffer)[control[index].SourceColor] = index; 428 Conquer_Build_Fading_Table(palette, (void*)table, control[index].DestColor, control[index].Fading); 429 table = (unsigned char*)Add_Long_To_Pointer((void*)table, 256); 430 } 431 } 432 } 433 return(buffer); 434 }