1 #include "dzip.h"
2 char te_size[] = {8, 8,  8,  8, 8, 16, 16, 8, 8, 16,
3 				  8, 8, 10, 16, 8,  8, 14};
4 
5 int dem_decode_type;
6 
dem_copy_ue()7 void dem_copy_ue()
8 {
9 	char mask = inptr[0] & 0x7f;
10 	char topmask;
11 	int len = 1;
12 
13 	topmask = (mask & 0x01)? inptr[len++] : 0x00;
14 	if (topmask & 0x40) len += 2; else len++;
15 	if (topmask & 0x04) len++;
16 	if (mask & 0x40) len++;
17 	if (topmask & 0x08) len++;
18 	if (topmask & 0x10) len++;
19 	if (topmask & 0x20) len++;
20 	if (mask & 0x02) len += 2;
21 	if (topmask & 0x01) len++;
22 	if (mask & 0x04) len += 2;
23 	if (mask & 0x10) len++;
24 	if (mask & 0x08) len += 2;
25 	if (topmask & 0x02) len++;
26 	if (topmask & 0x80)
27                 Sys_Error("dem_copy_ue(): topmask & 0x80");
28 	copy_msg(len);
29 }
30 
demx_bad()31 void demx_bad()
32 {
33         Sys_Error("bad message %d encountered", *inptr);
34 }
35 
demx_nop()36 void demx_nop()
37 {
38 	copy_msg(1);
39 }
40 
demx_disconnect()41 void demx_disconnect()
42 {
43 	copy_msg(1);
44 }
45 
demx_updatestat()46 void demx_updatestat()
47 {
48 	copy_msg(6);
49 }
50 
demx_version()51 void demx_version()
52 {
53 	copy_msg(5);
54 }
55 
demx_setview()56 void demx_setview()
57 {
58 	copy_msg(3);
59 }
60 
demx_sound()61 void demx_sound()
62 {
63 	int len = 11 - (*inptr > DEM_sound);
64 	int entity, c;
65 	char mask = inptr[1];
66 	char channel;
67 
68 	if (len == 10) mask = *inptr & 3;
69 	if (mask & 0x01) len++;
70 	if (mask & 0x02) len++;
71 
72 	if (dem_decode_type == TYPE_DEMV1) { copy_msg(len); return; }
73 
74 	*inptr = DEM_sound;
75 	insert_msg(inptr,1);
76 
77 	*inptr = mask;
78 	channel = inptr[len-9] & 7;
79 	inptr[len-9] = (inptr[len-9] & 0xf8) + ((2 - channel) & 7);
80 
81 	entity = getshort(inptr+len-9) >> 3;
82 	c = getshort(inptr+len-6); c += newent[entity].org0;
83 	c = cnvlong(c); memcpy(inptr+len-6,&c,2);
84 	c = getshort(inptr+len-4); c += newent[entity].org1;
85 	c = cnvlong(c); memcpy(inptr+len-4,&c,2);
86 	c = getshort(inptr+len-2); c += newent[entity].org2;
87 	c = cnvlong(c); memcpy(inptr+len-2,&c,2);
88 
89 	copy_msg(len);
90 }
91 
demx_longtime()92 void demx_longtime()
93 {
94 	long tmp = getlong(inptr+1);
95 	dem_gametime += tmp;
96 	tmp = cnvlong(dem_gametime);
97 	*inptr = DEM_time;
98 	memcpy(inptr+1,&tmp,4);
99 	copy_msg(5);
100 }
101 
demx_time()102 void demx_time()
103 {
104 	static char buf[5];
105 	long tmp = getshort(inptr+1) & 0xffff;
106 
107 	if (dem_decode_type == TYPE_DEMV1) { demx_longtime(); return; }
108 
109 	dem_gametime += tmp;
110 	tmp = cnvlong(dem_gametime);
111 	buf[0] = DEM_time;
112 	memcpy(buf+1,&tmp,4);
113 	insert_msg(buf,5);
114 	discard_msg(3);
115 }
116 
117 /* used by lots of msgs */
demx_string()118 void demx_string()
119 {
120 	char *ptr = inptr + 1;
121 	while (*ptr++);
122 	copy_msg(ptr-inptr);
123 }
124 
demx_setangle()125 void demx_setangle()
126 {
127 	copy_msg(4);
128 }
129 
demx_serverinfo()130 void demx_serverinfo()
131 {
132 	char *ptr = inptr + 7;
133 	char *start_ptr;
134 	while (*ptr++);
135 	do {
136 		start_ptr = ptr;
137 		while (*ptr++);
138 	} while (ptr - start_ptr > 1);
139 	do {
140 		start_ptr = ptr;
141 		while (*ptr++);
142 	} while (ptr - start_ptr > 1);
143 	copy_msg(ptr-inptr);
144 	sble = 0;
145 }
146 
demx_lightstyle()147 void demx_lightstyle()
148 {
149 	char *ptr = inptr + 2;
150 	while (*ptr++);
151 	copy_msg(ptr-inptr);
152 }
153 
demx_updatename()154 void demx_updatename()
155 {
156 	char *ptr = inptr + 2;
157 	while (*ptr++);
158 	copy_msg(ptr-inptr);
159 }
160 
demx_updatefrags()161 void demx_updatefrags()
162 {
163 	copy_msg(4);
164 }
165 
bplus(int x,int y)166 int bplus(int x, int y)
167 {
168 	if (x >= 128) x -= 256;
169 	return y + x;
170 }
171 
create_clientdata_msg()172 void create_clientdata_msg()
173 {
174 	static char buf[32];
175 	char *ptr = buf+3;
176 	int mask = newcd.invbit? 0 : 0x0200;
177 	long tmp;
178 
179 	buf[0] = DEM_clientdata;
180 
181 	#define CMADD(x,def,bit,bit2) if (newcd.x != def || newcd.force & bit2)\
182 		{ mask |= bit; *ptr++ = newcd.x; }
183 
184 	CMADD(voz,22,0x0001,0x0800);
185 	CMADD(pax,0,0x0002,0x1000);
186 	CMADD(ang0,0,0x0004,0x0100);
187 	CMADD(vel0,0,0x0020,0x0001);
188 	CMADD(ang1,0,0x0008,0x0200);
189 	CMADD(vel1,0,0x0040,0x0002);
190 	CMADD(ang2,0,0x0010,0x0400);
191 	CMADD(vel2,0,0x0080,0x0004);
192 	tmp = cnvlong(newcd.items); memcpy(ptr,&tmp,4); ptr += 4;
193 	if (newcd.uk10) mask |= 0x0400;
194 	if (newcd.uk11) mask |= 0x0800;
195 	CMADD(wpf,0,0x1000,0x2000);
196 	CMADD(av,0,0x2000,0x4000);
197 	CMADD(wpm,0,0x4000,0x8000);
198 	tmp = cnvlong(newcd.health); memcpy(ptr,&tmp,2); ptr += 2;
199 	*ptr++ = newcd.am;
200 	*ptr++ = newcd.sh;
201 	*ptr++ = newcd.nl;
202 	*ptr++ = newcd.rk;
203 	*ptr++ = newcd.ce;
204 	*ptr++ = newcd.wp;
205 	mask = cnvlong(mask);
206 	memcpy(buf+1,&mask,2);
207 	insert_msg(buf,ptr-buf);
208 
209 	oldcd = newcd;
210 }
211 
212 #define CPLUS(x,bit) if (mask & bit) { newcd.x = bplus(*ptr++,oldcd.x); }
213 
demx_clientdata()214 void demx_clientdata()
215 {
216 	char *ptr = inptr;
217 	int mask = *ptr++;
218 
219 	newcd = oldcd;
220 
221 	if (mask & 0x08) mask += *ptr++ << 8;
222 	if (mask & 0x8000) mask += *ptr++ << 16;
223 	if (mask & 0x800000) mask += *ptr++ << 24;
224 
225 	CPLUS(vel2,0x00000001);
226 	CPLUS(vel0,0x00000002);
227 	CPLUS(vel1,0x00000004);
228 
229 	CPLUS(wpf,0x00000100);
230 	if (mask & 0x00000200) newcd.uk10 = !oldcd.uk10;
231 	CPLUS(ang0,0x00000400);
232 	CPLUS(am,0x00000800);
233 	if (mask & 0x00001000) { newcd.health += getshort(ptr); ptr += 2; }
234 	if (mask & 0x00002000) { newcd.items ^= getlong(ptr); ptr += 4; }
235 	CPLUS(av,0x00004000);
236 
237 	CPLUS(pax,0x00010000);
238 	CPLUS(sh,0x00020000);
239 	CPLUS(nl,0x00040000);
240 	CPLUS(rk,0x00080000);
241 	CPLUS(wpm,0x00100000);
242 	CPLUS(wp,0x00200000);
243 	if (mask & 0x00400000) newcd.uk11 = !oldcd.uk11;
244 
245 	CPLUS(voz,0x01000000);
246 	CPLUS(ce,0x02000000);
247 	CPLUS(ang1,0x04000000);
248 	CPLUS(ang2,0x08000000);
249 	if (mask & 0x10000000) newcd.invbit = !oldcd.invbit;
250 
251 	discard_msg(ptr-inptr);
252 
253 	if ((*ptr & 0xf0) == 0x50)
254 	{
255 		mask = *ptr++;
256 		if (mask & 0x08) mask |= *ptr++ << 8;
257 		newcd.force ^= mask & 0xff07;
258 		discard_msg(ptr-inptr);
259 	}
260 
261 	create_clientdata_msg();
262 }
263 
demx_stopsound()264 void demx_stopsound()
265 {
266 	copy_msg(3);
267 }
268 
demx_updatecolors()269 void demx_updatecolors()
270 {
271 	copy_msg(3);
272 }
273 
demx_particle()274 void demx_particle()
275 {
276 	copy_msg(12);
277 }
278 
demx_damage()279 void demx_damage()
280 {
281 	copy_msg(9);
282 }
283 
demx_spawnstatic()284 void demx_spawnstatic()
285 {
286 	copy_msg(14);
287 }
288 
demx_spawnbinary()289 void demx_spawnbinary()
290 {
291 	copy_msg(1);
292 }
293 
demx_spawnbaseline()294 void demx_spawnbaseline()
295 {
296 	char buf[16], *ptr = inptr+3;
297 	ent_t ent;
298 	int mask = getshort(inptr+1);
299 
300 	sble += (mask & 0x03ff);
301 	memset(&ent,0,sizeof(ent_t));
302 	ent.modelindex = *ptr++;
303 	if (mask & 0x0400) ent.frame = *ptr++;
304 	if (mask & 0x0800) ent.colormap = *ptr++;
305 	if (mask & 0x1000) ent.skin = *ptr++;
306 	if (mask & 0x2000)
307 	{
308 		ent.org0 = getshort(ptr); ptr += 2;
309 		ent.org1 = getshort(ptr); ptr += 2;
310 		ent.org2 = getshort(ptr); ptr += 2;
311 	}
312 	if (mask & 0x4000) ent.ang1 = *ptr++;
313 	if (mask & 0x8000) { ent.ang0 = *ptr++; ent.ang2 = *ptr++; }
314 	discard_msg(ptr-inptr);
315 
316 	buf[0] = DEM_spawnbaseline;
317 	mask = cnvlong(sble); memcpy(buf+1,&mask,2);
318 	buf[3] = ent.modelindex;
319 	buf[4] = ent.frame;
320 	buf[5] = ent.colormap;
321 	buf[6] = ent.skin;
322 	mask = cnvlong(ent.org0); memcpy(buf+7,&mask,2);
323 	buf[9] = ent.ang0;
324 	mask = cnvlong(ent.org1); memcpy(buf+10,&mask,2);
325 	buf[12] = ent.ang1;
326 	mask = cnvlong(ent.org2); memcpy(buf+13,&mask,2);
327 	buf[15] = ent.ang2;
328 	insert_msg(buf,16);
329 
330 	base[sble] = ent;
331 	copybaseline = 1;
332 }
333 
334 extern char te_size[];
335 
demx_temp_entity()336 void demx_temp_entity()
337 {
338 	if (inptr[1] == 17)
339 		copy_msg(strlen(inptr + 2) + 17);
340 	else
341 		copy_msg(te_size[inptr[1]]);
342 }
343 
demx_setpause()344 void demx_setpause()
345 {
346 	copy_msg(2);
347 }
348 
demx_signonnum()349 void demx_signonnum()
350 {
351 	copy_msg(2);
352 }
353 
demx_killedmonster()354 void demx_killedmonster()
355 {
356 	copy_msg(1);
357 }
358 
demx_foundsecret()359 void demx_foundsecret()
360 {
361 	copy_msg(1);
362 }
363 
demx_spawnstaticsound()364 void demx_spawnstaticsound()
365 {
366 	copy_msg(10);
367 }
368 
demx_intermission()369 void demx_intermission()
370 {
371 	copy_msg(1);
372 }
373 
demx_cdtrack()374 void demx_cdtrack()
375 {
376 	copy_msg(3);
377 }
378 
demx_sellscreen()379 void demx_sellscreen()
380 {
381 	copy_msg(1);
382 }
383 
384 /* nehahra */
demx_showlmp(void)385 void demx_showlmp(void)
386 {
387 	char *ptr = inptr + 1;
388 	while (*ptr++);
389 	while (*ptr++);
390 	ptr += 2;
391 	*inptr = DEM_showlmp;
392 	copy_msg(ptr-inptr);
393 }
394 
demx_updateentity()395 void demx_updateentity()
396 {
397 	char buf[32], *ptr;
398 	int mask, i, entity;
399 	int baseval = 0, prev;
400 	ent_t n, o;
401 	long tmp;
402 
403 
404 	lastent = 0;
405 	for (ptr = inptr+1; *ptr; ptr++)
406 	{
407 		if (*ptr == 0xff) { baseval += 0xfe; continue; }
408 		entity = baseval + *ptr;
409 		newent[entity].active = 1;
410 		while (entlink[lastent] <= entity) lastent = entlink[lastent];
411 		if (lastent < entity)
412 		{
413 			entlink[entity] = entlink[lastent];
414 			entlink[lastent] = entity;
415 		}
416 	}
417 
418 	for (prev = 0, i = entlink[0], ptr++; i < MAX_ENT; i = entlink[i])
419 	{
420 		newent[i].org0 += newent[i].od0;
421 		newent[i].org1 += newent[i].od1;
422 		newent[i].org2 += newent[i].od2;
423 
424 		if (!newent[i].active) { prev = i; continue; }
425 
426 		mask = *ptr++;
427 
428 		if (mask == 0x80)
429 		{
430 			oldent[i] = newent[i] = base[i];
431 			entlink[prev] = entlink[i];
432 			continue;
433 		}
434 
435 		prev = i;
436 
437 		if (mask == 0x00) { newent[i].active = 0; continue; }
438 
439 		if (mask & 0x80) mask += (*ptr++) << 8;
440 		if (mask & 0x8000) mask += (*ptr++) << 16;
441 
442 		n = newent[i];
443 		o = oldent[i];
444 
445 		if (mask & 0x000001) { n.od2 = bplus(*ptr++,o.od2);
446 				       n.org2 = o.org2 + n.od2; }
447 		if (mask & 0x000800) { n.org2 = getshort(ptr); ptr += 2;
448 				       n.od2 = n.org2 - o.org2; }
449 		if (mask & 0x000002) { n.od1 = bplus(*ptr++,o.od1);
450 				       n.org1 = o.org1 + n.od1; }
451 		if (mask & 0x000400) { n.org1 = getshort(ptr); ptr += 2;
452 				       n.od1 = n.org1 - o.org1; }
453 		if (mask & 0x000004) { n.od0 = bplus(*ptr++,o.od0);
454 				       n.org0 = o.org0 + n.od0; }
455 		if (mask & 0x000200) { n.org0 = getshort(ptr); ptr += 2;
456 				       n.od0 = n.org0 - o.org0; }
457 
458 		if (mask & 0x000008) n.ang0 = bplus(*ptr++,o.ang0);
459 		if (mask & 0x000010) n.ang1 = bplus(*ptr++,o.ang1);
460 		if (mask & 0x000020) n.ang2 = bplus(*ptr++,o.ang2);
461 		if (mask & 0x000040) n.frame = o.frame+1;
462 		if (mask & 0x000100) n.frame = bplus(*ptr++,o.frame);
463 
464 		if (mask & 0x001000) n.effects = *ptr++;
465 		if (mask & 0x002000) n.modelindex = *ptr++;
466 		if (mask & 0x004000) n.new = !o.new;
467 		if (mask & 0x010000) n.colormap = *ptr++;
468 		if (mask & 0x020000) n.skin = *ptr++;
469 	// nehahra
470 		if (mask & 0x040000)
471 		{ n.alpha = getfloat(ptr); ptr+= 4; }
472 		else n.alpha = o.alpha;
473 		if (mask & 0x080000) n.fullbright = *ptr++;
474 		else n.fullbright = o.fullbright;
475 
476 		newent[i] = n;
477 	}
478 
479 	if (*ptr == 0x31)
480 	{
481 		ptr++;
482 		while ((mask = getshort(ptr)))
483 		{
484 			ptr += 2;
485 			mask &= 0xffff;
486 			if (mask & 0x8000) mask |= *ptr++ << 16;
487 			entity = mask & 0x3ff;
488 			newent[entity].force ^= mask & 0xfffc00;
489 		}
490 		ptr += 2;
491 	}
492 
493 	discard_msg(ptr-inptr);
494 
495 	for (i = entlink[0]; i < MAX_ENT; i = entlink[i])
496 	{
497 		ent_t n = newent[i], b = base[i];
498 
499 		ptr = buf+2;
500 		mask = 0x80;
501 
502 		if (i > 0xff || (n.force & 0x400000))
503 		{
504 			tmp = cnvlong(i);
505 			memcpy(ptr,&tmp,2);
506 			ptr += 2;
507 			mask |= 0x4000;
508 		}
509 		else
510 			*ptr++ = i;
511 
512 		#define BDIFF(x,bit,bit2) \
513 			if (n.x != b.x || n.force & bit2) \
514 				{ *ptr++ = n.x; mask |= bit; }
515 
516 		BDIFF(modelindex,0x0400,0x040000);
517 		BDIFF(frame,0x0040,0x4000);
518 		BDIFF(colormap,0x0800,0x080000);
519 		BDIFF(skin,0x1000,0x100000);
520 		BDIFF(effects,0x2000,0x200000);
521 		if (n.org0 != b.org0 || n.force & 0x010000)
522 		    { mask |= 0x0002; tmp = cnvlong(n.org0);
523 		      memcpy(ptr,&tmp,2); ptr += 2; }
524 		BDIFF(ang0,0x0100,0x0800);
525 		if (n.org1 != b.org1 || n.force & 0x0400)
526 		    { mask |= 0x0004; tmp = cnvlong(n.org1);
527 		      memcpy(ptr,&tmp,2); ptr += 2; }
528 		BDIFF(ang1,0x0010,0x1000);
529 		if (n.org2 != b.org2 || n.force & 0x020000)
530 		    { mask |= 0x0008; tmp = cnvlong(n.org2);
531 		      memcpy(ptr,&tmp,2); ptr += 2; }
532 		BDIFF(ang2,0x0200,0x2000);
533 // nehahra
534 		if (n.force & 0x800000)
535 		{
536 			float f = 1;
537 
538 			if (n.fullbright)
539 				f = 2;
540 			tmp = cnvlong(*(int *)&f);
541 			memcpy(ptr, &tmp, 4);
542 			tmp = cnvlong(*(int *)&n.alpha);
543 			memcpy(ptr + 4, &tmp, 4);
544 			ptr += 8;
545 			if (f == 2)
546 			{
547 				f = (char)(n.fullbright - 1);
548 				tmp = cnvlong(*(int *)&f);
549 				memcpy(ptr, &tmp, 4);
550 				ptr += 4;
551 			}
552 			mask |= 0x8000;
553 		}
554 
555 		if (n.new) mask |= 0x20;
556 		if (mask & 0xff00) mask |= 0x01;
557 		buf[0] = mask & 0xff;
558 		buf[1] = (mask & 0xff00) >> 8;
559 		if (!(mask & 0x01)) { memcpy(buf+1,buf+2,ptr-buf-2); ptr--; }
560 		insert_msg(buf,ptr-buf);
561 
562 		oldent[i] = newent[i];
563 	}
564 
565 }
566 
567 void (*demx_message[])() = {
568 	demx_bad, demx_nop, demx_disconnect, demx_updatestat, demx_version,
569 	demx_setview, demx_sound, demx_time, demx_string, demx_string,
570 	demx_setangle, demx_serverinfo, demx_lightstyle, demx_updatename,
571 	demx_updatefrags, demx_clientdata, demx_stopsound, demx_updatecolors,
572 	demx_particle, demx_damage, demx_spawnstatic, demx_spawnbinary,
573 	demx_spawnbaseline, demx_temp_entity, demx_setpause, demx_signonnum,
574 	demx_string, demx_killedmonster, demx_foundsecret,
575 	demx_spawnstaticsound, demx_intermission, demx_string,
576 	demx_cdtrack, demx_sellscreen, demx_string, demx_longtime,
577 	demx_string, demx_string, demx_showlmp	/* nehahra */
578 };
579 
580 long cam0, cam1, cam2;
581 char cdstring_char;
582 
dem_uncompress_init(int type)583 void dem_uncompress_init (int type)
584 {
585 	cdstring_char = 0;
586 
587 	dem_decode_type = type;
588 	memset(&base,0,sizeof(ent_t)*MAX_ENT);
589 	memset(&oldent,0,sizeof(ent_t)*MAX_ENT);
590 	memset(&oldcd,0,sizeof(cdata_t));
591 	oldcd.voz = 22;
592 	oldcd.items = 0x4001;
593 	entlink[0] = MAX_ENT;
594 	cam0 = cam1 = cam2 = 0;
595 	copybaseline = 0;
596 	dem_gametime = 0;
597 	maxent = 0;
598 	sble = 0;
599 }
600 
dem_uncompress()601 int dem_uncompress ()
602 {
603 	long a1;
604 	char cfields;
605 	int uemask = (dem_decode_type == TYPE_DEMV1)? 0x80 : 0x30;
606 	int cdmask = (dem_decode_type == TYPE_DEMV1)? 0xf0 : 0x40;
607 
608 	inptr = inblk;
609 
610 	if (!cdstring_char)
611 		while (cdstring_char != '\n')
612 		{
613 			cdstring_char = *inptr++;
614 			write_output(&cdstring_char,1);
615 		}
616 
617 	cfields = *inptr++;
618 
619 	if (cfields == 0xff)
620 	{
621 		long len = getlong(inblk+1);
622 		write_output(inblk+5,len);
623 		return len+5;
624 	}
625 
626 	if (cfields & 1) { cam0 += getlong(inptr); inptr += 4; }
627 	if (cfields & 2) { cam1 += getlong(inptr); inptr += 4; }
628 	if (cfields & 4) { cam2 += getlong(inptr); inptr += 4; }
629 
630 	outlen = 0;
631 	insert_msg(&a1,4);
632 	a1 = cnvlong(cam0); insert_msg(&a1,4);
633 	a1 = cnvlong(cam1); insert_msg(&a1,4);
634 	a1 = cnvlong(cam2); insert_msg(&a1,4);
635 
636 	dem_updateframe = 0;
637 	while (*inptr)
638 	{
639 		if ((*inptr & 0xf8) == uemask)
640 			demx_updateentity();
641 		else
642 		{
643 			if (dem_updateframe)
644 				{ demv1_dxentities(); dem_updateframe = 0; }
645 			if (*inptr <= DZ_showlmp)
646 				demx_message[(int)(*inptr)]();
647 			else if ((*inptr & 0xf0) == cdmask)
648 				demx_clientdata();
649 			else if ((*inptr & 0xf8) == 0x38)
650 				demx_sound();
651 			else if (*inptr >= 0x80) dem_copy_ue();
652                         else
653 				demx_message[DEM_bad]();
654 		}
655 	}
656 	if (dem_updateframe) demv1_dxentities();
657 
658 	outlen -= 16;
659 	outlen = cnvlong(outlen);
660 	memcpy(outblk,&outlen,4);
661 	write_output(outblk,cnvlong(outlen)+16);
662 
663 	if (copybaseline)
664 	{
665 		copybaseline = 0;
666 		memcpy(oldent,base,sizeof(ent_t)*MAX_ENT);
667 		memcpy(newent,base,sizeof(ent_t)*MAX_ENT);
668 	}
669 
670 	return inptr-inblk+1;
671 }
672 
demv1_dxentities()673 void demv1_dxentities()
674 {
675 	char buf[32];
676 	char *ptr;
677 	long tmp;
678 	int i, mask;
679 
680 	for (i = 1; i <= maxent; i++)
681 	{
682 		ent_t n = newent[i], b = base[i];
683 
684 		if (!n.present) continue;
685 		ptr = buf+2;
686 		mask = 0x80;
687 
688 		if (i > 0xff || (n.force & 0x400000))
689 		{
690 			tmp = cnvlong(i);
691 			memcpy(ptr,&tmp,2);
692 			ptr += 2;
693 			mask |= 0x4000;
694 		}
695 		else
696 			*ptr++ = i;
697 
698 		#define BDIFF(x,bit,bit2) \
699 			if (n.x != b.x || n.force & bit2) \
700 				{ *ptr++ = n.x; mask |= bit; }
701 
702 		BDIFF(modelindex,0x0400,0x040000);
703 		BDIFF(frame,0x0040,0x4000);
704 		BDIFF(colormap,0x0800,0x080000);
705 		BDIFF(skin,0x1000,0x100000);
706 		BDIFF(effects,0x2000,0x200000);
707 		if (n.org0 != b.org0 || n.force & 0x010000)
708 		    { mask |= 0x0002; tmp = cnvlong(n.org0);
709 		      memcpy(ptr,&tmp,2); ptr += 2; }
710 		BDIFF(ang0,0x0100,0x0800);
711 		if (n.org1 != b.org1 || n.force & 0x0400)
712 		    { mask |= 0x0004; tmp = cnvlong(n.org1);
713 		      memcpy(ptr,&tmp,2); ptr += 2; }
714 		BDIFF(ang1,0x0010,0x1000);
715 		if (n.org2 != b.org2 || n.force & 0x020000)
716 		    { mask |= 0x0008; tmp = cnvlong(n.org2);
717 		      memcpy(ptr,&tmp,2); ptr += 2; }
718 		BDIFF(ang2,0x0200,0x2000);
719 		if (n.new) mask |= 0x20;
720 
721 		if (mask & 0xff00) mask |= 0x01;
722 		buf[0] = mask & 0xff;
723 		buf[1] = (mask & 0xff00) >> 8;
724 		if (!(mask & 0x01)) { memcpy(buf+1,buf+2,ptr-buf-2); ptr--; }
725 		insert_msg(buf,ptr-buf);
726 		memcpy(oldent+i,newent+i,sizeof(ent_t));
727 	}
728 
729 }
730 
731 
732