diff options
author | Paul Gilbert | 2014-04-19 22:49:14 -0400 |
---|---|---|
committer | Paul Gilbert | 2014-04-19 22:49:14 -0400 |
commit | 1362414e77bfbd17d7a0224ce5fb7275c793c7c4 (patch) | |
tree | b0b2447e53849b79ee20debbe2b0e0fffaa1742d /engines/mads | |
parent | ad6a80cae796f781e7c8a0e53ad008504c54e266 (diff) | |
download | scummvm-rg350-1362414e77bfbd17d7a0224ce5fb7275c793c7c4.tar.gz scummvm-rg350-1362414e77bfbd17d7a0224ce5fb7275c793c7c4.tar.bz2 scummvm-rg350-1362414e77bfbd17d7a0224ce5fb7275c793c7c4.zip |
MADS: Implement palette animation code
Diffstat (limited to 'engines/mads')
-rw-r--r-- | engines/mads/animation.cpp | 21 | ||||
-rw-r--r-- | engines/mads/animation.h | 4 | ||||
-rw-r--r-- | engines/mads/dialogs.cpp | 4 | ||||
-rw-r--r-- | engines/mads/dialogs.h | 2 | ||||
-rw-r--r-- | engines/mads/events.cpp | 4 | ||||
-rw-r--r-- | engines/mads/nebular/nebular_scenes3.cpp | 8 | ||||
-rw-r--r-- | engines/mads/palette.cpp | 3 | ||||
-rw-r--r-- | engines/mads/palette.h | 10 | ||||
-rw-r--r-- | engines/mads/scene.cpp | 74 | ||||
-rw-r--r-- | engines/mads/scene.h | 16 | ||||
-rw-r--r-- | engines/mads/scene_data.cpp | 32 | ||||
-rw-r--r-- | engines/mads/scene_data.h | 4 |
12 files changed, 118 insertions, 64 deletions
diff --git a/engines/mads/animation.cpp b/engines/mads/animation.cpp index fec7f74423..874ce69301 100644 --- a/engines/mads/animation.cpp +++ b/engines/mads/animation.cpp @@ -112,8 +112,7 @@ void AnimFrameEntry::load(Common::SeekableReadStream *f, bool uiFlag) { _frameNumber = f->readUint16LE(); _seqIndex = f->readByte(); _spriteSlot._spritesIndex = f->readByte(); - uint frame = f->readUint16LE(); - _spriteSlot._frameNumber = (frame < 0x80) ? frame : -(frame & 0x7f); + _spriteSlot._frameNumber = f->readSint16LE(); _spriteSlot._position.x = f->readSint16LE(); _spriteSlot._position.y = f->readSint16LE(); _spriteSlot._depth = f->readSByte(); @@ -174,7 +173,7 @@ Animation::~Animation() { } void Animation::load(UserInterface &interfaceSurface, MSurface &depthSurface, - const Common::String &resName, int flags, Common::Array<RGB4> *palAnimData, + const Common::String &resName, int flags, Common::Array<PaletteCycle> *palCycles, SceneInfo *sceneInfo) { Common::String resourceName = resName; if (!resourceName.contains(".")) @@ -191,7 +190,7 @@ void Animation::load(UserInterface &interfaceSurface, MSurface &depthSurface, flags |= PALFLAG_RESERVED; if (flags & ANIMFLAG_LOAD_BACKGROUND) { - loadInterface(interfaceSurface, depthSurface, _header, flags, palAnimData, sceneInfo); + loadInterface(interfaceSurface, depthSurface, _header, flags, palCycles, sceneInfo); } if (flags & ANIMFLAG_LOAD_BACKGROUND_ONLY) { // No data @@ -376,24 +375,24 @@ bool Animation::drawFrame(SpriteAsset &spriteSet, const Common::Point &pt, int f } void Animation::loadInterface(UserInterface &interfaceSurface, MSurface &depthSurface, - AAHeader &header, int flags, Common::Array<RGB4> *palAnimData, SceneInfo *sceneInfo) { + AAHeader &header, int flags, Common::Array<PaletteCycle> *palCycles, SceneInfo *sceneInfo) { _scene->_depthStyle = 0; if (header._animMode <= 2) { _vm->_palette->_paletteUsage.setEmpty(); 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]); + if (palCycles) { + palCycles->clear(); + for (uint i = 0; i < sceneInfo->_paletteCycles.size(); ++i) + palCycles->push_back(sceneInfo->_paletteCycles[i]); } } else if (header._animMode == 4) { // Load a scene interface Common::String resourceName = "*" + header._interfaceFile; interfaceSurface.load(resourceName); - if (palAnimData) - palAnimData->clear(); + if (palCycles) + palCycles->clear(); } else { // Original has useless code here } diff --git a/engines/mads/animation.h b/engines/mads/animation.h index 8afb8cfcef..5faa47841e 100644 --- a/engines/mads/animation.h +++ b/engines/mads/animation.h @@ -165,7 +165,7 @@ private: * Load the user interface display for an animation */ void loadInterface(UserInterface &interfaceSurface, MSurface &depthSurface, - AAHeader &header, int flags, Common::Array<RGB4> *palAnimData, SceneInfo *sceneInfo); + AAHeader &header, int flags, Common::Array<PaletteCycle> *palCycles, SceneInfo *sceneInfo); /** * Returns true if there is a scroll required @@ -192,7 +192,7 @@ public: * Loads animation data */ void load(UserInterface &interfaceSurface, MSurface &depthSurface, const Common::String &resName, - int flags, Common::Array<RGB4> *palAnimData, SceneInfo *sceneInfo); + int flags, Common::Array<PaletteCycle> *palCycles, SceneInfo *sceneInfo); /** * Preload animation data for the scene diff --git a/engines/mads/dialogs.cpp b/engines/mads/dialogs.cpp index 8bc73e55dc..3c771e7ed9 100644 --- a/engines/mads/dialogs.cpp +++ b/engines/mads/dialogs.cpp @@ -125,7 +125,7 @@ TextDialog::TextDialog(MADSEngine *vm, const Common::String &fontName, // Save the high end of the palette, and set up the entries for dialog display Common::copy(&_vm->_palette->_mainPalette[TEXTDIALOG_CONTENT1 * 3], &_vm->_palette->_mainPalette[TEXTDIALOG_CONTENT1 * 3 + 8 * 3], - &_savedPalette[0]); + &_cyclingPalette[0]); Palette::setGradient(_vm->_palette->_mainPalette, TEXTDIALOG_CONTENT1, 2, 0x90, 0x80); Palette::setGradient(_vm->_palette->_mainPalette, TEXTDIALOG_EDGE, 2, 0x9C, 0x70); Palette::setGradient(_vm->_palette->_mainPalette, TEXTDIALOG_FC, 2, 0x90, 0x80); @@ -319,7 +319,7 @@ void TextDialog::drawWithInput() { } void TextDialog::restorePalette() { - Common::copy(&_savedPalette[0], &_savedPalette[8 * 3], + Common::copy(&_cyclingPalette[0], &_cyclingPalette[8 * 3], &_vm->_palette->_mainPalette[248 * 3]); _vm->_palette->setPalette(_vm->_palette->_mainPalette, 248, 8); } diff --git a/engines/mads/dialogs.h b/engines/mads/dialogs.h index 0c24dea5b9..e4f9bbb038 100644 --- a/engines/mads/dialogs.h +++ b/engines/mads/dialogs.h @@ -114,7 +114,7 @@ protected: int _askLineNum; Common::String _lines[TEXT_DIALOG_MAX_LINES]; int _lineXp[TEXT_DIALOG_MAX_LINES]; - byte _savedPalette[8 * 3]; + byte _cyclingPalette[8 * 3]; public: /** * Constructor diff --git a/engines/mads/events.cpp b/engines/mads/events.cpp index 85c62e30bd..ac03dd5665 100644 --- a/engines/mads/events.cpp +++ b/engines/mads/events.cpp @@ -26,6 +26,7 @@ #include "engines/util.h" #include "mads/mads.h" #include "mads/events.h" +#include "mads/scene.h" #define GAME_FRAME_RATE 50 #define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE) @@ -165,6 +166,9 @@ void EventsManager::checkForNextFrameCounter() { ++_frameCounter; _priorFrameTime = milli; + // Do any palette cycling + _vm->_game->_scene.animatePalette(); + // Give time to the debugger _vm->_debugger->onFrame(); diff --git a/engines/mads/nebular/nebular_scenes3.cpp b/engines/mads/nebular/nebular_scenes3.cpp index 603f87535c..8287605270 100644 --- a/engines/mads/nebular/nebular_scenes3.cpp +++ b/engines/mads/nebular/nebular_scenes3.cpp @@ -1786,10 +1786,10 @@ void Scene313::enter() { } if (_globals[kAfterHavoc]) { - for (uint16 i = 0; i < _scene->_animPalData.size(); i++) { - int palIdx = _scene->_animPalData[i]._firstColorIndex; - int size = _scene->_animPalData[i]._colorCount * 3; - memset(&_vm->_palette->_savedPalette[palIdx], 0, size); + for (uint16 i = 0; i < _scene->_paletteCycles.size(); i++) { + int palIdx = _scene->_paletteCycles[i]._firstColorIndex; + int size = _scene->_paletteCycles[i]._colorCount * 3; + memset(&_vm->_palette->_cyclingPalette[palIdx], 0, size); memset(&_vm->_palette->_mainPalette[palIdx], 0, size); } } diff --git a/engines/mads/palette.cpp b/engines/mads/palette.cpp index 64e0f80766..4a3ea04434 100644 --- a/engines/mads/palette.cpp +++ b/engines/mads/palette.cpp @@ -458,7 +458,6 @@ void Palette::resetGamePalette(int lowRange, int highRange) { } void Palette::initPalette() { - RGB4 rgb; uint32 palMask = 1; if (_vm->_game->_player._spritesLoaded && _vm->_game->_player._numSprites) { @@ -528,7 +527,7 @@ void Palette::unlock() { void Palette::refreshHighColors() { int val = 18; if (_vm->_game->_scene._cyclingActive) - val += _vm->_game->_scene._animCount; + val += _vm->_game->_scene._totalCycleColors; setPalette(_mainPalette, val, 256 - val); } diff --git a/engines/mads/palette.h b/engines/mads/palette.h index b306c8acb0..75aff7a6ec 100644 --- a/engines/mads/palette.h +++ b/engines/mads/palette.h @@ -45,13 +45,13 @@ enum { PALFLAG_MASK = 0xfc00 // Mask for all the palette flags }; -struct RGB4 { +struct PaletteCycle { byte _colorCount; - byte g; + byte _firstListColor; byte _firstColorIndex; - byte u; + byte _ticks; - RGB4() { _colorCount = g = _firstColorIndex = u = 0; } + PaletteCycle() { _colorCount = _firstListColor = _firstColorIndex = _ticks = 0; } }; struct RGB6 { @@ -165,7 +165,7 @@ protected: void reset(); public: byte _mainPalette[PALETTE_SIZE]; - byte _savedPalette[PALETTE_SIZE]; + byte _cyclingPalette[PALETTE_SIZE]; uint32 _palFlags[PALETTE_COUNT]; PaletteUsage _paletteUsage; RGBList _rgbList; diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp index aff4aa36aa..78a36d97d1 100644 --- a/engines/mads/scene.cpp +++ b/engines/mads/scene.cpp @@ -38,7 +38,8 @@ Scene::Scene(MADSEngine *vm): _vm(vm), _action(_vm), _depthSurface(vm), _sceneLogic = nullptr; _sceneInfo = nullptr; _cyclingActive = false; - _animVal1 = 0; + _cyclingThreshold = 0; + _cyclingDelay = 0; _depthStyle = 0; _roomChanged = false; _reloadSceneFlag = false; @@ -134,7 +135,7 @@ void Scene::loadScene(int sceneId, const Common::String &prefix, bool palFlag) { _depthSurface, _backgroundSurface); // Initialise palette animation for the scene - initPaletteAnimation(_sceneInfo->_palAnimData, false); + initPaletteAnimation(_sceneInfo->_paletteCycles, false); // Copy over nodes _rails.load(_sceneInfo->_nodes, &_depthSurface, _sceneInfo->_depthStyle); @@ -237,29 +238,75 @@ void Scene::loadVocabStrings() { f.close(); } -void Scene::initPaletteAnimation(Common::Array<RGB4> &animData, bool animFlag) { +void Scene::initPaletteAnimation(Common::Array<PaletteCycle> &palCycles, bool animFlag) { // Initialise the animation palette and ticks list - _animTicksList.clear(); - _animPalData.clear(); + _cycleTicks.clear(); + _paletteCycles.clear(); - for (uint i = 0; i < animData.size(); ++i) { - _animTicksList.push_back(_vm->_events->getFrameCounter()); - _animPalData.push_back(animData[i]); + for (uint i = 0; i < palCycles.size(); ++i) { + _cycleTicks.push_back(_vm->_events->getFrameCounter()); + _paletteCycles.push_back(palCycles[i]); } // Save the initial starting palette Common::copy(&_vm->_palette->_mainPalette[0], &_vm->_palette->_mainPalette[PALETTE_SIZE], - &_vm->_palette->_savedPalette[0]); + &_vm->_palette->_cyclingPalette[0]); // Calculate total - _animCount = 0; - for (uint i = 0; i < _animPalData.size(); ++i) - _animCount += _animPalData[i]._colorCount; + _totalCycleColors = 0; + for (uint i = 0; i < _paletteCycles.size(); ++i) + _totalCycleColors += _paletteCycles[i]._colorCount; - _animVal1 = (_animCount > 16) ? 3 : 0; + _cyclingThreshold = (_totalCycleColors > 16) ? 3 : 0; _cyclingActive = animFlag; } +void Scene::animatePalette() { + byte rgb[3]; + + if (_cyclingActive) { + Scene::_cyclingDelay++; + if (_cyclingDelay >= _cyclingThreshold) { + uint32 frameCounter = _vm->_events->getFrameCounter(); + bool changesFlag = false; + for (int idx = 0; idx < _paletteCycles.size(); idx++) { + if (frameCounter >= (_cycleTicks[idx] + _paletteCycles[idx]._ticks)) { + _cycleTicks[idx] = frameCounter; + int count = _paletteCycles[idx]._colorCount; + int first = _paletteCycles[idx]._firstColorIndex; + int listIndex = _paletteCycles[idx]._firstListColor; + changesFlag = true; + + if (count > 1) { + // Make a copy of the last color + byte *pSrc = &_vm->_palette->_cyclingPalette[first * 3]; + byte *pEnd = pSrc + count * 3; + Common::copy(pEnd - 3, pEnd, &rgb[0]); + + // Shift the cycle palette forward one entry + Common::copy_backward(pSrc, pEnd - 3, pEnd); + + // Move the saved color to the start of the cycle + Common::copy(&rgb[0], &rgb[3], pSrc); + + if (++listIndex >= count) + listIndex = 0; + } + + _paletteCycles[idx]._firstListColor = listIndex; + } + } + + if (changesFlag) { + _vm->_palette->setPalette(_vm->_palette->_cyclingPalette, + _paletteCycles[0]._firstColorIndex, _totalCycleColors); + } + + _cyclingDelay = 0; + } + } +} + bool Scene::getDepthHighBits(const Common::Point &pt) { if (_sceneInfo->_depthStyle == 2) { return 0; @@ -627,5 +674,4 @@ void Scene::freeAnimation() { _freeAnimationFlag = false; } - } // End of namespace MADS diff --git a/engines/mads/scene.h b/engines/mads/scene.h index 7944576a5a..eb84fbd814 100644 --- a/engines/mads/scene.h +++ b/engines/mads/scene.h @@ -55,7 +55,7 @@ private: /* * Initialises the data for palette animation within the scene */ - void initPaletteAnimation(Common::Array<RGB4> &animData, bool animFlag); + void initPaletteAnimation(Common::Array<PaletteCycle> &palCycles, bool animFlag); /** * Handles a single frame within the game scene @@ -106,10 +106,11 @@ public: DepthSurface _depthSurface; UserInterface _userInterface; bool _cyclingActive; - int _animVal1; - int _animCount; - Common::Array<uint32> _animTicksList; - Common::Array<RGB4> _animPalData; + int _cyclingThreshold; + int _cyclingDelay; + int _totalCycleColors; + Common::Array<uint32> _cycleTicks; + Common::Array<PaletteCycle> _paletteCycles; Common::StringArray _vocabStrings; Animation *_animationData; Animation *_activeAnimation; @@ -196,6 +197,11 @@ public: void drawElements(ScreenTransition transitionType, bool surfaceFlag); /** + * Handles cycling palette colors for the scene + */ + void animatePalette(); + + /** * Load an animation */ void loadAnimation(const Common::String &resName, int abortTimers = 0); diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp index d921465c04..9f4d7d99ec 100644 --- a/engines/mads/scene_data.cpp +++ b/engines/mads/scene_data.cpp @@ -63,16 +63,16 @@ void ARTHeader::load(Common::SeekableReadStream *f) { } f->skip(6 * (256 - palCount)); - // Read unknown??? - palCount = f->readUint16LE(); - for (int i = 0; i < palCount; ++i) { - RGB4 rgb; - rgb._colorCount = f->readByte(); - rgb.g = f->readByte(); - rgb._firstColorIndex = f->readByte(); - rgb.u = f->readByte(); - - _palAnimData.push_back(rgb); + // Read palette animations + int cycleCount = f->readUint16LE(); + for (int i = 0; i < cycleCount; ++i) { + PaletteCycle cycle; + cycle._colorCount = f->readByte(); + cycle._firstListColor = f->readByte(); + cycle._firstColorIndex = f->readByte(); + cycle._ticks = f->readByte(); + + _paletteCycles.push_back(cycle); } } @@ -202,9 +202,9 @@ void SceneInfo::load(int sceneId, int variant, const Common::String &resName, artHeader.load(stream); delete stream; - // Copy out the palette data - for (uint i = 0; i < artHeader._palAnimData.size(); ++i) - _palAnimData.push_back(artHeader._palAnimData[i]); + // Copy out the palette animation data + for (uint i = 0; i < artHeader._paletteCycles.size(); ++i) + _paletteCycles.push_back(artHeader._paletteCycles[i]); if (!(flags & 1)) { if (!_vm->_palette->_paletteUsage.empty()) { @@ -217,9 +217,9 @@ void SceneInfo::load(int sceneId, int variant, const Common::String &resName, if (_usageIndex > 0) { _vm->_palette->_paletteUsage.transform(artHeader._palette); - for (uint i = 0; i < _palAnimData.size(); ++i) { - byte g = _palAnimData[i].g; - _palAnimData[i]._firstColorIndex = artHeader._palette[g]._palIndex; + for (uint i = 0; i < _paletteCycles.size(); ++i) { + byte listColor = _paletteCycles[i]._firstListColor; + _paletteCycles[i]._firstColorIndex = artHeader._palette[listColor]._palIndex; } } } diff --git a/engines/mads/scene_data.h b/engines/mads/scene_data.h index e37aa43855..5b3d818b96 100644 --- a/engines/mads/scene_data.h +++ b/engines/mads/scene_data.h @@ -118,7 +118,7 @@ struct ARTHeader { int _width; int _height; Common::Array<RGB6> _palette; - Common::Array<RGB4> _palAnimData; + Common::Array<PaletteCycle> _paletteCycles; void load(Common::SeekableReadStream *f); }; @@ -158,7 +158,7 @@ public: int _field4A; int _usageIndex; - Common::Array<RGB4> _palAnimData; + Common::Array<PaletteCycle> _paletteCycles; WalkNodeList _nodes; public: /** |