changed a warning string
[mesa.git] / src / mesa / main / depth.c
1 /* $Id: depth.c,v 1.9 1999/11/11 01:22:26 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 #ifdef PC_HEADER
28 #include "all.h"
29 #else
30 #include "glheader.h"
31 #include "context.h"
32 #include "enums.h"
33 #include "depth.h"
34 #include "mem.h"
35 #include "types.h"
36 #endif
37
38
39
40 /**********************************************************************/
41 /***** API Functions *****/
42 /**********************************************************************/
43
44
45
46 void
47 _mesa_ClearDepth( GLclampd depth )
48 {
49 GET_CURRENT_CONTEXT(ctx);
50 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClearDepth");
51 ctx->Depth.Clear = (GLfloat) CLAMP( depth, 0.0, 1.0 );
52 if (ctx->Driver.ClearDepth)
53 (*ctx->Driver.ClearDepth)( ctx, ctx->Depth.Clear );
54 }
55
56
57
58 void
59 _mesa_DepthFunc( GLenum func )
60 {
61 GET_CURRENT_CONTEXT(ctx);
62 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthFunc");
63
64 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
65 fprintf(stderr, "glDepthFunc %s\n", gl_lookup_enum_by_nr(func));
66
67 switch (func) {
68 case GL_LESS: /* (default) pass if incoming z < stored z */
69 case GL_GEQUAL:
70 case GL_LEQUAL:
71 case GL_GREATER:
72 case GL_NOTEQUAL:
73 case GL_EQUAL:
74 case GL_ALWAYS:
75 if (ctx->Depth.Func != func) {
76 ctx->Depth.Func = func;
77 ctx->NewState |= NEW_RASTER_OPS;
78 ctx->TriangleCaps &= ~DD_Z_NEVER;
79 if (ctx->Driver.DepthFunc) {
80 (*ctx->Driver.DepthFunc)( ctx, func );
81 }
82 }
83 break;
84 case GL_NEVER:
85 if (ctx->Depth.Func != func) {
86 ctx->Depth.Func = func;
87 ctx->NewState |= NEW_RASTER_OPS;
88 ctx->TriangleCaps |= DD_Z_NEVER;
89 if (ctx->Driver.DepthFunc) {
90 (*ctx->Driver.DepthFunc)( ctx, func );
91 }
92 }
93 break;
94 default:
95 gl_error( ctx, GL_INVALID_ENUM, "glDepth.Func" );
96 }
97 }
98
99
100
101 void
102 _mesa_DepthMask( GLboolean flag )
103 {
104 GET_CURRENT_CONTEXT(ctx);
105 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthMask");
106
107 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
108 fprintf(stderr, "glDepthMask %d\n", flag);
109
110 /*
111 * GL_TRUE indicates depth buffer writing is enabled (default)
112 * GL_FALSE indicates depth buffer writing is disabled
113 */
114 if (ctx->Depth.Mask != flag) {
115 ctx->Depth.Mask = flag;
116 ctx->NewState |= NEW_RASTER_OPS;
117 if (ctx->Driver.DepthMask) {
118 (*ctx->Driver.DepthMask)( ctx, flag );
119 }
120 }
121 }
122
123
124
125 /**********************************************************************/
126 /***** Depth Testing Functions *****/
127 /**********************************************************************/
128
129
130 /*
131 * Depth test horizontal spans of fragments. These functions are called
132 * via ctx->Driver.depth_test_span only.
133 *
134 * Input: n - number of pixels in the span
135 * x, y - location of leftmost pixel in span in window coords
136 * z - array [n] of integer depth values
137 * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw)
138 * Return: number of pixels which passed depth test
139 */
140
141
142 /*
143 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
144 */
145 GLuint gl_depth_test_span_generic( GLcontext* ctx,
146 GLuint n, GLint x, GLint y,
147 const GLdepth z[],
148 GLubyte mask[] )
149 {
150 GLdepth *zptr = Z_ADDRESS( ctx, x, y );
151 GLubyte *m = mask;
152 GLuint i;
153 GLuint passed = 0;
154
155 /* switch cases ordered from most frequent to less frequent */
156 switch (ctx->Depth.Func) {
157 case GL_LESS:
158 if (ctx->Depth.Mask) {
159 /* Update Z buffer */
160 for (i=0; i<n; i++,zptr++,m++) {
161 if (*m) {
162 if (z[i] < *zptr) {
163 /* pass */
164 *zptr = z[i];
165 passed++;
166 }
167 else {
168 /* fail */
169 *m = 0;
170 }
171 }
172 }
173 }
174 else {
175 /* Don't update Z buffer */
176 for (i=0; i<n; i++,zptr++,m++) {
177 if (*m) {
178 if (z[i] < *zptr) {
179 /* pass */
180 passed++;
181 }
182 else {
183 *m = 0;
184 }
185 }
186 }
187 }
188 break;
189 case GL_LEQUAL:
190 if (ctx->Depth.Mask) {
191 /* Update Z buffer */
192 for (i=0;i<n;i++,zptr++,m++) {
193 if (*m) {
194 if (z[i] <= *zptr) {
195 *zptr = z[i];
196 passed++;
197 }
198 else {
199 *m = 0;
200 }
201 }
202 }
203 }
204 else {
205 /* Don't update Z buffer */
206 for (i=0;i<n;i++,zptr++,m++) {
207 if (*m) {
208 if (z[i] <= *zptr) {
209 /* pass */
210 passed++;
211 }
212 else {
213 *m = 0;
214 }
215 }
216 }
217 }
218 break;
219 case GL_GEQUAL:
220 if (ctx->Depth.Mask) {
221 /* Update Z buffer */
222 for (i=0;i<n;i++,zptr++,m++) {
223 if (*m) {
224 if (z[i] >= *zptr) {
225 *zptr = z[i];
226 passed++;
227 }
228 else {
229 *m = 0;
230 }
231 }
232 }
233 }
234 else {
235 /* Don't update Z buffer */
236 for (i=0;i<n;i++,zptr++,m++) {
237 if (*m) {
238 if (z[i] >= *zptr) {
239 /* pass */
240 passed++;
241 }
242 else {
243 *m = 0;
244 }
245 }
246 }
247 }
248 break;
249 case GL_GREATER:
250 if (ctx->Depth.Mask) {
251 /* Update Z buffer */
252 for (i=0;i<n;i++,zptr++,m++) {
253 if (*m) {
254 if (z[i] > *zptr) {
255 *zptr = z[i];
256 passed++;
257 }
258 else {
259 *m = 0;
260 }
261 }
262 }
263 }
264 else {
265 /* Don't update Z buffer */
266 for (i=0;i<n;i++,zptr++,m++) {
267 if (*m) {
268 if (z[i] > *zptr) {
269 /* pass */
270 passed++;
271 }
272 else {
273 *m = 0;
274 }
275 }
276 }
277 }
278 break;
279 case GL_NOTEQUAL:
280 if (ctx->Depth.Mask) {
281 /* Update Z buffer */
282 for (i=0;i<n;i++,zptr++,m++) {
283 if (*m) {
284 if (z[i] != *zptr) {
285 *zptr = z[i];
286 passed++;
287 }
288 else {
289 *m = 0;
290 }
291 }
292 }
293 }
294 else {
295 /* Don't update Z buffer */
296 for (i=0;i<n;i++,zptr++,m++) {
297 if (*m) {
298 if (z[i] != *zptr) {
299 /* pass */
300 passed++;
301 }
302 else {
303 *m = 0;
304 }
305 }
306 }
307 }
308 break;
309 case GL_EQUAL:
310 if (ctx->Depth.Mask) {
311 /* Update Z buffer */
312 for (i=0;i<n;i++,zptr++,m++) {
313 if (*m) {
314 if (z[i] == *zptr) {
315 *zptr = z[i];
316 passed++;
317 }
318 else {
319 *m =0;
320 }
321 }
322 }
323 }
324 else {
325 /* Don't update Z buffer */
326 for (i=0;i<n;i++,zptr++,m++) {
327 if (*m) {
328 if (z[i] == *zptr) {
329 /* pass */
330 passed++;
331 }
332 else {
333 *m =0;
334 }
335 }
336 }
337 }
338 break;
339 case GL_ALWAYS:
340 if (ctx->Depth.Mask) {
341 /* Update Z buffer */
342 for (i=0;i<n;i++,zptr++,m++) {
343 if (*m) {
344 *zptr = z[i];
345 passed++;
346 }
347 }
348 }
349 else {
350 /* Don't update Z buffer or mask */
351 passed = n;
352 }
353 break;
354 case GL_NEVER:
355 for (i=0;i<n;i++) {
356 mask[i] = 0;
357 }
358 break;
359 default:
360 gl_problem(ctx, "Bad depth func in gl_depth_test_span_generic");
361 } /*switch*/
362
363 return passed;
364 }
365
366
367
368 /*
369 * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE).
370 */
371 GLuint gl_depth_test_span_less( GLcontext* ctx,
372 GLuint n, GLint x, GLint y, const GLdepth z[],
373 GLubyte mask[] )
374 {
375 GLdepth *zptr = Z_ADDRESS( ctx, x, y );
376 GLuint i;
377 GLuint passed = 0;
378
379 for (i=0; i<n; i++) {
380 if (mask[i]) {
381 if (z[i] < zptr[i]) {
382 /* pass */
383 zptr[i] = z[i];
384 passed++;
385 }
386 else {
387 /* fail */
388 mask[i] = 0;
389 }
390 }
391 }
392 return passed;
393 }
394
395
396 /*
397 * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE).
398 */
399 GLuint gl_depth_test_span_greater( GLcontext* ctx,
400 GLuint n, GLint x, GLint y,
401 const GLdepth z[],
402 GLubyte mask[] )
403 {
404 GLdepth *zptr = Z_ADDRESS( ctx, x, y );
405 GLuint i;
406 GLuint passed = 0;
407
408 for (i=0; i<n; i++) {
409 if (mask[i]) {
410 if (z[i] > zptr[i]) {
411 /* pass */
412 zptr[i] = z[i];
413 passed++;
414 }
415 else {
416 /* fail */
417 mask[i] = 0;
418 }
419 }
420 }
421 return passed;
422 }
423
424
425
426 /*
427 * Depth test an array of randomly positioned fragments.
428 */
429
430
431 #define ZADDR_SETUP GLdepth *depthbuffer = ctx->Buffer->Depth; \
432 GLint width = ctx->Buffer->Width;
433
434 #define ZADDR( X, Y ) (depthbuffer + (Y) * width + (X) )
435
436
437
438 /*
439 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
440 */
441 void gl_depth_test_pixels_generic( GLcontext* ctx,
442 GLuint n, const GLint x[], const GLint y[],
443 const GLdepth z[], GLubyte mask[] )
444 {
445 register GLdepth *zptr;
446 register GLuint i;
447
448 /* switch cases ordered from most frequent to less frequent */
449 switch (ctx->Depth.Func) {
450 case GL_LESS:
451 if (ctx->Depth.Mask) {
452 /* Update Z buffer */
453 for (i=0; i<n; i++) {
454 if (mask[i]) {
455 zptr = Z_ADDRESS(ctx,x[i],y[i]);
456 if (z[i] < *zptr) {
457 /* pass */
458 *zptr = z[i];
459 }
460 else {
461 /* fail */
462 mask[i] = 0;
463 }
464 }
465 }
466 }
467 else {
468 /* Don't update Z buffer */
469 for (i=0; i<n; i++) {
470 if (mask[i]) {
471 zptr = Z_ADDRESS(ctx,x[i],y[i]);
472 if (z[i] < *zptr) {
473 /* pass */
474 }
475 else {
476 /* fail */
477 mask[i] = 0;
478 }
479 }
480 }
481 }
482 break;
483 case GL_LEQUAL:
484 if (ctx->Depth.Mask) {
485 /* Update Z buffer */
486 for (i=0; i<n; i++) {
487 if (mask[i]) {
488 zptr = Z_ADDRESS(ctx,x[i],y[i]);
489 if (z[i] <= *zptr) {
490 /* pass */
491 *zptr = z[i];
492 }
493 else {
494 /* fail */
495 mask[i] = 0;
496 }
497 }
498 }
499 }
500 else {
501 /* Don't update Z buffer */
502 for (i=0; i<n; i++) {
503 if (mask[i]) {
504 zptr = Z_ADDRESS(ctx,x[i],y[i]);
505 if (z[i] <= *zptr) {
506 /* pass */
507 }
508 else {
509 /* fail */
510 mask[i] = 0;
511 }
512 }
513 }
514 }
515 break;
516 case GL_GEQUAL:
517 if (ctx->Depth.Mask) {
518 /* Update Z buffer */
519 for (i=0; i<n; i++) {
520 if (mask[i]) {
521 zptr = Z_ADDRESS(ctx,x[i],y[i]);
522 if (z[i] >= *zptr) {
523 /* pass */
524 *zptr = z[i];
525 }
526 else {
527 /* fail */
528 mask[i] = 0;
529 }
530 }
531 }
532 }
533 else {
534 /* Don't update Z buffer */
535 for (i=0; i<n; i++) {
536 if (mask[i]) {
537 zptr = Z_ADDRESS(ctx,x[i],y[i]);
538 if (z[i] >= *zptr) {
539 /* pass */
540 }
541 else {
542 /* fail */
543 mask[i] = 0;
544 }
545 }
546 }
547 }
548 break;
549 case GL_GREATER:
550 if (ctx->Depth.Mask) {
551 /* Update Z buffer */
552 for (i=0; i<n; i++) {
553 if (mask[i]) {
554 zptr = Z_ADDRESS(ctx,x[i],y[i]);
555 if (z[i] > *zptr) {
556 /* pass */
557 *zptr = z[i];
558 }
559 else {
560 /* fail */
561 mask[i] = 0;
562 }
563 }
564 }
565 }
566 else {
567 /* Don't update Z buffer */
568 for (i=0; i<n; i++) {
569 if (mask[i]) {
570 zptr = Z_ADDRESS(ctx,x[i],y[i]);
571 if (z[i] > *zptr) {
572 /* pass */
573 }
574 else {
575 /* fail */
576 mask[i] = 0;
577 }
578 }
579 }
580 }
581 break;
582 case GL_NOTEQUAL:
583 if (ctx->Depth.Mask) {
584 /* Update Z buffer */
585 for (i=0; i<n; i++) {
586 if (mask[i]) {
587 zptr = Z_ADDRESS(ctx,x[i],y[i]);
588 if (z[i] != *zptr) {
589 /* pass */
590 *zptr = z[i];
591 }
592 else {
593 /* fail */
594 mask[i] = 0;
595 }
596 }
597 }
598 }
599 else {
600 /* Don't update Z buffer */
601 for (i=0; i<n; i++) {
602 if (mask[i]) {
603 zptr = Z_ADDRESS(ctx,x[i],y[i]);
604 if (z[i] != *zptr) {
605 /* pass */
606 }
607 else {
608 /* fail */
609 mask[i] = 0;
610 }
611 }
612 }
613 }
614 break;
615 case GL_EQUAL:
616 if (ctx->Depth.Mask) {
617 /* Update Z buffer */
618 for (i=0; i<n; i++) {
619 if (mask[i]) {
620 zptr = Z_ADDRESS(ctx,x[i],y[i]);
621 if (z[i] == *zptr) {
622 /* pass */
623 *zptr = z[i];
624 }
625 else {
626 /* fail */
627 mask[i] = 0;
628 }
629 }
630 }
631 }
632 else {
633 /* Don't update Z buffer */
634 for (i=0; i<n; i++) {
635 if (mask[i]) {
636 zptr = Z_ADDRESS(ctx,x[i],y[i]);
637 if (z[i] == *zptr) {
638 /* pass */
639 }
640 else {
641 /* fail */
642 mask[i] = 0;
643 }
644 }
645 }
646 }
647 break;
648 case GL_ALWAYS:
649 if (ctx->Depth.Mask) {
650 /* Update Z buffer */
651 for (i=0; i<n; i++) {
652 if (mask[i]) {
653 zptr = Z_ADDRESS(ctx,x[i],y[i]);
654 *zptr = z[i];
655 }
656 }
657 }
658 else {
659 /* Don't update Z buffer or mask */
660 }
661 break;
662 case GL_NEVER:
663 /* depth test never passes */
664 for (i=0;i<n;i++) {
665 mask[i] = 0;
666 }
667 break;
668 default:
669 gl_problem(ctx, "Bad depth func in gl_depth_test_pixels_generic");
670 } /*switch*/
671 }
672
673
674
675 /*
676 * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ).
677 */
678 void gl_depth_test_pixels_less( GLcontext* ctx,
679 GLuint n, const GLint x[], const GLint y[],
680 const GLdepth z[], GLubyte mask[] )
681 {
682 GLdepth *zptr;
683 GLuint i;
684
685 for (i=0; i<n; i++) {
686 if (mask[i]) {
687 zptr = Z_ADDRESS(ctx,x[i],y[i]);
688 if (z[i] < *zptr) {
689 /* pass */
690 *zptr = z[i];
691 }
692 else {
693 /* fail */
694 mask[i] = 0;
695 }
696 }
697 }
698 }
699
700
701 /*
702 * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ).
703 */
704 void gl_depth_test_pixels_greater( GLcontext* ctx,
705 GLuint n, const GLint x[], const GLint y[],
706 const GLdepth z[], GLubyte mask[] )
707 {
708 GLdepth *zptr;
709 GLuint i;
710
711 for (i=0; i<n; i++) {
712 if (mask[i]) {
713 zptr = Z_ADDRESS(ctx,x[i],y[i]);
714 if (z[i] > *zptr) {
715 /* pass */
716 *zptr = z[i];
717 }
718 else {
719 /* fail */
720 mask[i] = 0;
721 }
722 }
723 }
724 }
725
726
727
728
729 /**********************************************************************/
730 /***** Read Depth Buffer *****/
731 /**********************************************************************/
732
733
734 /*
735 * Return a span of depth values from the depth buffer as floats in [0,1].
736 * This function is only called through Driver.read_depth_span_float()
737 * Input: n - how many pixels
738 * x,y - location of first pixel
739 * Output: depth - the array of depth values
740 */
741 void gl_read_depth_span_float( GLcontext* ctx,
742 GLuint n, GLint x, GLint y, GLfloat depth[] )
743 {
744 GLdepth *zptr;
745 GLfloat scale;
746 GLuint i;
747
748 scale = 1.0F / DEPTH_SCALE;
749
750 if (ctx->Buffer->Depth) {
751 zptr = Z_ADDRESS( ctx, x, y );
752 for (i=0;i<n;i++) {
753 depth[i] = (GLfloat) zptr[i] * scale;
754 }
755 }
756 else {
757 for (i=0;i<n;i++) {
758 depth[i] = 0.0F;
759 }
760 }
761 }
762
763
764 /*
765 * Return a span of depth values from the depth buffer as integers in
766 * [0,MAX_DEPTH].
767 * This function is only called through Driver.read_depth_span_int()
768 * Input: n - how many pixels
769 * x,y - location of first pixel
770 * Output: depth - the array of depth values
771 */
772 void gl_read_depth_span_int( GLcontext* ctx,
773 GLuint n, GLint x, GLint y, GLdepth depth[] )
774 {
775 if (ctx->Buffer->Depth) {
776 GLdepth *zptr = Z_ADDRESS( ctx, x, y );
777 MEMCPY( depth, zptr, n * sizeof(GLdepth) );
778 }
779 else {
780 GLuint i;
781 for (i=0;i<n;i++) {
782 depth[i] = 0;
783 }
784 }
785 }
786
787
788
789 /**********************************************************************/
790 /***** Allocate and Clear Depth Buffer *****/
791 /**********************************************************************/
792
793
794
795 /*
796 * Allocate a new depth buffer. If there's already a depth buffer allocated
797 * it will be free()'d. The new depth buffer will be uniniitalized.
798 * This function is only called through Driver.alloc_depth_buffer.
799 */
800 void gl_alloc_depth_buffer( GLcontext* ctx )
801 {
802 /* deallocate current depth buffer if present */
803 if (ctx->Buffer->Depth) {
804 FREE(ctx->Buffer->Depth);
805 ctx->Buffer->Depth = NULL;
806 }
807
808 /* allocate new depth buffer, but don't initialize it */
809 ctx->Buffer->Depth = (GLdepth *) MALLOC( ctx->Buffer->Width
810 * ctx->Buffer->Height
811 * sizeof(GLdepth) );
812 if (!ctx->Buffer->Depth) {
813 /* out of memory */
814 ctx->Depth.Test = GL_FALSE;
815 ctx->NewState |= NEW_RASTER_OPS;
816 gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
817 }
818 }
819
820
821
822
823 /*
824 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
825 * allocate it now.
826 * This function is only called through Driver.clear_depth_buffer.
827 */
828 void gl_clear_depth_buffer( GLcontext* ctx )
829 {
830 GLdepth clear_value = (GLdepth) (ctx->Depth.Clear * DEPTH_SCALE);
831
832 if (ctx->Visual->DepthBits==0 || !ctx->Buffer->Depth || !ctx->Depth.Mask) {
833 /* no depth buffer, or writing to it is disabled */
834 return;
835 }
836
837 /* The loops in this function have been written so the IRIX 5.3
838 * C compiler can unroll them. Hopefully other compilers can too!
839 */
840
841 if (ctx->Scissor.Enabled) {
842 /* only clear scissor region */
843 GLint y;
844 for (y=ctx->Buffer->Ymin; y<=ctx->Buffer->Ymax; y++) {
845 GLdepth *d = Z_ADDRESS( ctx, ctx->Buffer->Xmin, y );
846 GLint n = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
847 do {
848 *d++ = clear_value;
849 n--;
850 } while (n);
851 }
852 }
853 else {
854 /* clear whole buffer */
855 if (sizeof(GLdepth)==2 && (clear_value&0xff)==(clear_value>>8)) {
856 /* lower and upper bytes of clear_value are same, use MEMSET */
857 MEMSET( ctx->Buffer->Depth, clear_value&0xff,
858 2*ctx->Buffer->Width*ctx->Buffer->Height);
859 }
860 else {
861 GLdepth *d = ctx->Buffer->Depth;
862 GLint n = ctx->Buffer->Width * ctx->Buffer->Height;
863 while (n>=16) {
864 d[0] = clear_value; d[1] = clear_value;
865 d[2] = clear_value; d[3] = clear_value;
866 d[4] = clear_value; d[5] = clear_value;
867 d[6] = clear_value; d[7] = clear_value;
868 d[8] = clear_value; d[9] = clear_value;
869 d[10] = clear_value; d[11] = clear_value;
870 d[12] = clear_value; d[13] = clear_value;
871 d[14] = clear_value; d[15] = clear_value;
872 d += 16;
873 n -= 16;
874 }
875 while (n>0) {
876 *d++ = clear_value;
877 n--;
878 }
879 }
880 }
881 }
882
883
884