]> 4ch.mooo.com Git - 16.git/blob - 16/cawat/SOFT.C
f86481e484d51b224ccfdebaa0aa9dce55eb155c
[16.git] / 16 / cawat / SOFT.C
1 /* Catacomb Armageddon Source Code\r
2  * Copyright (C) 1993-2014 Flat Rock Software\r
3  *\r
4  * This program is free software; you can redistribute it and/or modify\r
5  * it under the terms of the GNU General Public License as published by\r
6  * the Free Software Foundation; either version 2 of the License, or\r
7  * (at your option) any later version.\r
8  *\r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License along\r
15  * with this program; if not, write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
17  */\r
18 \r
19 #include <stdio.h>\r
20 #include <stdlib.h>\r
21 #include <string.h>\r
22 #include <ctype.h>\r
23 #include <alloc.h>\r
24 #include <fcntl.h>\r
25 #include <dos.h>\r
26 #include <io.h>\r
27 \r
28 #include "def.h"\r
29 #include "gelib.h"\r
30 #include "soft.h"\r
31 #include "lzw.h"\r
32 #include "lzhuff.h"\r
33 #include "jam_io.h"\r
34 \r
35 \r
36 \r
37 \r
38 \r
39 \r
40 //===========================================================================\r
41 //\r
42 //                                                                              SWITCHES\r
43 //\r
44 //===========================================================================\r
45 \r
46 #define LZH_SUPPORT             1\r
47 #define LZW_SUPPORT             0\r
48 \r
49 \r
50 \r
51 \r
52 //=========================================================================\r
53 //\r
54 //\r
55 //                                                              GENERAL LOAD ROUTINES\r
56 //\r
57 //\r
58 //=========================================================================\r
59 \r
60 \r
61 \r
62 //--------------------------------------------------------------------------\r
63 // BLoad()                      -- THIS HAS NOT BEEN FULLY TESTED!\r
64 //\r
65 // NOTICE : This version of BLOAD is compatable with JAMPak V3.0 and the\r
66 //                              new fileformat...\r
67 //--------------------------------------------------------------------------\r
68 unsigned long BLoad(char *SourceFile, memptr *DstPtr)\r
69 {\r
70         int handle;\r
71 \r
72         memptr SrcPtr;\r
73         unsigned long i, j, k, r, c;\r
74         word flags;\r
75         byte Buffer[8];\r
76         unsigned long SrcLen,DstLen;\r
77         struct CMP1Header CompHeader;\r
78         boolean Compressed = false;\r
79 \r
80 \r
81         memset((void *)&CompHeader,0,sizeof(struct CMP1Header));\r
82 \r
83         //\r
84         // Open file to load....\r
85         //\r
86 \r
87         if ((handle = open(SourceFile, O_RDONLY|O_BINARY)) == -1)\r
88                 return(0);\r
89 \r
90         //\r
91         // Look for JAMPAK headers\r
92         //\r
93 \r
94         read(handle,Buffer,4);\r
95 \r
96         if (!strncmp(Buffer,COMP,4))\r
97         {\r
98                 //\r
99                 // Compressed under OLD file format\r
100                 //\r
101 \r
102                 Compressed = true;\r
103                 SrcLen = Verify(SourceFile);\r
104 \r
105                 read(handle,(void *)&CompHeader.OrginalLen,4);\r
106                 CompHeader.CompType = ct_LZW;\r
107                 MM_GetPtr(DstPtr,CompHeader.OrginalLen);\r
108                 if (!*DstPtr)\r
109                         return(0);\r
110         }\r
111         else\r
112         if (!strncmp(Buffer,CMP1,4))\r
113         {\r
114                 //\r
115                 // Compressed under new file format...\r
116                 //\r
117 \r
118                 Compressed = true;\r
119                 SrcLen = Verify(SourceFile);\r
120 \r
121                 read(handle,(void *)&CompHeader,sizeof(struct CMP1Header));\r
122                 MM_GetPtr(DstPtr,CompHeader.OrginalLen);\r
123                 if (!*DstPtr)\r
124                         return(0);\r
125         }\r
126         else\r
127                 DstLen = Verify(SourceFile);\r
128 \r
129 \r
130         //\r
131         // Load the file in memory...\r
132         //\r
133 \r
134         if (Compressed)\r
135         {\r
136                 DstLen = CompHeader.OrginalLen;\r
137 \r
138                 if ((MM_TotalFree() < SrcLen) && (CompHeader.CompType))\r
139                 {\r
140                         if (!InitBufferedIO(handle,&lzwBIO))\r
141                                 TrashProg("No memory for buffered I/O.");\r
142 \r
143                         switch (CompHeader.CompType)\r
144                         {\r
145                                 #if LZW_SUPPORT\r
146                                 case ct_LZW:\r
147                                         lzwDecompress(&lzwBIO,MK_FP(*DstPtr,0),CompHeader.OrginalLen,(SRC_BFILE|DEST_MEM));\r
148                                 break;\r
149                                 #endif\r
150 \r
151                                 #if LZH_SUPPORT\r
152                                 case ct_LZH:\r
153                                         lzhDecompress(&lzwBIO,MK_FP(*DstPtr,0),CompHeader.OrginalLen,CompHeader.CompressLen,(SRC_BFILE|DEST_MEM));\r
154                                 break;\r
155                                 #endif\r
156 \r
157                                 default:\r
158                                         TrashProg("BLoad() - Unrecognized/Supported compression");\r
159                                 break;\r
160                         }\r
161 \r
162                         FreeBufferedIO(&lzwBIO);\r
163                 }\r
164                 else\r
165                 {\r
166                         CA_LoadFile(SourceFile,&SrcPtr);\r
167                         switch (CompHeader.CompType)\r
168                         {\r
169                                 #if LZW_SUPPORT\r
170                                 case ct_LZW:\r
171                                         lzwDecompress(MK_FP(SrcPtr,8),MK_FP(*DstPtr,0),CompHeader.OrginalLen,(SRC_MEM|DEST_MEM));\r
172                                 break;\r
173                                 #endif\r
174 \r
175                                 #if LZH_SUPPORT\r
176                                 case ct_LZH:\r
177                                         lzhDecompress(MK_FP(SrcPtr,8),MK_FP(*DstPtr,0),CompHeader.OrginalLen,CompHeader.CompressLen,(SRC_MEM|DEST_MEM));\r
178                                 break;\r
179                                 #endif\r
180 \r
181                                 default:\r
182                                         TrashProg("BLoad() - Unrecognized/Supported compression");\r
183                                 break;\r
184                         }\r
185                         MM_FreePtr(&SrcPtr);\r
186                 }\r
187         }\r
188         else\r
189                 CA_LoadFile(SourceFile,DstPtr);\r
190 \r
191         close(handle);\r
192         return(DstLen);\r
193 }\r
194 \r
195 \r
196 \r
197 \r
198 ////////////////////////////////////////////////////////////////////////////\r
199 //\r
200 // LoadLIBShape()\r
201 //\r
202 int LoadLIBShape(char *SLIB_Filename, char *Filename,struct Shape *SHP)\r
203 {\r
204         #define CHUNK(Name)     (*ptr == *Name) &&                      \\r
205                                                                 (*(ptr+1) == *(Name+1)) &&      \\r
206                                                                 (*(ptr+2) == *(Name+2)) &&      \\r
207                                                                 (*(ptr+3) == *(Name+3))\r
208 \r
209 \r
210         int RT_CODE;\r
211         FILE *fp;\r
212         char CHUNK[5];\r
213         char far *ptr;\r
214         memptr IFFfile = NULL;\r
215         unsigned long FileLen, size, ChunkLen;\r
216         int loop;\r
217 \r
218 \r
219         RT_CODE = 1;\r
220 \r
221         // Decompress to ram and return ptr to data and return len of data in\r
222         //      passed variable...\r
223 \r
224         if (!LoadLIBFile(SLIB_Filename,Filename,&IFFfile))\r
225                 TrashProg("Error Loading Compressed lib shape!");\r
226 \r
227         // Evaluate the file\r
228         //\r
229         ptr = MK_FP(IFFfile,0);\r
230         if (!CHUNK("FORM"))\r
231                 goto EXIT_FUNC;\r
232         ptr += 4;\r
233 \r
234         FileLen = *(long far *)ptr;\r
235         SwapLong((long far *)&FileLen);\r
236         ptr += 4;\r
237 \r
238         if (!CHUNK("ILBM"))\r
239                 goto EXIT_FUNC;\r
240         ptr += 4;\r
241 \r
242         FileLen += 4;\r
243         while (FileLen)\r
244         {\r
245                 ChunkLen = *(long far *)(ptr+4);\r
246                 SwapLong((long far *)&ChunkLen);\r
247                 ChunkLen = (ChunkLen+1) & 0xFFFFFFFE;\r
248 \r
249                 if (CHUNK("BMHD"))\r
250                 {\r
251                         ptr += 8;\r
252                         SHP->bmHdr.w = ((struct BitMapHeader far *)ptr)->w;\r
253                         SHP->bmHdr.h = ((struct BitMapHeader far *)ptr)->h;\r
254                         SHP->bmHdr.x = ((struct BitMapHeader far *)ptr)->x;\r
255                         SHP->bmHdr.y = ((struct BitMapHeader far *)ptr)->y;\r
256                         SHP->bmHdr.d = ((struct BitMapHeader far *)ptr)->d;\r
257                         SHP->bmHdr.trans = ((struct BitMapHeader far *)ptr)->trans;\r
258                         SHP->bmHdr.comp = ((struct BitMapHeader far *)ptr)->comp;\r
259                         SHP->bmHdr.pad = ((struct BitMapHeader far *)ptr)->pad;\r
260                         SwapWord(&SHP->bmHdr.w);\r
261                         SwapWord(&SHP->bmHdr.h);\r
262                         SwapWord(&SHP->bmHdr.x);\r
263                         SwapWord(&SHP->bmHdr.y);\r
264                         ptr += ChunkLen;\r
265                 }\r
266                 else\r
267                 if (CHUNK("BODY"))\r
268                 {\r
269                         ptr += 4;\r
270                         size = *((long far *)ptr);\r
271                         ptr += 4;\r
272                         SwapLong((long far *)&size);\r
273                         SHP->BPR = (SHP->bmHdr.w+7) >> 3;\r
274                         MM_GetPtr(&SHP->Data,size);\r
275                         if (!SHP->Data)\r
276                                 goto EXIT_FUNC;\r
277                         movedata(FP_SEG(ptr),FP_OFF(ptr),FP_SEG(SHP->Data),0,size);\r
278                         ptr += ChunkLen;\r
279 \r
280                         break;\r
281                 }\r
282                 else\r
283                         ptr += ChunkLen+8;\r
284 \r
285                 FileLen -= ChunkLen+8;\r
286         }\r
287 \r
288         RT_CODE = 0;\r
289 \r
290 EXIT_FUNC:;\r
291         if (IFFfile)\r
292         {\r
293 //              segptr = (memptr)FP_SEG(IFFfile);\r
294                 MM_FreePtr(&IFFfile);\r
295         }\r
296 \r
297         return (RT_CODE);\r
298 }\r
299 \r
300 \r
301 \r
302 \r
303 \r
304 //----------------------------------------------------------------------------\r
305 // LoadLIBFile() -- Copies a file from an existing archive to dos.\r
306 //\r
307 // PARAMETERS :\r
308 //\r
309 //                      LibName         - Name of lib file created with SoftLib V1.0\r
310 //\r
311 //                      FileName - Name of file to load from lib file.\r
312 //\r
313 //                      MemPtr   - (IF !NULL) - Pointer to memory to load into ..\r
314 //                                                (IF NULL)  - Routine allocates necessary memory and\r
315 //                                                                                      returns a MEM(SEG) pointer to memory allocated.\r
316 //\r
317 // RETURN :\r
318 //\r
319 //              (IF !NULL) - A pointer to the loaded data.\r
320 //                      (IF NULL)  - Error!\r
321 //\r
322 //----------------------------------------------------------------------------\r
323 memptr LoadLIBFile(char *LibName,char *FileName,memptr *MemPtr)\r
324 {\r
325         int handle;\r
326         unsigned long header;\r
327         struct ChunkHeader Header;\r
328         unsigned long ChunkLen;\r
329         short x;\r
330         struct FileEntryHdr FileEntry;                          // Storage for file once found\r
331         struct FileEntryHdr FileEntryHeader;            // Header used durring searching\r
332         struct SoftLibHdr LibraryHeader;                                // Library header - Version Checking\r
333         boolean FileFound = false;\r
334         unsigned long id_slib = ID_SLIB;\r
335         unsigned long id_chunk = ID_CHUNK;\r
336 \r
337 \r
338         //\r
339         // OPEN SOFTLIB FILE\r
340         //\r
341 \r
342         if ((handle = open(LibName,O_RDONLY|O_BINARY, S_IREAD)) == -1)\r
343                 return(NULL);\r
344 \r
345 \r
346         //\r
347         //      VERIFY it is a SOFTLIB (SLIB) file\r
348         //\r
349 \r
350         if (read(handle,&header,4) == -1)\r
351         {\r
352                 close(handle);\r
353                 return(NULL);\r
354         }\r
355 \r
356         if (header != id_slib)\r
357         {\r
358                 close(handle);\r
359                 return(NULL);\r
360         }\r
361 \r
362 \r
363         //\r
364         // CHECK LIBRARY HEADER VERSION NUMBER\r
365         //\r
366 \r
367         if (read(handle, &LibraryHeader,sizeof(struct SoftLibHdr)) == -1)\r
368                 TrashProg("read error in LoadSLIBFile()\n%c",7);\r
369 \r
370         if (LibraryHeader.Version > SOFTLIB_VER)\r
371                 TrashProg("Unsupported file ver %d",LibraryHeader.Version);\r
372 \r
373 \r
374         //\r
375         // MANAGE FILE ENTRY HEADERS...\r
376         //\r
377 \r
378         for (x = 1;x<=LibraryHeader.FileCount;x++)\r
379         {\r
380                 if (read(handle, &FileEntryHeader,sizeof(struct FileEntryHdr)) == -1)\r
381                 {\r
382                         close(handle);\r
383                         return(NULL);\r
384                 }\r
385 \r
386                 if (!stricmp(FileEntryHeader.FileName,FileName))\r
387                 {\r
388                         FileEntry = FileEntryHeader;\r
389                         FileFound = true;\r
390                 }\r
391         }\r
392 \r
393         //\r
394         // IF FILE HAS BEEN FOUND THEN SEEK TO POSITION AND EXTRACT\r
395         //      ELSE RETURN WITH ERROR CODE...\r
396         //\r
397 \r
398         if (FileFound)\r
399         {\r
400                 if (lseek(handle,FileEntry.Offset,SEEK_CUR) == -1)\r
401                 {\r
402                         close(handle);\r
403                         return(NULL);\r
404                 }\r
405 \r
406                 //\r
407                 // READ CHUNK HEADER - Verify we are at the beginning of a chunk..\r
408                 //\r
409 \r
410                 if (read(handle,(char *)&Header,sizeof(struct ChunkHeader)) == -1)\r
411                         TrashProg("LIB File - Unable to read Header!");\r
412 \r
413                 if (Header.HeaderID != id_chunk)\r
414                         TrashProg("LIB File - BAD HeaderID!");\r
415 \r
416                 //\r
417                 // Allocate memory if Necessary...\r
418                 //\r
419 \r
420 \r
421                 if (!*MemPtr)\r
422                         MM_GetPtr(MemPtr,FileEntry.OrginalLength);\r
423 \r
424                 //\r
425                 //      Calculate the length of the data (without the chunk header).\r
426                 //\r
427 \r
428                 ChunkLen = FileEntry.ChunkLen - sizeof(struct ChunkHeader);\r
429 \r
430 \r
431                 //\r
432                 // Extract Data from file\r
433                 //\r
434 \r
435                 switch (Header.Compression)\r
436                 {\r
437 \r
438                         #if LZW_SUPPORT\r
439                         case ct_LZW:\r
440                                 if (!InitBufferedIO(handle,&lzwBIO))\r
441                                         TrashProg("No memory for buffered I/O.");\r
442                                 lzwDecompress(&lzwBIO,MK_FP(*MemPtr,0),FileEntry.OrginalLength,(SRC_BFILE|DEST_MEM));\r
443                                 FreeBufferedIO(&lzwBIO);\r
444                                 break;\r
445                         #endif\r
446 \r
447                         #if LZH_SUPPORT\r
448                         case ct_LZH:\r
449                                 if (!InitBufferedIO(handle,&lzwBIO))\r
450                                         TrashProg("No memory for buffered I/O.");\r
451                                 lzhDecompress(&lzwBIO, MK_FP(*MemPtr,0), FileEntry.OrginalLength, ChunkLen, (SRC_BFILE|DEST_MEM));\r
452                                 FreeBufferedIO(&lzwBIO);\r
453                                 break;\r
454                         #endif\r
455 \r
456                         case ct_NONE:\r
457                                 if (!CA_FarRead(handle,MK_FP(*MemPtr,0),ChunkLen))\r
458                                 {\r
459 //                                      close(handle);\r
460                                         *MemPtr = NULL;\r
461                                 }\r
462                                 break;\r
463 \r
464                         default:\r
465                                 close(handle);\r
466                                 TrashProg("Unknown Chunk.Compression Type!");\r
467                                 break;\r
468                 }\r
469         }\r
470         else\r
471                 *MemPtr = NULL;\r
472 \r
473         close(handle);\r
474         return(*MemPtr);\r
475 }\r
476 \r
477 \r
478 \r
479 \r