2018-02-28 11:56:01 +00:00
|
|
|
#include "global.h"
|
2018-02-28 12:07:58 +00:00
|
|
|
#include "blit.h"
|
2018-02-28 11:56:01 +00:00
|
|
|
|
2018-12-20 21:53:08 +00:00
|
|
|
void BlitBitmapRect4BitWithoutColorKey(const struct Bitmap *src, struct Bitmap *dst, u16 srcX, u16 srcY, u16 dstX, u16 dstY, u16 width, u16 height)
|
2018-02-28 11:56:01 +00:00
|
|
|
{
|
|
|
|
BlitBitmapRect4Bit(src, dst, srcX, srcY, dstX, dstY, width, height, 0xFF);
|
|
|
|
}
|
|
|
|
|
2018-12-20 21:53:08 +00:00
|
|
|
void BlitBitmapRect4Bit(const struct Bitmap *src, struct Bitmap *dst, u16 srcX, u16 srcY, u16 dstX, u16 dstY, u16 width, u16 height, u8 colorKey)
|
2018-02-28 11:56:01 +00:00
|
|
|
{
|
|
|
|
s32 xEnd;
|
|
|
|
s32 yEnd;
|
|
|
|
s32 multiplierSrcY;
|
|
|
|
s32 multiplierDstY;
|
|
|
|
s32 loopSrcY, loopDstY;
|
|
|
|
s32 loopSrcX, loopDstX;
|
2018-12-20 21:53:08 +00:00
|
|
|
const u8 *pixelsSrc;
|
2018-02-28 11:56:01 +00:00
|
|
|
u8 *pixelsDst;
|
|
|
|
s32 toOrr;
|
|
|
|
s32 toAnd;
|
|
|
|
s32 toShift;
|
|
|
|
|
|
|
|
if (dst->width - dstX < width)
|
|
|
|
xEnd = (dst->width - dstX) + srcX;
|
|
|
|
else
|
|
|
|
xEnd = srcX + width;
|
|
|
|
|
|
|
|
if (dst->height - dstY < height)
|
|
|
|
yEnd = (dst->height - dstY) + srcY;
|
|
|
|
else
|
|
|
|
yEnd = height + srcY;
|
|
|
|
|
|
|
|
multiplierSrcY = (src->width + (src->width & 7)) >> 3;
|
|
|
|
multiplierDstY = (dst->width + (dst->width & 7)) >> 3;
|
|
|
|
|
|
|
|
if (colorKey == 0xFF)
|
|
|
|
{
|
|
|
|
for (loopSrcY = srcY, loopDstY = dstY; loopSrcY < yEnd; loopSrcY++, loopDstY++)
|
|
|
|
{
|
|
|
|
for (loopSrcX = srcX, loopDstX = dstX; loopSrcX < xEnd; loopSrcX++, loopDstX++)
|
|
|
|
{
|
|
|
|
pixelsSrc = src->pixels + ((loopSrcX >> 1) & 3) + ((loopSrcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1B);
|
|
|
|
pixelsDst = dst->pixels + ((loopDstX >> 1) & 3) + ((loopDstX >> 3) << 5) + (((loopDstY >> 3) * multiplierDstY) << 5) + ((u32)(loopDstY << 0x1d) >> 0x1B);
|
|
|
|
toOrr = ((*pixelsSrc >> ((loopSrcX & 1) << 2)) & 0xF);
|
|
|
|
toShift = ((loopDstX & 1) << 2);
|
|
|
|
toOrr <<= toShift;
|
|
|
|
toAnd = 0xF0 >> (toShift);
|
|
|
|
*pixelsDst = toOrr | (*pixelsDst & toAnd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (loopSrcY = srcY, loopDstY = dstY; loopSrcY < yEnd; loopSrcY++, loopDstY++)
|
|
|
|
{
|
|
|
|
for (loopSrcX = srcX, loopDstX = dstX; loopSrcX < xEnd; loopSrcX++, loopDstX++)
|
|
|
|
{
|
|
|
|
pixelsSrc = src->pixels + ((loopSrcX >> 1) & 3) + ((loopSrcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1B);
|
|
|
|
pixelsDst = dst->pixels + ((loopDstX >> 1) & 3) + ((loopDstX >> 3) << 5) + (((loopDstY >> 3) * multiplierDstY) << 5) + ((u32)(loopDstY << 0x1d) >> 0x1B);
|
|
|
|
toOrr = ((*pixelsSrc >> ((loopSrcX & 1) << 2)) & 0xF);
|
|
|
|
if (toOrr != colorKey)
|
|
|
|
{
|
|
|
|
toShift = ((loopDstX & 1) << 2);
|
|
|
|
toOrr <<= toShift;
|
|
|
|
toAnd = 0xF0 >> (toShift);
|
|
|
|
*pixelsDst = toOrr | (*pixelsDst & toAnd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FillBitmapRect4Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue)
|
|
|
|
{
|
|
|
|
s32 xEnd;
|
|
|
|
s32 yEnd;
|
|
|
|
s32 multiplierY;
|
|
|
|
s32 loopX, loopY;
|
2020-10-02 15:17:11 +00:00
|
|
|
u8 toOrr1, toOrr2;
|
2018-02-28 11:56:01 +00:00
|
|
|
|
|
|
|
xEnd = x + width;
|
|
|
|
if (xEnd > surface->width)
|
|
|
|
xEnd = surface->width;
|
|
|
|
|
|
|
|
yEnd = y + height;
|
|
|
|
if (yEnd > surface->height)
|
|
|
|
yEnd = surface->height;
|
|
|
|
|
|
|
|
multiplierY = (surface->width + (surface->width & 7)) >> 3;
|
2020-10-02 15:17:11 +00:00
|
|
|
toOrr1 = fillValue << 4;
|
|
|
|
toOrr2 = fillValue & 0xF;
|
2018-02-28 11:56:01 +00:00
|
|
|
|
|
|
|
for (loopY = y; loopY < yEnd; loopY++)
|
|
|
|
{
|
|
|
|
for (loopX = x; loopX < xEnd; loopX++)
|
|
|
|
{
|
|
|
|
u8 *pixels = surface->pixels + ((loopX >> 1) & 3) + ((loopX >> 3) << 5) + (((loopY >> 3) * multiplierY) << 5) + ((u32)(loopY << 0x1d) >> 0x1B);
|
|
|
|
if ((loopX << 0x1F) != 0)
|
|
|
|
*pixels = toOrr1 | (*pixels & 0xF);
|
|
|
|
else
|
|
|
|
*pixels = toOrr2 | (*pixels & 0xF0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-20 21:53:08 +00:00
|
|
|
void BlitBitmapRect4BitTo8Bit(const struct Bitmap *src, struct Bitmap *dst, u16 srcX, u16 srcY, u16 dstX, u16 dstY, u16 width, u16 height, u8 colorKey, u8 paletteOffset)
|
2018-02-28 11:56:01 +00:00
|
|
|
{
|
|
|
|
s32 palOffsetBits;
|
|
|
|
s32 xEnd;
|
|
|
|
s32 yEnd;
|
|
|
|
s32 multiplierSrcY;
|
|
|
|
s32 multiplierDstY;
|
|
|
|
s32 loopSrcY, loopDstY;
|
|
|
|
s32 loopSrcX, loopDstX;
|
2018-12-20 21:53:08 +00:00
|
|
|
const u8 *pixelsSrc;
|
2018-02-28 11:56:01 +00:00
|
|
|
u8 *pixelsDst;
|
|
|
|
s32 colorKeyBits;
|
|
|
|
|
|
|
|
palOffsetBits = (u32)(paletteOffset << 0x1C) >> 0x18;
|
|
|
|
colorKeyBits = (u32)(colorKey << 0x1C) >> 0x18;
|
|
|
|
|
|
|
|
if (dst->width - dstX < width)
|
|
|
|
xEnd = (dst->width - dstX) + srcX;
|
|
|
|
else
|
|
|
|
xEnd = width + srcX;
|
|
|
|
|
|
|
|
if (dst->height - dstY < height)
|
|
|
|
yEnd = (srcY + dst->height) - dstY;
|
|
|
|
else
|
|
|
|
yEnd = srcY + height;
|
|
|
|
|
|
|
|
multiplierSrcY = (src->width + (src->width & 7)) >> 3;
|
|
|
|
multiplierDstY = (dst->width + (dst->width & 7)) >> 3;
|
|
|
|
|
|
|
|
if (colorKey == 0xFF)
|
|
|
|
{
|
|
|
|
for (loopSrcY = srcY, loopDstY = dstY; loopSrcY < yEnd; loopSrcY++, loopDstY++)
|
|
|
|
{
|
|
|
|
pixelsSrc = src->pixels + ((srcX >> 1) & 3) + ((srcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1b);
|
|
|
|
for (loopSrcX = srcX, loopDstX = dstX; loopSrcX < xEnd; loopSrcX++, loopDstX++)
|
|
|
|
{
|
|
|
|
pixelsDst = dst->pixels + (loopDstX & 7) + ((loopDstX >> 3) << 6) + (((loopDstY >> 3) * multiplierDstY) << 6) + ((u32)(loopDstY << 0x1d) >> 0x1a);
|
|
|
|
if (loopSrcX & 1)
|
|
|
|
{
|
|
|
|
*pixelsDst = palOffsetBits + (*pixelsSrc >> 4);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pixelsSrc = src->pixels + ((loopSrcX >> 1) & 3) + ((loopSrcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1b);
|
|
|
|
*pixelsDst = palOffsetBits + (*pixelsSrc & 0xF);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (loopSrcY = srcY, loopDstY = dstY; loopSrcY < yEnd; loopSrcY++, loopDstY++)
|
|
|
|
{
|
|
|
|
pixelsSrc = src->pixels + ((srcX >> 1) & 3) + ((srcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1b);
|
|
|
|
for (loopSrcX = srcX, loopDstX = dstX; loopSrcX < xEnd; loopSrcX++, loopDstX++)
|
|
|
|
{
|
|
|
|
if (loopSrcX & 1)
|
|
|
|
{
|
|
|
|
if ((*pixelsSrc & 0xF0) != colorKeyBits)
|
|
|
|
{
|
|
|
|
pixelsDst = dst->pixels + (loopDstX & 7) + ((loopDstX >> 3) << 6) + (((loopDstY >> 3) * multiplierDstY) << 6) + ((u32)(loopDstY << 0x1d) >> 0x1a);
|
|
|
|
*pixelsDst = palOffsetBits + (*pixelsSrc >> 4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pixelsSrc = src->pixels + ((loopSrcX >> 1) & 3) + ((loopSrcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1b);
|
|
|
|
if ((*pixelsSrc & 0xF) != colorKey)
|
|
|
|
{
|
|
|
|
pixelsDst = dst->pixels + (loopDstX & 7) + ((loopDstX >> 3) << 6) + (((loopDstY >> 3) * multiplierDstY) << 6) + ((u32)(loopDstY << 0x1d) >> 0x1a);
|
|
|
|
*pixelsDst = palOffsetBits + (*pixelsSrc & 0xF);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FillBitmapRect8Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue)
|
|
|
|
{
|
|
|
|
s32 xEnd;
|
|
|
|
s32 yEnd;
|
|
|
|
s32 multiplierY;
|
|
|
|
s32 loopX, loopY;
|
|
|
|
|
|
|
|
xEnd = x + width;
|
|
|
|
if (xEnd > surface->width)
|
|
|
|
xEnd = surface->width;
|
|
|
|
|
|
|
|
yEnd = y + height;
|
|
|
|
if (yEnd > surface->height)
|
|
|
|
yEnd = surface->height;
|
|
|
|
|
|
|
|
multiplierY = (surface->width + (surface->width & 7)) >> 3;
|
|
|
|
|
|
|
|
for (loopY = y; loopY < yEnd; loopY++)
|
|
|
|
{
|
|
|
|
for (loopX = x; loopX < xEnd; loopX++)
|
|
|
|
{
|
|
|
|
u8 *pixels = surface->pixels + (loopX & 7) + ((loopX >> 3) << 6) + (((loopY >> 3) * multiplierY) << 6) + ((u32)(loopY << 0x1d) >> 0x1a);
|
|
|
|
*pixels = fillValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|