static int OkfRenderMask16(int dx, int dy, int width, int height,
unsigned char *bitmap, int bitmapx,
int bitmapy, int bitmapWidth, int bitmapHeight,
unsigned char *mask)
{
int i, j;
unsigned short *bmp, *screen;
unsigned char *msk;
unsigned char opacity;
int red, green, blue;
// Clip bitmap
//- If completly out of limits, return
if ((dx > okf.clip.x2) || (dy > okf.clip.y2))
return 0;
if ((dx + width - 1 < okf.clip.x1) || (dy + height - 1 < okf.clip.y1))
return 0;
//- Clip X and Width
if (dx < okf.clip.x1)
{
width -= okf.clip.x1 - dx;
bitmapx += okf.clip.x1 - dx;
dx = okf.clip.x1;
}
if (dx + width - 1 > okf.clip.x2)
width = okf.clip.x2 - dx + 1;
//- Clip Y and Height
if (dy < okf.clip.y1)
{
height -= okf.clip.y1 - dy;
bitmapy += okf.clip.y1 - dy;
dy = okf.clip.y1;
}
if (dy + height - 1 > okf.clip.y2)
height = okf.clip.y2 - dy + 1;
// Adjust to rotated screen
//- Source coordinates
i = bitmapx;
bitmapx = bitmapHeight - (bitmapy + height);
bitmapy = i;
//- Destination coordinates
i = dx;
dx = GPC_LCD_HEIGHT - (dy + height);
dy = i;
//- Sizes
bitmapWidth = bitmapHeight;
i = width;
width = height;
height = i;
// Blit bitmap
screen = (unsigned short *) (okf.pSurfaces[*okf.pCurSurface].ptbuffer) + dy * GPC_LCD_PHYSICAL_W + dx;
bmp = (unsigned short *) bitmap + bitmapy * bitmapWidth + bitmapx;
msk = mask + bitmapy * bitmapWidth + bitmapx;
for (j=0; j < height; j++)
{
for (i=0; i < width; i++, screen++, bmp++, msk++)
{
opacity = *msk;
if (opacity > 0)
{
// Modify opacity, if required
if (okf.opacity < 31)
opacity = (opacity * okf.opacity) / 31;
if (opacity > 0)
{
// Separate color components
red = GetRGBRed(*bmp);
green = GetRGBGreen(*bmp);
blue = GetRGBBlue(*bmp);
// Modify color
switch (okf.effect.type)
{
case okfOverlay:
OkfOverlayColor(red, green, blue, okf.effect.color, okf.effect.intensity);
break;
case okfAddColor:
OkfAddColor(red, green, blue, okf.effect.color);
OkfAdjustColorComponents(red, green, blue);
break;
case okfSubtractColor:
OkfSubtractColor(red, green, blue, okf.effect.color);
OkfAdjustColorComponents(red, green, blue);
break;
case okfGrayScale:
OkfGrayScaleColor(red, green, blue);
break;
}
// Merge color with background, if required
if (opacity < 31)
OkfUnderlayColor(red, green, blue, *screen, opacity);
// Draw pixel
*screen = RGB(red, green, blue);
}
}
}
screen += GPC_LCD_PHYSICAL_W - width;
bmp += bitmapWidth - width;
msk += bitmapWidth - width;
}
return 0;
}