lost pixlib sources

git-svn-id: svn://kolibrios.org@882 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2008-10-20 15:53:55 +00:00
parent a97b422321
commit 673a89c327
11 changed files with 2528 additions and 0 deletions

View File

@ -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++;
};

View File

@ -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;
};

View File

@ -0,0 +1,769 @@
#include <mmintrin.h>
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;
}

View File

@ -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 },
};

View File

@ -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();

View File

@ -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

View File

@ -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;
};

View File

@ -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,<params \} }
prologue@proc equ prologuedef
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,localbytes
end if
end if
irps reg, reglist \{ push reg \} }
epilogue@proc equ epiloguedef
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if (flag and 10000b) | (parmbytes=0)
retn
else
retn parmbytes
end if }
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
virtual at ebp+8
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $ - (ebp+8)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
match prologue:reglist, prologue@proc:<regs> \{ 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:<regs>
\\\{ 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 }

View File

@ -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 в случае неудачи.

View File

@ -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;
}

View File

@ -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