From a2a0b13de2cd6fb28787b2821466f3ef7c2210ea Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Tue, 22 Feb 2011 20:01:19 -0500 Subject: COMMON: Begin to merge some NE/PE code The ID classes are now common to both. The files have been renamed to better illustrate their purpose. --- graphics/fonts/winfont.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'graphics') diff --git a/graphics/fonts/winfont.cpp b/graphics/fonts/winfont.cpp index fb37c8ddef..449a1de83e 100644 --- a/graphics/fonts/winfont.cpp +++ b/graphics/fonts/winfont.cpp @@ -23,8 +23,8 @@ */ #include "common/file.h" -#include "common/ne_exe.h" #include "common/str.h" +#include "common/winexe_ne.h" #include "graphics/fonts/winfont.h" namespace Graphics { -- cgit v1.2.3 From 550cff84f81f016a2b54700e170b4cd9712793f3 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Wed, 23 Feb 2011 13:52:12 -0500 Subject: GRAPHICS: Add support for PE FON files This hopefully will work out of the box, but requires testing --- graphics/fonts/winfont.cpp | 87 ++++++++++++++++++++++++++++++++++------------ graphics/fonts/winfont.h | 4 +++ 2 files changed, 69 insertions(+), 22 deletions(-) (limited to 'graphics') diff --git a/graphics/fonts/winfont.cpp b/graphics/fonts/winfont.cpp index 449a1de83e..bdb6133695 100644 --- a/graphics/fonts/winfont.cpp +++ b/graphics/fonts/winfont.cpp @@ -25,6 +25,7 @@ #include "common/file.h" #include "common/str.h" #include "common/winexe_ne.h" +#include "common/winexe_pe.h" #include "graphics/fonts/winfont.h" namespace Graphics { @@ -75,8 +76,15 @@ static WinFontDirEntry readDirEntry(Common::SeekableReadStream &stream) { } bool WinFont::loadFromFON(const Common::String &fileName, const WinFontDirEntry &dirEntry) { - // TODO: PE libraries (If it's used anywhere by a ScummVM game) + // First try loading via the NE code + if (loadFromNE(fileName, dirEntry)) + return true; + // Then try loading via the PE code + return loadFromPE(fileName, dirEntry); +} + +bool WinFont::loadFromNE(const Common::String &fileName, const WinFontDirEntry &dirEntry) { Common::NEResources exe; if (!exe.loadFromEXE(fileName)) @@ -89,44 +97,53 @@ bool WinFont::loadFromFON(const Common::String &fileName, const WinFontDirEntry return false; } - uint16 numFonts = fontDirectory->readUint16LE(); + uint32 fontId = getFontIndex(*fontDirectory, dirEntry); + + delete fontDirectory; - // Probably not possible, so this is really a sanity check - if (numFonts == 0) { - warning("No fonts in '%s'", fileName.c_str()); + // Couldn't match the face name + if (fontId == 0xffffffff) { + warning("Could not find face '%s' in '%s'", dirEntry.faceName.c_str(), fileName.c_str()); return false; } - // Scour the directory for our matching name - int fontId = -1; - for (uint16 i = 0; i < numFonts; i++) { - uint16 id = fontDirectory->readUint16LE(); + // Actually go get our font now... + Common::SeekableReadStream *fontStream = exe.getResource(Common::kNEFont, fontId); + if (!fontStream) { + warning("Could not find font %d in %s", fontId, fileName.c_str()); + return false; + } - if (dirEntry.faceName.empty()) { - // Use the first name when empty - fontId = id; - break; - } + bool ok = loadFromFNT(*fontStream); + delete fontStream; + return ok; +} - WinFontDirEntry entry = readDirEntry(*fontDirectory); +bool WinFont::loadFromPE(const Common::String &fileName, const WinFontDirEntry &dirEntry) { + Common::PEResources exe; - if (dirEntry.faceName.equalsIgnoreCase(entry.faceName) && dirEntry.points == entry.points) { - // Match! - fontId = id; - break; - } + if (!exe.loadFromEXE(fileName)) + return false; + + // Let's pull out the font directory + Common::SeekableReadStream *fontDirectory = exe.getResource(Common::kPEFontDir, Common::String("FONTDIR")); + if (!fontDirectory) { + warning("No font directory in '%s'", fileName.c_str()); + return false; } + uint32 fontId = getFontIndex(*fontDirectory, dirEntry); + delete fontDirectory; // Couldn't match the face name - if (fontId < 0) { + if (fontId == 0xffffffff) { warning("Could not find face '%s' in '%s'", dirEntry.faceName.c_str(), fileName.c_str()); return false; } // Actually go get our font now... - Common::SeekableReadStream *fontStream = exe.getResource(Common::kNEFont, fontId); + Common::SeekableReadStream *fontStream = exe.getResource(Common::kPEFont, fontId); if (!fontStream) { warning("Could not find font %d in %s", fontId, fileName.c_str()); return false; @@ -137,6 +154,32 @@ bool WinFont::loadFromFON(const Common::String &fileName, const WinFontDirEntry return ok; } +uint32 WinFont::getFontIndex(Common::SeekableReadStream &stream, const WinFontDirEntry &dirEntry) { + uint16 numFonts = stream.readUint16LE(); + + // Probably not possible, so this is really a sanity check + if (numFonts == 0) { + warning("No fonts in exe"); + return 0xffffffff; + } + + // Scour the directory for our matching name + for (uint16 i = 0; i < numFonts; i++) { + uint16 id = stream.readUint16LE(); + + // Use the first name when empty + if (dirEntry.faceName.empty()) + return id; + + WinFontDirEntry entry = readDirEntry(stream); + + if (dirEntry.faceName.equalsIgnoreCase(entry.faceName) && dirEntry.points == entry.points) // Match! + return id; + } + + return 0xfffffff; +} + bool WinFont::loadFromFNT(const Common::String &fileName) { Common::File file; diff --git a/graphics/fonts/winfont.h b/graphics/fonts/winfont.h index b23455e2d5..fbe4a778e2 100644 --- a/graphics/fonts/winfont.h +++ b/graphics/fonts/winfont.h @@ -69,6 +69,10 @@ public: void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const; private: + bool loadFromPE(const Common::String &fileName, const WinFontDirEntry &dirEntry); + bool loadFromNE(const Common::String &fileName, const WinFontDirEntry &dirEntry); + + uint32 getFontIndex(Common::SeekableReadStream &stream, const WinFontDirEntry &dirEntry); bool loadFromFNT(Common::SeekableReadStream &stream); char indexToCharacter(uint16 index) const; uint16 characterToIndex(byte character) const; -- cgit v1.2.3 From c66233f83e2d86b72f45aff20fb3198976850e42 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Fri, 4 Mar 2011 23:17:57 -0500 Subject: 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. --- graphics/module.mk | 3 +- graphics/wincursor.cpp | 235 +++++++++++++++++++++++++++++++++++++++++++++++++ graphics/wincursor.h | 94 ++++++++++++++++++++ 3 files changed, 331 insertions(+), 1 deletion(-) create mode 100644 graphics/wincursor.cpp create mode 100644 graphics/wincursor.h (limited to 'graphics') 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 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 -- cgit v1.2.3 From 6143fe965bb5332d8f32709ff1cce3624cd0e51d Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Sat, 5 Mar 2011 13:36:55 -0500 Subject: GRAPHICS: Add support for PE cursors in WinCursorGroup Only 1bpp still --- graphics/wincursor.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ graphics/wincursor.h | 2 +- 2 files changed, 65 insertions(+), 1 deletion(-) (limited to 'graphics') diff --git a/graphics/wincursor.cpp b/graphics/wincursor.cpp index 68b4023c0a..8690e1b18f 100644 --- a/graphics/wincursor.cpp +++ b/graphics/wincursor.cpp @@ -29,6 +29,7 @@ #include "common/str.h" #include "common/stream.h" #include "common/winexe_ne.h" +#include "common/winexe_pe.h" #include "graphics/wincursor.h" @@ -232,4 +233,67 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::NEResources &exe, cons return group; } +WinCursorGroup *WinCursorGroup::createCursorGroup(Common::PEResources &exe, const Common::WinResourceID &id) { + Common::SeekableReadStream *stream = exe.getResource(Common::kPEGroupCursor, 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::kPECursor, 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 index 3e2fc55bb8..b89bda9cd4 100644 --- a/graphics/wincursor.h +++ b/graphics/wincursor.h @@ -86,7 +86,7 @@ struct WinCursorGroup { Common::Array cursors; static WinCursorGroup *createCursorGroup(Common::NEResources &exe, const Common::WinResourceID &id); - //static WinCursorGroup *createCursorGroup(Common::PEResources &exe, const Common::WinResourceID &id); + static WinCursorGroup *createCursorGroup(Common::PEResources &exe, const Common::WinResourceID &id); }; } // End of namespace Graphics -- cgit v1.2.3 From 5b907e828b519c71d1a042483ab0214f758a8ffd Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Sun, 6 Mar 2011 19:53:17 -0500 Subject: GRAPHICS: Fix PE cursors Initial work on 8bpp cursors has also been added --- graphics/wincursor.cpp | 99 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 40 deletions(-) (limited to 'graphics') diff --git a/graphics/wincursor.cpp b/graphics/wincursor.cpp index 8690e1b18f..2f3f29d8a0 100644 --- a/graphics/wincursor.cpp +++ b/graphics/wincursor.cpp @@ -83,12 +83,22 @@ bool WinCursor::readFromStream(Common::SeekableReadStream &stream) { _width = stream.readUint32LE(); _height = stream.readUint32LE() / 2; + if (_width & 3) { + // Cursors should always be a power of 2 + // Of course, it wouldn't be hard to handle but if we have no examples... + warning("Non-divisible-by-4 width cursor found"); + return false; + } + // Color planes if (stream.readUint16LE() != 1) return false; - // Bits per pixel - if (stream.readUint16LE() != 1) + + // Only 1bpp and 8bpp supported + uint16 bitsPerPixel = stream.readUint16LE(); + if (bitsPerPixel != 1 && bitsPerPixel != 8) return false; + // Compression if (stream.readUint32LE() != 0) return false; @@ -98,26 +108,16 @@ bool WinCursor::readFromStream(Common::SeekableReadStream &stream) { uint32 numColors = stream.readUint32LE(); + // If the color count is 0, then it uses up the maximum amount 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; + numColors = 1 << bitsPerPixel; // 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(); + _palette[i * 3 + 2] = stream.readByte(); + _palette[i * 3 + 1] = stream.readByte(); + _palette[i * 3 ] = stream.readByte(); stream.readByte(); } @@ -125,33 +125,57 @@ bool WinCursor::readFromStream(Common::SeekableReadStream &stream) { 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); + // Parse the XOR map + const byte *src = initialSource; _surface = new byte[_width * _height]; byte *dest = _surface + _width * (_height - 1); + uint32 imagePitch = _width * bitsPerPixel / 8; 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]; + if (bitsPerPixel == 1) { + // 1bpp + for (uint32 j = 0; j < (_width / 8); j++) { + byte p = src[j]; - for (int k = 0; k < 8; k++, rowDest++, p <<= 1, m <<= 1) { - if ((m & 0x80) != 0x80) { + for (int k = 0; k < 8; k++, rowDest++, p <<= 1) { if ((p & 0x80) == 0x80) - *rowDest = 2; - else *rowDest = 1; - } else - *rowDest = _keyColor; + else + *rowDest = 0; + } } + } else { + // 8bpp + memcpy(rowDest, src, _width); } dest -= _width; - srcP += _width / 8; - srcM += _width / 8; + src += imagePitch; + } + + // Calculate our key color + if (numColors < 256) { + // If we're not using the maximum colors in a byte, we can fit it in + _keyColor = numColors; + } else { + // TODO + warning("Handle 8bpp cursors with all colors"); + return false; + } + + // Now go through and apply the AND map to get the transparency + uint32 andWidth = (_width + 7) / 8; + src += andWidth * (_height - 1); + + for (uint32 y = 0; y < _height; y++) { + for (uint32 x = 0; x < _width; x++) + if (src[x / 8] & (1 << (7 - x % 8))) + _surface[y * _width + x] = _keyColor; + + src -= andWidth; } delete[] initialSource; @@ -195,7 +219,8 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::NEResources &exe, cons return 0; } - // Bit count + // Bits per pixel + // NE cursors can only be 1bpp if (stream->readUint16LE() != 1) { delete stream; delete group; @@ -241,7 +266,7 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::PEResources &exe, cons stream->skip(4); uint32 cursorCount = stream->readUint16LE(); - if ((uint32)stream->size() < (6 + cursorCount * 16)) + if ((uint32)stream->size() < (6 + cursorCount * 14)) return 0; WinCursorGroup *group = new WinCursorGroup(); @@ -258,15 +283,9 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::PEResources &exe, cons return 0; } - // Bit count - if (stream->readUint16LE() != 1) { - delete stream; - delete group; - return 0; - } - + stream->readUint16LE(); // bits per pixel stream->readUint32LE(); // data size - uint32 cursorId = stream->readUint32LE(); + uint32 cursorId = stream->readUint16LE(); Common::SeekableReadStream *cursorStream = exe.getResource(Common::kPECursor, cursorId); if (!cursorStream) { -- cgit v1.2.3 From d49f3a8a781b28ba46e22e8f8a2c486a146b7e8c Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 7 Mar 2011 00:53:40 -0500 Subject: GRAPHICS: Improve support of Windows 8bpp cursors --- graphics/wincursor.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'graphics') diff --git a/graphics/wincursor.cpp b/graphics/wincursor.cpp index 2f3f29d8a0..15ae69e2f1 100644 --- a/graphics/wincursor.cpp +++ b/graphics/wincursor.cpp @@ -161,9 +161,22 @@ bool WinCursor::readFromStream(Common::SeekableReadStream &stream) { // If we're not using the maximum colors in a byte, we can fit it in _keyColor = numColors; } else { - // TODO - warning("Handle 8bpp cursors with all colors"); - return false; + // HACK: Try to find a color that's not being used so it can become + // our keycolor. It's quite impossible to fit 257 entries into 256... + for (uint32 i = 0; i < 256; i++) { + for (int j = 0; j < _width * _height; j++) { + // TODO: Also check to see if the space is transparent + + if (_surface[j] == i) + break; + + if (j == _width * _height - 1) { + _keyColor = i; + i = 256; + break; + } + } + } } // Now go through and apply the AND map to get the transparency -- cgit v1.2.3 From 4dba6962f579b136a556142e9bd2b3f83af38473 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 7 Mar 2011 11:40:54 -0500 Subject: GRAPHICS: Fix a missing 'f' Thanks, fuzzie --- graphics/fonts/winfont.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'graphics') diff --git a/graphics/fonts/winfont.cpp b/graphics/fonts/winfont.cpp index bdb6133695..12509fd9e1 100644 --- a/graphics/fonts/winfont.cpp +++ b/graphics/fonts/winfont.cpp @@ -177,7 +177,7 @@ uint32 WinFont::getFontIndex(Common::SeekableReadStream &stream, const WinFontDi return id; } - return 0xfffffff; + return 0xffffffff; } bool WinFont::loadFromFNT(const Common::String &fileName) { -- cgit v1.2.3 From b158a4084463d478ba961434f88971ae2a7aeac2 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 7 Mar 2011 13:24:05 -0500 Subject: GRAPHICS: Add doxygen comments for WinCursorGroup --- graphics/wincursor.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'graphics') diff --git a/graphics/wincursor.h b/graphics/wincursor.h index b89bda9cd4..ca0abf6fe1 100644 --- a/graphics/wincursor.h +++ b/graphics/wincursor.h @@ -74,6 +74,15 @@ private: void clear(); }; +/** + * A structure holding an array of cursors from a single Windows Executable cursor group. + * + * Windows lumps different versions of the same cursors/icons together and decides which one + * to use based on the screen's color depth and resolution. For instance, one cursor group + * could hold a 1bpp 16x16 cursorand a 8bpp 16x16 cursor. This will hold all cursors in the + * group. This class should be used to actually parse the cursors, whereas WinCursor is just + * the representation used by this struct to store the cursors. + */ struct WinCursorGroup { WinCursorGroup(); ~WinCursorGroup(); @@ -85,7 +94,9 @@ struct WinCursorGroup { Common::Array cursors; + /** Create a cursor group from an NE EXE, returns 0 on failure */ static WinCursorGroup *createCursorGroup(Common::NEResources &exe, const Common::WinResourceID &id); + /** Create a cursor group from an PE EXE, returns 0 on failure */ static WinCursorGroup *createCursorGroup(Common::PEResources &exe, const Common::WinResourceID &id); }; -- cgit v1.2.3 From 4e7b66b1bc948f9fc22ba3ce67f76f8dfe2f5f99 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 7 Mar 2011 16:37:12 -0500 Subject: GRAPHICS: Cleanup WinCursorGroup functions a bit ScopedPtr is now used on the streams to avoid having repetitive delete calls. --- graphics/wincursor.cpp | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) (limited to 'graphics') diff --git a/graphics/wincursor.cpp b/graphics/wincursor.cpp index 15ae69e2f1..d3c9414e03 100644 --- a/graphics/wincursor.cpp +++ b/graphics/wincursor.cpp @@ -26,6 +26,7 @@ #include "common/debug.h" #include "common/file.h" #include "common/memstream.h" +#include "common/ptr.h" #include "common/str.h" #include "common/stream.h" #include "common/winexe_ne.h" @@ -208,7 +209,7 @@ WinCursorGroup::~WinCursorGroup() { } WinCursorGroup *WinCursorGroup::createCursorGroup(Common::NEResources &exe, const Common::WinResourceID &id) { - Common::SeekableReadStream *stream = exe.getResource(Common::kNEGroupCursor, id); + Common::ScopedPtr stream(exe.getResource(Common::kNEGroupCursor, id)); if (!stream || stream->size() <= 6) return 0; @@ -227,7 +228,6 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::NEResources &exe, cons // Plane count if (stream->readUint16LE() != 1) { - delete stream; delete group; return 0; } @@ -235,7 +235,6 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::NEResources &exe, cons // Bits per pixel // NE cursors can only be 1bpp if (stream->readUint16LE() != 1) { - delete stream; delete group; return 0; } @@ -243,36 +242,30 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::NEResources &exe, cons stream->readUint32LE(); // data size uint32 cursorId = stream->readUint32LE(); - Common::SeekableReadStream *cursorStream = exe.getResource(Common::kNECursor, cursorId); + Common::ScopedPtr 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; } WinCursorGroup *WinCursorGroup::createCursorGroup(Common::PEResources &exe, const Common::WinResourceID &id) { - Common::SeekableReadStream *stream = exe.getResource(Common::kPEGroupCursor, id); + Common::ScopedPtr stream(exe.getResource(Common::kPEGroupCursor, id)); if (!stream || stream->size() <= 6) return 0; @@ -291,7 +284,6 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::PEResources &exe, cons // Plane count if (stream->readUint16LE() != 1) { - delete stream; delete group; return 0; } @@ -300,31 +292,25 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::PEResources &exe, cons stream->readUint32LE(); // data size uint32 cursorId = stream->readUint16LE(); - Common::SeekableReadStream *cursorStream = exe.getResource(Common::kPECursor, cursorId); + Common::ScopedPtr cursorStream(exe.getResource(Common::kPECursor, 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; } -- cgit v1.2.3