aboutsummaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
authorJohannes Schickel2006-01-27 15:43:23 +0000
committerJohannes Schickel2006-01-27 15:43:23 +0000
commit5051b080a2cfefef81907be0324e229f284ae355 (patch)
treeaf2b67affe5aaf357c3278e3befdbd412dea5545 /graphics
parent901645cb0f28ef0278e5b5e3a7347a85f9142b8b (diff)
downloadscummvm-rg350-5051b080a2cfefef81907be0324e229f284ae355.tar.gz
scummvm-rg350-5051b080a2cfefef81907be0324e229f284ae355.tar.bz2
scummvm-rg350-5051b080a2cfefef81907be0324e229f284ae355.zip
- adds the new gui renderer also a new implementation for the classic gui
- adds a ImageMan and ImageDec class for loading and managing image files - adds a loader for zip files which is used by the new theme and the image manager - changes the widgets to use the new gui code - changes the scumm dialogs to use the new gui code - fixes a #include problem in the sky debugger with the new gui code To use the new gui copy gui/themes/default-theme.zip to your extrapath. If the theme zip can not be found the gui will fallback to the classic theme. If you want to change the gui styles use "gui_theme=classic" for the classic theme and "gui_theme=default-theme" for the new theme. Thanks to eriktorbjorn for testing and help with the new theme and to sev for reviewing this patch. svn-id: r20227
Diffstat (limited to 'graphics')
-rw-r--r--graphics/imagedec.cpp174
-rw-r--r--graphics/imagedec.h61
-rw-r--r--graphics/imageman.cpp146
-rw-r--r--graphics/imageman.h103
-rw-r--r--graphics/module.mk4
5 files changed, 487 insertions, 1 deletions
diff --git a/graphics/imagedec.cpp b/graphics/imagedec.cpp
new file mode 100644
index 0000000000..dd9bc588cd
--- /dev/null
+++ b/graphics/imagedec.cpp
@@ -0,0 +1,174 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * 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.
+ *
+ * $Header $
+ */
+
+#include "graphics/imagedec.h"
+
+#include "common/system.h"
+#include "common/file.h"
+
+namespace Graphics {
+//
+// BMP Decoder
+//
+class BMPDecoder : public ImageDecoder {
+public:
+ BMPDecoder() {}
+ virtual ~BMPDecoder() {}
+
+ bool decodeable(Common::SeekableReadStream &stream);
+ Surface *decodeImage(Common::SeekableReadStream &stream);
+
+ struct BitmapHeader {
+ uint16 type;
+ uint32 size;
+ uint16 res1;
+ uint16 res2;
+ uint32 imageOffset;
+ };
+
+ struct InfoHeader {
+ uint32 size;
+ uint32 width;
+ uint32 height;
+ uint16 planes;
+ uint16 bitsPerPixel;
+ uint32 compression;
+ uint32 imageSize;
+ uint32 pixelsPerMeterX;
+ uint32 pixelsPerMeterY;
+ uint32 colorsUsed;
+ uint32 colorsImportant;
+ };
+};
+
+bool BMPDecoder::decodeable(Common::SeekableReadStream &stream) {
+ BitmapHeader header;
+ stream.seek(0);
+ header.type = stream.readUint16BE();
+ header.size = stream.readUint32LE();
+
+ // TODO: maybe improve this detection
+ if (header.size == 0 || header.type != 'BM')
+ return false;
+
+ return true;
+}
+
+Surface *BMPDecoder::decodeImage(Common::SeekableReadStream &stream) {
+ if (!decodeable(stream)) {
+ return 0;
+ }
+
+ BitmapHeader header;
+ InfoHeader info;
+
+ stream.seek(0);
+ header.type = stream.readUint16BE();
+ header.size = stream.readUint32LE();
+ header.res1 = stream.readUint16LE();
+ header.res2 = stream.readUint16LE();
+ header.imageOffset = stream.readUint32LE();
+
+ if (header.size == 0 || header.type != 'BM') {
+ stream.seek(0);
+ return 0;
+ }
+
+ info.size = stream.readUint32LE();
+ info.width = stream.readUint32LE();
+ info.height = stream.readUint32LE();
+ info.planes = stream.readUint16LE();
+ info.bitsPerPixel = stream.readUint16LE();
+ info.compression = stream.readUint32LE();
+ info.imageSize = stream.readUint32LE();
+ info.pixelsPerMeterX = stream.readUint32LE();
+ info.pixelsPerMeterY = stream.readUint32LE();
+ info.colorsUsed = stream.readUint32LE();
+ info.colorsImportant = stream.readUint32LE();
+
+ stream.seek(header.imageOffset);
+
+ if (info.bitsPerPixel != 24) {
+ stream.seek(0);
+ return 0;
+ }
+
+ uint8 r = 0, g = 0, b = 0;
+ Surface *newSurf = new Surface;
+ assert(newSurf);
+ newSurf->create(info.width, info.height, sizeof(OverlayColor));
+ assert(newSurf->pixels);
+ OverlayColor *curPixel = (OverlayColor*)newSurf->pixels + (newSurf->h-1) * newSurf->w;
+ int pitchAdd = info.width % 4;
+ for (int i = 0; i < newSurf->h; ++i) {
+ for (int i2 = 0; i2 < newSurf->w; ++i2) {
+ b = stream.readByte();
+ g = stream.readByte();
+ r = stream.readByte();
+ *curPixel = OSystem::instance().RGBToColor(r, g, b);
+ ++curPixel;
+ }
+ stream.seek(pitchAdd, SEEK_CUR);
+ curPixel -= newSurf->w*2;
+ }
+
+ stream.seek(0);
+ return newSurf;
+}
+
+#pragma mark -
+
+Surface *ImageDecoder::loadFile(const Common::String &name) {
+ Surface *newSurf = 0;
+
+ Common::File imageFile;
+ if (imageFile.open(name.c_str())) {
+ newSurf = loadFile(imageFile);
+ }
+
+ return newSurf;
+}
+
+Surface *ImageDecoder::loadFile(Common::SeekableReadStream &stream) {
+ // TODO: implement support for bzipped memory
+
+ // FIXME: this is not a very nice solution but it should work
+ // for the moment, we should use a different way to get all
+ // decoders
+ static BMPDecoder bmpDecoder;
+ static ImageDecoder *decoderList[] = {
+ &bmpDecoder, // for uncompressed .BMP files
+ 0
+ };
+
+ ImageDecoder *decoder = 0;
+ for (int i = 0; decoderList[i] != 0; ++i) {
+ if (decoderList[i]->decodeable(stream)) {
+ decoder = decoderList[i];
+ break;
+ }
+ }
+
+ if (!decoder)
+ return 0;
+
+ return decoder->decodeImage(stream);
+}
+} // end of namespace Graphics
diff --git a/graphics/imagedec.h b/graphics/imagedec.h
new file mode 100644
index 0000000000..c59a458ff3
--- /dev/null
+++ b/graphics/imagedec.h
@@ -0,0 +1,61 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * 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.
+ *
+ * $Header $
+ */
+
+#ifndef GRAPHICS_IMAGEDEC_H
+#define GRAPHICS_IMAGEDEC_H
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "common/stream.h"
+
+#include "graphics/surface.h"
+
+namespace Graphics {
+class ImageDecoder {
+public:
+ ImageDecoder() {}
+ virtual ~ImageDecoder() {}
+
+ static Surface *loadFile(const Common::String &name);
+ static Surface *loadFile(Common::SeekableReadStream &stream);
+
+ /**
+ * checks if the data can be decoded by this decoder
+ *
+ * @param stream memory read stream
+ * @return true if it can be decoded, otherwise false
+ */
+ virtual bool decodeable(Common::SeekableReadStream &stream) = 0;
+
+ /**
+ * decodes the data and returns an pointer to the resulting surface.
+ * Surface::free() must be called by the user also it must be deleted
+ * with delete;
+ *
+ * @param stream the memory stream which should be decoded
+ * @return returns a new surface if the image could be decoded, otherwise 0
+ */
+ virtual Surface *decodeImage(Common::SeekableReadStream &stream) = 0;
+};
+} // end of namespace Graphics
+
+#endif
+
diff --git a/graphics/imageman.cpp b/graphics/imageman.cpp
new file mode 100644
index 0000000000..7e78b52279
--- /dev/null
+++ b/graphics/imageman.cpp
@@ -0,0 +1,146 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * 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.
+ *
+ * $Header $
+ */
+
+#include "graphics/imagedec.h"
+#include "graphics/imageman.h"
+#include "graphics/surface.h"
+
+DECLARE_SINGLETON(Graphics::ImageManager);
+
+namespace Graphics {
+ImageManager::ImageManager() : _surfaces()
+#ifdef USE_ZLIB
+, _archives()
+#endif
+{
+}
+
+ImageManager::~ImageManager() {
+ for (Iterator pos = _surfaces.begin(); pos != _surfaces.end(); ++pos) {
+ (*pos)->surface->free();
+ delete (*pos)->surface;
+ delete *pos;
+ *pos = 0;
+ }
+ _surfaces.clear();
+#ifdef USE_ZLIB
+ for (ZipIterator pos = _archives.begin(); pos != _archives.end(); ++pos) {
+ unzClose(*pos);
+ }
+ _archives.clear();
+#endif
+}
+
+bool ImageManager::addArchive(const Common::String &name) {
+#ifdef USE_ZLIB
+ unzFile newFile = unzOpen(name.c_str());
+ if (!newFile)
+ return false;
+ _archives.push_back(newFile);
+#endif
+ return true;
+}
+
+bool ImageManager::registerSurface(const Common::String &name, Surface *surf) {
+ if (getSurface(name)) {
+ return false;
+ }
+
+ Entry *newHandle = new Entry;
+ if (!newHandle)
+ return false;
+
+ if (!surf) {
+ surf = ImageDecoder::loadFile(name);
+ if (!surf) {
+#ifdef USE_ZLIB
+ ZipIterator file = _archives.end();
+ for (ZipIterator pos = _archives.begin(); pos != _archives.end(); ++pos) {
+ if (unzLocateFile(*pos, name.c_str(), 2) == UNZ_OK) {
+ file = pos;
+ break;
+ }
+ }
+
+ if (file == _archives.end())
+ return false;
+
+ unz_file_info fileInfo;
+ unzOpenCurrentFile(*file);
+ unzGetCurrentFileInfo(*file, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
+ uint8 *buffer = new uint8[fileInfo.uncompressed_size];
+ assert(buffer);
+ unzReadCurrentFile(*file, buffer, fileInfo.uncompressed_size);
+ unzCloseCurrentFile(*file);
+ Common::MemoryReadStream stream(buffer, fileInfo.uncompressed_size);
+ surf = ImageDecoder::loadFile(stream);
+ delete [] buffer;
+
+ if (!surf)
+ return false;
+#else
+ return false;
+#endif
+ }
+ }
+
+ newHandle->surface = surf;
+ newHandle->name = name;
+ _surfaces.push_back(newHandle);
+
+ return true;
+}
+
+bool ImageManager::unregisterSurface(const Common::String &name) {
+ Iterator pos = searchHandle(name);
+ if (pos == _surfaces.end()) {
+ // no surface handle it as success
+ return true;
+ }
+
+ (*pos)->surface->free();
+ delete (*pos)->surface;
+ delete *pos;
+ *pos = 0;
+
+ _surfaces.erase(pos);
+
+ return true;
+}
+
+Surface * ImageManager::getSurface(const Common::String &name) {
+ Iterator pos = searchHandle(name);
+ if (pos == _surfaces.end()) {
+ // no surface handle it as success
+ return 0;
+ }
+ return (*pos)->surface;
+}
+
+ImageManager::Iterator ImageManager::searchHandle(const Common::String &name) {
+ Iterator pos = _surfaces.begin();
+ while (pos != _surfaces.end()) {
+ if ((*pos)->name == name)
+ break;
+ ++pos;
+ }
+ return pos;
+}
+} // end of namespace Graphics
diff --git a/graphics/imageman.h b/graphics/imageman.h
new file mode 100644
index 0000000000..ff48701cce
--- /dev/null
+++ b/graphics/imageman.h
@@ -0,0 +1,103 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * 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.
+ *
+ * $Header $
+ */
+
+#ifndef GRAPHICS_IMAGEMAN_H
+#define GRAPHICS_IMAGEMAN_H
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/singleton.h"
+#include "common/str.h"
+#include "common/list.h"
+#include "common/unzip.h"
+
+namespace Graphics {
+struct Surface;
+
+class ImageManager : public Common::Singleton<ImageManager> {
+public:
+ ~ImageManager();
+
+ /**
+ * adds an .zip archive to the pool there the ImagaManager searches
+ * for image files
+ *
+ * @param name the name of the archive
+ * @return true on success and false on failure
+ */
+ bool addArchive(const Common::String &name);
+
+ /**
+ * registers a surface to the ImageManager.
+ * surf->free(), also delete surf, will be called when the ImageManager will
+ * be destroyed or if ImageManager::unregisterSurface is called.
+ * if the parameter 'surf' is 0 the Manger will try to load an image with
+ * the filename 'name'
+ *
+ * @param name the name of the new handle
+ * @param surf the surface which should be associated to the given name
+ * @return returns true on success and false on failure
+ */
+ bool registerSurface(const Common::String &name, Surface *surf);
+
+ /**
+ * unregisters a surface, after this the returned surface from
+ * getSurface should NOT be used anymore
+ *
+ * @param name the handle
+ * @return true on success, false on failure
+ */
+ bool unregisterSurface(const Common::String &name);
+
+ /**
+ * gets a surface registered to a handle
+ *
+ * @param name the name of the handle
+ * @return returns an pointer to an Surface object or 0 on failure
+ */
+ Surface *getSurface(const Common::String &name);
+private:
+ friend class Common::Singleton<SingletonBaseType>;
+ ImageManager();
+
+ struct Entry {
+ Common::String name;
+ Surface *surface;
+ };
+ typedef Common::List<Entry*>::iterator Iterator;
+#ifdef USE_ZLIB
+ typedef Common::List<unzFile>::iterator ZipIterator;
+#endif
+
+ Iterator searchHandle(const Common::String &name);
+
+ Common::List<Entry*> _surfaces;
+#ifdef USE_ZLIB
+ Common::List<unzFile> _archives;
+#endif
+};
+
+} // end of namespace Graphics
+
+/** Shortcut for accessing the font manager. */
+#define ImageMan (Graphics::ImageManager::instance())
+
+#endif
+
diff --git a/graphics/module.mk b/graphics/module.mk
index 4ff913d87c..66e63daf90 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -10,7 +10,9 @@ MODULE_OBJS := \
graphics/newfont_big.o \
graphics/primitives.o \
graphics/scummfont.o \
- graphics/surface.o
+ graphics/surface.o \
+ graphics/imageman.o \
+ graphics/imagedec.o
MODULE_DIRS += \
graphics