SWORD25: Moved glimage and swimage to image/

svn-id: r53357
This commit is contained in:
Eugene Sandulenko 2010-09-14 20:02:33 +00:00
parent 69cae2e7dd
commit 7dfea5ee4d
5 changed files with 770 additions and 2 deletions

View File

@ -0,0 +1,395 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
/*
* This code is based on Broken Sword 2.5 engine
*
* Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
*
* Licensed under GNU GPL v2
*
*/
// -----------------------------------------------------------------------------
// INCLUDES
// -----------------------------------------------------------------------------
#include "sword25/package/packagemanager.h"
#include "sword25/gfx/image/imageloader.h"
#include "sword25/gfx/opengl/openglgfx.h"
#include "sword25/gfx/opengl/glimage.h"
#include "common/system.h"
namespace Sword25 {
#define BS_LOG_PREFIX "GLIMAGE"
// -----------------------------------------------------------------------------
// CONSTRUCTION / DESTRUCTION
// -----------------------------------------------------------------------------
GLImage::GLImage(const Common::String &filename, bool &result) :
_data(0),
_width(0),
_height(0) {
result = false;
PackageManager *pPackage = static_cast<PackageManager *>(Kernel::GetInstance()->GetService("package"));
BS_ASSERT(pPackage);
_backSurface = (static_cast<GraphicEngine *>(Kernel::GetInstance()->GetService("gfx")))->getSurface();
// Datei laden
byte *pFileData;
uint fileSize;
if (!(pFileData = (byte *)pPackage->GetFile(filename, &fileSize))) {
BS_LOG_ERRORLN("File \"%s\" could not be loaded.", filename.c_str());
return;
}
// Bildeigenschaften bestimmen
GraphicEngine::COLOR_FORMATS colorFormat;
int pitch;
if (!ImageLoader::ExtractImageProperties(pFileData, fileSize, colorFormat, _width, _height)) {
BS_LOG_ERRORLN("Could not read image properties.");
delete[] pFileData;
return;
}
// Das Bild dekomprimieren
if (!ImageLoader::LoadImage(pFileData, fileSize, GraphicEngine::CF_ARGB32, _data, _width, _height, pitch)) {
BS_LOG_ERRORLN("Could not decode image.");
delete[] pFileData;
return;
}
// Dateidaten freigeben
delete[] pFileData;
_doCleanup = true;
result = true;
return;
}
// -----------------------------------------------------------------------------
GLImage::GLImage(uint width, uint height, bool &result) :
_width(width),
_height(height) {
_data = new byte[width * height * 4];
Common::set_to(_data, &_data[width * height * 4], 0);
_backSurface = (static_cast<GraphicEngine *>(Kernel::GetInstance()->GetService("gfx")))->getSurface();
_doCleanup = true;
result = true;
return;
}
GLImage::GLImage() : _width(0), _height(0), _data(0) {
_backSurface = (static_cast<GraphicEngine *>(Kernel::GetInstance()->GetService("gfx")))->getSurface();
_doCleanup = false;
return;
}
// -----------------------------------------------------------------------------
GLImage::~GLImage() {
if (_doCleanup)
delete[] _data;
}
// -----------------------------------------------------------------------------
bool GLImage::fill(const Common::Rect *pFillRect, uint color) {
BS_LOG_ERRORLN("Fill() is not supported.");
return false;
}
// -----------------------------------------------------------------------------
bool GLImage::setContent(const byte *pixeldata, uint size, uint offset, uint stride) {
// Überprüfen, ob PixelData ausreichend viele Pixel enthält um ein Bild der Größe Width * Height zu erzeugen
if (size < static_cast<uint>(_width * _height * 4)) {
BS_LOG_ERRORLN("PixelData vector is too small to define a 32 bit %dx%d image.", _width, _height);
return false;
}
const byte *in = &pixeldata[offset];
byte *out = _data;
for (int i = 0; i < _height; i++) {
memcpy(out, in, _width * 4);
out += _width * 4;
in += stride;
}
return true;
}
void GLImage::replaceContent(byte *pixeldata, int width, int height) {
_width = width;
_height = height;
_data = pixeldata;
}
// -----------------------------------------------------------------------------
uint GLImage::getPixel(int x, int y) {
BS_LOG_ERRORLN("GetPixel() is not supported. Returning black.");
return 0;
}
// -----------------------------------------------------------------------------
bool GLImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRect, uint color, int width, int height) {
int ca = (color >> 24) & 0xff;
// Check if we need to draw anything at all
if (ca == 0)
return true;
int cr = (color >> 16) & 0xff;
int cg = (color >> 8) & 0xff;
int cb = (color >> 0) & 0xff;
// Compensate for transparency. Since we're coming
// down to 255 alpha, we just compensate for the colors here
if (ca != 255) {
cr = cr * ca >> 8;
cg = cg * ca >> 8;
cb = cb * ca >> 8;
}
// Create an encapsulating surface for the data
Graphics::Surface srcImage;
srcImage.bytesPerPixel = 4;
srcImage.pitch = _width * 4;
srcImage.w = _width;
srcImage.h = _height;
srcImage.pixels = _data;
if (pPartRect) {
srcImage.pixels = &_data[pPartRect->top * srcImage.pitch + pPartRect->left * 4];
srcImage.w = pPartRect->right - pPartRect->left;
srcImage.h = pPartRect->bottom - pPartRect->top;
debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping,
pPartRect->left, pPartRect->top, pPartRect->width(), pPartRect->height(), color, width, height);
} else {
debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping, 0, 0,
srcImage.w, srcImage.h, color, width, height);
}
if (width == -1)
width = srcImage.w;
if (height == -1)
height = srcImage.h;
#ifdef SCALING_TESTING
// Hardcode scaling to 66% to test scaling
width = width * 2 / 3;
height = height * 2 / 3;
#endif
Graphics::Surface *img;
Graphics::Surface *imgScaled = NULL;
byte *savedPixels = NULL;
if ((width != srcImage.w) || (height != srcImage.h)) {
// Scale the image
img = imgScaled = scale(srcImage, width, height);
savedPixels = (byte *)img->pixels;
} else {
img = &srcImage;
}
// Handle off-screen clipping
if (posY < 0) {
img->h = MAX(0, (int)img->h - -posY);
img->pixels = (byte *)img->pixels + img->pitch * -posY;
posY = 0;
}
if (posX < 0) {
img->w = MAX(0, (int)img->w - -posX);
img->pixels = (byte *)img->pixels + (-posX * 4);
posX = 0;
}
img->w = CLIP((int)img->w, 0, (int)MAX((int)_backSurface->w - posX, 0));
img->h = CLIP((int)img->h, 0, (int)MAX((int)_backSurface->h - posY, 0));
if ((img->w > 0) && (img->h > 0)) {
int xp = 0, yp = 0;
int inStep = 4;
int inoStep = img->pitch;
if (flipping & Image::FLIP_V) {
inStep = -inStep;
xp = img->w - 1;
}
if (flipping & Image::FLIP_H) {
inoStep = -inoStep;
yp = img->h - 1;
}
byte *ino = (byte *)img->getBasePtr(xp, yp);
byte *outo = (byte *)_backSurface->getBasePtr(posX, posY);
byte *in, *out;
for (int i = 0; i < img->h; i++) {
out = outo;
in = ino;
for (int j = 0; j < img->w; j++) {
int r = in[0];
int g = in[1];
int b = in[2];
int a = in[3];
in += inStep;
switch (a) {
case 0: // Full transparency
out += 4;
break;
case 255: // Full opacity
if (cr != 255)
*out++ = (r * cr) >> 8;
else
*out++ = r;
if (cg != 255)
*out++ = (g * cg) >> 8;
else
*out++ = g;
if (cb != 255)
*out++ = (b * cb) >> 8;
else
*out++ = b;
*out++ = a;
break;
default: // alpha blending
if (cr != 255)
*out += ((r - *out) * a * cr) >> 16;
else
*out += ((r - *out) * a) >> 8;
out++;
if (cg != 255)
*out += ((g - *out) * a * cg) >> 16;
else
*out += ((g - *out) * a) >> 8;
out++;
if (cb != 255)
*out += ((b - *out) * a * cb) >> 16;
else
*out += ((b - *out) * a) >> 8;
out++;
*out = 255;
out++;
}
}
outo += _backSurface->pitch;
ino += inoStep;
}
g_system->copyRectToScreen((byte *)_backSurface->getBasePtr(posX, posY), _backSurface->pitch, posX, posY,
img->w, img->h);
}
if (imgScaled) {
imgScaled->pixels = savedPixels;
imgScaled->free();
delete imgScaled;
}
return true;
}
/**
* Scales a passed surface, creating a new surface with the result
* @param srcImage Source image to scale
* @param scaleFactor Scale amount. Must be between 0 and 1.0 (but not zero)
* @remarks Caller is responsible for freeing the returned surface
*/
Graphics::Surface *GLImage::scale(const Graphics::Surface &srcImage, int xSize, int ySize) {
Graphics::Surface *s = new Graphics::Surface();
s->create(xSize, ySize, srcImage.bytesPerPixel);
int *horizUsage = scaleLine(xSize, srcImage.w);
int *vertUsage = scaleLine(ySize, srcImage.h);
// Loop to create scaled version
for (int yp = 0; yp < ySize; ++yp) {
const byte *srcP = (const byte *)srcImage.getBasePtr(0, vertUsage[yp]);
byte *destP = (byte *)s->getBasePtr(0, yp);
for (int xp = 0; xp < xSize; ++xp) {
const byte *tempSrcP = srcP + (horizUsage[xp] * srcImage.bytesPerPixel);
for (int byteCtr = 0; byteCtr < srcImage.bytesPerPixel; ++byteCtr) {
*destP++ = *tempSrcP++;
}
}
}
// Delete arrays and return surface
delete[] horizUsage;
delete[] vertUsage;
return s;
}
/**
* Returns an array indicating which pixels of a source image horizontally or vertically get
* included in a scaled image
*/
int *GLImage::scaleLine(int size, int srcSize) {
int scale = 100 * size / srcSize;
assert(scale > 0);
int *v = new int[size];
Common::set_to(v, &v[size], 0);
int distCtr = 0;
int *destP = v;
for (int distIndex = 0; distIndex < srcSize; ++distIndex) {
distCtr += scale;
while (distCtr >= 100) {
assert(destP < &v[size]);
*destP++ = distIndex;
distCtr -= 100;
}
}
return v;
}
} // End of namespace Sword25

View File

@ -0,0 +1,131 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
/*
* This code is based on Broken Sword 2.5 engine
*
* Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
*
* Licensed under GNU GPL v2
*
*/
#ifndef SWORD25_GL_IMAGE_H
#define SWORD25_GL_IMAGE_H
// -----------------------------------------------------------------------------
// INCLUDES
// -----------------------------------------------------------------------------
#include "sword25/kernel/common.h"
#include "sword25/gfx/image/image.h"
#include "sword25/gfx/graphicengine.h"
namespace Sword25 {
// -----------------------------------------------------------------------------
// FORWARD DECLARATION
// -----------------------------------------------------------------------------
typedef void *GLS_Sprite;
// -----------------------------------------------------------------------------
// CLASS DEFINITION
// -----------------------------------------------------------------------------
class GLImage : public Image {
public:
GLImage(const Common::String &filename, bool &result);
/**
@brief Erzeugt ein leeres BS_GLImage
@param Width die Breite des zu erzeugenden Bildes.
@param Height die Höhe des zu erzeugenden Bildes
@param Result gibt dem Aufrufer bekannt, ob der Konstruktor erfolgreich ausgeführt wurde. Wenn es nach dem Aufruf false enthalten sollte,
dürfen keine Methoden am Objekt aufgerufen werden und das Objekt ist sofort zu zerstören.
*/
GLImage(uint width, uint height, bool &result);
GLImage();
virtual ~GLImage();
virtual int getWidth() const {
return _width;
}
virtual int getHeight() const {
return _height;
}
virtual GraphicEngine::COLOR_FORMATS getColorFormat() const {
return GraphicEngine::CF_ARGB32;
}
virtual bool blit(int posX = 0, int posY = 0,
int flipping = Image::FLIP_NONE,
Common::Rect *pPartRect = NULL,
uint color = BS_ARGB(255, 255, 255, 255),
int width = -1, int height = -1);
virtual bool fill(const Common::Rect *pFillRect, uint color);
virtual bool setContent(const byte *pixeldata, uint size, uint offset = 0, uint stride = 0);
void replaceContent(byte *pixeldata, int width, int height);
virtual uint getPixel(int x, int y);
virtual bool isBlitSource() const {
return true;
}
virtual bool isBlitTarget() const {
return false;
}
virtual bool isScalingAllowed() const {
return true;
}
virtual bool isFillingAllowed() const {
return false;
}
virtual bool isAlphaAllowed() const {
return true;
}
virtual bool isColorModulationAllowed() const {
return true;
}
virtual bool isSetContentAllowed() const {
return true;
}
static Graphics::Surface *scale(const Graphics::Surface &srcImage, int xSize, int ySize);
private:
byte *_data;
int _width;
int _height;
bool _doCleanup;
Graphics::Surface *_backSurface;
static int *scaleLine(int size, int srcSize);
};
} // End of namespace Sword25
#endif

View File

@ -0,0 +1,135 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
/*
* This code is based on Broken Sword 2.5 engine
*
* Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
*
* Licensed under GNU GPL v2
*
*/
// -----------------------------------------------------------------------------
// INCLUDES
// -----------------------------------------------------------------------------
#include "sword25/package/packagemanager.h"
#include "sword25/gfx/image/imageloader.h"
#include "sword25/gfx/opengl/swimage.h"
namespace Sword25 {
#define BS_LOG_PREFIX "SWIMAGE"
// -----------------------------------------------------------------------------
// CONSTRUCTION / DESTRUCTION
// -----------------------------------------------------------------------------
SWImage::SWImage(const Common::String &filename, bool &result) :
_imageDataPtr(0),
_width(0),
_height(0) {
result = false;
PackageManager *pPackage = static_cast<PackageManager *>(Kernel::GetInstance()->GetService("package"));
BS_ASSERT(pPackage);
// Datei laden
byte *pFileData;
uint fileSize;
if (!(pFileData = (byte *)pPackage->GetFile(filename, &fileSize))) {
BS_LOG_ERRORLN("File \"%s\" could not be loaded.", filename.c_str());
return;
}
// Bildeigenschaften bestimmen
GraphicEngine::COLOR_FORMATS colorFormat;
int pitch;
if (!ImageLoader::ExtractImageProperties(pFileData, fileSize, colorFormat, _width, _height)) {
BS_LOG_ERRORLN("Could not read image properties.");
return;
}
// Das Bild dekomprimieren
byte *pUncompressedData;
if (!ImageLoader::LoadImage(pFileData, fileSize, GraphicEngine::CF_ARGB32, pUncompressedData, _width, _height, pitch)) {
BS_LOG_ERRORLN("Could not decode image.");
return;
}
// Dateidaten freigeben
delete[] pFileData;
_imageDataPtr = (uint *)pUncompressedData;
result = true;
return;
}
// -----------------------------------------------------------------------------
SWImage::~SWImage() {
delete[] _imageDataPtr;
}
// -----------------------------------------------------------------------------
bool SWImage::blit(int posX, int posY,
int flipping,
Common::Rect *pPartRect,
uint color,
int width, int height) {
BS_LOG_ERRORLN("Blit() is not supported.");
return false;
}
// -----------------------------------------------------------------------------
bool SWImage::fill(const Common::Rect *pFillRect, uint color) {
BS_LOG_ERRORLN("Fill() is not supported.");
return false;
}
// -----------------------------------------------------------------------------
bool SWImage::setContent(const byte *pixeldata, uint size, uint offset, uint stride) {
BS_LOG_ERRORLN("SetContent() is not supported.");
return false;
}
// -----------------------------------------------------------------------------
uint SWImage::getPixel(int x, int y) {
BS_ASSERT(x >= 0 && x < _width);
BS_ASSERT(y >= 0 && y < _height);
return _imageDataPtr[_width * y + x];
}
} // End of namespace Sword25

View File

@ -0,0 +1,107 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
/*
* This code is based on Broken Sword 2.5 engine
*
* Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
*
* Licensed under GNU GPL v2
*
*/
#ifndef SWORD25_SWIMAGE_H
#define SWORD25_SWIMAGE_H
// -----------------------------------------------------------------------------
// INCLUDES
// -----------------------------------------------------------------------------
#include "sword25/kernel/common.h"
#include "sword25/gfx/image/image.h"
#include "sword25/gfx/graphicengine.h"
namespace Sword25 {
// -----------------------------------------------------------------------------
// CLASS DEFINITION
// -----------------------------------------------------------------------------
class SWImage : public Image {
public:
SWImage(const Common::String &filename, bool &result);
virtual ~SWImage();
virtual int getWidth() const {
return _width;
}
virtual int getHeight() const {
return _height;
}
virtual GraphicEngine::COLOR_FORMATS getColorFormat() const {
return GraphicEngine::CF_ARGB32;
}
virtual bool blit(int posX = 0, int posY = 0,
int flipping = Image::FLIP_NONE,
Common::Rect *pPartRect = NULL,
uint color = BS_ARGB(255, 255, 255, 255),
int width = -1, int height = -1);
virtual bool fill(const Common::Rect *fillRectPtr, uint color);
virtual bool setContent(const byte *pixeldata, uint size, uint offset, uint stride);
virtual uint getPixel(int x, int y);
virtual bool isBlitSource() const {
return false;
}
virtual bool isBlitTarget() const {
return false;
}
virtual bool isScalingAllowed() const {
return false;
}
virtual bool isFillingAllowed() const {
return false;
}
virtual bool isAlphaAllowed() const {
return false;
}
virtual bool isColorModulationAllowed() const {
return false;
}
virtual bool isSetContentAllowed() const {
return false;
}
private:
uint *_imageDataPtr;
int _width;
int _height;
};
} // End of namespace Sword25
#endif

View File

@ -28,8 +28,10 @@ MODULE_OBJS := \
gfx/text.o \ gfx/text.o \
gfx/timedrenderobject.o \ gfx/timedrenderobject.o \
gfx/image/b25sloader.o \ gfx/image/b25sloader.o \
gfx/image/glimage.o \
gfx/image/imageloader.o \ gfx/image/imageloader.o \
gfx/image/pngloader.o \ gfx/image/pngloader.o \
gfx/image/swimage.o \
gfx/image/vectorimage.o \ gfx/image/vectorimage.o \
gfx/image/vectorimagerenderer.o \ gfx/image/vectorimagerenderer.o \
gfx/image/art.o \ gfx/image/art.o \
@ -38,8 +40,6 @@ MODULE_OBJS := \
gfx/image/art_svp_vpath.o \ gfx/image/art_svp_vpath.o \
gfx/image/art_svp_vpath_stroke.o \ gfx/image/art_svp_vpath_stroke.o \
gfx/image/art_vpath_bpath.o \ gfx/image/art_vpath_bpath.o \
gfx/opengl/glimage.o \
gfx/opengl/swimage.o \
input/inputengine.o \ input/inputengine.o \
input/inputengine_script.o \ input/inputengine_script.o \
kernel/callbackregistry.o \ kernel/callbackregistry.o \