aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2014-04-19 22:49:14 -0400
committerPaul Gilbert2014-04-19 22:49:14 -0400
commit1362414e77bfbd17d7a0224ce5fb7275c793c7c4 (patch)
treeb0b2447e53849b79ee20debbe2b0e0fffaa1742d
parentad6a80cae796f781e7c8a0e53ad008504c54e266 (diff)
downloadscummvm-rg350-1362414e77bfbd17d7a0224ce5fb7275c793c7c4.tar.gz
scummvm-rg350-1362414e77bfbd17d7a0224ce5fb7275c793c7c4.tar.bz2
scummvm-rg350-1362414e77bfbd17d7a0224ce5fb7275c793c7c4.zip
MADS: Implement palette animation code
-rw-r--r--engines/mads/animation.cpp21
-rw-r--r--engines/mads/animation.h4
-rw-r--r--engines/mads/dialogs.cpp4
-rw-r--r--engines/mads/dialogs.h2
-rw-r--r--engines/mads/events.cpp4
-rw-r--r--engines/mads/nebular/nebular_scenes3.cpp8
-rw-r--r--engines/mads/palette.cpp3
-rw-r--r--engines/mads/palette.h10
-rw-r--r--engines/mads/scene.cpp74
-rw-r--r--engines/mads/scene.h16
-rw-r--r--engines/mads/scene_data.cpp32
-rw-r--r--engines/mads/scene_data.h4
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:
/**