diff --git a/programs/develop/libraries/pixlib/brush.inc b/programs/develop/libraries/pixlib/brush.inc new file mode 100644 index 0000000000..c598692662 --- /dev/null +++ b/programs/develop/libraries/pixlib/brush.inc @@ -0,0 +1,51 @@ + +brush_t* CreateHatch(int hatch, color_t bkcolor, color_t fcolor) +{ + if (hatch < HATCH_MAX) + { + if( br_slab.available ) + { + brush_t *brush; + + br_slab.available--; + brush = (brush_t*)br_slab.nextavail; + br_slab.nextavail = *(void**)brush; + + brush->bkcolor = bkcolor; + brush->fcolor = fcolor; + + brush->bmp[0] = hatches[hatch*2]; + brush->bmp[1] = hatches[hatch*2+1]; + return brush; + } + return NULL; + } + return NULL; +}; + +brush_t* CreateMonoBrush(color_t bkcolor, color_t fcolor,u32_t bmp0,u32_t bmp1) +{ + if( br_slab.available ) + { + brush_t *brush; + + br_slab.available--; + brush = (brush_t*)br_slab.nextavail; + br_slab.nextavail = *(void**)brush; + + brush->bkcolor = bkcolor; + brush->fcolor = fcolor; + + brush->bmp[0] = bmp0; + brush->bmp[1] = bmp1; + return brush; + } + return NULL; +}; + +void DestroyBrush(brush_t *brush) +{ + *(void**)brush = br_slab.nextavail; + br_slab.nextavail = brush; + br_slab.available++; +}; diff --git a/programs/develop/libraries/pixlib/clip.inc b/programs/develop/libraries/pixlib/clip.inc new file mode 100644 index 0000000000..cc51a4072b --- /dev/null +++ b/programs/develop/libraries/pixlib/clip.inc @@ -0,0 +1,180 @@ + +#define CLIP_TOP 1 +#define CLIP_BOTTOM 2 +#define CLIP_RIGHT 4 +#define CLIP_LEFT 8 + + +static int _L1OutCode( clip_t *clip, int x, int y ) +/*================================= + + Verify that a point is inside or outside the active viewport. */ +{ + int flag; + + flag = 0; + if( x < clip->xmin ) { + flag |= CLIP_LEFT; + } else if( x > clip->xmax ) { + flag |= CLIP_RIGHT; + } + if( y < clip->ymin ) { + flag |= CLIP_TOP; + } else if( y > clip->ymax ) { + flag |= CLIP_BOTTOM; + } + return( flag ); +} + + +static void line_inter( int * x1, int* y1, int x2, int y2, int x ) +/*=========================================================================== + + Find the intersection of a line with a boundary of the viewport. + (x1, y1) is outside and ( x2, y2 ) is inside the viewport. + NOTE : the signs of denom and ( x - *x1 ) cancel out during division + so make both of them positive before rounding. */ +{ + int numer; + int denom; + + denom = abs( x2 - *x1 ); + numer = 2L * (long)( y2 - *y1 ) * abs( x - *x1 ); + if( numer > 0 ) { + numer += denom; /* round to closest pixel */ + } else { + numer -= denom; + } + *y1 += numer / ( denom << 1 ); + *x1 = x; +} + + +int LineClip( clip_t *clip, int *x1, int *y1, int *x2, int *y2 ) +/*============================================================= + + Clips the line with end points (x1,y1) and (x2,y2) to the active + viewport using the Cohen-Sutherland clipping algorithm. Return the + clipped coordinates and a decision drawing flag. */ +{ + int flag1; + int flag2; + + flag1 = _L1OutCode( clip, *x1, *y1 ); + flag2 = _L1OutCode( clip, *x2, *y2 ); + for( ;; ) { + if( flag1 & flag2 ) break; /* trivially outside */ + if( flag1 == flag2 ) break; /* completely inside */ + if( flag1 == 0 ) { /* first point inside */ + if( flag2 & CLIP_TOP ) { + line_inter( y2, x2, *y1, *x1, clip->ymin ); + } else if( flag2 & CLIP_BOTTOM ) { + line_inter( y2, x2, *y1, *x1, clip->ymax ); + } else if( flag2 & CLIP_RIGHT ) { + line_inter( x2, y2, *x1, *y1, clip->xmax ); + } else if( flag2 & CLIP_LEFT ) { + line_inter( x2, y2, *x1, *y1, clip->xmin ); + } + flag2 = _L1OutCode( clip, *x2, *y2 ); + } else { /* second point inside */ + if( flag1 & CLIP_TOP ) { + line_inter( y1, x1, *y2, *x2, clip->ymin ); + } else if( flag1 & CLIP_BOTTOM ) { + line_inter( y1, x1, *y2, *x2, clip->ymax ); + } else if( flag1 & CLIP_RIGHT ) { + line_inter( x1, y1, *x2, *y2, clip->xmax ); + } else if( flag1 & CLIP_LEFT ) { + line_inter( x1, y1, *x2, *y2, clip->xmin ); + } + flag1 = _L1OutCode( clip, *x1, *y1 ); + } + } + return( flag1 & flag2 ); +} + + +static void block_inter( clip_t *clip, int *x, int *y, int flag ) +/*====================================================== + + Find the intersection of a block with a boundary of the viewport. */ +{ + if( flag & CLIP_TOP ) { + *y = clip->ymin; + } else if( flag & CLIP_BOTTOM ) { + *y = clip->ymax; + } else if( flag & CLIP_RIGHT ) { + *x = clip->xmax; + } else if( flag & CLIP_LEFT ) { + *x = clip->xmin; + } +} + + +int BlockClip(clip_t *clip, int *x1, int *y1, int *x2, int* y2 ) +/*============================================================== + + Clip a block with opposite corners (x1,y1) and (x2,y2) to the + active viewport based on the Cohen-Sutherland algorithm for line + clipping. Return the clipped coordinates and a decision drawing + flag ( 0 draw : 1 don't draw ). */ +{ + int flag1; + int flag2; + + flag1 = _L1OutCode( clip, *x1, *y1 ); + flag2 = _L1OutCode( clip, *x2, *y2 ); + for( ;; ) { + if( flag1 & flag2 ) break; /* trivially outside */ + if( flag1 == flag2 ) break; /* completely inside */ + if( flag1 == 0 ) { + block_inter( clip, x2, y2, flag2 ); + flag2 = _L1OutCode( clip, *x2, *y2 ); + } else { + block_inter( clip, x1, y1, flag1 ); + flag1 = _L1OutCode( clip, *x1, *y1 ); + } + } + return( flag1 & flag2 ); +} + + +int blit_clip(clip_t *dst_clip,int *dst_x,int *dst_y, + clip_t *src_clip,int *src_x, int *src_y, + int *w, int *h) +{ + int sx0, sy0, sx1, sy1; + + sx0 = *src_x; + sy0 = *src_y; + + sx1 = sx0 + *w - 1; + sy1 = sy0 + *h - 1; + + + if( ! BlockClip( src_clip, &sx0, &sy0, &sx1, &sy1)) + { + int dx0, dy0, dx1, dy1; + + dx0 = *dst_x + sx0 - *src_x; + dy0 = *dst_y + sy0 - *src_y; + + dx1 = dx0 + sx1 - sx0; + dy1 = dy0 + sy1 - sy0; + + if( ! BlockClip( dst_clip, &dx0, &dy0, &dx1, &dy1)) + { + *w = dx1 - dx0 + 1; + *h = dy1 - dy0 + 1; + + *src_x += dx0 - *dst_x; + *src_y += dy0 - *dst_y; + + *dst_x = dx0; + *dst_y = dx0; + + return 0; + }; + }; + return 1; +}; + diff --git a/programs/develop/libraries/pixlib/draw.inc b/programs/develop/libraries/pixlib/draw.inc new file mode 100644 index 0000000000..56b9948102 --- /dev/null +++ b/programs/develop/libraries/pixlib/draw.inc @@ -0,0 +1,769 @@ + +#include + + +static void HLine(char *addr,int width, color_t color) +{ + __m64 dst_color; + + dst_color = _mm_cvtsi32_si64(color); + dst_color = _mm_unpacklo_pi32(dst_color, dst_color); + + while (width >= 8) + { + __asm__ __volatile__ ( + "movq %[clr], (%0)\n\t" + "movq %[clr], 8(%0)\n\t" + "movq %[clr], 16(%0)\n\t" + "movq %[clr], 24(%0)\n\t" + :: "r" (addr), [clr] "y" (dst_color)); + addr += 32; + width -= 8; + } + if (width >= 4) + { + __asm__ __volatile__ ( + "movq %[clr], (%0)\n\t" + "movq %[clr], 8(%0)\n\t" + :: "r" (addr), [clr] "y" (dst_color)); + addr += 16; + width -= 4; + } + if (width >= 2) + { + __asm__ __volatile__ ( + "movq %[clr], (%0)\n\t" + :: "r" (addr), [clr] "y" (dst_color)); + addr += 8; + width -= 2; + } + if ( width ) + __asm__ __volatile__ ( + "movd %[clr], (%0)\n\t" + :: "r" (addr), [clr] "y" (dst_color)); + + _mm_empty(); +} + +static void pxDraw(char *dst_addr, int pitch, int w, int h, color_t dst_color) +{ + __m64 color; + + color = _mm_cvtsi32_si64(dst_color); + color = _mm_unpacklo_pi32(color, color); + + while(h--) + { + char *tmp_dst =dst_addr; + int width = w; + dst_addr += pitch; + + while(width >= 8) + { + __asm__ __volatile__ + ("movq %[clr], (%0)\n\t" + "movq %[clr], 8(%0)\n\t" + "movq %[clr], 16(%0)\n\t" + "movq %[clr], 24(%0)\n\t" + :: "r" (tmp_dst), [clr] "y" (color)); + tmp_dst += 32; + width -= 8; + }; + if(width >= 4) + { + __asm__ __volatile__ + ("movq %[clr], (%0)\n\t" + "movq %[clr], 8(%0)\n\t" + :: "r" (tmp_dst), [clr] "y" (color)); + tmp_dst += 16; + width -= 4; + }; + + if (width >= 2) + { + __asm__ __volatile__ + ("movq %[clr], (%0)\n\t" + :: "r" (tmp_dst), [clr] "y" (color)); + tmp_dst += 8; + width -= 2; + }; + if(width) + __asm__ __volatile__ + ("movd %[clr], (%0)\n\t" + :: "r" (tmp_dst), [clr] "y" (color)); + }; + _mm_empty(); +}; + +int ClearPixmap(pixmap_t *pixmap, color_t color) +{ + if( (srv_hw2d != 0) && + ( ((int)pixmap == -1) || + ( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) + { + ioctl_t io; + + if((int)pixmap != -1) + pixmap = (pixmap_t*)pixmap->handle; + + io.handle = srv_hw2d; + io.io_code = PX_CLEAR; + io.input = &pixmap; + io.inp_size = 2; + io.output = NULL; + io.out_size = 0; + + return call_service(&io); + } + + pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ; + + pxDraw(pixmap->mapped, pixmap->pitch, + pixmap->width, pixmap->height, color); + return ERR_OK; +}; + +int Line(pixmap_t *pixmap, int x0, int y0, int x1, int y1, color_t color) +{ + + clip_t clip; + + if( (srv_hw2d != 0) && + ( (pixmap == (void*)-1) || + ( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) + { + ioctl_t io; + + if((int)pixmap != -1) + pixmap = (pixmap_t*)pixmap->handle; + + io.handle = srv_hw2d; + io.io_code = PX_LINE; + io.input = &pixmap; + io.inp_size = 6; + io.output = NULL; + io.out_size = 0; + + return call_service(&io); + } + + pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ; + + clip.xmin = 0; + clip.ymin = 0; + clip.xmax = pixmap->width-1; + clip.ymax = pixmap->height-1; + + if ( !LineClip( &clip, &x0, &y0, &x1, &y1 )) + { + int dx, dy; + int sx, sy; + int e, e1, e2, e3; + + char *addr; + + dx = x1 - x0; + dy = y1 - y0; + + if( dx || dy) + { + if( dy == 0 ) + { + if (dx < 0) + { + dx = -dx; + x0 = x1; + }; + + addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; + HLine(addr, dx, color); + + return ERR_OK; + }; + if( dx == 0 ) + { + if (dy < 0) + { + dy = -dy; + y0 = y1; + }; + addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; + + while ( dy-- ) + { + *(color_t*)addr = color; + addr += pixmap->pitch; + } + return ERR_OK; + } + + sx = 4; + if ( dx < 0 ) + { + dx = -dx; + sx = -sx; + } + sy = pixmap->pitch; + if ( dy < 0 ) + { + dy = -dy; + sy = -sy; + }; + + addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; + + if (dx > dy) + { + e1 = dy << 1; + e2 = e1 - (dx << 1); + e = e1 - dx; + + e3 = e2 - e1; + e = e - e1; + + + while (dx--) + { + *(color_t*)addr = color; + addr += sx; + e += e1; + if (e >= 0) + { + addr += sy; + e += e3; + } + } + } + else + { + e1 = dx << 1; + e2 = e1 - (dy << 1); + e = e1 - dy; + e3 = e2 - e1; + e = e - e1; + + while (dy--) + { + *(color_t*)addr = color; + addr += sy; + e += e1; + if (e >= 0) + { + addr += sx; + e += e3; + } + } + } + } /* ( dx || dy ) */ + } + return ERR_OK; +} + +int DrawRect(pixmap_t *pixmap, int xorg, int yorg, + int width, int height, + color_t dst_color, color_t border) +{ + + if( ( width <= 0 ) || ( height<=0 ) ) + return ERR_PARAM; + +/* if "hardware acceleration present" and + "destinastion is primary screen or local videomemory" +*/ + + if( (srv_hw2d != 0) && + ( (pixmap == (void*)-1) || + ( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) + { + ioctl_t io; + + if((int)pixmap != -1) + pixmap = (pixmap_t*)pixmap->handle; + + io.handle = srv_hw2d; + io.io_code = PX_DRAW_RECT; + io.input = &pixmap; + io.inp_size = 7; + io.output = NULL; + io.out_size = 0; + + return call_service(&io); + } + else +/* no acceleration or destination in system memory */ + { + clip_t clip; + int x0, y0, x1, y1, xend, yend; + + pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ; + + x0 = xorg; + y0 = yorg; + + xend = x1 = x0 + width - 1; + yend = y1 = y0 + height - 1; + + clip.xmin = 0; + clip.ymin = 0; + clip.xmax = pixmap->width-1; + clip.ymax = pixmap->height-1; + + if( ! BlockClip( &clip, &x0, &y0, &x1, &y1)) + { + int w, h; + + char *dst_addr; + + w = x1 - x0 + 1; + h = y1 - y0 + 1; + + if( (dst_color == border) || + ((border & 0xFF000000)==0)) + { + dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; + pxDraw(dst_addr, pixmap->pitch, w, h, dst_color); + } + else + { + if( y0 == yorg) + { + dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; + HLine(dst_addr, w, border); + y0++; + h--; + } + if( y1 == yend ) + { + dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y1 + x0*4]; + HLine(dst_addr, w, border); + h--; + } + if( (h > 0) && (x0 == xorg)) + { + int dy = h; + + dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; + + while ( dy-- ) + { + *(color_t*)dst_addr = border; + dst_addr += pixmap->pitch; + } + x0++; + w--; + } + if( (h > 0) && (x1 == xend)) + { + int dy = h; + + dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x1*4]; + + while ( dy-- ) + { + *(color_t*)dst_addr = border; + dst_addr += pixmap->pitch; + } + w--; + } + if( (w > 0) && (h > 0) ) + { + dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; + pxDraw(dst_addr, pixmap->pitch, w, h, dst_color); + } + } + }; + }; + return ERR_OK; +}; + +int FillRect(pixmap_t *pixmap, int xorg, int yorg, + int width, int height, + brush_t *dst_brush, color_t border) +{ + if( ( width <= 0 ) || ( height<=0 ) ) + return ERR_PARAM; + +/* if "hardware acceleration present" and + "destinastion is primary screen or local videomemory" +*/ + + if( (srv_hw2d != 0) && + ( (pixmap == (void*)-1) || + ( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) + { + fill_t fill; + ioctl_t io; + + fill.dstpix = ((int)pixmap == -1) ? (pixmap_t*)-1 : (pixmap_t*)pixmap->handle; + fill.x = xorg; + fill.y = yorg; + fill.w = width; + fill.h = height; + fill.bkcolor = dst_brush->bkcolor; + fill.fcolor = dst_brush->fcolor; + fill.bmp0 = dst_brush->bmp[0]; + fill.bmp1 = dst_brush->bmp[1]; + fill.border = border; + + io.handle = srv_hw2d; + io.io_code = PX_FILL_RECT; + io.input = &fill; + io.inp_size = 10; + io.output = NULL; + io.out_size = 0; + + return call_service(&io); + } + else +/* no acceleration or destination in system memory */ + { + clip_t clip; + int x0, y0, x1, y1, xend, yend; + + pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ; + + x0 = xorg; + y0 = yorg; + x1 = xend = x0 + width - 1; + y1 = yend = y0 + height - 1; + + clip.xmin = 0; + clip.ymin = 0; + clip.xmax = pixmap->width-1; + clip.ymax = pixmap->height-1; + + if( ! BlockClip( &clip, &x0, &y0, &x1, &y1)) + { + int w, h, bh, bm_y; + + __m64 clr_bb, clr_bf, clr_fb, clr_ff; + char *dst_addr; + + clr_bb = _mm_cvtsi32_si64(dst_brush->bkcolor); + clr_ff = _mm_cvtsi32_si64(dst_brush->fcolor); + + clr_bb = _mm_unpacklo_pi32(clr_bb, clr_bb); + clr_ff = _mm_unpacklo_pi32(clr_ff, clr_ff); + + clr_bf = _mm_unpacklo_pi32(clr_ff, clr_bb); + clr_fb = _mm_unpacklo_pi32(clr_bb, clr_ff); + + w = x1 -x0 + 1; + bh = h = y1 -y0 + 1; + + dst_addr = & ((char*)(pixmap->mapped))[pixmap->pitch*y0+x0*4]; + + bm_y = y0 & 7; + + while(h--) + { + u8_t mask = dst_brush->bits[bm_y]; + + char *tmp_dst = dst_addr; + int width = w; + dst_addr += pixmap->pitch; + bm_y = (bm_y+1) & 7; + + while(width>=2) + { + __asm__ __volatile__ + ("rolb $2, %0 \n\t" + :"+g" (mask):"g"(mask) + :"cc"); + + switch( mask & 3 ) + { + case 0: + __asm__ __volatile__ + ("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_bb)); + break; + + case 1: + __asm__ __volatile__ + ("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_fb)); + break; + + case 2: + __asm__ __volatile__ + ("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_bf)); + break; + + case 3: + __asm__ __volatile__ + ("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_ff)); + break; + } + width -=2; + tmp_dst +=8; + } + if( width ) + if( mask & 1 ) + __asm__ __volatile__ + ("movd %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_ff)); + else + __asm__ __volatile__ + ("movd %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_bb)); + }; + + if( (border & 0xFF000000) != 0) + { + if( y0 == yorg) + { + dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; + HLine(dst_addr, w, border); + y0++; + bh--; + } + if( y1 == yend ) + { + dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y1 + x0*4]; + HLine(dst_addr, w, border); + bh--; + } + if( (bh > 0) && (x0 == xorg)) + { + int dy = bh; + + dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; + + while ( dy-- ) + { + *(color_t*)dst_addr = border; + dst_addr += pixmap->pitch; + } + } + if( (bh > 0) && (x1 == xend)) + { + int dy = bh; + + dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x1*4]; + + while ( dy-- ) + { + *(color_t*)dst_addr = border; + dst_addr += pixmap->pitch; + } + } + }; + + _mm_empty(); + }; + }; + return ERR_OK; +}; + + +int Blit(pixmap_t *dst_pixmap, int dst_x, int dst_y, + pixmap_t *src_pixmap, int src_x, int src_y, + int width, int height) +{ + + clip_t src_clip, dst_clip; + + if( ( width <= 0 ) || ( height<=0 ) ) + return ERR_PARAM; + +/* if "hardware acceleration present" and + "destinastion is primary screen or local videomemory" and + "source is primary screen or local videomemory" +*/ + if( (srv_hw2d != 0) && + ( (dst_pixmap == (void*)-1) || + ( (dst_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) && + ( (src_pixmap == (void*)-1) || + ( (src_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) + { + ioctl_t io; + pxblit_t *blit = (pxblit_t*)&dst_pixmap; + + if((int)dst_pixmap != -1) + blit->dst_pixmap = (pixmap_t*)dst_pixmap->handle; + + if((int)src_pixmap != -1) + blit->src_pixmap = (pixmap_t*)src_pixmap->handle; + + io.handle = srv_hw2d; + io.io_code = PX_BLIT; + io.input = blit; + io.inp_size = 8; + io.output = NULL; + io.out_size = 0; + + return call_service(&io); + } + + dst_pixmap = (dst_pixmap == (void*)-1) ? &scrn_pixmap : dst_pixmap ; + src_pixmap = (src_pixmap == (void*)-1) ? &scrn_pixmap : src_pixmap ; + + src_clip.xmin = 0; + src_clip.ymin = 0; + src_clip.xmax = src_pixmap->width-1; + src_clip.ymax = src_pixmap->height-1; + + dst_clip.xmin = 0; + dst_clip.ymin = 0; + dst_clip.xmax = dst_pixmap->width-1; + dst_clip.ymax = dst_pixmap->height-1; + + if( !blit_clip(&dst_clip, &dst_x, &dst_y, + &src_clip, &src_x, &src_y, + &width, &height) ) + { + color_t *src_addr = &((color_t*)(src_pixmap->mapped))[src_pixmap->pitch*src_y/4+src_x]; + color_t *dst_addr = &((color_t*)(dst_pixmap->mapped))[dst_pixmap->pitch*dst_y/4+dst_x]; + + while( height-- ) + { + int w = width; + color_t *tmp_src = src_addr; + color_t *tmp_dst = dst_addr; + + src_addr += src_pixmap->pitch/4; + dst_addr += dst_pixmap->pitch/4; + + while( w >= 8) + { + __asm__ __volatile__ ( + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "movq 16(%0), %%mm2\n" + "movq 24(%0), %%mm3\n" + "movq %%mm0, (%1)\n" + "movq %%mm1, 8(%1)\n" + "movq %%mm2, 16(%1)\n" + "movq %%mm3, 24(%1)\n" + :: "r" (tmp_src), "r" (tmp_dst) + : "memory", "%mm0", "%mm1", "%mm2", "%mm3"); + w -= 8; + tmp_src += 8; + tmp_dst += 8; + }; + if( w >= 4 ) + { + __asm__ __volatile__ ( + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "movq %%mm0, (%1)\n" + "movq %%mm1, 8(%1)\n" + :: "r" (tmp_src), "r" (tmp_dst) + : "memory", "%mm0", "%mm1"); + w -= 4; + tmp_src += 4; + tmp_dst += 4; + }; + if( w >= 2 ) + { + __asm__ __volatile__ ( + "movq (%0), %%mm0\n" + "movq %%mm0, (%1)\n" + :: "r" (tmp_src), "r" (tmp_dst) + : "memory", "%mm0"); + w -= 2; + tmp_src += 2; + tmp_dst += 2; + }; + if( w ) + *tmp_dst = *tmp_src; + }; + }; + return ERR_OK; +}; + +int TransparentBlit(pixmap_t *dst_pixmap, int dst_x, int dst_y, + pixmap_t *src_pixmap, int src_x, int src_y, + int width, int height, color_t key) +{ + clip_t src_clip, dst_clip; + +/* if "hardware acceleration present" and + "destinastion is primary screen or local videomemory" and + "source is primary screen or local videomemory" +*/ + + if( (srv_hw2d != 0) && + ( (dst_pixmap == (void*)-1) || + ( (dst_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) && + ( (src_pixmap == (void*)-1) || + ( (src_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) + { + ioctl_t io; + pxblit_t *blit = (pxblit_t*)&dst_pixmap; + + if((int)dst_pixmap != -1) + blit->dst_pixmap = (pixmap_t*)dst_pixmap->handle; + + if((int)src_pixmap != -1) + blit->src_pixmap = (pixmap_t*)src_pixmap->handle; + + io.handle = srv_hw2d; + io.io_code = PX_BLIT_TRANSPARENT; + io.input = blit; + io.inp_size = 9; + io.output = NULL; + io.out_size = 0; + + return call_service(&io); + }; + + src_clip.xmin = 0; + src_clip.ymin = 0; + src_clip.xmax = src_pixmap->width-1; + src_clip.ymax = src_pixmap->height-1; + + dst_clip.xmin = 0; + dst_clip.ymin = 0; + dst_clip.xmax = dst_pixmap->width-1; + dst_clip.ymax = dst_pixmap->height-1; + + + if( !blit_clip(&dst_clip, &dst_x, &dst_y, + &src_clip, &src_x, &src_y, + &width, &height) ) + { + __m64 clr_key; + + dst_pixmap = (dst_pixmap == (void*)-1) ? &scrn_pixmap : dst_pixmap ; + src_pixmap = (src_pixmap == (void*)-1) ? &scrn_pixmap : src_pixmap ; + + color_t *src_addr = &((color_t*)(src_pixmap->mapped))[src_pixmap->pitch*src_y/4+src_x]; + color_t *dst_addr = &((color_t*)(dst_pixmap->mapped))[dst_pixmap->pitch*dst_y/4+dst_x]; + + clr_key = _mm_cvtsi32_si64(key); + clr_key = _mm_unpacklo_pi32(clr_key, clr_key); + + while( height-- ) + { + int w = width; + color_t *tmp_src = src_addr; + color_t *tmp_dst = dst_addr; + + src_addr += src_pixmap->pitch/4; + dst_addr += dst_pixmap->pitch/4; + + while( w >= 2) + { + __asm__ __volatile__ ( + "movq %[clr_key], %%mm0 \n\t" + "pcmpeqd %[src_clr], %%mm0 \n\t" + "pand %%mm0, %[dst_clr] \n\t" + "pandn %[src_clr], %%mm0 \n\t" + "por %%mm0, %[dst_clr] \n\t" + "movq %[dst_clr], (%0)" + :: "r" (tmp_dst), + [src_clr] "y" (*(__m64*)tmp_src), + [dst_clr] "y" (*(__m64*)tmp_dst), + [clr_key] "y" (clr_key) + :"memory","mm0"); + + w -= 2; + tmp_src += 2; + tmp_dst += 2; + }; + if( w && (*tmp_src != key) ) + *tmp_dst = *tmp_src; + }; + }; + return ERR_OK; +} + + diff --git a/programs/develop/libraries/pixlib/pixlib.c b/programs/develop/libraries/pixlib/pixlib.c new file mode 100644 index 0000000000..3f01c1a877 --- /dev/null +++ b/programs/develop/libraries/pixlib/pixlib.c @@ -0,0 +1,162 @@ + +#include "types.h" +#include "system.h" + +#include "pixlib.h" + +static clip_t scrn_clip; +static pixmap_t scrn_pixmap; + +static u32_t srv_hw2d; + +#define HS_HORIZONTAL 0 +#define HS_VERTICAL 1 +#define HS_FDIAGONAL 2 +#define HS_BDIAGONAL 3 +#define HS_CROSS 4 +#define HS_DIAGCROSS 5 + + +static u32_t hatches[HATCH_MAX*2] = + { 0xFF000000, 0xFF000000, /* HORIZONTAL */ + 0x22222222, 0x22222222, /* VERTICAL */ + 0x11224488, 0x11224488, /* FDIAGONAL */ + 0x44221188, 0x44221188, /* BDIAGONAL */ + 0xFF111111, 0xFF111111, /* CROSS */ + 0x10284482, 0x01824428 /* DCROSS */ + }; + + +typedef struct { + int available; /**< Count of available items in this slab. */ + void *start; /**< Start address of first item. */ + void *nextavail; /**< The index of next available item. */ +} slab_t; + +static brush_t brushes[256]; +static pixmap_t pixmaps[64]; +static slab_t br_slab; +static slab_t px_slab; + +int __stdcall start(int state) +{ + int p; + int i; + + int scrnsize; + int scrnbpp; + int scrnpitch; + + if( !test_mmx()) + return FALSE; + + if( (scrnbpp = GetScreenBpp()) != 32) + return FALSE; + + scrnsize = GetScreenSize(); + scrnpitch = GetScreenPitch(); + + scrn_clip.xmin = 0; + scrn_clip.ymin = 0; + scrn_clip.xmax = (scrnsize >> 16) - 1; + scrn_clip.ymax = (scrnsize & 0xFFFF) - 1; + + scrn_pixmap.width = scrnsize >> 16; + scrn_pixmap.height = scrnsize & 0xFFFF; + scrn_pixmap.format = PICT_a8r8g8b8; + scrn_pixmap.flags = 0; + scrn_pixmap.pitch = scrnpitch; + scrn_pixmap.mapped = (void*)0xFE000000; + + br_slab.available = 256; + br_slab.start = brushes; + br_slab.nextavail = brushes; + + for (i = 0, p = (int)br_slab.start; i < 256; i++) + { + *(int *)p = p+sizeof(brush_t); + p = p+sizeof(brush_t); + }; + + px_slab.available = 64; + px_slab.start = pixmaps; + px_slab.nextavail = pixmaps; + + for (i = 0, p = (int)px_slab.start; i < 64; i++) + { + *(int *)p = p+sizeof(pixmap_t); + p = p+sizeof(pixmap_t); + }; + + srv_hw2d = get_service("HDRAW"); + if(srv_hw2d == 0) + srv_hw2d = load_service("/rd/1/drivers/ati2d.drv"); + + return TRUE; +}; + + +#include "clip.inc" +#include "pixmap.inc" +#include "brush.inc" +#include "draw.inc" + +typedef struct +{ + char *name; + void *f; +}export_t; + +char szStart[] = "START"; +char szVersion[] = "version"; + +//char szBlockClip[] = "BlockClip"; +//char szLineClip[] = "LineClip"; + +char szCreatePixmap[] = "CreatePixmap"; +char szDestroyPixmap[] = "DestroyPixmap"; +char szLockPixmap[] = "LockPixmap"; +char szUnlockPixmap[] = "UnlockPixmap"; +char szGetPixmapPitch[] = "GetPixmapPitch"; + +char szCreateHatch[] = "CreateHatch"; +char szCreateMonoBrush[] = "CreateMonoBrush"; +char szDestroyBrush[] = "DestroyBrush"; + +char szClearPixmap[] = "ClearPixmap"; +char szLine[] = "Line"; +char szDrawRect[] = "DrawRect"; +char szFillRect[] = "FillRect"; +char szBlit[] = "Blit"; +char szTransparentBlit[] = "TransparentBlit"; + + +export_t EXPORTS[] __asm__("EXPORTS") = + { + { szStart, start }, + { szVersion, (void*)0x00010001 }, + + // { szBlockClip, BlockClip }, + // { szLineClip, LineClip }, + + { szCreatePixmap, CreatePixmap }, + { szDestroyPixmap, DestroyPixmap }, + { szLockPixmap, LockPixmap }, + { szUnlockPixmap, UnlockPixmap }, + { szGetPixmapPitch, GetPixmapPitch }, + + { szCreateHatch, CreateHatch }, + { szCreateMonoBrush, CreateMonoBrush }, + { szDestroyBrush, DestroyBrush }, + + { szClearPixmap, ClearPixmap }, + { szLine, Line }, + { szDrawRect, DrawRect }, + { szFillRect, FillRect }, + { szBlit, Blit }, + { szTransparentBlit, TransparentBlit }, + + { NULL, NULL }, + }; + + diff --git a/programs/develop/libraries/pixlib/pixlib.h b/programs/develop/libraries/pixlib/pixlib.h new file mode 100644 index 0000000000..c7d0b47c37 --- /dev/null +++ b/programs/develop/libraries/pixlib/pixlib.h @@ -0,0 +1,277 @@ + +typedef unsigned int color_t; + +typedef struct +{ + int x; + int y; +}pt_t; + +/*********** Clipping **********/ + +typedef struct +{ + int xmin; + int ymin; + int xmax; + int ymax; +}clip_t, *PTRclip; + +#define CLIP_TOP 1 +#define CLIP_BOTTOM 2 +#define CLIP_RIGHT 4 +#define CLIP_LEFT 8 + +int LineClip ( clip_t *clip, int *x1, int *y1, int *x2, int *y2 ); + +int BlockClip( clip_t *clip, int *x1, int *y1, int *x2, int* y2 ); + +/*********** Brushes ***********/ + +typedef struct +{ + color_t bkcolor; + color_t fcolor; + union { + u32_t bmp[2]; + u8_t bits[8]; + }; +}brush_t; + +#define HS_HORIZONTAL 0 +#define HS_VERTICAL 1 +#define HS_FDIAGONAL 2 +#define HS_BDIAGONAL 3 +#define HS_CROSS 4 +#define HS_DIAGCROSS 5 + + +#define HATCH_MAX 7 + +brush_t* CreateHatch(int hatch, color_t bkcolor, color_t fcolor); + +void DestroyBrush(brush_t *brush); + +/*********** Pixmap & drawing ***********/ + +typedef struct +{ + unsigned width; + unsigned height; + u32_t format; + u32_t flags; + unsigned pitch; + void *mapped; + u32_t handle; +}pixmap_t; + +#define PX_MEM_SYSTEM 0 +#define PX_MEM_LOCAL 1 +#define PX_MEM_GART 2 + +#define PX_MEM_MASK 3 + +#define PX_LOCK 1 + +pixmap_t* CreatePixmap(unsigned width, unsigned height, u32_t format, u32_t flags); + +void* LockPixmap(pixmap_t *pixmap); + +int UnlockPixmap(pixmap_t *pixmap); + +int DrawRect(pixmap_t *pixmap, int xorg, int yorg, + int width, int height, + color_t dst_color, color_t border); + +int FillRect(pixmap_t *pixmap, int xorg, int yorg, + int width, int height, + brush_t *brush, color_t border); + +//int PixBlit(pixblit_t* blit); + +/******** Hardware accelerated *********/ + +typedef struct +{ + pixmap_t *dstpix; + + struct { + int x0; + int y0; + }; + union { + struct { + int x1; + int y1; + }; + struct { + int w; + int h; + }; + }; + color_t color; + color_t border; +}draw_t; + +typedef struct +{ + pixmap_t *dstpix; + + int x; + int y; + int w; + int h; + + color_t bkcolor; + color_t fcolor; + + u32_t bmp0; + u32_t bmp1; + color_t border; +}fill_t; + +typedef struct +{ + int src_x; + int src_y; + int dst_x; + int dst_y; + int w; + int h; +}blit_t; + +typedef struct +{ + pixmap_t *dst_pixmap; + int dst_x; + int dst_y; + + pixmap_t *src_pixmap; + int src_x; + int src_y; + int w; + int h; +}pxblit_t; + +#define PX_CREATE 1 +#define PX_DESTROY 2 +#define PX_CLEAR 3 +#define PX_DRAW_RECT 4 +#define PX_FILL_RECT 5 +#define PX_LINE 6 +#define PX_BLIT 7 +#define PX_BLIT_TRANSPARENT 8 +#define PX_BLIT_ALPHA 9 + +/*********************************************************/ + +#define DBG(x) x +// #define DBG(x) + +#pragma pack (push,1) +typedef struct s_cursor +{ + u32_t magic; // 'CURS' + void (*destroy)(struct s_cursor*); // destructor + u32_t fd; // next object in list + u32_t bk; // prev object in list + u32_t pid; // owner id + + void *base; // allocated memory + u32_t hot_x; // hotspot coords + u32_t hot_y; +}cursor_t; +#pragma pack (pop) + + +typedef struct { + u32_t x ; + u32_t y ; +} xPointFixed; + +typedef u32_t xFixed_16_16; + +typedef xFixed_16_16 xFixed; + +#define XFIXED_BITS 16 + +#define xFixedToInt(f) (int) ((f) >> XFIXED_BITS) +#define IntToxFixed(i) ((xFixed) (i) << XFIXED_BITS) + +#define xFixedToFloat(f) (((float) (f)) / 65536) + +#define PICT_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \ + ((type) << 16) | \ + ((a) << 12) | \ + ((r) << 8) | \ + ((g) << 4) | \ + ((b))) + +#define PICT_FORMAT_A(f) (((f) >> 12) & 0x0f) +#define PICT_FORMAT_RGB(f) (((f) ) & 0xfff) + +#define PICT_TYPE_OTHER 0 +#define PICT_TYPE_A 1 +#define PICT_TYPE_ARGB 2 +#define PICT_TYPE_ABGR 3 +#define PICT_TYPE_COLOR 4 +#define PICT_TYPE_GRAY 5 + +typedef enum _PictFormatShort { + PICT_a8r8g8b8 = PICT_FORMAT(32,PICT_TYPE_ARGB,8,8,8,8), + PICT_x8r8g8b8 = PICT_FORMAT(32,PICT_TYPE_ARGB,0,8,8,8), + PICT_a8b8g8r8 = PICT_FORMAT(32,PICT_TYPE_ABGR,8,8,8,8), + PICT_x8b8g8r8 = PICT_FORMAT(32,PICT_TYPE_ABGR,0,8,8,8), + +/* 24bpp formats */ + PICT_r8g8b8 = PICT_FORMAT(24,PICT_TYPE_ARGB,0,8,8,8), + PICT_b8g8r8 = PICT_FORMAT(24,PICT_TYPE_ABGR,0,8,8,8), + +/* 16bpp formats */ + PICT_r5g6b5 = PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,6,5), + PICT_b5g6r5 = PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,6,5), + + PICT_a1r5g5b5 = PICT_FORMAT(16,PICT_TYPE_ARGB,1,5,5,5), + PICT_x1r5g5b5 = PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,5,5), + PICT_a1b5g5r5 = PICT_FORMAT(16,PICT_TYPE_ABGR,1,5,5,5), + PICT_x1b5g5r5 = PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,5,5), + PICT_a4r4g4b4 = PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4), + PICT_x4r4g4b4 = PICT_FORMAT(16,PICT_TYPE_ARGB,0,4,4,4), + PICT_a4b4g4r4 = PICT_FORMAT(16,PICT_TYPE_ABGR,4,4,4,4), + PICT_x4b4g4r4 = PICT_FORMAT(16,PICT_TYPE_ABGR,0,4,4,4), + +/* 8bpp formats */ + PICT_a8 = PICT_FORMAT(8,PICT_TYPE_A,8,0,0,0), + PICT_r3g3b2 = PICT_FORMAT(8,PICT_TYPE_ARGB,0,3,3,2), + PICT_b2g3r3 = PICT_FORMAT(8,PICT_TYPE_ABGR,0,3,3,2), + PICT_a2r2g2b2 = PICT_FORMAT(8,PICT_TYPE_ARGB,2,2,2,2), + PICT_a2b2g2r2 = PICT_FORMAT(8,PICT_TYPE_ABGR,2,2,2,2), + + PICT_c8 = PICT_FORMAT(8,PICT_TYPE_COLOR,0,0,0,0), + PICT_g8 = PICT_FORMAT(8,PICT_TYPE_GRAY,0,0,0,0), + + PICT_x4a4 = PICT_FORMAT(8,PICT_TYPE_A,4,0,0,0), + + PICT_x4c4 = PICT_FORMAT(8,PICT_TYPE_COLOR,0,0,0,0), + PICT_x4g4 = PICT_FORMAT(8,PICT_TYPE_GRAY,0,0,0,0), + +/* 4bpp formats */ + PICT_a4 = PICT_FORMAT(4,PICT_TYPE_A,4,0,0,0), + PICT_r1g2b1 = PICT_FORMAT(4,PICT_TYPE_ARGB,0,1,2,1), + PICT_b1g2r1 = PICT_FORMAT(4,PICT_TYPE_ABGR,0,1,2,1), + PICT_a1r1g1b1 = PICT_FORMAT(4,PICT_TYPE_ARGB,1,1,1,1), + PICT_a1b1g1r1 = PICT_FORMAT(4,PICT_TYPE_ABGR,1,1,1,1), + + PICT_c4 = PICT_FORMAT(4,PICT_TYPE_COLOR,0,0,0,0), + PICT_g4 = PICT_FORMAT(4,PICT_TYPE_GRAY,0,0,0,0), + +/* 1bpp formats */ + PICT_a1 = PICT_FORMAT(1,PICT_TYPE_A,1,0,0,0), + + PICT_g1 = PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0), +} PictFormatShort; + +void dump_mem(); + + + diff --git a/programs/develop/libraries/pixlib/pixlib.inc b/programs/develop/libraries/pixlib/pixlib.inc new file mode 100644 index 0000000000..30e0634754 --- /dev/null +++ b/programs/develop/libraries/pixlib/pixlib.inc @@ -0,0 +1,260 @@ + +REQ_DLL_VER = 1 +DLL_ENTRY = 1 + +HS_HORIZONTAL = 0 +HS_VERTICAL = 1 +HS_FDIAGONAL = 2 +HS_BDIAGONAL = 3 +HS_CROSS = 4 +HS_DIAGCROSS = 5 + +SCR_PIXMAP = -1 + +PX_MEM_SYSTEM = 0 +PX_MEM_LOCAL = 1 +PX_MEM_GART = 2 + +PX_MEM_MASK = 3 + +ARGB32 = ((32 shl 24) or (2 shl 16) or 0x8888) + +macro CreateHatch hatch, bkcolor, fcolor +{ + pushd fcolor + pushd bkcolor + pushd hatch + call [imp_CreateHatch] + add esp, 3*4 +} + +macro DestroyBrush brush +{ + pushd brush + call [imp_DestroyBrush] + add esp, 4 +} + +macro CreatePixmap width, height, format, flags +{ + pushd flags + pushd format + pushd height + pushd width + call [imp_CreatePixmap] + add esp, 4*4 +} + +macro DestroyPixmap pixmap +{ + pushd pixmap + call [imp_DestroyPixmap] + add esp, 4 +}; + +macro LockPixmap pixmap +{ + pushd pixmap + call [imp_LockPixmap] + add esp, 4 +} + +macro UnlockPixmap pixmap +{ + pushd pixmap + call [imp_UnlockPixmap] + add esp, 4 +} + +macro ClearPixmap pixmap, color +{ + pushd color + pushd pixmap + call [imp_ClearPixmap] + add esp, 2*4 +} + +macro Line pixmap, x0,y0,x1,y1,color +{ + pushd color + pushd y1 + pushd x1 + pushd y0 + pushd x0 + pushd pixmap + call [imp_Line] + add esp, 6*4 +}; + +macro DrawRect pixmap,x,y,w,h,color,border +{ + pushd border + pushd color + pushd h + pushd w + pushd y + pushd x + pushd pixmap + call [imp_DrawRect] + add esp, 7*4 +} + +macro FillRect pixmap,x,y,w,h,brush,border +{ + pushd border + pushd brush + pushd h + pushd w + pushd y + pushd x + pushd pixmap + call [imp_FillRect] + add esp, 7*4 +} + +macro Blit dstpix, dstx, dsty, srcpix, srcx, srcy, w, h +{ + pushd h + pushd w + pushd srcy + pushd srcx + pushd srcpix + pushd dsty + pushd dstx + pushd dstpix + call [imp_Blit] + add esp, 8*4 +} + +macro TransparentBlit dstpix, dstx, dsty, srcpix, srcx, srcy, w, h, key +{ + pushd key + pushd h + pushd w + pushd srcy + pushd srcx + pushd srcpix + pushd dsty + pushd dstx + pushd dstpix + call [imp_TransparentBlit] + add esp, 9*4 +} + +szPxlib db '/rd/1/lib/pixlib.obj',0 + +szStart db 'START',0 +szVersion db 'version',0 + +szCreatePixmap db 'CreatePixmap',0 +szDestroyPixmap db 'DestroyPixmap',0 +szLockPixmap db 'LockPixmap',0 +szUnlockPixmap db 'UnlockPixmap',0 +szGetPixmapPitch db 'GetPixmapPitch',0 + +szCreateHatch db 'CreateHatch',0 +szCreateMonoBrush db 'CreateMonoBrush',0 +szDestroyBrush db 'DestroyBrush',0 + +szClearPixmap db 'ClearPixmap',0 +szLine db 'Line',0 +szDrawRect db 'DrawRect',0 +szFillRect db 'FillRect',0 +szBlit db 'Blit',0 +szTransparentBlit db 'TransparentBlit',0 + +align 4 + +px_import: + +imp_start dd szStart +imp_ver dd szVersion + +imp_CreatePixmap dd szCreatePixmap +imp_DestroyPixmap dd szDestroyPixmap +imp_LockPixmap dd szLockPixmap +imp_UnlockPixmap dd szUnlockPixmap +imp_GetPixmapPitch dd szGetPixmapPitch + +imp_CreateHatch dd szCreateHatch +imp_CreateMonoBrush dd szCreateMonoBrush +imp_DestroyBrush dd szDestroyBrush + +imp_ClearPixmap dd szClearPixmap +imp_Line dd szLine +imp_DrawRect dd szDrawRect +imp_FillRect dd szFillRect +imp_Blit dd szBlit +imp_TransparentBlit dd szTransparentBlit + + dd 0 + + +;szBlockClip db 'BlockClip',0 +;szLineClip db 'LineClip',0 +;imp_BlockClip dd szBlockClip +;imp_LineClip dd szLineClip + + +align 4 + +load_pxlib: + mov eax, 68 + mov ebx, 19 + mov ecx, szPxlib + int 0x40 + test eax, eax + jz .fail + + mov edx, eax + mov esi, px_import +.import_loop: + lodsd + test eax, eax + jz .import_done + push edx +.import_find: + mov ebx, [edx] + test ebx, ebx + jz .fail ;import_not_found + + push eax +@@: + mov cl, [eax] + cmp cl, [ebx] + jnz .import_find_next + + test cl, cl + jz .import_found + + inc eax + inc ebx + jmp @b +.import_find_next: + pop eax + add edx, 8 + jmp .import_find +.import_found: + pop eax + mov eax, [edx+4] + mov [esi-4], eax + pop edx + jmp .import_loop +.import_done: + + cmp word [imp_ver], REQ_DLL_VER + jb .fail + cmp word [imp_ver+2], REQ_DLL_VER + ja .fail + + push DLL_ENTRY + call [imp_start] + test eax, eax + jz .fail + + ret +.fail: + xor eax, eax + ret + + diff --git a/programs/develop/libraries/pixlib/pixmap.inc b/programs/develop/libraries/pixlib/pixmap.inc new file mode 100644 index 0000000000..0e84963035 --- /dev/null +++ b/programs/develop/libraries/pixlib/pixmap.inc @@ -0,0 +1,141 @@ + +static pixmap_t* alloc_pixmap() +{ + if( px_slab.available ) + { + pixmap_t *pixmap; + + px_slab.available--; + pixmap = (pixmap_t*)px_slab.nextavail; + px_slab.nextavail = *(void**)pixmap; + + return pixmap; + } + return NULL; +}; + +static void free_pixmap(pixmap_t *pixmap) +{ + *(void**)pixmap = px_slab.nextavail; + px_slab.nextavail = pixmap; + px_slab.available++; +}; + +pixmap_t* CreatePixmap(unsigned width, unsigned height, u32_t format, u32_t flags) +{ + pixmap_t *pixmap; + + if( (width == 0) || ( width > 2048)|| + (height == 0) || (height > 2048)|| + (format != PICT_a8r8g8b8)) + return NULL; + + pixmap = alloc_pixmap(); + + if( pixmap ) + { + void *raw; + int pitch; + + pixmap->width = width; + pixmap->height = height; + pixmap->format = format; + pixmap->flags = flags; + + if( (srv_hw2d != 0) && + ( (flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) + { + ioctl_t io; + io.handle = srv_hw2d; + io.io_code = PX_CREATE; + io.input = pixmap; + io.inp_size = 7; + io.output = NULL; + io.out_size = 0; + + if (call_service(&io)==ERR_OK) + return pixmap; + else + { + free_pixmap(pixmap) ; + return NULL; + } + } + else + { +/* + Only system memory +*/ + pixmap->flags &= ~PX_MEM_MASK; + + pitch = ((width+8)&~8)*4; + raw = UserAlloc(pitch * height); + + if (! raw) + { + free_pixmap(pixmap); + return NULL; + }; + pixmap->pitch = pitch; + pixmap->mapped = raw; + }; + return pixmap; + }; + return NULL; +}; + +int DestroyPixmap( pixmap_t *pixmap) +{ + int retval = ERR_OK; + + if(pixmap == (pixmap_t*)-1) + return ERR_PARAM; + + if( (srv_hw2d != 0) && + ( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) + { + int retval; + + ioctl_t io; + io.handle = srv_hw2d; + io.io_code = PX_DESTROY; + io.input = pixmap; + io.inp_size = 7; + io.output = NULL; + io.out_size = 0; + + retval = call_service(&io); + } + else + { + UserFree(pixmap->mapped); + + pixmap->pitch = 0; + pixmap->mapped = 0; + pixmap->handle = 0; + }; + free_pixmap(pixmap); + + return retval; +}; + +void* LockPixmap(pixmap_t *pixmap) +{ + if(pixmap == (pixmap_t*)-1) + return scrn_pixmap.mapped; + else + return pixmap->mapped; +} + +int UnlockPixmap(pixmap_t *pixmap) +{ + return ERR_OK; +}; + +int GetPixmapPitch(pixmap_t *pixmap) +{ + if(pixmap == (pixmap_t*)-1) + return scrn_pixmap.pitch; + else + return pixmap->pitch; +}; diff --git a/programs/develop/libraries/pixlib/proc32.inc b/programs/develop/libraries/pixlib/proc32.inc new file mode 100644 index 0000000000..f623e7273d --- /dev/null +++ b/programs/develop/libraries/pixlib/proc32.inc @@ -0,0 +1,269 @@ + + +; Macroinstructions for defining and calling procedures + +macro stdcall proc,[arg] ; directly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call proc } + +macro invoke proc,[arg] ; indirectly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call [proc] } + +macro ccall proc,[arg] ; directly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call proc + if size@ccall + add esp,size@ccall + end if } + +macro cinvoke proc,[arg] ; indirectly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call [proc] + if size@ccall + add esp,size@ccall + end if } + +macro proc [args] ; define procedure + { common + match name params, args> + \{ define@proc name, \{ prologue name,flag,parmbytes,localbytes,reglist \} + macro locals + \{ virtual at ebp-localbytes+current + macro label . \\{ deflocal@proc .,:, \\} + struc db [val] \\{ \common deflocal@proc .,db,val \\} + struc dw [val] \\{ \common deflocal@proc .,dw,val \\} + struc dp [val] \\{ \common deflocal@proc .,dp,val \\} + struc dd [val] \\{ \common deflocal@proc .,dd,val \\} + struc dt [val] \\{ \common deflocal@proc .,dt,val \\} + struc dq [val] \\{ \common deflocal@proc .,dq,val \\} + struc rb cnt \\{ deflocal@proc .,rb cnt, \\} + struc rw cnt \\{ deflocal@proc .,rw cnt, \\} + struc rp cnt \\{ deflocal@proc .,rp cnt, \\} + struc rd cnt \\{ deflocal@proc .,rd cnt, \\} + struc rt cnt \\{ deflocal@proc .,rt cnt, \\} + struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} + macro endl + \{ purge label + restruc db,dw,dp,dd,dt,dq + restruc rb,rw,rp,rd,rt,rq + restruc byte,word,dword,pword,tword,qword + current = $-(ebp-localbytes) + end virtual \} + macro ret operand + \{ match any, operand \\{ retn operand \\} + match , operand \\{ match epilogue:reglist, epilogue@proc: + \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} + macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 + end if \} } + +macro defargs@proc [arg] + { common + if ~ arg eq + forward + local ..arg,current@arg + match argname:type, arg + \{ current@arg equ argname + label ..arg type + argname equ ..arg + if dqword eq type + dd ?,?,?,? + else if tbyte eq type + dd ?,?,? + else if qword eq type | pword eq type + dd ?,? + else + dd ? + end if \} + match =current@arg,current@arg + \{ current@arg equ arg + arg equ ..arg + ..arg dd ? \} + common + args@proc equ current@arg + forward + restore current@arg + common + end if } + +macro deflocal@proc name,def,[val] + { common + match vars, all@vars \{ all@vars equ all@vars, \} + all@vars equ all@vars name + forward + local ..var,..tmp + ..var def val + match =?, val \{ ..tmp equ \} + match any =dup (=?), val \{ ..tmp equ \} + match tmp : value, ..tmp : val + \{ tmp: end virtual + initlocal@proc ..var,def value + virtual at tmp\} + common + match first rest, ..var, \{ name equ first \} } + +macro initlocal@proc name,def + { virtual at name + def + size@initlocal = $ - name + end virtual + position@initlocal = 0 + while size@initlocal > position@initlocal + virtual at name + def + if size@initlocal - position@initlocal < 2 + current@initlocal = 1 + load byte@initlocal byte from name+position@initlocal + else if size@initlocal - position@initlocal < 4 + current@initlocal = 2 + load word@initlocal word from name+position@initlocal + else + current@initlocal = 4 + load dword@initlocal dword from name+position@initlocal + end if + end virtual + if current@initlocal = 1 + mov byte [name+position@initlocal],byte@initlocal + else if current@initlocal = 2 + mov word [name+position@initlocal],word@initlocal + else + mov dword [name+position@initlocal],dword@initlocal + end if + position@initlocal = position@initlocal + current@initlocal + end while } + +macro endp + { purge ret,locals,endl + finish@proc + purge finish@proc + restore regs@proc + match all,args@proc \{ restore all \} + restore args@proc + match all,all@vars \{ restore all \} } + +macro local [var] + { common + locals + forward done@local equ + match varname[count]:vartype, var + \{ match =BYTE, vartype \\{ varname rb count + restore done@local \\} + match =WORD, vartype \\{ varname rw count + restore done@local \\} + match =DWORD, vartype \\{ varname rd count + restore done@local \\} + match =PWORD, vartype \\{ varname rp count + restore done@local \\} + match =QWORD, vartype \\{ varname rq count + restore done@local \\} + match =TBYTE, vartype \\{ varname rt count + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + rq count+count + restore done@local \\} + match , done@local \\{ virtual + varname vartype + end virtual + rb count*sizeof.\#vartype + restore done@local \\} \} + match :varname:vartype, done@local:var + \{ match =BYTE, vartype \\{ varname db ? + restore done@local \\} + match =WORD, vartype \\{ varname dw ? + restore done@local \\} + match =DWORD, vartype \\{ varname dd ? + restore done@local \\} + match =PWORD, vartype \\{ varname dp ? + restore done@local \\} + match =QWORD, vartype \\{ varname dq ? + restore done@local \\} + match =TBYTE, vartype \\{ varname dt ? + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + dq ?,? + restore done@local \\} + match , done@local \\{ varname vartype + restore done@local \\} \} + match ,done@local + \{ var + restore done@local \} + common + endl } diff --git a/programs/develop/libraries/pixlib/readme.txt b/programs/develop/libraries/pixlib/readme.txt new file mode 100644 index 0000000000..0320129f38 --- /dev/null +++ b/programs/develop/libraries/pixlib/readme.txt @@ -0,0 +1,269 @@ + +typedef unsigned int u32_t; +typedef unsignet int handle; +typedef unsigned int color_t; + + +handle CreateHatchBrush(int hatch, color_t bkcolor, color_t fcolor); + +Создать штрихованную кисть размером 8х8 пикселей + +hatch тип штриховки: + + HS_HORIZONTAL ------- + HS_VERTICAL ||||||| + HS_FDIAGONAL \\\\\\\ + HS_BDIAGONAL /////// + HS_CROSS +++++++ + HS_DIAGCROSS xxxxxxx + +bkcolor цвет "0" + +fcolor цвет "1" + + +Возвращаемое значение: логический номер кисти или 0 + + + + +handle CreateMonoBrush(color_t bkcolor, color_t fcolor, + u32_t bmp0, u32_t bmp1); + +Создать монохромную кисть размером 8х8 пикселей + +bkcolor цвет "0" + +fcolor цвет "1" + +bmp0 bmp1 монохромный битмап 8х8 пикселей + + +Возвращаемое значение: логический номер кисти или 0 + + + +void DestroyBrush(handle brush); + +Уничтожить кисть. + +brush логический номер кисти. + + +Кисть должна быть создана вызовом CreateHatchBrush или CreateMonoBrush + + + + +handle CreatePixmap(unsigned width, unsigned height, u32_t format, u32_t flags); + +Создать битмап + +width ширина в пикселях. Максимум 2048 + +height высота в пикселях. Максимум 2048 + +format формат пикселей. Сейчас поддерживается только ARGB32 + +flags дополнительные флаги: + + PX_MEM_SYSTEM = 0 битмап в системной памяти + PX_MEM_LOCAL = 1 битмап в локальной видеопамяти + PX_MEM_GART = 2 зарезервировано + остальные биты зарезервированы и должны быть 0 + + +Возвращаемое значение: логический номер битмапа в случае успеха или 0 + + + + +int DestroyPixmap( handle pixmap) + +Уничтожить битмап. + +pixmap логический номер битмапа. + +Битмап должен быть создан CreatePixmap. + + +Возвращаемое значение: ERR_OK в случае успеха или ERR_PARAM в случае неудачи. + + + + +void* LockPixmap(handle pixmap) + +Получить доступ к данным битмапа. + +pixmap логический номер битмапа. SCR_PIXMAP для первичного экрана. + + +Блокирование битмапа может снизить быстродействие если битмап +создан с флагами PX_MEM_LOCAL или PX_MEM_GART. + + +Возвращаемое значение: указатель на начало данных битмапа + или NULL в случае неудачи. + + + + +int GetPixmapPitch(handle pixmap) + +Получить ширину строки битмапа в байтах. + +pixmap логический номер битмапа. SCR_PIXMAP для первичного экрана. + + +Битмап должен быть заблокирован вызовом LockPixmap + +Возвращаемое значение: ширина строки битмапа в байтах или 0 в случае неудачи. + + + + +int UnlockPixmap(handle pixmap) + + +Возвращаемое значение: ERR_OK в случае успеха или ERR_PARAM в случае неудачи. + + + +int ClearPixmap(handle pixmap, color_t color) + +Заполняет битмап указанным цветом; + +pixmap логический номер битмапа. SCR_PIXMAP для первичного экрана. + +color цвет в формате ARGB32 + + +Возвращаемое значение: ERR_OK в случае успеха или ERR_PARAM в случае неудачи. + + + + +int Line(handle pixmap, int x0, int y0, int x1, int y1, color_t color) + +Нарисовать сплошную линию указаного цвета толщиной в 1 пиксель. + +pixmap логический номер битмапа в который будет производится отрисовка. + SCR_PIXMAP для первичного экрана + +x0,y0 x1,y1 координаты начальной и конечной точек линиии + +color цвет в формате ARGB32 + + +Возвращаемое значение: ERR_OK в случае успеха или ERR_PARAM в случае неудачи. + + + + +int DrawRect(handle pixmap, int xorg, int yorg, + int width, int height, + color_t dst_color, color_t border) + +Нарисовать сплошной прямоугльник указаного цвета c окантовкой. + +pixmap логический номер битмапа в который будет производится отрисовка. + SCR_PIXMAP для первичного экрана + +xorg,yorg координаты левого верхнего угла прямоугольника в пикселях + +width ширина прямоугольника в пикселях + +height высота прямоугольника в пикселях + +color цвет прямоугольника в формате ARGB32 + +border цвет окантовки в формате ARGB32. Толщина окантовки 1 пиксел. + + +Возвращаемое значение: ERR_OK в случае успеха или ERR_PARAM в случае неудачи. + + + + +int FillRect(handle pixmap, int xorg, int yorg, + int width, int height, + brush_t *brush, color_t border) + +Нарисовать прямоугольник используя кисть + +pixmap логический номер битмапа в который будет производится отрисовка. + SCR_PIXMAP для первичного экрана + +xorg,yorg координаты левого верхнего угла прямоугольника в пикселях + +width ширина прямоугольника в пикселях + +height высота прямоугольника в пикселях + +brush монохромная кисть размером 8х8 пикселей + +border цвет окантовки в формате ARGB32. Толщина окантовки 1 пиксел. + Окантовка не рисуется если альфа компонен цвета равен 0. + + +Кисть должна быть создана CreateHatch или CreateMonoBrush. + + +Возвращаемое значение: ERR_OK в случае успеха или ERR_PARAM в случае неудачи. + + + + +int Blit(handle dst_pixmap, int dst_x, int dst_y, + handle src_pixmap, int src_x, int src_y, + int width, int height) + +Скопировать прямоугольную область пикселей. + +dst_pixmap логический номер битмапа в который будет производитс + копирование. SCR_PIXMAP для первичного экрана. + +dst_x, dst_y координаты левого верхнего угла области назначени + +src_pixmap логический номер битмапа - источника пикселей. + SCR_PIXMAP для первичного экрана. + +src_x,src_y координаты левого верхнего угла копируемой области + +width ширина копируемой области + +height высота копируемой области + +Возвращаемое значение: ERR_OK в случае успеха или ERR_PARAM в случае неудачи. + + + + +int TransparentBlit(handle dst_pixmap, int dst_x, int dst_y, + handle src_pixmap, int src_x, int src_y, + int width, int height, color_t key) + +Скопировать прямоугольную область пикселей используя прозрачный цвет. + +dst_pixmap логический номер битмапа в который будет производитс + копирование. SCR_PIXMAP для первичного экрана. + +dst_x, dst_y координаты левого верхнего угла области назначени + +src_pixmap логический номер битмапа - источника пикселей. + SCR_PIXMAP для первичного экрана. + +src_x,src_y координаты левого верхнего угла копируемой области + +width ширина копируемой области + +height высота копируемой области + +key прозрачный цвет в формате ARGB32 + + +Функция не копирует пиксели цвет которых совпадает с key. + + +Возвращаемое значение: ERR_OK в случае успеха или ERR_PARAM в случае неудачи. diff --git a/programs/develop/libraries/pixlib/system.h b/programs/develop/libraries/pixlib/system.h new file mode 100644 index 0000000000..2025535fe1 --- /dev/null +++ b/programs/develop/libraries/pixlib/system.h @@ -0,0 +1,129 @@ + + +typedef struct +{ + unsigned handle; + unsigned io_code; + void *input; + int inp_size; + void *output; + int out_size; +}ioctl_t; + + +#define ERR_OK 0 +#define ERR_PARAM -1 +#define ERR_NOMEM -2 + + +/////////////////////////////////////////////////////////////////////////////// + + +void usleep(u32_t delay); + +static int __attribute__ ((always_inline)) +abs (int i) +{ + return i < 0 ? -i : i; +}; + + +extern inline u32_t get_service(char *name) +{ + u32_t retval; + asm("int $0x40" + :"=a"(retval) + :"a"(68),"b"(16),"c"(name)); + + return retval; +}; + +extern inline u32_t load_service(char *name) +{ + u32_t retval; + asm("int $0x40" + :"=a"(retval) + :"a"(68),"b"(21),"c"(name)); + + return retval; +}; + +extern inline int call_service(ioctl_t *io) +{ + int retval; + + asm("int $0x40" + :"=a"(retval) + :"a"(68),"b"(17),"c"(io) + :"memory"); + + return retval; +}; + +extern inline void* UserAlloc(size_t size) +{ + void *retval; + + asm("int $0x40" + :"=a"(retval) + :"a"(68),"b"(12),"c"(size) + :"memory"); + return retval; +} + +extern inline void UserFree(void *mem) +{ + __asm__ __volatile__( + "int $0x40" + ::"a"(68),"b"(13),"c"(mem) + :"memory"); +} + +extern inline int GetScreenSize() +{ + int retval; + + __asm__ __volatile__( + "int $0x40" + :"=a"(retval) + :"a"(61), "b"(1)); + return retval; +} + +extern inline int GetScreenBpp() +{ + int retval; + + __asm__ __volatile__( + "int $0x40" + :"=a"(retval) + :"a"(61), "b"(2)); + return retval; +} + +extern inline int GetScreenPitch() +{ + int retval; + + __asm__ __volatile__( + "int $0x40" + :"=a"(retval) + :"a"(61), "b"(3)); + return retval; +} + +extern inline int test_mmx() +{ + int retval; + + __asm__ __volatile__( + "cpuid\n\t" + "testl $23, %%edx\n\t" + "setnzb %%al\n\t" + "movzx %%al, %%eax" + :"=a"(retval) + :"a"(0) + :"ebx","ecx","edx"); + + return retval; +} diff --git a/programs/develop/libraries/pixlib/types.h b/programs/develop/libraries/pixlib/types.h new file mode 100644 index 0000000000..681cc4b9e2 --- /dev/null +++ b/programs/develop/libraries/pixlib/types.h @@ -0,0 +1,21 @@ + + +typedef unsigned int handle_t; +typedef unsigned int size_t; +typedef unsigned int count_t; + + +typedef unsigned char u8_t; +typedef unsigned short int u16_t; +typedef unsigned int u32_t; +typedef unsigned long long u64_t; + + +typedef int bool; + +#define NULL (void*)0 + +#define TRUE (bool)1 +#define FALSE (bool)0 + +