LOAD.CPP (17744B)
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: g:/library/wwlib32/file/rcs/load.cpp 1.4 1994/04/22 12:42:21 scott_bowen Exp $ */ 17 /*************************************************************************** 18 ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** 19 *************************************************************************** 20 * * 21 * Project Name : LIBRARY * 22 * * 23 * File Name : LOAD.C * 24 * * 25 * Programmer : Christopher Yates * 26 * * 27 * Last Update : September 17, 1993 [JLB] * 28 * * 29 *-------------------------------------------------------------------------* 30 * Functions: * 31 * Load_Uncompress -- Load and uncompress the given file. * 32 * Uncompress_Data -- Uncompress standard CPS buffer. * 33 * Load_Data -- Loads a data file from disk. * 34 * Load_Alloc_Data -- Loads and allocates buffer for a file. * 35 * Write_Data -- Writes a block of data as a file to disk. * 36 * Uncompress_Data -- Uncompresses data from one buffer to another. * 37 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 38 39 #include "iff.h" 40 #include "file.h" 41 #include <misc.h> 42 #include <wwstd.h> 43 #include <dos.h> 44 #include <wwmem.h> 45 46 47 /*=========================================================================*/ 48 /* The following PRIVATE functions are in this file: */ 49 /*=========================================================================*/ 50 51 52 53 /*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ 54 55 /*************************************************************************** 56 * LOAD_DATA -- Loads a data file from disk. * 57 * * 58 * This routine will load a data file from disk. It does no translation* 59 * on the data. * 60 * * 61 * INPUT: name -- Pointer to ASCII filename of the data file. * 62 * * 63 * ptr -- Buffer to load the data file into. * 64 * * 65 * size -- Maximum size of the buffer (in bytes). * 66 * * 67 * OUTPUT: Returns with the number of bytes read. * 68 * * 69 * WARNINGS: none * 70 * * 71 * HISTORY: * 72 * 06/24/1991 JLB : Created. * 73 *=========================================================================*/ 74 unsigned long __cdecl Load_Data(char const *name, void *ptr, unsigned long size) 75 { 76 int fd; 77 78 fd = Open_File(name, READ); 79 size = Read_File(fd, ptr, size); 80 Close_File(fd); 81 return(size); 82 } 83 84 85 /*************************************************************************** 86 * WRITE_DATA -- Writes a block of data as a file to disk. * 87 * * 88 * This routine will write a block of data as a file to the disk. It * 89 * is the compliment of Load_Data. * 90 * * 91 * INPUT: name -- Name of the file to create. * 92 * * 93 * ptr -- Pointer to the block of data to write. * 94 * * 95 * size -- Size of the data block to be written. * 96 * * 97 * OUTPUT: Returns with the number of bytes actually written. * 98 * * 99 * WARNINGS: none * 100 * * 101 * HISTORY: * 102 * 07/05/1992 JLB : Created. * 103 *=========================================================================*/ 104 unsigned long __cdecl Write_Data(char const *name, void *ptr, unsigned long size) 105 { 106 int fd; 107 108 fd = Open_File(name, WRITE); 109 size = Write_File(fd, ptr, size); 110 Close_File(fd); 111 return(size); 112 } 113 114 115 /*************************************************************************** 116 * LOAD_ALLOC_DATA -- Loads and allocates buffer for a file. * 117 * * 118 * The routine will allocate a buffer and load the specified file into * 119 * it. The kind of memory used for the buffer is determined by the * 120 * memory allocation flags passed in. * 121 * * 122 * INPUT: name -- Name of the file to load. * 123 * * 124 * flags -- Memory allocation flags to use when allocating. * 125 * * 126 * OUTPUT: Returns with a pointer to the buffer that contains the file's * 127 * data. * 128 * * 129 * WARNINGS: A memory error could occur if regular memory flags are * 130 * specified. If XMS memory is specified, then this routine * 131 * could likely return NULL. * 132 * * 133 * HISTORY: * 134 * 05/28/1992 JLB : Created. * 135 *=========================================================================*/ 136 void * __cdecl Load_Alloc_Data(char const *name, MemoryFlagType flags) 137 { 138 int fd; // Working file handle. 139 unsigned long size; // Size of the file to load. 140 void *buffer; // Buffer to hold the file. 141 142 fd = Open_File(name, READ); 143 size = File_Size(fd); 144 buffer = Alloc(size, flags); 145 if (buffer) { 146 Read_File(fd, buffer, size); 147 } 148 Close_File(fd); 149 return(buffer); 150 } 151 152 153 /*************************************************************************** 154 * LOAD_UNCOMPRESS -- Load and uncompress the given file. * 155 * * 156 * INPUT: char * - file name to uncompress * 157 * GraphicBufferClass& - to load the source data into * 158 * GraphicBufferClass& - for the picture * 159 * void * - ptr for header uncompressed data * 160 * * 161 * OUTPUT: unsigned long size of uncompressed data * 162 * * 163 * WARNINGS: none * 164 * * 165 * HISTORY: * 166 * 05/28/1991 CY : Created. * 167 * 06/26/1991 JLB : Handles load & uncompress to same buffer. * 168 *=========================================================================*/ 169 unsigned long __cdecl Load_Uncompress(char const *file, BufferClass& uncomp_buff, BufferClass& dest_buff, void *reserved_data) 170 { 171 int fd; // Source file handle. 172 unsigned int isize=0; // Size of the file. 173 unsigned int skipsize; // Size of the skip data bytes. 174 void *uncomp_ptr; // Source buffer pointer. 175 char *newuncomp_ptr; // Adjusted source pointer. 176 177 178 uncomp_ptr = uncomp_buff.Get_Buffer(); // get a pointer to buffer 179 180 /*======================================================================*/ 181 /* Read the file into the uncompression buffer. */ 182 /*======================================================================*/ 183 184 fd = Open_File(file, READ); // Open up the file to read from 185 Read_File(fd, (char *) &isize, 2L); // Read the file size 186 Read_File(fd, uncomp_ptr, 8L); // Read the header bytes in. 187 isize -= 8; // Remaining data in file. 188 189 /*======================================================================*/ 190 /* Check for and read in the skip data block. */ 191 /*======================================================================*/ 192 193 skipsize = *(((short *)uncomp_ptr) + 3); 194 195 if (reserved_data && skipsize) { 196 Read_File(fd, reserved_data, (unsigned long) skipsize); 197 } else { 198 Seek_File(fd, skipsize, SEEK_CUR); 199 } 200 201 *( ((short *)uncomp_ptr+3) ) = 0; // K/O any skip value. 202 isize -= skipsize; 203 204 /*======================================================================*/ 205 /* If the source and dest buffer are the same, we adjust the pointer so */ 206 /* that the compressed data is loaded into the end of the buffer. In */ 207 /* this way the uncompress code can write to the same buffer. */ 208 /*======================================================================*/ 209 newuncomp_ptr = (char *)Add_Long_To_Pointer(uncomp_buff.Get_Buffer(), uncomp_buff.Get_Size() - (isize+8L)); 210 211 /*======================================================================*/ 212 /* Duplicate the header bytes. */ 213 /*======================================================================*/ 214 Mem_Copy(uncomp_ptr,newuncomp_ptr,8); 215 216 /*======================================================================*/ 217 /* Read in the main compressed part of the file. */ 218 /*======================================================================*/ 219 Read_File(fd, newuncomp_ptr + 8, (unsigned long)isize); 220 Close_File(fd); 221 222 /*======================================================================*/ 223 /* Uncompress the file into the destination buffer (which may very well */ 224 /* be the source buffer). */ 225 /*======================================================================*/ 226 return(Uncompress_Data(newuncomp_ptr, dest_buff.Get_Buffer())); 227 } 228 #if(0) 229 /*************************************************************************** 230 * LOAD_UNCOMPRESS -- Load and uncompress the given file. * 231 * * 232 * INPUT: char *file name to uncompress, BuffType uncomp_buff to load * 233 * the source data into, BuffType dest_buff for the picture, * 234 * void *reserved_data pointer for header uncompressed data * 235 * * 236 * OUTPUT: unsigned long size of uncompressed data * 237 * * 238 * WARNINGS: none * 239 * * 240 * HISTORY: * 241 * 05/28/1991 CY : Created. * 242 * 06/26/1991 JLB : Handles load & uncompress to same buffer. * 243 *=========================================================================*/ 244 unsigned long __cdecl Load_Uncompress(char const *file, BuffType uncomp_buff, BuffType dest_buff, void *reserved_data) 245 { 246 int fd; // Source file handle. 247 unsigned int isize; // Size of the file. 248 unsigned int skipsize; // Size of the skip data bytes. 249 void *uncomp_ptr; // Source buffer pointer. 250 char *newuncomp_ptr; // Adjusted source pointer. 251 252 253 uncomp_ptr = Get_Buff(uncomp_buff); /* Get pointer to uncomp buffer */ 254 255 /* Read the file into the uncomp_buff */ 256 257 fd = Open_File(file, READ); 258 Read_File(fd, (char *) &isize, 2L); /* Read the file size */ 259 #if(AMIGA) 260 isize = Reverse_Word(isize); 261 #endif 262 263 Read_File(fd, uncomp_ptr, 8L); // Read the header bytes in. 264 isize -= 8; // Remaining data in file. 265 266 /* 267 ** Check for and read in the skip data block. 268 */ 269 270 skipsize = *(((short*)uncomp_ptr) + 3); 271 #if(AMIGA) 272 skipsize = Reverse_Word(skipsize); 273 #endif 274 275 if (reserved_data && skipsize) { 276 Read_File(fd, reserved_data, (unsigned long) skipsize); 277 } else { 278 Seek_File(fd, skipsize, SEEK_CUR); 279 } 280 *( ((short *)uncomp_ptr+3) ) = 0; // K/O any skip value. 281 isize -= skipsize; 282 283 /* 284 ** If the source and dest buffer are the same, we 285 ** adjust the pointer so that the compressed data is 286 ** loaded into the end of the buffer. In this way the 287 ** uncompress code can write to the same buffer. 288 */ 289 #if(IBM) 290 newuncomp_ptr = (char *)Add_Long_To_Pointer(Get_Buff(uncomp_buff), PageArraySize[uncomp_buff] - (isize+8L)); 291 #else 292 newuncomp_ptr = Get_Buff(uncomp_buff); 293 newuncomp_ptr += PageArraySize[uncomp_buff] - ((isize+10) & 0xFFFE); 294 #endif 295 296 /* 297 ** Duplicate the header bytes. 298 */ 299 Mem_Copy(uncomp_ptr,newuncomp_ptr,8); 300 301 /* 302 ** Read in the main compressed part of the file. 303 */ 304 Read_File(fd, newuncomp_ptr + 8, (unsigned long)isize); 305 Close_File(fd); 306 307 return(Uncompress_Data(newuncomp_ptr, Get_Buff(dest_buff))); 308 } 309 310 #endif 311 /*************************************************************************** 312 * Uncompress_Data -- Uncompresses data from one buffer to another. * 313 * * 314 * This routine takes data from a compressed file (sans the first two * 315 * size bytes) and uncompresses it to a destination buffer. The source * 316 * data MUST have the CompHeaderType at its start. * 317 * * 318 * INPUT: src -- Source compressed data pointer. * 319 * * 320 * dst -- Destination (paragraph aligned) pointer. * 321 * * 322 * OUTPUT: Returns with the size of the uncompressed data. * 323 * * 324 * WARNINGS: If LCW compression is used, the destination buffer must * 325 * be paragraph aligned. * 326 * * 327 * HISTORY: * 328 * 09/17/1993 JLB : Created. * 329 *=========================================================================*/ 330 unsigned long __cdecl Uncompress_Data(void const *src, void *dst) 331 { 332 unsigned int skip; // Number of leading data to skip. 333 CompressionType method; // Compression method used. 334 unsigned long uncomp_size=NULL; 335 336 if (!src || !dst) return(NULL); 337 338 /* 339 ** Interpret the data block header structure to determine 340 ** compression method, size, and skip data amount. 341 */ 342 uncomp_size = ((CompHeaderType*)src)->Size; 343 #if(AMIGA) 344 uncomp_size = Reverse_Long(uncomp_size); 345 #endif 346 skip = ((CompHeaderType*)src)->Skip; 347 #if(AMIGA) 348 skip = Reverse_Word(skip); 349 #endif 350 method = (CompressionType) ((CompHeaderType*)src)->Method; 351 src = Add_Long_To_Pointer((void *)src, (long)sizeof(CompHeaderType) + (long)skip); 352 353 switch (method) { 354 355 default: 356 case NOCOMPRESS: 357 Mem_Copy((void *) src, dst, uncomp_size); 358 break; 359 360 case HORIZONTAL: 361 #if LIB_EXTERNS_RESOLVED 362 RLE_Uncompress((void *) src, dst, uncomp_size); 363 #endif 364 break; 365 366 case LCW: 367 LCW_Uncompress((void *) src, (void *) dst, (unsigned long) uncomp_size); 368 break; 369 370 } 371 372 return(uncomp_size); 373 } 374 375