#include "dzip.h" FILE *pakfile; pakentry_t *pakdir; int paknum, pakptr; char flag[5]; void initpakfile (direntry_t *de) { if (flag[SW_VERIFY]) { paknum = 0; pakfile = NULL; return; } pakdir = malloc(de->pak * sizeof(pakentry_t)); paknum = *(int*)"PACK"; if (pakfile) safe_fwrite(&paknum,4,pakfile); if (pakfile) safe_fwrite(&paknum,4,pakfile); if (pakfile) safe_fwrite(&paknum,4,pakfile); paknum = 0; pakptr = 12; } void closepakfile (direntry_t *de) { int tmp; if (!pakfile) { free(pakdir); return; } safe_fwrite(pakdir,paknum*sizeof(pakentry_t),pakfile); fseek(pakfile,4,SEEK_SET); tmp = cnvlong(pakptr); safe_fwrite(&tmp,4,pakfile); paknum *= 64; tmp = cnvlong(paknum); safe_fwrite(&tmp,4,pakfile); free(pakdir); fclose(pakfile); if (maj_ver != 1) #ifdef _WIN32 setfiledate(de[-paknum/64].name,de->date); #endif pakfile = NULL; } void init_zlib_decompression () { zip_stream.zalloc = (alloc_func)0; zip_stream.zfree = (free_func)0; zip_stream.opaque = (voidpf)0; zip_err = inflateInit(&zip_stream); zip_stream.avail_in = p_blocksize + 1; check_dzip_err("inflateinit"); } void end_zlib_decompression () { inflateEnd(&zip_stream); } int check_filetype (int type) { if (type >= TYPE_LAST) Sys_Error("unknown type of file"); return (type == TYPE_DEM || type == TYPE_DEMV1 || type == TYPE_NEHAHRA); } void uncompress_file (FILE *handle, char *src, char *outname) { int i, inlen, ptr, readptr, eofptr, blocksize; char demomode; direntry_t *de; char *action = "extracting"; OpenDZFile(handle, src); // de->type = TYPE_NEHAHRA; printf("%s created using v%u.%u\n", src, maj_ver, min_ver); // maj_ver = 1; inlen = 0; if (maj_ver == 1) { ptr = directory[numfiles-1].ptr + directory[numfiles-1].size; readptr = totalsize = 12; init_zlib_decompression(); } for (i = 0; i < numfiles; i++) { de = directory + i; crcval = INITCRC; if (!de->pak) printf("%s %s",action,de->name); fflush(stdout); if (de->type == TYPE_PAK) { printf("%s %s:",action,de->name); if (flag[SW_VERIFY]) pakfile = NULL; else { #ifdef GUI pakfile = GuiGetUncompressOutfile(de); if (!pakfile && GuiAbort) return; #else pakfile = open_create(outname); #endif } if (pakfile || flag[SW_VERIFY]) printf("\n"); initpakfile(de); i++; de++; outfile = pakfile; } demomode = check_filetype(de->type); outfile = open_create(outname); if (demomode) dem_uncompress_init(TYPE_NEHAHRA); if (maj_ver > 1) { init_zlib_decompression(); readptr = totalsize = 0; ptr = eofptr = de->inter; ztotal = de->size; } else eofptr = de->ptr + de->size; while (readptr < eofptr) { read_file(handle,&inlen,ptr); if (demomode) blocksize = dem_uncompress(); else { blocksize = totalsize - readptr; if (totalsize >= eofptr) blocksize = eofptr - readptr; write_output(inblk,blocksize); } if (blocksize != p_blocksize) memcpy(inblk,inblk+blocksize,p_blocksize-blocksize); readptr += blocksize; inlen -= blocksize; } if (!de->pak && outfile) { fclose(outfile); // if (maj_ver > 1) setfiledate(de->name,de->date); } // demotime =de->date; if (pakfile && (i+1 == numfiles || !directory[i+1].pak || directory[i+1].type == TYPE_PAK)) closepakfile(de); // if (crcval != de->crc) // if (flag[SW_CRC]) // fprintf(stderr,": warning: CRC error!\n"); // else // Sys_Error("CRC checksum error! Archive is broken!"); if (flag[SW_VERIFY]) printf(": ok\n"); else printf("\n"); if (maj_ver > 1) end_zlib_decompression(); } if (maj_ver == 1) end_zlib_decompression(); for (i = 0; i < numfiles; free(directory[i++].name)); free(directory); fclose(handle); }