; ; ; Z buffer: 16 bits Z / 16 bits color ; ; ;include 'zbuffer.inc' ;output: ; eax - указатель на ZBuffer (0 если не удача) align 4 proc ZB_open uses ecx edi, xsize:dword, ysize:dword, mode:dword,\ nb_colors:dword, color_indexes:dword, color_table:dword, frame_buffer:dword stdcall gl_malloc, sizeof.ZBuffer cmp eax,0 jne @f stdcall dbg_print,f_zb_opn,err_1 jmp .end_f @@: mov edi,eax mov eax,[ysize] mov [edi+offs_zbuf_ysize],eax mov eax,[xsize] mov [edi+offs_zbuf_xsize],eax imul eax,PSZB add eax,3 and eax,not 3 mov [edi+offs_zbuf_linesize],eax mov eax,[mode] mov [edi+offs_zbuf_mode],eax if TGL_FEATURE_8_BITS eq 1 cmp eax,ZB_MODE_INDEX jne @f ;ZB_initDither(edi, nb_colors, color_indexes, color_table); jmp .end_s @@: end if if TGL_FEATURE_32_BITS eq 1 cmp eax,ZB_MODE_RGBA je .correct end if if TGL_FEATURE_24_BITS eq 1 cmp eax,ZB_MODE_RGB24 je .correct end if cmp eax,ZB_MODE_5R6G5B jne @f .correct: mov dword[edi+offs_zbuf_nb_colors],0 jmp .end_s @@: ;default: stdcall dbg_print,f_zb_opn,err_3 jmp .error .end_s: mov ecx,[edi+offs_zbuf_xsize] imul ecx,[edi+offs_zbuf_ysize] shl ecx,2 ;*= sizeof(unsigned short) stdcall gl_malloc, ecx mov [edi+offs_zbuf_zbuf],eax cmp eax,0 jne @f stdcall dbg_print,f_zb_opn,err_2 jmp .error @@: mov dword[edi+offs_zbuf_frame_buffer_allocated],0 mov dword[edi+offs_zbuf_pbuf],0 ;NULL mov dword[edi+offs_zbuf_current_texture],0 ;NULL mov eax,edi jmp .end_f .error: stdcall gl_free,edi xor eax,eax .end_f: ret endp ;void ZB_close(ZBuffer * zb) ;{ if TGL_FEATURE_8_BITS eq 1 ; if (zb->mode == ZB_MODE_INDEX) ; ZB_closeDither(zb); end if ; ; if (zb->frame_buffer_allocated) ; gl_free(zb->pbuf); ; ; gl_free(zb->zbuf); ; gl_free(zb); ;} align 4 proc ZB_resize uses eax ebx ecx edi esi, zb:dword, frame_buffer:dword, xsize:dword, ysize:dword mov ebx,[zb] ; xsize must be a multiple of 4 mov edi,[xsize] and edi,not 3 mov esi,[ysize] mov [ebx+offs_zbuf_xsize], edi mov [ebx+offs_zbuf_ysize], esi mov eax,edi imul eax,PSZB add eax,3 and eax,not 3 mov [ebx+offs_zbuf_linesize],eax ;zb.linesize = (xsize * PSZB + 3) & ~3 mov ecx,edi imul ecx,esi shl ecx,2 ;*= sizeof(unsigned short) stdcall gl_free,dword[ebx+offs_zbuf_zbuf] stdcall gl_malloc,ecx mov [ebx+offs_zbuf_zbuf],eax cmp dword[ebx+offs_zbuf_frame_buffer_allocated],0 je @f stdcall gl_free,dword[ebx+offs_zbuf_pbuf] @@: cmp dword[frame_buffer],0 jne .els_0 inc esi imul esi,dword[ebx+offs_zbuf_linesize] stdcall gl_malloc,esi mov dword[ebx+offs_zbuf_pbuf],eax mov dword[ebx+offs_zbuf_frame_buffer_allocated],1 jmp @f .els_0: mov eax,[frame_buffer] mov dword[ebx+offs_zbuf_pbuf],eax mov dword[ebx+offs_zbuf_frame_buffer_allocated],0 @@: ret endp ;static void ZB_copyBuffer(ZBuffer * zb, ; void *buf, ; int linesize) ;{ ; unsigned char *p1; ; PIXEL *q; ; int y, n; ; ; q = zb->pbuf; ; p1 = buf; ; n = zb->xsize * PSZB; ; for (y = 0; y < zb->ysize; y++) { ; memcpy(p1, q, n); ; p1 += linesize; ; q = (PIXEL *) ((char *) q + zb->linesize); ; } ;} ; ;#if TGL_FEATURE_RENDER_BITS == 16 ;/* 32 bpp copy */ ;#ifdef TGL_FEATURE_32_BITS ;#define RGB16_TO_RGB32(p0,p1,v)\ ;{\ ; unsigned int g,b,gb;\ ; g = (v & 0x07E007E0) << 5;\ ; b = (v & 0x001F001F) << 3;\ ; gb = g | b;\ ; p0 = (gb & 0x0000FFFF) | ((v & 0x0000F800) << 8);\ ; p1 = (gb >> 16) | ((v & 0xF8000000) >> 8);\ ;} ;static void ZB_copyFrameBufferRGB32(ZBuffer * zb, ; void *buf, ; int linesize) ;{ ; unsigned short *q; ; unsigned int *p, *p1, v, w0, w1; ; int y, n; ; ; q = zb->pbuf; ; p1 = (unsigned int *) buf; ; ; for (y = 0; y < zb->ysize; y++) { ; p = p1; ; n = zb->xsize >> 2; ; do { ; v = *(unsigned int *) q; ;#if BYTE_ORDER == BIG_ENDIAN ; RGB16_TO_RGB32(w1, w0, v); ;#else ; RGB16_TO_RGB32(w0, w1, v); ;#endif ; p[0] = w0; ; p[1] = w1; ; ; v = *(unsigned int *) (q + 2); ;#if BYTE_ORDER == BIG_ENDIAN ; RGB16_TO_RGB32(w1, w0, v); ;#else ; RGB16_TO_RGB32(w0, w1, v); ;#endif ; p[2] = w0; ; p[3] = w1; ; ; q += 4; ; p += 4; ; } while (--n > 0); ; ; p1 += linesize; ; } ;} ;#endif ;/* 24 bit packed pixel handling */ ;#ifdef TGL_FEATURE_24_BITS ;/* order: RGBR GBRG BRGB */ ;/* XXX: packed pixel 24 bit support not tested */ ;/* XXX: big endian case not optimised */ ;#if BYTE_ORDER == BIG_ENDIAN ;#define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\ ;{\ ; unsigned int r1,g1,b1,gb1,g2,b2,gb2;\ ; v1 = (v1 << 16) | (v1 >> 16);\ ; v2 = (v2 << 16) | (v2 >> 16);\ ; r1 = (v1 & 0xF800F800);\ ; g1 = (v1 & 0x07E007E0) << 5;\ ; b1 = (v1 & 0x001F001F) << 3;\ ; gb1 = g1 | b1;\ ; p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\ ; g2 = (v2 & 0x07E007E0) << 5;\ ; b2 = (v2 & 0x001F001F) << 3;\ ; gb2 = g2 | b2;\ ; p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\ ; p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\ ;} ;#else ;#define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\ ;{\ ; unsigned int r1,g1,b1,gb1,g2,b2,gb2;\ ; r1 = (v1 & 0xF800F800);\ ; g1 = (v1 & 0x07E007E0) << 5;\ ; b1 = (v1 & 0x001F001F) << 3;\ ; gb1 = g1 | b1;\ ; p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\ ; g2 = (v2 & 0x07E007E0) << 5;\ ; b2 = (v2 & 0x001F001F) << 3;\ ; gb2 = g2 | b2;\ ; p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\ ; p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\ ;} ;#endif ;static void ZB_copyFrameBufferRGB24(ZBuffer * zb, ; void *buf, int linesize) ;{ ; unsigned short *q; ; unsigned int *p, *p1, w0, w1, w2, v0, v1; ; int y, n; ; ; q = zb->pbuf; ; p1 = (unsigned int *) buf; ; linesize = linesize * 3; ; ; for (y = 0; y < zb->ysize; y++) { ; p = p1; ; n = zb->xsize >> 2; ; do { ; v0 = *(unsigned int *) q; ; v1 = *(unsigned int *) (q + 2); ; RGB16_TO_RGB24(w0, w1, w2, v0, v1); ; p[0] = w0; ; p[1] = w1; ; p[2] = w2; ; q += 4; ; p += 3; ; } while (--n > 0); ; ; (char *) p1 += linesize; ; } ;} ;#endif ;void ZB_copyFrameBuffer(ZBuffer * zb, void *buf, ; int linesize) ;{ ; switch (zb->mode) { ;#ifdef TGL_FEATURE_8_BITS ; case ZB_MODE_INDEX: ; ZB_ditherFrameBuffer(zb, buf, linesize >> 1); ; break; ;#endif ;#ifdef TGL_FEATURE_16_BITS ; case ZB_MODE_5R6G5B: ; ZB_copyBuffer(zb, buf, linesize); ; break; ;#endif ;#ifdef TGL_FEATURE_32_BITS ; case ZB_MODE_RGBA: ; ZB_copyFrameBufferRGB32(zb, buf, linesize >> 1); ; break; ;#endif ;#ifdef TGL_FEATURE_24_BITS ; case ZB_MODE_RGB24: ; ZB_copyFrameBufferRGB24(zb, buf, linesize >> 1); ; break; ;#endif ; default: ; assert(0); ; } ;} ;#endif /* TGL_FEATURE_RENDER_BITS == 16 */ ;#if TGL_FEATURE_RENDER_BITS == 24 ;#define RGB24_TO_RGB16(r, g, b) \ ; ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3)) ;/* XXX: not optimized */ ;static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb, ; void *buf, int linesize) ;{ ; PIXEL *q; ; unsigned short *p, *p1; ; int y, n; ; ; q = zb->pbuf; ; p1 = (unsigned short *) buf; ; ; for (y = 0; y < zb->ysize; y++) { ; p = p1; ; n = zb->xsize >> 2; ; do { ; p[0] = RGB24_TO_RGB16(q[0], q[1], q[2]); ; p[1] = RGB24_TO_RGB16(q[3], q[4], q[5]); ; p[2] = RGB24_TO_RGB16(q[6], q[7], q[8]); ; p[3] = RGB24_TO_RGB16(q[9], q[10], q[11]); ; q = (PIXEL *)((char *)q + 4 * PSZB); ; p += 4; ; } while (--n > 0); ; p1 = (unsigned short *)((char *)p1 + linesize); ; } ;} ;void ZB_copyFrameBuffer(ZBuffer * zb, void *buf, ; int linesize) ;{ ; switch (zb->mode) { ;#ifdef TGL_FEATURE_16_BITS ; case ZB_MODE_5R6G5B: ; ZB_copyFrameBuffer5R6G5B(zb, buf, linesize); ; break; ;#endif ;#ifdef TGL_FEATURE_24_BITS ; case ZB_MODE_RGB24: ; ZB_copyBuffer(zb, buf, linesize); ; break; ;#endif ; default: ; assert(0); ; } ;} ;#endif /* TGL_FEATURE_RENDER_BITS == 24 */ ;#if TGL_FEATURE_RENDER_BITS == 32 ;#define RGB32_TO_RGB16(v) \ ; (((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3)) ;/* XXX: not optimized */ ;static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb, ; void *buf, int linesize) ;{ ; PIXEL *q; ; unsigned short *p, *p1; ; int y, n; ; ; q = zb->pbuf; ; p1 = (unsigned short *) buf; ; ; for (y = 0; y < zb->ysize; y++) { ; p = p1; ; n = zb->xsize >> 2; ; do { ; p[0] = RGB32_TO_RGB16(q[0]); ; p[1] = RGB32_TO_RGB16(q[1]); ; p[2] = RGB32_TO_RGB16(q[2]); ; p[3] = RGB32_TO_RGB16(q[3]); ; q += 4; ; p += 4; ; } while (--n > 0); ; p1 = (unsigned short *)((char *)p1 + linesize); ; } ;} ; ;void ZB_copyFrameBuffer(ZBuffer * zb, void *buf, ; int linesize) ;{ ; switch (zb->mode) { ;#ifdef TGL_FEATURE_16_BITS ; case ZB_MODE_5R6G5B: ; ZB_copyFrameBuffer5R6G5B(zb, buf, linesize); ; break; ;#endif ;#ifdef TGL_FEATURE_32_BITS ; case ZB_MODE_RGBA: ; ZB_copyBuffer(zb, buf, linesize); ; break; ;#endif ; default: ; assert(0); ; } ;} ; ;#endif /* TGL_FEATURE_RENDER_BITS == 32 */ ; ; ;/* ; * adr must be aligned on an 'int' ; */ ;void memset_s(void *adr, int val, int count) ;{ ; int i, n, v; ; unsigned int *p; ; unsigned short *q; ; ; p = adr; ; v = val | (val << 16); ; ; n = count >> 3; ; for (i = 0; i < n; i++) { ; p[0] = v; ; p[1] = v; ; p[2] = v; ; p[3] = v; ; p += 4; ; } ; ; q = (unsigned short *) p; ; n = count & 7; ; for (i = 0; i < n; i++) ; *q++ = val; ;} ; ;void memset_l(void *adr, int val, int count) ;{ ; int i, n, v; ; unsigned int *p; ; ; p = adr; ; v = val; ; n = count >> 2; ; for (i = 0; i < n; i++) { ; p[0] = v; ; p[1] = v; ; p[2] = v; ; p[3] = v; ; p += 4; ; } ; ; n = count & 3; ; for (i = 0; i < n; i++) ; *p++ = val; ;} ; ;/* count must be a multiple of 4 and >= 4 */ ;void memset_RGB24(void *adr,int r, int v, int b,long count) ;{ ; long i, n; ; register long v1,v2,v3,*pt=(long *)(adr); ; unsigned char *p,R=(unsigned char)r,V=(unsigned char)v,B=(unsigned char)b; ; ; p=(unsigned char *)adr; ; *p++=R; ; *p++=V; ; *p++=B; ; *p++=R; ; *p++=V; ; *p++=B; ; *p++=R; ; *p++=V; ; *p++=B; ; *p++=R; ; *p++=V; ; *p++=B; ; v1=*pt++; ; v2=*pt++; ; v3=*pt++; ; n = count >> 2; ; for(i=1;izbuf, z, zb->xsize * zb->ysize); ; } ; if (clear_color) { ; pp = zb->pbuf; ; for (y = 0; y < zb->ysize; y++) { ;#if TGL_FEATURE_RENDER_BITS == 15 || TGL_FEATURE_RENDER_BITS == 16 ; color = RGB_TO_PIXEL(r, g, b); ; memset_s(pp, color, zb->xsize); ;#elif TGL_FEATURE_RENDER_BITS == 32 ; color = RGB_TO_PIXEL(r, g, b); ; memset_l(pp, color, zb->xsize); ;#elif TGL_FEATURE_RENDER_BITS == 24 ; memset_RGB24(pp,r>>8,g>>8,b>>8,zb->xsize); ;#else ;#error TODO ;#endif ; pp = (PIXEL *) ((char *) pp + zb->linesize); ; } ; } ;}