diff options
Diffstat (limited to 'engines/sword25/gfx/image')
-rw-r--r-- | engines/sword25/gfx/image/glimage.cpp | 395 | ||||
-rw-r--r-- | engines/sword25/gfx/image/glimage.h | 131 | ||||
-rw-r--r-- | engines/sword25/gfx/image/swimage.cpp | 135 | ||||
-rw-r--r-- | engines/sword25/gfx/image/swimage.h | 107 |
4 files changed, 768 insertions, 0 deletions
diff --git a/engines/sword25/gfx/image/glimage.cpp b/engines/sword25/gfx/image/glimage.cpp new file mode 100644 index 0000000000..73c6978efd --- /dev/null +++ b/engines/sword25/gfx/image/glimage.cpp @@ -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 diff --git a/engines/sword25/gfx/image/glimage.h b/engines/sword25/gfx/image/glimage.h new file mode 100644 index 0000000000..2b30cec718 --- /dev/null +++ b/engines/sword25/gfx/image/glimage.h @@ -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 diff --git a/engines/sword25/gfx/image/swimage.cpp b/engines/sword25/gfx/image/swimage.cpp new file mode 100644 index 0000000000..a6a6468f65 --- /dev/null +++ b/engines/sword25/gfx/image/swimage.cpp @@ -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 diff --git a/engines/sword25/gfx/image/swimage.h b/engines/sword25/gfx/image/swimage.h new file mode 100644 index 0000000000..caf6bdcc71 --- /dev/null +++ b/engines/sword25/gfx/image/swimage.h @@ -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 |