aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/mads/animation.cpp242
-rw-r--r--engines/mads/animation.h83
-rw-r--r--engines/mads/font.cpp6
-rw-r--r--engines/mads/font.h5
-rw-r--r--engines/mads/graphics.h1
-rw-r--r--engines/mads/scene.cpp1
-rw-r--r--engines/mads/scene.h3
-rw-r--r--engines/mads/scene_data.cpp35
-rw-r--r--engines/mads/scene_data.h8
-rw-r--r--engines/mads/sound.cpp4
-rw-r--r--engines/mads/sound.h5
11 files changed, 384 insertions, 9 deletions
diff --git a/engines/mads/animation.cpp b/engines/mads/animation.cpp
index f5144c3c49..dd62e7b0f0 100644
--- a/engines/mads/animation.cpp
+++ b/engines/mads/animation.cpp
@@ -21,17 +21,255 @@
*/
#include "mads/animation.h"
+#include "mads/compression.h"
+
+#define FILENAME_SIZE 64
namespace MADS {
+
+AAHeader::AAHeader(Common::SeekableReadStream *f) {
+ _spriteListCount = f->readUint16LE();
+ _miscEntriesCount = f->readUint16LE();
+ _frameEntriesCount = f->readUint16LE();
+ _messagesCount = f->readUint16LE();
+ f->skip(1);
+ _flags = f->readByte();
+
+ f->skip(2);
+ _animMode = f->readUint16LE();
+ _roomNumber = f->readUint16LE();
+ f->skip(2);
+ _field12 = f->readUint16LE() != 0;
+ _spriteListIndex = f->readUint16LE();
+ _scrollPosition.x = f->readSint16LE();
+ _scrollPosition.y = f->readSint16LE();
+ _scrollTicks = f->readUint16LE();
+ f->skip(8);
+
+ char buffer[FILENAME_SIZE];
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE] = '\0';
+ _interfaceFile = Common::String(buffer);
+
+ for (int i = 0; i < 10; ++i) {
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE] = '\0';
+ _spriteSetNames[i] = Common::String(buffer);
+ }
+
+ f->skip(81);
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE] = '\0';
+ _lbmFilename = Common::String(buffer);
+
+ f->skip(365);
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE] = '\0';
+ _spritesFilename = Common::String(buffer);
+
+ f->skip(48);
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE] = '\0';
+ _soundName = Common::String(buffer);
+
+ f->skip(13);
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE] = '\0';
+ _dsrName = Common::String(buffer);
+
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE] = '\0';
+ Common::String fontResource(buffer);
+}
+
+/*------------------------------------------------------------------------*/
+
+void AnimMessage::load(Common::SeekableReadStream *f) {
+ _soundId = f->readSint16LE();
+
+ char buffer[64];
+ f->read(&buffer[0], 64);
+ _msg = Common::String(buffer);
+ f->skip(4);
+ _pos.x = f->readSint16LE();
+ _pos.y = f->readSint16LE();
+ _flags = f->readUint16LE();
+ _rgb1[0] = f->readByte() << 2;
+ _rgb1[1] = f->readByte() << 2;
+ _rgb1[2] = f->readByte() << 2;
+ _rgb2[0] = f->readByte() << 2;
+ _rgb2[1] = f->readByte() << 2;
+ _rgb2[2] = f->readByte() << 2;
+ f->skip(2); // Space for kernelMsgIndex
+ _kernelMsgIndex = -1;
+ f->skip(6);
+ _startFrame = f->readUint16LE();
+ _endFrame = f->readUint16LE();
+ f->skip(2);
+}
+
+void AnimFrameEntry::load(Common::SeekableReadStream *f) {
+ _frameNumber = f->readUint16LE();
+ _seqIndex = f->readByte();
+ _spriteSlot._spritesIndex = f->readByte();
+ _spriteSlot._frameNumber = f->readUint16LE();
+ _spriteSlot._position.x = f->readSint16LE();
+ _spriteSlot._position.y = f->readSint16LE();
+ _spriteSlot._depth = f->readSByte();
+ _spriteSlot._scale = (int8)f->readByte();
+}
+
+/*------------------------------------------------------------------------*/
+
+void AnimMiscEntry::load(Common::SeekableReadStream *f) {
+ _soundId = f->readByte();
+ _msgIndex = f->readSByte();
+ _numTicks = f->readUint16LE();
+ _posAdjust.x = f->readSint16LE();
+ _posAdjust.y = f->readSint16LE();
+ _scrollPos.x = f->readSint16LE();
+ _scrollPos.y = f->readSint16LE();
+}
+
+/*------------------------------------------------------------------------*/
Animation *Animation::init(MADSEngine *vm, Scene *scene) {
return new Animation(vm, scene);
}
-void Animation::load(MSurface *sceneSurface, MSurface *interfaceSurface, int sceneId,
- int flags, byte *palette, SceneInfo *sceneInfo) {
+void Animation::load(MSurface &depthSurface, InterfaceSurface &interfaceSurface,
+ const Common::String &resName, int flags, Common::Array<RGB4> *palAnimData,
+ SceneInfo *sceneInfo) {
+ Common::String resourceName = resName;
+ if (!resourceName.contains("."))
+ resourceName += ".AA";
+
+ File f(resourceName);
+ MadsPack madsPack(&f);
+ Common::SeekableReadStream *stream = madsPack.getItemStream(0);
+ AAHeader aaHeader(stream);
+ delete stream;
+
+ if (aaHeader._animMode == 4)
+ flags |= 0x4000;
+
+ if (flags & 0x100) {
+ loadInterface(interfaceSurface, depthSurface, aaHeader, flags, palAnimData, sceneInfo);
+ }
+ if (flags & 0x200) {
+ // No data
+ aaHeader._messagesCount = 0;
+ aaHeader._frameEntriesCount = 0;
+ aaHeader._miscEntriesCount = 0;
+ }
+
+ // Initialize the reference list
+ for (int i = 0; i < aaHeader._spriteListCount; ++i)
+ _spriteListIndexes.push_back(-1);
+
+ if (aaHeader._messagesCount > 0) {
+ // Chunk 2: Following is a list of any messages for the animation
+ Common::SeekableReadStream *msgStream = madsPack.getItemStream(1);
+
+ for (int i = 0; i < aaHeader._messagesCount; ++i) {
+ AnimMessage rec;
+ rec.load(msgStream);
+ _messages.push_back(rec);
+ }
+
+ delete msgStream;
+ }
+
+ if (aaHeader._frameEntriesCount > 0) {
+ // Chunk 3: animation frame info
+ Common::SeekableReadStream *frameStream = madsPack.getItemStream(2);
+
+ for (int i = 0; i < aaHeader._frameEntriesCount; i++) {
+ AnimFrameEntry rec;
+ rec.load(frameStream);
+ _frameEntries.push_back(rec);
+ }
+
+ delete frameStream;
+ }
+
+ if (aaHeader._miscEntriesCount > 0) {
+ // Chunk 4: Misc Data
+ Common::SeekableReadStream *miscStream = madsPack.getItemStream(3);
+
+ for (int i = 0; i < aaHeader._miscEntriesCount; ++i) {
+ AnimMiscEntry rec;
+ rec.load(miscStream);
+ _miscEntries.push_back(rec);
+ }
+
+ delete miscStream;
+ }
+ /*
+ // If the animation specifies a font, then load it for access
+ if (_flags & ANIM_CUSTOM_FONT) {
+ Common::String fontName;
+ if (madsRes)
+ fontName += "*";
+ fontName += fontResource;
+
+ if (fontName != "")
+ _font = _vm->_font->getFont(fontName.c_str());
+ else
+ warning("Attempted to set a font with an empty name");
+ }
+
+ // If a speech file is specified, then load it
+ if (!_dsrName.empty())
+ _vm->_sound->loadDSRFile(_dsrName.c_str());
+
+ // Load all the sprite sets for the animation
+ for (int i = 0; i < spriteListCount; ++i) {
+ if (_field12 && (i == _spriteListIndex))
+ // Skip over field, since it's manually loaded
+ continue;
+
+ _spriteListIndexes[i] = _view->_spriteSlots.addSprites(_spriteSetNames[i].c_str());
+ }
+
+
+ if (_field12) {
+ Common::String resName;
+ if (madsRes)
+ resName += "*";
+ resName += _spriteSetNames[_spriteListIndex];
+
+ _spriteListIndexes[_spriteListIndex] = _view->_spriteSlots.addSprites(resName.c_str());
+ }
+ */
+ f.close();
}
+void Animation::loadInterface(InterfaceSurface &interfaceSurface, MSurface &depthSurface,
+ AAHeader &header, int flags, Common::Array<RGB4> *palAnimData, SceneInfo *sceneInfo) {
+ _scene->_depthStyle = 0;
+ if (header._animMode <= 2) {
+ sceneInfo->load(header._roomNumber, flags, header._interfaceFile, 0, depthSurface, interfaceSurface);
+ _scene->_depthStyle = sceneInfo->_depthStyle == 2 ? 1 : 0;
+ if (palAnimData) {
+ palAnimData->clear();
+ for (uint i = 0; i < sceneInfo->_palAnimData.size(); ++i)
+ palAnimData->push_back(sceneInfo->_palAnimData[i]);
+ }
+ }
+ else if (header._animMode == 4) {
+ // Load a scene interface
+ Common::String resourceName = "*" + header._interfaceFile;
+ interfaceSurface.load(_vm, resourceName);
+
+ if (palAnimData)
+ palAnimData->clear();
+ }
+ else {
+ // Original has useless code here
+ }
+}
+
} // End of namespace MADS
diff --git a/engines/mads/animation.h b/engines/mads/animation.h
index cc46143b32..1e542da590 100644
--- a/engines/mads/animation.h
+++ b/engines/mads/animation.h
@@ -31,23 +31,102 @@
namespace MADS {
+enum AnimFlag { ANIM_CUSTOM_FONT = 0x20 };
+
class MADSEngine;
class Scene;
+class AnimMessage {
+public:
+ int16 _soundId;
+ Common::String _msg;
+ Common::Point _pos;
+ byte _rgb1[3], _rgb2[3];
+ int _flags;
+ int _startFrame, _endFrame;
+ int _kernelMsgIndex;
+
+ /**
+ * Loads data for the message from a stream
+ */
+ void load(Common::SeekableReadStream *f);
+};
+
+class AnimFrameEntry {
+public:
+ int _frameNumber;
+ int _seqIndex;
+ SpriteSlotSubset _spriteSlot;
+
+ /**
+ * Loads data for the record
+ */
+ void load(Common::SeekableReadStream *f);
+};
+
+class AnimMiscEntry {
+public:
+ int _soundId;
+ int _msgIndex;
+ int _numTicks;
+ Common::Point _posAdjust;
+ Common::Point _scrollPos;
+
+ /**
+ * Loads data for the record
+ */
+ void load(Common::SeekableReadStream *f);
+};
+
+class AAHeader {
+public:
+ int _spriteListCount;
+ int _miscEntriesCount;
+ int _frameEntriesCount;
+ int _messagesCount;
+ byte _flags;
+ int _animMode;
+ int _roomNumber;
+ int _field12;
+ int _spriteListIndex;
+ Common::Point _scrollPosition;
+ uint32 _scrollTicks;
+ Common::String _interfaceFile;
+ Common::StringArray _spriteSetNames;
+ Common::String _lbmFilename;
+ Common::String _spritesFilename;
+ Common::String _soundName;
+ Common::String _dsrName;
+ Common::String _fontResource;
+
+ /**
+ * Loads the data for a animation file header
+ */
+ AAHeader(Common::SeekableReadStream *f);
+};
+
class Animation {
private:
MADSEngine *_vm;
Scene *_scene;
+
+ void loadInterface(InterfaceSurface &interfaceSurface, MSurface &depthSurface,
+ AAHeader &header, int flags, Common::Array<RGB4> *palAnimData, SceneInfo *sceneInfo);
protected:
Animation(MADSEngine *vm, Scene *scene) : _vm(vm), _scene(scene) {}
public:
static Animation *init(MADSEngine *vm, Scene *scene);
public:
+ Common::Array<int> _spriteListIndexes;
+ Common::Array<AnimMessage> _messages;
+ Common::Array<AnimFrameEntry> _frameEntries;
+ Common::Array<AnimMiscEntry> _miscEntries;
+public:
/**
* Loads animation data
*/
- void load(MSurface *sceneSurface, MSurface *interfaceSurface, int sceneId, int flags,
- byte *palette, SceneInfo *sceneInfo);
+ void load(MSurface &depthSurface, InterfaceSurface &interfaceSurface, const Common::String &resName,
+ int flags, Common::Array<RGB4> *palAnimData, SceneInfo *sceneInfo);
};
} // End of namespace MADS
diff --git a/engines/mads/font.cpp b/engines/mads/font.cpp
index 52541500c9..10d51fbbc0 100644
--- a/engines/mads/font.cpp
+++ b/engines/mads/font.cpp
@@ -205,4 +205,10 @@ int Font::getBpp(int charWidth) {
return 1;
}
+Font *Font::getFont(const Common::String &fontName) {
+ Font *font = new Font(_vm);
+ font->setFont(fontName);
+ return font;
+}
+
} // End of namespace MADS
diff --git a/engines/mads/font.h b/engines/mads/font.h
index 3deb3f4d2d..c642831952 100644
--- a/engines/mads/font.h
+++ b/engines/mads/font.h
@@ -68,6 +68,11 @@ public:
int writeString(MSurface *surface, const Common::String &msg, const Common::Point &pt, int width = 0, int spaceWidth = -1) {
return write(surface, msg, pt, width, spaceWidth, _fontColors);
}
+
+ /**
+ * Returns a new Font instance using the specified font name
+ */
+ Font *getFont(const Common::String &fontName);
};
} // End of namespace MADS
diff --git a/engines/mads/graphics.h b/engines/mads/graphics.h
index 87cd8be3c9..cadbbc8e8e 100644
--- a/engines/mads/graphics.h
+++ b/engines/mads/graphics.h
@@ -29,7 +29,6 @@ namespace MADS {
#define MADS_SCREEN_WIDTH 320
#define MADS_SCREEN_HEIGHT 200
-#define MADS_INTERFACE_HEIGHT 44
} // End of namespace MADS
diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp
index eaa1cab7fa..e6c02b89e0 100644
--- a/engines/mads/scene.cpp
+++ b/engines/mads/scene.cpp
@@ -37,6 +37,7 @@ Scene::Scene(MADSEngine *vm): _vm(vm), _spriteSlots(vm) {
_sceneInfo = nullptr;
_animFlag = false;
_animVal1 = 0;
+ _depthStyle = 0;
_verbList.push_back(VerbInit(VERB_LOOK, 2, 0));
_verbList.push_back(VerbInit(VERB_TAKE, 2, 0));
diff --git a/engines/mads/scene.h b/engines/mads/scene.h
index 7a7959e917..2c5880a405 100644
--- a/engines/mads/scene.h
+++ b/engines/mads/scene.h
@@ -80,7 +80,7 @@ public:
SceneInfo *_sceneInfo;
MSurface _backgroundSurface;
MSurface _depthSurface;
- MSurface _interfaceSurface;
+ InterfaceSurface _interfaceSurface;
bool _animFlag;
int _animVal1;
int _animCount;
@@ -89,6 +89,7 @@ public:
SceneNodeList _nodes;
Common::StringArray _vocabStrings;
Animation *_animation;
+ int _depthStyle;
/**
* Constructor
diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp
index 07a2ae856d..cec3e457a0 100644
--- a/engines/mads/scene_data.cpp
+++ b/engines/mads/scene_data.cpp
@@ -24,6 +24,7 @@
#include "mads/scene_data.h"
#include "mads/mads.h"
#include "mads/compression.h"
+#include "mads/graphics.h"
#include "mads/resources.h"
#include "mads/nebular/nebular_scenes.h"
@@ -214,6 +215,34 @@ void SceneInfo::SpriteInfo::load(Common::SeekableReadStream *f) {
/*------------------------------------------------------------------------*/
+void InterfaceSurface::load(MADSEngine *vm, const Common::String &resName) {
+ File f(resName);
+ MadsPack madsPack(&f);
+
+ // Load in the palette
+ Common::SeekableReadStream *palStream = madsPack.getItemStream(0);
+
+ RGB4 *gamePalP = &vm->_palette->_gamePalette[0];
+ byte *palP = &vm->_palette->_mainPalette[0];
+
+ for (int i = 0; i < 16; ++i, gamePalP++, palP += 3) {
+ palP[0] = palStream->readByte();
+ palP[1] = palStream->readByte();
+ palP[2] = palStream->readByte();
+ gamePalP->r |= 1;
+ palStream->skip(3);
+ }
+ delete palStream;
+
+ // set the size for the interface
+ setSize(MADS_SCREEN_WIDTH, MADS_INTERFACE_HEIGHT);
+ Common::SeekableReadStream *pixelsStream = madsPack.getItemStream(1);
+ pixelsStream->read(getData(), MADS_SCREEN_WIDTH * MADS_INTERFACE_HEIGHT);
+ delete pixelsStream;
+}
+
+/*------------------------------------------------------------------------*/
+
SceneInfo *SceneInfo::init(MADSEngine *vm) {
if (vm->getGameID() == GType_RexNebular) {
return new SceneInfoNebular(vm);
@@ -356,7 +385,7 @@ void SceneInfo::load(int sceneId, int v1, const Common::String &resName,
artFile.close();
Common::Array<SpriteAsset *> spriteSets;
- Common::Array<int> xpList;
+ Common::Array<int> indexList;
if (flags & 1) {
for (uint i = 0; i < setNames.size(); ++i) {
@@ -367,11 +396,11 @@ void SceneInfo::load(int sceneId, int v1, const Common::String &resName,
SpriteAsset *sprites = new SpriteAsset(_vm, setResName, flags);
spriteSets.push_back(sprites);
- xpList.push_back(-1); // TODO:: sprites->_field6
+ indexList.push_back(-1); // TODO:: sprites->_field6
}
}
- warning("TODO: sub_201E4(xpList, namesCount, &pal data2");
+ warning("TODO: sub_201E4(indexList, namesCount, &pal data2");
for (uint i = 0; i < spriteInfo.size(); ++i) {
SpriteInfo &si = spriteInfo[i];
diff --git a/engines/mads/scene_data.h b/engines/mads/scene_data.h
index c646215bbf..23eee3403f 100644
--- a/engines/mads/scene_data.h
+++ b/engines/mads/scene_data.h
@@ -54,6 +54,9 @@ enum MadsActionMode { ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, AC
enum MadsActionMode2 { ACTMODE2_0 = 0, ACTMODE2_2 = 2, ACTMODE2_4 = 4, ACTMODE2_5 = 5 };
enum AbortTimerMode { ABORTMODE_0 = 0, ABORTMODE_1 = 1, ABORTMODE_2 = 2 };
+#define MADS_INTERFACE_HEIGHT 44
+#define MADS_SCENE_HEIGHT (MADS_SCREEN_HEIGHT - MADS_INTERFACE_HEIGHT)
+
#define DEPTH_BANDS_SIZE 15
#define MAX_ROUTE_NODES 22
@@ -294,6 +297,11 @@ public:
};
typedef Common::Array<SceneNode> SceneNodeList;
+class InterfaceSurface : public MSurface {
+public:
+ void load(MADSEngine *vm, const Common::String &resName);
+};
+
/**
* Handles general data for a given scene
*/
diff --git a/engines/mads/sound.cpp b/engines/mads/sound.cpp
index ea0239076b..ae338461ec 100644
--- a/engines/mads/sound.cpp
+++ b/engines/mads/sound.cpp
@@ -90,6 +90,10 @@ void SoundManager::startQueuedCommands() {
}
}
+void SoundManager::loadDSRFile(const Common::String &filename) {
+ error("TODO: SoundManager::loadDSRFile");
+}
+
void SoundManager::command(int commandId, int param) {
if (_newSoundsPaused) {
if (_queuedCommands.size() < 8)
diff --git a/engines/mads/sound.h b/engines/mads/sound.h
index 0fd9ac1095..1fe322d6fb 100644
--- a/engines/mads/sound.h
+++ b/engines/mads/sound.h
@@ -77,6 +77,11 @@ public:
*/
void startQueuedCommands();
+ /**
+ * Loads a DSR resource
+ */
+ void loadDSRFile(const Common::String &filename);
+
//@{
/**
* Executes a command on the sound driver