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