Initial commit
This commit is contained in:
212
engines/ags/lib/allegro/surface_generic.cpp
Normal file
212
engines/ags/lib/allegro/surface_generic.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ags/lib/allegro/color.h"
|
||||
#include "ags/lib/allegro/surface.h"
|
||||
#include "ags/globals.h"
|
||||
|
||||
namespace AGS3 {
|
||||
|
||||
template<int DestBytesPerPixel, int SrcBytesPerPixel, bool Scale>
|
||||
void BITMAP::drawInnerGeneric(DrawInnerArgs &args) {
|
||||
const int xDir = args.horizFlip ? -1 : 1;
|
||||
byte rSrc, gSrc, bSrc, aSrc;
|
||||
byte rDest = 0, gDest = 0, bDest = 0, aDest = 0;
|
||||
|
||||
// Instead of skipping pixels outside our boundary here, we just clip
|
||||
// our area instead.
|
||||
int xCtrStart = 0, xCtrBppStart = 0, xCtrWidth = args.dstRect.width();
|
||||
if (args.xStart + xCtrWidth > args.destArea.w) { // Clip the right
|
||||
xCtrWidth = args.destArea.w - args.xStart;
|
||||
}
|
||||
if (args.xStart < 0) { // Clip the left
|
||||
xCtrStart = -args.xStart;
|
||||
xCtrBppStart = xCtrStart * SrcBytesPerPixel;
|
||||
args.xStart = 0;
|
||||
}
|
||||
int destY = args.yStart, yCtr = 0, srcYCtr = 0, scaleYCtr = 0, yCtrHeight = args.dstRect.height();
|
||||
if (args.yStart < 0) { // Clip the top
|
||||
yCtr = -args.yStart;
|
||||
destY = 0;
|
||||
if (Scale) {
|
||||
scaleYCtr = yCtr * args.scaleY;
|
||||
srcYCtr = scaleYCtr / BITMAP::SCALE_THRESHOLD;
|
||||
}
|
||||
}
|
||||
if (args.yStart + yCtrHeight > args.destArea.h) { // Clip the bottom
|
||||
yCtrHeight = args.destArea.h - args.yStart;
|
||||
}
|
||||
|
||||
byte *destP = (byte *)args.destArea.getBasePtr(0, destY);
|
||||
const byte *srcP = (const byte *)args.src.getBasePtr(
|
||||
args.horizFlip ? args.srcArea.right - 1 : args.srcArea.left,
|
||||
args.vertFlip ? args.srcArea.bottom - 1 - yCtr :
|
||||
args.srcArea.top + yCtr);
|
||||
for (; yCtr < yCtrHeight; ++destY, ++yCtr, scaleYCtr += args.scaleY) {
|
||||
if (Scale) {
|
||||
int newSrcYCtr = scaleYCtr / BITMAP::SCALE_THRESHOLD;
|
||||
if (srcYCtr != newSrcYCtr) {
|
||||
int diffSrcYCtr = newSrcYCtr - srcYCtr;
|
||||
srcP += args.src.pitch * diffSrcYCtr;
|
||||
srcYCtr = newSrcYCtr;
|
||||
}
|
||||
}
|
||||
// Loop through the pixels of the row
|
||||
for (int destX = args.xStart, xCtr = xCtrStart, xCtrBpp = xCtrBppStart, scaleXCtr = xCtr * args.scaleX; xCtr < xCtrWidth; ++destX, ++xCtr, xCtrBpp += SrcBytesPerPixel, scaleXCtr += args.scaleX) {
|
||||
const byte *srcVal = srcP + xDir * xCtrBpp;
|
||||
if (Scale) {
|
||||
srcVal = srcP + (scaleXCtr / BITMAP::SCALE_THRESHOLD) * SrcBytesPerPixel;
|
||||
}
|
||||
uint32 srcCol = getColor(srcVal, SrcBytesPerPixel);
|
||||
|
||||
// Check if this is a transparent color we should skip
|
||||
if (args.skipTrans && ((srcCol & args.alphaMask) == args.transColor))
|
||||
continue;
|
||||
|
||||
byte *destVal = (byte *)&destP[destX * DestBytesPerPixel];
|
||||
|
||||
// When blitting to the same format we can just copy the color
|
||||
if (DestBytesPerPixel == 1) {
|
||||
*destVal = srcCol;
|
||||
continue;
|
||||
} else if ((DestBytesPerPixel == SrcBytesPerPixel) && args.srcAlpha == -1) {
|
||||
if (DestBytesPerPixel == 4)
|
||||
*(uint32 *)destVal = srcCol;
|
||||
else
|
||||
*(uint16 *)destVal = srcCol;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We need the rgb values to do blending and/or convert between formats
|
||||
if (SrcBytesPerPixel == 1) {
|
||||
const RGB &rgb = args.palette[srcCol];
|
||||
aSrc = 0xff;
|
||||
rSrc = rgb.r;
|
||||
gSrc = rgb.g;
|
||||
bSrc = rgb.b;
|
||||
} else {
|
||||
if (SrcBytesPerPixel == 4) {
|
||||
aSrc = srcCol >> 24;
|
||||
rSrc = (srcCol >> 16) & 0xff;
|
||||
gSrc = (srcCol >> 8) & 0xff;
|
||||
bSrc = srcCol & 0xff;
|
||||
} else { // SrcBytesPerPixel == 2
|
||||
aSrc = 0xff;
|
||||
rSrc = (srcCol >> 11) & 0x1f;
|
||||
rSrc = (rSrc << 3) | (rSrc >> 2);
|
||||
gSrc = (srcCol >> 5) & 0x3f;
|
||||
gSrc = (gSrc << 2) | (gSrc >> 4);
|
||||
bSrc = srcCol & 0x1f;
|
||||
bSrc = (bSrc << 3) | (bSrc >> 2);
|
||||
}
|
||||
//src.format.colorToARGB(srcCol, aSrc, rSrc, gSrc, bSrc);
|
||||
}
|
||||
|
||||
if (args.srcAlpha == -1) {
|
||||
// This means we don't use blending.
|
||||
aDest = aSrc;
|
||||
rDest = rSrc;
|
||||
gDest = gSrc;
|
||||
bDest = bSrc;
|
||||
} else {
|
||||
if (args.useTint) {
|
||||
rDest = rSrc;
|
||||
gDest = gSrc;
|
||||
bDest = bSrc;
|
||||
aDest = aSrc;
|
||||
rSrc = args.tintRed;
|
||||
gSrc = args.tintGreen;
|
||||
bSrc = args.tintBlue;
|
||||
aSrc = args.srcAlpha;
|
||||
} else {
|
||||
uint32 destCol = getColor(destVal, DestBytesPerPixel);
|
||||
if (DestBytesPerPixel == 1) {
|
||||
const RGB &rgb = args.palette[destCol];
|
||||
aDest = 0xff;
|
||||
rDest = rgb.r;
|
||||
gDest = rgb.g;
|
||||
bDest = rgb.b;
|
||||
} else {
|
||||
if (DestBytesPerPixel == 4) {
|
||||
aDest = destCol >> 24;
|
||||
rDest = (destCol >> 16) & 0xff;
|
||||
gDest = (destCol >> 8) & 0xff;
|
||||
bDest = destCol & 0xff;
|
||||
} else { // DestBytesPerPixel == 2
|
||||
aDest = 0xff;
|
||||
rDest = (destCol >> 11) & 0x1f;
|
||||
rDest = (rDest << 3) | (rDest >> 2);
|
||||
gDest = (destCol >> 5) & 0x3f;
|
||||
gDest = (gDest << 2) | (gDest >> 4);
|
||||
bDest = destCol & 0x1f;
|
||||
bDest = (bDest << 3) | (bDest >> 2);
|
||||
}
|
||||
//src.format.colorToARGB(srcCol, aSrc, rSrc, gSrc, bSrc);
|
||||
}
|
||||
}
|
||||
blendPixel(aSrc, rSrc, gSrc, bSrc, aDest, rDest, gDest, bDest, args.srcAlpha, args.useTint, destVal);
|
||||
}
|
||||
|
||||
uint32 pixel;// = format.ARGBToColor(aDest, rDest, gDest, bDest);
|
||||
if (DestBytesPerPixel == 4) {
|
||||
pixel = (aDest << 24) | (rDest << 16) | (gDest << 8) | (bDest);
|
||||
*(uint32 *)destVal = pixel;
|
||||
}
|
||||
else {
|
||||
pixel = ((rDest >> 3) << 11) | ((gDest >> 2) << 5) | (bDest >> 3);
|
||||
*(uint16 *)destVal = pixel;
|
||||
}
|
||||
}
|
||||
|
||||
destP += args.destArea.pitch;
|
||||
if (!Scale) srcP += args.vertFlip ? -args.src.pitch : args.src.pitch;
|
||||
}
|
||||
}
|
||||
|
||||
template<bool Scale>
|
||||
void BITMAP::drawGeneric(DrawInnerArgs &args) {
|
||||
if (args.sameFormat) {
|
||||
switch (format.bytesPerPixel) {
|
||||
case 1: drawInnerGeneric<1, 1, Scale>(args); break;
|
||||
case 2: drawInnerGeneric<2, 2, Scale>(args); break;
|
||||
case 4: drawInnerGeneric<4, 4, Scale>(args); break;
|
||||
}
|
||||
} else if (format.bytesPerPixel == 4 && args.src.format.bytesPerPixel == 2) {
|
||||
drawInnerGeneric<4, 2, Scale>(args);
|
||||
} else if (format.bytesPerPixel == 2 && args.src.format.bytesPerPixel == 4) {
|
||||
drawInnerGeneric<2, 4, Scale>(args);
|
||||
}
|
||||
}
|
||||
|
||||
template void BITMAP::drawGeneric<false>(DrawInnerArgs &);
|
||||
template void BITMAP::drawGeneric<true>(DrawInnerArgs &);
|
||||
template void BITMAP::drawInnerGeneric<4, 4, false>(DrawInnerArgs &);
|
||||
template void BITMAP::drawInnerGeneric<4, 4, true>(DrawInnerArgs &);
|
||||
template void BITMAP::drawInnerGeneric<4, 2, false>(DrawInnerArgs &);
|
||||
template void BITMAP::drawInnerGeneric<4, 2, true>(DrawInnerArgs &);
|
||||
template void BITMAP::drawInnerGeneric<2, 4, false>(DrawInnerArgs &);
|
||||
template void BITMAP::drawInnerGeneric<2, 4, true>(DrawInnerArgs &);
|
||||
template void BITMAP::drawInnerGeneric<4, 1, false>(DrawInnerArgs &);
|
||||
template void BITMAP::drawInnerGeneric<4, 1, true>(DrawInnerArgs &);
|
||||
template void BITMAP::drawInnerGeneric<2, 1, false>(DrawInnerArgs &);
|
||||
template void BITMAP::drawInnerGeneric<2, 1, true>(DrawInnerArgs &);
|
||||
|
||||
} // end of namespace AGS3
|
||||
Reference in New Issue
Block a user