aboutsummaryrefslogtreecommitdiff
path: root/engines/mads/scene_data.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mads/scene_data.cpp')
-rw-r--r--engines/mads/scene_data.cpp358
1 files changed, 358 insertions, 0 deletions
diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp
new file mode 100644
index 0000000000..e0c25d89fb
--- /dev/null
+++ b/engines/mads/scene_data.cpp
@@ -0,0 +1,358 @@
+/* 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/scummsys.h"
+#include "mads/scene_data.h"
+#include "mads/mads.h"
+#include "mads/compression.h"
+#include "mads/resources.h"
+#include "mads/nebular/nebular_scenes.h"
+
+namespace MADS {
+
+SpriteSlot::SpriteSlot() {
+ _spriteType = ST_NONE;
+ _seqIndex = 0;
+ _spritesIndex = 0;
+ _frameNumber = 0;
+ _depth = 0;
+ _scale = 0;
+}
+
+SpriteSlot::SpriteSlot(SpriteType type, int seqIndex) {
+ _spriteType = type;
+ _seqIndex = seqIndex;
+ _spritesIndex = 0;
+ _frameNumber = 0;
+ _depth = 0;
+ _scale = 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+void SpriteSlots::clear(bool flag) {
+ _vm->_game->_scene._textDisplay.clear();
+
+ if (flag)
+ _vm->_game->_scene._sprites.clear();
+
+ Common::Array<SpriteSlot>::clear();
+ push_back(SpriteSlot(ST_FULL_SCREEN_REFRESH, -1));
+}
+
+/**
+ * Releases any sprites used by the player
+ */
+void SpriteSlots::releasePlayerSprites() {
+ Player &player = _vm->_game->player();
+
+ if (player._spritesLoaded && player._numSprites > 0) {
+ int spriteEnd = player._spritesStart + player._numSprites - 1;
+ do {
+ deleteEntry(spriteEnd);
+ } while (--spriteEnd >= player._spritesStart);
+ }
+}
+
+void SpriteSlots::deleteEntry(int index) {
+ remove_at(index);
+}
+
+
+/*------------------------------------------------------------------------*/
+
+TextDisplay::TextDisplay() {
+ _active = false;
+ _spacing = 0;
+ _expire = 0;
+ _col1 = _col2 = 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+DynamicHotspot::DynamicHotspot() {
+ _seqIndex = 0;
+ _facing = 0;
+ _descId = 0;
+ _field14 = 0;
+ _articleNumber = 0;
+ _cursor = 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+SequenceEntry::SequenceEntry() {
+ _spritesIndex = 0;
+ _flipped =0;
+ _frameIndex = 0;
+ _frameStart = 0;
+ _numSprites = 0;
+ _animType = 0;
+ _frameInc = 0;
+ _depth = 0;
+ _scale = 0;
+ _dynamicHotspotIndex = -1;
+ _triggerCountdown = 0;
+ _doneFlag = 0;
+ _entries._count = 0;
+ _abortMode = 0;
+ _actionNouns[0] = _actionNouns[1] = _actionNouns[2] = 0;
+ _numTicks = 0;
+ _extraTicks = 0;
+ _timeout = 0;
+}
+
+KernelMessage::KernelMessage() {
+ _flags = 0;
+ _seqInex = 0;
+ _asciiChar = '\0';
+ _asciiChar2 = '\0';
+ _colors = 0;
+ _msgOffset = 0;
+ _numTicks = 0;
+ _frameTimer2 = 0;
+ _frameTimer = 0;
+ _timeout = 0;
+ _field1C = 0;
+ _abortMode = 0;
+ _nounList[0] = _nounList[1] = _nounList[2] = 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+Hotspot::Hotspot() {
+ _facing = 0;
+ _articleNumber = 0;
+ _cursor = 0;
+ _vocabId = 0;
+ _verbId = 0;
+}
+
+Hotspot::Hotspot(Common::SeekableReadStream &f) {
+ _bounds.left = f.readSint16LE();
+ _bounds.top = f.readSint16LE();
+ _bounds.right = f.readSint16LE();
+ _bounds.bottom = f.readSint16LE();
+ _feetPos.x = f.readSint16LE();
+ _feetPos.y = f.readSint16LE();
+ _facing = f.readByte();
+ _articleNumber = f.readByte();
+ f.skip(1);
+ _cursor = f.readByte();
+ _vocabId = f.readUint16LE();
+ _verbId = f.readUint16LE();
+}
+
+/*------------------------------------------------------------------------*/
+
+void ARTHeader::load(Common::SeekableReadStream *f) {
+ // Read in dimensions of image
+ _width = f->readUint16LE();
+ _height = f->readUint16LE();
+
+ // Read in palette information
+ int palCount = f->readUint16LE();
+ for (int i = 0; i < palCount; ++i) {
+ RGB6 rgb;
+ rgb.load(f);
+ _palette.push_back(rgb);
+ }
+ f->skip(6 * (256 - palCount));
+
+ // Read unknown???
+ palCount = f->readUint16LE();
+ for (int i = 0; i < palCount; ++i) {
+ RGB4 rgb;
+ rgb.r = f->readByte();
+ rgb.g = f->readByte();
+ rgb.b = f->readByte();
+ rgb.u = f->readByte();
+
+ _palData.push_back(rgb);
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+SceneInfo *SceneInfo::load(MADSEngine *vm, int sceneId, int v1, const Common::String &resName,
+ int v3, MSurface &depthSurface, MSurface &bgSurface) {
+ return new SceneInfo(vm, sceneId, v1, resName, v3, depthSurface, bgSurface);
+}
+
+SceneInfo::SceneInfo(MADSEngine *vm, int sceneId, int v1, const Common::String &resName,
+ int flags, MSurface &depthSurface, MSurface &bgSurface) {
+ bool flag = true;
+ bool sceneFlag = sceneId >= 0;
+ bool ssFlag = false, wsFlag = false;
+
+ Common::Array<SpriteAsset *> spriteSets;
+ Common::Array<int> xpList;
+
+ // Figure out the resource to use
+ Common::String resourceName;
+ if (sceneFlag) {
+ resourceName = Resources::formatName(RESPREFIX_RM, sceneId, ".DAT");
+ } else {
+ resourceName = "*" + Resources::formatResource(resName, resName);
+ }
+
+ // Open the scene info resource for access
+ File infoFile(resName);
+
+ // Read in basic data
+ _sceneId = infoFile.readUint16LE();
+ _artFileNum = infoFile.readUint16LE();
+ _depthStyle = infoFile.readUint16LE();
+ _width = infoFile.readUint16LE();
+ _height = infoFile.readUint16LE();
+ infoFile.skip(24);
+ _nodeCount = infoFile.readUint16LE();
+ _yBandsEnd = infoFile.readUint16LE();
+ _yBandsStart = infoFile.readUint16LE();
+ _maxScale = infoFile.readUint16LE();
+ _minScale = infoFile.readUint16LE();
+ for (int i = 0; i < 15; ++i)
+ _depthList[i] = infoFile.readUint16LE();
+ _field4A = infoFile.readUint16LE();
+
+ // Load the set of objects that are associated with the scene
+ for (int i = 0; i < 20; ++i) {
+ InventoryObject obj;
+ obj.load(infoFile);
+ _objects.push_back(obj);
+ }
+
+ int setCount = infoFile.readUint16LE();
+ int field40E = infoFile.readUint16LE();
+
+ for (int i = 0; i < 20; ++i) {
+ char name[64];
+ infoFile.read(name, 64);
+ _setNames.push_back(Common::String(name));
+ }
+
+ infoFile.close();
+ int width = _width;
+ int height = _height;
+
+ if (!bgSurface.getPixels()) {
+ bgSurface.setSize(width, height);
+ ssFlag = true;
+ }
+
+ if (_depthStyle == 2)
+ width >>= 2;
+ if (!depthSurface.getPixels()) {
+ depthSurface.setSize(width, height);
+ wsFlag = true;
+ }
+
+ // Load the depth surface with the scene codes
+ loadCodes(depthSurface);
+
+ // Get the ART resource
+ if (sceneFlag) {
+ resourceName = Resources::formatName(RESPREFIX_RM, sceneId, ".ART");
+ } else {
+ resourceName = "*" + Resources::formatResource(resName, resName);
+ }
+
+ // Load in the ART header and palette
+ File artFile(resourceName);
+ MadsPack artResource(&artFile);
+ Common::SeekableReadStream *stream = artResource.getItemStream(0);
+
+ ARTHeader artHeader;
+ artHeader.load(stream);
+ artFile.close();
+
+ // Copy out the palette data
+ for (uint i = 0; i < artHeader._palData.size(); ++i)
+ _palette.push_back(artHeader._palData[i]);
+
+ if (!(flags & 1)) {
+ if (!_vm->_palette->_paletteUsage.empty()) {
+ _vm->_palette->_paletteUsage.getKeyEntries(artHeader._palette);
+ _vm->_palette->_paletteUsage.prioritize(artHeader._palette);
+ }
+
+ _field4C = _vm->_palette->_paletteUsage.process(artHeader._palette, 0xF800);
+ if (_field4C > 0) {
+ _vm->_palette->_paletteUsage.transform(artHeader._palette);
+
+ for (uint i = 0; i < _palette.size(); ++i) {
+ byte g = _palette[i].g;
+ _palette[g].b = artHeader._palette[g].palIndex;
+ }
+ }
+ }
+
+ // Read in the background surface data
+ assert(_width == bgSurface.w && _height == bgSurface.h);
+ stream->read(bgSurface.getPixels(), bgSurface.w * bgSurface.h);
+
+ if (flags & 1) {
+ for (uint i = 0; i < _setNames.size(); ++i) {
+ Common::String setResName;
+ if (sceneFlag || resName.hasPrefix("*"))
+ setResName += "*";
+ setResName += _setNames[i];
+
+ SpriteAsset *sprites = new SpriteAsset(_vm, setResName, flags);
+ spriteSets.push_back(sprites);
+ xpList.push_back(-1); // TODO:: sprites->_field6
+ }
+ }
+
+
+
+ warning("TODO");
+}
+
+void SceneInfo::loadCodes(MSurface &depthSurface) {
+ File f(Resources::formatName(RESPREFIX_RM, _sceneId, ".DAT"));
+
+ uint16 width = _width;
+ uint16 height = _height;
+ byte *walkMap = new byte[f.size()];
+
+ depthSurface.setSize(width, height);
+ f.read(walkMap, f.size());
+
+ byte *ptr = (byte *)depthSurface.getPixels();
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ int ofs = x + (y * width);
+ if ((walkMap[ofs / 8] << (ofs % 8)) & 0x80)
+ *ptr++ = 1; // walkable
+ else
+ *ptr++ = 0;
+ }
+ }
+
+ delete[] walkMap;
+}
+
+/*------------------------------------------------------------------------*/
+
+} // End of namespace MADS