aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEinar Johan Trøan Sømåen2012-06-18 19:11:15 +0200
committerEinar Johan Trøan Sømåen2012-06-18 19:11:15 +0200
commit06e8306aab6458e01b4356b6afa95544c64eae9d (patch)
tree27fc21f66a2650cd89dd9ad53fc9a07102bb3a76
parentece5997fc3cd4e9fcab6062d6959720129a7aeab (diff)
downloadscummvm-rg350-06e8306aab6458e01b4356b6afa95544c64eae9d.tar.gz
scummvm-rg350-06e8306aab6458e01b4356b6afa95544c64eae9d.tar.bz2
scummvm-rg350-06e8306aab6458e01b4356b6afa95544c64eae9d.zip
WINTERMUTE: Add savegame-thumbnail-support.
-rw-r--r--engines/wintermute/Base/BImage.cpp98
-rw-r--r--engines/wintermute/Base/BImage.h6
-rw-r--r--engines/wintermute/Base/BPersistMgr.cpp12
-rw-r--r--engines/wintermute/Base/BRenderSDL.cpp3
4 files changed, 110 insertions, 9 deletions
diff --git a/engines/wintermute/Base/BImage.cpp b/engines/wintermute/Base/BImage.cpp
index 31c05226f5..6076b09963 100644
--- a/engines/wintermute/Base/BImage.cpp
+++ b/engines/wintermute/Base/BImage.cpp
@@ -32,6 +32,7 @@
#include "engines/wintermute/Base/BGame.h"
#include "engines/wintermute/Base/BFileManager.h"
#include "engines/wintermute/graphics/transparentSurface.h"
+#include "engines/wintermute/utils/StringUtil.h"
#include "graphics/decoders/png.h"
#include "graphics/decoders/jpeg.h"
#include "graphics/decoders/bmp.h"
@@ -52,6 +53,7 @@ CBImage::CBImage(CBGame *inGame, FIBITMAP *bitmap): CBBase(inGame) {
_palette = NULL;
_surface = NULL;
_decoder = NULL;
+ _deletableSurface = NULL;
}
@@ -59,6 +61,7 @@ CBImage::CBImage(CBGame *inGame, FIBITMAP *bitmap): CBBase(inGame) {
CBImage::~CBImage() {
/* delete _bitmap; */
delete _decoder;
+ delete _deletableSurface;
#if 0
if (_bitmap) FreeImage_Unload(_bitmap);
#endif
@@ -66,8 +69,10 @@ CBImage::~CBImage() {
HRESULT CBImage::loadFile(const Common::String &filename) {
_filename = filename;
-
- if (filename.hasSuffix(".png")) {
+
+ if (StringUtil::StartsWith(filename, "savegame:", true)) {
+ _decoder = new Graphics::BitmapDecoder();
+ } else if (filename.hasSuffix(".png")) {
_decoder = new Graphics::PNGDecoder();
} else if (filename.hasSuffix(".bmp")) {
_decoder = new Graphics::BitmapDecoder();
@@ -98,6 +103,11 @@ byte CBImage::getAlphaAt(int x, int y) {
return a;
}
+void CBImage::copyFrom(Graphics::Surface *surface) {
+ _surface = _deletableSurface = new Graphics::Surface();
+ _deletableSurface->copyFrom(*surface);
+}
+
//////////////////////////////////////////////////////////////////////////
HRESULT CBImage::SaveBMPFile(const char *Filename) {
#if 0
@@ -131,8 +141,81 @@ HRESULT CBImage::Resize(int NewWidth, int NewHeight) {
//////////////////////////////////////////////////////////////////////////
-byte *CBImage::CreateBMPBuffer(uint32 *BufferSize) {
- if (!_bitmap) return NULL;
+bool CBImage::writeBMPToStream(Common::WriteStream *stream) {
+ if (!_surface) return NULL;
+
+ /* The following is just copied over and inverted to write-ops from the BMP-decoder */
+ stream->writeByte('B');
+ stream->writeByte('M');
+
+ /* Since we don't care during reads, we don't care during writes: */
+ /* uint32 fileSize = */ stream->writeUint32LE(0);
+ /* uint16 res1 = */ stream->writeUint16LE(0);
+ /* uint16 res2 = */ stream->writeUint16LE(0);
+ const uint32 imageOffset = 54;
+ stream->writeUint32LE(imageOffset);
+
+ const uint32 infoSize = 40; /* Windows v3 BMP */
+ stream->writeUint32LE(infoSize);
+
+ uint32 width = _surface->w;
+ int32 height = _surface->h;
+ stream->writeUint32LE(width);
+ stream->writeUint32LE(height);
+
+ if (width == 0 || height == 0)
+ return false;
+
+ if (height < 0) {
+ warning("Right-side up bitmaps not supported");
+ return false;
+ }
+
+ /* uint16 planes = */ stream->writeUint16LE(0);
+ const uint16 bitsPerPixel = 24;
+ stream->writeUint16LE(bitsPerPixel);
+
+ const uint32 compression = 0;
+ stream->writeUint32LE(compression);
+
+ /* uint32 imageSize = */ stream->writeUint32LE(0);
+ /* uint32 pixelsPerMeterX = */ stream->writeUint32LE(0);
+ /* uint32 pixelsPerMeterY = */ stream->writeUint32LE(0);
+ const uint32 paletteColorCount = 0;
+ stream->writeUint32LE(paletteColorCount);
+ /* uint32 colorsImportant = */ stream->writeUint32LE(0);
+
+ // Start us at the beginning of the image (54 bytes in)
+ Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
+
+ // BGRA for 24bpp
+ if (bitsPerPixel == 24)
+ format = Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0);
+
+ Graphics::Surface *surface = _surface->convertTo(format);
+
+ int srcPitch = width * (bitsPerPixel >> 3);
+ const int extraDataLength = (srcPitch % 4) ? 4 - (srcPitch % 4) : 0;
+
+ for (int32 i = height - 1; i >= 0; i--) {
+ for (uint32 j = 0; j < width; j++) {
+ byte b,g,r;
+ uint32 color = *(uint32*)surface->getBasePtr(j, i);
+ surface->format.colorToRGB(color, r, g, b);
+ stream->writeByte(b);
+ stream->writeByte(g);
+ stream->writeByte(r);
+ }
+
+ for (int k = 0; k < extraDataLength; k++) {
+ stream->writeByte(0);
+ }
+ }
+ surface->free();
+ delete surface;
+ return true;
+
+ //*BufferSize = 0;
#if 0
FIMEMORY *fiMem = FreeImage_OpenMemory();
FreeImage_SaveToMemory(FIF_PNG, _bitmap, fiMem);
@@ -164,6 +247,13 @@ HRESULT CBImage::CopyFrom(CBImage *OrigImage, int NewWidth, int NewHeight) {
_bitmap = FreeImage_Rescale(OrigImage->GetBitmap(), NewWidth, NewHeight, FILTER_BILINEAR);
#endif
+ TransparentSurface temp(*OrigImage->_surface, false);
+ if (_deletableSurface) {
+ _deletableSurface->free();
+ delete _deletableSurface;
+ _deletableSurface = NULL;
+ }
+ _surface = _deletableSurface = temp.scale(NewWidth, NewHeight);
return S_OK;
}
diff --git a/engines/wintermute/Base/BImage.h b/engines/wintermute/Base/BImage.h
index 90d684d01a..1161c97fa5 100644
--- a/engines/wintermute/Base/BImage.h
+++ b/engines/wintermute/Base/BImage.h
@@ -35,6 +35,7 @@
#include "graphics/decoders/image_decoder.h"
#include "common/endian.h"
#include "common/str.h"
+#include "common/stream.h"
struct FIBITMAP;
@@ -50,16 +51,17 @@ public:
const Graphics::Surface *getSurface() const { return _surface; };
const byte *getPalette() const { return _palette; }
byte getAlphaAt(int x, int y);
- byte *CreateBMPBuffer(uint32 *BufferSize = NULL);
+ bool writeBMPToStream(Common::WriteStream *stream);
HRESULT Resize(int NewWidth, int NewHeight);
HRESULT SaveBMPFile(const char *Filename);
HRESULT CopyFrom(CBImage *OrigImage, int NewWidth = 0, int NewHeight = 0);
-
+ void copyFrom(Graphics::Surface *surface);
private:
Common::String _filename;
Graphics::ImageDecoder *_decoder;
FIBITMAP *_bitmap;
const Graphics::Surface *_surface;
+ Graphics::Surface *_deletableSurface;
const byte *_palette;
};
diff --git a/engines/wintermute/Base/BPersistMgr.cpp b/engines/wintermute/Base/BPersistMgr.cpp
index 92307093ee..346a8bfa59 100644
--- a/engines/wintermute/Base/BPersistMgr.cpp
+++ b/engines/wintermute/Base/BPersistMgr.cpp
@@ -165,11 +165,17 @@ HRESULT CBPersistMgr::InitSave(const char *Desc) {
if (Game->_cachedThumbnail) {
if (Game->_cachedThumbnail->_thumbnail) {
uint32 Size = 0;
- byte *Buffer = Game->_cachedThumbnail->_thumbnail->CreateBMPBuffer(&Size);
+ Common::MemoryWriteStreamDynamic thumbStream(DisposeAfterUse::YES);
+ if (Game->_cachedThumbnail->_thumbnail->writeBMPToStream(&thumbStream)) {
+ _saveStream->writeUint32LE(thumbStream.size());
+ _saveStream->write(thumbStream.getData(), thumbStream.size());
+ } else {
+ _saveStream->writeUint32LE(0);
+ }
- PutDWORD(Size);
+/* PutDWORD(Size);
if (Size > 0) _saveStream->write(Buffer, Size);
- delete [] Buffer;
+ delete [] Buffer;*/
ThumbnailOK = true;
}
}
diff --git a/engines/wintermute/Base/BRenderSDL.cpp b/engines/wintermute/Base/BRenderSDL.cpp
index 86aa518de2..83adca59f3 100644
--- a/engines/wintermute/Base/BRenderSDL.cpp
+++ b/engines/wintermute/Base/BRenderSDL.cpp
@@ -399,6 +399,9 @@ HRESULT CBRenderSDL::DrawLine(int X1, int Y1, int X2, int Y2, uint32 Color) {
CBImage *CBRenderSDL::TakeScreenshot() {
// TODO: Fix this
warning("CBRenderSDL::TakeScreenshot() - not ported yet");
+ CBImage *screenshot = new CBImage(Game);
+ screenshot->copyFrom(_renderSurface);
+ return screenshot;
#if 0
SDL_Rect viewport;