// #define BufferMaxSize = 131072; // #define BufferMax = BufferMaxSize-1; // BufferIndex = 0..BufferMax; Basicly a range item I guess... // BufferSize = 0..BufferMaxSize; // byte Source[BufferMax], Dest[BufferMax]; // Array [0..BufferMax] of Byte; // Since code is being decompressed directly into memory, there is no need // to keep track of buffer.. Mainly for compression routines... #include #include "decomp.h" // ********************************************************************** // Vars, and defines. // ********************************************************************** #define FLAG_Copied 0x80 #define MAX_FAT 255 typedef struct TFatTable { char outfile[32]; } TFatTable; static TFatTable *p_FatTable, *c_FatTable; static u_char *p_decomparea; static TFatTable SngFat; u_long WAD_Decompression(u_long SourceSize, u_char *Dest1, u_char *Source1); // ********************************************************************** // Routines // ********************************************************************** u_long WAD_endian32(int posit) { u_long value = 0; // Converts a value from big endian to little endian // performs shifts, and moves bytes to correct positions in data value = (u_char)c_FatTable->outfile[posit + 3] * 16777216; value += (u_char)c_FatTable->outfile[posit + 2] * 65536; value += (u_char)c_FatTable->outfile[posit + 1] * 256; value += (u_char)c_FatTable->outfile[posit]; return(value); } void WAD_InitSession(u_long *location) { // Set up pointers to the start of the WAD file... p_FatTable = (TFatTable *)location; p_decomparea = (u_char *)location; } u_long WAD_Decompression(u_long SourceSize, u_char *Dest, u_char *Source) { unsigned long int X, Y, Pos; unsigned int Command, Size, K; u_char Bit; u_long i; u_long crc = 0, crc2; if (Source[0] == FLAG_Copied) { for(Y=1; Y < SourceSize -1; Y++) { Dest[Y - 1] = Source[Y]; } } else { Y = 0; X = 3; Command = (Source[1] << 8) + Source[2]; Bit = 16; while (X < SourceSize) { if (Bit == 0) { Command = (Source[X] << 8) + Source[X + 1]; Bit = 16; X += 2; } if ((Command & 0x8000) == 0) { Dest[Y] = Source[X]; X++; Y++; } else { Pos = ((Source[X] << 4) + (Source[X + 1] >> 4)); if (Pos == 0) { Size = (Source[X + 1] << 8) + Source[X + 2] + 15; for(K = 0; K < Size + 1; K++){ Dest[Y + K] = Source[X + 3];} X += 4; Y += Size + 1; } else { Size = (Source[X + 1] & 0x0F) + 2; for(K = 0; K < Size + 1; K++){ Dest[Y + K] = Dest[Y-Pos+K]; } X += 2; Y += Size + 1; } } Command = Command << 1; Bit--; } } return(Y); // The decompressed buffersize } u_long WAD_ExtractFile(int Seekto, u_char *decomp_to) { u_char *decomp_from; u_long zz; char CompStr[14]; int i; if (Seekto > 255) { printf("\n[WAD_ExtractFile error] \ninvalid Seekto[%d]\n",Seekto); return(-1); } // Seekto is the number of the file we want to get out of the fat. // decomp_to is the area of memory we are sending the buffer to c_FatTable = &p_FatTable[Seekto]; decomp_from = p_decomparea + WAD_endian32(20); for(i=1; i<13; i++) { CompStr[i-1] = toupper(c_FatTable->outfile[i]);} CompStr[13] = 0; zz = WAD_Decompression(WAD_endian32(24),decomp_to,decomp_from); return(zz); } u_long WAD_FindName(char *filename) { u_long x, i; char CompStr[14]; x = 0; do { x++; WAD_FileSize(x); for(i=1; i < strlen(filename) + 1; i++) { CompStr[i-1] = toupper(c_FatTable->outfile[i]);} CompStr[strlen(filename)] = 0; } while (strcmp(CompStr, filename) != 0 && x != 255); if (x == 255) { printf("[WAD_FindName error] \ninvalid filename[%s]\n",filename); return(-1); } return(x); } u_long WAD_FileSize(int Seekto) { if (Seekto > 255) { printf("\n[WAD_FileSize error] \ninvalid Seekto[%d]\n",Seekto); return(-1); } // Filename is the name of the file we need the size of... // Mainly used to allocate the memory needed... c_FatTable = &p_FatTable[Seekto]; return(WAD_endian32(16)); } u_long WAD_CompSize(int Seekto) { // Returns the compressed size of the file. if (Seekto > 255) { printf("\n[WAD_FileSize error] \ninvalid Seekto[%d]\n",Seekto); return(-1); } c_FatTable = &p_FatTable[Seekto]; return(WAD_endian32(WAD_endian32(24))); } char *WAD_FileData(int Seekto) { static char zz[150]; u_long *dd, m, c; if (Seekto > 255) { printf("\n[WAD_FileData error] \ninvalid Seekto[%d]\n",Seekto); sprintf(zz,"WAD_FileData error Seekto != [%d]",Seekto); return(zz); } // Returns a string in the format of // Filename [12 chars] FileSize Compressed Size c_FatTable = &p_FatTable[Seekto]; c_FatTable->outfile[13] = 0; m = (u_long)c_FatTable; m += WAD_endian32(20); dd = (u_long *)(m); sprintf(zz,"[Addr %x] %12.12s\n Size %8.8u Start %8.8u Finish %8.8u",(u_long)dd,&c_FatTable->outfile[1],WAD_endian32(16),WAD_endian32(20),WAD_endian32(24)); return(zz); }