1 #include "dzip.h"
2 #include "dzipcon.h"
3 
4 /* this file deals with uncompressing files made by
5    version 1.x of Dzip and can be omitted without much harm! */
6 
7 #define CPLUS(x,bit) if (mask & bit) { newcd.x = bplus(*ptr++,oldcd.x); }
8 
demv1_clientdata(void)9 void demv1_clientdata(void)
10 {
11 	uchar *ptr = inptr;
12 	int mask = *ptr++;
13 
14 	if (mask & 0x01) mask += *ptr++ << 8;
15 	if (mask & 0x0100) mask += *ptr++ << 16;
16 	if (mask & 0x010000) mask += *ptr++ << 24;
17 
18 	CPLUS(voz,0x01000000);
19 	CPLUS(pax,0x00100000);
20 	CPLUS(ang0,0x08000000);
21 	CPLUS(ang1,0x04000000);
22 	CPLUS(ang2,0x02000000);
23 	CPLUS(vel0,0x00000008);
24 	CPLUS(vel1,0x00000004);
25 	CPLUS(vel2,0x00000002);
26 	if (mask & 0x00008000) newcd.uk10 = !oldcd.uk10;
27 	if (mask & 0x00400000) newcd.uk11 = !oldcd.uk11;
28 	if (mask & 0x10000000) newcd.invbit = !oldcd.invbit;
29 	if (mask & 0x00200000)
30 	{
31 		newcd.items += getlong(ptr);
32 		ptr += 4;
33 	}
34 	CPLUS(wpf,0x00004000);
35 	CPLUS(av,0x00080000);
36 	CPLUS(wpm,0x00020000);
37 	if (mask & 0x00040000)
38 	{
39 		newcd.health += getshort(ptr);
40 		ptr += 2;
41 	}
42 	CPLUS(am,0x00002000);
43 	CPLUS(sh,0x00001000);
44 	CPLUS(nl,0x00000800);
45 	CPLUS(rk,0x00000400);
46 	CPLUS(ce,0x00800000);
47 	CPLUS(wp,0x00000200);
48 
49 	discard_msg(ptr-inptr);
50 
51 	if ((*ptr & 0xf0) == 0xe0)
52 	{
53 		mask = *ptr++;
54 		if (mask & 0x08) mask |= *ptr++ << 8;
55 		newcd.force ^= mask & 0xff07;
56 		discard_msg(ptr-inptr);
57 	}
58 
59 	create_clientdata_msg();
60 }
61 
demv1_updateentity(void)62 void demv1_updateentity(void)
63 {
64 	uchar *ptr = inptr+1;
65 	uchar code = *inptr;
66 	int mask, entity;
67 	ent_t n, o;
68 
69 	dem_updateframe = 1;
70 
71 	if (code == 0x82) { discard_msg(1); return; }
72 
73 	if (code == 0x83)
74 	{
75 		while ((entity = getshort(ptr)))
76 		{
77 			ptr += 2;
78 			memcpy(newent+entity,base+entity,sizeof(ent_t));
79 			memcpy(oldent+entity,base+entity,sizeof(ent_t));
80 		}
81 		discard_msg(ptr-inptr+2);
82 		return;
83 	}
84 
85 	if (code == 0x84)
86 	{
87 		while ((mask = getshort(ptr)))
88 		{
89 			ptr += 2;
90 			mask &= 0xffff;
91 			if (mask & 0x8000) mask |= *ptr++ << 16;
92 			entity = mask & 0x3ff;
93 			if (entity > maxent) maxent = entity;
94 			newent[entity].force ^= mask & 0xfffc00;
95 		}
96 		discard_msg(ptr-inptr+2);
97 		return;
98 	}
99 
100 	for (;;)
101 	{
102 		if (code == 0x81)
103 		{
104 			mask = (*ptr++ << 8) + 1;
105 			code = 0x80;
106 		}
107 		else
108 		{
109 			mask = getshort(ptr) & 0xffff;
110 			ptr += 2;
111 		}
112 
113 		if (mask & 0x8000) mask += (*ptr++) << 16;
114 		if (mask & 0x800000) mask += (*ptr++) << 24;
115 
116 		entity = mask & 0x1ff;
117 		if (mask & 0x08000000) entity += 0x200;
118 		if (entity > maxent) maxent = entity;
119 		if (!entity) break;
120 
121 		n = newent[entity];
122 		o = oldent[entity];
123 		n.present = 1;
124 		if (mask & 0x010000) n.modelindex = *ptr++;
125 		if (mask & 0x0200) n.frame = o.frame+1;
126 		if (mask & 0x080000) n.frame = bplus(*ptr++,o.frame);
127 		if (mask & 0x01000000) n.colormap = *ptr++;
128 		if (mask & 0x02000000) n.skin = *ptr++;
129 		if (mask & 0x04000000) n.effects = *ptr++;
130 		if (mask & 0x0400) n.org0 = bplus(*ptr++,o.org0);
131 		if (mask & 0x100000) { n.org0 = getshort(ptr); ptr += 2; }
132 		if (mask & 0x2000) n.ang0 = bplus(*ptr++,o.ang0);
133 		if (mask & 0x0800) n.org1 = bplus(*ptr++,o.org1);
134 		if (mask & 0x200000) { n.org1 = getshort(ptr); ptr += 2; }
135 		if (mask & 0x4000) n.ang1 = bplus(*ptr++,o.ang1);
136 		if (mask & 0x1000) n.org2 = bplus(*ptr++,o.org2);
137 		if (mask & 0x400000) { n.org2 = getshort(ptr); ptr += 2; }
138 		if (mask & 0x020000) n.ang2 = bplus(*ptr++,o.ang2);
139 		if (mask & 0x040000) n.newbit = !o.newbit;
140 		newent[entity] = n;
141 	}
142 
143 	discard_msg(ptr-inptr);
144 }
145 
demv1_dxentities(void)146 void demv1_dxentities(void)
147 {
148 	uchar buf[32];
149 	uchar *ptr;
150 	long tmp;
151 	int i, mask;
152 
153 	for (i = 1; i <= maxent; i++)
154 	{
155 		ent_t n = newent[i], b = base[i];
156 
157 		if (!n.present) continue;
158 		ptr = buf+2;
159 		mask = 0x80;
160 
161 		if (i > 0xff || (n.force & 0x400000))
162 		{
163 			tmp = cnvlong(i);
164 			memcpy(ptr,&tmp,2);
165 			ptr += 2;
166 			mask |= 0x4000;
167 		}
168 		else
169 			*ptr++ = i;
170 
171 		#define BDIFF(x,bit,bit2) \
172 			if (n.x != b.x || n.force & bit2) \
173 				{ *ptr++ = n.x; mask |= bit; }
174 
175 		BDIFF(modelindex,0x0400,0x040000);
176 		BDIFF(frame,0x0040,0x4000);
177 		BDIFF(colormap,0x0800,0x080000);
178 		BDIFF(skin,0x1000,0x100000);
179 		BDIFF(effects,0x2000,0x200000);
180 		if (n.org0 != b.org0 || n.force & 0x010000)
181 		    { mask |= 0x0002; tmp = cnvlong(n.org0);
182 		      memcpy(ptr,&tmp,2); ptr += 2; }
183 		BDIFF(ang0,0x0100,0x0800);
184 		if (n.org1 != b.org1 || n.force & 0x0400)
185 		    { mask |= 0x0004; tmp = cnvlong(n.org1);
186 		      memcpy(ptr,&tmp,2); ptr += 2; }
187 		BDIFF(ang1,0x0010,0x1000);
188 		if (n.org2 != b.org2 || n.force & 0x020000)
189 		    { mask |= 0x0008; tmp = cnvlong(n.org2);
190 		      memcpy(ptr,&tmp,2); ptr += 2; }
191 		BDIFF(ang2,0x0200,0x2000);
192 		if (n.newbit) mask |= 0x20;
193 
194 		if (mask & 0xff00) mask |= 0x01;
195 		buf[0] = mask & 0xff;
196 		buf[1] = (mask & 0xff00) >> 8;
197 		if (!(mask & 0x01)) { memcpy(buf+1,buf+2,ptr-buf-2); ptr--; }
198 		insert_msg(buf,ptr-buf);
199 		memcpy(oldent+i,newent+i,sizeof(ent_t));
200 	}
201 
202 }
203 
dzUncompressV1(int testing)204 void dzUncompressV1 (int testing)
205 {
206 	int i, inlen = 0;
207 	uInt eofptr, blocksize, readptr = 0;
208 	char demomode;
209 	direntry_t *de;
210 	char *action = testing ? "checking" : "extracting";
211 
212 	readptr = totalsize = 12;
213 	dzFile_Seek(12);
214 	inflateInit(&zs);	/* cant possibly fail with my modified zlib */
215 	zs.avail_in = 0;
216 
217 	if (testing)
218 		outfile = NULL;
219 
220 	for (i = 0; i < numfiles; i++)
221 	{
222 		de = directory + i;
223 		crcval = INITCRC;
224 		printf("%s %s",action,de->name);
225 		fflush(stdout);
226 
227 		if (de->type == TYPE_DEMV1)
228 			demomode = 1;
229 		else if (de->type == TYPE_NORMAL || de->type == TYPE_TXT)
230 			demomode = 0;
231 		else
232 		{
233 			error("%s has invalid type %i", de->name, de->type);
234 			break;
235 		}
236 
237 		if (!testing)
238 			outfile = open_create(de->name);
239 
240 		if (demomode)
241 			dem_uncompress_init(de->type);
242 
243 		eofptr = de->ptr + de->size;
244 
245 		while (readptr < eofptr)
246 		{
247 			if (!dzRead(inlen))
248 				break;
249 
250 			if (demomode)
251 			{
252 				blocksize = dem_uncompress(eofptr - readptr);
253 				if (!blocksize)
254 					break;
255 			}
256 			else
257 			{
258 				blocksize = totalsize - readptr;
259 				if (totalsize >= eofptr)
260 					blocksize = eofptr - readptr;
261 				Outfile_Write(inblk,blocksize);
262 			}
263 			if (blocksize != p_blocksize)
264 				memcpy(inblk,inblk+blocksize,p_blocksize-blocksize);
265 			readptr += blocksize;
266 			inlen = p_blocksize - blocksize;
267 		}
268 
269 		if (crcval != de->crc)
270 			error("CRC checksum error! Archive is broken!");
271 		else if (testing)
272 			printf(": ok\n");
273 		else
274 			printf("\n");
275 
276 		if (outfile)
277 			fclose(outfile);
278 	}
279 	inflateEnd(&zs);
280 }
281