aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMatthew Hoops2011-03-07 17:07:59 -0500
committerMatthew Hoops2011-03-07 17:07:59 -0500
commite8151026594c16a84d390059faa5aaaeafa621da (patch)
treef45770831cea801f72c706107108f8a6f46b6b55 /engines
parent212b58ad429718bcb0366541a413fc52db25f615 (diff)
parent4e7b66b1bc948f9fc22ba3ce67f76f8dfe2f5f99 (diff)
downloadscummvm-rg350-e8151026594c16a84d390059faa5aaaeafa621da.tar.gz
scummvm-rg350-e8151026594c16a84d390059faa5aaaeafa621da.tar.bz2
scummvm-rg350-e8151026594c16a84d390059faa5aaaeafa621da.zip
Merge branch 'pe_exe' of https://github.com/clone2727/scummvm into clone2727-pe_exe
Diffstat (limited to 'engines')
-rw-r--r--engines/mohawk/cursors.cpp224
-rw-r--r--engines/mohawk/cursors.h41
-rw-r--r--engines/mohawk/riven.cpp30
-rw-r--r--engines/mohawk/riven_cursors.h670
-rw-r--r--engines/mohawk/riven_external.cpp38
-rw-r--r--engines/mohawk/riven_scripts.cpp1
-rw-r--r--engines/sci/graphics/cursor.cpp12
-rw-r--r--engines/scumm/he/resource_he.cpp1108
-rw-r--r--engines/scumm/he/resource_he.h381
9 files changed, 236 insertions, 2269 deletions
diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp
index eb11eb175e..4a9fcb2ff2 100644
--- a/engines/mohawk/cursors.cpp
+++ b/engines/mohawk/cursors.cpp
@@ -28,12 +28,13 @@
#include "mohawk/resource.h"
#include "mohawk/graphics.h"
#include "mohawk/myst.h"
-#include "mohawk/riven_cursors.h"
#include "common/macresman.h"
-#include "common/ne_exe.h"
#include "common/system.h"
+#include "common/winexe_ne.h"
+#include "common/winexe_pe.h"
#include "graphics/cursorman.h"
+#include "graphics/wincursor.h"
namespace Mohawk {
@@ -83,15 +84,16 @@ void CursorManager::setCursor(uint16 id) {
setDefaultCursor();
}
-void CursorManager::decodeMacXorCursor(Common::SeekableReadStream *stream, byte *cursor) {
+void CursorManager::setMacXorCursor(Common::SeekableReadStream *stream) {
assert(stream);
- assert(cursor);
+
+ byte cursorBitmap[16 * 16];
// Get black and white data
for (int i = 0; i < 32; i++) {
byte imageByte = stream->readByte();
for (int b = 0; b < 8; b++)
- cursor[i * 8 + b] = (imageByte & (0x80 >> b)) ? 1 : 2;
+ cursorBitmap[i * 8 + b] = (imageByte & (0x80 >> b)) ? 1 : 2;
}
// Apply mask data
@@ -99,28 +101,18 @@ void CursorManager::decodeMacXorCursor(Common::SeekableReadStream *stream, byte
byte imageByte = stream->readByte();
for (int b = 0; b < 8; b++)
if ((imageByte & (0x80 >> b)) == 0)
- cursor[i * 8 + b] = 0;
+ cursorBitmap[i * 8 + b] = 0;
}
-}
-void CursorManager::setStandardCursor(Common::SeekableReadStream *stream) {
- // The Broderbund devs decided to rip off the Mac format, it seems.
- // However, they reversed the x/y hotspot. That makes it totally different!!!!
- assert(stream);
-
- byte cursorBitmap[16 * 16];
- decodeMacXorCursor(stream, cursorBitmap);
uint16 hotspotY = stream->readUint16BE();
uint16 hotspotX = stream->readUint16BE();
CursorMan.replaceCursor(cursorBitmap, 16, 16, hotspotX, hotspotY, 0);
CursorMan.replaceCursorPalette(s_bwPalette, 1, 2);
-
- delete stream;
}
void DefaultCursorManager::setCursor(uint16 id) {
- setStandardCursor(_vm->getResource(_tag, id));
+ setMacXorCursor(_vm->getResource(_tag, id));
}
MystCursorManager::MystCursorManager(MohawkEngine_Myst *vm) : _vm(vm) {
@@ -167,119 +159,6 @@ void MystCursorManager::setDefaultCursor() {
setCursor(kDefaultMystCursor);
}
-void RivenCursorManager::setCursor(uint16 id) {
- // All of Riven's cursors are hardcoded. See riven_cursors.h for these definitions.
-
- switch (id) {
- case 1002:
- // Zip Mode
- CursorMan.replaceCursor(s_zipModeCursor, 16, 16, 8, 8, 0);
- CursorMan.replaceCursorPalette(s_zipModeCursorPalette, 1, ARRAYSIZE(s_zipModeCursorPalette) / 3);
- break;
- case 2003:
- // Hand Over Object
- CursorMan.replaceCursor(s_objectHandCursor, 16, 16, 8, 8, 0);
- CursorMan.replaceCursorPalette(s_handCursorPalette, 1, ARRAYSIZE(s_handCursorPalette) / 3);
- break;
- case 2004:
- // Grabbing/Using Object
- CursorMan.replaceCursor(s_grabbingHandCursor, 13, 13, 6, 6, 0);
- CursorMan.replaceCursorPalette(s_handCursorPalette, 1, ARRAYSIZE(s_handCursorPalette) / 3);
- break;
- case 3000:
- // Standard Hand
- CursorMan.replaceCursor(s_standardHandCursor, 15, 16, 6, 0, 0);
- CursorMan.replaceCursorPalette(s_handCursorPalette, 1, ARRAYSIZE(s_handCursorPalette) / 3);
- break;
- case 3001:
- // Pointing Left
- CursorMan.replaceCursor(s_pointingLeftCursor, 15, 13, 0, 3, 0);
- CursorMan.replaceCursorPalette(s_handCursorPalette, 1, ARRAYSIZE(s_handCursorPalette) / 3);
- break;
- case 3002:
- // Pointing Right
- CursorMan.replaceCursor(s_pointingRightCursor, 15, 13, 14, 3, 0);
- CursorMan.replaceCursorPalette(s_handCursorPalette, 1, ARRAYSIZE(s_handCursorPalette) / 3);
- break;
- case 3003:
- // Pointing Down (Palm Up)
- CursorMan.replaceCursor(s_pointingDownCursorPalmUp, 13, 16, 3, 15, 0);
- CursorMan.replaceCursorPalette(s_handCursorPalette, 1, ARRAYSIZE(s_handCursorPalette) / 3);
- break;
- case 3004:
- // Pointing Up (Palm Up)
- CursorMan.replaceCursor(s_pointingUpCursorPalmUp, 13, 16, 3, 0, 0);
- CursorMan.replaceCursorPalette(s_handCursorPalette, 1, ARRAYSIZE(s_handCursorPalette) / 3);
- break;
- case 3005:
- // Pointing Left (Curved)
- CursorMan.replaceCursor(s_pointingLeftCursorBent, 15, 13, 0, 5, 0);
- CursorMan.replaceCursorPalette(s_handCursorPalette, 1, ARRAYSIZE(s_handCursorPalette) / 3);
- break;
- case 3006:
- // Pointing Right (Curved)
- CursorMan.replaceCursor(s_pointingRightCursorBent, 15, 13, 14, 5, 0);
- CursorMan.replaceCursorPalette(s_handCursorPalette, 1, ARRAYSIZE(s_handCursorPalette) / 3);
- break;
- case 3007:
- // Pointing Down (Palm Down)
- CursorMan.replaceCursor(s_pointingDownCursorPalmDown, 15, 16, 7, 15, 0);
- CursorMan.replaceCursorPalette(s_handCursorPalette, 1, ARRAYSIZE(s_handCursorPalette) / 3);
- break;
- case 4001:
- // Red Marble
- CursorMan.replaceCursor(s_redMarbleCursor, 12, 12, 5, 5, 0);
- CursorMan.replaceCursorPalette(s_redMarbleCursorPalette, 1, ARRAYSIZE(s_redMarbleCursorPalette) / 3);
- break;
- case 4002:
- // Orange Marble
- CursorMan.replaceCursor(s_orangeMarbleCursor, 12, 12, 5, 5, 0);
- CursorMan.replaceCursorPalette(s_orangeMarbleCursorPalette, 1, ARRAYSIZE(s_orangeMarbleCursorPalette) / 3);
- break;
- case 4003:
- // Yellow Marble
- CursorMan.replaceCursor(s_yellowMarbleCursor, 12, 12, 5, 5, 0);
- CursorMan.replaceCursorPalette(s_yellowMarbleCursorPalette, 1, ARRAYSIZE(s_yellowMarbleCursorPalette) / 3);
- break;
- case 4004:
- // Green Marble
- CursorMan.replaceCursor(s_greenMarbleCursor, 12, 12, 5, 5, 0);
- CursorMan.replaceCursorPalette(s_greenMarbleCursorPalette, 1, ARRAYSIZE(s_greenMarbleCursorPalette) / 3);
- break;
- case 4005:
- // Blue Marble
- CursorMan.replaceCursor(s_blueMarbleCursor, 12, 12, 5, 5, 0);
- CursorMan.replaceCursorPalette(s_blueMarbleCursorPalette, 1, ARRAYSIZE(s_blueMarbleCursorPalette) / 3);
- break;
- case 4006:
- // Violet Marble
- CursorMan.replaceCursor(s_violetMarbleCursor, 12, 12, 5, 5, 0);
- CursorMan.replaceCursorPalette(s_violetMarbleCursorPalette, 1, ARRAYSIZE(s_violetMarbleCursorPalette) / 3);
- break;
- case 5000:
- // Pellet
- CursorMan.replaceCursor(s_pelletCursor, 8, 8, 4, 4, 0);
- CursorMan.replaceCursorPalette(s_pelletCursorPalette, 1, ARRAYSIZE(s_pelletCursorPalette) / 3);
- break;
- case 9000:
- // Hide Cursor
- CursorMan.showMouse(false);
- break;
- default:
- error("Cursor %d does not exist!", id);
- }
-
- if (id != 9000) // Show Cursor
- CursorMan.showMouse(true);
-
- // Should help in cases where we need to hide the cursor immediately.
- g_system->updateScreen();
-}
-
-void RivenCursorManager::setDefaultCursor() {
- setCursor(kRivenMainCursor);
-}
-
NECursorManager::NECursorManager(const Common::String &appName) {
_exe = new Common::NEResources();
@@ -295,16 +174,14 @@ NECursorManager::~NECursorManager() {
}
void NECursorManager::setCursor(uint16 id) {
- if (!_exe) {
- Common::Array<Common::NECursorGroup> cursors = _exe->getCursors();
-
- for (uint32 i = 0; i < cursors.size(); i++) {
- if (cursors[i].id == id) {
- Common::NECursor *cursor = cursors[i].cursors[0];
- CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(), cursor->getHotspotY(), 0);
- CursorMan.replaceCursorPalette(cursor->getPalette(), 0, 256);
- return;
- }
+ if (_exe) {
+ Graphics::WinCursorGroup *cursorGroup = Graphics::WinCursorGroup::createCursorGroup(*_exe, id);
+
+ if (cursorGroup) {
+ Graphics::WinCursor *cursor = cursorGroup->cursors[0].cursor;
+ CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(), cursor->getHotspotY(), cursor->getKeyColor());
+ CursorMan.replaceCursorPalette(cursor->getPalette(), 0, 256);
+ return;
}
}
@@ -321,6 +198,8 @@ MacCursorManager::MacCursorManager(const Common::String &appName) {
delete _resFork;
_resFork = 0;
}
+ } else {
+ _resFork = 0;
}
}
@@ -334,22 +213,33 @@ void MacCursorManager::setCursor(uint16 id) {
return;
}
- Common::SeekableReadStream *stream = _resFork->getResource(MKID_BE('CURS'), id);
+ // Try a color cursor first
+ Common::SeekableReadStream *stream = _resFork->getResource(MKID_BE('crsr'), id);
- if (!stream) {
- setDefaultCursor();
+ if (stream) {
+ byte *cursor, *palette;
+ int width, height, hotspotX, hotspotY, keyColor, palSize;
+
+ _resFork->convertCrsrCursor(stream, &cursor, width, height, hotspotX, hotspotY, keyColor, true, &palette, palSize);
+
+ CursorMan.replaceCursor(cursor, width, height, hotspotX, hotspotY, keyColor);
+ CursorMan.replaceCursorPalette(palette, 0, palSize);
+
+ delete[] cursor;
+ delete[] palette;
+ delete stream;
return;
}
- byte cursorBitmap[16 * 16];
- decodeMacXorCursor(stream, cursorBitmap);
- uint16 hotspotX = stream->readUint16BE();
- uint16 hotspotY = stream->readUint16BE();
+ // Fall back to b&w cursors
+ stream = _resFork->getResource(MKID_BE('CURS'), id);
- CursorMan.replaceCursor(cursorBitmap, 16, 16, hotspotX, hotspotY, 0);
- CursorMan.replaceCursorPalette(s_bwPalette, 1, 2);
-
- delete stream;
+ if (stream) {
+ setMacXorCursor(stream);
+ delete stream;
+ } else {
+ setDefaultCursor();
+ }
}
LivingBooksCursorManager_v2::LivingBooksCursorManager_v2() {
@@ -368,10 +258,40 @@ LivingBooksCursorManager_v2::~LivingBooksCursorManager_v2() {
void LivingBooksCursorManager_v2::setCursor(uint16 id) {
if (_sysArchive && _sysArchive->hasResource(ID_TCUR, id)) {
- setStandardCursor(_sysArchive->getResource(ID_TCUR, id));
+ setMacXorCursor(_sysArchive->getResource(ID_TCUR, id));
} else {
// TODO: Handle generated cursors
}
}
+PECursorManager::PECursorManager(const Common::String &appName) {
+ _exe = new Common::PEResources();
+
+ if (!_exe->loadFromEXE(appName)) {
+ // Not all have cursors anyway, so this is not a problem
+ delete _exe;
+ _exe = 0;
+ }
+}
+
+PECursorManager::~PECursorManager() {
+ delete _exe;
+}
+
+void PECursorManager::setCursor(uint16 id) {
+ if (_exe) {
+ Graphics::WinCursorGroup *cursorGroup = Graphics::WinCursorGroup::createCursorGroup(*_exe, id);
+
+ if (cursorGroup) {
+ Graphics::WinCursor *cursor = cursorGroup->cursors[0].cursor;
+ CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(), cursor->getHotspotY(), cursor->getKeyColor());
+ CursorMan.replaceCursorPalette(cursor->getPalette(), 0, 256);
+ return;
+ }
+ }
+
+ // Last resort (not all have cursors)
+ setDefaultCursor();
+}
+
} // End of namespace Mohawk
diff --git a/engines/mohawk/cursors.h b/engines/mohawk/cursors.h
index a542ddb7c3..e6c417948f 100644
--- a/engines/mohawk/cursors.h
+++ b/engines/mohawk/cursors.h
@@ -31,6 +31,7 @@
namespace Common {
class MacResManager;
class NEResources;
+ class PEResources;
class SeekableReadStream;
class String;
}
@@ -80,13 +81,11 @@ public:
virtual void hideCursor();
virtual void setCursor(uint16 id);
virtual void setDefaultCursor();
+ virtual bool hasSource() const { return false; }
protected:
- // Handles the Mac version of the xor/and map cursor
- void decodeMacXorCursor(Common::SeekableReadStream *stream, byte *cursor);
-
- // Set a tCUR resource as the current cursor
- void setStandardCursor(Common::SeekableReadStream *stream);
+ // Set a Mac XOR/AND map cursor to the screen
+ void setMacXorCursor(Common::SeekableReadStream *stream);
};
// The default Mohawk cursor manager
@@ -97,6 +96,7 @@ public:
~DefaultCursorManager() {}
void setCursor(uint16 id);
+ bool hasSource() const { return true; }
private:
MohawkEngine *_vm;
@@ -114,31 +114,21 @@ public:
void hideCursor();
void setCursor(uint16 id);
void setDefaultCursor();
+ bool hasSource() const { return true; }
private:
MohawkEngine_Myst *_vm;
MystBitmap *_bmpDecoder;
};
-
-// The cursor manager for Riven
-// Uses hardcoded cursors
-class RivenCursorManager : public CursorManager {
-public:
- RivenCursorManager() {}
- ~RivenCursorManager() {}
-
- void setCursor(uint16 id);
- void setDefaultCursor();
-};
-
-// The cursor manager for NE exe's
+// The cursor manager for NE EXE's
class NECursorManager : public CursorManager {
public:
NECursorManager(const Common::String &appName);
~NECursorManager();
void setCursor(uint16 id);
+ bool hasSource() const { return _exe != 0; }
private:
Common::NEResources *_exe;
@@ -151,6 +141,7 @@ public:
~MacCursorManager();
void setCursor(uint16 id);
+ bool hasSource() const { return _resFork != 0; }
private:
Common::MacResManager *_resFork;
@@ -164,11 +155,25 @@ public:
~LivingBooksCursorManager_v2();
void setCursor(uint16 id);
+ bool hasSource() const { return _sysArchive != 0; }
private:
MohawkArchive *_sysArchive;
};
+// The cursor manager for PE EXE's
+class PECursorManager : public CursorManager {
+public:
+ PECursorManager(const Common::String &appName);
+ ~PECursorManager();
+
+ void setCursor(uint16 id);
+ bool hasSource() const { return _exe != 0; }
+
+private:
+ Common::PEResources *_exe;
+};
+
} // End of namespace Mohawk
#endif
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index abc7f5304e..d75c98bcd4 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -120,21 +120,43 @@ Common::Error MohawkEngine_Riven::run() {
_externalScriptHandler = new RivenExternal(this);
_optionsDialog = new RivenOptionsDialog(this);
_scriptMan = new RivenScriptManager(this);
- _cursor = new RivenCursorManager();
_rnd = new Common::RandomSource();
g_eventRec.registerRandomSource(*_rnd, "riven");
+ // Create the cursor manager
+ if (Common::File::exists("rivendmo.exe"))
+ _cursor = new PECursorManager("rivendmo.exe");
+ else if (Common::File::exists("riven.exe"))
+ _cursor = new PECursorManager("riven.exe");
+ else // last resort: try the Mac executable
+ _cursor = new MacCursorManager("Riven");
+
initVars();
+ // We need to have a cursor source, or the game won't work
+ if (!_cursor->hasSource()) {
+ Common::String message = "You're missing a Riven executable. The Windows executable is 'riven.exe' or 'rivendemo.exe'. ";
+ message += "Using the 'arcriven.z' installer file also works. In addition, you can use the Mac 'Riven' executable.";
+ GUIErrorMessage(message);
+ warning("%s", message.c_str());
+ return Common::kNoGameDataFoundError;
+ }
+
// Open extras.mhk for common images
_extrasFile = new MohawkArchive();
- if (!_extrasFile->open("extras.mhk"))
- error("Could not open extras.mhk");
+ // We need extras.mhk for inventory images, marble images, and credits images
+ if (!_extrasFile->open("extras.mhk")) {
+ Common::String message = "You're missing 'extras.mhk'. Using the 'arcriven.z' installer file also works.";
+ GUIErrorMessage(message);
+ warning("%s", message.c_str());
+ return Common::kNoGameDataFoundError;
+ }
// Start at main cursor
_cursor->setCursor(kRivenMainCursor);
+ _system->updateScreen();
// Let's begin, shall we?
if (getFeatures() & GF_DEMO) {
@@ -488,10 +510,12 @@ void MohawkEngine_Riven::checkHotspotChange() {
if (_curHotspot != hotspotIndex) {
_curHotspot = hotspotIndex;
_cursor->setCursor(_hotspots[_curHotspot].mouse_cursor);
+ _system->updateScreen();
}
} else {
_curHotspot = -1;
_cursor->setCursor(kRivenMainCursor);
+ _system->updateScreen();
}
}
diff --git a/engines/mohawk/riven_cursors.h b/engines/mohawk/riven_cursors.h
deleted file mode 100644
index dadfdf0549..0000000000
--- a/engines/mohawk/riven_cursors.h
+++ /dev/null
@@ -1,670 +0,0 @@
-/* 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$
- *
- */
-
-namespace Mohawk {
-
-//////////////////////////////////////////////
-// Cursors and Cursor Palettes
-//////////////////////////////////////////////
-
-////////////////////////////////////////
-// Zip Mode Cursor (16x16):
-// Shown when a zip mode spot is active
-//
-// 0 = Transparent
-// 1 = Black (0x000000)
-// 2 = Yellow (0xDCFF00)
-////////////////////////////////////////
-static const byte s_zipModeCursor[] = {
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 2, 1, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 2, 1, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 2, 2, 1, 2, 2, 2, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 2, 2, 1, 2, 2, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 1, 2, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 1, 2, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 1, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
-};
-
-
-////////////////////////////////////////
-// Zip Mode Cursor Palette:
-// Palette For The Zip Mode Cursor
-////////////////////////////////////////
-static const byte s_zipModeCursorPalette[] = {
- 0x00, 0x00, 0x00, // Black
- 0xDC, 0xFF, 0x00 // Yellow
-};
-
-
-////////////////////////////////////////
-// Hand Over Object Cursor (16x16):
-// Shown when over a hotspot that's interactive
-//
-// 0 = Transparent
-// 1 = Black (0x000000)
-// 2 = Light Peach (0xEDCD96)
-// 3 = Brown (0x8A672F)
-// 4 = Dark Peach (0xE89A62)
-////////////////////////////////////////
-static const byte s_objectHandCursor[] = {
- 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 0, 1, 2, 3, 1, 1, 1, 0, 0, 0, 0,
- 0, 0, 1, 2, 3, 1, 1, 2, 3, 1, 2, 3, 1, 0, 0, 0,
- 0, 0, 1, 2, 3, 1, 1, 4, 3, 1, 2, 3, 1, 0, 1, 0,
- 0, 0, 0, 1, 2, 3, 1, 2, 3, 1, 4, 3, 1, 1, 2, 1,
- 0, 0, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1,
- 0, 1, 1, 0, 1, 2, 2, 2, 2, 2, 2, 3, 1, 2, 3, 1,
- 1, 2, 2, 1, 1, 2, 2, 2, 4, 2, 4, 2, 2, 4, 2, 1,
- 1, 3, 4, 2, 1, 2, 4, 2, 2, 2, 2, 2, 4, 4, 1, 0,
- 0, 1, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 3, 1, 0,
- 0, 0, 1, 3, 2, 2, 2, 2, 2, 2, 2, 4, 4, 3, 1, 0,
- 0, 0, 1, 3, 2, 2, 2, 2, 2, 2, 2, 4, 3, 1, 0, 0,
- 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 1, 0, 0,
- 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 4, 3, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 4, 3, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 4, 3, 1, 0, 0, 0
-};
-
-
-////////////////////////////////////////
-// Grabbing Hand Cursor (13x13):
-// Shown when interacting with an object
-//
-// 0 = Transparent
-// 1 = Black (0x000000)
-// 2 = Light Peach (0xEDCD96)
-// 3 = Brown (0x8A672F)
-// 4 = Dark Peach (0xE89A62)
-////////////////////////////////////////
-static const byte s_grabbingHandCursor[] = {
- 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 1, 2, 3, 1, 1, 1, 0, 0, 0,
- 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 0,
- 0, 1, 2, 2, 2, 2, 2, 2, 2, 3, 1, 2, 1,
- 0, 1, 1, 2, 2, 2, 4, 2, 4, 2, 2, 4, 1,
- 1, 2, 1, 2, 4, 2, 2, 2, 2, 2, 4, 4, 1,
- 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 3, 1,
- 1, 3, 2, 2, 2, 2, 2, 2, 2, 4, 4, 3, 1,
- 1, 3, 2, 2, 2, 2, 2, 2, 2, 4, 3, 1, 0,
- 0, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 1, 0,
- 0, 0, 1, 2, 2, 2, 2, 2, 4, 3, 1, 0, 0,
- 0, 0, 0, 1, 2, 2, 2, 2, 4, 3, 1, 0, 0,
- 0, 0, 0, 1, 2, 2, 2, 2, 4, 3, 1, 0, 0
-};
-
-
-////////////////////////////////////////
-// Standard Hand Cursor (15x16):
-// Standard Cursor
-//
-// 0 = Transparent
-// 1 = Black (0x000000)
-// 2 = Light Peach (0xEDCD96)
-// 3 = Brown (0x8A672F)
-// 4 = Dark Peach (0xE89A62)
-////////////////////////////////////////
-static const byte s_standardHandCursor[] = {
- 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 4, 4, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 3, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 4, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 4, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 4, 1, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 0, 0, 1, 2, 4, 1, 1, 1, 1, 1, 0, 0,
- 1, 4, 2, 1, 0, 1, 2, 4, 1, 4, 1, 4, 1, 1, 1,
- 0, 1, 3, 2, 1, 1, 2, 4, 1, 4, 1, 4, 1, 4, 1,
- 0, 0, 1, 4, 2, 1, 2, 2, 4, 2, 4, 2, 1, 4, 1,
- 0, 0, 1, 4, 2, 1, 2, 2, 2, 2, 2, 2, 2, 3, 1,
- 0, 0, 0, 1, 4, 2, 2, 2, 2, 2, 2, 2, 4, 3, 1,
- 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 4, 3, 1,
- 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 3, 1, 0,
- 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 4, 3, 1, 0,
- 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 4, 3, 1, 0
-};
-
-
-////////////////////////////////////////
-// Pointing Left Cursor (15x13):
-// Cursor When Over A Hotspot That Allows You To Move Left
-//
-// 0 = Transparent
-// 1 = Black (0x000000)
-// 2 = Light Peach (0xEDCD96)
-// 3 = Brown (0x8A672F)
-// 4 = Dark Peach (0xE89A62)
-////////////////////////////////////////
-static const byte s_pointingLeftCursor[] = {
- 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 3, 2, 2, 2, 1, 1, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 3, 1, 1,
- 1, 4, 2, 2, 2, 2, 1, 2, 3, 2, 2, 2, 4, 4, 4,
- 1, 4, 4, 4, 4, 4, 1, 2, 1, 3, 4, 2, 2, 2, 2,
- 0, 1, 1, 1, 1, 1, 1, 2, 1, 3, 3, 4, 2, 2, 2,
- 0, 0, 0, 0, 0, 1, 1, 1, 1, 3, 3, 3, 4, 4, 2,
- 0, 0, 0, 0, 0, 1, 2, 2, 2, 4, 1, 3, 4, 2, 2,
- 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 4, 2, 2,
- 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 4, 2, 4,
- 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 4, 4, 1,
- 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0
-};
-
-
-////////////////////////////////////////
-// Pointing Right Cursor (15x13):
-// Cursor When Over A Hotspot That Allows You To Move Right
-//
-// 0 = Transparent
-// 1 = Black (0x000000)
-// 2 = Light Peach (0xEDCD96)
-// 3 = Brown (0x8A672F)
-// 4 = Dark Peach (0xE89A62)
-////////////////////////////////////////
-static const byte s_pointingRightCursor[] = {
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 2, 2, 2, 3, 1, 0, 0, 0, 0, 0, 0,
- 1, 1, 3, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0,
- 4, 4, 4, 2, 2, 2, 3, 2, 1, 4, 4, 4, 4, 4, 1,
- 2, 2, 2, 2, 4, 3, 1, 2, 1, 2, 2, 2, 2, 4, 1,
- 2, 2, 2, 4, 3, 3, 1, 2, 1, 1, 1, 1, 1, 1, 0,
- 2, 4, 4, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 2, 2, 4, 3, 1, 4, 2, 2, 2, 1, 0, 0, 0, 0, 0,
- 2, 2, 4, 3, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 4, 2, 4, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0,
- 1, 4, 4, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0
-};
-
-
-////////////////////////////////////////
-// Pointing Down Cursor (Palm Up)(13x16):
-// Cursor When Over A Hotspot That Allows You To Move Down
-//
-// 0 = Transparent
-// 1 = Black (0x000000)
-// 2 = Light Peach (0xEDCD96)
-// 3 = Brown (0x8A672F)
-// 4 = Dark Peach (0xE89A62)
-////////////////////////////////////////
-static const byte s_pointingDownCursorPalmUp[] = {
- 0, 0, 1, 4, 2, 2, 2, 2, 2, 4, 1, 0, 0,
- 0, 0, 1, 4, 2, 2, 4, 2, 2, 2, 4, 1, 0,
- 0, 1, 3, 4, 2, 2, 4, 4, 4, 4, 4, 1, 0,
- 0, 1, 4, 2, 2, 4, 3, 3, 3, 1, 1, 1, 1,
- 1, 2, 2, 2, 4, 3, 3, 1, 1, 2, 1, 2, 1,
- 1, 2, 2, 2, 3, 3, 3, 4, 1, 2, 1, 2, 1,
- 1, 2, 2, 3, 1, 1, 1, 2, 1, 2, 1, 2, 1,
- 1, 3, 2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1,
- 0, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1,
- 0, 0, 1, 2, 4, 1, 1, 1, 1, 1, 1, 0, 0,
- 0, 0, 1, 2, 4, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 2, 4, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 2, 4, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 2, 4, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-
-////////////////////////////////////////
-// Pointing Up Cursor (Palm Up)(13x16):
-// Cursor When Over A Hotspot That Allows You To Move Up
-//
-// 0 = Transparent
-// 1 = Black (0x000000)
-// 2 = Light Peach (0xEDCD96)
-// 3 = Brown (0x8A672F)
-// 4 = Dark Peach (0xE89A62)
-////////////////////////////////////////
-static const byte s_pointingUpCursorPalmUp[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 1, 0, 0,
- 0, 0, 1, 1, 1, 1, 1, 1, 2, 4, 1, 0, 0,
- 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 0,
- 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2, 3, 1,
- 1, 2, 1, 2, 1, 2, 1, 1, 1, 3, 2, 2, 1,
- 1, 2, 1, 2, 1, 4, 3, 3, 3, 2, 2, 2, 1,
- 1, 2, 1, 2, 1, 1, 3, 3, 4, 2, 2, 2, 1,
- 1, 1, 1, 1, 3, 3, 3, 4, 2, 2, 4, 1, 0,
- 0, 1, 4, 4, 4, 4, 4, 2, 2, 4, 3, 1, 0,
- 0, 1, 4, 2, 2, 2, 4, 2, 2, 4, 1, 0, 0,
- 0, 0, 1, 4, 2, 2, 2, 2, 2, 4, 1, 0, 0
-};
-
-
-////////////////////////////////////////
-// Pointing Left Cursor (Bent)(15x13):
-// Cursor When Over A Hotspot That Allows You To Turn Left 180 Degrees
-//
-// 0 = Transparent
-// 1 = Black (0x000000)
-// 2 = Light Peach (0xEDCD96)
-// 3 = Brown (0x8A672F)
-// 4 = Dark Peach (0xE89A62)
-////////////////////////////////////////
-static const byte s_pointingLeftCursorBent[] = {
- 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 3, 2, 2, 2, 1, 1, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 3, 1, 1,
- 1, 3, 2, 4, 4, 2, 1, 2, 3, 3, 2, 2, 4, 4, 4,
- 1, 2, 4, 3, 3, 4, 1, 2, 1, 3, 4, 2, 2, 2, 2,
- 1, 4, 4, 1, 1, 1, 1, 2, 1, 1, 3, 4, 2, 2, 2,
- 1, 1, 1, 0, 0, 1, 1, 1, 1, 3, 3, 3, 4, 4, 2,
- 0, 0, 0, 0, 0, 1, 2, 2, 2, 4, 1, 3, 4, 3, 2,
- 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 4, 2, 2,
- 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 4, 2, 4,
- 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 4, 4, 1,
- 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0
-};
-
-
-////////////////////////////////////////
-// Pointing Right Cursor (Bent)(15x13):
-// Cursor When Over A Hotspot That Allows You To Turn Right 180 Degrees
-//
-// 0 = Transparent
-// 1 = Black (0x000000)
-// 2 = Light Peach (0xEDCD96)
-// 3 = Brown (0x8A672F)
-// 4 = Dark Peach (0xE89A62)
-////////////////////////////////////////
-static const byte s_pointingRightCursorBent[] = {
- 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 2, 2, 2, 3, 1, 0, 0, 0, 0, 0, 0,
- 1, 1, 3, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0,
- 4, 4, 4, 2, 2, 3, 3, 2, 1, 2, 4, 4, 2, 3, 1,
- 2, 2, 2, 2, 4, 3, 1, 2, 1, 4, 3, 3, 4, 2, 1,
- 2, 2, 2, 4, 3, 1, 1, 2, 1, 1, 1, 1, 4, 4, 1,
- 2, 4, 4, 3, 3, 3, 1, 1, 1, 1, 0, 0, 1, 1, 1,
- 2, 3, 4, 3, 1, 4, 2, 2, 2, 1, 0, 0, 0, 0, 0,
- 2, 2, 4, 3, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 4, 2, 4, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0,
- 1, 4, 4, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0
-};
-
-
-////////////////////////////////////////
-// Pointing Down Cursor (Palm Down)(15x16):
-// Similar to Standard Cursor
-//
-// 0 = Transparent
-// 1 = Black (0x000000)
-// 2 = Light Peach (0xEDCD96)
-// 3 = Brown (0x8A672F)
-// 4 = Dark Peach (0xE89A62)
-////////////////////////////////////////
-static const byte s_pointingDownCursorPalmDown[] = {
- 0, 1, 3, 4, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0,
- 0, 1, 3, 4, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0,
- 0, 1, 3, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0,
- 1, 3, 4, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0,
- 1, 3, 4, 2, 2, 2, 2, 2, 2, 2, 4, 1, 0, 0, 0,
- 1, 3, 2, 3, 2, 2, 2, 2, 2, 1, 2, 4, 1, 0, 0,
- 1, 4, 1, 2, 2, 3, 2, 3, 2, 1, 2, 4, 1, 0, 0,
- 1, 4, 1, 4, 1, 4, 1, 4, 4, 1, 1, 2, 3, 1, 0,
- 0, 1, 1, 4, 1, 4, 1, 4, 2, 1, 0, 1, 2, 4, 1,
- 0, 0, 1, 1, 1, 1, 1, 4, 2, 1, 0, 0, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 1, 4, 4, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 4, 2, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 4, 2, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 3, 2, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 4, 4, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0
-};
-
-////////////////////////////////////////
-// Hand Cursor Palette:
-// Palette For All Hand Cursors
-////////////////////////////////////////
-static const byte s_handCursorPalette[] = {
- 0x00, 0x00, 0x00, // Black
- 0xED, 0xCD, 0x96, // Light Peach
- 0x8A, 0x67, 0x2F, // Brown
- 0xE8, 0x9A, 0x62 // Dark Peach
-};
-
-
-////////////////////////////////////////
-// Pellet Cursor (8x8):
-// Cursor When Using The Pellet In The Frog Trap
-//
-// 0 = Transparent
-// 1 = Light Olive Green (0x5D6730)
-// 2 = Maroon (0x5E3333)
-// 3 = Light Gray (0x555555)
-// 4 = Medium Gray (0x444444)
-// 5 = Dark Gray (0x333333)
-// 6 = Dark Green (0x2D3300)
-// 7 = Darkest Gray (0x222222)
-////////////////////////////////////////
-static const byte s_pelletCursor[] = {
- 0, 0, 1, 1, 2, 3, 0, 0,
- 0, 2, 1, 4, 1, 2, 5, 0,
- 4, 1, 4, 1, 2, 1, 5, 4,
- 4, 2, 1, 2, 1, 1, 2, 6,
- 6, 4, 2, 1, 4, 4, 1, 5,
- 5, 6, 5, 2, 1, 2, 4, 4,
- 0, 7, 5, 5, 4, 2, 5, 0,
- 0, 0, 5, 6, 6, 5, 0, 0
-};
-
-////////////////////////////////////////
-// Pellet Cursor Palette:
-// Palette For The Pellet Cursor
-////////////////////////////////////////
-static const byte s_pelletCursorPalette[] = {
- 0x5D, 0x67, 0x30,
- 0x5E, 0x33, 0x33,
- 0x55, 0x55, 0x55,
- 0x44, 0x44, 0x44,
- 0x33, 0x33, 0x33,
- 0x2D, 0x33, 0x00,
- 0x22, 0x22, 0x22
-};
-
-////////////////////////////////////////
-// Red Marble Cursor (12x12):
-// Cursor When Holding The Red Marble
-////////////////////////////////////////
-static const byte s_redMarbleCursor[] = {
- 0, 0, 0, 0, 1, 2, 2, 2, 0, 0, 0, 0,
- 0, 0, 3, 4, 2, 5, 2, 2, 2, 2, 0, 0,
- 0, 6, 1, 1, 2, 2, 5, 2, 2, 2, 2, 0,
- 0, 6, 3, 4, 5, 2, 2, 7, 8, 5, 2, 0,
- 9, 6, 10,11,2, 2, 2, 12,13,2, 2, 2,
- 14,10,6, 4, 1, 2, 8, 2, 2, 5, 2, 2,
- 15,16,6, 3, 1, 2, 2, 2, 2, 2, 2, 5,
- 17,9,18, 3, 4, 4, 4, 5, 2, 5, 1, 2,
- 0, 16,9, 6, 6, 19,1, 20,1, 4, 11,0,
- 0, 17,15,18,9, 10,6, 10,3, 21,4, 0,
- 0, 0, 18,15,9, 18,6, 22,10,23,0, 0,
- 0, 0, 0, 0, 15,15,16,9, 0, 0, 0, 0
-};
-
-
-////////////////////////////////////////
-// Red Marble Cursor Palette:
-// Palette For The Red Marble Cursor
-////////////////////////////////////////
-static const byte s_redMarbleCursorPalette[] = {
- 0xb8, 0x33, 0x32,
- 0xe5, 0x33, 0x31,
- 0x98, 0x06, 0x00,
- 0xb8, 0x00, 0x34,
- 0xe6, 0x00, 0x34,
- 0x7a, 0x04, 0x00,
- 0xe8, 0x9a, 0x62,
- 0xea, 0x31, 0x67,
- 0x6a, 0x03, 0x00,
- 0x8c, 0x00, 0x35,
- 0xb6, 0x36, 0x00,
- 0xed, 0xcd, 0x96,
- 0xe9, 0x66, 0x65,
- 0x5b, 0x35, 0x00,
- 0x5b, 0x02, 0x00,
- 0x5f, 0x00, 0x35,
- 0x4c, 0x01, 0x00,
- 0x5e, 0x33, 0x33,
- 0x89, 0x05, 0x00,
- 0xb6, 0x08, 0x00,
- 0xa7, 0x07, 0x00,
- 0x88, 0x36, 0x00,
- 0x8b, 0x33, 0x33
-};
-
-////////////////////////////////////////
-// Orange Marble Cursor (12x12):
-// Cursor When Holding The Orange Marble
-////////////////////////////////////////
-static const byte s_orangeMarbleCursor[] = {
- 0, 0, 0, 0, 1, 2, 2, 3, 0, 0, 0, 0,
- 0, 0, 4, 5, 2, 2, 3, 3, 3, 3, 0, 0,
- 0, 6, 7, 4, 2, 1, 2, 2, 3, 3, 3, 0,
- 0, 6, 6, 7, 1, 2, 3, 8, 9, 2, 10,0,
- 11,12,7, 4, 2, 3, 3, 13,9, 2, 2, 1,
- 14,15,6, 4, 2, 16,3, 3, 2, 1, 1, 1,
- 14,14,12,17,4, 2, 2, 1, 2, 1, 2, 1,
- 14,18,12,6, 4, 4, 4, 19,2, 19,20,4,
- 0, 14,14,15,6, 15,6, 4, 4, 4, 4, 0,
- 0, 14,11,14,14,12,12,12,17,6, 17,0,
- 0, 0, 14,14,17,14,17,6, 6, 17,0, 0,
- 0, 0, 0, 0, 14,11,14,11,0, 0, 0, 0
-};
-
-////////////////////////////////////////
-// Orange Marble Cursor Palette:
-// Palette For The Orange Marble Cursor
-////////////////////////////////////////
-static const byte s_orangeMarbleCursorPalette[] = {
- 0xe1, 0x9e, 0x00,
- 0xe3, 0x9b, 0x28,
- 0xe2, 0xcf, 0x20,
- 0xb5, 0x6a, 0x00,
- 0xb6, 0x9b, 0x29,
- 0x87, 0x69, 0x00,
- 0xb7, 0x67, 0x2f,
- 0xe9, 0xff, 0x93,
- 0xe1, 0xff, 0x5a,
- 0xe0, 0xd0, 0x00,
- 0x5e, 0x33, 0x33,
- 0x88, 0x36, 0x00,
- 0xf3, 0xff, 0xc9,
- 0x5b, 0x35, 0x00,
- 0x8b, 0x33, 0x33,
- 0xe6, 0xce, 0x5f,
- 0x8a, 0x67, 0x2f,
- 0x5d, 0x67, 0x30,
- 0xe2, 0x6a, 0x00,
- 0xb3, 0x9d, 0x00
-};
-
-////////////////////////////////////////
-// Yellow Marble Cursor (12x12):
-// Cursor When Holding The Yellow Marble
-////////////////////////////////////////
-static const byte s_yellowMarbleCursor[] = {
- 0, 0, 0, 0, 1, 1, 1, 2, 0, 0, 0, 0,
- 0, 0, 3, 4, 1, 1, 1, 5, 6, 6, 0, 0,
- 0, 3, 3, 7, 1, 1, 1, 1, 2, 1, 6, 0,
- 0, 3, 3, 3, 3, 1, 1, 8, 6, 1, 6, 0,
- 9, 9, 3, 3, 1, 1, 2, 10,8, 1, 1, 2,
- 11,9, 3, 3, 1, 1, 1, 1, 1, 1, 5, 1,
- 9, 9, 12,3, 3, 1, 1, 1, 1, 1, 1, 1,
- 9, 9, 9, 3, 3, 3, 3, 3, 1, 1, 1, 1,
- 0, 11,9, 9, 12,3, 3, 3, 3, 3, 3, 0,
- 0, 9, 9, 13,9, 14,12,3, 3, 3, 3, 0,
- 0, 0, 9, 9, 9, 12,14,3, 13,3, 0, 0,
- 0, 0, 0, 0, 11,9, 11,9, 0, 0, 0, 0
-};
-
-////////////////////////////////////////
-// Yellow Marble Cursor Palette:
-// Palette For The Yellow Marble Cursor
-////////////////////////////////////////
-static const byte s_yellowMarbleCursorPalette[] = {
- 0xb3, 0xd0, 0x00,
- 0xb0, 0xff, 0x00,
- 0x86, 0x9c, 0x00,
- 0x87, 0xd0, 0x00,
- 0xe0, 0xd0, 0x00,
- 0xdc, 0xff, 0x00,
- 0xb3, 0x9d, 0x00,
- 0xdc, 0xff, 0x11,
- 0x5a, 0x68, 0x00,
- 0xe1, 0xff, 0x5a,
- 0x5d, 0x67, 0x30,
- 0x87, 0x69, 0x00,
- 0x88, 0x9b, 0x2a,
- 0x5a, 0x9c, 0x00
-};
-
-////////////////////////////////////////
-// Green Marble Cursor (12x12):
-// Cursor When Holding The Green Marble
-////////////////////////////////////////
-static const byte s_greenMarbleCursor[] = {
- 0, 0, 0, 0, 1, 2, 3, 3, 0, 0, 0, 0,
- 0, 0, 4, 5, 2, 1, 2, 3, 6, 6, 0, 0,
- 0, 7, 5, 8, 8, 1, 1, 2, 3, 6, 6, 0,
- 0, 7, 7, 4, 8, 1, 2, 9, 6, 2, 6, 0,
- 10,7, 7, 4, 1, 2, 3, 11,12,2, 2, 3,
- 13,13,7, 4, 1, 2, 3, 2, 1, 2, 2, 3,
- 14,13,7, 7, 5, 1, 1, 8, 2, 1, 1, 2,
- 15,16,13,7, 4, 4, 5, 5, 1, 8, 1, 1,
- 0, 15,13,7, 7, 7, 4, 4, 4, 5, 8, 0,
- 0, 14,16,15,13, 7, 7, 7, 4,17,5, 0,
- 0, 0, 10,16,13,13,13,17,18,17,0, 0,
- 0, 0, 0, 0, 15,10,19,10,0, 0, 0, 0
-};
-
-////////////////////////////////////////
-// Green Marble Cursor Palette:
-// Palette For The Green Marble Cursor
-////////////////////////////////////////
-static const byte s_greenMarbleCursorPalette[] = {
- 0x0e, 0xd0, 0x00,
- 0x0f, 0xe1, 0x00,
- 0x10, 0xf2, 0x00,
- 0x0b, 0x9c, 0x00,
- 0x0c, 0xad, 0x00,
- 0x11, 0xff, 0x00,
- 0x09, 0x8a, 0x00,
- 0x0d, 0xbe, 0x00,
- 0x30, 0xff, 0x5a,
- 0x0d, 0x67, 0x30,
- 0x6b, 0xff, 0x92,
- 0x00, 0xff, 0x28,
- 0x08, 0x79, 0x00,
- 0x05, 0x57, 0x00,
- 0x30, 0x67, 0x30,
- 0x06, 0x68, 0x00,
- 0x00, 0x9b, 0x2c,
- 0x2e, 0x9c, 0x00,
- 0x2e, 0x68, 0x00
-};
-
-////////////////////////////////////////
-// Blue Marble Cursor (12x12):
-// Cursor When Holding The Blue Marble
-////////////////////////////////////////
-static const byte s_blueMarbleCursor[] = {
- 0, 0, 0, 0, 1, 2, 3, 3, 0, 0, 0, 0,
- 0, 0, 4, 5, 2, 2, 6, 3, 7, 3, 0, 0,
- 0, 8, 9, 5, 10,11,2, 6, 3, 3, 7, 0,
- 0, 12,13,9, 10,11,6, 14,7, 6, 3, 0,
- 15,8, 4, 13,2, 6, 3, 16,17,6, 6, 3,
- 18,15,19,13,10,7, 3, 6, 2, 2, 6, 7,
- 20,8, 18,4, 21,11,2, 10,6, 2, 2, 2,
- 15,15,18,8, 13,9, 21,5, 11,10,2, 1,
- 0, 8, 15,19,15,13,13,21,21,5, 9, 0,
- 0, 22,20,15, 8,19,15,19,4, 9, 4, 0,
- 0, 0, 15,20,15,15,19,15,9, 15,0, 0,
- 0, 0, 0, 0, 20,15, 8,15,0, 0, 0, 0
-};
-
-////////////////////////////////////////
-// Blue Marble Cursor Palette:
-// Palette For The Blue Marble Cursor
-////////////////////////////////////////
-static const byte s_blueMarbleCursorPalette[] = {
- 0x6b, 0x00, 0xd2,
- 0x66, 0x00, 0xe3,
- 0x72, 0x00, 0xff,
- 0x53, 0x2d, 0x9d,
- 0x4e, 0x00, 0xaf,
- 0x6d, 0x00, 0xf5,
- 0x7d, 0x00, 0xff,
- 0x44, 0x00, 0x69,
- 0x56, 0x00, 0x9d,
- 0x56, 0x00, 0xc0,
- 0x5e, 0x00, 0xd2,
- 0x2b, 0x31, 0x68,
- 0x3f, 0x00, 0x8c,
- 0x91, 0x22, 0xff,
- 0x41, 0x31, 0x68,
- 0xd7, 0x95, 0xff,
- 0x77, 0x22, 0xff,
- 0x2f, 0x00, 0x69,
- 0x37, 0x00, 0x7a,
- 0x27, 0x00, 0x58,
- 0x46, 0x00, 0x9d,
- 0x33, 0x33, 0x33
-};
-
-////////////////////////////////////////
-// Violet Marble Cursor (12x12):
-// Cursor When Holding The Violet Marble
-////////////////////////////////////////
-static const byte s_violetMarbleCursor[] = {
- 0, 0, 0, 0, 1, 1, 1, 2, 0, 0, 0, 0,
- 0, 0, 3, 3, 1, 1, 1, 4, 2, 4, 0, 0,
- 0, 3, 3, 3, 1, 5, 1, 1, 4, 2, 4, 0,
- 0, 3, 3, 3, 3, 1, 1, 6, 4, 1, 2, 0,
- 3, 7, 8, 3, 1, 1, 4, 9, 4, 1, 1, 4,
- 8, 7, 8, 3, 10,4, 1, 1, 1, 1, 4, 1,
- 8, 3, 8, 7, 3, 1, 1, 5, 1, 1, 1, 1,
- 7, 7, 11,3, 3, 3, 3, 3, 1, 3, 1, 1,
- 0, 8, 7, 7, 8, 8, 7, 3, 3, 3, 1, 0,
- 0, 7, 8, 3, 11,7, 3, 11,3, 10,3, 0,
- 0, 0, 8, 7, 3, 3, 7, 3, 3, 3, 0, 0,
- 0, 0, 0, 0, 8, 7, 11,3, 0, 0, 0, 0
-};
-
-////////////////////////////////////////
-// Violet Marble Cursor Palette:
-// Palette For The Violet Marble Cursor
-////////////////////////////////////////
-static const byte s_violetMarbleCursorPalette[] = {
- 0xaa, 0x00, 0xd1,
- 0xd8, 0x00, 0xff,
- 0x76, 0x00, 0x9d,
- 0xb5, 0x00, 0xff,
- 0x87, 0x00, 0xd2,
- 0xd7, 0x22, 0xff,
- 0x68, 0x00, 0x69,
- 0x44, 0x00, 0x69,
- 0xd7, 0x5e, 0xff,
- 0x9c, 0x00, 0x9d,
- 0x56, 0x00, 0x9d
-};
-
-} // End of namespace Mohawk
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index 7da5515411..e6ea25c9a6 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -316,6 +316,7 @@ void RivenExternal::checkSliderCursorChange(uint16 startHotspot) {
_vm->_cursor->setCursor(kRivenOpenHandCursor);
else
_vm->_cursor->setCursor(kRivenMainCursor);
+ _vm->_system->updateScreen();
break;
}
}
@@ -341,6 +342,7 @@ void RivenExternal::dragDomeSlider(uint16 soundId, uint16 resetSlidersHotspot, u
// We've clicked down, so show the closed hand cursor
_vm->_cursor->setCursor(kRivenClosedHandCursor);
+ _vm->_system->updateScreen();
bool done = false;
while (!done) {
@@ -862,6 +864,7 @@ void RivenExternal::xbcheckcatch(uint16 argc, uint16 *argv) {
void RivenExternal::xbait(uint16 argc, uint16 *argv) {
// Set the cursor to the pellet
_vm->_cursor->setCursor(kRivenPelletCursor);
+ _vm->_system->updateScreen();
// Loop until the player lets go (or quits)
Common::Event event;
@@ -881,6 +884,7 @@ void RivenExternal::xbait(uint16 argc, uint16 *argv) {
// Set back the cursor
_vm->_cursor->setCursor(kRivenMainCursor);
+ _vm->_system->updateScreen();
// Set the bait if we put it on the plate
if (_vm->_hotspots[9].rect.contains(_vm->_system->getEventManager()->getMousePos())) {
@@ -899,8 +903,8 @@ void RivenExternal::xbfreeytram(uint16 argc, uint16 *argv) {
void RivenExternal::xbaitplate(uint16 argc, uint16 *argv) {
// Remove the pellet from the plate and put it in your hand
_vm->_gfx->drawPLST(3);
- _vm->_gfx->updateScreen();
_vm->_cursor->setCursor(kRivenPelletCursor);
+ _vm->_gfx->updateScreen();
// Loop until the player lets go (or quits)
Common::Event event;
@@ -920,6 +924,7 @@ void RivenExternal::xbaitplate(uint16 argc, uint16 *argv) {
// Set back the cursor
_vm->_cursor->setCursor(kRivenMainCursor);
+ _vm->_system->updateScreen();
// Set the bait if we put it on the plate, remove otherwise
if (_vm->_hotspots[9].rect.contains(_vm->_system->getEventManager()->getMousePos())) {
@@ -988,23 +993,27 @@ void RivenExternal::xvalvecontrol(uint16 argc, uint16 *argv) {
if (*valve == 0 && changeY <= -10) {
*valve = 1;
_vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
_vm->_video->playMovieBlockingRiven(2);
_vm->refreshCard();
} else if (*valve == 1) {
if (changeX >= 0 && changeY >= 10) {
*valve = 0;
_vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
_vm->_video->playMovieBlockingRiven(3);
_vm->refreshCard();
} else if (changeX <= -10 && changeY <= 10) {
*valve = 2;
_vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
_vm->_video->playMovieBlockingRiven(1);
_vm->refreshCard();
}
} else if (*valve == 2 && changeX >= 10) {
*valve = 1;
_vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
_vm->_video->playMovieBlockingRiven(4);
_vm->refreshCard();
}
@@ -1219,6 +1228,7 @@ void RivenExternal::xgisland1490_domecheck(uint16 argc, uint16 *argv) {
void RivenExternal::xgplateau3160_dopools(uint16 argc, uint16 *argv) {
// Play the deactivation of a pool if one is active and a different one is activated
_vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
_vm->_video->playMovieBlockingRiven(*_vm->getVar("glkbtns") * 2);
}
@@ -1522,11 +1532,13 @@ void RivenExternal::xvga1300_carriage(uint16 argc, uint16 *argv) {
// Run the gallows's carriage
_vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor
- _vm->_video->playMovieBlockingRiven(1); // Play handle movie
+ _vm->_system->updateScreen(); // Update
+ _vm->_video->playMovieBlockingRiven(1); // Play handle movie
_vm->_gfx->scheduleTransition(15); // Set pan down transition
_vm->changeToCard(_vm->matchRMAPToCard(0x18e77)); // Change to card facing up
_vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor (again)
- _vm->_video->playMovieBlockingRiven(4); // Play carriage beginning to drop
+ _vm->_system->updateScreen(); // Update
+ _vm->_video->playMovieBlockingRiven(4); // Play carriage beginning to drop
_vm->_gfx->scheduleTransition(14); // Set pan up transition
_vm->changeToCard(_vm->matchRMAPToCard(0x183a9)); // Change to card looking straight again
_vm->_video->playMovieBlockingRiven(2);
@@ -1560,19 +1572,22 @@ void RivenExternal::xvga1300_carriage(uint16 argc, uint16 *argv) {
}
_vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor
+ _vm->_system->updateScreen(); // Update
if (gotClick) {
_vm->_gfx->scheduleTransition(16); // Schedule dissolve transition
_vm->changeToCard(_vm->matchRMAPToCard(0x18d4d)); // Move forward
_vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor
+ _vm->_system->updateScreen(); // Update
_vm->_system->delayMillis(500); // Delay a half second before changing again
_vm->_gfx->scheduleTransition(12); // Schedule pan left transition
_vm->changeToCard(_vm->matchRMAPToCard(0x18ab5)); // Turn right
_vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor
- _vm->_video->playMovieBlockingRiven(1); // Play carriage ride movie
+ _vm->_system->updateScreen(); // Update
+ _vm->_video->playMovieBlockingRiven(1); // Play carriage ride movie
_vm->changeToCard(_vm->matchRMAPToCard(0x17167)); // We have arrived at the top
} else
- _vm->_video->playMovieBlockingRiven(3); // Too slow!
+ _vm->_video->playMovieBlockingRiven(3); // Too slow!
}
void RivenExternal::xjdome25_resetsliders(uint16 argc, uint16 *argv) {
@@ -1603,6 +1618,7 @@ int RivenExternal::jspitElevatorLoop() {
_vm->_cursor->setCursor(kRivenClosedHandCursor);
_vm->_system->updateScreen();
+
for (;;) {
while (_vm->_system->getEventManager()->pollEvent(event)) {
switch (event.type) {
@@ -1766,6 +1782,7 @@ void RivenExternal::xschool280_playwhark(uint16 argc, uint16 *argv) {
// Hide the cursor
_vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
// Play the spin movie
_vm->_video->playMovieBlockingRiven(spinMLST);
@@ -1831,6 +1848,7 @@ void RivenExternal::xorollcredittime(uint16 argc, uint16 *argv) {
void RivenExternal::xbookclick(uint16 argc, uint16 *argv) {
// Hide the cursor
_vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
// Let's hook onto our video
VideoHandle video = _vm->_video->findVideoHandleRiven(argv[0]);
@@ -1873,6 +1891,8 @@ void RivenExternal::xbookclick(uint16 argc, uint16 *argv) {
_vm->_cursor->setCursor(kRivenOpenHandCursor);
else
_vm->_cursor->setCursor(kRivenMainCursor);
+
+ _vm->_system->updateScreen();
// OK, Gehn has opened the trap book and has asked us to go in. Let's watch
// and see what the player will do...
@@ -1887,7 +1907,7 @@ void RivenExternal::xbookclick(uint16 argc, uint16 *argv) {
_vm->_cursor->setCursor(kRivenOpenHandCursor);
else
_vm->_cursor->setCursor(kRivenMainCursor);
- updateScreen = false; // Don't update twice, changing the cursor already updates the screen
+ updateScreen = true;
break;
case Common::EVENT_LBUTTONUP:
if (hotspotRect.contains(_vm->_system->getEventManager()->getMousePos())) {
@@ -1899,7 +1919,7 @@ void RivenExternal::xbookclick(uint16 argc, uint16 *argv) {
_vm->_gfx->updateScreen(); // Update the screen
_vm->_sound->playSound(0); // Play the link sound
_vm->_video->activateMLST(7, _vm->getCurCard()); // Activate Gehn Link Video
- _vm->_video->playMovieBlockingRiven(1); // Play Gehn Link Video
+ _vm->_video->playMovieBlockingRiven(1); // Play Gehn Link Video
*_vm->getVar("agehn") = 4; // Set Gehn to the trapped state
*_vm->getVar("atrapbook") = 1; // We've got the trap book again
_vm->_sound->playSound(0); // Play the link sound again
@@ -1924,6 +1944,7 @@ void RivenExternal::xbookclick(uint16 argc, uint16 *argv) {
// Hide the cursor again
_vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
// If there was no click and this is the third time Gehn asks us to
// use the trap book, he will shoot the player. Dead on arrival.
@@ -2012,6 +2033,7 @@ uint16 RivenExternal::getComboDigit(uint32 correctCombo, uint32 digit) {
void RivenExternal::xgwatch(uint16 argc, uint16 *argv) {
// Hide the cursor
_vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
uint32 *prisonCombo = _vm->getVar("pcorrectorder");
uint32 soundTime = _vm->_system->getMillis() - 500; // Start the first sound instantly
@@ -2173,6 +2195,7 @@ void RivenExternal::xtexterior300_telescopedown(uint16 argc, uint16 *argv) {
// ...the telescope can't move down anymore.
// Play the sound of not being able to move
_vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
_vm->_sound->playSoundBlocking(13);
}
} else {
@@ -2206,6 +2229,7 @@ void RivenExternal::xtexterior300_telescopeup(uint16 argc, uint16 *argv) {
if (*telescopePos == 5) {
// Play the sound of not being able to move
_vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
_vm->_sound->playSoundBlocking(13);
return;
}
diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp
index 5d459354e9..98452e1e09 100644
--- a/engines/mohawk/riven_scripts.cpp
+++ b/engines/mohawk/riven_scripts.cpp
@@ -424,6 +424,7 @@ void RivenScript::stopSound(uint16 op, uint16 argc, uint16 *argv) {
void RivenScript::changeCursor(uint16 op, uint16 argc, uint16 *argv) {
debug(2, "Change to cursor %d", argv[0]);
_vm->_cursor->setCursor(argv[0]);
+ _vm->_system->updateScreen();
}
// Command 14: pause script execution (delay in ms, u1)
diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp
index 09f08e4b15..9d1c3dabd6 100644
--- a/engines/sci/graphics/cursor.cpp
+++ b/engines/sci/graphics/cursor.cpp
@@ -26,6 +26,7 @@
#include "common/config-manager.h"
#include "common/events.h"
#include "common/macresman.h"
+#include "common/memstream.h"
#include "common/system.h"
#include "common/util.h"
#include "graphics/cursorman.h"
@@ -491,8 +492,8 @@ void GfxCursor::kernelSetMacCursor(GuiResourceId viewNum, int loopNum, int celNu
cursorBitmap[i * 8 + b] = 0; // Doesn't matter, just is transparent
}
- uint16 hotspotX = READ_BE_UINT16(data);
- uint16 hotspotY = READ_BE_UINT16(data + 2);
+ uint16 hotspotY = READ_BE_UINT16(data);
+ uint16 hotspotX = READ_BE_UINT16(data + 2);
static const byte cursorPalette[] = { 0x00, 0x00, 0x00, 0xff, 0xff, 0xff };
@@ -504,11 +505,12 @@ void GfxCursor::kernelSetMacCursor(GuiResourceId viewNum, int loopNum, int celNu
// Mac crsr cursor
byte *cursorBitmap, *palette;
int width, height, hotspotX, hotspotY, palSize, keycolor;
- Common::MacResManager::convertCrsrCursor(resource->data, resource->size, &cursorBitmap, &width, &height, &hotspotX, &hotspotY, &keycolor, true, &palette, &palSize);
+ Common::MemoryReadStream resStream(resource->data, resource->size);
+ Common::MacResManager::convertCrsrCursor(&resStream, &cursorBitmap, width, height, hotspotX, hotspotY, keycolor, true, &palette, palSize);
CursorMan.replaceCursor(cursorBitmap, width, height, hotspotX, hotspotY, keycolor);
CursorMan.replaceCursorPalette(palette, 0, palSize);
- free(cursorBitmap);
- free(palette);
+ delete[] cursorBitmap;
+ delete[] palette;
}
kernelShow();
diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp
index 72e7052034..9349e70eb9 100644
--- a/engines/scumm/he/resource_he.cpp
+++ b/engines/scumm/he/resource_he.cpp
@@ -4,10 +4,6 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * Parts of this code are heavily based on:
- * icoutils - A set of programs dealing with MS Windows icons and cursors.
- * Copyright (C) 1998-2001 Oskar Liljeblad
- *
* 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
@@ -36,6 +32,7 @@
#include "audio/decoders/wave.h"
#include "graphics/cursorman.h"
+#include "graphics/wincursor.h"
#include "common/archive.h"
#include "common/memstream.h"
@@ -43,14 +40,6 @@
namespace Scumm {
-#if defined(SCUMM_LITTLE_ENDIAN)
-#define LE16(x)
-#define LE32(x)
-#elif defined(SCUMM_BIG_ENDIAN)
-#define LE16(x) ((x) = TO_LE_16(x))
-#define LE32(x) ((x) = TO_LE_32(x))
-#endif
-
ResExtractor::ResExtractor(ScummEngine_v70he *scumm)
: _vm(scumm) {
@@ -65,1092 +54,112 @@ ResExtractor::~ResExtractor() {
free(cc->palette);
}
}
+
memset(_cursorCache, 0, sizeof(_cursorCache));
}
ResExtractor::CachedCursor *ResExtractor::findCachedCursor(int id) {
- for (int i = 0; i < MAX_CACHED_CURSORS; ++i) {
- CachedCursor *cc = &_cursorCache[i];
- if (cc->valid && cc->id == id) {
- return cc;
- }
- }
+ for (int i = 0; i < MAX_CACHED_CURSORS; ++i)
+ if (_cursorCache[i].valid && _cursorCache[i].id == id)
+ return &_cursorCache[i];
+
return NULL;
}
ResExtractor::CachedCursor *ResExtractor::getCachedCursorSlot() {
- uint32 min_last_used = 0;
+ uint32 minLastUsed = 0;
CachedCursor *r = NULL;
+
for (int i = 0; i < MAX_CACHED_CURSORS; ++i) {
CachedCursor *cc = &_cursorCache[i];
- if (!cc->valid) {
+ if (!cc->valid)
return cc;
- } else {
- if (min_last_used == 0 || cc->last_used < min_last_used) {
- min_last_used = cc->last_used;
- r = cc;
- }
+
+ if (minLastUsed == 0 || cc->lastUsed < minLastUsed) {
+ minLastUsed = cc->lastUsed;
+ r = cc;
}
}
+
assert(r);
- free(r->bitmap);
- free(r->palette);
+ delete[] r->bitmap;
+ delete[] r->palette;
memset(r, 0, sizeof(CachedCursor));
return r;
}
void ResExtractor::setCursor(int id) {
- byte *cursorRes = 0;
- int cursorsize;
- int keycolor = 0;
CachedCursor *cc = findCachedCursor(id);
+
if (cc != NULL) {
debug(7, "Found cursor %d in cache slot %lu", id, (long)(cc - _cursorCache));
} else {
cc = getCachedCursorSlot();
assert(cc && !cc->valid);
- cursorsize = extractResource(id, &cursorRes);
- convertIcons(cursorRes, cursorsize, &cc->bitmap, &cc->w, &cc->h, &cc->hotspot_x, &cc->hotspot_y, &keycolor, &cc->palette, &cc->palSize);
+
+ if (!extractResource(id, cc))
+ error("Could not extract cursor %d", id);
+
debug(7, "Adding cursor %d to cache slot %lu", id, (long)(cc - _cursorCache));
- free(cursorRes);
+
cc->valid = true;
cc->id = id;
- cc->last_used = g_system->getMillis();
+ cc->lastUsed = g_system->getMillis();
}
if (cc->palette)
CursorMan.replaceCursorPalette(cc->palette, 0, cc->palSize);
- _vm->setCursorHotspot(cc->hotspot_x, cc->hotspot_y);
- _vm->setCursorFromBuffer(cc->bitmap, cc->w, cc->h, cc->w);
+ _vm->setCursorHotspot(cc->hotspotX, cc->hotspotY);
+ _vm->setCursorFromBuffer(cc->bitmap, cc->width, cc->height, cc->width);
}
-/*
- * Static variables
- */
-const char *res_types[] = {
- /* 0x01: */
- "cursor", "bitmap", "icon", "menu", "dialog", "string",
- "fontdir", "font", "accelerator", "rcdata", "messagelist",
- "group_cursor", NULL, "group_icon", NULL,
- /* the following are not defined in winbase.h, but found in wrc. */
- /* 0x10: */
- "version", "dlginclude", NULL, "plugplay", "vxd",
- "anicursor", "aniicon"
-};
-#define RES_TYPE_COUNT (sizeof(res_types)/sizeof(char *))
-
Win32ResExtractor::Win32ResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) {
}
-int Win32ResExtractor::extractResource(int resId, byte **data) {
- char buf[20];
-
- snprintf(buf, sizeof(buf), "%d", resId);
-
- return extractResource_("group_cursor", buf, data);
-}
-
-int Win32ResExtractor::extractResource_(const char *resType, char *resName, byte **data) {
- char *arg_language = NULL;
- const char *arg_type = resType;
- char *arg_name = resName;
- int ressize = 0;
-
- _arg_raw = false;
-
- /* translate --type option from resource type string to integer */
- arg_type = res_type_string_to_id(arg_type);
-
- WinLibrary fi;
-
- /* initiate stuff */
- fi.memory = NULL;
- fi.file = NULL;
-
+bool Win32ResExtractor::extractResource(int id, CachedCursor *cc) {
if (_fileName.empty()) { // We are running for the first time
_fileName = _vm->generateFilename(-3);
- }
-
- /* get file size */
- fi.file = SearchMan.createReadStreamForMember(_fileName);
- if (!fi.file) {
- error("Cannot open file %s", _fileName.c_str());
- }
-
- fi.total_size = fi.file->size();
- if (fi.total_size == -1) {
- error("Cannot get size of file %s", _fileName.c_str());
- goto cleanup;
- }
- if (fi.total_size == 0) {
- error("%s: file has a size of 0", _fileName.c_str());
- goto cleanup;
- }
-
- /* read all of file */
- fi.memory = (byte *)malloc(fi.total_size);
- if (fi.file->read(fi.memory, fi.total_size) == 0) {
- error("Cannot read from file %s", _fileName.c_str());
- goto cleanup;
- }
-
- /* identify file and find resource table */
- if (!read_library(&fi)) {
- /* error reported by read_library */
- goto cleanup;
- }
-
- /* errors will be printed by the callback */
- ressize = do_resources(&fi, arg_type, arg_name, arg_language, data);
-
- /* free stuff and close file */
- cleanup:
- delete fi.file;
- free(fi.memory);
-
- return ressize;
-}
-
-
-/**
- * Translate a numeric resource type to it's corresponding string type.
- * (For informative-ness.)
- */
-const char *Win32ResExtractor::res_type_id_to_string(int id) {
- if (id == 241)
- return "toolbar";
- if (id > 0 && id <= (int)RES_TYPE_COUNT)
- return res_types[id-1];
- return NULL;
-}
-
-/**
- * Translate a resource type string to integer.
- * (Used to convert the --type option.)
- */
-const char *Win32ResExtractor::res_type_string_to_id(const char *type) {
- static const char *res_type_ids[] = {
- "-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9", "-10",
- "-11", "-12", NULL, "-14", NULL, "-16", "-17", NULL, "-19",
- "-20", "-21", "-22"
- };
- int c;
-
- if (type == NULL)
- return NULL;
-
- for (c = 0; c < (int)RES_TYPE_COUNT; c++) {
- if (res_types[c] != NULL && !scumm_stricmp(type, res_types[c]))
- return res_type_ids[c];
- }
-
- return type;
-}
-
-/**
- * Return the resource id quoted if it is a string, otherwise (i.e. if
- * it is numeric) just return it.
- */
-Common::String Win32ResExtractor::WinResource::getQuotedResourceId() const {
- if (numeric_id || id[0] == '\0')
- return id;
- return '"' + Common::String(id) + '"';
-}
-
-int Win32ResExtractor::extract_resources(WinLibrary *fi, WinResource *wr,
- WinResource *type_wr, WinResource *name_wr,
- WinResource *lang_wr, byte **data) {
- int size;
- bool free_it;
- const char *type;
- int32 id;
-
- if (*data) {
- error("Win32ResExtractor::extract_resources() more than one cursor");
- return 0;
- }
-
- *data = extract_resource(fi, wr, &size, &free_it, type_wr->id, (lang_wr == NULL ? NULL : lang_wr->id), _arg_raw);
-
- if (data == NULL) {
- error("Win32ResExtractor::extract_resources() problem with resource extraction");
- return 0;
- }
-
- /* get named resource type if possible */
- type = NULL;
- if ((id = strtol(type_wr->id, 0, 10)) != 0)
- type = res_type_id_to_string(id);
-
- if (lang_wr != NULL && lang_wr->id[0] != '\0') {
- debugC(DEBUG_RESOURCE, "extractCursor(). Found cursor name: %s language: %s [size=%d]",
- name_wr->getQuotedResourceId().c_str(), lang_wr->getQuotedResourceId().c_str(), size);
- } else {
- debugC(DEBUG_RESOURCE, "extractCursor(). Found cursor name: %s [size=%d]",
- name_wr->getQuotedResourceId().c_str(), size);
- }
- return size;
-}
-
-/**
- * Extract a resource, returning pointer to data.
- */
-byte *Win32ResExtractor::extract_resource(WinLibrary *fi, WinResource *wr, int *size,
- bool *free_it, char *type, char *lang, bool raw) {
- char *str;
- int32 intval;
-
- /* just return pointer to data if raw */
- if (raw) {
- *free_it = false;
- /* get_resource_entry will print possible error */
- return get_resource_entry(fi, wr, size);
- }
-
- /* find out how to extract */
- str = type;
- if (str != NULL && (intval = strtol(STRIP_RES_ID_FORMAT(str), 0, 10))) {
- if (intval == (int)RT_GROUP_ICON) {
- *free_it = true;
- return extract_group_icon_cursor_resource(fi, wr, lang, size, true);
- }
- if (intval == (int)RT_GROUP_CURSOR) {
- *free_it = true;
- return extract_group_icon_cursor_resource(fi, wr, lang, size, false);
- }
- }
-
- return NULL;
-}
-
-/**
- * Create a complete RT_GROUP_ICON resource, that can be written to
- * an `.ico' file without modifications. Returns an allocated
- * memory block that should be freed with free() once used.
- *
- * `root' is the offset in file that specifies the resource.
- * `base' is the offset that string pointers are calculated from.
- * `ressize' should point to an integer variable where the size of
- * the returned memory block will be placed.
- * `is_icon' indicates whether resource to be extracted is icon
- * or cursor group.
- */
-byte *Win32ResExtractor::extract_group_icon_cursor_resource(WinLibrary *fi, WinResource *wr, char *lang,
- int *ressize, bool is_icon) {
- Win32CursorIconDir *icondir;
- Win32CursorIconFileDir *fileicondir;
- byte *memory;
- int c, offset, skipped;
- int size;
-
- /* get resource data and size */
- icondir = (Win32CursorIconDir *)get_resource_entry(fi, wr, &size);
- if (icondir == NULL) {
- /* get_resource_entry will print error */
- return NULL;
- }
-
- /* calculate total size of output file */
- RETURN_IF_BAD_POINTER(NULL, icondir->count);
- skipped = 0;
- for (c = 0; c < FROM_LE_16(icondir->count); c++) {
- int level;
- int iconsize;
- char name[14];
- WinResource *fwr;
-
- RETURN_IF_BAD_POINTER(NULL, icondir->entries[c]);
- /*debug("%d. bytes_in_res=%d width=%d height=%d planes=%d bit_count=%d", c,
- FROM_LE_32(icondir->entries[c].bytes_in_res),
- (is_icon ? icondir->entries[c].res_info.icon.width : FROM_LE_16(icondir->entries[c].res_info.cursor.width)),
- (is_icon ? icondir->entries[c].res_info.icon.height : FROM_LE_16(icondir->entries[c].res_info.cursor.height)),
- FROM_LE_16(icondir->entries[c].plane_count),
- FROM_LE_16(icondir->entries[c].bit_count));*/
-
- /* find the corresponding icon resource */
- snprintf(name, sizeof(name)/sizeof(char), "-%d", FROM_LE_16(icondir->entries[c].res_id));
- fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level);
- if (fwr == NULL) {
- error("%s: could not find `%s' in `%s' resource.",
- _fileName.c_str(), &name[1], (is_icon ? "group_icon" : "group_cursor"));
- return NULL;
- }
-
- if (get_resource_entry(fi, fwr, &iconsize) != NULL) {
- if (iconsize == 0) {
- debugC(DEBUG_RESOURCE, "%s: icon resource `%s' is empty, skipping", _fileName.c_str(), name);
- skipped++;
- continue;
- }
- if ((uint32)iconsize != FROM_LE_32(icondir->entries[c].bytes_in_res)) {
- debugC(DEBUG_RESOURCE, "%s: mismatch of size in icon resource `%s' and group (%d != %d)",
- _fileName.c_str(), name, iconsize, FROM_LE_32(icondir->entries[c].bytes_in_res));
- }
- size += iconsize; /* size += FROM_LE_32(icondir->entries[c].bytes_in_res); */
- /* cursor resources have two additional WORDs that contain
- * hotspot info */
- if (!is_icon)
- size -= sizeof(uint16)*2;
- }
- }
- offset = sizeof(Win32CursorIconFileDir) + (FROM_LE_16(icondir->count)-skipped) * sizeof(Win32CursorIconFileDirEntry);
- size += offset;
- *ressize = size;
-
- /* allocate that much memory */
- memory = (byte *)malloc(size);
- fileicondir = (Win32CursorIconFileDir *)memory;
-
- /* transfer Win32CursorIconDir structure members */
- fileicondir->reserved = icondir->reserved;
- fileicondir->type = icondir->type;
- fileicondir->count = TO_LE_16(FROM_LE_16(icondir->count) - skipped);
-
- /* transfer each cursor/icon: Win32CursorIconDirEntry and data */
- skipped = 0;
- for (c = 0; c < FROM_LE_16(icondir->count); c++) {
- int level;
- char name[14];
- WinResource *fwr;
- byte *data;
-
- /* find the corresponding icon resource */
- snprintf(name, sizeof(name)/sizeof(char), "-%d", FROM_LE_16(icondir->entries[c].res_id));
- fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level);
- if (fwr == NULL) {
- error("%s: could not find `%s' in `%s' resource.",
- _fileName.c_str(), &name[1], (is_icon ? "group_icon" : "group_cursor"));
- return NULL;
- }
-
- /* get data and size of that resource */
- data = (byte *)get_resource_entry(fi, fwr, &size);
- if (data == NULL) {
- /* get_resource_entry has printed error */
- return NULL;
- }
- if (size == 0) {
- skipped++;
- continue;
- }
-
- /* copy ICONDIRENTRY (not including last dwImageOffset) */
- memcpy(&fileicondir->entries[c-skipped], &icondir->entries[c],
- sizeof(Win32CursorIconFileDirEntry)-sizeof(uint32));
-
- /* special treatment for cursors */
- if (!is_icon) {
- fileicondir->entries[c-skipped].width = icondir->entries[c].res_info.cursor.width;
- fileicondir->entries[c-skipped].height = TO_LE_16(FROM_LE_16(icondir->entries[c].res_info.cursor.height) / 2);
- fileicondir->entries[c-skipped].color_count = 0;
- fileicondir->entries[c-skipped].reserved = 0;
- }
-
- /* set image offset and increase it */
- fileicondir->entries[c-skipped].dib_offset = TO_LE_32(offset);
-
- /* transfer resource into file memory */
- if (is_icon) {
- memcpy(&memory[offset], data, FROM_LE_32(icondir->entries[c].bytes_in_res));
- } else {
- fileicondir->entries[c-skipped].hotspot_x = ((uint16 *) data)[0];
- fileicondir->entries[c-skipped].hotspot_y = ((uint16 *) data)[1];
- memcpy(&memory[offset], data+sizeof(uint16)*2,
- FROM_LE_32(icondir->entries[c].bytes_in_res)-sizeof(uint16)*2);
- offset -= sizeof(uint16)*2;
- }
-
- /* increase the offset pointer */
- offset += FROM_LE_32(icondir->entries[c].bytes_in_res);
+ if (!_exe.loadFromEXE(_fileName))
+ error("Cannot open file %s", _fileName.c_str());
}
- return memory;
-}
-
-/**
- * Check if a chunk of data (determined by offset and size)
- * is within the bounds of the WinLibrary file.
- * Usually not called directly.
- */
-bool Win32ResExtractor::check_offset(byte *memory, int total_size, const char *name, void *offset, int size) {
- int need_size = (int)((byte *)offset - memory + size);
-
- debugC(DEBUG_RESOURCE, "check_offset: size=%x vs %x offset=%x size=%x",
- need_size, total_size, (uint)((byte *)offset - memory), size);
+ Graphics::WinCursorGroup *group = Graphics::WinCursorGroup::createCursorGroup(_exe, id);
- if (need_size < 0 || need_size > total_size) {
- error("%s: premature end", name);
+ if (!group)
return false;
- }
-
- return true;
-}
-
-
-/**
- * Do something for each resource matching type, name and lang.
- */
-int Win32ResExtractor::do_resources(WinLibrary *fi, const char *type, char *name, char *lang, byte **data) {
- WinResource *type_wr;
- WinResource *name_wr;
- WinResource *lang_wr;
- int size;
-
- type_wr = (WinResource *)calloc(3, sizeof(WinResource));
- name_wr = type_wr + 1;
- lang_wr = type_wr + 2;
-
- size = do_resources_recurs(fi, NULL, type_wr, name_wr, lang_wr, type, name, lang, data);
-
- free(type_wr);
-
- return size;
-}
-
-/* what is each entry in this directory level for? type, name or language? */
-#define WINRESOURCE_BY_LEVEL(x) ((x)==0 ? type_wr : ((x)==1 ? name_wr : lang_wr))
-
-/* does the id of this entry match the specified id? */
-#define LEVEL_MATCHES(x) (x == NULL || x ## _wr->id[0] == '\0' || compare_resource_id(x ## _wr, x))
-int Win32ResExtractor::do_resources_recurs(WinLibrary *fi, WinResource *base,
- WinResource *type_wr, WinResource *name_wr, WinResource *lang_wr,
- const char *type, char *name, char *lang, byte **data) {
- int c, rescnt;
- WinResource *wr;
- uint32 size = 0;
+ Graphics::WinCursor *cursor = group->cursors[0].cursor;
- /* get a list of all resources at this level */
- wr = list_resources(fi, base, &rescnt);
- if (wr == NULL) {
- return size;
- }
-
- /* process each resource listed */
- for (c = 0; c < rescnt; c++) {
- /* (over)write the corresponding WinResource holder with the current */
- memcpy(WINRESOURCE_BY_LEVEL(wr[c].level), wr+c, sizeof(WinResource));
-
- /* go deeper unless there is something that does NOT match */
- if (LEVEL_MATCHES(type) && LEVEL_MATCHES(name) && LEVEL_MATCHES(lang)) {
- if (wr->is_directory)
- size = do_resources_recurs(fi, wr+c, type_wr, name_wr, lang_wr, type, name, lang, data);
- else
- size = extract_resources(fi, wr+c, type_wr, name_wr, lang_wr, data);
- }
- }
-
- /* since we're moving back one level after this, unset the
- * WinResource holder used on this level */
- memset(WINRESOURCE_BY_LEVEL(wr[0].level), 0, sizeof(WinResource));
-
- return size;
-}
-
-bool Win32ResExtractor::compare_resource_id(WinResource *wr, const char *id) {
- if (wr->numeric_id) {
- int32 cmp1, cmp2;
- if (id[0] == '+')
- return false;
- if (id[0] == '-')
- id++;
- cmp1 = strtol(wr->id, 0, 10);
- cmp2 = strtol(id, 0, 10);
- if (!cmp1 || !cmp2 || cmp1 != cmp2)
- return false;
- } else {
- if (id[0] == '-')
- return false;
- if (id[0] == '+')
- id++;
- if (strcmp(wr->id, id))
- return false;
- }
+ cc->bitmap = new byte[cursor->getWidth() * cursor->getHeight()];
+ cc->width = cursor->getWidth();
+ cc->height = cursor->getHeight();
+ cc->hotspotX = cursor->getHotspotX();
+ cc->hotspotY = cursor->getHotspotY();
- return true;
-}
+ // Convert from the paletted format to the SCUMM palette
+ const byte *srcBitmap = cursor->getSurface();
-bool Win32ResExtractor::decode_pe_resource_id(WinLibrary *fi, WinResource *wr, uint32 value) {
- if (value & IMAGE_RESOURCE_NAME_IS_STRING) { /* numeric id */
- int c, len;
- uint16 *mem = (uint16 *)
- (fi->first_resource + (value & ~IMAGE_RESOURCE_NAME_IS_STRING));
-
- /* copy each char of the string, and terminate it */
- RETURN_IF_BAD_POINTER(false, *mem);
- len = FROM_LE_16(mem[0]);
- RETURN_IF_BAD_OFFSET(false, &mem[1], sizeof(uint16) * len);
-
- len = MIN(FROM_LE_16(mem[0]), (uint16)WINRES_ID_MAXLEN);
- for (c = 0; c < len; c++)
- wr->id[c] = FROM_LE_16(mem[c+1]) & 0x00FF;
- wr->id[len] = '\0';
- wr->numeric_id = false;
- } else { /* Unicode string id */
- /* translate id into a string */
- snprintf(wr->id, WINRES_ID_MAXLEN, "%d", value);
- wr->numeric_id = true;
+ for (int i = 0; i < cursor->getWidth() * cursor->getHeight(); i++) {
+ if (srcBitmap[i] == cursor->getKeyColor()) // Transparent
+ cc->bitmap[i] = 255;
+ else if (srcBitmap[i] == 0) // Black
+ cc->bitmap[i] = 253;
+ else // White
+ cc->bitmap[i] = 254;
}
+ delete group;
return true;
}
-byte *Win32ResExtractor::get_resource_entry(WinLibrary *fi, WinResource *wr, int *size) {
- byte *result;
-
- Win32ImageResourceDataEntry *dataent;
-
- dataent = (Win32ImageResourceDataEntry *) wr->children;
- RETURN_IF_BAD_POINTER(NULL, *dataent);
- *size = FROM_LE_32(dataent->size);
-
- result = fi->memory + FROM_LE_32(dataent->offset_to_data);
-
- RETURN_IF_BAD_OFFSET(NULL, result, *size);
-
- return result;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::list_pe_resources(WinLibrary *fi, Win32ImageResourceDirectory *pe_res, int level, int *count) {
- WinResource *wr;
- int c, rescnt;
- Win32ImageResourceDirectoryEntry *dirent
- = (Win32ImageResourceDirectoryEntry *)(pe_res + 1);
-
- /* count number of `type' resources */
- RETURN_IF_BAD_POINTER(NULL, *dirent);
- rescnt = FROM_LE_16(pe_res->number_of_named_entries) + FROM_LE_16(pe_res->number_of_id_entries);
- *count = rescnt;
-
- /* allocate WinResource's */
- wr = (WinResource *)malloc(sizeof(WinResource) * rescnt);
-
- /* fill in the WinResource's */
- for (c = 0; c < rescnt; c++) {
- RETURN_IF_BAD_POINTER(NULL, dirent[c]);
- wr[c].this_ = pe_res;
- wr[c].level = level;
- wr[c].is_directory = ((FROM_LE_32(dirent[c].offset_to_data) & IMAGE_RESOURCE_DATA_IS_DIRECTORY) != 0);
- wr[c].children = fi->first_resource + (FROM_LE_32(dirent[c].offset_to_data) & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY);
-
- /* fill in wr->id, wr->numeric_id */
- if (!decode_pe_resource_id(fi, wr + c, FROM_LE_32(dirent[c].name))) {
- free(wr);
- return NULL;
- }
- }
-
- return wr;
-}
-
-
-/**
- * Return an array of WinResource's in the current
- * resource level specified by _res->
- */
-Win32ResExtractor::WinResource *Win32ResExtractor::list_resources(WinLibrary *fi, WinResource *res, int *count) {
- if (res != NULL && !res->is_directory)
- return NULL;
-
- return list_pe_resources(fi, (Win32ImageResourceDirectory *)
- (res == NULL ? fi->first_resource : res->children),
- (res == NULL ? 0 : res->level+1),
- count);
-}
-
-/**
- * Read header and get resource directory offset in a Windows library
- * (AKA module).
- */
-bool Win32ResExtractor::read_library(WinLibrary *fi) {
- /* check for DOS header signature `MZ' */
- RETURN_IF_BAD_POINTER(false, MZ_HEADER(fi->memory)->magic);
- if (FROM_LE_16(MZ_HEADER(fi->memory)->magic) == IMAGE_DOS_SIGNATURE) {
- DOSImageHeader *mz_header = MZ_HEADER(fi->memory);
-
- RETURN_IF_BAD_POINTER(false, mz_header->lfanew);
-
- // Apply endian fix (currently only lfanew is used from the DOSImageHeader,
- // so we don't bother to 'fix' the rest).
- LE32(mz_header->lfanew);
-
- if (mz_header->lfanew < sizeof(DOSImageHeader)) {
- error("%s: not a Windows library", _fileName.c_str());
- return false;
- }
- }
-
- /* check for NT header signature `PE' */
- RETURN_IF_BAD_POINTER(false, PE_HEADER(fi->memory)->signature);
- if (FROM_LE_32(PE_HEADER(fi->memory)->signature) == IMAGE_NT_SIGNATURE) {
- Win32ImageNTHeaders *pe_header;
- int d;
-
- // Fix image header endianess
- fix_win32_image_header_endian(PE_HEADER(fi->memory));
-
- /* allocate new memory */
- fi->total_size = calc_vma_size(fi);
- if (fi->total_size == 0) {
- /* calc_vma_size has reported error */
- return false;
- }
- byte *ptr = (byte *)realloc(fi->memory, fi->total_size);
- assert(ptr);
- fi->memory = ptr;
-
- /* relocate memory, start from last section */
- pe_header = PE_HEADER(fi->memory);
- RETURN_IF_BAD_POINTER(false, pe_header->file_header.number_of_sections);
-
- /* we don't need to do OFFSET checking for the sections.
- * calc_vma_size has already done that */
- for (d = pe_header->file_header.number_of_sections - 1; d >= 0; d--) {
- Win32ImageSectionHeader *pe_sec = PE_SECTIONS(fi->memory) + d;
-
- if (pe_sec->characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
- continue;
-
- //if (pe_sec->virtual_address + pe_sec->size_of_raw_data > fi->total_size)
-
- RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->virtual_address, pe_sec->size_of_raw_data);
- RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->pointer_to_raw_data, pe_sec->size_of_raw_data);
- if (FROM_LE_32(pe_sec->virtual_address) != pe_sec->pointer_to_raw_data) {
- memmove(fi->memory + pe_sec->virtual_address,
- fi->memory + pe_sec->pointer_to_raw_data,
- pe_sec->size_of_raw_data);
- }
- }
-
- /* find resource directory */
- RETURN_IF_BAD_POINTER(false, pe_header->optional_header.data_directory[IMAGE_DIRECTORY_ENTRY_RESOURCE]);
- Win32ImageDataDirectory *dir = pe_header->optional_header.data_directory + IMAGE_DIRECTORY_ENTRY_RESOURCE;
- if (dir->size == 0) {
- error("%s: file contains no resources", _fileName.c_str());
- return false;
- }
-
- fix_win32_image_data_directory(dir);
-
- fi->first_resource = fi->memory + dir->virtual_address;
- return true;
- }
-
- /* other (unknown) header signature was found */
- error("%s: not a Windows library", _fileName.c_str());
- return false;
-}
-
-/**
- * Calculate the total amount of memory needed for a 32-bit Windows
- * module. Returns -1 if file was too small.
- */
-int Win32ResExtractor::calc_vma_size(WinLibrary *fi) {
- Win32ImageSectionHeader *seg;
- int c, segcount, size;
-
- size = 0;
- RETURN_IF_BAD_POINTER(-1, PE_HEADER(fi->memory)->file_header.number_of_sections);
- segcount = PE_HEADER(fi->memory)->file_header.number_of_sections;
-
- /* If there are no segments, just process file like it is.
- * This is (probably) not the right thing to do, but problems
- * will be delt with later anyway.
- */
- if (segcount == 0)
- return fi->total_size;
-
- seg = PE_SECTIONS(fi->memory);
- RETURN_IF_BAD_POINTER(-1, *seg);
- for (c = 0; c < segcount; c++) {
- RETURN_IF_BAD_POINTER(0, *seg);
- fix_win32_image_section_header(seg);
-
- size = MAX((uint32)size, seg->virtual_address + seg->size_of_raw_data);
- /* I have no idea what misc.virtual_size is for... */
- size = MAX((uint32)size, seg->virtual_address + seg->misc.virtual_size);
- seg++;
- }
-
- return size;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::find_with_resource_array(WinLibrary *fi, WinResource *wr, const char *id) {
- int c, rescnt;
- WinResource *return_wr;
-
- wr = list_resources(fi, wr, &rescnt);
- if (wr == NULL)
- return NULL;
-
- for (c = 0; c < rescnt; c++) {
- if (compare_resource_id(&wr[c], id)) {
- /* duplicate WinResource and return it */
- return_wr = (WinResource *)malloc(sizeof(WinResource));
- memcpy(return_wr, &wr[c], sizeof(WinResource));
-
- /* free old WinResource */
- free(wr);
- return return_wr;
- }
- }
-
- return NULL;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::find_resource(WinLibrary *fi, const char *type, const char *name, const char *language, int *level) {
- WinResource *wr;
-
- *level = 0;
- if (type == NULL)
- return NULL;
- wr = find_with_resource_array(fi, NULL, type);
- if (wr == NULL || !wr->is_directory)
- return wr;
-
- *level = 1;
- if (name == NULL)
- return wr;
- wr = find_with_resource_array(fi, wr, name);
- if (wr == NULL || !wr->is_directory)
- return wr;
-
- *level = 2;
- if (language == NULL)
- return wr;
- wr = find_with_resource_array(fi, wr, language);
- return wr;
-}
-
-#define ROW_BYTES(bits) ((((bits) + 31) >> 5) << 2)
-
-
-int Win32ResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
- int *hotspot_x, int *hotspot_y, int *keycolor, byte **pal, int *palSize) {
- Win32CursorIconFileDir dir;
- Win32CursorIconFileDirEntry *entries = NULL;
- uint32 offset;
- uint32 c, d;
- int completed;
- int matched = 0;
- Common::MemoryReadStream *in = new Common::MemoryReadStream(data, datasize);
-
- if (!in->read(&dir, sizeof(Win32CursorIconFileDir)- sizeof(Win32CursorIconFileDirEntry)))
- goto cleanup;
- fix_win32_cursor_icon_file_dir_endian(&dir);
-
- if (dir.reserved != 0) {
- error("not an icon or cursor file (reserved non-zero)");
- goto cleanup;
- }
- if (dir.type != 1 && dir.type != 2) {
- error("not an icon or cursor file (wrong type)");
- goto cleanup;
- }
-
- entries = (Win32CursorIconFileDirEntry *)malloc(dir.count * sizeof(Win32CursorIconFileDirEntry));
- for (c = 0; c < dir.count; c++) {
- if (!in->read(&entries[c], sizeof(Win32CursorIconFileDirEntry)))
- goto cleanup;
- fix_win32_cursor_icon_file_dir_entry_endian(&entries[c]);
- if (entries[c].reserved != 0)
- error("reserved is not zero");
- }
-
- offset = sizeof(Win32CursorIconFileDir) + (dir.count - 1) * (sizeof(Win32CursorIconFileDirEntry));
-
- for (completed = 0; completed < dir.count; ) {
- uint32 min_offset = 0x7fffffff;
- int previous = completed;
-
- for (c = 0; c < dir.count; c++) {
- if (entries[c].dib_offset == offset) {
- Win32BitmapInfoHeader bitmap;
- Win32RGBQuad *palette = NULL;
- uint32 palette_count = 0;
- uint32 image_size, mask_size;
- uint32 width, height;
- byte *image_data = NULL, *mask_data = NULL;
- byte *row = NULL;
-
- if (!in->read(&bitmap, sizeof(Win32BitmapInfoHeader)))
- goto local_cleanup;
-
- fix_win32_bitmap_info_header_endian(&bitmap);
- if (bitmap.size < sizeof(Win32BitmapInfoHeader)) {
- error("bitmap header is too short");
- goto local_cleanup;
- }
- if (bitmap.compression != 0) {
- error("compressed image data not supported");
- goto local_cleanup;
- }
- if (bitmap.x_pels_per_meter != 0)
- error("x_pels_per_meter field in bitmap should be zero");
- if (bitmap.y_pels_per_meter != 0)
- error("y_pels_per_meter field in bitmap should be zero");
- if (bitmap.clr_important != 0)
- error("clr_important field in bitmap should be zero");
- if (bitmap.planes != 1)
- error("planes field in bitmap should be one");
- if (bitmap.size != sizeof(Win32BitmapInfoHeader)) {
- uint32 skip = bitmap.size - sizeof(Win32BitmapInfoHeader);
- error("skipping %d bytes of extended bitmap header", skip);
- in->seek(skip, SEEK_CUR);
- }
- offset += bitmap.size;
-
- if (bitmap.clr_used != 0 || bitmap.bit_count < 24) {
- palette_count = (bitmap.clr_used != 0 ? bitmap.clr_used : 1 << bitmap.bit_count);
- palette = (Win32RGBQuad *)malloc(sizeof(Win32RGBQuad) * palette_count);
- if (!in->read(palette, sizeof(Win32RGBQuad) * palette_count))
- goto local_cleanup;
- offset += sizeof(Win32RGBQuad) * palette_count;
- }
-
- width = bitmap.width;
- height = ABS(bitmap.height)/2;
-
- image_size = height * ROW_BYTES(width * bitmap.bit_count);
- mask_size = height * ROW_BYTES(width);
-
- if (entries[c].dib_size != bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad))
- debugC(DEBUG_RESOURCE, "incorrect total size of bitmap (%d specified; %d real)",
- entries[c].dib_size,
- (int)(bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad))
- );
-
- image_data = (byte *)malloc(image_size);
- if (!in->read(image_data, image_size))
- goto local_cleanup;
-
- mask_data = (byte *)malloc(mask_size);
- if (!in->read(mask_data, mask_size))
- goto local_cleanup;
-
- offset += image_size;
- offset += mask_size;
- completed++;
- matched++;
-
- *hotspot_x = entries[c].hotspot_x;
- *hotspot_y = entries[c].hotspot_y;
- *w = width;
- *h = height;
- *keycolor = 0;
- *cursor = (byte *)malloc(width * height);
-
- row = (byte *)malloc(width * 4);
-
- for (d = 0; d < height; d++) {
- uint32 x;
- uint32 y = (bitmap.height < 0 ? d : height - d - 1);
- uint32 imod = y * (image_size / height) * 8 / bitmap.bit_count;
- uint32 mmod = y * (mask_size / height) * 8;
-
- for (x = 0; x < width; x++) {
-
- uint32 color = simple_vec(image_data, x + imod, bitmap.bit_count);
-
- // We set up cursor palette for default cursor, so use it
- if (!simple_vec(mask_data, x + mmod, 1)) {
- if (color) {
- cursor[0][width * d + x] = 254; // white
- } else {
- cursor[0][width * d + x] = 253; // black
- }
- } else {
- cursor[0][width * d + x] = 255; // transparent
- }
- /*
-
- if (bitmap.bit_count <= 16) {
- if (color >= palette_count) {
- error("color out of range in image data");
- goto local_cleanup;
- }
- row[4*x+0] = palette[color].red;
- row[4*x+1] = palette[color].green;
- row[4*x+2] = palette[color].blue;
-
- } else {
- row[4*x+0] = (color >> 16) & 0xFF;
- row[4*x+1] = (color >> 8) & 0xFF;
- row[4*x+2] = (color >> 0) & 0xFF;
- }
- if (bitmap.bit_count == 32)
- row[4*x+3] = (color >> 24) & 0xFF;
- else
- row[4*x+3] = simple_vec(mask_data, x + mmod, 1) ? 0 : 0xFF;
- */
- }
-
- }
-
- free(row);
- free(palette);
- if (image_data != NULL) {
- free(image_data);
- free(mask_data);
- }
- continue;
-
- local_cleanup:
-
- free(row);
- free(palette);
- if (image_data != NULL) {
- free(image_data);
- free(mask_data);
- }
- goto cleanup;
- } else {
- if (entries[c].dib_offset > offset)
- min_offset = MIN(min_offset, entries[c].dib_offset);
- }
- }
-
- if (previous == completed) {
- if (min_offset < offset) {
- error("offset of bitmap header incorrect (too low)");
- goto cleanup;
- }
- assert(min_offset != 0x7fffffff);
- debugC(DEBUG_RESOURCE, "skipping %d bytes of garbage at %d", min_offset-offset, offset);
- in->seek(min_offset - offset, SEEK_CUR);
- offset = min_offset;
- }
- }
-
- free(entries);
- return matched;
-
-cleanup:
-
- free(entries);
- return -1;
-}
-
-uint32 Win32ResExtractor::simple_vec(byte *data, uint32 ofs, byte size) {
- switch (size) {
- case 1:
- return (data[ofs/8] >> (7 - ofs%8)) & 1;
- case 2:
- return (data[ofs/4] >> ((3 - ofs%4) << 1)) & 3;
- case 4:
- return (data[ofs/2] >> ((1 - ofs%2) << 2)) & 15;
- case 8:
- return data[ofs];
- case 16:
- return data[2*ofs] | data[2*ofs+1] << 8;
- case 24:
- return data[3*ofs] | data[3*ofs+1] << 8 | data[3*ofs+2] << 16;
- case 32:
- return data[4*ofs] | data[4*ofs+1] << 8 | data[4*ofs+2] << 16 | data[4*ofs+3] << 24;
- }
-
- return 0;
-}
-
-void Win32ResExtractor::fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj) {
- LE16(obj->reserved);
- LE16(obj->type);
- LE16(obj->count);
-}
-
-void Win32ResExtractor::fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj) {
- LE32(obj->size);
- LE32(obj->width);
- LE32(obj->height);
- LE16(obj->planes);
- LE16(obj->bit_count);
- LE32(obj->compression);
- LE32(obj->size_image);
- LE32(obj->x_pels_per_meter);
- LE32(obj->y_pels_per_meter);
- LE32(obj->clr_used);
- LE32(obj->clr_important);
-}
-
-void Win32ResExtractor::fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj) {
- LE16(obj->hotspot_x);
- LE16(obj->hotspot_y);
- LE32(obj->dib_size);
- LE32(obj->dib_offset);
-}
-
-void Win32ResExtractor::fix_win32_image_section_header(Win32ImageSectionHeader *obj) {
- LE32(obj->misc.physical_address);
- LE32(obj->virtual_address);
- LE32(obj->size_of_raw_data);
- LE32(obj->pointer_to_raw_data);
- LE32(obj->pointer_to_relocations);
- LE32(obj->pointer_to_linenumbers);
- LE16(obj->number_of_relocations);
- LE16(obj->number_of_linenumbers);
- LE32(obj->characteristics);
-}
-
-/* fix_win32_image_header_endian:
- * NOTE: This assumes that the optional header is always available.
- */
-void Win32ResExtractor::fix_win32_image_header_endian(Win32ImageNTHeaders *obj) {
- LE32(obj->signature);
- LE16(obj->file_header.machine);
- LE16(obj->file_header.number_of_sections);
- LE32(obj->file_header.time_date_stamp);
- LE32(obj->file_header.pointer_to_symbol_table);
- LE32(obj->file_header.number_of_symbols);
- LE16(obj->file_header.size_of_optional_header);
- LE16(obj->file_header.characteristics);
-
- // FIXME: Does this assert ever trigger? If so, we should modify this function
- // to properly deal with it.
- assert(obj->file_header.size_of_optional_header >= sizeof(obj->optional_header));
- LE16(obj->optional_header.magic);
- LE32(obj->optional_header.size_of_code);
- LE32(obj->optional_header.size_of_initialized_data);
- LE32(obj->optional_header.size_of_uninitialized_data);
- LE32(obj->optional_header.address_of_entry_point);
- LE32(obj->optional_header.base_of_code);
- LE32(obj->optional_header.base_of_data);
- LE32(obj->optional_header.image_base);
- LE32(obj->optional_header.section_alignment);
- LE32(obj->optional_header.file_alignment);
- LE16(obj->optional_header.major_operating_system_version);
- LE16(obj->optional_header.minor_operating_system_version);
- LE16(obj->optional_header.major_image_version);
- LE16(obj->optional_header.minor_image_version);
- LE16(obj->optional_header.major_subsystem_version);
- LE16(obj->optional_header.minor_subsystem_version);
- LE32(obj->optional_header.win32_version_value);
- LE32(obj->optional_header.size_of_image);
- LE32(obj->optional_header.size_of_headers);
- LE32(obj->optional_header.checksum);
- LE16(obj->optional_header.subsystem);
- LE16(obj->optional_header.dll_characteristics);
- LE32(obj->optional_header.size_of_stack_reserve);
- LE32(obj->optional_header.size_of_stack_commit);
- LE32(obj->optional_header.size_of_heap_reserve);
- LE32(obj->optional_header.size_of_heap_commit);
- LE32(obj->optional_header.loader_flags);
- LE32(obj->optional_header.number_of_rva_and_sizes);
-}
-
-void Win32ResExtractor::fix_win32_image_data_directory(Win32ImageDataDirectory *obj) {
- LE32(obj->virtual_address);
- LE32(obj->size);
-}
-
-
MacResExtractor::MacResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) {
_resMgr = NULL;
}
-int MacResExtractor::extractResource(int id, byte **buf) {
+bool MacResExtractor::extractResource(int id, CachedCursor *cc) {
// Create the MacResManager if not created already
if (_resMgr == NULL) {
_resMgr = new Common::MacResManager();
@@ -1158,25 +167,18 @@ int MacResExtractor::extractResource(int id, byte **buf) {
error("Cannot open file %s", _fileName.c_str());
}
- Common::SeekableReadStream *dataStream = _resMgr->getResource('crsr', 1000 + id);
+ Common::SeekableReadStream *dataStream = _resMgr->getResource('crsr', id + 1000);
if (!dataStream)
- error("There is no cursor ID #%d", 1000 + id);
-
- uint32 size = dataStream->size();
- *buf = (byte *)malloc(size);
- dataStream->read(*buf, size);
- delete dataStream;
+ return false;
- return size;
-}
+ int keyColor; // HACK: key color is ignored
+ _resMgr->convertCrsrCursor(dataStream, &cc->bitmap, cc->width, cc->height, cc->hotspotX, cc->hotspotY,
+ keyColor, _vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette),
+ &cc->palette, cc->palSize);
-int MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
- int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize) {
-
- _resMgr->convertCrsrCursor(data, datasize, cursor, w, h, hotspot_x, hotspot_y, keycolor,
- _vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette), palette, palSize);
- return 1;
+ delete dataStream;
+ return true;
}
void ScummEngine_v70he::readRoomsOffsets() {
diff --git a/engines/scumm/he/resource_he.h b/engines/scumm/he/resource_he.h
index 6b4c3fe493..5d7c70db76 100644
--- a/engines/scumm/he/resource_he.h
+++ b/engines/scumm/he/resource_he.h
@@ -4,10 +4,6 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * Parts of this code are heavily based on:
- * icoutils - A set of programs dealing with MS Windows icons and cursors.
- * Copyright (C) 1998-2001 Oskar Liljeblad
- *
* 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
@@ -31,89 +27,10 @@
#define SCUMM_HE_RESOURCE_HE_H
#include "common/macresman.h"
+#include "common/winexe_pe.h"
namespace Scumm {
-#define WINRES_ID_MAXLEN (256)
-
-/*
- * Definitions
- */
-
-#define MZ_HEADER(x) ((DOSImageHeader *)(x))
-
-#define STRIP_RES_ID_FORMAT(x) (x != NULL && (x[0] == '-' || x[0] == '+') ? ++x : x)
-
-#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
-#define IMAGE_SIZEOF_SHORT_NAME 8
-
-#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
-#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
-
-#define PE_HEADER(module) \
- ((Win32ImageNTHeaders*)((byte *)(module) + \
- (((DOSImageHeader*)(module))->lfanew)))
-
-#define PE_SECTIONS(module) \
- ((Win32ImageSectionHeader *)((byte *) &PE_HEADER(module)->optional_header + \
- PE_HEADER(module)->file_header.size_of_optional_header))
-
-#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
-#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
-
-/* The following symbols below and another group a few lines below are defined in
- * the windows header, at least in wince and most likely in plain win32 as well.
- * Defining them out silences a redefinition warning in gcc.
- * If the same problem arises in win32 builds as well, please replace
- * _WIN32_WCE with _WIN32 which is also defined in the wince platform.
- */
-#ifndef _WIN32_WCE
-#define IMAGE_SCN_CNT_CODE 0x00000020
-#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
-#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
-#endif
-
-// Only IMAGE_DIRECTORY_ENTRY_RESOURCE is used:
-#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
-#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
-#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
-#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
-#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
-#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
-#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
-#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
-#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */
-#define IMAGE_DIRECTORY_ENTRY_TLS 9
-#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
-#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
-#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */
-#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
-#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
-
-#ifndef _WIN32_WCE
-// Only RT_GROUP_CURSOR and RT_GROUP_ICON are used
-#define RT_CURSOR 1
-#define RT_BITMAP 2
-#define RT_ICON 3
-#define RT_MENU 4
-#define RT_DIALOG 5
-#define RT_STRING 6
-#define RT_FONTDIR 7
-#define RT_FONT 8
-#define RT_ACCELERATOR 9
-#define RT_RCDATA 10
-#define RT_MESSAGELIST 11
-#define RT_GROUP_CURSOR 12
-#define RT_GROUP_ICON 14
-#endif
-
-#define RETURN_IF_BAD_POINTER(r, x) \
- if (!check_offset(fi->memory, fi->total_size, _fileName.c_str(), &(x), sizeof(x))) \
- return (r);
-#define RETURN_IF_BAD_OFFSET(r, x, s) \
- if (!check_offset(fi->memory, fi->total_size, _fileName.c_str(), x, s)) \
- return (r);
-
class ScummEngine_v70he;
class ResExtractor {
@@ -123,312 +40,54 @@ public:
void setCursor(int id);
- virtual int extractResource(int id, byte **buf) { return 0; }
- virtual int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
- int *hotspot_x, int *hotspot_y, int *keycolor,
- byte **palette, int *palSize) { return 0; }
-
- enum {
- MAX_CACHED_CURSORS = 10
- };
-
+protected:
struct CachedCursor {
bool valid;
int id;
byte *bitmap;
- int w, h;
- int hotspot_x, hotspot_y;
- uint32 last_used;
+ int width, height;
+ int hotspotX, hotspotY;
+ uint32 lastUsed;
byte *palette;
int palSize;
};
+ Common::String _fileName;
ScummEngine_v70he *_vm;
+ virtual bool extractResource(int id, CachedCursor *cc) = 0;
+
+private:
+ enum {
+ MAX_CACHED_CURSORS = 10
+ };
+
ResExtractor::CachedCursor *findCachedCursor(int id);
ResExtractor::CachedCursor *getCachedCursorSlot();
-
- bool _arg_raw;
- Common::String _fileName;
+
CachedCursor _cursorCache[MAX_CACHED_CURSORS];
};
class Win32ResExtractor : public ResExtractor {
- public:
+public:
Win32ResExtractor(ScummEngine_v70he *scumm);
~Win32ResExtractor() {}
- int extractResource(int id, byte **data);
- void setCursor(int id);
- int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
- int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize);
- private:
- int extractResource_(const char *resType, char *resName, byte **data);
-/*
- * Structures
- */
-
-#include "common/pack-start.h" // START STRUCT PACKING
-
- struct WinLibrary {
- Common::SeekableReadStream *file;
- byte *memory;
- byte *first_resource;
- int total_size;
- } PACKED_STRUCT;
-
- struct WinResource {
- char id[256];
- void *this_;
- void *children;
- int level;
- bool numeric_id;
- bool is_directory;
-
- Common::String getQuotedResourceId() const;
- } PACKED_STRUCT;
-
-
- struct Win32IconResDir {
- byte width;
- byte height;
- byte color_count;
- byte reserved;
- } PACKED_STRUCT;
-
- struct Win32CursorDir {
- uint16 width;
- uint16 height;
- } PACKED_STRUCT;
-
- struct Win32CursorIconDirEntry {
- union {
- Win32IconResDir icon;
- Win32CursorDir cursor;
- } res_info;
- uint16 plane_count;
- uint16 bit_count;
- uint32 bytes_in_res;
- uint16 res_id;
- } PACKED_STRUCT;
-
- struct Win32CursorIconDir {
- uint16 reserved;
- uint16 type;
- uint16 count;
- Win32CursorIconDirEntry entries[1];
- } PACKED_STRUCT;
-
- struct Win32CursorIconFileDirEntry {
- byte width;
- byte height;
- byte color_count;
- byte reserved;
- uint16 hotspot_x;
- uint16 hotspot_y;
- uint32 dib_size;
- uint32 dib_offset;
- } PACKED_STRUCT;
-
- struct Win32CursorIconFileDir {
- uint16 reserved;
- uint16 type;
- uint16 count;
- Win32CursorIconFileDirEntry entries[1];
- } PACKED_STRUCT;
-
- struct Win32BitmapInfoHeader {
- uint32 size;
- int32 width;
- int32 height;
- uint16 planes;
- uint16 bit_count;
- uint32 compression;
- uint32 size_image;
- int32 x_pels_per_meter;
- int32 y_pels_per_meter;
- uint32 clr_used;
- uint32 clr_important;
- } PACKED_STRUCT;
-
- struct Win32RGBQuad {
- byte blue;
- byte green;
- byte red;
- byte reserved;
- } PACKED_STRUCT;
-
- struct Win32ImageResourceDirectoryEntry {
- uint32 name;
- uint32 offset_to_data;
- } PACKED_STRUCT;
-
- struct Win16NETypeInfo {
- uint16 type_id;
- uint16 count;
- uint32 resloader; // FARPROC16 - smaller? uint16?
- } PACKED_STRUCT;
-
- struct DOSImageHeader {
- uint16 magic;
- uint16 cblp;
- uint16 cp;
- uint16 crlc;
- uint16 cparhdr;
- uint16 minalloc;
- uint16 maxalloc;
- uint16 ss;
- uint16 sp;
- uint16 csum;
- uint16 ip;
- uint16 cs;
- uint16 lfarlc;
- uint16 ovno;
- uint16 res[4];
- uint16 oemid;
- uint16 oeminfo;
- uint16 res2[10];
- uint32 lfanew;
- } PACKED_STRUCT;
-
- struct Win32ImageFileHeader {
- uint16 machine;
- uint16 number_of_sections;
- uint32 time_date_stamp;
- uint32 pointer_to_symbol_table;
- uint32 number_of_symbols;
- uint16 size_of_optional_header;
- uint16 characteristics;
- } PACKED_STRUCT;
-
- struct Win32ImageDataDirectory {
- uint32 virtual_address;
- uint32 size;
- } PACKED_STRUCT;
-
- struct Win32ImageOptionalHeader {
- uint16 magic;
- byte major_linker_version;
- byte minor_linker_version;
- uint32 size_of_code;
- uint32 size_of_initialized_data;
- uint32 size_of_uninitialized_data;
- uint32 address_of_entry_point;
- uint32 base_of_code;
- uint32 base_of_data;
- uint32 image_base;
- uint32 section_alignment;
- uint32 file_alignment;
- uint16 major_operating_system_version;
- uint16 minor_operating_system_version;
- uint16 major_image_version;
- uint16 minor_image_version;
- uint16 major_subsystem_version;
- uint16 minor_subsystem_version;
- uint32 win32_version_value;
- uint32 size_of_image;
- uint32 size_of_headers;
- uint32 checksum;
- uint16 subsystem;
- uint16 dll_characteristics;
- uint32 size_of_stack_reserve;
- uint32 size_of_stack_commit;
- uint32 size_of_heap_reserve;
- uint32 size_of_heap_commit;
- uint32 loader_flags;
- uint32 number_of_rva_and_sizes;
- Win32ImageDataDirectory data_directory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
- } PACKED_STRUCT;
-
- struct Win32ImageNTHeaders {
- uint32 signature;
- Win32ImageFileHeader file_header;
- Win32ImageOptionalHeader optional_header;
- } PACKED_STRUCT;
-
- struct Win32ImageSectionHeader {
- byte name[IMAGE_SIZEOF_SHORT_NAME];
- union {
- uint32 physical_address;
- uint32 virtual_size;
- } misc;
- uint32 virtual_address;
- uint32 size_of_raw_data;
- uint32 pointer_to_raw_data;
- uint32 pointer_to_relocations;
- uint32 pointer_to_linenumbers;
- uint16 number_of_relocations;
- uint16 number_of_linenumbers;
- uint32 characteristics;
- } PACKED_STRUCT;
-
- struct Win32ImageResourceDataEntry {
- uint32 offset_to_data;
- uint32 size;
- uint32 code_page;
- uint32 resource_handle;
- } PACKED_STRUCT;
-
- struct Win32ImageResourceDirectory {
- uint32 characteristics;
- uint32 time_date_stamp;
- uint16 major_version;
- uint16 minor_version;
- uint16 number_of_named_entries;
- uint16 number_of_id_entries;
- } PACKED_STRUCT;
-
-#include "common/pack-end.h" // END STRUCT PACKING
-
-/*
- * Function Prototypes
- */
-
- WinResource *list_resources(WinLibrary *, WinResource *, int *);
- bool read_library(WinLibrary *);
- WinResource *find_resource(WinLibrary *, const char *, const char *, const char *, int *);
- byte *get_resource_entry(WinLibrary *, WinResource *, int *);
- int do_resources(WinLibrary *, const char *, char *, char *, byte **);
- bool compare_resource_id(WinResource *, const char *);
- const char *res_type_string_to_id(const char *);
-
- const char *res_type_id_to_string(int);
- char *get_destination_name(WinLibrary *, char *, char *, char *);
-
- byte *extract_resource(WinLibrary *, WinResource *, int *, bool *, char *, char *, bool);
- int extract_resources(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, byte **);
- byte *extract_group_icon_cursor_resource(WinLibrary *, WinResource *, char *, int *, bool);
-
- bool decode_pe_resource_id(WinLibrary *, WinResource *, uint32);
- WinResource *list_pe_resources(WinLibrary *, Win32ImageResourceDirectory *, int, int *);
- int calc_vma_size(WinLibrary *);
- int do_resources_recurs(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, const char *, char *, char *, byte **);
- WinResource *find_with_resource_array(WinLibrary *, WinResource *, const char *);
-
- bool check_offset(byte *, int, const char *, void *, int);
-
- uint32 simple_vec(byte *data, uint32 ofs, byte size);
+private:
+ Common::PEResources _exe;
- void fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj);
- void fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj);
- void fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj);
- void fix_win32_image_section_header(Win32ImageSectionHeader *obj);
- void fix_win32_image_header_endian(Win32ImageNTHeaders *obj);
- void fix_win32_image_data_directory(Win32ImageDataDirectory *obj);
+ bool extractResource(int id, CachedCursor *cc);
};
class MacResExtractor : public ResExtractor {
-
public:
MacResExtractor(ScummEngine_v70he *scumm);
- ~MacResExtractor() { }
+ ~MacResExtractor() {}
private:
Common::MacResManager *_resMgr;
- int extractResource(int id, byte **buf);
- int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
- int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize);
+ bool extractResource(int id, CachedCursor *cc);
};
} // End of namespace Scumm