aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kiewitz2010-06-20 16:31:24 +0000
committerMartin Kiewitz2010-06-20 16:31:24 +0000
commitb016c16300577ae29d5a78e5be532cef3d4e21ce (patch)
tree4d2688516b33b9ae4a6460d3b44439fddac99a29
parent7ce739f51b1556e211bffc3f82617013afe23cb8 (diff)
downloadscummvm-rg350-b016c16300577ae29d5a78e5be532cef3d4e21ce.tar.gz
scummvm-rg350-b016c16300577ae29d5a78e5be532cef3d4e21ce.tar.bz2
scummvm-rg350-b016c16300577ae29d5a78e5be532cef3d4e21ce.zip
SCI: some kPalVary support - intro of island dr. brain works fine now
svn-id: r50082
-rw-r--r--engines/sci/engine/kgraphics.cpp11
-rw-r--r--engines/sci/graphics/palette.cpp91
-rw-r--r--engines/sci/graphics/palette.h18
3 files changed, 94 insertions, 26 deletions
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index da0f533709..f011f0e2d6 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -646,14 +646,15 @@ reg_t kPalVary(EngineState *s, int argc, reg_t *argv) {
switch (operation) {
case 0: { // Init
GuiResourceId paletteId;
- uint16 ticks, paletteStop, paletteDirection;
+ uint16 ticks, stepStop;
+ int16 direction;
if ((argc >= 3) && (argc <= 5)) {
paletteId = argv[1].toUint16();
ticks = argv[2].toUint16();
- paletteStop = argc >= 4 ? argv[3].toUint16() : 64;
- paletteDirection = argc >= 5 ? argv[4].toUint16() : 1;
- g_sci->_gfxPalette->kernelPalVaryInit(paletteId, ticks);
- warning("kPalVary(init) called with paletteId = %d, ticks = %d, stop = %d, direction = %d", paletteId, ticks, paletteStop, paletteDirection);
+ stepStop = argc >= 4 ? argv[3].toUint16() : 64;
+ direction = argc >= 5 ? argv[4].toUint16() : 1;
+ g_sci->_gfxPalette->kernelPalVaryInit(paletteId, ticks, stepStop, direction);
+ warning("kPalVary(init) called with paletteId = %d, ticks = %d, stop = %d, direction = %d", paletteId, ticks, stepStop, direction);
} else {
warning("kPalVary(init) called with unsupported argc %d", argc);
}
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index 5a0a661a56..68483ac954 100644
--- a/engines/sci/graphics/palette.cpp
+++ b/engines/sci/graphics/palette.cpp
@@ -212,6 +212,10 @@ void GfxPalette::setEGA() {
void GfxPalette::set(Palette *newPalette, bool force, bool forceRealMerge) {
uint32 systime = _sysPalette.timestamp;
+ // Pal-Vary is taking place -> abort merge
+ if (_palVaryResourceId != -1)
+ return;
+
if (force || newPalette->timestamp != systime) {
_sysPaletteChanged |= merge(newPalette, force, forceRealMerge);
newPalette->timestamp = _sysPalette.timestamp;
@@ -475,17 +479,36 @@ void GfxPalette::kernelAssertPalette(GuiResourceId resourceId) {
// Saving/restoring
// need to save start and target-palette, when palVaryOn = true
-void GfxPalette::kernelPalVaryInit(GuiResourceId resourceId, uint16 ticks) {
- kernelSetFromResource(resourceId, true);
- return;
+void GfxPalette::palVaryInit() {
+ _palVaryResourceId = -1;
+ _palVaryPaused = 0;
+ _palVarySignal = 0;
+ _palVaryStep = 0;
+ _palVaryStepStop = 0;
+ _palVaryDirection = 0;
+}
- if (_palVaryResourceId >= 0) // another palvary is taking place, return
+void GfxPalette::kernelPalVaryInit(GuiResourceId resourceId, uint16 ticks, uint16 stepStop, int16 direction) {
+ //kernelSetFromResource(resourceId, true);
+ //return;
+ if (_palVaryResourceId != -1) // another palvary is taking place, return
return;
_palVaryResourceId = resourceId;
- _palVarySignal = 0;
- // Call signal increase every [ticks]
- g_sci->getTimerManager()->installTimerProc(&palVaryCallback, 1000000 / 60 * ticks, this);
+ Resource *palResource = _resMan->findResource(ResourceId(kResourceTypePalette, resourceId), 0);
+ if (palResource) {
+ // Load and initialize destination palette
+ createFromData(palResource->data, &_palVaryTargetPalette);
+ // Save current palette
+ memcpy(&_palVaryOriginPalette, &_sysPalette, sizeof(Palette));
+
+ _palVarySignal = 0;
+ _palVaryStep = 1;
+ _palVaryStepStop = stepStop;
+ _palVaryDirection = direction;
+ // Call signal increase every [ticks]
+ g_sci->getTimerManager()->installTimerProc(&palVaryCallback, 1000000 / 60 * ticks, this);
+ }
}
void GfxPalette::kernelPalVaryToggle(bool pause) {
@@ -503,17 +526,11 @@ void GfxPalette::kernelPalVaryDeinit() {
g_sci->getTimerManager()->removeTimerProc(&palVaryCallback);
// HACK: just set the target palette
- kernelSetFromResource(_palVaryResourceId, true);
+ //kernelSetFromResource(_palVaryResourceId, true);
_palVaryResourceId = -1; // invalidate the target palette
}
-void GfxPalette::palVaryInit() {
- _palVaryResourceId = -1;
- _palVaryPaused = 0;
- _palVarySignal = 0;
-}
-
void GfxPalette::palVaryCallback(void *refCon) {
((GfxPalette *)refCon)->palVaryIncreaseSignal();
}
@@ -525,7 +542,53 @@ void GfxPalette::palVaryIncreaseSignal() {
// Actually do the pal vary processing
void GfxPalette::palVaryUpdate() {
+ if (_palVarySignal) {
+ palVaryProcess(_palVarySignal, true);
+ _palVarySignal = 0;
+ }
+}
+
+// Processes pal vary updates
+void GfxPalette::palVaryProcess(int signal, bool setPalette) {
+ int16 stepChange = signal * _palVaryDirection;
+
+ _palVaryStep += stepChange;
+ if (stepChange > 0) {
+ if (_palVaryStep > _palVaryStepStop)
+ _palVaryStep = _palVaryStepStop;
+ } else {
+ if (_palVaryStep < _palVaryStepStop) {
+ if (!signal)
+ _palVaryStep = _palVaryStepStop;
+ }
+ }
+ // We don't need updates anymore, if we reached end-position
+ if (_palVaryStep == _palVaryStepStop)
+ g_sci->getTimerManager()->removeTimerProc(&palVaryCallback);
+
+ // Calculate inbetween palette
+ Sci::Color inbetween;
+ int16 color;
+ for (int colorNr = 1; colorNr < 255; colorNr++) {
+ inbetween.used = _sysPalette.colors[colorNr].used;
+ color = _palVaryTargetPalette.colors[colorNr].r - _palVaryOriginPalette.colors[colorNr].r;
+ inbetween.r = ((color * _palVaryStep) >> 6) + _palVaryOriginPalette.colors[colorNr].r;
+ color = _palVaryTargetPalette.colors[colorNr].g - _palVaryOriginPalette.colors[colorNr].g;
+ inbetween.g = ((color * _palVaryStep) >> 6) + _palVaryOriginPalette.colors[colorNr].g;
+ color = _palVaryTargetPalette.colors[colorNr].b - _palVaryOriginPalette.colors[colorNr].b;
+ inbetween.b = ((color * _palVaryStep) >> 6) + _palVaryOriginPalette.colors[colorNr].b;
+
+ if (memcmp(&inbetween, &_sysPalette.colors[colorNr], sizeof(Sci::Color))) {
+ _sysPalette.colors[colorNr] = inbetween;
+ _sysPaletteChanged = true;
+ }
+ }
+
+ if ((_sysPaletteChanged) && (setPalette) && (_screen->_picNotValid == 0)) {
+ setOnScreen();
+ _sysPaletteChanged = false;
+ }
}
} // End of namespace Sci
diff --git a/engines/sci/graphics/palette.h b/engines/sci/graphics/palette.h
index af649015d5..861684ecb4 100644
--- a/engines/sci/graphics/palette.h
+++ b/engines/sci/graphics/palette.h
@@ -62,10 +62,11 @@ public:
void kernelAnimateSet();
void kernelAssertPalette(GuiResourceId resourceId);
- void kernelPalVaryInit(GuiResourceId resourceId, uint16 ticks);
+ void kernelPalVaryInit(GuiResourceId resourceId, uint16 ticks, uint16 stopPercentage, int16 direction);
void kernelPalVaryToggle(bool pause);
void kernelPalVaryDeinit();
void palVaryUpdate();
+ void palVaryProcess(int signal, bool setPalette);
Palette _sysPalette;
@@ -77,16 +78,19 @@ private:
GfxScreen *_screen;
ResourceManager *_resMan;
- GuiResourceId _palVaryResourceId;
- uint32 _palVaryStart;
- uint32 _palVaryEnd;
- int _palVaryPaused;
- int _palVarySignal;
-
bool _sysPaletteChanged;
bool _alwaysForceRealMerge;
Common::Array<PalSchedule> _schedules;
+
+ GuiResourceId _palVaryResourceId;
+ Palette _palVaryOriginPalette;
+ Palette _palVaryTargetPalette;
+ uint16 _palVaryStep;
+ uint16 _palVaryStepStop;
+ int16 _palVaryDirection;
+ int _palVaryPaused;
+ int _palVarySignal;
};
} // End of namespace Sci