[Scummvm-cvs-logs] scummvm master -> 7f5f9c9f91eb8cd52ebcffe208d0e778f8ff6448
DrMcCoy
drmccoy at drmccoy.de
Sat Sep 3 18:05:59 CEST 2011
This automated email contains information about 10 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
eebd5a28f9 GOB: Add Util::readString()
cceaa04ef2 GOB: Make Util::setExtension() not add an extension to an empty string
44b83551aa GOB: Add the Amiga version of Geisha
2985f118b8 GOB: Add class RXYFile
37964e8e85 GOB: Add class DECFile
a4f42017d7 GOB: Add class ANIFile
220fc2b593 GOB: Add class ANIObject
dbb70e3d6f GOB: Add class Geisha::EvilFish
26dd2f5f60 GOB: Move keyPressed() to Util
7f5f9c9f91 GOB: Stub classes for Geisha's Diving and Penetration minigames
Commit: eebd5a28f9a76f3021041480fd22d218bcfa18d9
https://github.com/scummvm/scummvm/commit/eebd5a28f9a76f3021041480fd22d218bcfa18d9
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2011-09-03T09:00:08-07:00
Commit Message:
GOB: Add Util::readString()
Changed paths:
engines/gob/util.cpp
engines/gob/util.h
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 6d83745..1add604 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -20,6 +20,10 @@
*
*/
+#include "common/stream.h"
+#include "common/events.h"
+
+#include "graphics/palette.h"
#include "gob/gob.h"
#include "gob/util.h"
@@ -31,10 +35,6 @@
#include "gob/videoplayer.h"
#include "gob/sound/sound.h"
-#include "common/events.h"
-
-#include "graphics/palette.h"
-
namespace Gob {
Util::Util(GobEngine *vm) : _vm(vm) {
@@ -534,6 +534,23 @@ Common::String Util::setExtension(const Common::String &str, const Common::Strin
return str + ext;
}
+Common::String Util::readString(Common::SeekableReadStream &stream, int n) {
+ Common::String str;
+
+ char c;
+ while (n-- > 0) {
+ if ((c = stream.readByte()) == '\0')
+ break;
+
+ str += c;
+ }
+
+ if (n > 0)
+ stream.skip(n);
+
+ return str;
+}
+
/* NOT IMPLEMENTED */
void Util::checkJoystick() {
_vm->_global->_useJoystick = 0;
diff --git a/engines/gob/util.h b/engines/gob/util.h
index a6a689c..7c1e44c 100644
--- a/engines/gob/util.h
+++ b/engines/gob/util.h
@@ -23,8 +23,13 @@
#ifndef GOB_UTIL_H
#define GOB_UTIL_H
+#include "common/str.h"
#include "common/keyboard.h"
+namespace Common {
+ class SeekableReadStream;
+}
+
namespace Gob {
class GobEngine;
@@ -131,6 +136,9 @@ public:
static char *setExtension(char *str, const char *ext);
static Common::String setExtension(const Common::String &str, const Common::String &ext);
+ /** Read a constant-length string out of a stream. */
+ static Common::String readString(Common::SeekableReadStream &stream, int n);
+
Util(GobEngine *vm);
protected:
Commit: cceaa04ef23d766bc666324e69b8fa6fbfa1e39a
https://github.com/scummvm/scummvm/commit/cceaa04ef23d766bc666324e69b8fa6fbfa1e39a
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2011-09-03T09:00:08-07:00
Commit Message:
GOB: Make Util::setExtension() not add an extension to an empty string
Changed paths:
engines/gob/util.cpp
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 1add604..58dfc9c 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -518,6 +518,11 @@ void Util::deleteList(List *list) {
}
char *Util::setExtension(char *str, const char *ext) {
+ assert(str && ext);
+
+ if (str[0] == '\0')
+ return str;
+
char *dot = strrchr(str, '.');
if (dot)
*dot = '\0';
@@ -527,6 +532,9 @@ char *Util::setExtension(char *str, const char *ext) {
}
Common::String Util::setExtension(const Common::String &str, const Common::String &ext) {
+ if (str.empty())
+ return str;
+
const char *dot = strrchr(str.c_str(), '.');
if (dot)
return Common::String(str.c_str(), dot - str.c_str()) + ext;
Commit: 44b83551aa1d6aee8e6e9a643bfade93d1aa5fef
https://github.com/scummvm/scummvm/commit/44b83551aa1d6aee8e6e9a643bfade93d1aa5fef
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2011-09-03T09:00:08-07:00
Commit Message:
GOB: Add the Amiga version of Geisha
Changed paths:
engines/gob/detection_tables.h
diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h
index 4c1ff9a..9c13b4f 100644
--- a/engines/gob/detection_tables.h
+++ b/engines/gob/detection_tables.h
@@ -2515,6 +2515,20 @@ static const GOBGameDescription gameDescriptions[] = {
},
{
{
+ "geisha",
+ "",
+ AD_ENTRY1s("disk1.stk", "e5892f00917c62423e93f5fd9920cf47", 208120),
+ UNK_LANG,
+ kPlatformAmiga,
+ ADGF_NO_FLAGS,
+ GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ },
+ kGameTypeGeisha,
+ kFeaturesEGA,
+ "disk1.stk", "intro.tot", 0
+ },
+ {
+ {
"gob3",
"",
AD_ENTRY1s("intro.stk", "32b0f57f5ae79a9ae97e8011df38af42", 157084),
Commit: 2985f118b802d231aa5ec328c8b61e1419c14e48
https://github.com/scummvm/scummvm/commit/2985f118b802d231aa5ec328c8b61e1419c14e48
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2011-09-03T09:00:09-07:00
Commit Message:
GOB: Add class RXYFile
Handles RXY files, containing relative sprite coordinates.
Used in hardcoded "actiony" parts of gob games, like
Geisha's minigames.
Changed paths:
A engines/gob/rxyfile.cpp
A engines/gob/rxyfile.h
engines/gob/module.mk
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 0300bcc..a026964 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -53,6 +53,7 @@ MODULE_OBJS := \
mult_v2.o \
palanim.o \
resources.o \
+ rxyfile.o \
scenery.o \
scenery_v1.o \
scenery_v2.o \
diff --git a/engines/gob/rxyfile.cpp b/engines/gob/rxyfile.cpp
new file mode 100644
index 0000000..5311eec
--- /dev/null
+++ b/engines/gob/rxyfile.cpp
@@ -0,0 +1,82 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/stream.h"
+
+#include "gob/rxyfile.h"
+
+namespace Gob {
+
+RXYFile::RXYFile(Common::SeekableReadStream &rxy) : _width(0), _height(0) {
+ load(rxy);
+}
+
+RXYFile::~RXYFile() {
+}
+
+uint RXYFile::size() const {
+ return _coords.size();
+}
+
+uint16 RXYFile::getWidth() const {
+ return _width;
+}
+
+uint16 RXYFile::getHeight() const {
+ return _height;
+}
+
+uint16 RXYFile::getRealCount() const {
+ return _realCount;
+}
+
+const RXYFile::Coordinates &RXYFile::operator[](uint i) const {
+ assert(i < _coords.size());
+
+ return _coords[i];
+}
+
+void RXYFile::load(Common::SeekableReadStream &rxy) {
+ if (rxy.size() < 2)
+ return;
+
+ rxy.seek(0);
+
+ _realCount = rxy.readUint16LE();
+
+ uint16 count = (rxy.size() - 2) / 8;
+
+ _coords.resize(count);
+ for (CoordArray::iterator c = _coords.begin(); c != _coords.end(); ++c) {
+ c->left = rxy.readUint16LE();
+ c->right = rxy.readUint16LE();
+ c->top = rxy.readUint16LE();
+ c->bottom = rxy.readUint16LE();
+
+ if (c->left != 0xFFFF) {
+ _width = MAX<uint16>(_width , c->right + 1);
+ _height = MAX<uint16>(_height, c->bottom + 1);
+ }
+ }
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/rxyfile.h b/engines/gob/rxyfile.h
new file mode 100644
index 0000000..828f8b7
--- /dev/null
+++ b/engines/gob/rxyfile.h
@@ -0,0 +1,76 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GOB_RXYFILE_H
+#define GOB_RXYFILE_H
+
+#include "common/system.h"
+#include "common/array.h"
+
+namespace Common {
+ class SeekableReadStream;
+}
+
+namespace Gob {
+
+/** A RXY file, containing relative sprite coordinates.
+ *
+ * Used in hardcoded "actiony" parts of gob games.
+ */
+class RXYFile {
+public:
+ struct Coordinates {
+ uint16 left;
+ uint16 top;
+ uint16 right;
+ uint16 bottom;
+ };
+
+ RXYFile(Common::SeekableReadStream &rxy);
+ ~RXYFile();
+
+ uint size() const;
+
+ uint16 getWidth () const;
+ uint16 getHeight() const;
+
+ uint16 getRealCount() const;
+
+ const Coordinates &operator[](uint i) const;
+
+private:
+ typedef Common::Array<Coordinates> CoordArray;
+
+ CoordArray _coords;
+
+ uint16 _realCount;
+
+ uint16 _width;
+ uint16 _height;
+
+
+ void load(Common::SeekableReadStream &rxy);
+};
+
+} // End of namespace Gob
+
+#endif // GOB_RXYFILE_H
Commit: 37964e8e85137ff7cb3a317c34b6a6210b7564d4
https://github.com/scummvm/scummvm/commit/37964e8e85137ff7cb3a317c34b6a6210b7564d4
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2011-09-03T09:00:09-07:00
Commit Message:
GOB: Add class DECFile
Handles DEC files, describing "decals" (backgrounds).
Used in hardcoded "actiony" parts of gob games, like
Geisha's minigames.
Changed paths:
A engines/gob/decfile.cpp
A engines/gob/decfile.h
engines/gob/module.mk
diff --git a/engines/gob/decfile.cpp b/engines/gob/decfile.cpp
new file mode 100644
index 0000000..f5910f0
--- /dev/null
+++ b/engines/gob/decfile.cpp
@@ -0,0 +1,214 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/str.h"
+#include "common/stream.h"
+#include "common/substream.h"
+
+#include "gob/gob.h"
+#include "gob/util.h"
+#include "gob/dataio.h"
+#include "gob/surface.h"
+#include "gob/video.h"
+#include "gob/rxyfile.h"
+#include "gob/decfile.h"
+
+namespace Gob {
+
+DECFile::Layer::Layer() : surface(0), coordinates(0) {
+}
+
+DECFile::Layer::~Layer() {
+ delete coordinates;
+ delete surface;
+}
+
+
+DECFile::DECFile(GobEngine *vm, const Common::String &fileName,
+ uint16 width, uint16 height, uint8 bpp) : _vm(vm),
+ _width(width), _height(height), _bpp(bpp), _hasPadding(false) {
+
+ _backdrop = new Surface(_width, _height, _bpp);
+
+ Common::SeekableReadStream *dec = _vm->_dataIO->getFile(fileName);
+ if (dec) {
+ Common::SeekableSubReadStreamEndian sub(dec, 0, dec->size(), false, DisposeAfterUse::YES);
+
+ load(sub, fileName);
+ return;
+ }
+
+ // File doesn't exist, try to open the big-endian'd alternate file
+ Common::String alternateFileName = fileName;
+ alternateFileName.setChar('_', 0);
+
+ dec = _vm->_dataIO->getFile(alternateFileName);
+ if (dec) {
+ Common::SeekableSubReadStreamEndian sub(dec, 0, dec->size(), true, DisposeAfterUse::YES);
+
+ // The big endian version pads a few fields to even size
+ _hasPadding = true;
+
+ load(sub, fileName);
+ return;
+ }
+
+ warning("DECFile::DECFile(): No such file \"%s\"", fileName.c_str());
+}
+
+DECFile::~DECFile() {
+ delete _backdrop;
+}
+
+void DECFile::load(Common::SeekableSubReadStreamEndian &dec, const Common::String &fileName) {
+ dec.skip(2); // Unused
+
+ int16 backdropCount = dec.readUint16();
+ int16 layerCount = dec.readUint16();
+
+ // Sanity checks
+ if (backdropCount > 1)
+ warning("DECFile::load(): More than one backdrop (%d) in file \"%s\"",
+ backdropCount, fileName.c_str());
+ if (layerCount < 1)
+ warning("DECFile::load(): Less than one layer (%d) in file \"%s\"",
+ layerCount, fileName.c_str());
+
+ // Load the backdrop
+ if (backdropCount > 0) {
+ loadBackdrop(dec);
+
+ // We only support one backdrop, skip the rest
+ dec.skip((backdropCount - 1) * (13 + (_hasPadding ? 1 : 0)));
+ }
+
+ // Load the layers
+ _layers.resize(MAX(0, layerCount - 1));
+ for (LayerArray::iterator l = _layers.begin(); l != _layers.end(); ++l)
+ loadLayer(*l, dec);
+
+ // Load the backdrop parts
+ if (backdropCount > 0)
+ loadParts(dec);
+}
+
+void DECFile::loadBackdrop(Common::SeekableSubReadStreamEndian &dec) {
+ // Interestingly, DEC files reference "FOO.LBM" instead of "FOO.CMP"
+ Common::String file = Util::setExtension(Util::readString(dec, 13), ".CMP");
+ if (_hasPadding)
+ dec.skip(1);
+
+ if (file.empty() || !_vm->_dataIO->hasFile(file))
+ return;
+
+ _vm->_video->drawPackedSprite(file.c_str(), *_backdrop);
+}
+
+void DECFile::loadLayer(Layer &layer, Common::SeekableSubReadStreamEndian &dec) {
+ Common::String file = Util::readString(dec, 13);
+ if (_hasPadding)
+ dec.skip(1);
+
+ if (file.empty())
+ return;
+
+ Common::String fileRXY = Util::setExtension(file, ".RXY");
+ Common::String fileCMP = Util::setExtension(file, ".CMP");
+ if (!_vm->_dataIO->hasFile(fileRXY) || !_vm->_dataIO->hasFile(fileCMP))
+ return;
+
+ loadLayer(layer, fileRXY, fileCMP);
+}
+
+void DECFile::loadLayer(Layer &layer, const Common::String &fileRXY,
+ const Common::String &fileCMP) {
+
+ Common::SeekableReadStream *dataRXY = _vm->_dataIO->getFile(fileRXY);
+ if (!dataRXY)
+ return;
+
+ layer.coordinates = new RXYFile(*dataRXY);
+ layer.surface = new Surface(_width, layer.coordinates->getHeight(), _bpp);
+
+ _vm->_video->drawPackedSprite(fileCMP.c_str(), *layer.surface);
+}
+
+void DECFile::loadParts(Common::SeekableSubReadStreamEndian &dec) {
+ dec.skip(13); // Name
+ if (_hasPadding)
+ dec.skip(1);
+
+ dec.skip(13); // File?
+ if (_hasPadding)
+ dec.skip(1);
+
+ uint16 partCount = dec.readUint16();
+
+ _parts.resize(partCount);
+ for (PartArray::iterator p = _parts.begin(); p != _parts.end(); ++p)
+ loadPart(*p, dec);
+}
+
+void DECFile::loadPart(Part &part, Common::SeekableSubReadStreamEndian &dec) {
+ part.layer = dec.readByte() - 1;
+ part.part = dec.readByte();
+
+ dec.skip(1); // Unknown
+
+ part.x = dec.readUint16();
+ part.y = dec.readUint16();
+
+ part.transp = dec.readByte() != 0;
+}
+
+void DECFile::draw(Surface &dest) const {
+ drawBackdrop(dest);
+
+ for (PartArray::const_iterator p = _parts.begin(); p != _parts.end(); ++p)
+ drawLayer(dest, p->layer, p->part, p->x, p->y, p->transp ? 0 : -1);
+}
+
+void DECFile::drawBackdrop(Surface &dest) const {
+ dest.blit(*_backdrop);
+}
+
+void DECFile::drawLayer(Surface &dest, uint16 layer, uint16 part,
+ uint16 x, uint16 y, int32 transp) const {
+
+ if (layer >= _layers.size())
+ return;
+
+ const Layer &l = _layers[layer];
+ if (!l.surface || !l.coordinates)
+ return;
+
+ if (part >= l.coordinates->size())
+ return;
+
+ const RXYFile::Coordinates &c = (*l.coordinates)[part];
+ if (c.left == 0xFFFF)
+ return;
+
+ dest.blit(*l.surface, c.left, c.top, c.right, c.bottom, x, y, transp);
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/decfile.h b/engines/gob/decfile.h
new file mode 100644
index 0000000..31d9018
--- /dev/null
+++ b/engines/gob/decfile.h
@@ -0,0 +1,111 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GOB_DECFILE_H
+#define GOB_DECFILE_H
+
+#include "common/system.h"
+
+namespace Common {
+ class String;
+ class SeekableSubReadStreamEndian;
+}
+
+namespace Gob {
+
+class GobEngine;
+class Surface;
+class RXYFile;
+
+/** A DEC file, describing a "decal" (background).
+ *
+ * Used in hardcoded "actiony" parts of gob games.
+ * The principle is similar to a Static in Scenery (see scenery.cpp), but
+ * instead of referencing indices in the sprites array, DECs reference sprites
+ * directly by filename.
+ */
+class DECFile {
+public:
+ DECFile(GobEngine *vm, const Common::String &fileName,
+ uint16 width, uint16 height, uint8 bpp = 1);
+ ~DECFile();
+
+ /** Draw the background, including all default layer parts. */
+ void draw(Surface &dest) const;
+
+ /** Explicitly draw the backdrop. */
+ void drawBackdrop(Surface &dest) const;
+
+ /** Explicitly draw a layer part. */
+ void drawLayer(Surface &dest, uint16 layer, uint16 part,
+ uint16 x, uint16 y, int32 transp = -1) const;
+
+private:
+ struct Layer {
+ Surface *surface; ///< The surface containing the layer sprite.
+ RXYFile *coordinates; ///< The coordinates describing the layer sprite parts.
+
+ Layer();
+ ~Layer();
+ };
+
+ struct Part {
+ uint8 layer;
+ uint8 part;
+
+ uint16 x;
+ uint16 y;
+ bool transp;
+ };
+
+ typedef Common::Array<Layer> LayerArray;
+ typedef Common::Array<Part> PartArray;
+
+ GobEngine *_vm;
+
+ uint16 _width;
+ uint16 _height;
+ uint8 _bpp;
+
+ byte _hasPadding;
+
+ Surface *_backdrop;
+
+ LayerArray _layers;
+ PartArray _parts;
+
+
+ void load(Common::SeekableSubReadStreamEndian &dec, const Common::String &fileName);
+
+ void loadBackdrop(Common::SeekableSubReadStreamEndian &dec);
+
+ void loadLayer(Layer &layer, Common::SeekableSubReadStreamEndian &dec);
+ void loadLayer(Layer &layer, const Common::String &fileRXY,
+ const Common::String &fileCMP);
+
+ void loadParts(Common::SeekableSubReadStreamEndian &dec);
+ void loadPart(Part &part, Common::SeekableSubReadStreamEndian &dec);
+};
+
+} // End of namespace Gob
+
+#endif // GOB_DECFILE_H
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index a026964..0fdbdf9 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
dataio.o \
databases.o \
dbase.o \
+ decfile.o \
detection.o \
draw.o \
draw_v1.o \
Commit: a4f42017d7a43ae0e8cd7c61d6af746a19c410f5
https://github.com/scummvm/scummvm/commit/a4f42017d7a43ae0e8cd7c61d6af746a19c410f5
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2011-09-03T09:00:09-07:00
Commit Message:
GOB: Add class ANIFile
Handles ANI files, describing animations.
Used in hardcoded "actiony" parts of gob games, like
Geisha's minigames.
Changed paths:
A engines/gob/anifile.cpp
A engines/gob/anifile.h
engines/gob/module.mk
diff --git a/engines/gob/anifile.cpp b/engines/gob/anifile.cpp
new file mode 100644
index 0000000..1a905f1
--- /dev/null
+++ b/engines/gob/anifile.cpp
@@ -0,0 +1,326 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/stream.h"
+#include "common/substream.h"
+
+#include "gob/gob.h"
+#include "gob/util.h"
+#include "gob/dataio.h"
+#include "gob/surface.h"
+#include "gob/video.h"
+#include "gob/anifile.h"
+
+namespace Gob {
+
+ANIFile::Layer::Layer() : surface(0), coordinates(0) {
+}
+
+ANIFile::Layer::~Layer() {
+ delete coordinates;
+ delete surface;
+}
+
+
+ANIFile::ANIFile(GobEngine *vm, const Common::String &fileName,
+ uint16 width, uint8 bpp) : _vm(vm),
+ _width(width), _bpp(bpp), _hasPadding(false) {
+
+ Common::SeekableReadStream *ani = _vm->_dataIO->getFile(fileName);
+ if (ani) {
+ Common::SeekableSubReadStreamEndian sub(ani, 0, ani->size(), false, DisposeAfterUse::YES);
+
+ load(sub, fileName);
+ return;
+ }
+
+ // File doesn't exist, try to open the big-endian'd alternate file
+ Common::String alternateFileName = fileName;
+ alternateFileName.setChar('_', 0);
+
+ ani = _vm->_dataIO->getFile(alternateFileName);
+ if (ani) {
+ Common::SeekableSubReadStreamEndian sub(ani, 0, ani->size(), true, DisposeAfterUse::YES);
+
+ // The big endian version pads a few fields to even size
+ _hasPadding = true;
+
+ load(sub, fileName);
+ return;
+ }
+
+ warning("ANIFile::ANIFile(): No such file \"%s\"", fileName.c_str());
+}
+
+ANIFile::~ANIFile() {
+}
+
+void ANIFile::load(Common::SeekableSubReadStreamEndian &ani, const Common::String &fileName) {
+ ani.skip(2); // Unused
+
+ uint16 animationCount = ani.readUint16();
+ uint16 layerCount = ani.readUint16();
+
+ if (layerCount < 1)
+ warning("ANIFile::load(): Less than one layer (%d) in file \"%s\"",
+ layerCount, fileName.c_str());
+
+ // Load the layers
+ if (layerCount > 0) {
+ ani.skip(13); // The first layer is ignored?
+ if (_hasPadding)
+ ani.skip(1);
+
+ _layers.resize(layerCount - 1);
+ for (LayerArray::iterator l = _layers.begin(); l != _layers.end(); ++l)
+ loadLayer(*l, ani);
+ }
+
+ _maxWidth = 0;
+ _maxHeight = 0;
+
+ // Load the animations
+ _animations.resize(animationCount);
+ _frames.resize(animationCount);
+
+ for (uint16 animation = 0; animation < animationCount; animation++) {
+ loadAnimation(_animations[animation], _frames[animation], ani);
+
+ _maxWidth = MAX<uint16>(_maxWidth , _animations[animation].width);
+ _maxHeight = MAX<uint16>(_maxHeight, _animations[animation].height);
+ }
+}
+
+void ANIFile::loadAnimation(Animation &animation, FrameArray &frames,
+ Common::SeekableSubReadStreamEndian &ani) {
+
+ // Animation properties
+
+ animation.name = Util::readString(ani, 13);
+ if (_hasPadding)
+ ani.skip(1);
+
+ ani.skip(13); // The name a second time?!?
+ if (_hasPadding)
+ ani.skip(1);
+
+ ani.skip(2); // Unknown
+
+ animation.x = (int16) ani.readUint16();
+ animation.y = (int16) ani.readUint16();
+ animation.deltaX = (int16) ani.readUint16();
+ animation.deltaY = (int16) ani.readUint16();
+
+ animation.transp = ani.readByte() != 0;
+
+ if (_hasPadding)
+ ani.skip(1);
+
+ uint16 frameCount = ani.readUint16();
+
+ // Load the frames
+
+ frames.resize(MAX<uint16>(1, frameCount));
+ loadFrames(frames, ani);
+
+ animation.frameCount = frames.size();
+
+ animation.width = 0;
+ animation.height = 0;
+
+ // Calculate the areas of each frame
+
+ animation.frameAreas.resize(animation.frameCount);
+ for (uint16 i = 0; i < animation.frameCount; i++) {
+ const ChunkList &frame = frames[i];
+ FrameArea &area = animation.frameAreas[i];
+
+ area.left = area.top = 0x7FFF;
+ area.right = area.bottom = -0x7FFF;
+
+ for (ChunkList::const_iterator c = frame.begin(); c != frame.end(); c++) {
+ const Layer *layer;
+ const RXYFile::Coordinates *coords;
+
+ if (!getPart(c->layer, c->part, layer, coords))
+ continue;
+
+ const uint16 width = coords->right - coords->left + 1;
+ const uint16 height = coords->bottom - coords->top + 1;
+
+ const uint16 l = c->x;
+ const uint16 t = c->y;
+ const uint16 r = l + width - 1;
+ const uint16 b = t + height - 1;
+
+ area.left = MIN<int16>(area.left , l);
+ area.top = MIN<int16>(area.top , t);
+ area.right = MAX<int16>(area.right , r);
+ area.bottom = MAX<int16>(area.bottom, b);
+ }
+
+ if ((area.left <= area.right) && (area.top <= area.bottom)) {
+ animation.width = MAX<uint16>(animation.width , area.right - area.left + 1);
+ animation.height = MAX<uint16>(animation.height, area.bottom - area.top + 1);
+ }
+ }
+}
+
+void ANIFile::loadFrames(FrameArray &frames, Common::SeekableSubReadStreamEndian &ani) {
+ uint32 curFrame = 0;
+
+ bool end = false;
+ while (!end) {
+ frames[curFrame].push_back(AnimationChunk());
+ AnimationChunk &chunk = frames[curFrame].back();
+
+ uint8 layerFlags = ani.readByte();
+
+ // Chunk properties
+ chunk.layer = (layerFlags & 0x0F) - 1;
+ chunk.part = ani.readByte();
+ chunk.x = (int8) ani.readByte();
+ chunk.y = (int8) ani.readByte();
+
+ // X multiplier/offset
+ int16 xOff = ((layerFlags & 0xC0) >> 6) << 7;
+ if (chunk.x >= 0)
+ chunk.x += xOff;
+ else
+ chunk.x -= xOff;
+
+ // Y multiplier/offset
+ int16 yOff = ((layerFlags & 0x30) >> 4) << 7;
+ if (chunk.y >= 0)
+ chunk.y += yOff;
+ else
+ chunk.y -= yOff;
+
+ uint8 multiPart = ani.readByte();
+ if (multiPart == 0xFF) // No more frames in this animation
+ end = true;
+ else if (multiPart != 0x01) // No more chunks in this frame
+ curFrame++;
+
+ // Shouldn't happen, but just to be safe
+ if (curFrame >= frames.size())
+ frames.resize(curFrame + 1);
+
+ if (_hasPadding)
+ ani.skip(1);
+
+ if (ani.eos() || ani.err())
+ error("ANIFile::loadFrames(): Read error");
+ }
+}
+
+void ANIFile::loadLayer(Layer &layer, Common::SeekableSubReadStreamEndian &ani) {
+ Common::String file = Util::readString(ani, 13);
+ if (_hasPadding)
+ ani.skip(1);
+
+ if (file.empty())
+ return;
+
+ Common::String fileRXY = Util::setExtension(file, ".RXY");
+ Common::String fileCMP = Util::setExtension(file, ".CMP");
+ if (!_vm->_dataIO->hasFile(fileRXY) || !_vm->_dataIO->hasFile(fileCMP))
+ return;
+
+ loadLayer(layer, fileRXY, fileCMP);
+}
+
+void ANIFile::loadLayer(Layer &layer, const Common::String &fileRXY,
+ const Common::String &fileCMP) {
+
+ Common::SeekableReadStream *dataRXY = _vm->_dataIO->getFile(fileRXY);
+ if (!dataRXY)
+ return;
+
+ layer.coordinates = new RXYFile(*dataRXY);
+ layer.surface = new Surface(_width, layer.coordinates->getHeight(), _bpp);
+
+ _vm->_video->drawPackedSprite(fileCMP.c_str(), *layer.surface);
+}
+
+uint16 ANIFile::getAnimationCount() const {
+ return _animations.size();
+}
+
+void ANIFile::getMaxSize(uint16 &width, uint16 &height) const {
+ width = _maxWidth;
+ height = _maxHeight;
+}
+
+const ANIFile::Animation &ANIFile::getAnimationInfo(uint16 animation) const {
+ assert(animation < _animations.size());
+
+ return _animations[animation];
+}
+
+bool ANIFile::getPart(uint16 layer, uint16 part,
+ const Layer *&l, const RXYFile::Coordinates *&c) const {
+
+ if (layer >= _layers.size())
+ return false;
+
+ l = &_layers[layer];
+ if (!l->surface || !l->coordinates)
+ return false;
+
+ if (part >= l->coordinates->size())
+ return false;
+
+ c = &(*l->coordinates)[part];
+ if (c->left == 0xFFFF)
+ return false;
+
+ return true;
+}
+
+void ANIFile::draw(Surface &dest, uint16 animation, uint16 frame, int16 x, int16 y) const {
+ if (animation >= _animations.size())
+ return;
+
+ const Animation &anim = _animations[animation];
+ if (frame >= anim.frameCount)
+ return;
+
+ const ChunkList &chunks = _frames[animation][frame];
+
+ for (ChunkList::const_iterator c = chunks.begin(); c != chunks.end(); ++c)
+ drawLayer(dest, c->layer, c->part, x + c->x, y + c->y, anim.transp ? 0 : -1);
+}
+
+void ANIFile::drawLayer(Surface &dest, uint16 layer, uint16 part,
+ int16 x, int16 y, int32 transp) const {
+
+ const Layer *l;
+ const RXYFile::Coordinates *c;
+
+ if (!getPart(layer, part, l, c))
+ return;
+
+ dest.blit(*l->surface, c->left, c->top, c->right, c->bottom, x, y, transp);
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/anifile.h b/engines/gob/anifile.h
new file mode 100644
index 0000000..1e10da6
--- /dev/null
+++ b/engines/gob/anifile.h
@@ -0,0 +1,161 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GOB_ANIFILE_H
+#define GOB_ANIFILE_H
+
+#include "common/system.h"
+#include "common/str.h"
+#include "common/array.h"
+#include "common/list.h"
+
+#include "gob/rxyfile.h"
+
+namespace Common {
+ class SeekableSubReadStreamEndian;
+}
+
+namespace Gob {
+
+class GobEngine;
+class Surface;
+
+/** An ANI file, describing an animation.
+ *
+ * Used in hardcoded "actiony" parts of gob games.
+ * The principle is similar to an Anim in Scenery (see scenery.cpp), but
+ * instead of referencing indices in the sprites array, ANIs reference sprites
+ * directly by filename.
+ */
+class ANIFile {
+public:
+ /** The relative area a frame sprite occupies. */
+ struct FrameArea {
+ int16 left;
+ int16 top;
+ int16 right;
+ int16 bottom;
+ };
+
+ /** An animation within an ANI file. */
+ struct Animation {
+ Common::String name; ///< The name of the animation.
+
+ uint16 frameCount; ///< The number of frames in this animation.
+
+ int16 x; ///< The default x position for this animation.
+ int16 y; ///< The default y position for this animation.
+ bool transp; ///< Should the animation frames be drawn with transparency?
+
+ int16 deltaX; ///< # of pixels to advance in X direction after each cycle.
+ int16 deltaY; ///< # of pixels to advance in Y direction after each cycle.
+
+ /** The relative area each frame sprite occupies. */
+ Common::Array<FrameArea> frameAreas;
+
+ uint16 width; ///< The maximum width of this animation's frames.
+ uint16 height; ///< The maximum height of this animation's frames.
+ };
+
+
+ ANIFile(GobEngine *vm, const Common::String &fileName,
+ uint16 width = 320, uint8 bpp = 1);
+ ~ANIFile();
+
+ /** Return the number of animations in this ANI file. */
+ uint16 getAnimationCount() const;
+
+ /** Return the maximum size of all animation frames. */
+ void getMaxSize(uint16 &width, uint16 &height) const;
+
+ /** Get this animation's properties. */
+ const Animation &getAnimationInfo(uint16 animation) const;
+
+ /** Draw an animation frame. */
+ void draw(Surface &dest, uint16 animation, uint16 frame, int16 x, int16 y) const;
+
+private:
+ /** A sprite layer. */
+ struct Layer {
+ Surface *surface; ///< The surface containing the layer sprite.
+ RXYFile *coordinates; ///< The coordinates describing the layer sprite parts.
+
+ Layer();
+ ~Layer();
+ };
+
+ typedef Common::Array<Layer> LayerArray;
+ typedef Common::Array<Animation> AnimationArray;
+
+ /** A "chunk" of an animation frame. */
+ struct AnimationChunk {
+ int16 x; ///< The relative x offset of this chunk.
+ int16 y; ///< The relative y offset of this chunk.
+
+ uint16 layer; ///< The layer the chunk's sprite is on.
+ uint16 part; ///< The layer part the chunk's sprite is.
+ };
+
+ typedef Common::List<AnimationChunk> ChunkList;
+ typedef Common::Array<ChunkList> FrameArray;
+ typedef Common::Array<FrameArray> AnimationFrameArray;
+
+
+ GobEngine *_vm;
+
+ uint16 _width; ///< The width of a sprite layer.
+ uint8 _bpp; ///< Number of bytes per pixel in a sprite layer.
+
+ byte _hasPadding;
+
+ LayerArray _layers; ///< The animation sprite layers.
+ AnimationArray _animations; ///< The animations.
+ AnimationFrameArray _frames; ///< The animation frames.
+
+ uint16 _maxWidth;
+ uint16 _maxHeight;
+
+
+ // Loading helpers
+
+ void load(Common::SeekableSubReadStreamEndian &ani, const Common::String &fileName);
+
+ void loadLayer(Layer &layer, Common::SeekableSubReadStreamEndian &ani);
+ void loadLayer(Layer &layer, const Common::String &fileRXY,
+ const Common::String &fileCMP);
+
+ void loadAnimation(Animation &animation, FrameArray &frames,
+ Common::SeekableSubReadStreamEndian &ani);
+ void loadFrames(FrameArray &frames, Common::SeekableSubReadStreamEndian &ani);
+
+ // Drawing helpers
+
+ bool getPart(uint16 layer, uint16 part,
+ const Layer *&l, const RXYFile::Coordinates *&c) const;
+
+ void drawLayer(Surface &dest, uint16 layer, uint16 part,
+ int16 x, int16 y, int32 transp) const;
+};
+
+} // End of namespace Gob
+
+#endif // GOB_ANIFILE_H
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 0fdbdf9..a2a78bc 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -1,6 +1,7 @@
MODULE := engines/gob
MODULE_OBJS := \
+ anifile.o \
console.o \
dataio.o \
databases.o \
Commit: 220fc2b59307734a26057fa6446ed13fa2c543a1
https://github.com/scummvm/scummvm/commit/220fc2b59307734a26057fa6446ed13fa2c543a1
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2011-09-03T09:00:09-07:00
Commit Message:
GOB: Add class ANIObject
Controls an animation stored within an ANI file.
Changed paths:
A engines/gob/aniobject.cpp
A engines/gob/aniobject.h
engines/gob/module.mk
diff --git a/engines/gob/aniobject.cpp b/engines/gob/aniobject.cpp
new file mode 100644
index 0000000..c6a9234
--- /dev/null
+++ b/engines/gob/aniobject.cpp
@@ -0,0 +1,185 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "gob/surface.h"
+#include "gob/anifile.h"
+#include "gob/aniobject.h"
+
+namespace Gob {
+
+ANIObject::ANIObject(const ANIFile &ani) : _ani(&ani), _visible(false),
+ _x(0), _y(0), _background(0), _drawn(false) {
+
+ setAnimation(0);
+ setPosition();
+}
+
+ANIObject::~ANIObject() {
+ delete _background;
+}
+
+void ANIObject::setVisible(bool visible) {
+ _visible = visible;
+}
+
+bool ANIObject::isVisible() const {
+ return _visible;
+}
+
+void ANIObject::setAnimation(uint16 animation) {
+ _animation = animation;
+ _frame = 0;
+}
+
+void ANIObject::setPosition() {
+ if (_animation >= _ani->getAnimationCount())
+ return;
+
+ const ANIFile::Animation &animation = _ani->getAnimationInfo(_animation);
+
+ _x = animation.x;
+ _y = animation.y;
+}
+
+void ANIObject::setPosition(int16 x, int16 y) {
+ _x = x;
+ _y = y;
+}
+
+void ANIObject::getPosition(int16 &x, int16 &y) const {
+ x = _x;
+ y = _y;
+}
+
+void ANIObject::getFramePosition(int16 &x, int16 &y) const {
+ if (_animation >= _ani->getAnimationCount())
+ return;
+
+ const ANIFile::Animation &animation = _ani->getAnimationInfo(_animation);
+ if (_frame >= animation.frameCount)
+ return;
+
+ x = _x + animation.frameAreas[_frame].left;
+ y = _y + animation.frameAreas[_frame].top;
+}
+
+void ANIObject::getFrameSize(int16 &width, int16 &height) const {
+ if (_animation >= _ani->getAnimationCount())
+ return;
+
+ const ANIFile::Animation &animation = _ani->getAnimationInfo(_animation);
+ if (_frame >= animation.frameCount)
+ return;
+
+ width = animation.frameAreas[_frame].right - animation.frameAreas[_frame].left + 1;
+ height = animation.frameAreas[_frame].bottom - animation.frameAreas[_frame].top + 1;
+}
+
+void ANIObject::draw(Surface &dest, int16 &left, int16 &top,
+ int16 &right, int16 &bottom) {
+
+ if (!_visible)
+ return;
+
+ if (!_background) {
+ uint16 width, height;
+
+ _ani->getMaxSize(width, height);
+
+ _background = new Surface(width, height, dest.getBPP());
+ }
+
+ const ANIFile::Animation &animation = _ani->getAnimationInfo(_animation);
+ if (_frame >= animation.frameCount)
+ return;
+
+ const ANIFile::FrameArea &area = animation.frameAreas[_frame];
+
+ _backgroundLeft = CLIP<int16>(area.left + _x, 0, dest.getWidth () - 1);
+ _backgroundTop = CLIP<int16>(area.top + _y, 0, dest.getHeight() - 1);
+ _backgroundRight = CLIP<int16>(area.right + _x, 0, dest.getWidth () - 1);
+ _backgroundBottom = CLIP<int16>(area.bottom + _y, 0, dest.getHeight() - 1);
+
+ _background->blit(dest, _backgroundLeft , _backgroundTop,
+ _backgroundRight, _backgroundBottom, 0, 0);
+
+ _ani->draw(dest, _animation, _frame, _x, _y);
+
+ _drawn = true;
+
+ left = _backgroundLeft;
+ top = _backgroundTop;
+ right = _backgroundRight;
+ bottom = _backgroundBottom;
+}
+
+void ANIObject::clear(Surface &dest, int16 &left, int16 &top,
+ int16 &right, int16 &bottom) {
+
+ if (!_drawn)
+ return;
+
+ const int16 bgRight = _backgroundRight - _backgroundLeft;
+ const int16 bgBottom = _backgroundBottom - _backgroundTop;
+
+ dest.blit(*_background, 0, 0, bgRight, bgBottom, _backgroundLeft, _backgroundTop);
+
+ _drawn = false;
+
+ left = _backgroundLeft;
+ top = _backgroundTop;
+ right = _backgroundRight;
+ bottom = _backgroundBottom;
+}
+
+void ANIObject::advance() {
+ if (_animation >= _ani->getAnimationCount())
+ return;
+
+ const ANIFile::Animation &animation = _ani->getAnimationInfo(_animation);
+
+ _frame = (_frame + 1) % animation.frameCount;
+
+ if (_frame == 0) {
+ _x += animation.deltaX;
+ _y += animation.deltaY;
+ }
+}
+
+uint16 ANIObject::getAnimation() const {
+ return _animation;
+}
+
+uint16 ANIObject::getFrame() const {
+ return _frame;
+}
+
+bool ANIObject::lastFrame() const {
+ if (_animation >= _ani->getAnimationCount())
+ return true;
+
+ const ANIFile::Animation &animation = _ani->getAnimationInfo(_animation);
+
+ return (_frame + 1) >= animation.frameCount;
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h
new file mode 100644
index 0000000..357c2a9
--- /dev/null
+++ b/engines/gob/aniobject.h
@@ -0,0 +1,99 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GOB_ANIOBJECT_H
+#define GOB_ANIOBJECT_H
+
+#include "common/system.h"
+
+namespace Gob {
+
+class ANIFile;
+class Surface;
+
+/** An ANI object, controlling an animation within an ANI file. */
+class ANIObject {
+public:
+ ANIObject(const ANIFile &ani);
+ virtual ~ANIObject();
+
+ /** Make the object visible/invisible. */
+ void setVisible(bool visible);
+
+ /** Is the object currently visible? */
+ bool isVisible() const;
+
+ /** Set the current position to the animation's default. */
+ void setPosition();
+ /** Set the current position. */
+ void setPosition(int16 x, int16 y);
+
+ /** Return the current position. */
+ void getPosition(int16 &x, int16 &y) const;
+
+ /** Return the current frame position. */
+ void getFramePosition(int16 &x, int16 &y) const;
+ /** Return the current frame size. */
+ void getFrameSize(int16 &width, int16 &height) const;
+
+ /** Set the animation number. */
+ void setAnimation(uint16 animation);
+
+ /** Return the current animation number. */
+ uint16 getAnimation() const;
+ /** Return the current frame number. */
+ uint16 getFrame() const;
+
+ /** Is this the last frame within this animation cycle? */
+ bool lastFrame() const;
+
+ /** Draw the current frame onto the surface and return the affected rectangle. */
+ void draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom);
+ /** Draw the current frame from the surface and return the affected rectangle. */
+ void clear(Surface &dest, int16 &left , int16 &top, int16 &right, int16 &bottom);
+
+ /** Advance the animation to the next frame. */
+ virtual void advance();
+
+private:
+ const ANIFile *_ani; ///< The managed ANI file.
+
+ uint16 _animation; ///< The current animation number
+ uint16 _frame; ///< The current frame.
+
+ bool _visible; ///< Is the object currently visible?
+
+ int16 _x; ///< The current X position.
+ int16 _y; ///< The current Y position.
+
+ Surface *_background; ///< The saved background.
+ bool _drawn; ///< Was the animation drawn?
+
+ int16 _backgroundLeft; ///< The left position of the saved background.
+ int16 _backgroundTop; ///< The top of the saved background.
+ int16 _backgroundRight; ///< The right position of the saved background.
+ int16 _backgroundBottom; ///< The bottom position of the saved background.
+};
+
+} // End of namespace Gob
+
+#endif // GOB_ANIOBJECT_H
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index a2a78bc..d451e25 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/gob
MODULE_OBJS := \
anifile.o \
+ aniobject.o \
console.o \
dataio.o \
databases.o \
Commit: dbb70e3d6f3b6ce5ff0497dbded420783edb3256
https://github.com/scummvm/scummvm/commit/dbb70e3d6f3b6ce5ff0497dbded420783edb3256
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2011-09-03T09:00:09-07:00
Commit Message:
GOB: Add class Geisha::EvilFish
An "evil" fish in Geisha's "Diving" minigame.
Changed paths:
A engines/gob/minigames/geisha/evilfish.cpp
A engines/gob/minigames/geisha/evilfish.h
engines/gob/module.mk
diff --git a/engines/gob/minigames/geisha/evilfish.cpp b/engines/gob/minigames/geisha/evilfish.cpp
new file mode 100644
index 0000000..e2672d7
--- /dev/null
+++ b/engines/gob/minigames/geisha/evilfish.cpp
@@ -0,0 +1,163 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "gob/minigames/geisha/evilfish.h"
+
+namespace Gob {
+
+namespace Geisha {
+
+EvilFish::EvilFish(const ANIFile &ani, uint16 screenWidth,
+ uint16 animSwimLeft, uint16 animSwimRight,
+ uint16 animTurnLeft, uint16 animTurnRight, uint16 animDie) :
+ ANIObject(ani), _screenWidth(screenWidth),
+ _animSwimLeft(animSwimLeft), _animSwimRight(animSwimRight),
+ _animTurnLeft(animTurnLeft), _animTurnRight(animTurnRight), _animDie(animDie),
+ _shouldLeave(false), _state(kStateNone) {
+
+}
+
+EvilFish::~EvilFish() {
+}
+
+bool EvilFish::isIn(int16 x, int16 y) const {
+ int16 frameX, frameY, frameWidth, frameHeight;
+ getFramePosition(frameX, frameY);
+ getFrameSize(frameWidth, frameHeight);
+
+ if ((x < frameX) || (y < frameY))
+ return false;
+ if ((x > (frameX + frameWidth)) || (y > (frameY + frameHeight)))
+ return false;
+
+ return true;
+}
+
+void EvilFish::enter(Direction from, int16 y) {
+ _shouldLeave = false;
+
+ bool left = from == kDirectionLeft;
+
+ setAnimation(left ? _animSwimLeft : _animSwimRight);
+
+ int16 width, height;
+ getFrameSize(width, height);
+
+ setPosition(left ? -width : _screenWidth, y);
+ setVisible(true);
+
+ _state = left ? kStateSwimLeft : kStateSwimRight;
+}
+
+void EvilFish::leave() {
+ if (_state == kStateNone)
+ return;
+
+ _shouldLeave = true;
+}
+
+void EvilFish::die() {
+ if ((_state == kStateNone) || (_state == kStateDie))
+ return;
+
+ int16 x, y;
+ getFramePosition(x, y);
+
+ setAnimation(_animDie);
+ setPosition(x, y);
+
+ _state = kStateDie;
+}
+
+void EvilFish::advance() {
+ if (_state == kStateNone)
+ return;
+
+ bool wasLastFrame = lastFrame();
+
+ ANIObject::advance();
+
+ int16 x, y, width, height;
+ getFramePosition(x, y);
+ getFrameSize(width, height);
+
+ switch (_state) {
+ case kStateNone:
+ break;
+
+ case kStateSwimLeft:
+ if (!_shouldLeave && (x >= _screenWidth - width)) {
+ setAnimation(_animTurnRight);
+ setPosition(x, y);
+ _state = kStateTurnRight;
+ }
+
+ if (_shouldLeave && (x >= _screenWidth)) {
+ setVisible(false);
+
+ _shouldLeave = false;
+ _state = kStateNone;
+ }
+ break;
+
+ case kStateSwimRight:
+ if (!_shouldLeave && (x <= 0)) {
+ setAnimation(_animTurnLeft);
+ setPosition(x, y);
+ _state = kStateTurnLeft;
+ }
+
+ if (_shouldLeave && (x < -width)) {
+ setVisible(false);
+
+ _shouldLeave = false;
+ _state = kStateNone;
+ }
+ break;
+
+ case kStateTurnLeft:
+ if (wasLastFrame) {
+ setAnimation(_animSwimLeft);
+ _state = kStateSwimLeft;
+ }
+ break;
+
+ case kStateTurnRight:
+ if (wasLastFrame) {
+ setAnimation(_animSwimRight);
+ _state = kStateSwimRight;
+ }
+ break;
+
+ case kStateDie:
+ if (wasLastFrame) {
+ setVisible(false);
+
+ _state = kStateNone;
+ }
+ break;
+ }
+}
+
+} // End of namespace Geisha
+
+} // End of namespace Gob
diff --git a/engines/gob/minigames/geisha/evilfish.h b/engines/gob/minigames/geisha/evilfish.h
new file mode 100644
index 0000000..9144cef
--- /dev/null
+++ b/engines/gob/minigames/geisha/evilfish.h
@@ -0,0 +1,86 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GOB_MINIGAMES_GEISHA_EVILFISH_H
+#define GOB_MINIGAMES_GEISHA_EVILFISH_H
+
+#include "gob/aniobject.h"
+
+namespace Gob {
+
+namespace Geisha {
+
+/** An "evil" fish in Geisha's "Diving" minigame. */
+class EvilFish : public ANIObject {
+public:
+ enum Direction {
+ kDirectionLeft,
+ kDirectionRight
+ };
+
+ EvilFish(const ANIFile &ani, uint16 screenWidth,
+ uint16 animSwimLeft, uint16 animSwimRight,
+ uint16 animTurnLeft, uint16 animTurnRight, uint16 animDie);
+ ~EvilFish();
+
+ /** Are there coordinates within the fish's sprite? */
+ bool isIn(int16 x, int16 y) const;
+
+ /** Enter from this direction / screen edge. */
+ void enter(Direction from, int16 y);
+ /** Leave the screen in the current direction. */
+ void leave();
+
+ /** Kill the fish. */
+ void die();
+
+ /** Advance the animation to the next frame. */
+ void advance();
+
+private:
+ enum State {
+ kStateNone,
+ kStateSwimLeft,
+ kStateSwimRight,
+ kStateTurnLeft,
+ kStateTurnRight,
+ kStateDie
+ };
+
+ uint16 _screenWidth;
+
+ uint16 _animSwimLeft;
+ uint16 _animSwimRight;
+ uint16 _animTurnLeft;
+ uint16 _animTurnRight;
+ uint16 _animDie;
+
+ bool _shouldLeave;
+
+ State _state;
+};
+
+} // End of namespace Geisha
+
+} // End of namespace Gob
+
+#endif // GOB_MINIGAMES_GEISHA_EVILFISH_H
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index d451e25..0ea4f26 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -73,6 +73,7 @@ MODULE_OBJS := \
demos/demoplayer.o \
demos/scnplayer.o \
demos/batplayer.o \
+ minigames/geisha/evilfish.o \
save/savefile.o \
save/savehandler.o \
save/saveload.o \
Commit: 26dd2f5f603b10b3b54664b6589c8feb6c4f7b82
https://github.com/scummvm/scummvm/commit/26dd2f5f603b10b3b54664b6589c8feb6c4f7b82
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2011-09-03T09:00:09-07:00
Commit Message:
GOB: Move keyPressed() to Util
Changed paths:
engines/gob/inter.h
engines/gob/inter_geisha.cpp
engines/gob/util.cpp
engines/gob/util.h
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index c84cc38..d1c28fc 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -362,8 +362,6 @@ protected:
void oGeisha_caress2(OpGobParams ¶ms);
int16 loadSound(int16 slot);
-
- bool keyPressed();
};
class Inter_v2 : public Inter_v1 {
diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp
index 6c3e97c..d72dd79 100644
--- a/engines/gob/inter_geisha.cpp
+++ b/engines/gob/inter_geisha.cpp
@@ -82,18 +82,6 @@ void Inter_Geisha::oGeisha_loadCursor(OpFuncParams ¶ms) {
o1_loadCursor(params);
}
-bool Inter_Geisha::keyPressed() {
- int16 key = _vm->_util->checkKey();
- if (key)
- return true;
-
- int16 x, y;
- MouseButtons buttons;
-
- _vm->_util->getMouseState(&x, &y, &buttons);
- return buttons != kMouseButtonsNone;
-}
-
struct TOTTransition {
const char *to;
const char *from;
@@ -134,7 +122,7 @@ void Inter_Geisha::oGeisha_loadTot(OpFuncParams ¶ms) {
}
if (needWait)
- while (!keyPressed())
+ while (!_vm->_util->keyPressed())
_vm->_util->longDelay(1);
}
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 58dfc9c..7f9c613 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -257,6 +257,18 @@ bool Util::checkKey(int16 &key) {
return true;
}
+bool Util::keyPressed() {
+ int16 key = checkKey();
+ if (key)
+ return true;
+
+ int16 x, y;
+ MouseButtons buttons;
+
+ getMouseState(&x, &y, &buttons);
+ return buttons != kMouseButtonsNone;
+}
+
void Util::getMouseState(int16 *pX, int16 *pY, MouseButtons *pButtons) {
Common::Point mouse = g_system->getEventManager()->getMousePos();
*pX = mouse.x + _vm->_video->_scrollOffsetX - _vm->_video->_screenDeltaX;
diff --git a/engines/gob/util.h b/engines/gob/util.h
index 7c1e44c..4228dac 100644
--- a/engines/gob/util.h
+++ b/engines/gob/util.h
@@ -108,6 +108,7 @@ public:
int16 getKey();
int16 checkKey();
bool checkKey(int16 &key);
+ bool keyPressed();
void getMouseState(int16 *pX, int16 *pY, MouseButtons *pButtons);
void setMousePos(int16 x, int16 y);
Commit: 7f5f9c9f91eb8cd52ebcffe208d0e778f8ff6448
https://github.com/scummvm/scummvm/commit/7f5f9c9f91eb8cd52ebcffe208d0e778f8ff6448
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2011-09-03T09:00:09-07:00
Commit Message:
GOB: Stub classes for Geisha's Diving and Penetration minigames
Changed paths:
A engines/gob/minigames/geisha/diving.cpp
A engines/gob/minigames/geisha/diving.h
A engines/gob/minigames/geisha/penetration.cpp
A engines/gob/minigames/geisha/penetration.h
engines/gob/inter.h
engines/gob/inter_geisha.cpp
engines/gob/module.mk
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index d1c28fc..6fd4dc2 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -33,6 +33,11 @@
namespace Gob {
+namespace Geisha {
+ class Diving;
+ class Penetration;
+}
+
// This is to help devices with small memory (PDA, smartphones, ...)
// to save a bit of memory used by opcode names in the Gob engine.
#ifndef REDUCE_MEMORY_USAGE
@@ -337,7 +342,7 @@ protected:
class Inter_Geisha : public Inter_v1 {
public:
Inter_Geisha(GobEngine *vm);
- virtual ~Inter_Geisha() {}
+ virtual ~Inter_Geisha();
protected:
virtual void setupOpcodesDraw();
@@ -362,6 +367,10 @@ protected:
void oGeisha_caress2(OpGobParams ¶ms);
int16 loadSound(int16 slot);
+
+private:
+ Geisha::Diving *_diving;
+ Geisha::Penetration *_penetration;
};
class Inter_v2 : public Inter_v1 {
diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp
index d72dd79..c5b91a4 100644
--- a/engines/gob/inter_geisha.cpp
+++ b/engines/gob/inter_geisha.cpp
@@ -38,6 +38,9 @@
#include "gob/sound/sound.h"
#include "gob/sound/sounddesc.h"
+#include "gob/minigames/geisha/diving.h"
+#include "gob/minigames/geisha/penetration.h"
+
namespace Gob {
#define OPCODEVER Inter_Geisha
@@ -45,7 +48,16 @@ namespace Gob {
#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x)
#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x)
-Inter_Geisha::Inter_Geisha(GobEngine *vm) : Inter_v1(vm) {
+Inter_Geisha::Inter_Geisha(GobEngine *vm) : Inter_v1(vm),
+ _diving(0), _penetration(0) {
+
+ _diving = new Geisha::Diving(vm);
+ _penetration = new Geisha::Penetration(vm);
+}
+
+Inter_Geisha::~Inter_Geisha() {
+ delete _penetration;
+ delete _diving;
}
void Inter_Geisha::setupOpcodesDraw() {
@@ -251,30 +263,24 @@ void Inter_Geisha::oGeisha_writeData(OpFuncParams ¶ms) {
}
void Inter_Geisha::oGeisha_gamePenetration(OpGobParams ¶ms) {
- uint16 var1 = _vm->_game->_script->readUint16();
- uint16 var2 = _vm->_game->_script->readUint16();
- uint16 var3 = _vm->_game->_script->readUint16();
- uint16 var4 = _vm->_game->_script->readUint16();
-
- WRITE_VAR_UINT32(var4, 0);
+ uint16 var1 = _vm->_game->_script->readUint16();
+ uint16 var2 = _vm->_game->_script->readUint16();
+ uint16 var3 = _vm->_game->_script->readUint16();
+ uint16 resultVar = _vm->_game->_script->readUint16();
- warning("Geisha Stub: Minigame \"Penetration\": %d, %d, %d, %d", var1, var2, var3, var4);
+ bool result = _penetration->play(var1, var2, var3);
- // Fudge a win for now
- WRITE_VAR_UINT32(var4, 1);
+ WRITE_VAR_UINT32(resultVar, result ? 1 : 0);
}
void Inter_Geisha::oGeisha_gameDiving(OpGobParams ¶ms) {
- uint16 var1 = _vm->_game->_script->readUint16();
- uint16 var2 = _vm->_game->_script->readUint16();
- uint16 var3 = _vm->_game->_script->readUint16();
-
- WRITE_VAR_UINT32(var3, 1);
+ uint16 playerCount = _vm->_game->_script->readUint16();
+ uint16 hasPearlLocation = _vm->_game->_script->readUint16();
+ uint16 resultVar = _vm->_game->_script->readUint16();
- warning("Geisha Stub: Minigame \"Diving\": %d, %d, %d", var1, var2, var3);
+ bool result = _diving->play(playerCount, hasPearlLocation);
- // Fudge a win for now
- WRITE_VAR_UINT32(var3, 0);
+ WRITE_VAR_UINT32(resultVar, result ? 1 : 0);
}
void Inter_Geisha::oGeisha_loadTitleMusic(OpGobParams ¶ms) {
diff --git a/engines/gob/minigames/geisha/diving.cpp b/engines/gob/minigames/geisha/diving.cpp
new file mode 100644
index 0000000..0d216ab
--- /dev/null
+++ b/engines/gob/minigames/geisha/diving.cpp
@@ -0,0 +1,155 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/list.h"
+
+#include "gob/global.h"
+#include "gob/util.h"
+#include "gob/draw.h"
+#include "gob/video.h"
+#include "gob/decfile.h"
+#include "gob/anifile.h"
+
+#include "gob/minigames/geisha/evilfish.h"
+#include "gob/minigames/geisha/diving.h"
+
+namespace Gob {
+
+namespace Geisha {
+
+Diving::Diving(GobEngine *vm) : _vm(vm), _background(0),
+ _objects(0), _gui(0), _oko(0), _lungs(0), _heart(0) {
+
+}
+
+Diving::~Diving() {
+ deinit();
+}
+
+bool Diving::play(uint16 playerCount, bool hasPearlLocation) {
+ init();
+ initScreen();
+
+ _vm->_draw->blitInvalidated();
+ _vm->_video->retrace();
+
+ EvilFish shark(*_objects, 320, 0, 14, 8, 9, 3);
+
+ Common::List<ANIObject *> objects;
+
+ objects.push_back(_water);
+ objects.push_back(&shark);
+
+ shark.enter(EvilFish::kDirectionLeft, 90);
+
+ while (!_vm->_util->keyPressed() && !_vm->shouldQuit()) {
+ int16 left, top, right, bottom;
+
+ // Clear the previous animation frames
+ for (Common::List<ANIObject *>::iterator o = objects.reverse_begin();
+ o != objects.end(); --o) {
+
+ (*o)->clear(*_vm->_draw->_backSurface, left, top, right, bottom);
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
+ }
+
+ // Draw the current animation frames
+ for (Common::List<ANIObject *>::iterator o = objects.begin();
+ o != objects.end(); ++o) {
+
+ (*o)->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
+
+ (*o)->advance();
+ }
+
+ _vm->_draw->blitInvalidated();
+
+ _vm->_util->waitEndFrame();
+ _vm->_util->processInput();
+ }
+
+ deinit();
+ return true;
+}
+
+void Diving::init() {
+ _background = new DECFile(_vm, "tperle.dec" , 320, 200);
+ _objects = new ANIFile(_vm, "tperle.ani" , 320);
+ _gui = new ANIFile(_vm, "tperlcpt.ani", 320);
+ _oko = new ANIFile(_vm, "tplonge.ani" , 320);
+
+ _water = new ANIObject(*_objects);
+ _lungs = new ANIObject(*_gui);
+ _heart = new ANIObject(*_gui);
+
+ _water->setAnimation(7);
+ _water->setPosition();
+ _water->setVisible(true);
+
+ _lungs->setAnimation(0);
+ _lungs->setPosition();
+ _lungs->setVisible(true);
+
+ _heart->setAnimation(1);
+ _heart->setPosition();
+ _heart->setVisible(true);
+}
+
+void Diving::deinit() {
+ delete _heart;
+ delete _lungs;
+ delete _water;
+
+ delete _oko;
+ delete _gui;
+ delete _objects;
+ delete _background;
+
+ _water = 0;
+ _heart = 0;
+ _lungs = 0;
+
+ _oko = 0;
+ _gui = 0;
+ _objects = 0;
+ _background = 0;
+}
+
+void Diving::initScreen() {
+ _vm->_util->setFrameRate(15);
+
+ _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+
+ _vm->_draw->_backSurface->clear();
+ _background->draw(*_vm->_draw->_backSurface);
+
+ int16 left, top, right, bottom;
+ _lungs->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
+ _heart->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
+
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199);
+}
+
+} // End of namespace Geisha
+
+} // End of namespace Gob
diff --git a/engines/gob/minigames/geisha/diving.h b/engines/gob/minigames/geisha/diving.h
new file mode 100644
index 0000000..238a1ad
--- /dev/null
+++ b/engines/gob/minigames/geisha/diving.h
@@ -0,0 +1,68 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GOB_MINIGAMES_GEISHA_DIVING_H
+#define GOB_MINIGAMES_GEISHA_DIVING_H
+
+#include "common/system.h"
+
+namespace Gob {
+
+class GobEngine;
+class DECFile;
+class ANIFile;
+class ANIObject;
+
+namespace Geisha {
+
+/** Geisha's "Diving" minigame. */
+class Diving {
+public:
+ Diving(GobEngine *vm);
+ ~Diving();
+
+ bool play(uint16 playerCount, bool hasPearlLocation);
+
+private:
+ GobEngine *_vm;
+
+ DECFile *_background;
+ ANIFile *_objects;
+ ANIFile *_gui;
+ ANIFile *_oko;
+
+ ANIObject *_water;
+ ANIObject *_lungs;
+ ANIObject *_heart;
+
+
+ void init();
+ void deinit();
+
+ void initScreen();
+};
+
+} // End of namespace Geisha
+
+} // End of namespace Gob
+
+#endif // GOB_MINIGAMES_GEISHA_DIVING_H
diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp
new file mode 100644
index 0000000..4334cae
--- /dev/null
+++ b/engines/gob/minigames/geisha/penetration.cpp
@@ -0,0 +1,106 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "gob/global.h"
+#include "gob/util.h"
+#include "gob/draw.h"
+#include "gob/video.h"
+#include "gob/decfile.h"
+#include "gob/anifile.h"
+
+#include "gob/minigames/geisha/penetration.h"
+
+namespace Gob {
+
+namespace Geisha {
+
+static byte kPalette[48] = {
+ 0x16, 0x16, 0x16,
+ 0x12, 0x14, 0x16,
+ 0x34, 0x00, 0x25,
+ 0x1D, 0x1F, 0x22,
+ 0x24, 0x27, 0x2A,
+ 0x2C, 0x0D, 0x22,
+ 0x2B, 0x2E, 0x32,
+ 0x12, 0x09, 0x20,
+ 0x3D, 0x3F, 0x00,
+ 0x3F, 0x3F, 0x3F,
+ 0x00, 0x00, 0x00,
+ 0x15, 0x15, 0x3F,
+ 0x25, 0x22, 0x2F,
+ 0x1A, 0x14, 0x28,
+ 0x3F, 0x00, 0x00,
+ 0x15, 0x3F, 0x15
+};
+
+Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _objects(0) {
+ _background = new Surface(320, 200, 1);
+}
+
+Penetration::~Penetration() {
+ deinit();
+
+ delete _background;
+}
+
+bool Penetration::play(uint16 var1, uint16 var2, uint16 var3) {
+ init();
+ initScreen();
+
+ _vm->_draw->blitInvalidated();
+ _vm->_video->retrace();
+ while (!_vm->_util->keyPressed() && !_vm->shouldQuit())
+ _vm->_util->longDelay(1);
+
+ deinit();
+ return true;
+}
+
+void Penetration::init() {
+ _background->clear();
+
+ _vm->_video->drawPackedSprite("hyprmef2.cmp", *_background);
+
+ _objects = new ANIFile(_vm, "tcite.ani", 320);
+}
+
+void Penetration::deinit() {
+ delete _objects;
+
+ _objects = 0;
+}
+
+void Penetration::initScreen() {
+ _vm->_util->setFrameRate(15);
+
+ memcpy(_vm->_draw->_vgaPalette , kPalette, 48);
+ memcpy(_vm->_draw->_vgaSmallPalette, kPalette, 48);
+
+ _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+
+ _vm->_draw->_backSurface->blit(*_background);
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199);
+}
+
+} // End of namespace Geisha
+
+} // End of namespace Gob
diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h
new file mode 100644
index 0000000..c346a7b
--- /dev/null
+++ b/engines/gob/minigames/geisha/penetration.h
@@ -0,0 +1,61 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GOB_MINIGAMES_GEISHA_PENETRATION_H
+#define GOB_MINIGAMES_GEISHA_PENETRATION_H
+
+#include "common/system.h"
+
+namespace Gob {
+
+class GobEngine;
+class Surface;
+class ANIFile;
+
+namespace Geisha {
+
+/** Geisha's "Penetration" minigame. */
+class Penetration {
+public:
+ Penetration(GobEngine *vm);
+ ~Penetration();
+
+ bool play(uint16 var1, uint16 var2, uint16 var3);
+
+private:
+ GobEngine *_vm;
+
+ Surface *_background;
+ ANIFile *_objects;
+
+
+ void init();
+ void deinit();
+
+ void initScreen();
+};
+
+} // End of namespace Geisha
+
+} // End of namespace Gob
+
+#endif // GOB_MINIGAMES_GEISHA_PENETRATION_H
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 0ea4f26..bf040c5 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -74,6 +74,8 @@ MODULE_OBJS := \
demos/scnplayer.o \
demos/batplayer.o \
minigames/geisha/evilfish.o \
+ minigames/geisha/diving.o \
+ minigames/geisha/penetration.o \
save/savefile.o \
save/savehandler.o \
save/saveload.o \
More information about the Scummvm-git-logs
mailing list