aboutsummaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
authorMatthew Hoops2011-03-04 23:17:57 -0500
committerMatthew Hoops2011-03-04 23:17:57 -0500
commitc66233f83e2d86b72f45aff20fb3198976850e42 (patch)
tree23d5e007641fe950eea3d89fc0b538902699c36f /graphics
parent550cff84f81f016a2b54700e170b4cd9712793f3 (diff)
downloadscummvm-rg350-c66233f83e2d86b72f45aff20fb3198976850e42.tar.gz
scummvm-rg350-c66233f83e2d86b72f45aff20fb3198976850e42.tar.bz2
scummvm-rg350-c66233f83e2d86b72f45aff20fb3198976850e42.zip
GRAPHICS: Split the NE cursor code from the NEResources class
Now the code lies in Graphics and all cursors are not cached upon opening an exe. The engine is now in charge of caching which cursors it wants.
Diffstat (limited to 'graphics')
-rw-r--r--graphics/module.mk3
-rw-r--r--graphics/wincursor.cpp235
-rw-r--r--graphics/wincursor.h94
3 files changed, 331 insertions, 1 deletions
diff --git a/graphics/module.mk b/graphics/module.mk
index c962f0617d..cb3a07e691 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -23,7 +23,8 @@ MODULE_OBJS := \
surface.o \
thumbnail.o \
VectorRenderer.o \
- VectorRendererSpec.o
+ VectorRendererSpec.o \
+ wincursor.o
ifdef USE_SCALERS
MODULE_OBJS += \
diff --git a/graphics/wincursor.cpp b/graphics/wincursor.cpp
new file mode 100644
index 0000000000..68b4023c0a
--- /dev/null
+++ b/graphics/wincursor.cpp
@@ -0,0 +1,235 @@
+/* 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$
+ *
+ */
+
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/memstream.h"
+#include "common/str.h"
+#include "common/stream.h"
+#include "common/winexe_ne.h"
+
+#include "graphics/wincursor.h"
+
+namespace Graphics {
+
+WinCursor::WinCursor() {
+ _width = 0;
+ _height = 0;
+ _hotspotX = 0;
+ _hotspotY = 0;
+ _surface = 0;
+ _keyColor = 0;
+ memset(_palette, 0, 256 * 3);
+}
+
+WinCursor::~WinCursor() {
+ clear();
+}
+
+uint16 WinCursor::getWidth() const {
+ return _width;
+}
+
+uint16 WinCursor::getHeight() const {
+ return _height;
+}
+
+uint16 WinCursor::getHotspotX() const {
+ return _hotspotX;
+}
+
+uint16 WinCursor::getHotspotY() const {
+ return _hotspotY;
+}
+
+byte WinCursor::getKeyColor() const {
+ return _keyColor;
+}
+
+bool WinCursor::readFromStream(Common::SeekableReadStream &stream) {
+ clear();
+
+ _hotspotX = stream.readUint16LE();
+ _hotspotY = stream.readUint16LE();
+
+ // Check header size
+ if (stream.readUint32LE() != 40)
+ return false;
+
+ // Check dimensions
+ _width = stream.readUint32LE();
+ _height = stream.readUint32LE() / 2;
+
+ // Color planes
+ if (stream.readUint16LE() != 1)
+ return false;
+ // Bits per pixel
+ if (stream.readUint16LE() != 1)
+ return false;
+ // Compression
+ if (stream.readUint32LE() != 0)
+ return false;
+
+ // Image size + X resolution + Y resolution
+ stream.skip(12);
+
+ uint32 numColors = stream.readUint32LE();
+
+ if (numColors == 0)
+ numColors = 2;
+ else if (numColors > 2)
+ return false;
+
+ // Sanity check: ensure that enough data is there for the whole cursor
+ if ((uint32)(stream.size() - stream.pos()) < 40 + numColors * 4 + _width * _height * 2 / 8)
+ return false;
+
+ // Standard palette: transparent, black, white
+ _palette[6] = 0xff;
+ _palette[7] = 0xff;
+ _palette[8] = 0xff;
+
+ // Reading the palette
+ stream.seek(40 + 4);
+ for (uint32 i = 0 ; i < numColors; i++) {
+ _palette[(i + 1) * 3 + 2] = stream.readByte();
+ _palette[(i + 1) * 3 + 1] = stream.readByte();
+ _palette[(i + 1) * 3 + 0] = stream.readByte();
+ stream.readByte();
+ }
+
+ // Reading the bitmap data
+ uint32 dataSize = stream.size() - stream.pos();
+ byte *initialSource = new byte[dataSize];
+ stream.read(initialSource, dataSize);
+ const byte *srcP = initialSource;
+ const byte *srcM = srcP + ((_width * _height) / 8);
+
+ _surface = new byte[_width * _height];
+ byte *dest = _surface + _width * (_height - 1);
+
+ for (uint32 i = 0; i < _height; i++) {
+ byte *rowDest = dest;
+
+ for (uint32 j = 0; j < (_width / 8); j++) {
+ byte p = srcP[j];
+ byte m = srcM[j];
+
+ for (int k = 0; k < 8; k++, rowDest++, p <<= 1, m <<= 1) {
+ if ((m & 0x80) != 0x80) {
+ if ((p & 0x80) == 0x80)
+ *rowDest = 2;
+ else
+ *rowDest = 1;
+ } else
+ *rowDest = _keyColor;
+ }
+ }
+
+ dest -= _width;
+ srcP += _width / 8;
+ srcM += _width / 8;
+ }
+
+ delete[] initialSource;
+ return true;
+}
+
+void WinCursor::clear() {
+ delete[] _surface; _surface = 0;
+}
+
+WinCursorGroup::WinCursorGroup() {
+}
+
+WinCursorGroup::~WinCursorGroup() {
+ for (uint32 i = 0; i < cursors.size(); i++)
+ delete cursors[i].cursor;
+}
+
+WinCursorGroup *WinCursorGroup::createCursorGroup(Common::NEResources &exe, const Common::WinResourceID &id) {
+ Common::SeekableReadStream *stream = exe.getResource(Common::kNEGroupCursor, id);
+
+ if (!stream || stream->size() <= 6)
+ return 0;
+
+ stream->skip(4);
+ uint32 cursorCount = stream->readUint16LE();
+ if ((uint32)stream->size() < (6 + cursorCount * 16))
+ return 0;
+
+ WinCursorGroup *group = new WinCursorGroup();
+ group->cursors.reserve(cursorCount);
+
+ for (uint32 i = 0; i < cursorCount; i++) {
+ stream->readUint16LE(); // width
+ stream->readUint16LE(); // height
+
+ // Plane count
+ if (stream->readUint16LE() != 1) {
+ delete stream;
+ delete group;
+ return 0;
+ }
+
+ // Bit count
+ if (stream->readUint16LE() != 1) {
+ delete stream;
+ delete group;
+ return 0;
+ }
+
+ stream->readUint32LE(); // data size
+ uint32 cursorId = stream->readUint32LE();
+
+ Common::SeekableReadStream *cursorStream = exe.getResource(Common::kNECursor, cursorId);
+ if (!cursorStream) {
+ delete stream;
+ delete group;
+ return 0;
+ }
+
+ WinCursor *cursor = new WinCursor();
+ if (!cursor->readFromStream(*cursorStream)) {
+ delete stream;
+ delete cursorStream;
+ delete cursor;
+ delete group;
+ return 0;
+ }
+
+ delete cursorStream;
+
+ CursorItem item;
+ item.id = cursorId;
+ item.cursor = cursor;
+ group->cursors.push_back(item);
+ }
+
+ delete stream;
+ return group;
+}
+
+} // End of namespace Graphics
diff --git a/graphics/wincursor.h b/graphics/wincursor.h
new file mode 100644
index 0000000000..3e2fc55bb8
--- /dev/null
+++ b/graphics/wincursor.h
@@ -0,0 +1,94 @@
+/* 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$
+ *
+ */
+
+#ifndef GRAPHICS_WINCURSOR_H
+#define GRAPHICS_WINCURSOR_H
+
+#include "common/array.h"
+#include "common/winexe.h"
+
+namespace Common {
+ class NEResources;
+ class PEResources;
+ class SeekableReadStream;
+}
+
+namespace Graphics {
+
+/** A Windows cursor. */
+class WinCursor {
+public:
+ WinCursor();
+ ~WinCursor();
+
+ /** Return the cursor's width. */
+ uint16 getWidth() const;
+ /** Return the cursor's height. */
+ uint16 getHeight() const;
+ /** Return the cursor's hotspot's x coordinate. */
+ uint16 getHotspotX() const;
+ /** Return the cursor's hotspot's y coordinate. */
+ uint16 getHotspotY() const;
+ /** Return the cursor's transparent key. */
+ byte getKeyColor() const;
+
+ const byte *getSurface() const { return _surface; }
+ const byte *getPalette() const { return _palette; }
+
+ /** Read the cursor's data out of a stream. */
+ bool readFromStream(Common::SeekableReadStream &stream);
+
+private:
+ byte *_surface;
+ byte _palette[256 * 3];
+
+ uint16 _width; ///< The cursor's width.
+ uint16 _height; ///< The cursor's height.
+ uint16 _hotspotX; ///< The cursor's hotspot's x coordinate.
+ uint16 _hotspotY; ///< The cursor's hotspot's y coordinate.
+ byte _keyColor; ///< The cursor's transparent key
+
+ /** Clear the cursor. */
+ void clear();
+};
+
+struct WinCursorGroup {
+ WinCursorGroup();
+ ~WinCursorGroup();
+
+ struct CursorItem {
+ Common::WinResourceID id;
+ WinCursor *cursor;
+ };
+
+ Common::Array<CursorItem> cursors;
+
+ static WinCursorGroup *createCursorGroup(Common::NEResources &exe, const Common::WinResourceID &id);
+ //static WinCursorGroup *createCursorGroup(Common::PEResources &exe, const Common::WinResourceID &id);
+};
+
+} // End of namespace Graphics
+
+#endif