aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS10
-rw-r--r--COPYRIGHT47
-rw-r--r--backends/platform/dc/dc-fs.cpp8
-rw-r--r--backends/platform/dc/selector.cpp2
-rw-r--r--backends/platform/gp2x/gp2x.cpp1
-rw-r--r--backends/platform/sdl/events.cpp2
-rw-r--r--backends/platform/sdl/graphics.cpp19
-rw-r--r--backends/platform/sdl/sdl.cpp2
-rw-r--r--backends/platform/sdl/sdl.h2
-rw-r--r--base/main.cpp20
-rw-r--r--common/archive.cpp29
-rw-r--r--common/archive.h20
-rw-r--r--common/file.cpp39
-rw-r--r--common/str.cpp27
-rw-r--r--common/str.h4
-rw-r--r--common/system.h2
-rw-r--r--common/unarj.cpp6
-rw-r--r--common/unarj.h8
-rw-r--r--common/unzip.cpp556
-rw-r--r--common/unzip.h326
-rw-r--r--common/util.h8
-rw-r--r--common/xmlparser.h4
-rw-r--r--engines/agi/predictive.cpp5
-rw-r--r--engines/cruise/cruise_main.cpp2
-rw-r--r--engines/cruise/ctp.cpp14
-rw-r--r--engines/cruise/dataLoader.cpp21
-rw-r--r--engines/cruise/overlay.cpp312
-rw-r--r--engines/cruise/overlay.h2
-rw-r--r--engines/cruise/saveload.cpp3
-rw-r--r--engines/cruise/vars.h3
-rw-r--r--engines/drascula/drascula.cpp12
-rw-r--r--engines/drascula/drascula.h2
-rw-r--r--engines/drascula/sound.cpp11
-rw-r--r--engines/drascula/talk.cpp44
-rw-r--r--engines/gob/detection.cpp13
-rw-r--r--engines/made/screen.cpp19
-rw-r--r--engines/made/scriptfuncs.cpp2
-rw-r--r--engines/parallaction/balloons.cpp2
-rw-r--r--engines/parallaction/saveload.cpp5
-rw-r--r--engines/saga/animation.cpp3
-rw-r--r--engines/saga/displayinfo.h8
-rw-r--r--engines/saga/interface.cpp17
-rw-r--r--engines/saga/interface.h5
-rw-r--r--engines/scumm/actor.cpp208
-rw-r--r--engines/scumm/actor.h69
-rw-r--r--engines/scumm/akos.cpp28
-rw-r--r--engines/scumm/charset-fontdata.cpp1
-rw-r--r--engines/scumm/detection.cpp19
-rw-r--r--engines/scumm/detection_tables.h1
-rw-r--r--engines/scumm/dialogs.cpp8
-rw-r--r--engines/scumm/file.cpp6
-rw-r--r--engines/scumm/file.h18
-rw-r--r--engines/scumm/file_nes.h6
-rw-r--r--engines/scumm/gfx.cpp13
-rw-r--r--engines/scumm/he/intern_he.h3
-rw-r--r--engines/scumm/he/resource_he.cpp25
-rw-r--r--engines/scumm/he/resource_he.h4
-rw-r--r--engines/scumm/he/script_v100he.cpp6
-rw-r--r--engines/scumm/he/script_v60he.cpp5
-rw-r--r--engines/scumm/he/script_v70he.cpp2
-rw-r--r--engines/scumm/he/script_v71he.cpp12
-rw-r--r--engines/scumm/he/script_v72he.cpp6
-rw-r--r--engines/scumm/he/script_v80he.cpp6
-rw-r--r--engines/scumm/he/script_v90he.cpp12
-rw-r--r--engines/scumm/object.cpp7
-rw-r--r--engines/scumm/scumm-md5.h8
-rw-r--r--engines/scumm/scumm.cpp2
-rw-r--r--engines/scumm/scumm.h2
-rw-r--r--engines/sword1/animation.cpp29
-rw-r--r--engines/sword1/animation.h9
-rw-r--r--engines/sword1/logic.cpp5
-rw-r--r--engines/sword1/logic.h4
-rw-r--r--engines/sword1/sword1.cpp2
-rw-r--r--graphics/imageman.cpp74
-rw-r--r--graphics/imageman.h17
-rw-r--r--gui/ThemeEngine.cpp78
-rw-r--r--gui/credits.h17
-rw-r--r--gui/launcher.cpp8
-rw-r--r--gui/theme.cpp8
-rw-r--r--gui/theme.h2
-rwxr-xr-xtools/credits.pl10
-rw-r--r--tools/scumm-md5.txt6
82 files changed, 1202 insertions, 1191 deletions
diff --git a/AUTHORS b/AUTHORS
index 45cebf57c6..d0c015581d 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -139,7 +139,6 @@ ScummVM Team
Kostas Nakos
PlayStation 2:
- Robert Goeffringmann
Max Lingua
PSP (PlayStation Portable):
@@ -192,10 +191,13 @@ ScummVM Team
Nicolas Bacca - Former WinCE porter
Ralph Brorsen - Help with GUI implementation
Jamieson Christian - iMUSE, MIDI, all things musical
+ Hans-Jorg Frieden - Former AmigaOS 4 packager
+ Robert Goeffringmann - Original PS2 porter
Ruediger Hanke - Port: MorphOS
Felix Jakschitsch - Zak256 reverse engineering
Mutwin Kraus - Original MacOS porter
Peter Moraliyski - Port: GP32
+ Juha Niemimaki - Formaer AmigaOS 4 packager
Jeremy Newman - Former webmaster
Lionel Ulmer - Port: X11
Won Star - Former GP32 porter
@@ -205,9 +207,7 @@ Other contributions
Packages
--------
AmigaOS 4:
- Hans-Jorg Frieden
Hubert Maier
- Juha Niemimaki
Atari/FreeMiNT:
Keith Scroggins
@@ -266,6 +266,7 @@ Other contributions
Stuart Caie - Decoders for Simon 1 Amiga data files
Paolo Costabel - PSP port contributions
Thierry Crozat - Support for Broken Sword 1 Macintosh version
+ Martin Doucha - CinE engine objectification
Thomas Fach-Pedersen - ProTracker module player
Benjamin Haisch - Heavily improved de-/encoder for DXA videos
Janne Huttunen - V3 actor mask support, Dig/FT SMUSH audio
@@ -295,15 +296,18 @@ Special thanks to
Sander Buskens - For his work on the initial reversing of Monkey2
Canadacow - For the original MT-32 emulator
Kevin Carnes - For Scumm16, the basis of ScummVM's older gfx codecs
+ Curt Coder - For the original TrollVM (preAGI) code
Patrick Combet - For the original Gobliiins ADL player
Ivan Dubrov - For contributing the initial version of the Gobliiins
engine
+ Till Kresslein - For design of modern ScummVM GUI
Jezar - For his freeverb filter implementation
Jim Leiterman - Various info on his FM-TOWNS/Marty SCUMM ports
lloyd - For deep tech details about C64 Zak & MM
Sarien Team - Original AGI engine code
Jimmi Thogersen - For ScummRev, and much obscure code/documentation
Tristan - For additional work on the original MT-32 emulator
+ James Woodcock - Soundtrack enhancements
Tony Warriner and everyone at Revolution Software Ltd. for sharing with us
the source of some of their brilliant games, allowing us to release
diff --git a/COPYRIGHT b/COPYRIGHT
index c4c3cf0a65..b37c1c0fe5 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -60,6 +60,7 @@ Eugene Sandulenko
Johannes Schickel
Won Star
Ludvig Strigeus
+Keith Scroggins
David Symonds
Jordi Vilalta
Robin Watts
@@ -74,23 +75,34 @@ Patches contributed by:
Laura Abbott "sageofminerva"
Vikram Aggarwal "youngelf"
+the rara avis "theraraavis"
Dieter Baron "dillo"
Alban Bedel "albeu"
Bodo Bellut "bellut"
+Bramvandijk "bramvandijk"
Andreas Bierfert "awjb"
Elio Blanca "eblanca76"
+Bastien Bouclet "bgk"
David Breakey "dbreakey"
Robert Buchholz "prendi"
-Rainer Canavan
+Rainer Canavan "canavan"
Mathieu Carot "yokna"
Stefano Ceccherini "jackburton"
Travis S Coady "theealien"
Josh Coalson "jcoalson"
Thomas Combeleran "hibernatus"
+Kees Cook "keescook"
Carlos Corbacho "cathectic"
Roberto Costa "fiix76"
+Thiery Crozat "criezy"
+dc france "erwan2004"
+dewt "mncl"
+Martin Doucha "next_ghost"
Michael Drueing "doc_wagon"
+dubsdj
Matthew Duggan "stauff1"
+Olivier Duverne "richiefs"
+Andrei Dziahel "develop7"
John Eckerdal "johneck"
Thomas Fach-Pedersen "madm00se"
Florent "flobo"
@@ -109,6 +121,7 @@ Stefan Haubenthal "polluks"
Alexander Holler "holler"
Falk Hueffner "mellum"
Casey Hutchinson "nnooiissee"
+j0tt
Gregor Jasny "gjasny"
Jellby "jellby"
Joerg "macdrega"
@@ -122,38 +135,49 @@ Janne Kujanpaa "jukuja"
Jay Lanagan "r0ni"
Norbert Lange "nolange"
Manuel Lauss "mlau2"
+Rolf Leggewie "leggewie"
Duncan Lock "dflock"
Mark Lodato "itsr0y"
Fridvin Logi "phillip_j_fry"
+Lostech "lostech"
Georg Lukas "ge0rg"
Dmitry Marakasov "amdmi3"
-Markus "meist3r"
Connor McLeod "mcleod2032"
Mickey McMurray "metafox"
Vladimir Menshakov "megath"
+Adam Metcalf "gamblore"
Frank Meyering "frank_m24"
Gael Le Migno "kilobug"
Alyssa Anne Milburn "fuzzie"
Andy Molloy "maloi"
+Sean Murrau "lightcast"
Armin Mueller "arm_in"
Andrea Musuruane "musuruan"
KO Myung-Hun "lvzuufx"
+Markus Napp "meist3r"
Peter Naulls "pnaulls"
Christian Neumair "mannythegnome"
Nicos "anarxia"
Juha Niemimaki "capehill"
Markus Niemisto "niemisto"
+ole
Chris Paras "paras_rasmatazz"
Aubin Paul "outlyer"
+Vincent Pelletier "subdino"
+phi1
+Pix2 "pix2"
Carsten Pohl "carstenpohl"
Markus Pyykko "mankeli"
Richard "trinity78"
Felix Riemann "kirschsaft"
+Thomas Richter "thorfdbg"
Timo Roehling "t1m0"
Andreas Roever "roever"
Jonathan Rogers "jonner"
Marek Roth "logicdeluxe"
+Uwe Ryssel "uweryssel"
Simon Sawatzki "simsaw"
+Scarlatti "escarlate"
Daniel Schepler "dschepler"
Florian Schmitt "fatpenguin"
Mark Schreiber "mark7"
@@ -161,12 +185,17 @@ Ben Shadwick "benshadwick"
Jean-Yves Simon "lethalwp"
Andrej Sinicyn "andrej4000"
Andre Souza "luke_br"
+spookypeanut "spookypeanut"
Steve Stavropoulos "isnothere"
Daniel Steinberger "amorphousshape"
Sven Strothoff "dataslayer"
Andrea Suatoni "mrhandler"
+tbcarey
+Tim "tipabu"
+Tobigun "tobigun"
Luigi Toscano "ltosky"
Xavier Trochu "xtrochu"
+Michal Tulacek "tutchek"
Michael Udaltsov "cccp99"
Kristof Vansant "lupusbe"
Tim Walters "realmz"
@@ -174,16 +203,6 @@ David Weinehall "weine"
Eric A. Welsh "eweish42"
Yudhi Widyatama "yudhi97"
Robert Wohlrab "moshroum"
+Xanathar "xanathar"
+Grant Yeager "glo_kidd"
Benjamin W. Zale "junior_aepi"
-the rara avis "theraraavis"
-dewt "mncl"
-dubsdj
-exo "exofreeze"
-dc france "erwan2004"
-j0tt
-glo kidd "glo_kidd"
-ole
-phi1
-spookypeanut "spookypeanut"
-tbcarey
-Tim "tipabu"
diff --git a/backends/platform/dc/dc-fs.cpp b/backends/platform/dc/dc-fs.cpp
index c4f1d76f10..4baba5b7dc 100644
--- a/backends/platform/dc/dc-fs.cpp
+++ b/backends/platform/dc/dc-fs.cpp
@@ -54,7 +54,7 @@ public:
virtual AbstractFilesystemNode *getParent() const;
virtual Common::SeekableReadStream *openForReading();
- virtual Common::WriteStream *openForWriting();
+ virtual Common::WriteStream *openForWriting() { return 0; }
static AbstractFilesystemNode *makeFileNodePath(const Common::String &path);
};
@@ -67,6 +67,7 @@ public:
virtual bool isDirectory() const { return true; }
virtual AbstractFilesystemNode *getChild(const Common::String &n) const;
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
+ virtual Common::SeekableReadStream *openForReading() { return 0; }
};
/* A file/directory which does not exist */
@@ -76,6 +77,7 @@ public:
virtual bool exists() const { return false; }
virtual bool isReadable() const { return false; }
+ virtual Common::SeekableReadStream *openForReading() { return 0; }
};
AbstractFilesystemNode *RoninCDFileNode::makeFileNodePath(const Common::String &path) {
@@ -152,10 +154,6 @@ Common::SeekableReadStream *RoninCDFileNode::openForReading() {
return StdioStream::makeFromPath(getPath().c_str(), false);
}
-Common::WriteStream *RoninCDFileNode::openForWriting() {
- return StdioStream::makeFromPath(getPath().c_str(), true);
-}
-
AbstractFilesystemNode *OSystem_Dreamcast::makeRootFileNode() const {
return new RoninCDDirectoryNode("/");
}
diff --git a/backends/platform/dc/selector.cpp b/backends/platform/dc/selector.cpp
index a4a53e0f65..883787781a 100644
--- a/backends/platform/dc/selector.cpp
+++ b/backends/platform/dc/selector.cpp
@@ -26,8 +26,8 @@
#include <common/scummsys.h>
#include <engines/engine.h>
#include <engines/metaengine.h>
+#include <engines/game.h>
#include <base/plugins.h>
-#include <base/game.h>
#include <common/fs.h>
#include <common/events.h>
#include "dc.h"
diff --git a/backends/platform/gp2x/gp2x.cpp b/backends/platform/gp2x/gp2x.cpp
index e5f062ed35..1fbda44077 100644
--- a/backends/platform/gp2x/gp2x.cpp
+++ b/backends/platform/gp2x/gp2x.cpp
@@ -145,6 +145,7 @@ void OSystem_GP2X::initBackend() {
if (mkdir(enginedataPath, 0755) != 0)
warning("mkdir for '%s' failed!", enginedataPath);
+ //FIXME: Do not use File::addDefaultDirectory, rather implement OSystem::addSysArchivesToSearchSet() !
Common::File::addDefaultDirectory(enginedataPath);
// Note: Review and clean this, it's OTT at the moment.
diff --git a/backends/platform/sdl/events.cpp b/backends/platform/sdl/events.cpp
index a4a72ca380..a7a9251678 100644
--- a/backends/platform/sdl/events.cpp
+++ b/backends/platform/sdl/events.cpp
@@ -195,7 +195,9 @@ bool OSystem_SDL::pollEvent(Common::Event &event) {
// Alt-Return and Alt-Enter toggle full screen mode
if (b == Common::KBD_ALT && (ev.key.keysym.sym == SDLK_RETURN
|| ev.key.keysym.sym == SDLK_KP_ENTER)) {
+ beginGFXTransaction();
setFullscreenMode(!_fullscreen);
+ endGFXTransaction();
#ifdef USE_OSD
if (_fullscreen)
displayMessageOnOSD("Fullscreen mode");
diff --git a/backends/platform/sdl/graphics.cpp b/backends/platform/sdl/graphics.cpp
index 4a5c143712..96b74ecba7 100644
--- a/backends/platform/sdl/graphics.cpp
+++ b/backends/platform/sdl/graphics.cpp
@@ -691,20 +691,14 @@ bool OSystem_SDL::saveScreenshot(const char *filename) {
void OSystem_SDL::setFullscreenMode(bool enable) {
Common::StackLock lock(_graphicsMutex);
+
+ if (_fullscreen == enable)
+ return;
- if (_fullscreen != enable || _transactionMode == kTransactionCommit) {
+ if (_transactionMode == kTransactionCommit) {
assert(_hwscreen != 0);
_fullscreen = enable;
- if (_transactionMode == kTransactionActive) {
- _transactionDetails.fs = enable;
- _transactionDetails.fsChanged = true;
-
- _transactionDetails.needHotswap = true;
-
- return;
- }
-
// Switch between fullscreen and windowed mode by invoking hotswapGFXMode().
// We used to use SDL_WM_ToggleFullScreen() in the past, but this caused various
// problems. E.g. on OS X, it was implemented incorrectly for a long time; on
@@ -713,6 +707,11 @@ void OSystem_SDL::setFullscreenMode(bool enable) {
// So, we just do it "manually" now. There shouldn't be any drawbacks to that
// anyway.
hotswapGFXMode();
+ } else if (_transactionMode == kTransactionActive) {
+ _transactionDetails.fs = enable;
+ _transactionDetails.fsChanged = true;
+
+ _transactionDetails.needHotswap = true;
}
}
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index 9a6f294a55..0550017555 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -275,7 +275,7 @@ FilesystemFactory *OSystem_SDL::getFilesystemFactory() {
return _fsFactory;
}
-void OSystem_SDL::addSysArchivesToSearchSet(Common::SearchSet &s, uint priority) {
+void OSystem_SDL::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
#ifdef DATA_PATH
// Add the global DATA_PATH to the directory search list
diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h
index 1cc0acbc29..602cf8d24d 100644
--- a/backends/platform/sdl/sdl.h
+++ b/backends/platform/sdl/sdl.h
@@ -209,7 +209,7 @@ public:
virtual Common::SaveFileManager *getSavefileManager();
virtual FilesystemFactory *getFilesystemFactory();
- virtual void addSysArchivesToSearchSet(Common::SearchSet &s, uint priority = 0);
+ virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
virtual Common::SeekableReadStream *openConfigFileForReading();
virtual Common::WriteStream *openConfigFileForWriting();
diff --git a/base/main.cpp b/base/main.cpp
index e1b65aebbd..93e2c71c8f 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -70,6 +70,17 @@ static bool launcherDialog(OSystem &system) {
system.setFeatureState(OSystem::kFeatureFullscreenMode, ConfMan.getBool("fullscreen"));
system.endGFXTransaction();
+ // When starting up launcher for the first time, the user might have specified
+ // a --gui-theme option, to allow that option to be working, we need to initialize
+ // GUI here.
+ // FIXME: Find a nicer way to allow --gui-theme to be working
+ GUI::NewGui::instance();
+
+ // Discard any command line options. Those that affect the graphics
+ // mode and the others (like bootparam etc.) should not
+ // blindly be passed to the first game launched from the launcher.
+ ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear();
+
// Set initial window caption
system.setWindowCaption(gScummVMFullVersion);
@@ -277,15 +288,8 @@ extern "C" int scummvm_main(int argc, char *argv[]) {
system.initBackend();
// Unless a game was specified, show the launcher dialog
- if (0 == ConfMan.getActiveDomain()) {
- // Discard any command line options. Those that affect the graphics
- // mode etc. already have should have been handled by the backend at
- // this point. And the others (like bootparam etc.) should not
- // blindly be passed to the first game launched from the launcher.
- ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear();
-
+ if (0 == ConfMan.getActiveDomain())
launcherDialog(system);
- }
// FIXME: We're now looping the launcher. This, of course, doesn't
// work as well as it should. In theory everything should be destroyed
diff --git a/common/archive.cpp b/common/archive.cpp
index 7e17fdca32..49e43a5973 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -26,6 +26,7 @@
#include "common/archive.h"
#include "common/fs.h"
#include "common/util.h"
+#include "common/system.h"
namespace Common {
@@ -231,7 +232,7 @@ void SearchSet::insert(const Node &node) {
_list.insert(it, node);
}
-void SearchSet::add(const String& name, ArchivePtr archive, uint priority) {
+void SearchSet::add(const String& name, ArchivePtr archive, int priority) {
if (find(name) == _list.end()) {
Node node = { priority, name, archive };
insert(node);
@@ -256,7 +257,7 @@ void SearchSet::clear() {
_list.clear();
}
-void SearchSet::setPriority(const String& name, uint priority) {
+void SearchSet::setPriority(const String& name, int priority) {
ArchiveList::iterator it = find(name);
if (it == _list.end()) {
warning("SearchSet::setPriority: archive '%s' is not present", name.c_str());
@@ -328,17 +329,29 @@ SeekableReadStream *SearchSet::openFile(const String &name) {
DECLARE_SINGLETON(SearchManager);
-void SearchManager::addArchive(const String &name, ArchivePtr archive) {
- add(name, archive);
+SearchManager::SearchManager() {
+ clear(); // Force a reset
}
-void SearchManager::addDirectory(const String &name, const String &directory) {
- addDirectoryRecursive(name, 1);
+void SearchManager::addArchive(const String &name, ArchivePtr archive, int priority) {
+ add(name, archive, priority);
}
-void SearchManager::addDirectoryRecursive(const String &name, const String &directory, int depth) {
- add(name, SharedPtr<FSDirectory>(new FSDirectory(directory, depth)));
+void SearchManager::addDirectory(const String &name, const String &directory, int priority) {
+ addDirectoryRecursive(name, directory, 1, priority);
}
+void SearchManager::addDirectoryRecursive(const String &name, const String &directory, int depth, int priority) {
+ add(name, ArchivePtr(new FSDirectory(directory, depth)), priority);
+}
+
+void SearchManager::clear() {
+ SearchSet::clear();
+
+ // Always keep system specific archives in the SearchManager.
+ // But we give them a lower priority than the default priority (which is 0),
+ // so that archives added by client code are searched first.
+ g_system->addSysArchivesToSearchSet(*this, -1);
+}
} // namespace Common
diff --git a/common/archive.h b/common/archive.h
index 89ea6a5ce2..246d9da8cf 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -153,7 +153,7 @@ public:
*/
class SearchSet : public Archive {
struct Node {
- uint _priority;
+ int _priority;
String _name;
ArchivePtr _arc;
};
@@ -169,7 +169,7 @@ public:
/**
* Add a new archive to the searchable set.
*/
- void add(const String& name, ArchivePtr archive, uint priority = 0);
+ void add(const String& name, ArchivePtr archive, int priority = 0);
/**
* Remove an archive from the searchable set.
@@ -184,12 +184,12 @@ public:
/**
* Empties the searchable set.
*/
- void clear();
+ virtual void clear();
/**
* Change the order of searches.
*/
- void setPriority(const String& name, uint priority);
+ void setPriority(const String& name, int priority);
virtual bool hasFile(const String &name);
virtual int matchPattern(StringList &list, const String &pattern);
@@ -205,22 +205,28 @@ public:
class SearchManager : public Singleton<SearchManager>, public SearchSet {
public:
+ SearchManager();
+
/**
* Add an existing Archive. This is meant to support searching in system-specific
* archives, namely the MACOSX/IPHONE bundles.
*/
- void addArchive(const String &name, ArchivePtr archive);
+ void addArchive(const String &name, ArchivePtr archive, int priority = 0);
/**
* Create and add a FSDirectory by name
*/
- void addDirectory(const String &name, const String &directory);
+ void addDirectory(const String &name, const String &directory, int priority = 0);
/**
* Create and add a FSDirectory and its subdirectories by name
*/
- void addDirectoryRecursive(const String &name, const String &directory, int depth = 4);
+ void addDirectoryRecursive(const String &name, const String &directory, int depth = 4, int priority = 0);
+ /**
+ * TODO
+ */
+ virtual void clear();
};
/** Shortcut for accessing the search manager. */
diff --git a/common/file.cpp b/common/file.cpp
index cf396a32cd..6558dfea33 100644
--- a/common/file.cpp
+++ b/common/file.cpp
@@ -31,9 +31,6 @@
namespace Common {
-static Common::SearchSet *s_searchSet = 0;
-
-
void File::addDefaultDirectory(const String &directory) {
FilesystemNode dir(directory);
addDefaultDirectoryRecursive(dir, 1);
@@ -52,18 +49,12 @@ void File::addDefaultDirectoryRecursive(const FilesystemNode &dir, int level) {
if (level <= 0 || !dir.exists() || !dir.isDirectory())
return;
- if (!s_searchSet) {
- s_searchSet = new Common::SearchSet();
- g_system->addSysArchivesToSearchSet(*s_searchSet);
- }
-
Common::ArchivePtr dataArchive(new Common::FSDirectory(dir, level));
- s_searchSet->add(dir.getPath(), dataArchive, 1);
+ SearchMan.add(dir.getPath(), dataArchive);
}
void File::resetDefaultDirectories() {
- delete s_searchSet;
- s_searchSet = 0;
+ SearchMan.clear();
}
File::File()
@@ -82,23 +73,18 @@ bool File::open(const String &filename) {
_name.clear();
clearIOFailed();
- if (s_searchSet && s_searchSet->hasFile(filename)) {
+ if (SearchMan.hasFile(filename)) {
debug(3, "Opening hashed: %s", filename.c_str());
- _handle = s_searchSet->openFile(filename);
- } else if (s_searchSet && s_searchSet->hasFile(filename + ".")) {
+ _handle = SearchMan.openFile(filename);
+ } else if (SearchMan.hasFile(filename + ".")) {
// WORKAROUND: Bug #1458388: "SIMON1: Game Detection fails"
// sometimes instead of "GAMEPC" we get "GAMEPC." (note trailing dot)
debug(3, "Opening hashed: %s.", filename.c_str());
- _handle = s_searchSet->openFile(filename);
- } else {
- // Last resort: try the current directory
- FilesystemNode file(filename);
- if (file.exists() && !file.isDirectory())
- _handle = file.openForReading();
+ _handle = SearchMan.openFile(filename + ".");
}
if (_handle == NULL)
- debug(2, "File %s not opened", filename.c_str());
+ debug(2, "File::open: '%s' not found", filename.c_str());
else
_name = filename;
@@ -127,7 +113,7 @@ bool File::open(const FilesystemNode &node) {
_handle = node.openForReading();
if (_handle == NULL)
- debug(2, "File %s not found", filename.c_str());
+ debug(2, "File::open: '%s' not found", node.getPath().c_str());
else
_name = filename;
@@ -135,17 +121,12 @@ bool File::open(const FilesystemNode &node) {
}
bool File::exists(const String &filename) {
- if (s_searchSet && s_searchSet->hasFile(filename)) {
+ if (SearchMan.hasFile(filename)) {
return true;
- } else if (s_searchSet && s_searchSet->hasFile(filename + ".")) {
+ } else if (SearchMan.hasFile(filename + ".")) {
// WORKAROUND: Bug #1458388: "SIMON1: Game Detection fails"
// sometimes instead of "GAMEPC" we get "GAMEPC." (note trailing dot)
return true;
- } else {
- // Last resort: try the current directory
- FilesystemNode file(filename);
- if (file.exists() && !file.isDirectory())
- return true;
}
return false;
diff --git a/common/str.cpp b/common/str.cpp
index a415e376c9..6c48738533 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -26,6 +26,13 @@
#include "common/hash-str.h"
#include "common/util.h"
+#include "common/memorypool.h"
+
+#if !defined(__SYMBIAN32__)
+#include <new>
+#endif
+
+
namespace Common {
#if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
@@ -34,6 +41,9 @@ const String String::emptyString;
const char *String::emptyString = "";
#endif
+
+MemoryPool *g_refCountPool = 0; // FIXME: This is never freed right now
+
static uint32 computeCapacity(uint32 len) {
// By default, for the capacity we use the next multiple of 32
return ((len + 32 - 1) & ~0x1F);
@@ -79,15 +89,17 @@ void String::initWithCStr(const char *str, uint32 len) {
}
String::String(const String &str)
- : _size(str._size), _str(str.isStorageIntern() ? _storage : str._str) {
+ : _size(str._size) {
if (str.isStorageIntern()) {
// String in internal storage: just copy it
- memcpy(_storage, str._storage, sizeof(_storage));
+ memcpy(_storage, str._storage, _builtinCapacity);
+ _str = _storage;
} else {
// String in external storage: use refcount mechanism
str.incRefCount();
_extern._refCount = str._extern._refCount;
_extern._capacity = str._extern._capacity;
+ _str = str._str;
}
assert(_str != 0);
}
@@ -178,7 +190,11 @@ void String::ensureCapacity(uint32 new_size, bool keep_old) {
void String::incRefCount() const {
assert(!isStorageIntern());
if (_extern._refCount == 0) {
- _extern._refCount = new int(2);
+ if (g_refCountPool == 0)
+ g_refCountPool = new MemoryPool(sizeof(int));
+
+ _extern._refCount = (int *)g_refCountPool->malloc();
+ *_extern._refCount = 2;
} else {
++(*_extern._refCount);
}
@@ -194,7 +210,10 @@ void String::decRefCount(int *oldRefCount) {
if (!oldRefCount || *oldRefCount <= 0) {
// The ref count reached zero, so we free the string storage
// and the ref count storage.
- delete oldRefCount;
+ if (oldRefCount) {
+ assert(g_refCountPool);
+ g_refCountPool->free(oldRefCount);
+ }
free(_str);
// Even though _str points to a freed memory block now,
diff --git a/common/str.h b/common/str.h
index 20914c1f1f..c3e773c3e4 100644
--- a/common/str.h
+++ b/common/str.h
@@ -54,7 +54,7 @@ protected:
* than 8 makes no sense, since that's the size of member _extern
* (on 32 bit machines; 12 bytes on systems with 64bit pointers).
*/
- static const uint32 _builtinCapacity = 32;
+ static const uint32 _builtinCapacity = 32 - sizeof(uint32) - sizeof(char*);
/**
* Length of the string. Stored to avoid having to call strlen
@@ -112,7 +112,7 @@ public:
String(const String &str);
/** Construct a string consisting of the given character. */
- String(char c);
+ explicit String(char c);
~String();
diff --git a/common/system.h b/common/system.h
index cb9dbedad7..176e53ddb4 100644
--- a/common/system.h
+++ b/common/system.h
@@ -917,7 +917,7 @@ public:
* @param s the SearchSet to which the system specific dirs, if any, are added
* @param priority the priority with which those dirs are added
*/
- virtual void addSysArchivesToSearchSet(Common::SearchSet &s, uint priority = 0) {}
+ virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0) {}
/**
* Open the default config file for reading, by returning a suitable
diff --git a/common/unarj.cpp b/common/unarj.cpp
index 244a296efb..00f51ac252 100644
--- a/common/unarj.cpp
+++ b/common/unarj.cpp
@@ -324,15 +324,15 @@ uint32 ArjFile::read(void *dataPtr, uint32 dataSize) {
return _uncompressed->read(dataPtr, dataSize);
}
-bool ArjFile::eos() {
+bool ArjFile::eos() const {
return _uncompressed->eos();
}
-int32 ArjFile::pos() {
+int32 ArjFile::pos() const {
return _uncompressed->pos();
}
-int32 ArjFile::size() {
+int32 ArjFile::size() const {
return _uncompressed->size();
}
diff --git a/common/unarj.h b/common/unarj.h
index 52e0d13948..d16d748ad3 100644
--- a/common/unarj.h
+++ b/common/unarj.h
@@ -85,7 +85,7 @@ struct ArjHeader {
typedef HashMap<String, int, IgnoreCase_Hash, IgnoreCase_EqualTo> ArjFilesMap;
-class ArjFile : public File {
+class ArjFile : public SeekableReadStream, public NonCopyable {
public:
ArjFile();
~ArjFile();
@@ -98,9 +98,9 @@ public:
void close();
uint32 read(void *dataPtr, uint32 dataSize);
- bool eos();
- int32 pos();
- int32 size();
+ bool eos() const;
+ int32 pos() const;
+ int32 size() const;
bool seek(int32 offset, int whence = SEEK_SET);
bool isOpen() { return _isOpen; }
diff --git a/common/unzip.cpp b/common/unzip.cpp
index 93fb60f41c..27001519a1 100644
--- a/common/unzip.cpp
+++ b/common/unzip.cpp
@@ -28,14 +28,51 @@
Read unzip.h for more info
*/
+/* unzip.h -- IO for uncompress .zip files using zlib
+ Version 0.15 beta, Mar 19th, 1998,
+
+ Copyright (C) 1998 Gilles Vollant
+
+ This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
+ WinZip, InfoZip tools and compatible.
+ Encryption and multi volume ZipFile (span) are not supported.
+ Old compressions used by old PKZip 1.x are not supported
+
+ THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
+ CAN CHANGE IN FUTURE VERSION !!
+ I WAIT FEEDBACK at mail info@winimage.com
+ Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
+
+ Condition of use and distribution are the same than zlib :
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+
+*/
+/* for more info about .ZIP format, see
+ ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
+ PkWare has also a specification at :
+ ftp://ftp.pkware.com/probdesc.zip */
+
+
#include "common/scummsys.h"
#ifdef USE_ZLIB
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
#ifdef __SYMBIAN32__
#include <zlib\zlib.h>
#else
@@ -45,24 +82,213 @@
#include "common/unzip.h"
#include "common/file.h"
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+ from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef unzFile__ *unzFile;
#else
-# include <errno.h>
+typedef voidp unzFile;
#endif
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
+#define UNZ_OK (0)
+#define UNZ_END_OF_LIST_OF_FILE (-100)
+#define UNZ_ERRNO (Z_ERRNO)
+#define UNZ_EOF (0)
+#define UNZ_PARAMERROR (-102)
+#define UNZ_BADZIPFILE (-103)
+#define UNZ_INTERNALERROR (-104)
+#define UNZ_CRCERROR (-105)
+
+/* tm_unz contain date/time info */
+typedef struct {
+ uInt tm_sec; /* seconds after the minute - [0,59] */
+ uInt tm_min; /* minutes after the hour - [0,59] */
+ uInt tm_hour; /* hours since midnight - [0,23] */
+ uInt tm_mday; /* day of the month - [1,31] */
+ uInt tm_mon; /* months since January - [0,11] */
+ uInt tm_year; /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+ These data comes from the end of central dir */
+typedef struct {
+ uLong number_entry; /* total number of entries in
+ the central dir on this disk */
+ uLong size_comment; /* size of the global comment of the zipfile */
+} unz_global_info;
+
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct {
+ uLong version; /* version made by 2 bytes */
+ uLong version_needed; /* version needed to extract 2 bytes */
+ uLong flag; /* general purpose bit flag 2 bytes */
+ uLong compression_method; /* compression method 2 bytes */
+ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
+ uLong crc; /* crc-32 4 bytes */
+ uLong compressed_size; /* compressed size 4 bytes */
+ uLong uncompressed_size; /* uncompressed size 4 bytes */
+ uLong size_filename; /* filename length 2 bytes */
+ uLong size_file_extra; /* extra field length 2 bytes */
+ uLong size_file_comment; /* file comment length 2 bytes */
+
+ uLong disk_num_start; /* disk number start 2 bytes */
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+
+ tm_unz tmu_date;
+} unz_file_info;
+
+int unzStringFileNameCompare(const char* fileName1,
+ const char* fileName2,
+ int iCaseSensitivity);
+/*
+ Compare two filename (fileName1,fileName2).
+ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ or strcasecmp)
+ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ (like 1 on Unix, 2 on Windows)
+*/
+
+
+unzFile unzOpen(const char *path);
+/*
+ Open a Zip file. path contain the full pathname (by example,
+ on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
+ "zlib/zlib111.zip".
+ If the zipfile cannot be opened (file don't exist or in not valid), the
+ return value is NULL.
+ Else, the return value is a unzFile Handle, usable with other function
+ of this unzip package.
+*/
+
+int unzClose(unzFile file);
+/*
+ Close a ZipFile opened with unzipOpen.
+ If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+ these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+ return UNZ_OK if there is no problem. */
+
+int unzGetGlobalInfo(unzFile file,
+ unz_global_info *pglobal_info);
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem. */
+
+
+int unzGetGlobalComment(unzFile file, char *szComment, uLong uSizeBuf);
+/*
+ Get the global comment string of the ZipFile, in the szComment buffer.
+ uSizeBuf is the size of the szComment buffer.
+ return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+int unzGoToFirstFile(unzFile file);
+/*
+ Set the current file of the zipfile to the first file.
+ return UNZ_OK if there is no problem
+*/
+
+int unzGoToNextFile(unzFile file);
+/*
+ Set the current file of the zipfile to the next file.
+ return UNZ_OK if there is no problem
+ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+int unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity);
+/*
+ Try locate the file szFileName in the zipfile.
+ For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+ return value :
+ UNZ_OK if the file is found. It becomes the current file.
+ UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+int unzGetCurrentFileInfo(unzFile file,
+ unz_file_info *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize);
+/*
+ Get Info about the current file
+ if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+ the current file
+ if szFileName!=NULL, the filemane string will be copied in szFileName
+ (fileNameBufferSize is the size of the buffer)
+ if extraField!=NULL, the extra field information will be copied in extraField
+ (extraFieldBufferSize is the size of the buffer).
+ This is the Central-header version of the extra field
+ if szComment!=NULL, the comment string of the file will be copied in szComment
+ (commentBufferSize is the size of the buffer)
+*/
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+ from it, and close it (you can close it before reading all the file)
+ */
+
+int unzOpenCurrentFile(unzFile file);
+/*
+ Open for reading data the current file in the zipfile.
+ If there is no error, the return value is UNZ_OK.
+*/
+int unzCloseCurrentFile(unzFile file);
+/*
+ Close the file in zip opened with unzOpenCurrentFile
+ Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+
+int unzReadCurrentFile(unzFile file, voidp buf, unsigned len);
+/*
+ Read bytes from the current file (opened by unzOpenCurrentFile)
+ buf contain buffer where data must be copied
+ len the size of buf.
+
+ return the number of byte copied if somes bytes are copied
+ return 0 if the end of file was reached
+ return <0 with error code if there is an error
+ (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+z_off_t unztell(unzFile file);
+/*
+ Give the current position in uncompressed data
+*/
+
+int unzeof(unzFile file);
+/*
+ return 1 if the end of file was reached, 0 elsewhere
+*/
+
+int unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len);
+/*
+ Read extra field from the current file (opened by unzOpenCurrentFile)
+ This is the local-header version of the extra field (sometimes, there is
+ more info in the local-header version than in the central-header)
+
+ if buf==NULL, it return the size of the local extra field
+
+ if buf!=NULL, len is the size of the buffer, the extra header is copied in
+ buf.
+ the return value is the number of bytes copied in buf, or (if <0)
+ the error code
+*/
#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
!defined(CASESENSITIVITYDEFAULT_NO)
@@ -78,45 +304,22 @@
#define UNZ_MAXFILENAMEINZIP (256)
#endif
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
#define SIZECENTRALDIRITEM (0x2e)
#define SIZEZIPLOCALHEADER (0x1e)
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
const char unz_copyright[] =
" unzip 0.15 Copyright 1998 Gilles Vollant ";
/* unz_file_info_interntal contain internal info about a file in zipfile*/
-typedef struct unz_file_info_internal_s
-{
+typedef struct {
uLong offset_curfile;/* relative offset of local header 4 bytes */
} unz_file_info_internal;
/* file_in_zip_read_info_s contain internal information about a file in zipfile,
when reading and decompress it */
-typedef struct
-{
+typedef struct {
char *read_buffer; /* internal buffer for compressed data */
z_stream stream; /* zLib stream structure for inflate */
@@ -139,8 +342,7 @@ typedef struct
/* unz_s contain internal information about the zipfile
*/
-typedef struct
-{
+typedef struct {
Common::File file; /* io structore of the zipfile */
unz_global_info gi; /* public global information */
uLong byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/
@@ -166,14 +368,11 @@ typedef struct
*/
-/*local int unzlocal_getByte(Common::File &fin, int *pi)
-{
+/*static int unzlocal_getByte(Common::File &fin, int *pi) {
unsigned char c = fin.readByte();
*pi = (int)c;
return UNZ_OK;
- }
- else
- {
+ } else {
if (fin.ioFailed())
return UNZ_ERRNO;
else
@@ -185,37 +384,14 @@ typedef struct
/* ===========================================================================
Reads a long in LSB order from the given gz_stream. Sets
*/
-local int unzlocal_getShort (Common::File &fin, uLong *pX)
-{
+static int unzlocal_getShort(Common::File &fin, uLong *pX) {
*pX = fin.readUint16LE();
- return UNZ_OK;
+ return fin.ioFailed() ? UNZ_ERRNO : UNZ_OK;
}
-local int unzlocal_getLong (Common::File &fin, uLong *pX)
-{
+static int unzlocal_getLong(Common::File &fin, uLong *pX) {
*pX = fin.readUint32LE();
- return UNZ_OK;
-}
-
-/* My own strcmpi / strcasecmp */
-local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) {
- for (;;)
- {
- char c1=*(fileName1++);
- char c2=*(fileName2++);
- if ((c1>='a') && (c1<='z'))
- c1 -= 0x20;
- if ((c2>='a') && (c2<='z'))
- c2 -= 0x20;
- if (c1=='\0')
- return ((c2=='\0') ? 0 : -1);
- if (c2=='\0')
- return 1;
- if (c1<c2)
- return -1;
- if (c1>c2)
- return 1;
- }
+ return fin.ioFailed() ? UNZ_ERRNO : UNZ_OK;
}
@@ -225,10 +401,6 @@ local int strcmpcasenosensitive_internal (const char* fileName1, const char* fil
#define CASESENSITIVITYDEFAULTVALUE 1
#endif
-#ifndef STRCMPCASENOSENTIVEFUNCTION
-#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
-#endif
-
/*
Compare two filename (fileName1,fileName2).
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
@@ -238,15 +410,14 @@ local int strcmpcasenosensitive_internal (const char* fileName1, const char* fil
(like 1 on Unix, 2 on Windows)
*/
-extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, const char* fileName2, int iCaseSensitivity)
-{
+int unzStringFileNameCompare(const char* fileName1, const char* fileName2, int iCaseSensitivity) {
if (iCaseSensitivity==0)
iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
if (iCaseSensitivity==1)
return strcmp(fileName1,fileName2);
- return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
+ return scumm_stricmp(fileName1,fileName2);
}
#define BUFREADCOMMENT (0x400)
@@ -255,8 +426,7 @@ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, const char*
Locate the Central directory of a zipfile (at the end, just before
the global comment)
*/
-local uLong unzlocal_SearchCentralDir(Common::File &fin)
-{
+static uLong unzlocal_SearchCentralDir(Common::File &fin) {
unsigned char* buf;
uLong uSizeFile;
uLong uBackRead;
@@ -270,13 +440,12 @@ local uLong unzlocal_SearchCentralDir(Common::File &fin)
if (uMaxBack>uSizeFile)
uMaxBack = uSizeFile;
- buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ buf = (unsigned char*)malloc(BUFREADCOMMENT+4);
if (buf==NULL)
return 0;
uBackRead = 4;
- while (uBackRead<uMaxBack)
- {
+ while (uBackRead<uMaxBack) {
uLong uReadSize,uReadPos ;
int i;
if (uBackRead+BUFREADCOMMENT>uMaxBack)
@@ -305,7 +474,7 @@ local uLong unzlocal_SearchCentralDir(Common::File &fin)
if (uPosFound!=0)
break;
}
- TRYFREE(buf);
+ free(buf);
return uPosFound;
}
@@ -318,8 +487,7 @@ local uLong unzlocal_SearchCentralDir(Common::File &fin)
Else, the return value is a unzFile Handle, usable with other function
of this unzip package.
*/
-extern unzFile ZEXPORT unzOpen (const char *path)
-{
+unzFile unzOpen(const char *path) {
unz_s *us = new unz_s;
uLong central_pos,uL;
@@ -408,8 +576,7 @@ extern unzFile ZEXPORT unzOpen (const char *path)
If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzClose (unzFile file)
-{
+int unzClose(unzFile file) {
unz_s* s;
if (file==NULL)
return UNZ_PARAMERROR;
@@ -428,8 +595,7 @@ extern int ZEXPORT unzClose (unzFile file)
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info)
-{
+int unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info) {
unz_s* s;
if (file==NULL)
return UNZ_PARAMERROR;
@@ -442,8 +608,7 @@ extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info
/*
Translate date/time from Dos format to tm_unz (readable more easilty)
*/
-local void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm)
-{
+static void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm) {
uLong uDate;
uDate = (uLong)(ulDosDate>>16);
ptm->tm_mday = (uInt)(uDate&0x1f) ;
@@ -458,7 +623,7 @@ local void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm)
/*
Get Info about the current file in the zipfile, with internal only info
*/
-local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
+static int unzlocal_GetCurrentFileInfoInternal(unzFile file,
unz_file_info *pfile_info,
unz_file_info_internal
*pfile_info_internal,
@@ -467,9 +632,9 @@ local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
void *extraField,
uLong extraFieldBufferSize,
char *szComment,
- uLong commentBufferSize));
+ uLong commentBufferSize);
-local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
+static int unzlocal_GetCurrentFileInfoInternal(unzFile file,
unz_file_info *pfile_info,
unz_file_info_internal *pfile_info_internal,
char *szFileName, uLong fileNameBufferSize,
@@ -492,8 +657,7 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
/* we check the magic */
- if (err==UNZ_OK)
- {
+ if (err==UNZ_OK) {
if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
err=UNZ_ERRNO;
else if (uMagic!=0x02014b50)
@@ -548,15 +712,12 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
err=UNZ_ERRNO;
lSeek+=file_info.size_filename;
- if ((err==UNZ_OK) && (szFileName!=NULL))
- {
+ if ((err==UNZ_OK) && (szFileName!=NULL)) {
uLong uSizeRead ;
- if (file_info.size_filename<fileNameBufferSize)
- {
+ if (file_info.size_filename<fileNameBufferSize) {
*(szFileName+file_info.size_filename)='\0';
uSizeRead = file_info.size_filename;
- }
- else
+ } else
uSizeRead = fileNameBufferSize;
if ((file_info.size_filename>0) && (fileNameBufferSize>0))
@@ -566,16 +727,14 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
}
- if ((err==UNZ_OK) && (extraField!=NULL))
- {
+ if ((err==UNZ_OK) && (extraField!=NULL)) {
uLong uSizeRead ;
if (file_info.size_file_extra<extraFieldBufferSize)
uSizeRead = file_info.size_file_extra;
else
uSizeRead = extraFieldBufferSize;
- if (lSeek!=0)
- {
+ if (lSeek!=0) {
s->file.seek(lSeek, SEEK_CUR);
if (s->file.ioFailed())
lSeek=0;
@@ -591,19 +750,15 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
lSeek+=file_info.size_file_extra;
- if ((err==UNZ_OK) && (szComment!=NULL))
- {
+ if ((err==UNZ_OK) && (szComment!=NULL)) {
uLong uSizeRead ;
- if (file_info.size_file_comment<commentBufferSize)
- {
+ if (file_info.size_file_comment<commentBufferSize) {
*(szComment+file_info.size_file_comment)='\0';
uSizeRead = file_info.size_file_comment;
- }
- else
+ } else
uSizeRead = commentBufferSize;
- if (lSeek!=0)
- {
+ if (lSeek!=0) {
s->file.seek(lSeek, SEEK_CUR);
if (s->file.ioFailed())
lSeek=0;
@@ -614,8 +769,7 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
if (s->file.read(szComment,(uInt)uSizeRead)!=uSizeRead)
err=UNZ_ERRNO;
lSeek+=file_info.size_file_comment - uSizeRead;
- }
- else
+ } else
lSeek+=file_info.size_file_comment;
if ((err==UNZ_OK) && (pfile_info!=NULL))
@@ -634,7 +788,7 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
No preparation of the structure is needed
return UNZ_OK if there is no problem.
*/
-extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
+int unzGetCurrentFileInfo(unzFile file,
unz_file_info *pfile_info,
char *szFileName, uLong fileNameBufferSize,
void *extraField, uLong extraFieldBufferSize,
@@ -650,8 +804,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
-extern int ZEXPORT unzGoToFirstFile (unzFile file)
-{
+int unzGoToFirstFile(unzFile file) {
int err=UNZ_OK;
unz_s* s;
if (file==NULL)
@@ -672,8 +825,7 @@ extern int ZEXPORT unzGoToFirstFile (unzFile file)
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
-extern int ZEXPORT unzGoToNextFile (unzFile file)
-{
+int unzGoToNextFile(unzFile file) {
unz_s* s;
int err;
@@ -704,8 +856,7 @@ extern int ZEXPORT unzGoToNextFile (unzFile file)
UNZ_OK if the file is found. It becomes the current file.
UNZ_END_OF_LIST_OF_FILE if the file is not found
*/
-extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
-{
+int unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity) {
unz_s* s;
int err;
@@ -729,8 +880,7 @@ extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCas
err = unzGoToFirstFile(file);
- while (err == UNZ_OK)
- {
+ while (err == UNZ_OK) {
char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
unzGetCurrentFileInfo(file,NULL,
szCurrentFileName,sizeof(szCurrentFileName)-1,
@@ -754,10 +904,9 @@ extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCas
store in *piSizeVar the size of extra info in local header
(filename and size of extra field data)
*/
-local int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar,
+static int unzlocal_CheckCurrentFileCoherencyHeader(unz_s* s, uInt* piSizeVar,
uLong *poffset_local_extrafield,
- uInt *psize_local_extrafield)
-{
+ uInt *psize_local_extrafield) {
uLong uMagic,uData,uFlags;
uLong size_filename;
uLong size_extra_field;
@@ -773,8 +922,7 @@ local int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar,
return UNZ_ERRNO;
- if (err==UNZ_OK)
- {
+ if (err==UNZ_OK) {
if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
err=UNZ_ERRNO;
else if (uMagic!=0x04034b50)
@@ -843,8 +991,7 @@ local int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar,
Open for reading data the current file in the zipfile.
If there is no error and the file is opened, the return value is UNZ_OK.
*/
-extern int ZEXPORT unzOpenCurrentFile (unzFile file)
-{
+int unzOpenCurrentFile (unzFile file) {
int err=UNZ_OK;
int Store;
uInt iSizeVar;
@@ -866,19 +1013,19 @@ extern int ZEXPORT unzOpenCurrentFile (unzFile file)
&offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
return UNZ_BADZIPFILE;
- pfile_in_zip_read_info = (file_in_zip_read_info_s*) ALLOC(sizeof(file_in_zip_read_info_s));
+ pfile_in_zip_read_info = (file_in_zip_read_info_s*) malloc(sizeof(file_in_zip_read_info_s));
if (pfile_in_zip_read_info==NULL)
return UNZ_INTERNALERROR;
- pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
+ pfile_in_zip_read_info->read_buffer=(char*)malloc(UNZ_BUFSIZE);
pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
pfile_in_zip_read_info->pos_local_extrafield=0;
if (pfile_in_zip_read_info->read_buffer==NULL)
{
- TRYFREE(pfile_in_zip_read_info);
+ free(pfile_in_zip_read_info);
return UNZ_INTERNALERROR;
}
@@ -938,8 +1085,7 @@ extern int ZEXPORT unzOpenCurrentFile (unzFile file)
return <0 with error code if there is an error
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
-extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
-{
+int unzReadCurrentFile(unzFile file, voidp buf, unsigned len) {
int err=UNZ_OK;
uInt iRead = 0;
unz_s* s;
@@ -1051,8 +1197,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
/*
Give the current position in uncompressed data
*/
-extern z_off_t ZEXPORT unztell (unzFile file)
-{
+z_off_t unztell(unzFile file) {
unz_s* s;
file_in_zip_read_info_s* pfile_in_zip_read_info;
if (file==NULL)
@@ -1070,8 +1215,7 @@ extern z_off_t ZEXPORT unztell (unzFile file)
/*
return 1 if the end of file was reached, 0 elsewhere
*/
-extern int ZEXPORT unzeof (unzFile file)
-{
+int unzeof(unzFile file) {
unz_s* s;
file_in_zip_read_info_s* pfile_in_zip_read_info;
if (file==NULL)
@@ -1102,8 +1246,7 @@ extern int ZEXPORT unzeof (unzFile file)
the return value is the number of bytes copied in buf, or (if <0)
the error code
*/
-extern int ZEXPORT unzGetLocalExtrafield (unzFile file,voidp buf,unsigned len)
-{
+int unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) {
unz_s* s;
file_in_zip_read_info_s* pfile_in_zip_read_info;
uInt read_now;
@@ -1146,8 +1289,7 @@ extern int ZEXPORT unzGetLocalExtrafield (unzFile file,voidp buf,unsigned len)
Close the file in zip opened with unzipOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
-extern int ZEXPORT unzCloseCurrentFile (unzFile file)
-{
+int unzCloseCurrentFile(unzFile file) {
int err=UNZ_OK;
unz_s* s;
@@ -1167,13 +1309,13 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file)
}
- TRYFREE(pfile_in_zip_read_info->read_buffer);
+ free(pfile_in_zip_read_info->read_buffer);
pfile_in_zip_read_info->read_buffer = NULL;
if (pfile_in_zip_read_info->stream_initialised)
inflateEnd(&pfile_in_zip_read_info->stream);
pfile_in_zip_read_info->stream_initialised = 0;
- TRYFREE(pfile_in_zip_read_info);
+ free(pfile_in_zip_read_info);
s->pfile_in_zip_read=NULL;
@@ -1186,8 +1328,7 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file)
uSizeBuf is the size of the szComment buffer.
return the number of byte copied or an error code <0
*/
-extern int ZEXPORT unzGetGlobalComment (unzFile file, char *szComment, uLong uSizeBuf)
-{
+int unzGetGlobalComment(unzFile file, char *szComment, uLong uSizeBuf) {
unz_s* s;
uLong uReadThis ;
if (file==NULL)
@@ -1213,4 +1354,111 @@ extern int ZEXPORT unzGetGlobalComment (unzFile file, char *szComment, uLong uSi
return (int)uReadThis;
}
+
+namespace Common {
+
+
+/*
+class ZipArchiveMember : public ArchiveMember {
+ unzFile _zipFile;
+
+public:
+ ZipArchiveMember(FilesystemNode &node) : _node(node) {
+ }
+
+ String getName() const {
+ ...
+ }
+
+ SeekableReadStream *open() {
+ ...
+ }
+};
+*/
+
+ZipArchive::ZipArchive(const Common::String &name) {
+ _zipFile = unzOpen(name.c_str());
+}
+
+ZipArchive::~ZipArchive() {
+ unzClose(_zipFile);
+}
+
+bool ZipArchive::isOpen() const {
+ return _zipFile != 0;
+}
+
+bool ZipArchive::hasFile(const Common::String &name) {
+ return (_zipFile && unzLocateFile(_zipFile, name.c_str(), 2) == UNZ_OK);
+}
+
+int ZipArchive::getAllNames(Common::StringList &list) {
+ if (!_zipFile)
+ return 0;
+
+ if (unzGoToFirstFile(_zipFile) != UNZ_OK)
+ return 0;
+
+ char fileNameBuffer[UNZ_MAXFILENAMEINZIP+1];
+ list.clear();
+
+ do {
+ unzOpenCurrentFile(_zipFile);
+ unzGetCurrentFileInfo(_zipFile, 0, fileNameBuffer, UNZ_MAXFILENAMEINZIP+1, 0, 0, 0, 0);
+
+ list.push_back(Common::String(fileNameBuffer));
+
+ unzCloseCurrentFile(_zipFile);
+
+ } while (unzGoToNextFile(_zipFile) == UNZ_OK);
+
+ return list.size();
+}
+
+/*
+int ZipArchive::listMembers(Common::ArchiveMemberList &list) {
+ if (!_zipFile)
+ return 0;
+
+ int matches = 0;
+ int err = unzGoToFirstFile(_zipFile);
+
+ while (err == UNZ_OK) {
+ char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
+ unzGetCurrentFileInfo(_zipFile, NULL,
+ szCurrentFileName, sizeof(szCurrentFileName)-1,
+ NULL, 0, NULL, 0);
+
+ szCurrentFileName
+ matches++;
+ err = unzGoToNextFile(file);
+ }
+ return 0;
+}
+*/
+
+Common::SeekableReadStream *ZipArchive::openFile(const Common::String &name) {
+ if (!_zipFile)
+ return 0;
+
+ unzLocateFile(_zipFile, name.c_str(), 2);
+
+ unz_file_info fileInfo;
+ unzOpenCurrentFile(_zipFile);
+ unzGetCurrentFileInfo(_zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
+ byte *buffer = (byte *)calloc(fileInfo.uncompressed_size+1, 1);
+ assert(buffer);
+ unzReadCurrentFile(_zipFile, buffer, fileInfo.uncompressed_size);
+ unzCloseCurrentFile(_zipFile);
+ return new Common::MemoryReadStream(buffer, fileInfo.uncompressed_size+1, true);
+
+ // FIXME: instead of reading all into a memory stream, we could
+ // instead create a new ZipStream class. But then we have to be
+ // careful to handle the case where the client code opens multiple
+ // files in the archive and tries to use them indepenendtly.
+}
+
+} // End of namespace Common
+
+
#endif
diff --git a/common/unzip.h b/common/unzip.h
index 43faaf4a74..e4eb754eee 100644
--- a/common/unzip.h
+++ b/common/unzip.h
@@ -22,332 +22,34 @@
* $Id$
*/
-/* unzip.h -- IO for uncompress .zip files using zlib
- Version 0.15 beta, Mar 19th, 1998,
-
- Copyright (C) 1998 Gilles Vollant
-
- This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
- WinZip, InfoZip tools and compatible.
- Encryption and multi volume ZipFile (span) are not supported.
- Old compressions used by old PKZip 1.x are not supported
-
- THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
- CAN CHANGE IN FUTURE VERSION !!
- I WAIT FEEDBACK at mail info@winimage.com
- Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
-
- Condition of use and distribution are the same than zlib :
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
-
-*/
-/* for more info about .ZIP format, see
- ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
- PkWare has also a specification at :
- ftp://ftp.pkware.com/probdesc.zip */
-
-#ifndef _unz_H
-#define _unz_H
+#ifndef COMMON_UNZIP_H
+#define COMMON_UNZIP_H
#ifdef USE_ZLIB
#include "common/scummsys.h"
#include "common/archive.h"
-#include "common/stream.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __SYMBIAN32__
-#include <zlib\zlib.h>
-#else
-#include <zlib.h>
-#endif
-
-#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
-typedef struct TagunzFile__ { int unused; } unzFile__;
-typedef unzFile__ *unzFile;
-#else
-typedef voidp unzFile;
-#endif
-
-
-#define UNZ_OK (0)
-#define UNZ_END_OF_LIST_OF_FILE (-100)
-#define UNZ_ERRNO (Z_ERRNO)
-#define UNZ_EOF (0)
-#define UNZ_PARAMERROR (-102)
-#define UNZ_BADZIPFILE (-103)
-#define UNZ_INTERNALERROR (-104)
-#define UNZ_CRCERROR (-105)
-
-/* tm_unz contain date/time info */
-typedef struct tm_unz_s
-{
- uInt tm_sec; /* seconds after the minute - [0,59] */
- uInt tm_min; /* minutes after the hour - [0,59] */
- uInt tm_hour; /* hours since midnight - [0,23] */
- uInt tm_mday; /* day of the month - [1,31] */
- uInt tm_mon; /* months since January - [0,11] */
- uInt tm_year; /* years - [1980..2044] */
-} tm_unz;
-
-/* unz_global_info structure contain global data about the ZIPfile
- These data comes from the end of central dir */
-typedef struct unz_global_info_s
-{
- uLong number_entry; /* total number of entries in
- the central dir on this disk */
- uLong size_comment; /* size of the global comment of the zipfile */
-} unz_global_info;
-
-
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_info_s
-{
- uLong version; /* version made by 2 bytes */
- uLong version_needed; /* version needed to extract 2 bytes */
- uLong flag; /* general purpose bit flag 2 bytes */
- uLong compression_method; /* compression method 2 bytes */
- uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
- uLong crc; /* crc-32 4 bytes */
- uLong compressed_size; /* compressed size 4 bytes */
- uLong uncompressed_size; /* uncompressed size 4 bytes */
- uLong size_filename; /* filename length 2 bytes */
- uLong size_file_extra; /* extra field length 2 bytes */
- uLong size_file_comment; /* file comment length 2 bytes */
-
- uLong disk_num_start; /* disk number start 2 bytes */
- uLong internal_fa; /* internal file attributes 2 bytes */
- uLong external_fa; /* external file attributes 4 bytes */
-
- tm_unz tmu_date;
-} unz_file_info;
-
-extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
- const char* fileName2,
- int iCaseSensitivity));
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-*/
-
-
-extern unzFile ZEXPORT unzOpen OF((const char *path));
-/*
- Open a Zip file. path contain the full pathname (by example,
- on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
- "zlib/zlib111.zip".
- If the zipfile cannot be opened (file don't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-
-extern int ZEXPORT unzClose OF((unzFile file));
-/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
- unz_global_info *pglobal_info));
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
+typedef void *unzFile;
+namespace Common {
-extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
- char *szComment,
- uLong uSizeBuf));
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-
-
-/***************************************************************************/
-/* Unzip package allow you browse the directory of the zipfile */
-
-extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-
-extern int ZEXPORT unzGoToNextFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-
-extern int ZEXPORT unzLocateFile OF((unzFile file,
- const char *szFileName,
- int iCaseSensitivity));
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-
-
-extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
- unz_file_info *pfile_info,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-/*
- Get Info about the current file
- if pfile_info!=NULL, the *pfile_info structure will contain somes info about
- the current file
- if szFileName!=NULL, the filemane string will be copied in szFileName
- (fileNameBufferSize is the size of the buffer)
- if extraField!=NULL, the extra field information will be copied in extraField
- (extraFieldBufferSize is the size of the buffer).
- This is the Central-header version of the extra field
- if szComment!=NULL, the comment string of the file will be copied in szComment
- (commentBufferSize is the size of the buffer)
-*/
-
-/***************************************************************************/
-/* for reading the content of the current zipfile, you can open it, read data
- from it, and close it (you can close it before reading all the file)
- */
-
-extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
-/*
- Open for reading data the current file in the zipfile.
- If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
-/*
- Close the file in zip opened with unzOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-
-
-extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read bytes from the current file (opened by unzOpenCurrentFile)
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-
-extern z_off_t ZEXPORT unztell OF((unzFile file));
-/*
- Give the current position in uncompressed data
-*/
-
-extern int ZEXPORT unzeof OF((unzFile file));
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-
-extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-
-class ZipArchive : Common::Archive {
- unzFile _zipFile;
+class ZipArchive : public Archive {
+ void *_zipFile;
public:
- ZipArchive(const Common::String &name) {
- _zipFile = unzOpen(name.c_str());
- }
- ~ZipArchive() {
- unzClose(_zipFile);
- }
-
- virtual bool hasFile(const Common::String &name) {
- return (_zipFile && unzLocateFile(_zipFile, name.c_str(), 2) == UNZ_OK);
- }
-
- virtual int getAllNames(Common::StringList &list) {
- // TODO
- return 0;
- }
-
- virtual Common::SeekableReadStream *openFile(const Common::String &name) {
- if (!_zipFile)
- return 0;
+ ZipArchive(const String &name);
+ ~ZipArchive();
- unzLocateFile(_zipFile, name.c_str(), 2);
+ bool isOpen() const;
- unz_file_info fileInfo;
- unzOpenCurrentFile(_zipFile);
- unzGetCurrentFileInfo(_zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
- byte *buffer = (byte *)calloc(fileInfo.uncompressed_size+1, 1);
- assert(buffer);
- unzReadCurrentFile(_zipFile, buffer, fileInfo.uncompressed_size);
- unzCloseCurrentFile(_zipFile);
- return new Common::MemoryReadStream(buffer, fileInfo.uncompressed_size+1, true);
-
- // FIXME: instead of reading all into a memory stream, we could
- // instead create a new ZipStream class. But then we have to be
- // careful to handle the case where the client code opens multiple
- // files in the archive and tries to use them indepenendtly.
- }
+ virtual bool hasFile(const String &name);
+ virtual int getAllNames(StringList &list);
+ virtual Common::SeekableReadStream *openFile(const Common::String &name);
};
+} // End of namespace Common
+
#endif // USE_ZLIB
#endif /* _unz_H */
diff --git a/common/util.h b/common/util.h
index 32f07181c4..573004c437 100644
--- a/common/util.h
+++ b/common/util.h
@@ -106,20 +106,20 @@ public:
/**
* Generates a random unsigned integer in the interval [0, max].
* @param max the upper bound
- * @return a random number in the interval [0, max].
+ * @return a random number in the interval [0, max]
*/
uint getRandomNumber(uint max);
/**
- * Generates a random unsigned integer in the interval [0, 1].
+ * Generates a random bit, i.e. either 0 or 1.
* Identical to getRandomNumber(1), but faster, hopefully.
- * @return a random number in the interval [0, max].
+ * @return a random bit, either 0 or 1
*/
uint getRandomBit(void);
/**
* Generates a random unsigned integer in the interval [min, max].
* @param min the lower bound
* @param max the upper bound
- * @return a random number in the interval [min, max].
+ * @return a random number in the interval [min, max]
*/
uint getRandomNumberRng(uint min, uint max);
};
diff --git a/common/xmlparser.h b/common/xmlparser.h
index 967b73535b..4b76278d47 100644
--- a/common/xmlparser.h
+++ b/common/xmlparser.h
@@ -217,9 +217,9 @@ public:
return true;
}
- bool loadStream(MemoryReadStream *stream) {
+ bool loadStream(Common::SeekableReadStream *stream) {
_stream = stream;
- _fileName = "Compressed File Stream";
+ _fileName = "File Stream";
return true;
}
diff --git a/engines/agi/predictive.cpp b/engines/agi/predictive.cpp
index 21f9256e70..09472235ad 100644
--- a/engines/agi/predictive.cpp
+++ b/engines/agi/predictive.cpp
@@ -491,7 +491,8 @@ void AgiEngine::loadDict(void) {
ConfMan.registerDefault("predictive_dictionary", "pred.dic");
uint32 time1 = _system->getMillis();
- if (!inFile.open(ConfMan.get("predictive_dictionary")))
+ Common::String inFileName(ConfMan.get("predictive_dictionary"));
+ if (!inFile.open(inFileName))
return;
char *ptr;
@@ -505,7 +506,7 @@ void AgiEngine::loadDict(void) {
inFile.read(_predictiveDictText, size);
_predictiveDictText[size] = 0;
uint32 time2 = _system->getMillis();
- debug("Time to read %s: %d bytes, %d ms", inFile.name(), size, time2-time1);
+ debug("Time to read %s: %d bytes, %d ms", inFileName.c_str(), size, time2-time1);
inFile.close();
ptr = _predictiveDictText;
diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp
index 5d16c6e68a..7064f81a90 100644
--- a/engines/cruise/cruise_main.cpp
+++ b/engines/cruise/cruise_main.cpp
@@ -243,7 +243,7 @@ ovlData3Struct *scriptFunc1Sub2(int32 scriptNumber, int32 param) {
return NULL;
}
- return ((ovlData3Struct *) (ovlData->ptr1 + param * 0x1C));
+ return &ovlData->ptr1[param];
}
void scriptFunc2(int scriptNumber, scriptInstanceStruct * scriptHandle,
diff --git a/engines/cruise/ctp.cpp b/engines/cruise/ctp.cpp
index 6c7be713ef..b45b6dc866 100644
--- a/engines/cruise/ctp.cpp
+++ b/engines/cruise/ctp.cpp
@@ -153,8 +153,8 @@ void makeCtStruct(uint8* str, int16 table[][40], int num, int z) {
int16* a2;
a1 = a2 = (int16*)str;
- a2 += 4+sizeof(int16*); // skip header
-
+ a2 += sizeof(int16*) / sizeof(int16) + 6; // skip header
+
int16* XArray = XMIN_XMAX;
int minY = *XArray++;
@@ -178,8 +178,8 @@ void makeCtStruct(uint8* str, int16 table[][40], int num, int z) {
adrStructPoly = (uint8*)a2;
- *(uint16**)a2 = (uint16*)-1;
-
+ *(uint16**)a2 = (uint16*)-1; //chained list terminator
+
a1+=sizeof(int16*);
*a1++=num;
*a1++=walkboxColor[num];
@@ -339,20 +339,20 @@ int initCt(const char *ctpName) {
makeCtStruct(adrStructPoly, ctp_walkboxTable, i, 0 );
}
- polyStructExp = adrStructPoly += 4;
+ polyStructExp = adrStructPoly += sizeof(int16 *);
for(int i= numberOfWalkboxes-1; i >=0; i--) {
makeCtStruct(adrStructPoly, ctp_walkboxTable, i, walkboxZoom[i] * 20 );
}
- int ctSize = (adrStructPoly - ptr) + 4; // for now, the +4 is a safe zone
+ int ctSize = (adrStructPoly - ptr) + sizeof(int16 *); // for now, the +sizeof(int16 *) is a safe zone
adrStructPoly = polyStructNorm = polyStruct = (uint8 *) malloc(ctSize);
for(int i= numberOfWalkboxes-1; i >=0; i--) {
makeCtStruct(adrStructPoly, ctp_walkboxTable, i, 0);
}
- polyStructExp = adrStructPoly += 4;
+ polyStructExp = adrStructPoly += sizeof(int16 *);
for(int i= numberOfWalkboxes-1; i >=0; i--) {
makeCtStruct(adrStructPoly, ctp_walkboxTable, i, walkboxZoom[i] * 20);
diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp
index 7ce69448a6..c274291142 100644
--- a/engines/cruise/dataLoader.cpp
+++ b/engines/cruise/dataLoader.cpp
@@ -24,6 +24,7 @@
*/
#include "cruise/cruise_main.h"
+#include "common/endian.h"
namespace Cruise {
@@ -412,7 +413,6 @@ int loadFNTSub(uint8 *ptr, int destIdx) {
}
int loadSetEntry(const char *name, uint8 *ptr, int currentEntryIdx, int currentDestEntry) {
- uint8 *ptr2;
uint8 *ptr3;
int offset;
int sec = 0;
@@ -422,28 +422,27 @@ int loadSetEntry(const char *name, uint8 *ptr, int currentEntryIdx, int currentD
sec = 1;
}
- ptr2 = ptr + 4;
-
- memcpy(&numIdx, ptr2, 2);
- flipShort(&numIdx);
+ numIdx = READ_BE_UINT16(ptr + 4);
ptr3 = ptr + 6;
offset = currentEntryIdx * 16;
{
- uint8 *ptr4;
int resourceSize;
int fileIndex;
setHeaderEntry localBuffer;
uint8 *ptr5;
- ptr4 = ptr + offset + 6;
-
- memcpy(&localBuffer, ptr4, sizeof(setHeaderEntry));
+ Common::MemoryReadStream s4(ptr + offset + 6, 16);
- flipLong((int32 *) & localBuffer.field_0);
- flipGen(&localBuffer.width, 12);
+ localBuffer.field_0 = s4.readUint32BE();
+ localBuffer.width = s4.readUint16BE();
+ localBuffer.height = s4.readUint16BE();
+ localBuffer.type = s4.readUint16BE();
+ localBuffer.transparency = s4.readUint16BE();
+ localBuffer.field_C = s4.readUint16BE();
+ localBuffer.field_E = s4.readUint16BE();
if (sec == 1) {
localBuffer.width = localBuffer.width - (localBuffer.type * 2); // Type 1: Width - (1*2) , Type 5: Width - (5*2)
diff --git a/engines/cruise/overlay.cpp b/engines/cruise/overlay.cpp
index d3cb93c37c..4d476ceaf1 100644
--- a/engines/cruise/overlay.cpp
+++ b/engines/cruise/overlay.cpp
@@ -23,6 +23,8 @@
*
*/
+#include "common/stream.h"
+
#include "cruise/cruise_main.h"
namespace Cruise {
@@ -50,8 +52,7 @@ int loadOverlay(const char *scriptName) {
char fileName[50];
int fileIdx;
int unpackedSize;
- char *unpackedBuffer;
- char *scriptPtr;
+ byte *unpackedBuffer;
ovlDataStruct *ovlData;
printf("Load overlay: %s\n", scriptName);
@@ -105,7 +106,7 @@ int loadOverlay(const char *scriptName) {
unpackedSize = volumePtrToFileDescriptor[fileIdx].extSize + 2;
// TODO: here, can unpack in gfx module buffer
- unpackedBuffer = (char *)mallocAndZero(unpackedSize);
+ unpackedBuffer = (byte *)mallocAndZero(unpackedSize);
if (!unpackedBuffer) {
return (-2);
@@ -127,12 +128,13 @@ int loadOverlay(const char *scriptName) {
printf("OVL loading done...\n");
- scriptPtr = unpackedBuffer;
+ Common::MemoryReadStream s(unpackedBuffer, unpackedSize);
ovlData = overlayTable[scriptIdx].ovlData;
- memcpy(ovlData, scriptPtr, sizeof(ovlDataStruct));
-
+ // Skip pointers
+ s.skip(60);
+
ovlData->arrayProc = NULL;
ovlData->ptr1 = NULL;
ovlData->arrayObject = NULL;
@@ -148,24 +150,22 @@ int loadOverlay(const char *scriptName) {
ovlData->arrayNameSymbGlob = NULL;
ovlData->data4Ptr = NULL;
ovlData->ptr8 = NULL;
- ovlData->numProc = readB16(scriptPtr + 60);
- ovlData->numRel = readB16(scriptPtr + 62);
- ovlData->numSymbGlob = readB16(scriptPtr + 64);
- ovlData->numRelocGlob = readB16(scriptPtr + 66);
- ovlData->numMsgRelHeader = readB16(scriptPtr + 68);
- ovlData->numObj = readB16(scriptPtr + 70);
- ovlData->numStrings = readB16(scriptPtr + 72);
- ovlData->size8 = readB16(scriptPtr + 74);
- ovlData->size9 = readB16(scriptPtr + 76);
- ovlData->nameExportSize = readB16(scriptPtr + 78);
- ovlData->exportNamesSize = readB16(scriptPtr + 80);
- ovlData->specialString2Length = readB16(scriptPtr + 82);
- ovlData->sizeOfData4 = readB16(scriptPtr + 84);
- ovlData->size12 = readB16(scriptPtr + 86);
- ovlData->specialString1Length = readB16(scriptPtr + 88);
- ovlData->scriptNumber = readB16(scriptPtr + 90);
-
- scriptPtr += 92;
+ ovlData->numProc = s.readUint16BE();
+ ovlData->numRel = s.readUint16BE();
+ ovlData->numSymbGlob = s.readUint16BE();
+ ovlData->numRelocGlob = s.readUint16BE();
+ ovlData->numMsgRelHeader = s.readUint16BE();
+ ovlData->numObj = s.readUint16BE();
+ ovlData->numStrings = s.readUint16BE();
+ ovlData->size8 = s.readUint16BE();
+ ovlData->size9 = s.readUint16BE();
+ ovlData->nameExportSize = s.readUint16BE();
+ ovlData->exportNamesSize = s.readUint16BE();
+ ovlData->specialString2Length = s.readUint16BE();
+ ovlData->sizeOfData4 = s.readUint16BE();
+ ovlData->size12 = s.readUint16BE();
+ ovlData->specialString1Length = s.readUint16BE();
+ ovlData->scriptNumber = s.readUint16BE();
if (ovlData->numSymbGlob) { // export data
int i;
@@ -177,13 +177,11 @@ int loadOverlay(const char *scriptName) {
}
for (i = 0; i < ovlData->numSymbGlob; i++) {
- ovlData->arraySymbGlob[i].var0 = readB16(scriptPtr);
- ovlData->arraySymbGlob[i].var2 = readB16(scriptPtr + 2);
- ovlData->arraySymbGlob[i].var4 = readB16(scriptPtr + 4);
- ovlData->arraySymbGlob[i].idx = readB16(scriptPtr + 6);
- ovlData->arraySymbGlob[i].offsetToName = readB16(scriptPtr + 8);
-
- scriptPtr += 10;
+ ovlData->arraySymbGlob[i].var0 = s.readUint16BE();
+ ovlData->arraySymbGlob[i].var2 = s.readUint16BE();
+ ovlData->arraySymbGlob[i].var4 = s.readUint16BE();
+ ovlData->arraySymbGlob[i].idx = s.readUint16BE();
+ ovlData->arraySymbGlob[i].offsetToName = s.readUint16BE();
}
}
@@ -194,8 +192,7 @@ int loadOverlay(const char *scriptName) {
return (-2);
}
- memcpy(ovlData->arrayNameSymbGlob, scriptPtr, ovlData->exportNamesSize);
- scriptPtr += ovlData->exportNamesSize;
+ s.read(ovlData->arrayNameSymbGlob, ovlData->exportNamesSize);
}
if (ovlData->numRelocGlob) { // import data
@@ -210,13 +207,11 @@ int loadOverlay(const char *scriptName) {
}
for (i = 0; i < ovlData->numRelocGlob; i++) {
- ovlData->arrayRelocGlob[i].var0 = readB16(scriptPtr);
- ovlData->arrayRelocGlob[i].var1 = readB16(scriptPtr + 2);
- ovlData->arrayRelocGlob[i].linkType = readB16(scriptPtr + 4);
- ovlData->arrayRelocGlob[i].linkIdx = readB16(scriptPtr + 6);
- ovlData->arrayRelocGlob[i].nameOffset = readB16(scriptPtr + 8);
-
- scriptPtr += 10;
+ ovlData->arrayRelocGlob[i].var0 = s.readUint16BE();
+ ovlData->arrayRelocGlob[i].var1 = s.readUint16BE();
+ ovlData->arrayRelocGlob[i].linkType = s.readUint16BE();
+ ovlData->arrayRelocGlob[i].linkIdx = s.readUint16BE();
+ ovlData->arrayRelocGlob[i].nameOffset = s.readUint16BE();
}
}
@@ -226,13 +221,12 @@ int loadOverlay(const char *scriptName) {
if (!ovlData->arrayNameRelocGlob) {
return (-2);
}
-
- memcpy(ovlData->arrayNameRelocGlob, scriptPtr,
- ovlData->nameExportSize);
- scriptPtr += ovlData->nameExportSize;
+
+ s.read(ovlData->arrayNameRelocGlob, ovlData->nameExportSize);
}
if (ovlData->numMsgRelHeader) { // link data
+ int i;
ASSERT(sizeof(linkDataStruct) == 0x22);
ovlData->arrayMsgRelHeader = (linkDataStruct *) mallocAndZero(ovlData->numMsgRelHeader * sizeof(linkDataStruct));
@@ -241,9 +235,30 @@ int loadOverlay(const char *scriptName) {
return (-2);
}
- memcpy(ovlData->arrayMsgRelHeader, scriptPtr, ovlData->numMsgRelHeader * sizeof(linkDataStruct));
- scriptPtr += ovlData->numMsgRelHeader * sizeof(linkDataStruct);
- flipGen(ovlData->arrayMsgRelHeader, ovlData->numMsgRelHeader * sizeof(linkDataStruct));
+ for (i = 0; i < ovlData->numMsgRelHeader; i++) {
+ ovlData->arrayMsgRelHeader[i].type = s.readUint16BE();
+ ovlData->arrayMsgRelHeader[i].id = s.readUint16BE();
+ ovlData->arrayMsgRelHeader[i].offsetVerbeName = s.readUint16BE();
+ ovlData->arrayMsgRelHeader[i].verbOverlay = s.readUint16BE();
+ ovlData->arrayMsgRelHeader[i].verbNumber = s.readUint16BE();
+
+ ovlData->arrayMsgRelHeader[i].obj1Overlay = s.readUint16BE();
+ ovlData->arrayMsgRelHeader[i].obj1Number = s.readUint16BE();
+ ovlData->arrayMsgRelHeader[i].obj2Overlay = s.readUint16BE();
+ ovlData->arrayMsgRelHeader[i].obj2Number = s.readUint16BE();
+
+ ovlData->arrayMsgRelHeader[i].trackX = s.readUint16BE();
+ ovlData->arrayMsgRelHeader[i].trackY = s.readUint16BE();
+
+ ovlData->arrayMsgRelHeader[i].obj1NewState = s.readUint16BE();
+ ovlData->arrayMsgRelHeader[i].obj2NewState = s.readUint16BE();
+
+ ovlData->arrayMsgRelHeader[i].obj1OldState = s.readUint16BE();
+ ovlData->arrayMsgRelHeader[i].obj2OldState = s.readUint16BE();
+
+ ovlData->arrayMsgRelHeader[i].trackDirection = s.readUint16BE();
+ ovlData->arrayMsgRelHeader[i].dialog = s.readUint16BE();
+ }
}
if (ovlData->numProc) { // script
@@ -251,53 +266,47 @@ int loadOverlay(const char *scriptName) {
int i;
ovlData->arrayProc =
- (ovlData3Struct *) mallocAndZero(ovlData->numProc *
- sizeof(ovlData3Struct));
+ (ovlData3Struct *) mallocAndZero(ovlData->numProc * sizeof(ovlData3Struct));
if (!ovlData->arrayProc) {
-/* releaseScript(scriptIdx,scriptName);
-
- if (freeIsNeeded) {
- freePtr(unpackedBuffer);
- } */
-
return (-2);
}
- memcpy(ovlData->arrayProc, scriptPtr,
- ovlData->numProc * sizeof(ovlData3Struct));
- scriptPtr += ovlData->numProc * 0x1C;
-
- flipGen(ovlData->arrayProc,
- ovlData->numProc * sizeof(ovlData3Struct));
+ for (i = 0; i < ovlData->numProc; i++) {
+ s.skip(4);
+ ovlData->arrayProc[i].dataPtr = NULL;
+ ovlData->arrayProc[i].sizeOfData = s.readUint16BE();
+ ovlData->arrayProc[i].offsetToSubData3 = s.readUint16BE();
+ ovlData->arrayProc[i].offsetToImportData = s.readUint16BE();
+ ovlData->arrayProc[i].offsetToSubData2 = s.readUint16BE();
+ ovlData->arrayProc[i].offsetToImportName = s.readUint16BE();
+ ovlData->arrayProc[i].offsetToSubData5 = s.readUint16BE();
+ ovlData->arrayProc[i].sysKey = s.readUint16BE();
+ ovlData->arrayProc[i].var12 = s.readUint16BE();
+ ovlData->arrayProc[i].numRelocGlob = s.readUint16BE();
+ ovlData->arrayProc[i].subData2Size = s.readUint16BE();
+ ovlData->arrayProc[i].var18 = s.readUint16BE();
+ ovlData->arrayProc[i].var1A = s.readUint16BE();
+ }
tempPtr = ovlData->arrayProc;
for (i = 0; i < ovlData->numProc; i++) {
- uint8 *ptr = tempPtr->dataPtr =
- (uint8 *) mallocAndZero(tempPtr->sizeOfData);
-
- if (!ptr) {
- /* releaseScript(scriptIdx,scriptName);
- *
- * if (freeIsNeeded)
- * {
- * freePtr(unpackedBuffer);
- * } */
+ tempPtr->dataPtr = (uint8 *) mallocAndZero(tempPtr->sizeOfData);
+ if (!tempPtr->dataPtr) {
return (-2);
}
- memcpy(ptr, scriptPtr, tempPtr->sizeOfData);
- scriptPtr += tempPtr->sizeOfData;
+ s.read(tempPtr->dataPtr, tempPtr->sizeOfData);
if (tempPtr->offsetToImportData) {
- flipGen(ptr + tempPtr->offsetToImportData,
+ flipGen(tempPtr->dataPtr + tempPtr->offsetToImportData,
tempPtr->numRelocGlob * 10);
}
if (tempPtr->offsetToSubData2) {
- flipGen(ptr + tempPtr->offsetToImportData,
+ flipGen(tempPtr->dataPtr + tempPtr->offsetToSubData2,
tempPtr->subData2Size * 10);
}
@@ -310,43 +319,47 @@ int loadOverlay(const char *scriptName) {
int i;
ovlData->ptr1 =
- (uint8 *) mallocAndZero(ovlData->numRel * 0x1C);
+ (ovlData3Struct *) mallocAndZero(ovlData->numRel * sizeof(ovlData3Struct));
if (!ovlData->ptr1) {
return (-2);
}
- memcpy(ovlData->ptr1, scriptPtr, ovlData->numRel * 0x1C);
- scriptPtr += ovlData->numRel * 0x1C;
- flipGen(ovlData->ptr1, ovlData->numRel * 0x1C);
-
+ for (i = 0; i < ovlData->numRel; i++) {
+ s.skip(4);
+ ovlData->ptr1[i].dataPtr = NULL;
+ ovlData->ptr1[i].sizeOfData = s.readUint16BE();
+ ovlData->ptr1[i].offsetToSubData3 = s.readUint16BE();
+ ovlData->ptr1[i].offsetToImportData = s.readUint16BE();
+ ovlData->ptr1[i].offsetToSubData2 = s.readUint16BE();
+ ovlData->ptr1[i].offsetToImportName = s.readUint16BE();
+ ovlData->ptr1[i].offsetToSubData5 = s.readUint16BE();
+ ovlData->ptr1[i].sysKey = s.readUint16BE();
+ ovlData->ptr1[i].var12 = s.readUint16BE();
+ ovlData->ptr1[i].numRelocGlob = s.readUint16BE();
+ ovlData->ptr1[i].subData2Size = s.readUint16BE();
+ ovlData->ptr1[i].var18 = s.readUint16BE();
+ ovlData->ptr1[i].var1A = s.readUint16BE();
+ }
+
tempPtr = (ovlData3Struct *) ovlData->ptr1;
for (i = 0; i < ovlData->numRel; i++) {
- uint8 *ptr = tempPtr->dataPtr =
- (uint8 *) mallocAndZero(tempPtr->sizeOfData);
-
- if (!ptr) {
- /* releaseScript(scriptIdx,scriptName);
- *
- * if (freeIsNeeded)
- * {
- * freePtr(unpackedBuffer);
- * } */
+ tempPtr->dataPtr = (uint8 *) mallocAndZero(tempPtr->sizeOfData);
+ if (!tempPtr->dataPtr) {
return (-2);
}
- memcpy(ptr, scriptPtr, tempPtr->sizeOfData);
- scriptPtr += tempPtr->sizeOfData;
+ s.read(tempPtr->dataPtr, tempPtr->sizeOfData);
if (tempPtr->offsetToImportData) {
- flipGen(ptr + tempPtr->offsetToImportData,
+ flipGen(tempPtr->dataPtr + tempPtr->offsetToImportData,
tempPtr->numRelocGlob * 10);
}
if (tempPtr->offsetToSubData2) {
- flipGen(ptr + tempPtr->offsetToImportData,
+ flipGen(tempPtr->dataPtr + tempPtr->offsetToSubData2,
tempPtr->subData2Size * 10);
}
@@ -367,8 +380,7 @@ int loadOverlay(const char *scriptName) {
return (-2);
}
- memcpy(ovlData->ptr8, scriptPtr, ovlData->size12);
- scriptPtr += ovlData->size12;
+ s.read(ovlData->ptr8, ovlData->size12);
}
if (ovlData->numObj) {
@@ -378,47 +390,20 @@ int loadOverlay(const char *scriptName) {
sizeof(objDataStruct));
if (!ovlData->arrayObject) {
-/* releaseScript(scriptIdx,scriptName);
-
- if (freeIsNeeded) {
- freePtr(unpackedBuffer);
- } */
-
return (-2);
}
for (i = 0; i < ovlData->numObj; i++) {
- ovlData->arrayObject[i]._type = *(int16 *) scriptPtr;
- scriptPtr += 2;
- flipShort(&ovlData->arrayObject[i]._type);
-
- int16 tempClass = *(int16 *) scriptPtr;
- flipShort(&tempClass);
- ovlData->arrayObject[i]._class = (eClass)tempClass;
- scriptPtr += 2;
-
- ovlData->arrayObject[i]._nameOffset = *(int16 *) scriptPtr;
- scriptPtr += 2;
- flipShort(&ovlData->arrayObject[i]._nameOffset);
-
- ovlData->arrayObject[i]._numStates = *(int16 *) scriptPtr;
- scriptPtr += 2;
- flipShort(&ovlData->arrayObject[i]._numStates);
-
- ovlData->arrayObject[i]._varTableIdx = *(int16 *) scriptPtr;
- scriptPtr += 2;
- flipShort(&ovlData->arrayObject[i]._varTableIdx);
-
- ovlData->arrayObject[i]._firstStateIdx = *(int16 *) scriptPtr;
- scriptPtr += 2;
- flipShort(&ovlData->arrayObject[i]._firstStateIdx);
-
- ovlData->arrayObject[i]._stateTableIdx = *(int16 *) scriptPtr;
- scriptPtr += 2;
- flipShort(&ovlData->arrayObject[i]._stateTableIdx);
+ ovlData->arrayObject[i]._type = s.readUint16BE();
+ ovlData->arrayObject[i]._class = (eClass) s.readUint16BE();
+ ovlData->arrayObject[i]._nameOffset = s.readUint16BE();
+ ovlData->arrayObject[i]._numStates = s.readUint16BE();
+ ovlData->arrayObject[i]._varTableIdx = s.readUint16BE();
+ ovlData->arrayObject[i]._firstStateIdx = s.readUint16BE();
+ ovlData->arrayObject[i]._stateTableIdx = s.readUint16BE();
}
- // allocte states for object with multiple states
+ // allocate states for object with multiple states
if (scriptNotLoadedBefore) {
overlayTable[scriptIdx].state = stateID;
@@ -430,38 +415,30 @@ int loadOverlay(const char *scriptName) {
ovlData->arrayObjVar =
(objectParams *) mallocAndZero(ovlData->size9 *
sizeof(objectParams));
- memset(ovlData->arrayObjVar, 0,
- ovlData->size9 * sizeof(objectParams));
if (!ovlData->arrayObjVar) {
-/* releaseScript(scriptIdx,scriptName);
-
- if (freeIsNeeded) {
- freePtr(unpackedBuffer);
- } */
-
return (-2);
}
}
if (ovlData->size8) {
+ int i;
ovlData->arrayStates =
(objectParams *) mallocAndZero(ovlData->size8 *
sizeof(objectParams));
if (!ovlData->arrayStates) {
-/* releaseScript(scriptIdx,scriptName);
-
- if (freeIsNeeded) {
- freePtr(unpackedBuffer);
- } */
-
return (-2);
}
- memcpy(ovlData->arrayStates, scriptPtr, ovlData->size8 * 12); // TODO: made read item by item
- scriptPtr += ovlData->size8 * 12;
- flipGen(ovlData->arrayStates, ovlData->size8 * 12);
+ for (i = 0; i < ovlData->size8; i++) {
+ ovlData->arrayStates[i].X = s.readUint16BE();
+ ovlData->arrayStates[i].Y = s.readUint16BE();
+ ovlData->arrayStates[i].Z = s.readUint16BE();
+ ovlData->arrayStates[i].frame = s.readUint16BE();
+ ovlData->arrayStates[i].scale = s.readUint16BE();
+ ovlData->arrayStates[i].state = s.readUint16BE();
+ }
}
if (ovlData->numStrings) {
@@ -472,23 +449,15 @@ int loadOverlay(const char *scriptName) {
sizeof(stringEntryStruct));
for (i = 0; i < ovlData->numStrings; i++) {
- ovlData->stringTable[i].idx = *(int16 *) scriptPtr;
- flipShort(&ovlData->stringTable[i].idx);
- scriptPtr += 2;
+ ovlData->stringTable[i].idx = s.readUint16BE();
}
}
-/* if (freeIsNeeded) {
- freePtr(unpackedBuffer);
- } */
-
if (ovlData->sizeOfData4) {
ovlData->data4Ptr =
(uint8 *) mallocAndZero(ovlData->sizeOfData4);
- memset(ovlData->data4Ptr, 0, ovlData->sizeOfData4);
if (!ovlData->data4Ptr) {
- //releaseScript(scriptIdx,scriptName);
return (-2);
}
}
@@ -516,7 +485,7 @@ int loadOverlay(const char *scriptName) {
unpackedSize = volumePtrToFileDescriptor[fileIdx].extSize + 2;
// TODO: here, can unpack in gfx module buffer
- unpackedBuffer = (char *)mallocAndZero(unpackedSize);
+ unpackedBuffer = (byte *)mallocAndZero(unpackedSize);
if (!unpackedBuffer) {
return (-2);
@@ -538,12 +507,9 @@ int loadOverlay(const char *scriptName) {
loadPakedFileToMem(fileIdx, (uint8 *) unpackedBuffer);
}
- scriptPtr = unpackedBuffer;
-
- memcpy(&ovlData->specialString1Length, scriptPtr, 2);
- scriptPtr += 2;
- flipShort(&ovlData->specialString1Length); // recheck if needed
+ Common::MemoryReadStream s2(unpackedBuffer, unpackedSize);
+ ovlData->specialString1Length = s2.readUint16BE();
if (ovlData->specialString1Length) {
ovlData->nameVerbGlob = (char *) mallocAndZero(ovlData->specialString1Length);
@@ -558,15 +524,10 @@ int loadOverlay(const char *scriptName) {
return (-2);
}
- memcpy(ovlData->nameVerbGlob, scriptPtr,
- ovlData->specialString1Length);
- scriptPtr += ovlData->specialString1Length;
+ s2.read(ovlData->nameVerbGlob, ovlData->specialString1Length);
}
- memcpy(&ovlData->specialString2Length, scriptPtr, 2);
- scriptPtr += 2;
- flipShort(&ovlData->specialString2Length); // recheck if needed
-
+ ovlData->specialString2Length = s2.readUint16BE();
if (ovlData->specialString2Length) {
ovlData->arrayNameObj = (char *) mallocAndZero(ovlData->specialString2Length);
@@ -581,15 +542,11 @@ int loadOverlay(const char *scriptName) {
return (-2);
}
- memcpy(ovlData->arrayNameObj, scriptPtr,
- ovlData->specialString2Length);
- scriptPtr += ovlData->specialString2Length;
+ s2.read(ovlData->arrayNameObj, ovlData->specialString2Length);
}
for (i = 0; i < ovlData->numStrings; i++) {
- ovlData->stringTable[i].length = *(int16 *) scriptPtr;
- scriptPtr += 2;
- flipShort(&ovlData->stringTable[i].length);
+ ovlData->stringTable[i].length = s2.readUint16BE();
if (ovlData->stringTable[i].length) {
ovlData->stringTable[i].string =
@@ -607,8 +564,7 @@ int loadOverlay(const char *scriptName) {
return (-2);
}
- memcpy(ovlData->stringTable[i].string, scriptPtr, ovlData->stringTable[i].length);
- scriptPtr += ovlData->stringTable[i].length;
+ s2.read(ovlData->stringTable[i].string, ovlData->stringTable[i].length);
}
}
}
diff --git a/engines/cruise/overlay.h b/engines/cruise/overlay.h
index 7d8b2051e1..7ba90a1449 100644
--- a/engines/cruise/overlay.h
+++ b/engines/cruise/overlay.h
@@ -129,7 +129,7 @@ struct objectParams {
struct ovlDataStruct {
ovlData3Struct *arrayProc;
- uint8 *ptr1;
+ ovlData3Struct *ptr1;
objDataStruct *arrayObject;
objectParams *arrayStates;
objectParams *arrayObjVar;
diff --git a/engines/cruise/saveload.cpp b/engines/cruise/saveload.cpp
index 63edf7cb36..3d8321e420 100644
--- a/engines/cruise/saveload.cpp
+++ b/engines/cruise/saveload.cpp
@@ -465,8 +465,7 @@ void saveCT(Common::OutSaveFile& currentSaveFile) {
void loadSavegameDataSub6(Common::InSaveFile& currentSaveFile) {
int32 var;
- var = currentSaveFile.readUint32LE();
- flipLong(&var);
+ var = currentSaveFile.readUint32BE();
if (var) {
int i;
diff --git a/engines/cruise/vars.h b/engines/cruise/vars.h
index 5f65446cc5..692d1baeb6 100644
--- a/engines/cruise/vars.h
+++ b/engines/cruise/vars.h
@@ -91,8 +91,7 @@ struct dataFileName {
};
struct setHeaderEntry {
- int16 field_0; // offset ptr part 1
- int16 field_2; // offset ptr part 2
+ int32 field_0; // offset ptr
int16 width;
int16 height;
int16 type; // resource type, ie. sprites 0,1,4,5 and 8
diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
index c1449ea2c9..fce4fa73c6 100644
--- a/engines/drascula/drascula.cpp
+++ b/engines/drascula/drascula.cpp
@@ -55,7 +55,7 @@ static const GameSettings drasculaSettings[] = {
DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
// Setup mixer
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
_rnd = new Common::RandomSource();
@@ -220,7 +220,7 @@ int DrasculaEngine::go() {
allocMemory();
- withVoices = 0;
+ _subtitlesDisabled = !ConfMan.getBool("subtitles");
selectionMade = 0;
if (currentChapter != 3)
@@ -560,12 +560,16 @@ bool DrasculaEngine::runCurrentChapter() {
} else if (key == Common::KEYCODE_F8) {
selectVerb(0);
} else if (key == Common::KEYCODE_v) {
- withVoices = 1;
+ _subtitlesDisabled = true;
+ ConfMan.setBool("subtitles", !_subtitlesDisabled);
+
print_abc(_textsys[2], 96, 86);
updateScreen();
delay(1410);
} else if (key == Common::KEYCODE_t) {
- withVoices = 0;
+ _subtitlesDisabled = false;
+ ConfMan.setBool("subtitles", !_subtitlesDisabled);
+
print_abc(_textsys[3], 94, 86);
updateScreen();
delay(1460);
diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h
index 3b499f27a0..4a00d35d10 100644
--- a/engines/drascula/drascula.h
+++ b/engines/drascula/drascula.h
@@ -380,7 +380,7 @@ public:
int _destX[40], _destY[40], trackCharacter_alkeva[40], roomExits[40];
int x1[40], y1[40], x2[40], y2[40];
int takeObject, pickedObject;
- int withVoices;
+ bool _subtitlesDisabled;
int menuBar, menuScreen, hasName;
char textName[20];
int curExcuseLook;
diff --git a/engines/drascula/sound.cpp b/engines/drascula/sound.cpp
index 6a3d83cae6..51517280ba 100644
--- a/engines/drascula/sound.cpp
+++ b/engines/drascula/sound.cpp
@@ -26,6 +26,7 @@
#include "sound/mixer.h"
#include "sound/voc.h"
#include "sound/audiocd.h"
+#include "common/config-manager.h"
#include "drascula/drascula.h"
@@ -52,7 +53,7 @@ void DrasculaEngine::volumeControls() {
for (;;) {
int masterVolume = CLIP((_mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType) / 16), 0, 15);
- int voiceVolume = CLIP((_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 16), 0, 15);
+ int voiceVolume = CLIP((_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 16), 0, 15);
int musicVolume = CLIP((_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 16), 0, 15);
int masterVolumeY = 72 + 61 - masterVolume * 4;
@@ -82,7 +83,7 @@ void DrasculaEngine::volumeControls() {
}
if (mouseX > 136 && mouseX < 178) {
- updateVolume(Audio::Mixer::kSFXSoundType, voiceVolumeY);
+ updateVolume(Audio::Mixer::kSpeechSoundType, voiceVolumeY);
}
if (mouseX > 192 && mouseX < 233) {
@@ -173,7 +174,11 @@ void DrasculaEngine::playFile(const char *fname) {
_arj.read(soundData, soundSize);
_arj.close();
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, &_soundHandle, soundData, soundSize - 64,
+ _subtitlesDisabled = !ConfMan.getBool("subtitles");
+ if (ConfMan.getBool("speech_mute"))
+ memset(soundData, 0x80, soundSize); // Mute speech but keep the pause
+
+ _mixer->playRaw(Audio::Mixer::kSpeechSoundType, &_soundHandle, soundData, soundSize - 64,
11025, Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED);
} else
warning("playFile: Could not open %s", fname);
diff --git a/engines/drascula/talk.cpp b/engines/drascula/talk.cpp
index 7bf55b7c40..4ecc3e20f2 100644
--- a/engines/drascula/talk.cpp
+++ b/engines/drascula/talk.cpp
@@ -82,7 +82,7 @@ void DrasculaEngine::talk_igor(int index, int talkerType) {
copyBackground(igorX + 17, igorY, igorX + 17, igorY, 37, 24, bgSurface, screenSurface);
copyRect(x_talk0[face], 148, igorX + 17, igorY, 25, 24, frontSurface, screenSurface);
updateRefresh();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, igorX + 26, igorY);
updateScreen();
pause(3);
@@ -95,13 +95,13 @@ void DrasculaEngine::talk_igor(int index, int talkerType) {
copyBackground(igorX, igorY, igorX, igorY, 29, 25, bgSurface, screenSurface);
copyRect(x_talk1[face], 173, igorX, igorY, 29, 25, frontSurface, screenSurface);
updateRefresh();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, igorX + 26, igorY);
updateScreen();
pause(3);
} else if (talkerType == kIgorDoor) {
updateRoom();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, 87, 66);
updateScreen();
} else if (talkerType == kIgorSeated || talkerType == kIgorWig) {
@@ -111,7 +111,7 @@ void DrasculaEngine::talk_igor(int index, int talkerType) {
copyBackground(x_talk4[face], 78, 199, 94, 38, 27, drawSurface3, screenSurface);
moveCharacters();
updateRefresh();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, 221, 102);
updateScreen();
@@ -166,7 +166,7 @@ void DrasculaEngine::talk_drascula(int index, int talkerType) {
updateRefresh();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, drasculaX + 19, drasculaY);
updateScreen();
@@ -211,7 +211,7 @@ void DrasculaEngine::talk_drascula_big(int index) {
if (l == 7)
l = 0;
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, 191, 69);
updateScreen();
@@ -237,7 +237,7 @@ void DrasculaEngine::talk_solo(const char *said, const char *filename) {
copyBackground();
do {
- if (withVoices == 0) {
+ if (!_subtitlesDisabled) {
if (currentChapter == 1)
centerText(said, 156, 90);
else if (currentChapter == 6)
@@ -300,7 +300,7 @@ void DrasculaEngine::talk_bartender(int index, int talkerType) {
moveCharacters();
updateRefresh();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, 132, 45);
updateScreen();
@@ -339,7 +339,7 @@ void DrasculaEngine::talk_bj(int index) {
moveCharacters();
updateRefresh();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, bjX + 7, bjY);
updateScreen();
@@ -348,7 +348,7 @@ void DrasculaEngine::talk_bj(int index) {
} else {
updateRoom();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, 93, 80);
updateScreen();
@@ -463,7 +463,7 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
updateRefresh();
}
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, curX, curY);
updateScreen();
@@ -555,7 +555,7 @@ void DrasculaEngine::talk_vonBraun(int index, int talkerType) {
updateRefresh();
}
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, vonBraunX, 66);
updateScreen();
@@ -563,7 +563,7 @@ void DrasculaEngine::talk_vonBraun(int index, int talkerType) {
} else {
updateRoom();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, 150, 80);
updateScreen();
@@ -617,7 +617,7 @@ void DrasculaEngine::talk_blind(int index) {
copyRect(bX, 2, 73, 1, 126, h, frontSurface, screenSurface);
}
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, 260, 71);
updateScreen();
@@ -639,7 +639,7 @@ void DrasculaEngine::talk_hacker(int index) {
talkInit(filename);
do {
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, 156, 170);
updateScreen();
} while (!isTalkFinished());
@@ -700,7 +700,7 @@ void DrasculaEngine::talk_pen(const char *said, const char *filename, int talker
updateRefresh();
- if (withVoices == 0) {
+ if (!_subtitlesDisabled) {
if (talkerType == 0)
centerText(said, 160, 105);
else
@@ -741,7 +741,7 @@ void DrasculaEngine::talk_bj_bed(int index) {
moveCharacters();
updateRefresh();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, 104, 102);
updateScreen();
@@ -777,7 +777,7 @@ void DrasculaEngine::talk_htel(int index) {
else
copyBackground(x_talk[face], 1, 45, 24, 92, 108, backSurface, screenSurface);
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, 90, 50);
updateScreen();
@@ -857,7 +857,7 @@ void DrasculaEngine::talk_sync(const char *said, const char *filename, const cha
updateRefresh();
}
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, curX, curY);
updateScreen();
@@ -890,7 +890,7 @@ void DrasculaEngine::talk_trunk(int index) {
flags[19] = face;
updateRoom();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, 263, 69);
updateScreen();
@@ -917,7 +917,7 @@ void DrasculaEngine::talk_generic(const char* said, const char* filename, int* f
moveCharacters();
updateRefresh();
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText(said, coords[5], coords[6]);
updateScreen();
@@ -938,7 +938,7 @@ void DrasculaEngine::grr() {
updateRoom();
copyBackground(253, 110, 150, 65, 20, 30, drawSurface3, screenSurface);
- if (withVoices == 0)
+ if (!_subtitlesDisabled)
centerText("groaaarrrrgghhhh!", 153, 65);
updateScreen();
diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp
index 2b0c015677..c871bdb976 100644
--- a/engines/gob/detection.cpp
+++ b/engines/gob/detection.cpp
@@ -992,6 +992,19 @@ static const GOBGameDescription gameDescriptions[] = {
kFeaturesAdlib,
"intro"
},
+ { // Supplied by goodoldgeorg in bug report #2105220
+ {
+ "lostintime",
+ "",
+ AD_ENTRY1s("intro.stk", "cd322cb3c64ef2ba2f2134aa2122cfe9", 3936700),
+ ES_ESP,
+ kPlatformPC,
+ Common::ADGF_NO_FLAGS
+ },
+ kGameTypeLostInTime,
+ kFeaturesAdlib,
+ "intro"
+ },
{
{
"lostintime",
diff --git a/engines/made/screen.cpp b/engines/made/screen.cpp
index 0c22d40259..38a4baffc5 100644
--- a/engines/made/screen.cpp
+++ b/engines/made/screen.cpp
@@ -174,13 +174,15 @@ void Screen::drawSurface(Graphics::Surface *sourceSurface, int x, int y, int16 f
if (_vm->getGameID() != GID_RTZ)
maskp = (byte*)_maskDrawCtx.destSurface->getBasePtr(x, y);
- int32 sourcePitch, linePtrAdd;
+ int32 sourcePitch, linePtrAdd, sourceAdd;
byte *linePtr;
if (flipX) {
linePtrAdd = -1;
+ sourceAdd = sourceSurface->w;
} else {
linePtrAdd = 1;
+ sourceAdd = 0;
}
if (flipY) {
@@ -191,11 +193,7 @@ void Screen::drawSurface(Graphics::Surface *sourceSurface, int x, int y, int16 f
}
for (int16 yc = 0; yc < clipHeight; yc++) {
- if (flipX) {
- linePtr = source + sourceSurface->w;
- } else {
- linePtr = source;
- }
+ linePtr = source + sourceAdd;
for (int16 xc = 0; xc < clipWidth; xc++) {
if (*linePtr && (_vm->getGameID() == GID_RTZ || (mask == 0 || maskp[xc] == 0))) {
if (*linePtr)
@@ -688,7 +686,7 @@ void Screen::printText(const char *text) {
for (int textPos = 0; textPos < textLen; textPos++) {
- uint c = ((byte*)text)[textPos];
+ uint c = ((const byte*)text)[textPos];
int charWidth = _font->getCharWidth(c);
if (c == 9) {
@@ -806,7 +804,12 @@ void Screen::showWorkScreen() {
void Screen::updateScreenAndWait(int delay) {
_vm->_system->updateScreen();
- _vm->_system->delayMillis(delay);
+ uint32 startTime = _vm->_system->getMillis();
+ while (_vm->_system->getMillis() < startTime + delay) {
+ _vm->handleEvents();
+ _vm->_system->updateScreen();
+ _vm->_system->delayMillis(5);
+ }
}
int16 Screen::addToSpriteList(int16 index, int16 xofs, int16 yofs) {
diff --git a/engines/made/scriptfuncs.cpp b/engines/made/scriptfuncs.cpp
index d697e24b04..0051b80dae 100644
--- a/engines/made/scriptfuncs.cpp
+++ b/engines/made/scriptfuncs.cpp
@@ -571,7 +571,7 @@ int16 ScriptFunctions::sfGetCdTime(int16 argc, int16 *argv) {
// This one is called loads of times, so it has been commented out to reduce spam
//warning("Unimplemented opcode: sfGetCdTime");
// TODO
- return 0;
+ return 32000;
}
int16 ScriptFunctions::sfPlayCdSegment(int16 argc, int16 *argv) {
diff --git a/engines/parallaction/balloons.cpp b/engines/parallaction/balloons.cpp
index 290aa5e625..70c3d5789e 100644
--- a/engines/parallaction/balloons.cpp
+++ b/engines/parallaction/balloons.cpp
@@ -79,7 +79,7 @@ public:
token = tokenizer.nextToken();
token = expand(token);
- if (token == '/') {
+ if (token == "/") {
tokenWidth = 0;
action();
textNewLine();
diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp
index 9a787d7f00..8093d4f234 100644
--- a/engines/parallaction/saveload.cpp
+++ b/engines/parallaction/saveload.cpp
@@ -266,8 +266,6 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel)
_list->setEditable(true);
_list->setNumberingMode(GUI::kListNumberingOne);
- _container = new GUI::ContainerWidget(this, 0, 0, 10, 10);
-
_gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10);
_date = new GUI::StaticTextWidget(this, 0, 0, 10, 10, "No date saved", GUI::kTextAlignCenter);
@@ -278,6 +276,9 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel)
new GUI::ButtonWidget(this, "ScummSaveLoad.Cancel", "Cancel", GUI::kCloseCmd, 0);
_chooseButton = new GUI::ButtonWidget(this, "ScummSaveLoad.Choose", buttonLabel, kChooseCmd, 0);
_chooseButton->setEnabled(false);
+
+ _container = new GUI::ContainerWidget(this, 0, 0, 10, 10);
+// _container->setHints(GUI::THEME_HINT_USE_SHADOW);
}
SaveLoadChooser::~SaveLoadChooser() {
diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp
index e9e146013f..493c05022c 100644
--- a/engines/saga/animation.cpp
+++ b/engines/saga/animation.cpp
@@ -579,6 +579,9 @@ void Anim::play(uint16 animId, int vectorTime, bool playing) {
_vm->_events->queue(&event);
}
return;
+ } else {
+ anim->currentFrame = 0;
+ anim->completed = 0;
}
}
diff --git a/engines/saga/displayinfo.h b/engines/saga/displayinfo.h
index 3775e904ff..c85b5b830f 100644
--- a/engines/saga/displayinfo.h
+++ b/engines/saga/displayinfo.h
@@ -64,7 +64,7 @@ struct GameDisplayInfo {
int saveReminderWidth;
int saveReminderHeight;
int saveReminderFirstSpriteNumber;
- int saveReminderSecondSpriteNumber;
+ int saveReminderNumSprites;
int leftPortraitXOffset;
int leftPortraitYOffset;
@@ -230,7 +230,8 @@ static const GameDisplayInfo ITE_DisplayInfo = {
15, // status BG color
308,137, // save reminder pos
12,12, // save reminder w & h
- 6,7, // save reminder sprite numbers
+ 6, // save reminder first sprite number
+ 2, // number of save reminder sprites
5, 4, // left portrait x, y offset
274, 4, // right portrait x, y offset
@@ -376,7 +377,8 @@ static const GameDisplayInfo IHNM_DisplayInfo = {
250, // status BG color
616, 304, // save reminder pos
24, 24, // save reminder w&h
- 0,1, // save reminder sprite numbers
+ 0, // save reminder first sprite number
+ 16, // number of save reminder sprites
11, 12, // left portrait x, y offset
-1, -1, // right portrait x, y offset
diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp
index abf8094533..38d126c5d4 100644
--- a/engines/saga/interface.cpp
+++ b/engines/saga/interface.cpp
@@ -358,15 +358,12 @@ void Interface::saveReminderCallback(void *refCon) {
}
void Interface::updateSaveReminder() {
- // TODO: finish this
- /*
if (_active && _panelMode == kPanelMain) {
- _vm->_timer->removeTimerProc(&saveReminderCallback);
- _saveReminderState = (_saveReminderState == 0) ? 1 : 0;
+ _saveReminderState = _saveReminderState % _vm->getDisplayInfo().saveReminderNumSprites + 1;
drawStatusBar();
- _vm->_timer->installTimerProc(&saveReminderCallback, TIMETOSAVE, this);
+ _vm->_timer->removeTimerProc(&saveReminderCallback);
+ _vm->_timer->installTimerProc(&saveReminderCallback, ((_vm->getGameType() == GType_ITE) ? TIMETOBLINK_ITE : TIMETOBLINK_IHNM), this);
}
- */
}
int Interface::activate() {
@@ -423,7 +420,7 @@ void Interface::setMode(int mode) {
if (mode == kPanelMain) {
_inMainMode = true;
- _saveReminderState = 1; //TODO: blinking timeout
+ _saveReminderState = 1;
} else if (mode == kPanelChapterSelection) {
_saveReminderState = 1;
} else if (mode == kPanelNull) {
@@ -1420,6 +1417,10 @@ void Interface::setSave(PanelButton *panelButton) {
fileName = _vm->calcSaveFileName(_vm->getSaveFile(_optionSaveFileTitleNumber)->slotNumber);
_vm->save(fileName, _textInputString);
}
+ _vm->_timer->removeTimerProc(&saveReminderCallback);
+ _vm->_timer->installTimerProc(&saveReminderCallback, TIMETOSAVE, this);
+ setSaveReminderState(1);
+
_textInput = false;
setMode(kPanelOption);
break;
@@ -1925,7 +1926,7 @@ void Interface::drawStatusBar() {
rect.right = rect.left + _vm->getDisplayInfo().saveReminderWidth;
rect.bottom = rect.top + _vm->getDisplayInfo().saveReminderHeight;
_vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _vm->_sprite->_saveReminderSprites,
- _saveReminderState == 1 ? _vm->getDisplayInfo().saveReminderFirstSpriteNumber : _vm->getDisplayInfo().saveReminderSecondSpriteNumber,
+ _vm->getDisplayInfo().saveReminderFirstSpriteNumber + _saveReminderState - 1,
rect, 256);
}
diff --git a/engines/saga/interface.h b/engines/saga/interface.h
index 2091c9f071..46df12ed51 100644
--- a/engines/saga/interface.h
+++ b/engines/saga/interface.h
@@ -59,8 +59,9 @@ enum InterfaceUpdateFlags {
#define RID_IHNM_BOSS_SCREEN 19 // not in demo
#define RID_ITE_TYCHO_MAP 1686
#define RID_ITE_SPR_CROSSHAIR (73 + 9)
-#define TIMETOSAVE (kScriptTimeTicksPerSecond * 1000 * 60 * 30)
-#define TIMETOBLINK (kScriptTimeTicksPerSecond * 1000 * 1)
+#define TIMETOSAVE (1000000 * 60 * 30) // 30 minutes
+#define TIMETOBLINK_ITE (1000000 * 1)
+#define TIMETOBLINK_IHNM (1000000 / 10)
// Converse-specific stuff
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index df6660523a..b2bb8be9c9 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -50,9 +50,11 @@ Actor::Actor(ScummEngine *scumm, int id) :
assert(_vm != 0);
}
-void Actor::initActor(int mode) {
- // begin HE specific
+void ActorHE::initActor(int mode) {
+ Actor::initActor(mode);
+
if (mode == -1) {
+ _heOffsX = _heOffsY = 0;
_heSkipLimbs = false;
memset(_heTalkQueue, 0, sizeof(_heTalkQueue));
}
@@ -70,11 +72,18 @@ void Actor::initActor(int mode) {
_hePaletteNum = 0;
_heFlags = 0;
_heTalking = false;
- // end HE specific
+ if (_vm->_game.heversion >= 61)
+ _flip = 0;
+
+ _clipOverride = _vm->_actorClipOverride;
+
+ _auxBlock.reset();
+}
+
+void Actor::initActor(int mode) {
if (mode == -1) {
- _offsX = _offsY = 0;
_top = _bottom = 0;
_needRedraw = false;
_needBgReset = false;
@@ -132,9 +141,6 @@ void Actor::initActor(int mode) {
_forceClip = (_vm->_game.version >= 7) ? 100 : 0;
_ignoreTurns = false;
- if (_vm->_game.heversion >= 61)
- _flip = 0;
-
_talkFrequency = 256;
_talkPan = 64;
_talkVolume = 127;
@@ -148,10 +154,6 @@ void Actor::initActor(int mode) {
_walkScript = 0;
_talkScript = 0;
- _clipOverride = _vm->_actorClipOverride;
-
- _auxBlock.reset();
-
_vm->_classData[_number] = (_vm->_game.version >= 7) ? _vm->_classData[0] : 0;
}
@@ -879,9 +881,9 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
_vm->stopTalk();
}
- // WORKAROUND: The green transparency of the tank in the Hall of Oddities is
- // is positioned one pixel too far to the left. This appears to be a
- // bug in the original game as well.
+ // WORKAROUND: The green transparency of the tank in the Hall of Oddities
+ // is positioned one pixel too far to the left. This appears to be a bug
+ // in the original game as well.
if (_vm->_game.id == GID_SAMNMAX && newRoom == 16 && _number == 5 && dstX == 235 && dstY == 236)
dstX++;
@@ -904,7 +906,7 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
} else {
#ifdef ENABLE_HE
if (_vm->_game.heversion >= 71)
- ((ScummEngine_v71he *)_vm)->queueAuxBlock(this);
+ ((ScummEngine_v71he *)_vm)->queueAuxBlock((ActorHE *)this);
#endif
hideActor();
}
@@ -1208,6 +1210,10 @@ void Actor::hideActor() {
_cost.soundCounter = 0;
_needRedraw = false;
_needBgReset = true;
+}
+
+void ActorHE::hideActor() {
+ Actor::hideActor();
_auxBlock.reset();
}
@@ -1434,39 +1440,28 @@ void Actor::drawActorCostume(bool hitTestMode) {
}
setupActorScale();
+
+ BaseCostumeRenderer *bcr = _vm->_costumeRenderer;
+ prepareDrawActorCostume(bcr);
- BaseCostumeRenderer* bcr = _vm->_costumeRenderer;
-
- bcr->_actorID = _number;
-
- bcr->_actorX = _pos.x + _offsX;
- bcr->_actorY = _pos.y + _offsY - _elevation;
-
- if (_vm->_game.version <= 2) {
- bcr->_actorX *= V12_X_MULTIPLIER;
- bcr->_actorY *= V12_Y_MULTIPLIER;
+ // If the actor is partially hidden, redraw it next frame.
+ if (bcr->drawCostume(_vm->_virtscr[kMainVirtScreen], _vm->_gdi->_numStrips, this, _drawToBackBuf) & 1) {
+ _needRedraw = (_vm->_game.version <= 6);
}
- bcr->_actorX -= _vm->_virtscr[kMainVirtScreen].xstart;
- if (_vm->_game.platform == Common::kPlatformNES) {
- // In the NES version, when the actor is facing right,
- // we need to shift it 8 pixels to the left
- if (_facing == 90)
- bcr->_actorX -= 8;
- } else if (_vm->_game.version <= 2) {
- // HACK: We have to adjust the x position by one strip (8 pixels) in
- // V2 games. However, it is not quite clear to me why. And to fully
- // match the original, it seems we have to offset by 2 strips if the
- // actor is facing left (270 degree).
- // V1 games are once again slightly different, here we only have
- // to adjust the 270 degree case...
- if (_facing == 270)
- bcr->_actorX += 16;
- else if (_vm->_game.version == 2)
- bcr->_actorX += 8;
+ if (!hitTestMode) {
+ // Record the vertical extent of the drawn actor
+ _top = bcr->_draw_top;
+ _bottom = bcr->_draw_bottom;
}
+}
- bcr->_clipOverride = _clipOverride;
+
+void Actor::prepareDrawActorCostume(BaseCostumeRenderer *bcr) {
+
+ bcr->_actorID = _number;
+ bcr->_actorX = _pos.x - _vm->_virtscr[kMainVirtScreen].xstart;
+ bcr->_actorY = _pos.y - _elevation;
if (_vm->_game.version == 4 && (_boxscale & 0x8000)) {
bcr->_scaleX = bcr->_scaleY = _vm->getScaleFromSlot((_boxscale & 0x7fff) + 1, _pos.x, _pos.y);
@@ -1478,8 +1473,6 @@ void Actor::drawActorCostume(bool hitTestMode) {
bcr->_shadow_mode = _shadowMode;
if (_vm->_game.version >= 5 && _vm->_game.heversion == 0) {
bcr->_shadow_table = _vm->_shadowPalette;
- } else if (_vm->_game.heversion == 70) {
- bcr->_shadow_table = _vm->_HEV7ActorPalette;
}
bcr->setCostume(_costume, _heXmapNum);
@@ -1510,6 +1503,19 @@ void Actor::drawActorCostume(bool hitTestMode) {
bcr->_draw_top = 0x7fffffff;
bcr->_draw_bottom = 0;
+}
+
+void ActorHE::prepareDrawActorCostume(BaseCostumeRenderer *bcr) {
+ Actor::prepareDrawActorCostume(bcr);
+
+ bcr->_actorX += _heOffsX;
+ bcr->_actorY += _heOffsY;
+
+ bcr->_clipOverride = _clipOverride;
+
+ if (_vm->_game.heversion == 70) {
+ bcr->_shadow_table = _vm->_HEV7ActorPalette;
+ }
bcr->_skipLimbs = (_heSkipLimbs != 0);
bcr->_paletteNum = _hePaletteNum;
@@ -1530,16 +1536,36 @@ void Actor::drawActorCostume(bool hitTestMode) {
}
}
_heNoTalkAnimation = 0;
+}
- // If the actor is partially hidden, redraw it next frame.
- if (bcr->drawCostume(_vm->_virtscr[kMainVirtScreen], _vm->_gdi->_numStrips, this, _drawToBackBuf) & 1) {
- _needRedraw = (_vm->_game.version <= 6);
+void Actor_v2::prepareDrawActorCostume(BaseCostumeRenderer *bcr) {
+ Actor::prepareDrawActorCostume(bcr);
+
+ bcr->_actorX = _pos.x;
+ bcr->_actorY = _pos.y - _elevation;
+
+ if (_vm->_game.version <= 2) {
+ bcr->_actorX *= V12_X_MULTIPLIER;
+ bcr->_actorY *= V12_Y_MULTIPLIER;
}
+ bcr->_actorX -= _vm->_virtscr[kMainVirtScreen].xstart;
- if (!hitTestMode) {
- // Record the vertical extent of the drawn actor
- _top = bcr->_draw_top;
- _bottom = bcr->_draw_bottom;
+ if (_vm->_game.platform == Common::kPlatformNES) {
+ // In the NES version, when the actor is facing right,
+ // we need to shift it 8 pixels to the left
+ if (_facing == 90)
+ bcr->_actorX -= 8;
+ } else if (_vm->_game.version <= 2) {
+ // HACK: We have to adjust the x position by one strip (8 pixels) in
+ // V2 games. However, it is not quite clear to me why. And to fully
+ // match the original, it seems we have to offset by 2 strips if the
+ // actor is facing left (270 degree).
+ // V1 games are once again slightly different, here we only have
+ // to adjust the 270 degree case...
+ if (_facing == 270)
+ bcr->_actorX += 16;
+ else if (_vm->_game.version == 2)
+ bcr->_actorX += 8;
}
}
@@ -1611,13 +1637,15 @@ void Actor::startAnimActor(int f) {
if (isInCurrentRoom() && _costume != 0) {
_animProgress = 0;
- _cost.animCounter = 0;
_needRedraw = true;
+ _cost.animCounter = 0;
// V1 - V2 games don't seem to need a _cost.reset() at this point.
// Causes Zak to lose his body in several scenes, see bug #771508
if (_vm->_game.version >= 3 && f == _initFrame) {
_cost.reset();
- _auxBlock.reset();
+ if (_vm->_game.heversion != 0) {
+ ((ActorHE *)this)->_auxBlock.reset();
+ }
}
_vm->_costumeLoader->costumeDecodeData(this, f, (uint) - 1);
_frame = f;
@@ -1758,7 +1786,7 @@ void ScummEngine::resetActorBgs() {
clearGfxUsageBit(strip, USAGE_BIT_DIRTY);
clearGfxUsageBit(strip, USAGE_BIT_RESTORED);
for (j = 1; j < _numActors; j++) {
- if (_actors[j]->_heFlags & 1)
+ if (_game.heversion != 0 && ((ActorHE *)_actors[j])->_heFlags & 1)
continue;
if (testGfxUsageBit(strip, j) &&
@@ -1776,7 +1804,7 @@ void ScummEngine::resetActorBgs() {
}
// HE specific
-void Actor::drawActorToBackBuf(int x, int y) {
+void ActorHE::drawActorToBackBuf(int x, int y) {
int curTop = _top;
int curBottom = _bottom;
@@ -1936,7 +1964,8 @@ void ScummEngine::actorTalk(const byte *msg) {
stopTalk();
}
setTalkingActor(a->_number);
- a->_heTalking = true;
+ if (_game.heversion != 0)
+ ((ActorHE *)a)->_heTalking = true;
if (!_string[0].no_talk_anim) {
a->runActorTalkScript(a->_talkStartFrame);
_useTalkAnims = true;
@@ -2009,7 +2038,8 @@ void ScummEngine::stopTalk() {
}
if (_game.version <= 7 && _game.heversion == 0)
setTalkingActor(0xFF);
- a->_heTalking = false;
+ if (_game.heversion != 0)
+ ((ActorHE *)a)->_heTalking = false;
}
if (_game.id == GID_DIG || _game.id == GID_CMI) {
@@ -2035,9 +2065,7 @@ void ScummEngine::stopTalk() {
#pragma mark -
-void Actor::setActorCostume(int c) {
- int i;
-
+void ActorHE::setActorCostume(int c) {
if (_vm->_game.heversion >= 61 && (c == -1 || c == -2)) {
_heSkipLimbs = (c == -1);
_needRedraw = true;
@@ -2049,27 +2077,43 @@ void Actor::setActorCostume(int c) {
if (_vm->_game.heversion == 61)
c &= 0xff;
- _costumeNeedsInit = true;
-
if (_vm->_game.features & GF_NEW_COSTUMES) {
- memset(_animVariable, 0, sizeof(_animVariable));
-
#ifdef ENABLE_HE
if (_vm->_game.heversion >= 71)
((ScummEngine_v71he *)_vm)->queueAuxBlock(this);
#endif
+ _auxBlock.reset();
+ if (_visible) {
+ if (_vm->_game.heversion >= 60)
+ _needRedraw = true;
+ }
+ }
+
+ Actor::setActorCostume(c);
+
+ if (_vm->_game.heversion >= 71 && _vm->getTalkingActor() == _number) {
+ if (_vm->_game.heversion <= 95 || (_vm->_game.heversion >= 98 && _vm->VAR(_vm->VAR_SKIP_RESET_TALK_ACTOR) == 0)) {
+ _vm->setTalkingActor(0);
+ }
+ }
+}
+
+void Actor::setActorCostume(int c) {
+ int i;
+
+ _costumeNeedsInit = true;
+
+ if (_vm->_game.features & GF_NEW_COSTUMES) {
+ memset(_animVariable, 0, sizeof(_animVariable));
_costume = c;
_cost.reset();
- _auxBlock.reset();
if (_visible) {
if (_costume) {
_vm->ensureResourceLoaded(rtCostume, _costume);
}
startAnimActor(_initFrame);
- if (_vm->_game.heversion >= 60)
- _needRedraw = true;
}
} else {
if (_visible) {
@@ -2104,12 +2148,6 @@ void Actor::setActorCostume(int c) {
for (i = 0; i < 32; i++)
_palette[i] = 0xFF;
}
-
- if (_vm->_game.heversion >= 71 && _vm->getTalkingActor() == _number) {
- if (_vm->_game.heversion <= 95 || (_vm->_game.heversion >= 98 && _vm->VAR(_vm->VAR_SKIP_RESET_TALK_ACTOR) == 0)) {
- _vm->setTalkingActor(0);
- }
- }
}
static const char* v0ActorNames[7] = {
@@ -2245,7 +2283,7 @@ bool Actor_v2::isPlayer() {
return _vm->VAR(42) <= _number && _number <= _vm->VAR(43);
}
-void Actor::setHEFlag(int bit, int set) {
+void ActorHE::setHEFlag(int bit, int set) {
// Note that condition is inverted
if (!set) {
_heFlags |= bit;
@@ -2254,7 +2292,7 @@ void Actor::setHEFlag(int bit, int set) {
}
}
-void Actor::setUserCondition(int slot, int set) {
+void ActorHE::setUserCondition(int slot, int set) {
const int condMaskCode = (_vm->_game.heversion >= 85) ? 0x1FFF : 0x3FF;
assertRange(1, slot, 32, "setUserCondition: Condition");
if (set == 0) {
@@ -2269,12 +2307,12 @@ void Actor::setUserCondition(int slot, int set) {
}
}
-bool Actor::isUserConditionSet(int slot) const {
+bool ActorHE::isUserConditionSet(int slot) const {
assertRange(1, slot, 32, "isUserConditionSet: Condition");
return (_heCondMask & (1 << (slot + 0xF))) != 0;
}
-void Actor::setTalkCondition(int slot) {
+void ActorHE::setTalkCondition(int slot) {
const int condMaskCode = (_vm->_game.heversion >= 85) ? 0x1FFF : 0x3FF;
assertRange(1, slot, 32, "setTalkCondition: Condition");
_heCondMask = (_heCondMask & ~condMaskCode) | 1;
@@ -2288,7 +2326,7 @@ void Actor::setTalkCondition(int slot) {
}
}
-bool Actor::isTalkConditionSet(int slot) const {
+bool ActorHE::isTalkConditionSet(int slot) const {
assertRange(1, slot, 32, "isTalkConditionSet: Condition");
return (_heCondMask & (1 << (slot - 1))) != 0;
}
@@ -2311,10 +2349,10 @@ void ScummEngine_v71he::postProcessAuxQueue() {
for (int i = 0; i < _auxEntriesNum; ++i) {
AuxEntry *ae = &_auxEntries[i];
if (ae->actorNum != -1) {
- Actor *a = derefActor(ae->actorNum, "postProcessAuxQueue");
+ ActorHE *a = (ActorHE *)derefActor(ae->actorNum, "postProcessAuxQueue");
const uint8 *cost = getResourceAddress(rtCostume, a->_costume);
- int dy = a->_offsY + a->getPos().y;
- int dx = a->_offsX + a->getPos().x;
+ int dy = a->_heOffsY + a->getPos().y;
+ int dx = a->_heOffsX + a->getPos().x;
if (_game.heversion >= 72)
dy -= a->getElevation();
@@ -2378,7 +2416,7 @@ void ScummEngine_v71he::postProcessAuxQueue() {
_auxEntriesNum = 0;
}
-void ScummEngine_v71he::queueAuxBlock(Actor *a) {
+void ScummEngine_v71he::queueAuxBlock(ActorHE *a) {
if (!a->_auxBlock.visible)
return;
@@ -2401,8 +2439,8 @@ void Actor::saveLoadWithSerializer(Serializer *ser) {
static const SaveLoadEntry actorEntries[] = {
MKLINE(Actor, _pos.x, sleInt16, VER(8)),
MKLINE(Actor, _pos.y, sleInt16, VER(8)),
- MKLINE(Actor, _offsX, sleInt16, VER(32)),
- MKLINE(Actor, _offsY, sleInt16, VER(32)),
+ MKLINE(Actor, _heOffsX, sleInt16, VER(32)),
+ MKLINE(Actor, _heOffsY, sleInt16, VER(32)),
MKLINE(Actor, _top, sleInt16, VER(8)),
MKLINE(Actor, _bottom, sleInt16, VER(8)),
MKLINE(Actor, _elevation, sleInt16, VER(8)),
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index 30dc7789d6..3e8fe6626b 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -61,6 +61,7 @@ struct CostumeData {
uint16 end[16];
uint16 frame[16];
+ /* HE specific */
uint16 heJumpOffsetTable[16];
uint16 heJumpCountTable[16];
uint32 heCondMaskTable[16];
@@ -95,10 +96,6 @@ protected:
Common::Point _pos;
public:
- /** HE specific: This rect is used to clip actor drawing. */
- Common::Rect _clipOverride;
-
- int _offsX, _offsY;
int _top, _bottom;
uint _width;
byte _number;
@@ -137,22 +134,11 @@ public:
CostumeData _cost;
/* HE specific */
- bool _heNoTalkAnimation;
+ int _heOffsX, _heOffsY;
bool _heSkipLimbs;
- bool _heTalking;
uint32 _heCondMask;
uint32 _hePaletteNum;
uint32 _heXmapNum;
- byte _heFlags;
-
- AuxBlock _auxBlock;
-
- struct {
- int16 posX;
- int16 posY;
- int16 color;
- byte sentence[128];
- } _heTalkQueue[16];
protected:
struct ActorWalkData {
@@ -187,7 +173,7 @@ public:
virtual ~Actor() {}
//protected:
- void hideActor();
+ virtual void hideActor();
void showActor();
virtual void initActor(int mode);
@@ -223,10 +209,10 @@ public:
void faceToObject(int obj);
void turnToDirection(int newdir);
virtual void walkActor();
- void drawActorToBackBuf(int x, int y);
void drawActorCostume(bool hitTestMode = false);
+ virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
void animateCostume();
- void setActorCostume(int c);
+ virtual void setActorCostume(int c);
void animateLimb(int limb, int f);
@@ -317,6 +303,27 @@ public:
void classChanged(int cls, bool value);
+ // Used by the save/load system:
+ void saveLoadWithSerializer(Serializer *ser);
+
+protected:
+ bool isInClass(int cls);
+
+ virtual bool isPlayer();
+
+ bool findPathTowards(byte box, byte box2, byte box3, Common::Point &foundPath);
+};
+
+class ActorHE : public Actor {
+public:
+ ActorHE(ScummEngine *scumm, int id) : Actor(scumm, id) {}
+
+ virtual void initActor(int mode);
+
+ virtual void hideActor();
+
+ void drawActorToBackBuf(int x, int y);
+
void setHEFlag(int bit, int set);
void setUserCondition(int slot, int set);
@@ -325,15 +332,26 @@ public:
void setTalkCondition(int slot);
bool isTalkConditionSet(int slot) const;
- // Used by the save/load system:
- void saveLoadWithSerializer(Serializer *ser);
+public:
+ /** This rect is used to clip actor drawing. */
+ Common::Rect _clipOverride;
-protected:
- bool isInClass(int cls);
+ bool _heNoTalkAnimation;
+ bool _heTalking;
+ byte _heFlags;
- virtual bool isPlayer();
+ AuxBlock _auxBlock;
- bool findPathTowards(byte box, byte box2, byte box3, Common::Point &foundPath);
+ struct {
+ int16 posX;
+ int16 posY;
+ int16 color;
+ byte sentence[128];
+ } _heTalkQueue[16];
+
+
+ virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
+ virtual void setActorCostume(int c);
};
class Actor_v3 : public Actor {
@@ -357,6 +375,7 @@ public:
protected:
virtual bool isPlayer();
+ virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
};
class ActorC64 : public Actor_v2 {
diff --git a/engines/scumm/akos.cpp b/engines/scumm/akos.cpp
index 8e8fff938d..19c7c3320b 100644
--- a/engines/scumm/akos.cpp
+++ b/engines/scumm/akos.cpp
@@ -1664,28 +1664,28 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
akos_queCommand(9, a, a->_sound[a->getAnimVar(GB(2))], 0);
continue;
case AKC_C045:
- a->setUserCondition(GB(3), a->getAnimVar(GB(4)));
+ ((ActorHE *)a)->setUserCondition(GB(3), a->getAnimVar(GB(4)));
continue;
case AKC_C046:
- a->setAnimVar(GB(4), a->isUserConditionSet(GB(3)));
+ a->setAnimVar(GB(4), ((ActorHE *)a)->isUserConditionSet(GB(3)));
continue;
case AKC_C047:
- a->setTalkCondition(GB(3));
+ ((ActorHE *)a)->setTalkCondition(GB(3));
continue;
case AKC_C048:
- a->setAnimVar(GB(4), a->isTalkConditionSet(GB(3)));
+ a->setAnimVar(GB(4), ((ActorHE *)a)->isTalkConditionSet(GB(3)));
continue;
case AKC_C0A0:
akos_queCommand(8, a, GB(2), 0);
continue;
case AKC_C0A1:
- if (a->_heTalking != 0) {
+ if (((ActorHE *)a)->_heTalking != 0) {
curpos = GUW(2);
break;
}
continue;
case AKC_C0A2:
- if (a->_heTalking == 0) {
+ if (((ActorHE *)a)->_heTalking == 0) {
curpos = GUW(2);
break;
}
@@ -1763,8 +1763,8 @@ void ScummEngine_v6::akos_processQueue() {
a->_forceClip = param_1;
break;
case 6:
- a->_offsX = param_1;
- a->_offsY = param_2;
+ a->_heOffsX = param_1;
+ a->_heOffsY = param_2;
break;
case 7:
#ifdef ENABLE_HE
@@ -1775,13 +1775,13 @@ void ScummEngine_v6::akos_processQueue() {
case 8:
_actorToPrintStrFor = a->_number;
- a->_talkPosX = a->_heTalkQueue[param_1].posX;
- a->_talkPosY = a->_heTalkQueue[param_1].posY;
- a->_talkColor = a->_heTalkQueue[param_1].color;
+ a->_talkPosX = ((ActorHE *)a)->_heTalkQueue[param_1].posX;
+ a->_talkPosY = ((ActorHE *)a)->_heTalkQueue[param_1].posY;
+ a->_talkColor = ((ActorHE *)a)->_heTalkQueue[param_1].color;
_string[0].loadDefault();
_string[0].color = a->_talkColor;
- actorTalk(a->_heTalkQueue[param_1].sentence);
+ actorTalk(((ActorHE *)a)->_heTalkQueue[param_1].sentence);
break;
case 9:
@@ -1825,8 +1825,8 @@ void ScummEngine_v7::akos_processQueue() {
a->_forceClip = param_1;
break;
case 6:
- a->_offsX = param_1;
- a->_offsY = param_2;
+ a->_heOffsX = param_1;
+ a->_heOffsY = param_2;
break;
case 7:
if (param_1 != 0) {
diff --git a/engines/scumm/charset-fontdata.cpp b/engines/scumm/charset-fontdata.cpp
index 6a45d53139..e9a496f6ed 100644
--- a/engines/scumm/charset-fontdata.cpp
+++ b/engines/scumm/charset-fontdata.cpp
@@ -1070,6 +1070,7 @@ CharsetRendererV2::CharsetRendererV2(ScummEngine *vm, Common::Language language)
: CharsetRendererV3(vm) {
_fontHeight = 8;
+ _curId = 0;
switch (language) {
case Common::DE_DEU:
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index d3397fe208..b14f51cb14 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -25,6 +25,7 @@
#include "base/plugins.h"
+#include "common/archive.h"
#include "common/config-manager.h"
#include "common/fs.h"
#include "common/list.h"
@@ -211,9 +212,11 @@ static Common::Language detectLanguage(const Common::FSList &fslist, byte id) {
// ever determine that this is insufficient, we can still
// switch to MD5 based detection).
const char *filename = (id == GID_CMI) ? "LANGUAGE.TAB" : "LANGUAGE.BND";
- Common::File tmp;
+ Common::FilePtr tmp;
Common::FilesystemNode langFile;
- if (!searchFSNode(fslist, filename, langFile) || !tmp.open(langFile)) {
+ if (searchFSNode(fslist, filename, langFile))
+ tmp = Common::FilePtr(langFile.openForReading());
+ if (!tmp) {
// try loading in RESOURCE sub dir...
Common::FilesystemNode resDir;
Common::FSList tmpList;
@@ -221,11 +224,11 @@ static Common::Language detectLanguage(const Common::FSList &fslist, byte id) {
&& resDir.isDirectory()
&& resDir.getChildren(tmpList, Common::FilesystemNode::kListFilesOnly)
&& searchFSNode(tmpList, filename, langFile)) {
- tmp.open(langFile);
+ tmp = Common::FilePtr(langFile.openForReading());
}
}
- if (tmp.isOpen()) {
- uint size = tmp.size();
+ if (tmp) {
+ uint size = tmp->size();
if (id == GID_CMI) {
switch (size) {
case 439080: // 2daf3db71d23d99d19fc9a544fcf6431
@@ -450,8 +453,8 @@ static bool testGame(const GameSettings *g, const DescMap &fileMD5Map, const Com
// To do this, we take a close look at the detection file and
// try to filter out some cases.
- Common::File tmp;
- if (!tmp.open(d.node)) {
+ Common::FilePtr tmp(d.node.openForReading());
+ if (!tmp) {
warning("SCUMM testGame: failed to open '%s' for read access", d.node.getPath().c_str());
return false;
}
@@ -465,7 +468,7 @@ static bool testGame(const GameSettings *g, const DescMap &fileMD5Map, const Com
// Read a few bytes to narrow down the game.
byte buf[6];
- tmp.read(buf, 6);
+ tmp->read(buf, 6);
if (buf[0] == 0xbc && buf[1] == 0xb9) {
// The NES version of MM
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index d281364a77..8d70afecf2 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -713,6 +713,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "puttrace", "racedemo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "puttrace", "RaceDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttrace", "Rennen", kGenHEPC, Common::DE_DEU, UNK, 0 },
+ { "puttrace", "PouceCourse", kGenHEPC, Common::FR_FRA, UNK, 0 },
{ "puttrace", "Putt500", kGenHEPC, Common::NL_NLD, UNK, 0 },
{ "puttrace", "Putt500", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "puttrace", "Putt500 demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp
index ee1c0abf1c..382a0a9338 100644
--- a/engines/scumm/dialogs.cpp
+++ b/engines/scumm/dialogs.cpp
@@ -244,7 +244,10 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel,
_list->setEditable(saveMode);
_list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero);
- _container = new GUI::ContainerWidget(this, 0, 0, 10, 10);
+// Tanoku: SVNMerge removed this. Unconvinient. ///////////////
+// _container = new GUI::ContainerWidget(this, 0, 0, 10, 10);
+///////////////////////////////////////////////////////////////
+
_gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10);
_date = new StaticTextWidget(this, 0, 0, 10, 10, "No date saved", kTextAlignCenter);
@@ -255,6 +258,9 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel,
new GUI::ButtonWidget(this, "ScummSaveLoad.Cancel", "Cancel", kCloseCmd, 0);
_chooseButton = new GUI::ButtonWidget(this, "ScummSaveLoad.Choose", buttonLabel, kChooseCmd, 0);
_chooseButton->setEnabled(false);
+
+ _container = new GUI::ContainerWidget(this, 0, 0, 10, 10);
+// _container->setHints(GUI::THEME_HINT_USE_SHADOW);
}
SaveLoadChooser::~SaveLoadChooser() {
diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index f258ddd420..38c7a1a180 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -125,15 +125,15 @@ bool ScummFile::openSubFile(const Common::String &filename) {
}
-bool ScummFile::eos() {
+bool ScummFile::eos() const {
return _subFileLen ? (pos() >= _subFileLen) : File::eos(); // FIXME
}
-int32 ScummFile::pos() {
+int32 ScummFile::pos() const {
return File::pos() - _subFileStart;
}
-int32 ScummFile::size() {
+int32 ScummFile::size() const {
return _subFileLen ? _subFileLen : File::size();
}
diff --git a/engines/scumm/file.h b/engines/scumm/file.h
index 336f3cde12..e0ba7badff 100644
--- a/engines/scumm/file.h
+++ b/engines/scumm/file.h
@@ -39,9 +39,9 @@ public:
virtual bool open(const Common::String &filename) = 0;
virtual bool openSubFile(const Common::String &filename) = 0;
- virtual bool eos() = 0;
- virtual int32 pos() = 0;
- virtual int32 size() = 0;
+ virtual bool eos() const = 0;
+ virtual int32 pos() const = 0;
+ virtual int32 size() const = 0;
virtual bool seek(int32 offs, int whence = SEEK_SET) = 0;
virtual uint32 read(void *dataPtr, uint32 dataSize) = 0;
};
@@ -66,9 +66,9 @@ public:
bool ioFailed() const { return _myIoFailed || BaseScummFile::ioFailed(); }
void clearIOFailed() { _myIoFailed = false; BaseScummFile::clearIOFailed(); }
- bool eos();
- int32 pos();
- int32 size();
+ bool eos() const;
+ int32 pos() const;
+ int32 size() const;
bool seek(int32 offs, int whence = SEEK_SET);
uint32 read(void *dataPtr, uint32 dataSize);
};
@@ -111,9 +111,9 @@ public:
bool openSubFile(const Common::String &filename);
void close();
- bool eos() { return _stream->eos(); }
- int32 pos() { return _stream->pos(); }
- int32 size() { return _stream->size(); }
+ bool eos() const { return _stream->eos(); }
+ int32 pos() const { return _stream->pos(); }
+ int32 size() const { return _stream->size(); }
bool seek(int32 offs, int whence = SEEK_SET) { return _stream->seek(offs, whence); }
uint32 read(void *dataPtr, uint32 dataSize) { return _stream->read(dataPtr, dataSize); }
};
diff --git a/engines/scumm/file_nes.h b/engines/scumm/file_nes.h
index f1a07f8085..0a26ed9027 100644
--- a/engines/scumm/file_nes.h
+++ b/engines/scumm/file_nes.h
@@ -68,9 +68,9 @@ public:
bool openSubFile(const Common::String &filename);
void close();
- bool eos() { return _stream->eos(); }
- int32 pos() { return _stream->pos(); }
- int32 size() { return _stream->size(); }
+ bool eos() const { return _stream->eos(); }
+ int32 pos() const { return _stream->pos(); }
+ int32 size() const { return _stream->size(); }
bool seek(int32 offs, int whence = SEEK_SET) { return _stream->seek(offs, whence); }
uint32 read(void *dataPtr, uint32 dataSize) { return _stream->read(dataPtr, dataSize); }
};
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 45b078b6f9..4e8c22479d 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -22,7 +22,6 @@
*
*/
-
#include "common/system.h"
#include "scumm/scumm.h"
#include "scumm/actor.h"
@@ -577,15 +576,12 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
const byte *src = vs->getPixels(x, top);
int m = _textSurfaceMultiplier;
- byte *dst;
int vsPitch;
int pitch = vs->pitch;
if (_useCJKMode && _textSurfaceMultiplier == 2) {
- dst = _fmtownsBuf;
-
- scale2x(dst, _screenWidth * m, src, vs->pitch, width, height);
- src = dst;
+ scale2x(_fmtownsBuf, _screenWidth * m, src, vs->pitch, width, height);
+ src = _fmtownsBuf;
vsPitch = _screenWidth * m - width * m;
@@ -593,7 +589,6 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
vsPitch = vs->pitch - width;
}
- dst = _compositeBuf;
if (_game.version < 7) {
// For The Dig, FT and COMI, we just blit everything to the screen at once.
@@ -613,12 +608,12 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
// Compose the text over the game graphics
#ifdef USE_ARM_GFX_ASM
- asmDrawStripToScreen(height, width, text, src, dst, vs->pitch, width, _textSurface.pitch);
+ asmDrawStripToScreen(height, width, text, src, _compositeBuf, vs->pitch, width, _textSurface.pitch);
#else
// We blit four pixels at a time, for improved performance.
const uint32 *src32 = (const uint32 *)src;
const uint32 *text32 = (const uint32 *)text;
- uint32 *dst32 = (uint32 *)dst;
+ uint32 *dst32 = (uint32 *)_compositeBuf;
vsPitch >>= 2;
const int textPitch = (_textSurface.pitch - width * m) >> 2;
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index 72ba7edb85..8fd9122503 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -39,6 +39,7 @@ class WriteStream;
namespace Scumm {
+class ActorHE;
class ResExtractor;
#ifdef ENABLE_HE
class LogicHE;
@@ -243,7 +244,7 @@ public:
AuxEntry _auxEntries[16];
uint16 _auxEntriesNum;
- void queueAuxBlock(Actor *a);
+ void queueAuxBlock(ActorHE *a);
void queueAuxEntry(int actorNum, int subIndex);
void remapHEPalette(const uint8 *src, uint8 *dst);
diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp
index f8fb1efca2..4f74a74b89 100644
--- a/engines/scumm/he/resource_he.cpp
+++ b/engines/scumm/he/resource_he.cpp
@@ -165,7 +165,6 @@ int Win32ResExtractor::extractResource_(const char *resType, char *resName, byte
_fileName = _vm->generateFilename(-3);
}
-
/* get file size */
fi.file->open(_fileName);
if (!fi.file->isOpen()) {
@@ -174,18 +173,18 @@ int Win32ResExtractor::extractResource_(const char *resType, char *resName, byte
fi.total_size = fi.file->size();
if (fi.total_size == -1) {
- error("Cannot get size of file %s", fi.file->name());
+ 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", fi.file->name());
+ 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", fi.file->name());
+ error("Cannot read from file %s", _fileName.c_str());
goto cleanup;
}
@@ -200,8 +199,10 @@ int Win32ResExtractor::extractResource_(const char *resType, char *resName, byte
/* free stuff and close file */
cleanup:
- if (fi.file != NULL)
+ if (fi.file != NULL) {
fi.file->close();
+ delete fi.file;
+ }
if (fi.memory != NULL)
free(fi.memory);
@@ -371,19 +372,19 @@ byte *Win32ResExtractor::extract_group_icon_cursor_resource(WinLibrary *fi, WinR
fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level);
if (fwr == NULL) {
error("%s: could not find `%s' in `%s' resource.",
- fi->file->name(), &name[1], (is_icon ? "group_icon" : "group_cursor"));
+ _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", fi->file->name(), name);
+ 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)",
- fi->file->name(), name, iconsize, FROM_LE_32(icondir->entries[c].bytes_in_res));
+ _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); */
@@ -419,7 +420,7 @@ byte *Win32ResExtractor::extract_group_icon_cursor_resource(WinLibrary *fi, WinR
fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level);
if (fwr == NULL) {
error("%s: could not find `%s' in `%s' resource.",
- fi->file->name(), &name[1], (is_icon ? "group_icon" : "group_cursor"));
+ _fileName.c_str(), &name[1], (is_icon ? "group_icon" : "group_cursor"));
return NULL;
}
@@ -675,7 +676,7 @@ bool Win32ResExtractor::read_library(WinLibrary *fi) {
LE32(mz_header->lfanew);
if (mz_header->lfanew < sizeof(DOSImageHeader)) {
- error("%s: not a Windows library", fi->file->name());
+ error("%s: not a Windows library", _fileName.c_str());
return false;
}
}
@@ -724,7 +725,7 @@ bool Win32ResExtractor::read_library(WinLibrary *fi) {
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", fi->file->name());
+ error("%s: file contains no resources", _fileName.c_str());
return false;
}
@@ -735,7 +736,7 @@ bool Win32ResExtractor::read_library(WinLibrary *fi) {
}
/* other (unknown) header signature was found */
- error("%s: not a Windows library", fi->file->name());
+ error("%s: not a Windows library", _fileName.c_str());
return false;
}
diff --git a/engines/scumm/he/resource_he.h b/engines/scumm/he/resource_he.h
index a3237e7b3b..9f4b423d3d 100644
--- a/engines/scumm/he/resource_he.h
+++ b/engines/scumm/he/resource_he.h
@@ -102,10 +102,10 @@ namespace Scumm {
#endif
#define RETURN_IF_BAD_POINTER(r, x) \
- if (!check_offset(fi->memory, fi->total_size, fi->file->name(), &(x), sizeof(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, fi->file->name(), x, s)) \
+ if (!check_offset(fi->memory, fi->total_size, _fileName.c_str(), x, s)) \
return (r);
class ScummEngine_v70he;
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index 5717d77640..f1a202e22c 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "common/system.h"
#include "scumm/actor.h"
@@ -381,7 +379,7 @@ const char *ScummEngine_v100he::getOpcodeDesc(byte i) {
}
void ScummEngine_v100he::o100_actorOps() {
- Actor *a;
+ ActorHE *a;
int i, j, k;
int args[32];
byte string[256];
@@ -392,7 +390,7 @@ void ScummEngine_v100he::o100_actorOps() {
return;
}
- a = derefActorSafe(_curActor, "o100_actorOps");
+ a = (ActorHE *)derefActorSafe(_curActor, "o100_actorOps");
if (!a)
return;
diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp
index 9429f8d086..7f36d53791 100644
--- a/engines/scumm/he/script_v60he.cpp
+++ b/engines/scumm/he/script_v60he.cpp
@@ -23,7 +23,6 @@
*
*/
-
#include "common/savefile.h"
#include "scumm/actor.h"
@@ -623,7 +622,7 @@ void ScummEngine_v60he::swapObjects(int object1, int object2) {
}
void ScummEngine_v60he::o60_actorOps() {
- Actor *a;
+ ActorHE *a;
int i, j, k;
int args[8];
@@ -633,7 +632,7 @@ void ScummEngine_v60he::o60_actorOps() {
return;
}
- a = derefActorSafe(_curActor, "o60_actorOps");
+ a = (ActorHE *)derefActorSafe(_curActor, "o60_actorOps");
if (!a)
return;
diff --git a/engines/scumm/he/script_v70he.cpp b/engines/scumm/he/script_v70he.cpp
index 8fcb8b6fe8..577e7c3d99 100644
--- a/engines/scumm/he/script_v70he.cpp
+++ b/engines/scumm/he/script_v70he.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "common/config-manager.h"
#include "common/system.h"
diff --git a/engines/scumm/he/script_v71he.cpp b/engines/scumm/he/script_v71he.cpp
index 8b2823aa8c..1338ab3db8 100644
--- a/engines/scumm/he/script_v71he.cpp
+++ b/engines/scumm/he/script_v71he.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "scumm/actor.h"
#include "scumm/he/intern_he.h"
#include "scumm/scumm.h"
@@ -500,7 +498,7 @@ void ScummEngine_v71he::adjustRect(Common::Rect &rect) {
void ScummEngine_v71he::o71_kernelSetFunctions() {
int args[29];
int num;
- Actor *a;
+ ActorHE *a;
num = getStackList(args, ARRAYSIZE(args));
@@ -511,8 +509,8 @@ void ScummEngine_v71he::o71_kernelSetFunctions() {
virtScreenLoad(args[1], args[2], args[3], args[4], args[5]);
break;
case 20: // HE72+
- a = derefActor(args[1], "o71_kernelSetFunctions: 20");
- ((ScummEngine_v71he *)this)->queueAuxBlock(a);
+ a = (ActorHE *)derefActor(args[1], "o71_kernelSetFunctions: 20");
+ queueAuxBlock(a);
break;
case 21:
_skipDrawObject = 1;
@@ -533,14 +531,14 @@ void ScummEngine_v71he::o71_kernelSetFunctions() {
redrawAllActors();
break;
case 26:
- a = derefActor(args[1], "o71_kernelSetFunctions: 26");
+ a = (ActorHE *)derefActor(args[1], "o71_kernelSetFunctions: 26");
a->_auxBlock.r.left = 0;
a->_auxBlock.r.right = -1;
a->_auxBlock.r.top = 0;
a->_auxBlock.r.bottom = -2;
break;
case 30:
- a = derefActor(args[1], "o71_kernelSetFunctions: 30");
+ a = (ActorHE *)derefActor(args[1], "o71_kernelSetFunctions: 30");
a->_clipOverride.bottom = args[2];
break;
case 42:
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index 7e31383f4e..2fecc58bff 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "common/config-manager.h"
#include "common/savefile.h"
#include "common/system.h"
@@ -1021,7 +1019,7 @@ void ScummEngine_v72he::o72_roomOps() {
}
void ScummEngine_v72he::o72_actorOps() {
- Actor *a;
+ ActorHE *a;
int i, j, k;
int args[32];
byte string[256];
@@ -1032,7 +1030,7 @@ void ScummEngine_v72he::o72_actorOps() {
return;
}
- a = derefActorSafe(_curActor, "o72_actorOps");
+ a = (ActorHE *)derefActorSafe(_curActor, "o72_actorOps");
if (!a)
return;
diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp
index 39ec715d94..46449d1683 100644
--- a/engines/scumm/he/script_v80he.cpp
+++ b/engines/scumm/he/script_v80he.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "common/config-file.h"
#include "common/config-manager.h"
#include "common/savefile.h"
@@ -646,7 +644,7 @@ void ScummEngine_v80he::drawLine(int x1, int y1, int x, int y, int step, int typ
if (type == 2) {
- Actor *a = derefActor(id, "drawLine");
+ ActorHE *a = (ActorHE *)derefActor(id, "drawLine");
a->drawActorToBackBuf(x, y);
} else if (type == 3) {
WizImage wi;
@@ -697,7 +695,7 @@ void ScummEngine_v80he::drawLine(int x1, int y1, int x, int y, int step, int typ
continue;
if (type == 2) {
- Actor *a = derefActor(id, "drawLine");
+ ActorHE *a = (ActorHE *)derefActor(id, "drawLine");
a->drawActorToBackBuf(x, y);
} else if (type == 3) {
WizImage wi;
diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp
index 6d15303378..9829d0ecb5 100644
--- a/engines/scumm/he/script_v90he.cpp
+++ b/engines/scumm/he/script_v90he.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "scumm/actor.h"
#include "scumm/charset.h"
#include "scumm/he/animation_he.h"
@@ -1617,13 +1615,13 @@ void ScummEngine_v90he::o90_getWizData() {
}
void ScummEngine_v90he::o90_getActorData() {
- Actor *a;
+ ActorHE *a;
int subOp = pop();
int val = pop();
int act = pop();
- a = derefActor(act, "o90_getActorData");
+ a = (ActorHE *)derefActor(act, "o90_getActorData");
switch (subOp) {
case 1:
@@ -2570,13 +2568,13 @@ void ScummEngine_v90he::o90_kernelGetFunctions() {
void ScummEngine_v90he::o90_kernelSetFunctions() {
int args[29];
int num, tmp;
- Actor *a;
+ ActorHE *a;
num = getStackList(args, ARRAYSIZE(args));
switch (args[0]) {
case 20:
- a = derefActor(args[1], "o90_kernelSetFunctions: 20");
+ a = (ActorHE *)derefActor(args[1], "o90_kernelSetFunctions: 20");
queueAuxBlock(a);
break;
case 21:
@@ -2618,7 +2616,7 @@ void ScummEngine_v90he::o90_kernelSetFunctions() {
// Remote start script function
break;
case 1969:
- a = derefActor(args[1], "o90_kernelSetFunctions: 1969");
+ a = (ActorHE *)derefActor(args[1], "o90_kernelSetFunctions: 1969");
tmp = a->_heCondMask;
tmp ^= args[2];
tmp &= 0x7FFF0000;
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index 8bcd92fd3b..eaffbd04bb 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -109,6 +109,13 @@ void ScummEngine::setOwnerOf(int obj, int owner) {
int arg = (_game.version >= 6) ? obj : 0;
+ // WORKAROUND for bug #1917981: Game crash when finishing Indy3 demo.
+ // Script 94 tries to empty the inventory but does so in a bogus way.
+ // This causes it to try to remove object 0 from the inventory.
+ if (_game.id == GID_PASS && obj == 0 && vm.slot[_currentScript].number == 94)
+ return;
+ assert(obj > 0);
+
if (owner == 0) {
clearOwnerOf(obj);
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 9c076ddfc8..ce40d808b1 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Sat Sep 06 07:02:46 2008
+ This file was generated by the md5table tool on Mon Sep 29 00:06:57 2008
DO NOT EDIT MANUALLY!
*/
@@ -187,7 +187,7 @@ static const MD5Table md5table[] = {
{ "47e75b1bdcb44c78cb94883d1731ccf8", "fbear", "HE 61", "Demo", 6203, Common::EN_ANY, Common::kPlatformPC },
{ "48b9f04b348bc5013327753f0d12a144", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformAmiga },
{ "49210e124e4c2b30f1290a9ef6306301", "monkey", "EGA", "EGA", 8357, Common::EN_ANY, Common::kPlatformPC },
- { "4973bbc3899e3826dbf316e1d7271ec7", "zak", "V1", "", -1, Common::DE_DEU, Common::kPlatformC64 },
+ { "4973bbc3899e3826dbf316e1d7271ec7", "zak", "V1", "", 196608, Common::DE_DEU, Common::kPlatformC64 },
{ "499c958affc394f2a3868f1eb568c3ee", "freddi4", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "49a1739981a89066b1121fac04b710f4", "spyfox2", "HE CUP", "Preview", 5756234, Common::UNK_LANG, Common::kPlatformUnknown },
{ "4aa93cb30e485b728504ba3a693f12bf", "pajama", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows },
@@ -223,9 +223,10 @@ static const MD5Table md5table[] = {
{ "53e94115b55dd51d4b8ff0871aa1df1e", "spyfox", "", "Demo", 20103, Common::EN_ANY, Common::kPlatformUnknown },
{ "54a936ad06161ff7bfefcb96200f7bff", "monkey", "VGA", "VGA Demo", -1, Common::EN_ANY, Common::kPlatformAmiga },
{ "55518cd73cf9c6d23ea29c51ee06bdfe", "ft", "", "", -1, Common::IT_ITA, Common::kPlatformUnknown },
- { "55d3987641bf229c83bc729210173383", "zak", "V1", "", -1, Common::EN_ANY, Common::kPlatformC64 },
+ { "55d3987641bf229c83bc729210173383", "zak", "V1", "", 174848, Common::EN_ANY, Common::kPlatformC64 },
{ "55e4cc866ff9046824e1c638ba2b8c7f", "ft", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "566165a7338fa11029e7c14d94fa70d0", "freddi", "HE 73", "Demo", 9800, Common::EN_ANY, Common::kPlatformWindows },
+ { "5719fc8a13b4638b78d9d8d12f091f94", "puttrace", "HE 98.5", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "5798972220cd458be2626d54c80f71d7", "atlantis", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformAmiga },
{ "57a17febe2183f521250e55d55b83e60", "PuttTime", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "57a5cfec9ef231a007043cc1917e8988", "freddi", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii },
@@ -320,6 +321,7 @@ static const MD5Table md5table[] = {
{ "78bd5f036ea35a878b74e4f47941f784", "freddi4", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "78c07ca088526d8d4446a4c2cb501203", "freddi3", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "7974365d3dc0f43a2748c975f91ff042", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformPC },
+ { "7b60620558b8d6b7d7313b8ac7bb5a98", "zak", "V1", "", 174848, Common::IT_ITA, Common::kPlatformC64 },
{ "7bad72e332a59f9fcc1d437f4edad32a", "puttcircus", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "7c2e76087027eeee9c8f8985f93a1cc5", "freddi4", "", "Demo", 13584, Common::EN_ANY, Common::kPlatformUnknown },
{ "7c8100e360e8ef05f88069d4cfa0afd1", "puttrace", "HE 99", "Demo", 13108, Common::EN_GRB, Common::kPlatformWindows },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index f87adfd9ac..a10af41145 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1307,6 +1307,8 @@ void ScummEngine::resetScumm() {
_actors[i] = new Actor_v2(this, i);
else if (_game.version == 3)
_actors[i] = new Actor_v3(this, i);
+ else if (_game.heversion != 0)
+ _actors[i] = new ActorHE(this, i);
else
_actors[i] = new Actor(this, i);
_actors[i]->initActor(-1);
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 27c8943fee..ec733d32f4 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -918,7 +918,7 @@ public:
// Generic costume code
bool isCostumeInUse(int i) const;
- Common::Rect _actorClipOverride;
+ Common::Rect _actorClipOverride; // HE specific
protected:
/* Should be in Graphics class? */
diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp
index 3e15429e44..eb6b6d4dca 100644
--- a/engines/sword1/animation.cpp
+++ b/engines/sword1/animation.cpp
@@ -66,8 +66,8 @@ static const char *sequenceList[20] = {
// Basic movie player
///////////////////////////////////////////////////////////////////////////////
-MoviePlayer::MoviePlayer(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system)
- : _screen(screen), _textMan(textMan), _snd(snd), _system(system) {
+MoviePlayer::MoviePlayer(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system)
+ : _vm(vm), _screen(screen), _textMan(textMan), _snd(snd), _system(system) {
_bgSoundStream = NULL;
_ticks = 0;
_textSpriteBuf = NULL;
@@ -295,17 +295,20 @@ void MoviePlayer::play(void) {
handleScreenChanged();
break;
case Common::EVENT_KEYDOWN:
- if (event.kbd.keycode == Common::KEYCODE_ESCAPE) {
- _snd->stopHandle(_bgSoundHandle);
+ if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
terminated = true;
- }
break;
default:
break;
}
}
+ if (_vm->quit())
+ terminated = true;
}
+ if (terminated)
+ _snd->stopHandle(_bgSoundHandle);
+
while (!_movieTexts.empty()) {
delete _movieTexts.remove_at(_movieTexts.size() - 1);
}
@@ -390,8 +393,8 @@ int SplittedAudioStream::readBuffer(int16 *buffer, const int numSamples) {
// Movie player for the new DXA movies
///////////////////////////////////////////////////////////////////////////////
-MoviePlayerDXA::MoviePlayerDXA(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system)
- : MoviePlayer(screen, textMan, snd, system) {
+MoviePlayerDXA::MoviePlayerDXA(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system)
+ : MoviePlayer(vm, screen, textMan, snd, system) {
debug(0, "Creating DXA cutscene player");
}
@@ -438,7 +441,7 @@ bool MoviePlayerDXA::decodeFrame(void) {
void MoviePlayerDXA::processFrame(void) {
// TODO: Handle the advanced cutscene packs. Do they really exist?
- // We cannot draw the text to _drawBuffer, sinzce ethat's one of the
+ // We cannot draw the text to _drawBuffer, since that's one of the
// decoder's internal buffers. Instead, we copy part of _drawBuffer
// to the text sprite.
@@ -492,8 +495,8 @@ void MoviePlayerDXA::updateScreen(void) {
// Movie player for the old MPEG movies
///////////////////////////////////////////////////////////////////////////////
-MoviePlayerMPEG::MoviePlayerMPEG(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system)
- : MoviePlayer(screen, textMan, snd, system) {
+MoviePlayerMPEG::MoviePlayerMPEG(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system)
+ : MoviePlayer(vm, screen, textMan, snd, system) {
#ifdef BACKEND_8BIT
debug(0, "Creating MPEG cutscene player (8-bit)");
#else
@@ -625,7 +628,7 @@ Audio::AudioStream *AnimationState::createAudioStream(const char *name, void *ar
// Factory function for creating the appropriate cutscene player
///////////////////////////////////////////////////////////////////////////////
-MoviePlayer *makeMoviePlayer(uint32 id, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system) {
+MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system) {
#if defined(USE_ZLIB) || defined(USE_MPEG2)
char filename[20];
#endif
@@ -634,7 +637,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, Screen *screen, Text *textMan, Audio::Mi
snprintf(filename, sizeof(filename), "%s.dxa", sequenceList[id]);
if (Common::File::exists(filename)) {
- return new MoviePlayerDXA(screen, textMan, snd, system);
+ return new MoviePlayerDXA(vm, screen, textMan, snd, system);
}
#endif
@@ -642,7 +645,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, Screen *screen, Text *textMan, Audio::Mi
snprintf(filename, sizeof(filename), "%s.mp2", sequenceList[id]);
if (Common::File::exists(filename)) {
- return new MoviePlayerMPEG(screen, textMan, snd, system);
+ return new MoviePlayerMPEG(vm, screen, textMan, snd, system);
}
#endif
diff --git a/engines/sword1/animation.h b/engines/sword1/animation.h
index 0837814c69..fd9c774190 100644
--- a/engines/sword1/animation.h
+++ b/engines/sword1/animation.h
@@ -78,7 +78,7 @@ public:
class MoviePlayer {
public:
- MoviePlayer(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
+ MoviePlayer(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
virtual ~MoviePlayer(void);
virtual bool load(uint32 id);
void play(void);
@@ -86,6 +86,7 @@ public:
private:
bool checkSkipFrame(void);
protected:
+ SwordEngine *_vm;
Screen *_screen;
Text *_textMan;
Audio::Mixer *_snd;
@@ -122,7 +123,7 @@ class MoviePlayerDXA : public MoviePlayer, ::Graphics::DXAPlayer {
protected:
virtual void setPalette(byte *pal);
public:
- MoviePlayerDXA(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
+ MoviePlayerDXA(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
virtual ~MoviePlayerDXA(void);
bool load(uint32 id);
protected:
@@ -159,7 +160,7 @@ protected:
class MoviePlayerMPEG : public MoviePlayer {
public:
- MoviePlayerMPEG(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
+ MoviePlayerMPEG(SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
virtual ~MoviePlayerMPEG(void);
bool load(uint32 id);
protected:
@@ -195,7 +196,7 @@ private:
FileQueue *_queue;
};
-MoviePlayer *makeMoviePlayer(uint32 id, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
+MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system);
} // End of namespace Sword1
diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp
index 2fa108ebdd..8950986b09 100644
--- a/engines/sword1/logic.cpp
+++ b/engines/sword1/logic.cpp
@@ -55,9 +55,10 @@ namespace Sword1 {
uint32 Logic::_scriptVars[NUM_SCRIPT_VARS];
-Logic::Logic(ObjectMan *pObjMan, ResMan *resMan, Screen *pScreen, Mouse *pMouse, Sound *pSound, Music *pMusic, Menu *pMenu, OSystem *system, Audio::Mixer *mixer) {
+Logic::Logic(SwordEngine *vm, ObjectMan *pObjMan, ResMan *resMan, Screen *pScreen, Mouse *pMouse, Sound *pSound, Music *pMusic, Menu *pMenu, OSystem *system, Audio::Mixer *mixer) {
g_system->getEventManager()->registerRandomSource(_rnd, "sword1");
+ _vm = vm;
_objMan = pObjMan;
_resMan = resMan;
_screen = pScreen;
@@ -963,7 +964,7 @@ int Logic::fnPlaySequence(Object *cpt, int32 id, int32 sequenceId, int32 d, int3
CreditsPlayer player(_system, _mixer);
player.play();
} else {
- MoviePlayer *player = makeMoviePlayer(sequenceId, _screen, _textMan, _mixer, _system);
+ MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _screen, _textMan, _mixer, _system);
if (player) {
if (player->load(sequenceId))
player->play();
diff --git a/engines/sword1/logic.h b/engines/sword1/logic.h
index 8e2f24ac83..6e3f08c4af 100644
--- a/engines/sword1/logic.h
+++ b/engines/sword1/logic.h
@@ -37,6 +37,7 @@ namespace Sword1 {
#define NON_ZERO_SCRIPT_VARS 95
#define NUM_SCRIPT_VARS 1179
+class SwordEngine;
class Text;
class Sound;
class EventManager;
@@ -51,7 +52,7 @@ typedef int (Logic::*BSMcodeTable)(Object *, int32, int32, int32, int32, int32,
class Logic {
public:
- Logic(ObjectMan *pObjMan, ResMan *resMan, Screen *pScreen, Mouse *pMouse, Sound *pSound, Music *pMusic, Menu *pMenu, OSystem *system, Audio::Mixer *mixer);
+ Logic(SwordEngine *vm, ObjectMan *pObjMan, ResMan *resMan, Screen *pScreen, Mouse *pMouse, Sound *pSound, Music *pMusic, Menu *pMenu, OSystem *system, Audio::Mixer *mixer);
~Logic(void);
void initialize(void);
void newScreen(uint32 screen);
@@ -64,6 +65,7 @@ public:
// public for mouse (menu looking)
int cfnPresetScript (Object *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x);
private:
+ SwordEngine *_vm;
ObjectMan *_objMan;
OSystem *_system;
Audio::Mixer *_mixer;
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index 9b79f59a32..42124d419e 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -303,7 +303,7 @@ int SwordEngine::init() {
_music = new Music(_mixer);
_sound = new Sound("", _mixer, _resMan);
_menu = new Menu(_screen, _mouse);
- _logic = new Logic(_objectMan, _resMan, _screen, _mouse, _sound, _music, _menu, _system, _mixer);
+ _logic = new Logic(this, _objectMan, _resMan, _screen, _mouse, _sound, _music, _menu, _system, _mixer);
_mouse->useLogicAndMenu(_logic, _menu);
syncSoundSettings();
diff --git a/graphics/imageman.cpp b/graphics/imageman.cpp
index 83ffc40c99..44ac7c9e75 100644
--- a/graphics/imageman.cpp
+++ b/graphics/imageman.cpp
@@ -26,14 +26,13 @@
#include "graphics/imageman.h"
#include "graphics/surface.h"
+#include "common/unzip.h"
+
DECLARE_SINGLETON(Graphics::ImageManager);
namespace Graphics {
-ImageManager::ImageManager() : _surfaces()
-#ifdef USE_ZLIB
-, _archives()
-#endif
-{
+
+ImageManager::ImageManager() {
}
ImageManager::~ImageManager() {
@@ -44,36 +43,21 @@ ImageManager::~ImageManager() {
*pos = 0;
}
_surfaces.clear();
-#ifdef USE_ZLIB
- for (ZipIterator pos2 = _archives.begin(); pos2 != _archives.end(); ++pos2) {
- unzClose(pos2->file);
- }
- _archives.clear();
-#endif
}
bool ImageManager::addArchive(const Common::String &name) {
#ifdef USE_ZLIB
- unzFile newFile = unzOpen(name.c_str());
- if (!newFile)
+ Common::ZipArchive *arch = new Common::ZipArchive(name);
+ if (!arch || !arch->isOpen())
return false;
- Archive arch;
- arch.file = newFile;
- arch.filename = name;
- _archives.push_back(arch);
+ _archives.add(name, Common::ArchivePtr(arch));
#endif
return true;
}
-void ImageManager::remArchive(const Common::String &name) {
+void ImageManager::removeArchive(const Common::String &name) {
#ifdef USE_ZLIB
- for (ZipIterator pos = _archives.begin(); pos != _archives.end(); ++pos) {
- if (pos->filename.compareToIgnoreCase(name) == 0) {
- unzClose(pos->file);
- _archives.erase(pos);
- break;
- }
- }
+ _archives.remove(name);
#endif
}
@@ -86,39 +70,21 @@ bool ImageManager::registerSurface(const Common::String &name, Surface *surf) {
if (!newHandle)
return false;
- if (!surf) {
+ if (!surf)
surf = ImageDecoder::loadFile(name);
- if (!surf) {
+
#ifdef USE_ZLIB
- ZipIterator file = _archives.end();
- for (ZipIterator pos = _archives.begin(); pos != _archives.end(); ++pos) {
- if (unzLocateFile(pos->file, name.c_str(), 2) == UNZ_OK) {
- file = pos;
- break;
- }
- }
-
- if (file == _archives.end())
- return false;
-
- unz_file_info fileInfo;
- unzOpenCurrentFile(file->file);
- unzGetCurrentFileInfo(file->file, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
- uint8 *buffer = new uint8[fileInfo.uncompressed_size];
- assert(buffer);
- unzReadCurrentFile(file->file, buffer, fileInfo.uncompressed_size);
- unzCloseCurrentFile(file->file);
- Common::MemoryReadStream stream(buffer, fileInfo.uncompressed_size);
- surf = ImageDecoder::loadFile(stream);
- delete[] buffer;
-
- if (!surf)
- return false;
-#else
- return false;
-#endif
+ if (!surf) {
+ Common::SeekableReadStream *stream = _archives.openFile(name);
+ if (stream) {
+ surf = ImageDecoder::loadFile(*stream);
+ delete stream;
}
}
+#endif
+
+ if (!surf)
+ return false;
newHandle->surface = surf;
newHandle->name = name;
diff --git a/graphics/imageman.h b/graphics/imageman.h
index c3b56c311f..f555b4c844 100644
--- a/graphics/imageman.h
+++ b/graphics/imageman.h
@@ -26,12 +26,14 @@
#define GRAPHICS_IMAGEMAN_H
#include "common/scummsys.h"
+
+#include "common/archive.h"
#include "common/singleton.h"
#include "common/str.h"
#include "common/list.h"
-#include "common/unzip.h"
namespace Graphics {
+
struct Surface;
class ImageManager : public Common::Singleton<ImageManager> {
@@ -53,7 +55,7 @@ public:
*
* @param name the name of the archive
*/
- void remArchive(const Common::String &name);
+ void removeArchive(const Common::String &name);
/**
* registers a surface to the ImageManager.
@@ -93,20 +95,11 @@ private:
Surface *surface;
};
typedef Common::List<Entry*>::iterator Iterator;
-#ifdef USE_ZLIB
- struct Archive {
- unzFile file;
- Common::String filename;
- };
- typedef Common::List<Archive>::iterator ZipIterator;
-#endif
Iterator searchHandle(const Common::String &name);
Common::List<Entry*> _surfaces;
-#ifdef USE_ZLIB
- Common::List<Archive> _archives;
-#endif
+ Common::SearchSet _archives;
};
} // end of namespace Graphics
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index c33251b546..6af62f7b80 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -30,6 +30,7 @@
#include "common/events.h"
#include "common/config-manager.h"
#include "common/fs.h"
+#include "common/unzip.h"
#include "graphics/imageman.h"
#include "graphics/cursorman.h"
#include "gui/launcher.h"
@@ -251,7 +252,7 @@ void ThemeEngine::unloadTheme() {
ImageMan.unregisterSurface(i->_key);
if (_themeFileName.hasSuffix(".zip"))
- ImageMan.remArchive(_themeFileName);
+ ImageMan.removeArchive(_themeFileName);
Common::File::resetDefaultDirectories();
@@ -534,53 +535,36 @@ bool ThemeEngine::loadThemeXML(Common::String themeName) {
bool failed = false;
#ifdef USE_ZLIB
- unzFile zipFile = unzOpen((themeName).c_str());
+ Common::ZipArchive zipFile(themeName.c_str());
+ Common::StringList zipContents;
- if (zipFile && unzGoToFirstFile(zipFile) == UNZ_OK) {
- while (true) {
- unz_file_info fileInfo;
- unzOpenCurrentFile(zipFile);
- unzGetCurrentFileInfo(zipFile, &fileInfo, fileNameBuffer, 32, NULL, 0, NULL, 0);
+ if (zipFile.isOpen() && zipFile.getAllNames(zipContents)) {
- if (matchString(fileNameBuffer, "*.stx") || !strcmp(fileNameBuffer, "THEMERC")) {
- uint8 *buffer = new uint8[fileInfo.uncompressed_size+1];
- assert(buffer);
- memset(buffer, 0, (fileInfo.uncompressed_size+1)*sizeof(uint8));
- unzReadCurrentFile(zipFile, buffer, fileInfo.uncompressed_size);
-
- Common::MemoryReadStream *stream = new Common::MemoryReadStream(buffer, fileInfo.uncompressed_size+1, true);
+ for (uint i = 0; i < zipContents.size(); ++i) {
+ if (!failed && matchString(zipContents[i].c_str(), "*.stx")) {
+ if (parser()->loadStream(zipFile.openFile(zipContents[i])) == false) {
+ warning("Failed to load stream for zipped file '%s'", fileNameBuffer);
+ failed = true;
+ }
- if (!strcmp(fileNameBuffer, "THEMERC")) {
- stxHeader = stream->readLine();
-
- if (!themeConfigParseHeader(stxHeader.c_str(), _themeName)) {
- warning("Corrupted 'THEMERC' file in theme '%s'", _themeFileName.c_str());
- failed = true;
- }
-
- delete stream;
-
- } else if (!failed) {
- parseCount++;
-
- if (parser()->loadStream(stream) == false) {
- warning("Failed to load stream for zipped file '%s'", fileNameBuffer);
- failed = true;
- }
-
- if (parser()->parse() == false) {
- warning("Theme parsing failed on zipped file '%s'.", fileNameBuffer);
- failed = true;
- }
-
- parser()->close();
+ if (parser()->parse() == false) {
+ warning("Theme parsing failed on zipped file '%s'.", fileNameBuffer);
+ failed = true;
}
- }
-
- unzCloseCurrentFile(zipFile);
-
- if (unzGoToNextFile(zipFile) != UNZ_OK)
- break;
+
+ parser()->close();
+ parseCount++;
+ } else if (zipContents[i] == "THEMERC") {
+ Common::SeekableReadStream *stream = zipFile.openFile(zipContents[i]);
+ stxHeader = stream->readLine();
+
+ if (!themeConfigParseHeader(stxHeader.c_str(), _themeName)) {
+ warning("Corrupted 'THEMERC' file in theme '%s'", _themeFileName.c_str());
+ failed = true;
+ }
+
+ delete stream;
+ }
}
} else {
#endif
@@ -619,13 +603,9 @@ bool ThemeEngine::loadThemeXML(Common::String themeName) {
}
}
#ifdef USE_ZLIB
- }
-
- unzClose(zipFile);
-
+ }
#endif
-
return (parseCount > 0 && _themeName.empty() == false && failed == false);
}
diff --git a/gui/credits.h b/gui/credits.h
index b8d2e345c8..c04a99ddbd 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -144,7 +144,6 @@ static const char *credits[] = {
"\\C\\c0""Kostas Nakos",
"\\C\\c0""",
"\\C\\c1""PlayStation 2",
-"\\C\\c0""Robert G\366ffringmann",
"\\C\\c0""Max Lingua",
"\\C\\c0""",
"\\C\\c1""PSP (PlayStation Portable)",
@@ -205,6 +204,10 @@ static const char *credits[] = {
"\\C\\c2""Help with GUI implementation",
"\\C\\c0""Jamieson Christian",
"\\C\\c2""iMUSE, MIDI, all things musical",
+"\\C\\c0""Hans-J\366rg Frieden",
+"\\C\\c2""Former AmigaOS 4 packager",
+"\\C\\c0""Robert G\366ffringmann",
+"\\C\\c2""Original PS2 porter",
"\\C\\c0""R\374diger Hanke",
"\\C\\c2""Port: MorphOS",
"\\C\\c0""Felix Jakschitsch",
@@ -213,6 +216,8 @@ static const char *credits[] = {
"\\C\\c2""Original MacOS porter",
"\\C\\c0""Peter Moraliyski",
"\\C\\c2""Port: GP32",
+"\\C\\c0""Juha Niemim\344ki",
+"\\C\\c2""Formaer AmigaOS 4 packager",
"\\C\\c0""Jeremy Newman",
"\\C\\c2""Former webmaster",
"\\C\\c0""Lionel Ulmer",
@@ -225,9 +230,7 @@ static const char *credits[] = {
"\\C\\c0""",
"\\C\\c1""Packages",
"\\C\\c1""AmigaOS 4",
-"\\C\\c0""Hans-J\366rg Frieden",
"\\C\\c0""Hubert Maier",
-"\\C\\c0""Juha Niemim\344ki",
"\\C\\c0""",
"\\C\\c1""Atari/FreeMiNT",
"\\C\\c0""Keith Scroggins",
@@ -294,6 +297,8 @@ static const char *credits[] = {
"\\C\\c2""PSP port contributions",
"\\C\\c0""Thierry Crozat",
"\\C\\c2""Support for Broken Sword 1 Macintosh version",
+"\\C\\c0""Martin Doucha",
+"\\C\\c2""CinE engine objectification",
"\\C\\c0""Thomas Fach-Pedersen",
"\\C\\c2""ProTracker module player",
"\\C\\c0""Benjamin Haisch",
@@ -342,10 +347,14 @@ static const char *credits[] = {
"\\C\\c2""For the original MT-32 emulator",
"\\C\\c0""Kevin Carnes",
"\\C\\c2""For Scumm16, the basis of ScummVM's older gfx codecs",
+"\\C\\c0""Curt Coder",
+"\\C\\c2""For the original TrollVM (preAGI) code",
"\\C\\c0""Patrick Combet",
"\\C\\c2""For the original Gobliiins ADL player",
"\\C\\c0""Ivan Dubrov",
"\\C\\c2""For contributing the initial version of the Gobliiins engine",
+"\\C\\c0""Till Kresslein",
+"\\C\\c2""For design of modern ScummVM GUI",
"\\C\\c0""Jezar",
"\\C\\c2""For his freeverb filter implementation",
"\\C\\c0""Jim Leiterman",
@@ -358,6 +367,8 @@ static const char *credits[] = {
"\\C\\c2""For ScummRev, and much obscure code/documentation",
"\\C\\c0""Tristan",
"\\C\\c2""For additional work on the original MT-32 emulator",
+"\\C\\c0""James Woodcock",
+"\\C\\c2""Soundtrack enhancements",
"\\C\\c0""Tony Warriner and everyone at Revolution Software Ltd. for sharing with us the source of some of their brilliant games, allowing us to release Beneath a Steel Sky as freeware... and generally being supportive above and beyond the call of duty.",
"\\C\\c0""",
"\\C\\c0""John Passfield and Steve Stamatiadis for sharing the source of their classic title, Flight of the Amazon Queen and also being incredibly supportive.",
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 978c224afd..e337c718a2 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -524,10 +524,7 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel)
// Add choice list
_list = new GUI::ListWidget(this, "ScummSaveLoad.List");
_list->setNumberingMode(GUI::kListNumberingOff);
-
- _container = new GUI::ContainerWidget(this, 0, 0, 10, 10);
-// _container->setHints(GUI::THEME_HINT_USE_SHADOW);
-
+
_gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10);
_date = new StaticTextWidget(this, 0, 0, 10, 10, "No date saved", kTextAlignCenter);
@@ -543,6 +540,9 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel)
_deleteButton->setEnabled(false);
_delSupport = _metaInfoSupport = _thumbnailSupport = false;
+
+ _container = new GUI::ContainerWidget(this, 0, 0, 10, 10);
+// _container->setHints(GUI::THEME_HINT_USE_SHADOW);
}
SaveLoadChooser::~SaveLoadChooser() {
diff --git a/gui/theme.cpp b/gui/theme.cpp
index df9ae34017..8c27d27417 100644
--- a/gui/theme.cpp
+++ b/gui/theme.cpp
@@ -45,7 +45,7 @@ const Graphics::Font *Theme::loadFont(const char *filename) {
return font;
#ifdef USE_ZLIB
- ZipArchive zipArchive(getThemeFileName().c_str());
+ Common::ZipArchive zipArchive(getThemeFileName().c_str());
if (zipArchive.hasFile(cacheFilename)) {
Common::FilePtr stream(zipArchive.openFile(cacheFilename));
font = Graphics::NewFont::loadFromCache(*stream.get());
@@ -62,7 +62,8 @@ const Graphics::Font *Theme::loadFont(const char *filename) {
#ifdef USE_ZLIB
if (!font) {
- ZipArchive zipArchive(getThemeFileName().c_str());
+ Common::ZipArchive zipArchive(getThemeFileName().c_str());
+
if (zipArchive.hasFile(filename)) {
Common::FilePtr stream(zipArchive.openFile(filename));
font = Graphics::NewFont::loadFont(*stream.get());
@@ -145,7 +146,8 @@ bool Theme::themeConfigUseable(const Common::FilesystemNode &node, Common::Strin
if (node.getName().hasSuffix(".zip")) {
#ifdef USE_ZLIB
- ZipArchive zipArchive(node.getPath().c_str());
+
+ Common::ZipArchive zipArchive(node.getPath().c_str());
if (zipArchive.hasFile("THEMERC")) {
Common::FilePtr stream(zipArchive.openFile("THEMERC"));
stxHeader = stream->readLine();
diff --git a/gui/theme.h b/gui/theme.h
index 302029247b..5294daa4d4 100644
--- a/gui/theme.h
+++ b/gui/theme.h
@@ -34,7 +34,7 @@
#include "graphics/surface.h"
#include "graphics/fontman.h"
-#define THEME_VERSION 23
+#define THEME_VERSION 24
#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_THEME_V23"
namespace GUI {
diff --git a/tools/credits.pl b/tools/credits.pl
index 45351146c2..2c5fed46f6 100755
--- a/tools/credits.pl
+++ b/tools/credits.pl
@@ -624,7 +624,6 @@ begin_credits("Credits");
end_section();
begin_section("PlayStation 2");
- add_person("Robert G&ouml;ffringmann", "lavosspawn", "");
add_person("Max Lingua", "sunmax", "");
end_section();
@@ -685,10 +684,13 @@ begin_credits("Credits");
add_person("Nicolas Bacca", "arisme", "Former WinCE porter");
add_person("Ralph Brorsen", "painelf", "Help with GUI implementation");
add_person("Jamieson Christian", "jamieson630", "iMUSE, MIDI, all things musical");
+ add_person("Hans-J&ouml;rg Frieden", "", "Former AmigaOS 4 packager");
+ add_person("Robert G&ouml;ffringmann", "lavosspawn", "Original PS2 porter");
add_person("R&uuml;diger Hanke", "", "Port: MorphOS");
add_person("Felix Jakschitsch", "yot", "Zak256 reverse engineering");
add_person("Mutwin Kraus", "mutle", "Original MacOS porter");
add_person("Peter Moraliyski", "ph0x", "Port: GP32");
+ add_person("Juha Niemim&auml;ki", "", "Formaer AmigaOS 4 packager");
add_person("Jeremy Newman", "laxdragon", "Former webmaster");
add_person("Lionel Ulmer", "bbrox", "Port: X11");
add_person("Won Star", "wonst719", "Former GP32 porter");
@@ -701,9 +703,7 @@ begin_credits("Credits");
begin_section("Packages");
begin_section("AmigaOS 4");
- add_person("Hans-J&ouml;rg Frieden", "", "");
add_person("Hubert Maier", "Raziel_AOne", "");
- add_person("Juha Niemim&auml;ki", "", "");
end_section();
begin_section("Atari/FreeMiNT");
@@ -778,6 +778,7 @@ begin_credits("Credits");
add_person("Stuart Caie", "", "Decoders for Simon 1 Amiga data files");
add_person("Paolo Costabel", "", "PSP port contributions");
add_person("Thierry Crozat", "criezy", "Support for Broken Sword 1 Macintosh version");
+ add_person("Martin Doucha", "next_ghost", "CinE engine objectification");
add_person("Thomas Fach-Pedersen", "madmoose", "ProTracker module player");
add_person("Benjamin Haisch", "john_doe", "Heavily improved de-/encoder for DXA videos");
add_person("Janne Huttunen", "", "V3 actor mask support, Dig/FT SMUSH audio");
@@ -812,14 +813,17 @@ begin_credits("Credits");
add_person("Sander Buskens", "", "For his work on the initial reversing of Monkey2");
add_person("", "Canadacow", "For the original MT-32 emulator");
add_person("Kevin Carnes", "", "For Scumm16, the basis of ScummVM's older gfx codecs");
+ add_person("Curt Coder", "", "For the original TrollVM (preAGI) code");
add_person("Patrick Combet", "Dorian Gray", "For the original Gobliiins ADL player");
add_person("Ivan Dubrov", "", "For contributing the initial version of the Gobliiins engine");
+ add_person("Till Kresslein", "Krest", "For design of modern ScummVM GUI");
add_person("", "Jezar", "For his freeverb filter implementation");
add_person("Jim Leiterman", "", "Various info on his FM-TOWNS/Marty SCUMM ports");
add_person("", "lloyd", "For deep tech details about C64 Zak &amp; MM");
add_person("Sarien Team", "", "Original AGI engine code");
add_person("Jimmi Th&oslash;gersen", "", "For ScummRev, and much obscure code/documentation");
add_person("", "Tristan", "For additional work on the original MT-32 emulator");
+ add_person("James Woodcock", "", "Soundtrack enhancements");
end_persons();
add_paragraph(
diff --git a/tools/scumm-md5.txt b/tools/scumm-md5.txt
index 0ce6ded8a3..cb805fcc26 100644
--- a/tools/scumm-md5.txt
+++ b/tools/scumm-md5.txt
@@ -89,8 +89,9 @@ maniac Maniac Mansion
40564ec47da48a67787d1f9bd043902a 1988 en DOS V2 Demo V2 Demo non-interactive Fingolfin
zak Zak McKracken and the Alien Mindbenders
- 55d3987641bf229c83bc729210173383 -1 en C64 V1 - -
- 4973bbc3899e3826dbf316e1d7271ec7 -1 de C64 V1 - -
+ 55d3987641bf229c83bc729210173383 174848 en C64 V1 - -
+ 4973bbc3899e3826dbf316e1d7271ec7 196608 de C64 V1 - -
+ 7b60620558b8d6b7d7313b8ac7bb5a98 174848 it C64 V1 - -
7020931d5a2be0a49d68e7a1882363e4 1896 en DOS V1 V1 - Fingolfin
b23f7cd7c304d7dff08e92a96120d5b4 -1 en DOS V1 V1 alt? Andrea Petrucci
@@ -660,6 +661,7 @@ puttrace Putt-Putt Enters the Race
981e1e1891f2be7e25a01f50ae55a5af -1 us All HE 98 - - Kirben
1ed22f601f8b3695804a6583cc3083f1 -1 nl All HE 98.5 - - daniel9
33e989f85da700e2014d00f345cab3d7 -1 fr Windows HE 98.5 - - gist974
+ 5719fc8a13b4638b78d9d8d12f091f94 -1 fr Windows HE 98.5 - - thyphoon
b47be81e39a9710f6f595f7b527b60f8 -1 gb Windows HE 99 - - Reckless
055ffe4f47753e47594ac67823220c54 -1 de All HE 99 - - Joachim Eberhard
62050da376483d8edcbd98cd26b6cb57 -1 ru Windows HE 99 - - sev