#include "dzip.h" #include "dzipcon.h" /* this file deals with uncompressing files made by version 1.x of Dzip and can be omitted without much harm! */ #define CPLUS(x,bit) if (mask & bit) { newcd.x = bplus(*ptr++,oldcd.x); } void demv1_clientdata(void) { uchar *ptr = inptr; int mask = *ptr++; if (mask & 0x01) mask += *ptr++ << 8; if (mask & 0x0100) mask += *ptr++ << 16; if (mask & 0x010000) mask += *ptr++ << 24; CPLUS(voz,0x01000000); CPLUS(pax,0x00100000); CPLUS(ang0,0x08000000); CPLUS(ang1,0x04000000); CPLUS(ang2,0x02000000); CPLUS(vel0,0x00000008); CPLUS(vel1,0x00000004); CPLUS(vel2,0x00000002); if (mask & 0x00008000) newcd.uk10 = !oldcd.uk10; if (mask & 0x00400000) newcd.uk11 = !oldcd.uk11; if (mask & 0x10000000) newcd.invbit = !oldcd.invbit; if (mask & 0x00200000) { newcd.items += getlong(ptr); ptr += 4; } CPLUS(wpf,0x00004000); CPLUS(av,0x00080000); CPLUS(wpm,0x00020000); if (mask & 0x00040000) { newcd.health += getshort(ptr); ptr += 2; } CPLUS(am,0x00002000); CPLUS(sh,0x00001000); CPLUS(nl,0x00000800); CPLUS(rk,0x00000400); CPLUS(ce,0x00800000); CPLUS(wp,0x00000200); discard_msg(ptr-inptr); if ((*ptr & 0xf0) == 0xe0) { mask = *ptr++; if (mask & 0x08) mask |= *ptr++ << 8; newcd.force ^= mask & 0xff07; discard_msg(ptr-inptr); } create_clientdata_msg(); } void demv1_updateentity(void) { uchar *ptr = inptr+1; uchar code = *inptr; int mask, entity; ent_t n, o; dem_updateframe = 1; if (code == 0x82) { discard_msg(1); return; } if (code == 0x83) { while ((entity = getshort(ptr))) { ptr += 2; memcpy(newent+entity,base+entity,sizeof(ent_t)); memcpy(oldent+entity,base+entity,sizeof(ent_t)); } discard_msg(ptr-inptr+2); return; } if (code == 0x84) { while ((mask = getshort(ptr))) { ptr += 2; mask &= 0xffff; if (mask & 0x8000) mask |= *ptr++ << 16; entity = mask & 0x3ff; if (entity > maxent) maxent = entity; newent[entity].force ^= mask & 0xfffc00; } discard_msg(ptr-inptr+2); return; } for (;;) { if (code == 0x81) { mask = (*ptr++ << 8) + 1; code = 0x80; } else { mask = getshort(ptr) & 0xffff; ptr += 2; } if (mask & 0x8000) mask += (*ptr++) << 16; if (mask & 0x800000) mask += (*ptr++) << 24; entity = mask & 0x1ff; if (mask & 0x08000000) entity += 0x200; if (entity > maxent) maxent = entity; if (!entity) break; n = newent[entity]; o = oldent[entity]; n.present = 1; if (mask & 0x010000) n.modelindex = *ptr++; if (mask & 0x0200) n.frame = o.frame+1; if (mask & 0x080000) n.frame = bplus(*ptr++,o.frame); if (mask & 0x01000000) n.colormap = *ptr++; if (mask & 0x02000000) n.skin = *ptr++; if (mask & 0x04000000) n.effects = *ptr++; if (mask & 0x0400) n.org0 = bplus(*ptr++,o.org0); if (mask & 0x100000) { n.org0 = getshort(ptr); ptr += 2; } if (mask & 0x2000) n.ang0 = bplus(*ptr++,o.ang0); if (mask & 0x0800) n.org1 = bplus(*ptr++,o.org1); if (mask & 0x200000) { n.org1 = getshort(ptr); ptr += 2; } if (mask & 0x4000) n.ang1 = bplus(*ptr++,o.ang1); if (mask & 0x1000) n.org2 = bplus(*ptr++,o.org2); if (mask & 0x400000) { n.org2 = getshort(ptr); ptr += 2; } if (mask & 0x020000) n.ang2 = bplus(*ptr++,o.ang2); if (mask & 0x040000) n.newbit = !o.newbit; newent[entity] = n; } discard_msg(ptr-inptr); } void demv1_dxentities(void) { uchar buf[32]; uchar *ptr; long tmp; int i, mask; for (i = 1; i <= maxent; i++) { ent_t n = newent[i], b = base[i]; if (!n.present) continue; ptr = buf+2; mask = 0x80; if (i > 0xff || (n.force & 0x400000)) { tmp = cnvlong(i); memcpy(ptr,&tmp,2); ptr += 2; mask |= 0x4000; } else *ptr++ = i; #define BDIFF(x,bit,bit2) \ if (n.x != b.x || n.force & bit2) \ { *ptr++ = n.x; mask |= bit; } BDIFF(modelindex,0x0400,0x040000); BDIFF(frame,0x0040,0x4000); BDIFF(colormap,0x0800,0x080000); BDIFF(skin,0x1000,0x100000); BDIFF(effects,0x2000,0x200000); if (n.org0 != b.org0 || n.force & 0x010000) { mask |= 0x0002; tmp = cnvlong(n.org0); memcpy(ptr,&tmp,2); ptr += 2; } BDIFF(ang0,0x0100,0x0800); if (n.org1 != b.org1 || n.force & 0x0400) { mask |= 0x0004; tmp = cnvlong(n.org1); memcpy(ptr,&tmp,2); ptr += 2; } BDIFF(ang1,0x0010,0x1000); if (n.org2 != b.org2 || n.force & 0x020000) { mask |= 0x0008; tmp = cnvlong(n.org2); memcpy(ptr,&tmp,2); ptr += 2; } BDIFF(ang2,0x0200,0x2000); if (n.newbit) mask |= 0x20; if (mask & 0xff00) mask |= 0x01; buf[0] = mask & 0xff; buf[1] = (mask & 0xff00) >> 8; if (!(mask & 0x01)) { memcpy(buf+1,buf+2,ptr-buf-2); ptr--; } insert_msg(buf,ptr-buf); memcpy(oldent+i,newent+i,sizeof(ent_t)); } } void dzUncompressV1 (int testing) { int i, inlen = 0; uInt eofptr, blocksize, readptr = 0; char demomode; direntry_t *de; char *action = testing ? "checking" : "extracting"; readptr = totalsize = 12; dzFile_Seek(12); inflateInit(&zs); /* cant possibly fail with my modified zlib */ zs.avail_in = 0; if (testing) outfile = NULL; for (i = 0; i < numfiles; i++) { de = directory + i; crcval = INITCRC; printf("%s %s",action,de->name); fflush(stdout); if (de->type == TYPE_DEMV1) demomode = 1; else if (de->type == TYPE_NORMAL || de->type == TYPE_TXT) demomode = 0; else { error("%s has invalid type %i", de->name, de->type); break; } if (!testing) outfile = open_create(de->name); if (demomode) dem_uncompress_init(de->type); eofptr = de->ptr + de->size; while (readptr < eofptr) { if (!dzRead(inlen)) break; if (demomode) { blocksize = dem_uncompress(eofptr - readptr); if (!blocksize) break; } else { blocksize = totalsize - readptr; if (totalsize >= eofptr) blocksize = eofptr - readptr; Outfile_Write(inblk,blocksize); } if (blocksize != p_blocksize) memcpy(inblk,inblk+blocksize,p_blocksize-blocksize); readptr += blocksize; inlen = p_blocksize - blocksize; } if (crcval != de->crc) error("CRC checksum error! Archive is broken!"); else if (testing) printf(": ok\n"); else printf("\n"); if (outfile) fclose(outfile); } inflateEnd(&zs); }