From a77ed90618664e50705b3e59dd2111faec2f5f39 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 6 Mar 2014 22:31:41 -0500 Subject: MADS: Implementing support methods needed for scene 804 initialisation --- engines/mads/game.cpp | 37 ++++++++++++++-------------- engines/mads/game.h | 20 ++++++++++++---- engines/mads/messages.cpp | 2 -- engines/mads/msurface.cpp | 13 ++++++++++ engines/mads/msurface.h | 15 ++++++++++++ engines/mads/nebular/globals_nebular.cpp | 5 ++-- engines/mads/nebular/globals_nebular.h | 2 ++ engines/mads/nebular/nebular_scenes.cpp | 41 +++++++++++++++++++++++++++++++- engines/mads/nebular/nebular_scenes.h | 16 +++++++++++++ engines/mads/nebular/nebular_scenes8.cpp | 32 +++++++++++++++++++++++++ engines/mads/resources.h | 3 ++- engines/mads/scene.cpp | 8 +++---- engines/mads/scene.h | 2 +- engines/mads/scene_data.cpp | 33 ++----------------------- engines/mads/scene_data.h | 11 --------- engines/mads/sequence.cpp | 19 +++++++++++++++ engines/mads/sequence.h | 2 ++ engines/mads/sprites.cpp | 4 ++++ engines/mads/sprites.h | 14 +++++++++++ 19 files changed, 202 insertions(+), 77 deletions(-) diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index b64c59c986..962e82ca18 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -140,7 +140,6 @@ void Game::sectionLoop() { _v6 = 0; _vm->_events->resetCursor(); - _quotes = nullptr; _scene.clearVocab(); _scene._dynamicHotspots.clear(); _scene.loadSceneLogic(); @@ -223,8 +222,7 @@ void Game::sectionLoop() { if ((_v5 || _v6) && !_updateSceneFlag) { _scene._currentSceneId = _scene._priorSceneId; _updateSceneFlag = true; - } - else { + } else { _updateSceneFlag = false; _scene.loop(); } @@ -232,8 +230,6 @@ void Game::sectionLoop() { _vm->_events->resetCursor(); _v1 = 3; - delete _quotes; - _quotes = nullptr; delete _scene._animation; _scene._animation = nullptr; @@ -274,22 +270,27 @@ void Game::loadResourceSequence(const Common::String prefix, int v) { warning("TODO: loadResourceSequence"); } -Common::String Game::getQuote(int quoteId) { - if (_quotes && *_quotes) { - // Loop through the list of quotes - char *p = (char *)_quotes; - while (*p) { - // Get a pointer to the quote Id after the string - char *idP = p + strlen(p) + 1; - if (READ_LE_UINT16(idP) == quoteId) - // Found the correct string, so return it - return Common::String(p); - - p = idP + 2; +void Game::loadQuotes() { + File f("*QUOTES.DAT"); + int curPos = 0; + + char buffer[128]; + strcpy(buffer, ""); + + while (true) { + uint8 b = f.readByte(); + if (f.eos()) break; + + buffer[curPos++] = b; + if (buffer[curPos - 1] == '\0') { + // end of string, add it to the strings list + _quotes.push_back(buffer); + curPos = 0; + strcpy(buffer, ""); } } - return Common::String(); + f.close(); } } // End of namespace MADS diff --git a/engines/mads/game.h b/engines/mads/game.h index 0cd46b6f7e..aa1810963d 100644 --- a/engines/mads/game.h +++ b/engines/mads/game.h @@ -24,6 +24,7 @@ #define MADS_GAME_H #include "common/scummsys.h" +#include "common/str-array.h" #include "mads/scene.h" #include "mads/game_data.h" #include "mads/player.h" @@ -51,6 +52,11 @@ private: * Inner game loop for executing gameplay within a game section */ void sectionLoop(); + + /** + * Load quotes data + */ + void loadQuotes(); protected: MADSEngine *_vm; MSurface *_surface; @@ -59,7 +65,7 @@ protected: int _statusFlag; SectionHandler *_sectionHandler; VisitedScenes _visitedScenes; - byte *_quotes; + Common::StringArray _quotes; int _v1; int _v3; int _v5; @@ -130,10 +136,14 @@ public: */ void run(); - /** - * Get a quote - */ - Common::String getQuote(int quoteId); + uint32 getQuotesSize() { return _quotes.size(); } + const Common::String &getQuote(uint32 index) { return _quotes[index - 1]; } + + // DEPRECATED: ScummVM re-implementation keeps all the quotes loaded, so the methods below are stubs + void clearQuotes() {} + void loadQuoteRange(int startNum, int endNum) {} + void loadQuoteSet(...) {} + void loadQuote(int quoteNum) {} }; } // End of namespace MADS diff --git a/engines/mads/messages.cpp b/engines/mads/messages.cpp index 33a6a8ef6c..aaf6c4100e 100644 --- a/engines/mads/messages.cpp +++ b/engines/mads/messages.cpp @@ -30,8 +30,6 @@ namespace MADS { KernelMessages::KernelMessages(MADSEngine *vm): _vm(vm) { - Scene &scene = _vm->_game->_scene; - for (int i = 0; i < KERNEL_MESSAGES_SIZE; ++i) { KernelMessage rec; _entries.push_back(rec); diff --git a/engines/mads/msurface.cpp b/engines/mads/msurface.cpp index 754fea851d..74043bf91f 100644 --- a/engines/mads/msurface.cpp +++ b/engines/mads/msurface.cpp @@ -497,4 +497,17 @@ MSurface *MSurface::flipHorizontal() const { return dest; } +/*------------------------------------------------------------------------*/ + +int DepthSurface::getDepth(const Common::Point &pt) { + + if (_vm->_game->_scene._sceneInfo->_depthStyle == 2) { + int bits = (3 - (pt.x % 4)) * 2; + byte v = *getBasePtr(pt.x >> 2, pt.y); + return v >> bits; + } else { + return *getBasePtr(pt.x, pt.y) & 0xF; + } +} + } // End of namespace MADS diff --git a/engines/mads/msurface.h b/engines/mads/msurface.h index bd8142fd1a..96994170aa 100644 --- a/engines/mads/msurface.h +++ b/engines/mads/msurface.h @@ -202,6 +202,21 @@ public: MSurface *flipHorizontal() const; }; +class DepthSurface : public MSurface { +private: + MADSEngine *_vm; +public: + /** + * Constructor + */ + DepthSurface(MADSEngine *vm) : _vm(vm) {} + + /** + * Returns the depth at a given position + */ + int getDepth(const Common::Point &pt); +}; + } // End of namespace MADS #endif /* MADS_MSURFACE_H */ diff --git a/engines/mads/nebular/globals_nebular.cpp b/engines/mads/nebular/globals_nebular.cpp index 20789cd154..37ebf5f8d6 100644 --- a/engines/mads/nebular/globals_nebular.cpp +++ b/engines/mads/nebular/globals_nebular.cpp @@ -29,10 +29,9 @@ namespace MADS { namespace Nebular { Globals::Globals() { - // Initialise global flags + // Initialise lists _flags.resize(210); - for (int i = 0; i < 210; ++i) - _flags[i] = 0; + _spriteIndexes.resize(30); // Initialise game flags _chairHotspotIndex = 0; diff --git a/engines/mads/nebular/globals_nebular.h b/engines/mads/nebular/globals_nebular.h index 0d8da78e42..daa384f88f 100644 --- a/engines/mads/nebular/globals_nebular.h +++ b/engines/mads/nebular/globals_nebular.h @@ -35,6 +35,8 @@ class Globals { private: Common::Array _flags; public: + Common::Array _spriteIndexes; + int _chairHotspotIndex; int _v1; int _v2; diff --git a/engines/mads/nebular/nebular_scenes.cpp b/engines/mads/nebular/nebular_scenes.cpp index f82e102bfa..d14120a5b7 100644 --- a/engines/mads/nebular/nebular_scenes.cpp +++ b/engines/mads/nebular/nebular_scenes.cpp @@ -23,7 +23,10 @@ #include "common/scummsys.h" #include "common/config-manager.h" #include "mads/mads.h" +#include "mads/compression.h" +#include "mads/resources.h" #include "mads/scene.h" +#include "mads/nebular/game_nebular.h" #include "mads/nebular/nebular_scenes.h" #include "mads/nebular/nebular_scenes8.h" @@ -46,7 +49,43 @@ SceneLogic *SceneFactory::createScene(MADSEngine *vm) { return new Scene804(vm); } -NebularScene::NebularScene(MADSEngine *vm) : SceneLogic(vm) { +/*------------------------------------------------------------------------*/ + +NebularScene::NebularScene(MADSEngine *vm) : SceneLogic(vm), + _globals(static_cast(vm->_game)->_globals) { +} + +Common::String NebularScene::formAnimName(char sepChar, int suffixNum) { + return Resources::formatName(_scene->_currentSceneId, sepChar, suffixNum, + EXT_NONE, ""); +} + +/*------------------------------------------------------------------------*/ + +void SceneInfoNebular::loadCodes(MSurface &depthSurface) { + File f(Resources::formatName(RESPREFIX_RM, _sceneId, ".DAT")); + MadsPack codesPack(&f); + Common::SeekableReadStream *stream = codesPack.getItemStream(0); + + byte *destP = depthSurface.getData(); + byte *endP = depthSurface.getBasePtr(0, depthSurface.h); + + byte runLength = stream->readByte(); + while (destP < endP && runLength > 0) { + byte runValue = stream->readByte(); + + // Write out the run length + Common::fill(destP, destP + runLength, runValue); + destP += runLength; + + // Get the next run length + runLength = stream->readByte(); + } + + if (destP < endP) + Common::fill(destP, endP, 0); + delete stream; + f.close(); } } // End of namespace Nebular diff --git a/engines/mads/nebular/nebular_scenes.h b/engines/mads/nebular/nebular_scenes.h index 9d617bb543..92b5626bf0 100644 --- a/engines/mads/nebular/nebular_scenes.h +++ b/engines/mads/nebular/nebular_scenes.h @@ -95,6 +95,11 @@ public: class NebularScene : public SceneLogic { protected: Globals &_globals; + + /** + * Forms an animation resoucre name + */ + Common::String formAnimName(char sepChar, int suffixNum); public: /** * Constructor @@ -102,6 +107,17 @@ public: NebularScene(MADSEngine *vm); }; +class SceneInfoNebular : public SceneInfo { + friend class SceneInfo; +protected: + virtual void loadCodes(MSurface &depthSurface); + + /** + * Constructor + */ + SceneInfoNebular(MADSEngine *vm) : SceneInfo(vm) {} +}; + } // End of namespace Nebular } // End of namespace MADS diff --git a/engines/mads/nebular/nebular_scenes8.cpp b/engines/mads/nebular/nebular_scenes8.cpp index d08e64506e..773b0e6d7a 100644 --- a/engines/mads/nebular/nebular_scenes8.cpp +++ b/engines/mads/nebular/nebular_scenes8.cpp @@ -75,6 +75,38 @@ void Scene8xx::enter1() { /*------------------------------------------------------------------------*/ void Scene804::setup() { + _globals._chairHotspotIndex = 0; + _globals._v1 = _globals._v2 = 0; + _globals._v3 = _globals._v4 = 0; + _globals._v5 = -1; + _globals._v6 = _globals._v7 = 0; + _globals._v8 = 0; + if (_globals[5]) { + // Copy protection failed + _globals[165] = 0xFFFF; + _globals[164] = 0; + } + + _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 0)); + _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('x', 1)); + _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('x', 2)); + _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('x', 3)); + _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('x', 4)); + _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('f', 1)); + + _vm->_game->loadQuoteSet(791, 0); + + if (_globals[165]) { + if (_globals[164]) { + _globals._spriteIndexes[19] = _scene->_sequences.startCycle( + _globals._spriteIndexes[4], 0, 1); + // TODO + } else { + + } + } else { + // TODO + } } void Scene804::enter() { diff --git a/engines/mads/resources.h b/engines/mads/resources.h index 01f6490ecc..3d5d582707 100644 --- a/engines/mads/resources.h +++ b/engines/mads/resources.h @@ -36,7 +36,8 @@ enum RESPREFIX { }; enum EXTTYPE { - EXT_SS = 1, EXT_AA = 2, EXT_DAT = 3, EXT_HH = 4, EXT_ART = 5, EXT_INT = 6 + EXT_NONE = -1, EXT_SS = 1, EXT_AA = 2, EXT_DAT = 3, EXT_HH = 4, + EXT_ART = 5, EXT_INT = 6 }; class Resources { diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp index f974be4d1e..bbf46f164c 100644 --- a/engines/mads/scene.cpp +++ b/engines/mads/scene.cpp @@ -28,10 +28,10 @@ namespace MADS { -Scene::Scene(MADSEngine *vm): _vm(vm), _action(_vm), _dirtyAreas(_vm), - _dynamicHotspots(vm), _interface(vm), _kernelMessages(vm), - _screenObjects(vm), _sequences(vm), _spriteSlots(vm), - _textDisplay(vm) { +Scene::Scene(MADSEngine *vm): _vm(vm), _action(_vm), _depthSurface(vm), + _dirtyAreas(_vm), _dynamicHotspots(vm), _interface(vm), + _kernelMessages(vm), _screenObjects(vm), _sequences(vm), + _sprites(vm), _spriteSlots(vm), _textDisplay(vm) { _priorSceneId = 0; _nextSceneId = 0; _currentSceneId = 0; diff --git a/engines/mads/scene.h b/engines/mads/scene.h index f31927d877..3fe3a4eddf 100644 --- a/engines/mads/scene.h +++ b/engines/mads/scene.h @@ -98,7 +98,7 @@ public: int _v1; SceneInfo *_sceneInfo; MSurface _backgroundSurface; - MSurface _depthSurface; + DepthSurface _depthSurface; InterfaceSurface _interface; bool _animFlag; int _animVal1; diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp index 813e9062cf..c15a3876a8 100644 --- a/engines/mads/scene_data.cpp +++ b/engines/mads/scene_data.cpp @@ -383,9 +383,8 @@ void SceneInfo::SpriteInfo::load(Common::SeekableReadStream *f) { SceneInfo *SceneInfo::init(MADSEngine *vm) { if (vm->getGameID() == GType_RexNebular) { - return new SceneInfoNebular(vm); - } - else { + return new Nebular::SceneInfoNebular(vm); + } else { return new SceneInfo(vm); } } @@ -587,34 +586,6 @@ void SceneInfo::loadCodes(MSurface &depthSurface) { /*------------------------------------------------------------------------*/ -void SceneInfoNebular::loadCodes(MSurface &depthSurface) { - File f(Resources::formatName(RESPREFIX_RM, _sceneId, ".DAT")); - MadsPack codesPack(&f); - Common::SeekableReadStream *stream = codesPack.getItemStream(0); - - byte *destP = depthSurface.getData(); - byte *endP = depthSurface.getBasePtr(0, depthSurface.h); - - byte runLength = stream->readByte(); - while (destP < endP && runLength > 0) { - byte runValue = stream->readByte(); - - // Write out the run length - Common::fill(destP, destP + runLength, runValue); - destP += runLength; - - // Get the next run length - runLength = stream->readByte(); - } - - if (destP < endP) - Common::fill(destP, endP, 0); - delete stream; - f.close(); -} - -/*------------------------------------------------------------------------*/ - SceneLogic::SceneLogic(MADSEngine *vm) : _vm(vm) { _scene = &_vm->_game->_scene; } diff --git a/engines/mads/scene_data.h b/engines/mads/scene_data.h index 4d8cfc72cf..d2fd624512 100644 --- a/engines/mads/scene_data.h +++ b/engines/mads/scene_data.h @@ -288,17 +288,6 @@ public: MSurface &depthSurface, MSurface &bgSurface); }; -class SceneInfoNebular : public SceneInfo { - friend class SceneInfo; -protected: - virtual void loadCodes(MSurface &depthSurface); - - /** - * Constructor - */ - SceneInfoNebular(MADSEngine *vm) : SceneInfo(vm) {} -}; - } // End of namespace MADS #endif /* MADS_SCENE_DATA_H */ diff --git a/engines/mads/sequence.cpp b/engines/mads/sequence.cpp index 8f25007b48..33febe3ec7 100644 --- a/engines/mads/sequence.cpp +++ b/engines/mads/sequence.cpp @@ -367,4 +367,23 @@ void SequenceList::scan() { void SequenceList::setDepth(int seqIndex, int depth) { _entries[seqIndex]._depth = depth; } + +int SequenceList::addSpriteCycle(int srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) { + Scene &scene = _vm->_game->_scene; + MSprite *spriteFrame = scene._spriteSlots.getSprite(srcSpriteIdx).getFrame(0); + int depth = scene._depthSurface.getDepth(Common::Point(spriteFrame->_pos.x + + (spriteFrame->w / 2), spriteFrame->_pos.y + (spriteFrame->h / 2))); + + return add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0, + true, 100, depth - 1, 1, ANIMTYPE_CYCLED, 0, 0); +} + +int SequenceList::startCycle(int srcSpriteIndex, bool flipped, int cycleIndex) { + int result = addSpriteCycle(srcSpriteIndex, flipped, INDEFINITE_TIMEOUT, 0, 0, 0); + if (result >= 0) + setAnimRange(result, cycleIndex, cycleIndex); + + return result; +} + } // End of namespace diff --git a/engines/mads/sequence.h b/engines/mads/sequence.h index f73d48bb8f..80f695cf5a 100644 --- a/engines/mads/sequence.h +++ b/engines/mads/sequence.h @@ -102,6 +102,8 @@ public: void setAnimRange(int seqIndex, int startVal, int endVal); void scan(); void setDepth(int seqIndex, int depth); + int addSpriteCycle(int srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks); + int startCycle(int srcSpriteIdx, bool flipped, int cycleIndex); }; } // End of namespace MADS diff --git a/engines/mads/sprites.cpp b/engines/mads/sprites.cpp index 23360b0a00..321acf026d 100644 --- a/engines/mads/sprites.cpp +++ b/engines/mads/sprites.cpp @@ -355,4 +355,8 @@ int SpriteSets::add(SpriteAsset *asset, int idx) { return idx; } +int SpriteSets::addSprites(const Common::String &resName, int flags) { + return add(new SpriteAsset(_vm, resName, flags)); +} + } // End of namespace MADS diff --git a/engines/mads/sprites.h b/engines/mads/sprites.h index 49f13add21..2061a41043 100644 --- a/engines/mads/sprites.h +++ b/engines/mads/sprites.h @@ -201,11 +201,25 @@ public: }; class SpriteSets : public Common::Array { +private: + MADSEngine *_vm; public: + /** + * Constructor + */ + SpriteSets(MADSEngine *vm) : _vm(vm) {} + /** * Add a sprite asset to the list */ int add(SpriteAsset *asset, int idx = 0); + + /** + * Adds a sprite asset to the list by name + */ + int addSprites(const Common::String &resName, int flags = 0); + + int startCycle(int srcSpriteIndex, bool flipped, int cycleIndex); }; } // End of namespace MADS -- cgit v1.2.3