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