aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Snover2016-01-06 20:00:28 -0600
committerColin Snover2016-01-07 16:35:09 -0600
commitaeee621e4413fe71ffada6c4bc096ae2a5a8c204 (patch)
tree41817ee3e96fcc279988bb5e604553694e2737ba
parent453afd7bbc7b83506638bf87b830384078f729e1 (diff)
downloadscummvm-rg350-aeee621e4413fe71ffada6c4bc096ae2a5a8c204.tar.gz
scummvm-rg350-aeee621e4413fe71ffada6c4bc096ae2a5a8c204.tar.bz2
scummvm-rg350-aeee621e4413fe71ffada6c4bc096ae2a5a8c204.zip
SCI32: Add initial support for palette cycling (kPalCycle) and fading (kPalFade)
Graphics palette code was rewritten between SCI1 and SCI2, so SCI32 palette engine code has been moved to a separate GfxPalette32 class.
-rw-r--r--engines/sci/console.cpp6
-rw-r--r--engines/sci/engine/kgraphics.cpp50
-rw-r--r--engines/sci/engine/kgraphics32.cpp103
-rw-r--r--engines/sci/engine/kpathing.cpp12
-rw-r--r--engines/sci/engine/kvideo.cpp2
-rw-r--r--engines/sci/engine/savegame.cpp2
-rw-r--r--engines/sci/graphics/frameout.cpp9
-rw-r--r--engines/sci/graphics/frameout.h4
-rw-r--r--engines/sci/graphics/maciconbar.cpp2
-rw-r--r--engines/sci/graphics/palette.cpp64
-rw-r--r--engines/sci/graphics/palette.h10
-rw-r--r--engines/sci/graphics/palette32.cpp350
-rw-r--r--engines/sci/graphics/palette32.h122
-rw-r--r--engines/sci/module.mk1
-rw-r--r--engines/sci/sci.cpp42
-rw-r--r--engines/sci/sci.h5
16 files changed, 607 insertions, 177 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 5cd7b9f7ca..438c725324 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -487,8 +487,8 @@ bool Console::cmdGetVersion(int argc, const char **argv) {
debugPrintf("SCI2.1 kernel table: %s\n", (_engine->_features->detectSci21KernelType() == SCI_VERSION_2) ? "modified SCI2 (old)" : "SCI2.1 (new)");
#endif
debugPrintf("View type: %s\n", viewTypeDesc[g_sci->getResMan()->getViewType()]);
- debugPrintf("Uses palette merging: %s\n", g_sci->_gfxPalette->isMerging() ? "yes" : "no");
- debugPrintf("Uses 16 bit color matching: %s\n", g_sci->_gfxPalette->isUsing16bitColorMatch() ? "yes" : "no");
+ debugPrintf("Uses palette merging: %s\n", g_sci->_gfxPalette16->isMerging() ? "yes" : "no");
+ debugPrintf("Uses 16 bit color matching: %s\n", g_sci->_gfxPalette16->isUsing16bitColorMatch() ? "yes" : "no");
debugPrintf("Resource volume version: %s\n", g_sci->getResMan()->getVolVersionDesc());
debugPrintf("Resource map version: %s\n", g_sci->getResMan()->getMapVersionDesc());
debugPrintf("Contains selector vocabulary (vocab.997): %s\n", hasVocab997 ? "yes" : "no");
@@ -1618,7 +1618,7 @@ bool Console::cmdSetPalette(int argc, const char **argv) {
uint16 resourceId = atoi(argv[1]);
- _engine->_gfxPalette->kernelSetFromResource(resourceId, true);
+ _engine->_gfxPalette16->kernelSetFromResource(resourceId, true);
return true;
}
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 8b790e6a58..0b945c1eec 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -254,7 +254,7 @@ reg_t kGraph(EngineState *s, int argc, reg_t *argv) {
}
reg_t kGraphGetColorCount(EngineState *s, int argc, reg_t *argv) {
- return make_reg(0, g_sci->_gfxPalette->getTotalColorCount());
+ return make_reg(0, g_sci->_gfxPalette16->getTotalColorCount());
}
reg_t kGraphDrawLine(EngineState *s, int argc, reg_t *argv) {
@@ -596,10 +596,10 @@ reg_t kPaletteSetFromResource(EngineState *s, int argc, reg_t *argv) {
// Non-VGA games don't use palette resources.
// This has been changed to 64 colors because Longbow Amiga does have
// one palette (palette 999).
- if (g_sci->_gfxPalette->getTotalColorCount() < 64)
+ if (g_sci->_gfxPalette16->getTotalColorCount() < 64)
return s->r_acc;
- g_sci->_gfxPalette->kernelSetFromResource(resourceId, force);
+ g_sci->_gfxPalette16->kernelSetFromResource(resourceId, force);
return s->r_acc;
}
@@ -607,7 +607,7 @@ reg_t kPaletteSetFlag(EngineState *s, int argc, reg_t *argv) {
uint16 fromColor = CLIP<uint16>(argv[0].toUint16(), 1, 255);
uint16 toColor = CLIP<uint16>(argv[1].toUint16(), 1, 255);
uint16 flags = argv[2].toUint16();
- g_sci->_gfxPalette->kernelSetFlag(fromColor, toColor, flags);
+ g_sci->_gfxPalette16->kernelSetFlag(fromColor, toColor, flags);
return s->r_acc;
}
@@ -615,7 +615,7 @@ reg_t kPaletteUnsetFlag(EngineState *s, int argc, reg_t *argv) {
uint16 fromColor = CLIP<uint16>(argv[0].toUint16(), 1, 255);
uint16 toColor = CLIP<uint16>(argv[1].toUint16(), 1, 255);
uint16 flags = argv[2].toUint16();
- g_sci->_gfxPalette->kernelUnsetFlag(fromColor, toColor, flags);
+ g_sci->_gfxPalette16->kernelUnsetFlag(fromColor, toColor, flags);
return s->r_acc;
}
@@ -626,10 +626,10 @@ reg_t kPaletteSetIntensity(EngineState *s, int argc, reg_t *argv) {
bool setPalette = (argc < 4) ? true : (argv[3].isNull()) ? true : false;
// Palette intensity in non-VGA SCI1 games has been removed
- if (g_sci->_gfxPalette->getTotalColorCount() < 256)
+ if (g_sci->_gfxPalette16->getTotalColorCount() < 256)
return s->r_acc;
- g_sci->_gfxPalette->kernelSetIntensity(fromColor, toColor, intensity, setPalette);
+ g_sci->_gfxPalette16->kernelSetIntensity(fromColor, toColor, intensity, setPalette);
return s->r_acc;
}
@@ -637,7 +637,7 @@ reg_t kPaletteFindColor(EngineState *s, int argc, reg_t *argv) {
uint16 r = argv[0].toUint16();
uint16 g = argv[1].toUint16();
uint16 b = argv[2].toUint16();
- return make_reg(0, g_sci->_gfxPalette->kernelFindColor(r, g, b));
+ return make_reg(0, g_sci->_gfxPalette16->kernelFindColor(r, g, b));
}
reg_t kPaletteAnimate(EngineState *s, int argc, reg_t *argv) {
@@ -645,18 +645,18 @@ reg_t kPaletteAnimate(EngineState *s, int argc, reg_t *argv) {
bool paletteChanged = false;
// Palette animation in non-VGA SCI1 games has been removed
- if (g_sci->_gfxPalette->getTotalColorCount() < 256)
+ if (g_sci->_gfxPalette16->getTotalColorCount() < 256)
return s->r_acc;
for (argNr = 0; argNr < argc; argNr += 3) {
uint16 fromColor = argv[argNr].toUint16();
uint16 toColor = argv[argNr + 1].toUint16();
int16 speed = argv[argNr + 2].toSint16();
- if (g_sci->_gfxPalette->kernelAnimate(fromColor, toColor, speed))
+ if (g_sci->_gfxPalette16->kernelAnimate(fromColor, toColor, speed))
paletteChanged = true;
}
if (paletteChanged)
- g_sci->_gfxPalette->kernelAnimateSet();
+ g_sci->_gfxPalette16->kernelAnimateSet();
// WORKAROUND: The game scripts in SQ4 floppy count the number of elapsed
// cycles in the intro from the number of successive kAnimate calls during
@@ -676,11 +676,11 @@ reg_t kPaletteAnimate(EngineState *s, int argc, reg_t *argv) {
}
reg_t kPaletteSave(EngineState *s, int argc, reg_t *argv) {
- return g_sci->_gfxPalette->kernelSave();
+ return g_sci->_gfxPalette16->kernelSave();
}
reg_t kPaletteRestore(EngineState *s, int argc, reg_t *argv) {
- g_sci->_gfxPalette->kernelRestore(argv[0]);
+ g_sci->_gfxPalette16->kernelRestore(argv[0]);
return argv[0];
}
@@ -695,7 +695,7 @@ reg_t kPalVaryInit(EngineState *s, int argc, reg_t *argv) {
uint16 ticks = argv[1].toUint16();
uint16 stepStop = argc >= 3 ? argv[2].toUint16() : 64;
uint16 direction = argc >= 4 ? argv[3].toUint16() : 1;
- if (g_sci->_gfxPalette->kernelPalVaryInit(paletteId, ticks, stepStop, direction))
+ if (g_sci->_gfxPalette16->kernelPalVaryInit(paletteId, ticks, stepStop, direction))
return SIGNAL_REG;
return NULL_REG;
}
@@ -705,40 +705,40 @@ reg_t kPalVaryReverse(EngineState *s, int argc, reg_t *argv) {
int16 stepStop = argc >= 2 ? argv[1].toUint16() : 0;
int16 direction = argc >= 3 ? argv[2].toSint16() : -1;
- return make_reg(0, g_sci->_gfxPalette->kernelPalVaryReverse(ticks, stepStop, direction));
+ return make_reg(0, g_sci->_gfxPalette16->kernelPalVaryReverse(ticks, stepStop, direction));
}
reg_t kPalVaryGetCurrentStep(EngineState *s, int argc, reg_t *argv) {
- return make_reg(0, g_sci->_gfxPalette->kernelPalVaryGetCurrentStep());
+ return make_reg(0, g_sci->_gfxPalette16->kernelPalVaryGetCurrentStep());
}
reg_t kPalVaryDeinit(EngineState *s, int argc, reg_t *argv) {
- g_sci->_gfxPalette->kernelPalVaryDeinit();
+ g_sci->_gfxPalette16->kernelPalVaryDeinit();
return NULL_REG;
}
reg_t kPalVaryChangeTarget(EngineState *s, int argc, reg_t *argv) {
GuiResourceId paletteId = argv[0].toUint16();
- int16 currentStep = g_sci->_gfxPalette->kernelPalVaryChangeTarget(paletteId);
+ int16 currentStep = g_sci->_gfxPalette16->kernelPalVaryChangeTarget(paletteId);
return make_reg(0, currentStep);
}
reg_t kPalVaryChangeTicks(EngineState *s, int argc, reg_t *argv) {
uint16 ticks = argv[0].toUint16();
- g_sci->_gfxPalette->kernelPalVaryChangeTicks(ticks);
+ g_sci->_gfxPalette16->kernelPalVaryChangeTicks(ticks);
return NULL_REG;
}
reg_t kPalVaryPauseResume(EngineState *s, int argc, reg_t *argv) {
bool pauseState = !argv[0].isNull();
- g_sci->_gfxPalette->kernelPalVaryPause(pauseState);
+ g_sci->_gfxPalette16->kernelPalVaryPause(pauseState);
return NULL_REG;
}
reg_t kAssertPalette(EngineState *s, int argc, reg_t *argv) {
GuiResourceId paletteId = argv[0].toUint16();
- g_sci->_gfxPalette->kernelAssertPalette(paletteId);
+ g_sci->_gfxPalette16->kernelAssertPalette(paletteId);
return s->r_acc;
}
@@ -1253,16 +1253,16 @@ reg_t kRemapColors(EngineState *s, int argc, reg_t *argv) {
switch (operation) {
case 0: { // remap by percent
uint16 percent = argv[1].toUint16();
- g_sci->_gfxPalette->resetRemapping();
- g_sci->_gfxPalette->setRemappingPercent(254, percent);
+ g_sci->_gfxPalette16->resetRemapping();
+ g_sci->_gfxPalette16->setRemappingPercent(254, percent);
}
break;
case 1: { // remap by range
uint16 from = argv[1].toUint16();
uint16 to = argv[2].toUint16();
uint16 base = argv[3].toUint16();
- g_sci->_gfxPalette->resetRemapping();
- g_sci->_gfxPalette->setRemappingRange(254, from, to, base);
+ g_sci->_gfxPalette16->resetRemapping();
+ g_sci->_gfxPalette16->setRemappingRange(254, from, to, base);
}
break;
case 2: // turn remapping off (unused)
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 8953f45266..5de440c536 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -49,6 +49,7 @@
#include "sci/graphics/text16.h"
#include "sci/graphics/view.h"
#ifdef ENABLE_SCI32
+#include "sci/graphics/palette32.h"
#include "sci/graphics/controls32.h"
#include "sci/graphics/font.h" // TODO: remove once kBitmap is moved in a separate class
#include "sci/graphics/text32.h"
@@ -707,66 +708,64 @@ reg_t kPalVaryUnknown2(EngineState *s, int argc, reg_t *argv) {
return kStub(s, argc, argv);
}
+enum {
+ kSetCycle = 0,
+ kDoCycle = 1,
+ kCyclePause = 2,
+ kCycleOn = 3,
+ kCycleOff = 4
+};
+
reg_t kPalCycle(EngineState *s, int argc, reg_t *argv) {
// Examples: GK1 room 480 (Bayou ritual), LSL6 room 100 (title screen)
switch (argv[0].toUint16()) {
- case 0: { // Palette animation initialization
- // 3 or 4 extra params
- // Case 1 sends fromColor and speed again, so we don't need them here.
- // Only toColor is stored
- //uint16 fromColor = argv[1].toUint16();
- s->_palCycleToColor = argv[2].toUint16();
- //uint16 speed = argv[3].toUint16();
-
- // Invalidate the picture, so that the palette steps calls (case 1
- // below) can update its palette without it being overwritten by the
- // view/picture palettes.
- g_sci->_gfxScreen->_picNotValid = 1;
-
- // TODO: The fourth optional parameter is an unknown integer, and is 0 by default
- if (argc == 5) {
- // When this variant is used, picNotValid doesn't seem to be set
- // (e.g. GK1 room 480). In this case, the animation step calls are
- // not made, so perhaps this signifies the palette cycling steps
- // to make.
- // GK1 sets this to 6 (6 palette steps?)
- g_sci->_gfxScreen->_picNotValid = 0;
- }
- kStub(s, argc, argv);
+ case kSetCycle: {
+ uint16 fromColor = argv[1].toUint16();
+ uint16 toColor = argv[2].toUint16();
+ int16 direction = argv[3].toSint16();
+ uint16 delay = (argc == 4 ? 0 : argv[4].toUint16());
+
+ g_sci->_gfxPalette32->setCycle(fromColor, toColor, direction, delay);
}
break;
- case 1: { // Palette animation step
- // This is the same as the old kPaletteAnimate call, with 1 set of colors.
- // The end color is set up during initialization in case 0 above.
-
- // 1 or 2 extra params
+ case kDoCycle: {
uint16 fromColor = argv[1].toUint16();
- uint16 speed = (argc == 2) ? 1 : argv[2].toUint16();
- // TODO: For some reason, this doesn't set the color correctly
- // (e.g. LSL6 intro, room 100, Sierra logo)
- if (g_sci->_gfxPalette->kernelAnimate(fromColor, s->_palCycleToColor, speed))
- g_sci->_gfxPalette->kernelAnimateSet();
+ int16 speed = (argc == 2) ? 1 : argv[2].toSint16();
+ g_sci->_gfxPalette32->doCycle(fromColor, speed);
}
- // No kStub() call here, as this gets called loads of times, like kPaletteAnimate
break;
- // case 2 hasn't been encountered
- // case 3 hasn't been encountered
- case 4: // reset any palette cycling and make the picture valid again
- // Gets called when changing rooms and after palette cycling animations finish
- // 0 or 1 extra params
+ case kCyclePause: {
if (argc == 1) {
- g_sci->_gfxScreen->_picNotValid = 0;
- // TODO: This also seems to perform more steps
+ g_sci->_gfxPalette32->cycleAllPause();
} else {
- // The variant with the 1 extra param resets remapping to base
- // TODO
+ uint16 fromColor = argv[1].toUint16();
+ g_sci->_gfxPalette32->cyclePause(fromColor);
+ }
+ }
+ break;
+ case kCycleOn: {
+ if (argc == 1) {
+ g_sci->_gfxPalette32->cycleAllOn();
+ } else {
+ uint16 fromColor = argv[1].toUint16();
+ g_sci->_gfxPalette32->cycleOn(fromColor);
+ }
+ }
+ break;
+ case kCycleOff: {
+ if (argc == 1) {
+ g_sci->_gfxPalette32->cycleAllOff();
+ } else {
+ uint16 fromColor = argv[1].toUint16();
+ g_sci->_gfxPalette32->cycleOff(fromColor);
}
- kStub(s, argc, argv);
break;
+ }
default:
- // TODO
- kStub(s, argc, argv);
+ // In SCI2.1 there are no values above 4, so should never get here;
+ // SCI just returns early if this ever happens.
+ assert(false);
break;
}
@@ -787,7 +786,7 @@ reg_t kRemapColors32(EngineState *s, int argc, reg_t *argv) {
int16 base = (argc >= 2) ? argv[1].toSint16() : 0;
if (base > 0)
warning("kRemapColors(0) called with base %d", base);
- g_sci->_gfxPalette->resetRemapping();
+ g_sci->_gfxPalette32->resetRemapping();
}
break;
case 1: { // remap by range
@@ -798,7 +797,7 @@ reg_t kRemapColors32(EngineState *s, int argc, reg_t *argv) {
uint16 unk5 = (argc >= 6) ? argv[5].toUint16() : 0;
if (unk5 > 0)
warning("kRemapColors(1) called with 6 parameters, unknown parameter is %d", unk5);
- g_sci->_gfxPalette->setRemappingRange(color, from, to, base);
+ g_sci->_gfxPalette32->setRemappingRange(color, from, to, base);
}
break;
case 2: { // remap by percent
@@ -806,7 +805,7 @@ reg_t kRemapColors32(EngineState *s, int argc, reg_t *argv) {
uint16 percent = argv[2].toUint16(); // 0 - 100
if (argc >= 4)
warning("RemapByPercent called with 4 parameters, unknown parameter is %d", argv[3].toUint16());
- g_sci->_gfxPalette->setRemappingPercent(color, percent);
+ g_sci->_gfxPalette32->setRemappingPercent(color, percent);
}
break;
case 3: { // remap to gray
@@ -816,7 +815,7 @@ reg_t kRemapColors32(EngineState *s, int argc, reg_t *argv) {
int16 percent = argv[2].toSint16(); // 0 - 100
if (argc >= 4)
warning("RemapToGray called with 4 parameters, unknown parameter is %d", argv[3].toUint16());
- g_sci->_gfxPalette->setRemappingPercentGray(color, percent);
+ g_sci->_gfxPalette32->setRemappingPercentGray(color, percent);
}
break;
case 4: { // remap to percent gray
@@ -826,7 +825,7 @@ reg_t kRemapColors32(EngineState *s, int argc, reg_t *argv) {
// argv[3] is unknown (a number, e.g. 200) - start color, perhaps?
if (argc >= 5)
warning("RemapToGrayPercent called with 5 parameters, unknown parameter is %d", argv[4].toUint16());
- g_sci->_gfxPalette->setRemappingPercentGray(color, percent);
+ g_sci->_gfxPalette32->setRemappingPercentGray(color, percent);
}
break;
case 5: { // don't map to range
@@ -834,7 +833,7 @@ reg_t kRemapColors32(EngineState *s, int argc, reg_t *argv) {
uint16 intensity = argv[2].toUint16();
// HACK for PQ4
if (g_sci->getGameId() == GID_PQ4)
- g_sci->_gfxPalette->kernelSetIntensity(0, 255, intensity, true);
+ g_sci->_gfxPalette32->kernelSetIntensity(0, 255, intensity, true);
kStub(s, argc, argv);
}
diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp
index 67d814b86f..5b2245e84d 100644
--- a/engines/sci/engine/kpathing.cpp
+++ b/engines/sci/engine/kpathing.cpp
@@ -312,10 +312,10 @@ static void draw_line(EngineState *s, Common::Point p1, Common::Point p2, int ty
// Red : Barred access
// Yellow: Contained access
int poly_colors[4] = {
- g_sci->_gfxPalette->kernelFindColor(0, 255, 0), // green
- g_sci->_gfxPalette->kernelFindColor(0, 0, 255), // blue
- g_sci->_gfxPalette->kernelFindColor(255, 0, 0), // red
- g_sci->_gfxPalette->kernelFindColor(255, 255, 0) // yellow
+ g_sci->_gfxPalette16->kernelFindColor(0, 255, 0), // green
+ g_sci->_gfxPalette16->kernelFindColor(0, 0, 255), // blue
+ g_sci->_gfxPalette16->kernelFindColor(255, 0, 0), // red
+ g_sci->_gfxPalette16->kernelFindColor(255, 255, 0) // yellow
};
// Clip
@@ -334,8 +334,8 @@ static void draw_point(EngineState *s, Common::Point p, int start, int width, in
// Green: End point
// Blue: Starting point
int point_colors[2] = {
- g_sci->_gfxPalette->kernelFindColor(0, 255, 0), // green
- g_sci->_gfxPalette->kernelFindColor(0, 0, 255) // blue
+ g_sci->_gfxPalette16->kernelFindColor(0, 255, 0), // green
+ g_sci->_gfxPalette16->kernelFindColor(0, 0, 255) // blue
};
Common::Rect rect = Common::Rect(p.x - 1, p.y - 1, p.x - 1 + 3, p.y - 1 + 3);
diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp
index 6920466711..8db0c542eb 100644
--- a/engines/sci/engine/kvideo.cpp
+++ b/engines/sci/engine/kvideo.cpp
@@ -231,7 +231,7 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) {
initGraphics(screenWidth, screenHeight, screenWidth > 320);
else {
g_sci->_gfxScreen->kernelSyncWithFramebuffer();
- g_sci->_gfxPalette->kernelSyncScreenPalette();
+ g_sci->_gfxPalette16->kernelSyncScreenPalette();
}
}
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index b464d347bd..09ccff39ac 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -304,7 +304,7 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) {
_segMan->saveLoadWithSerializer(s);
g_sci->_soundCmd->syncPlayList(s);
- g_sci->_gfxPalette->saveLoadWithSerializer(s);
+ g_sci->_gfxPalette16->saveLoadWithSerializer(s);
}
void Vocabulary::saveLoadWithSerializer(Common::Serializer &s) {
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index 61aeb00ac3..7396115f4c 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -44,7 +44,7 @@
#include "sci/graphics/view.h"
#include "sci/graphics/screen.h"
#include "sci/graphics/paint32.h"
-#include "sci/graphics/palette.h"
+#include "sci/graphics/palette32.h"
#include "sci/graphics/picture.h"
#include "sci/graphics/text32.h"
#include "sci/graphics/frameout.h"
@@ -59,7 +59,7 @@ enum SciSpeciaPlanelPictureCodes {
kPlanePlainColored = 0xffff // -1
};
-GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, GfxCache *cache, GfxScreen *screen, GfxPalette *palette, GfxPaint32 *paint32)
+GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, GfxCache *cache, GfxScreen *screen, GfxPalette32 *palette, GfxPaint32 *paint32)
: _segMan(segMan), _resMan(resMan), _cache(cache), _screen(screen), _palette(palette), _paint32(paint32) {
_coordAdjuster = (GfxCoordAdjuster32 *)coordAdjuster;
@@ -658,6 +658,11 @@ void GfxFrameout::kernelFrameout() {
}
_palette->palVaryUpdate();
+ _palette->applyCycles();
+ _palette->applyFade();
+ // TODO: This should probably not require screen pic invalidation
+ _screen->_picNotValid = 1;
+ _palette->setOnScreen();
for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) {
reg_t planeObject = it->object;
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h
index e0c60f92c1..a422572ef4 100644
--- a/engines/sci/graphics/frameout.h
+++ b/engines/sci/graphics/frameout.h
@@ -114,7 +114,7 @@ class GfxScreen;
*/
class GfxFrameout {
public:
- GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, GfxCache *cache, GfxScreen *screen, GfxPalette *palette, GfxPaint32 *paint32);
+ GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, GfxCache *cache, GfxScreen *screen, GfxPalette32 *palette, GfxPaint32 *paint32);
~GfxFrameout();
void kernelAddPlane(reg_t object);
@@ -161,7 +161,7 @@ private:
ResourceManager *_resMan;
GfxCoordAdjuster32 *_coordAdjuster;
GfxCache *_cache;
- GfxPalette *_palette;
+ GfxPalette32 *_palette;
GfxScreen *_screen;
GfxPaint32 *_paint32;
diff --git a/engines/sci/graphics/maciconbar.cpp b/engines/sci/graphics/maciconbar.cpp
index 8e2e12b7bd..e10b9fddbf 100644
--- a/engines/sci/graphics/maciconbar.cpp
+++ b/engines/sci/graphics/maciconbar.cpp
@@ -234,7 +234,7 @@ void GfxMacIconBar::remapColors(Graphics::Surface *surf, const byte *palette) {
byte g = palette[color * 3 + 1];
byte b = palette[color * 3 + 2];
- *pixels++ = g_sci->_gfxPalette->findMacIconBarColor(r, g, b);
+ *pixels++ = g_sci->_gfxPalette16->findMacIconBarColor(r, g, b);
}
}
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index 59abef5550..667aef4f28 100644
--- a/engines/sci/graphics/palette.cpp
+++ b/engines/sci/graphics/palette.cpp
@@ -86,10 +86,6 @@ GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen)
_macClut = 0;
loadMacIconBarPalette();
-#ifdef ENABLE_SCI32
- _clutTable = 0;
-#endif
-
switch (_resMan->getViewType()) {
case kViewEga:
_totalScreenColors = 16;
@@ -117,10 +113,6 @@ GfxPalette::~GfxPalette() {
palVaryRemoveTimer();
delete[] _macClut;
-
-#ifdef ENABLE_SCI32
- unloadClut();
-#endif
}
bool GfxPalette::isMerging() {
@@ -819,6 +811,8 @@ bool GfxPalette::palVaryLoadTargetPalette(GuiResourceId resourceId) {
return false;
}
+// TODO: This code should not set up an independent timer in SCI32. SCI32 engine palette varies happen in
+// Palette::UpdateForFrame which is called by GraphicsMgr::FrameOut.
void GfxPalette::palVaryInstallTimer() {
// Remove any possible leftover palVary timer callbacks.
// This happens for example in QFG1VGA, when sleeping at Erana's place
@@ -1087,58 +1081,4 @@ bool GfxPalette::colorIsFromMacClut(byte index) {
return index != 0 && _macClut && (_macClut[index * 3] != 0 || _macClut[index * 3 + 1] != 0 || _macClut[index * 3 + 2] != 0);
}
-#ifdef ENABLE_SCI32
-
-bool GfxPalette::loadClut(uint16 clutId) {
- // loadClut() will load a color lookup table from a clu file and set
- // the palette found in the file. This is to be used with Phantasmagoria 2.
-
- unloadClut();
-
- Common::String filename = Common::String::format("%d.clu", clutId);
- Common::File clut;
-
- if (!clut.open(filename) || clut.size() != 0x10000 + 236 * 3)
- return false;
-
- // Read in the lookup table
- // It maps each RGB565 color to a palette index
- _clutTable = new byte[0x10000];
- clut.read(_clutTable, 0x10000);
-
- Palette pal;
- memset(&pal, 0, sizeof(Palette));
-
- // Setup 1:1 mapping
- for (int i = 0; i < 256; i++) {
- pal.mapping[i] = i;
- }
-
- // Now load in the palette
- for (int i = 1; i <= 236; i++) {
- pal.colors[i].used = 1;
- pal.colors[i].r = clut.readByte();
- pal.colors[i].g = clut.readByte();
- pal.colors[i].b = clut.readByte();
- }
-
- set(&pal, true);
- setOnScreen();
- return true;
-}
-
-byte GfxPalette::matchClutColor(uint16 color) {
- // Match a color in RGB565 format to a palette index based on the loaded CLUT
- assert(_clutTable);
- return _clutTable[color];
-}
-
-void GfxPalette::unloadClut() {
- // This will only unload the actual table, but not reset any palette
- delete[] _clutTable;
- _clutTable = 0;
-}
-
-#endif
-
} // End of namespace Sci
diff --git a/engines/sci/graphics/palette.h b/engines/sci/graphics/palette.h
index 500a45eccf..82fd20a432 100644
--- a/engines/sci/graphics/palette.h
+++ b/engines/sci/graphics/palette.h
@@ -110,12 +110,6 @@ public:
byte findMacIconBarColor(byte r, byte g, byte b);
bool colorIsFromMacClut(byte index);
-#ifdef ENABLE_SCI32
- bool loadClut(uint16 clutId);
- byte matchClutColor(uint16 color);
- void unloadClut();
-#endif
-
private:
void palVaryInit();
void palVaryInstallTimer();
@@ -152,10 +146,6 @@ private:
void loadMacIconBarPalette();
byte *_macClut;
-
-#ifdef ENABLE_SCI32
- byte *_clutTable;
-#endif
};
} // End of namespace Sci
diff --git a/engines/sci/graphics/palette32.cpp b/engines/sci/graphics/palette32.cpp
new file mode 100644
index 0000000000..61ca1b99c2
--- /dev/null
+++ b/engines/sci/graphics/palette32.cpp
@@ -0,0 +1,350 @@
+/* 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/file.h"
+
+#include "sci/sci.h"
+#include "sci/graphics/palette32.h"
+
+namespace Sci {
+
+GfxPalette32::GfxPalette32(ResourceManager *resMan, GfxScreen *screen)
+ : GfxPalette(resMan, screen), _clutTable(0), _cyclers(), _cycleMap() {}
+
+GfxPalette32::~GfxPalette32() {
+ unloadClut();
+ cycleAllOff();
+}
+
+bool GfxPalette32::loadClut(uint16 clutId) {
+ // loadClut() will load a color lookup table from a clu file and set
+ // the palette found in the file. This is to be used with Phantasmagoria 2.
+
+ unloadClut();
+
+ Common::String filename = Common::String::format("%d.clu", clutId);
+ Common::File clut;
+
+ if (!clut.open(filename) || clut.size() != 0x10000 + 236 * 3)
+ return false;
+
+ // Read in the lookup table
+ // It maps each RGB565 color to a palette index
+ _clutTable = new byte[0x10000];
+ clut.read(_clutTable, 0x10000);
+
+ Palette pal;
+ memset(&pal, 0, sizeof(Palette));
+
+ // Setup 1:1 mapping
+ for (int i = 0; i < 256; i++) {
+ pal.mapping[i] = i;
+ }
+
+ // Now load in the palette
+ for (int i = 1; i <= 236; i++) {
+ pal.colors[i].used = 1;
+ pal.colors[i].r = clut.readByte();
+ pal.colors[i].g = clut.readByte();
+ pal.colors[i].b = clut.readByte();
+ }
+
+ set(&pal, true);
+ setOnScreen();
+ return true;
+}
+
+byte GfxPalette32::matchClutColor(uint16 color) {
+ // Match a color in RGB565 format to a palette index based on the loaded CLUT
+ assert(_clutTable);
+ return _clutTable[color];
+}
+
+void GfxPalette32::unloadClut() {
+ // This will only unload the actual table, but not reset any palette
+ delete[] _clutTable;
+ _clutTable = 0;
+}
+
+inline void GfxPalette32::_clearCycleMap(const uint16 fromColor, const uint16 numColorsToClear) {
+ bool *mapEntry = _cycleMap + fromColor;
+ const bool *lastEntry = _cycleMap + numColorsToClear;
+ while (mapEntry < lastEntry) {
+ *mapEntry++ = false;
+ }
+}
+
+inline void GfxPalette32::_setCycleMap(const uint16 fromColor, const uint16 numColorsToSet) {
+ bool *mapEntry = _cycleMap + fromColor;
+ const bool *lastEntry = _cycleMap + numColorsToSet;
+ while (mapEntry < lastEntry) {
+ if (*mapEntry != false) {
+ error("Cycles intersect");
+ }
+ *mapEntry++ = true;
+ }
+}
+
+inline PalCycler *GfxPalette32::_getCycler(const uint16 fromColor) {
+ const int numCyclers = ARRAYSIZE(_cyclers);
+
+ for (int cyclerIndex = 0; cyclerIndex < numCyclers; ++cyclerIndex) {
+ PalCycler *cycler = _cyclers[cyclerIndex];
+ if (cycler != nullptr && cycler->fromColor == fromColor) {
+ return cycler;
+ }
+ }
+
+ return nullptr;
+}
+
+inline void _doCycle(PalCycler *cycler, const int16 speed) {
+ int16 currentCycle = cycler->currentCycle;
+ const uint16 numColorsToCycle = cycler->numColorsToCycle;
+
+ if (cycler->direction == 0) {
+ currentCycle = (currentCycle - (speed % numColorsToCycle)) + numColorsToCycle;
+ } else {
+ currentCycle = currentCycle + speed;
+ }
+
+ cycler->currentCycle = (uint8) (currentCycle % numColorsToCycle);
+}
+
+inline void _applyCycleToPalette(PalCycler *cycler, Palette *palette) {
+ const int16 currentCycle = cycler->currentCycle;
+ const uint16 numColorsToCycle = cycler->numColorsToCycle;
+
+ Sci::Color tempPalette[numColorsToCycle];
+ Sci::Color *sourceColor = palette->colors + cycler->fromColor;
+ memcpy(tempPalette, sourceColor, sizeof(tempPalette));
+
+ Sci::Color *targetColor = sourceColor;
+ for (int numColorsCycled = 0; numColorsCycled < numColorsToCycle; ++numColorsCycled) {
+ Sci::Color sourceColor = *(tempPalette + ((currentCycle + numColorsCycled) % numColorsToCycle));
+ *(targetColor + numColorsCycled) = sourceColor;
+ }
+}
+
+void GfxPalette32::applyAllCycles() {
+ for (int cyclerIndex = 0, numCyclers = ARRAYSIZE(_cyclers); cyclerIndex < numCyclers; ++cyclerIndex) {
+ PalCycler *cycler = _cyclers[cyclerIndex];
+ if (cycler != nullptr) {
+ cycler->currentCycle = (uint8) ((((int) cycler->currentCycle) + 1) % cycler->numColorsToCycle);
+ // Disassembly was not fully evaluated to verify this is exactly the same
+ // as the code from applyCycles, but it appeared to be at a glance
+ _applyCycleToPalette(cycler, &_sysPalette);
+ }
+ }
+}
+
+void GfxPalette32::applyCycles() {
+ for (int i = 0, len = ARRAYSIZE(_cyclers); i < len; ++i) {
+ PalCycler *cycler = _cyclers[i];
+ if (cycler == nullptr) {
+ continue;
+ }
+
+ if (cycler->delay != 0 && cycler->numTimesPaused == 0) {
+ while ((cycler->delay + cycler->lastUpdateTick) < g_sci->getTickCount()) {
+ _doCycle(cycler, 1);
+ cycler->lastUpdateTick += cycler->delay;
+ }
+ }
+
+ _applyCycleToPalette(cycler, &_sysPalette);
+ }
+}
+
+int16 GfxPalette32::setCycle(const uint16 fromColor, const uint16 toColor, const int16 direction, const int16 delay) {
+ assert(fromColor <= UINT8_MAX);
+ assert(toColor <= UINT8_MAX);
+ assert(fromColor < toColor);
+
+ int cyclerIndex;
+ const int numCyclers = ARRAYSIZE(_cyclers);
+
+ PalCycler *cycler = _getCycler(fromColor);
+
+ if (cycler != nullptr) {
+ debug("Resetting existing cycler");
+ _clearCycleMap(fromColor, cycler->numColorsToCycle);
+ } else {
+ for (cyclerIndex = 0; cyclerIndex < numCyclers; ++cyclerIndex) {
+ if (_cyclers[cyclerIndex] == nullptr) {
+ cycler = new PalCycler;
+ _cyclers[cyclerIndex] = cycler;
+ break;
+ }
+ }
+ }
+
+ // SCI engine overrides the first oldest cycler that it finds where
+ // “oldest” is determined by the difference between the tick and now
+ if (cycler == nullptr) {
+ int maxUpdateDelta = -1;
+ // Optimization: Unlike actual SCI (SQ6) engine, we call
+ // getTickCount only once and store it, instead of calling it
+ // twice on each iteration through the loop
+ const uint32 now = g_sci->getTickCount();
+
+ for (cyclerIndex = 0; cyclerIndex < numCyclers; ++cyclerIndex) {
+ PalCycler *candidate = _cyclers[cyclerIndex];
+
+ const int32 updateDelta = now - candidate->lastUpdateTick;
+ if (updateDelta >= maxUpdateDelta) {
+ maxUpdateDelta = updateDelta;
+ cycler = candidate;
+ }
+ }
+
+ _clearCycleMap(cycler->fromColor, cycler->numColorsToCycle);
+ }
+
+ const uint16 numColorsToCycle = 1 + ((uint8) toColor) - fromColor;
+ cycler->fromColor = (uint8) fromColor;
+ cycler->numColorsToCycle = (uint8) numColorsToCycle;
+ cycler->currentCycle = (uint8) fromColor;
+ cycler->direction = direction < 0 ? PalCycleBackward : PalCycleForward;
+ cycler->delay = delay;
+ cycler->lastUpdateTick = g_sci->getTickCount();
+ cycler->numTimesPaused = 0;
+
+ _setCycleMap(fromColor, numColorsToCycle);
+
+ // TODO: Validate that this is the correct return value according
+ // to disassembly
+ return 0;
+}
+
+void GfxPalette32::doCycle(const uint16 fromColor, const int16 speed) {
+ PalCycler *cycler = _getCycler(fromColor);
+ if (cycler != nullptr) {
+ cycler->lastUpdateTick = g_sci->getTickCount();
+ _doCycle(cycler, speed);
+ }
+}
+
+void GfxPalette32::cycleOn(const uint16 fromColor) {
+ PalCycler *cycler = _getCycler(fromColor);
+ if (cycler != nullptr && cycler->numTimesPaused > 0) {
+ --cycler->numTimesPaused;
+ }
+}
+
+void GfxPalette32::cyclePause(const uint16 fromColor) {
+ PalCycler *cycler = _getCycler(fromColor);
+ if (cycler != nullptr) {
+ ++cycler->numTimesPaused;
+ }
+}
+
+void GfxPalette32::cycleAllOn() {
+ for (int i = 0, len = ARRAYSIZE(_cyclers); i < len; ++i) {
+ PalCycler *cycler = _cyclers[i];
+ if (cycler != nullptr && cycler->numTimesPaused > 0) {
+ --cycler->numTimesPaused;
+ }
+ }
+}
+
+void GfxPalette32::cycleAllPause() {
+ // TODO: The SCI SQ6 cycleAllPause function does not seem to perform
+ // nullptr checking?? This would definitely cause null pointer
+ // dereference in SCI code. I have not seen anything actually call
+ // this function yet, so it is possible it is just unused and broken
+ // in SCI SQ6. This assert exists so that if this function is called,
+ // it is noticed and can be rechecked in the actual engine.
+ // Obviously this code *does* do nullptr checks instead of crashing. :)
+ assert(0);
+ for (int i = 0, len = ARRAYSIZE(_cyclers); i < len; ++i) {
+ PalCycler *cycler = _cyclers[i];
+ if (cycler != nullptr) {
+ // This seems odd, because currentCycle is 0..numColorsPerCycle,
+ // but fromColor is 0..255. When applyAllCycles runs, the values
+ // end up back in range
+ cycler->currentCycle = cycler->fromColor;
+ }
+ }
+
+ applyAllCycles();
+
+ for (int i = 0, len = ARRAYSIZE(_cyclers); i < len; ++i) {
+ PalCycler *cycler = _cyclers[i];
+ if (cycler != nullptr) {
+ ++cycler->numTimesPaused;
+ }
+ }
+}
+
+void GfxPalette32::cycleOff(const uint16 fromColor) {
+ for (int i = 0, len = ARRAYSIZE(_cyclers); i < len; ++i) {
+ PalCycler *cycler = _cyclers[i];
+ if (cycler != nullptr && cycler->fromColor == fromColor) {
+ _clearCycleMap(fromColor, cycler->numColorsToCycle);
+ delete cycler;
+ _cyclers[i] = nullptr;
+ break;
+ }
+ }
+}
+
+void GfxPalette32::cycleAllOff() {
+ for (int i = 0, len = ARRAYSIZE(_cyclers); i < len; ++i) {
+ PalCycler *cycler = _cyclers[i];
+ if (cycler != nullptr) {
+ _clearCycleMap(cycler->fromColor, cycler->numColorsToCycle);
+ delete cycler;
+ _cyclers[i] = nullptr;
+ }
+ }
+}
+
+void GfxPalette32::applyFade() {
+ // TODO: Create and update a _nextPalette, not a single _sysPalette, to
+ // conform to the way the actual SCI32 engine works (writes to a
+ // next-frame-palette and then copies to the current palette on frameout)
+ Sci::Color *color = _sysPalette.colors;
+ uint8 *fadeAmount = _fadeTable;
+ for (int i = 0; i < 256; ++i) {
+ if (*fadeAmount == 100) {
+ continue;
+ }
+
+ color->r = ((int) color->r * ((int) *fadeAmount)) / 100;
+ color->g = ((int) color->r * ((int) *fadeAmount)) / 100;
+ color->b = ((int) color->r * ((int) *fadeAmount)) / 100;
+ }
+}
+
+void GfxPalette32::setFade(uint8 percent, uint16 fromColor, uint16 toColor) {
+ uint8 *fadeAmount = _fadeTable;
+ for (int i = fromColor, len = toColor - fromColor + 1; i < len; ++i) {
+ *fadeAmount++ = percent;
+ }
+}
+
+void GfxPalette32::fadeOff() {
+ setFade(100, 0, 255);
+}
+
+}
diff --git a/engines/sci/graphics/palette32.h b/engines/sci/graphics/palette32.h
new file mode 100644
index 0000000000..87bebbb2fa
--- /dev/null
+++ b/engines/sci/graphics/palette32.h
@@ -0,0 +1,122 @@
+/* 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.
+ *
+ */
+
+#ifndef SCI_GRAPHICS_PALETTE32_H
+#define SCI_GRAPHICS_PALETTE32_H
+
+#include "sci/graphics/palette.h"
+
+enum PalCyclerDirection {
+ PalCycleBackward = 0,
+ PalCycleForward = 1
+};
+
+struct PalCycler {
+ /**
+ * The color index of the palette cycler. This value is effectively used as the ID for the
+ * cycler.
+ */
+ uint8 fromColor;
+
+ /**
+ * The number of palette slots which are cycled by the palette cycler.
+ */
+ uint16 numColorsToCycle;
+
+ /**
+ * The position of the cursor in its cycle.
+ */
+ uint8 currentCycle;
+
+ /**
+ * The direction of the cycler.
+ */
+ PalCyclerDirection direction;
+
+ /**
+ * The cycle tick at the last time the cycler’s currentCycle was updated.
+ * 795 days of game time ought to be enough for everyone? :)
+ */
+ uint32 lastUpdateTick;
+
+ /**
+ * The amount of time in ticks each cycle should take to complete. In other words,
+ * the higher the delay, the slower the cycle animation. If delay is 0, the cycler
+ * does not automatically cycle and needs to be pumped manually with DoCycle.
+ */
+ int16 delay;
+
+ /**
+ * The number of times this cycler has been paused.
+ */
+ uint16 numTimesPaused;
+};
+
+namespace Sci {
+ class GfxPalette32 : public GfxPalette {
+ public:
+ GfxPalette32(ResourceManager *resMan, GfxScreen *screen);
+ ~GfxPalette32();
+
+ private:
+ // SCI2 (SQ6) defines 10 cyclers
+ PalCycler *_cyclers[10];
+ /**
+ * The cycle map is used to detect overlapping cyclers. According to SCI engine code, when two cyclers overlap,
+ * a fatal error has occurred and the engine will display an error and then exit.
+ */
+ bool _cycleMap[256];
+ inline void _clearCycleMap(uint16 fromColor, uint16 numColorsToClear);
+ inline void _setCycleMap(uint16 fromColor, uint16 numColorsToClear);
+ inline PalCycler *_getCycler(uint16 fromColor);
+
+ /**
+ * The fade table records the expected intensity level of each pixel in the palette that will be displayed on
+ * the next frame.
+ */
+ byte _fadeTable[256];
+ byte *_clutTable;
+
+ public:
+ void applyAllCycles();
+ void applyCycles();
+ void applyFade();
+
+ bool loadClut(uint16 clutId);
+ byte matchClutColor(uint16 color);
+ void unloadClut();
+
+ int16 setCycle(uint16 fromColor, uint16 toColor, int16 direction, int16 delay);
+ void doCycle(uint16 fromColor, int16 speed);
+ void cycleOn(uint16 fromColor);
+ void cyclePause(uint16 fromColor);
+ void cycleAllOn();
+ void cycleAllPause();
+ void cycleOff(uint16 fromColor);
+ void cycleAllOff();
+
+ void setFade(uint8 percent, uint16 fromColor, uint16 toColor);
+ void fadeOff();
+ };
+}
+
+#endif
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 33392e3b42..08e5ea84d8 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -84,6 +84,7 @@ MODULE_OBJS += \
graphics/controls32.o \
graphics/frameout.o \
graphics/paint32.o \
+ graphics/palette32.o \
graphics/text32.o \
video/robot_decoder.o
endif
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index f1ab65ef98..598368e428 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -63,6 +63,7 @@
#include "sci/graphics/transitions.h"
#ifdef ENABLE_SCI32
+#include "sci/graphics/palette32.h"
#include "sci/graphics/text32.h"
#include "sci/graphics/frameout.h"
#include "sci/video/robot_decoder.h"
@@ -153,6 +154,9 @@ SciEngine::~SciEngine() {
DebugMan.clearAllDebugChannels();
#ifdef ENABLE_SCI32
+ // _gfxPalette32 is the same as _gfxPalette16
+ // and will be destroyed when _gfxPalette16 is
+ // destroyed
delete _gfxControls32;
delete _gfxText32;
delete _robotDecoder;
@@ -168,7 +172,7 @@ SciEngine::~SciEngine() {
delete _gfxCoordAdjuster;
delete _gfxPorts;
delete _gfxCache;
- delete _gfxPalette;
+ delete _gfxPalette16;
delete _gfxCursor;
delete _gfxScreen;
@@ -614,7 +618,8 @@ void SciEngine::initGraphics() {
_gfxMenu = 0;
_gfxPaint = 0;
_gfxPaint16 = 0;
- _gfxPalette = 0;
+ _gfxPalette16 = 0;
+ _gfxPalette32 = 0;
_gfxPorts = 0;
_gfxText16 = 0;
_gfxTransitions = 0;
@@ -629,9 +634,19 @@ void SciEngine::initGraphics() {
if (hasMacIconBar())
_gfxMacIconBar = new GfxMacIconBar();
- _gfxPalette = new GfxPalette(_resMan, _gfxScreen);
- _gfxCache = new GfxCache(_resMan, _gfxScreen, _gfxPalette);
- _gfxCursor = new GfxCursor(_resMan, _gfxPalette, _gfxScreen);
+#ifdef ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2) {
+ _gfxPalette32 = new GfxPalette32(_resMan, _gfxScreen);
+ _gfxPalette16 = _gfxPalette32;
+ } else {
+#endif
+ _gfxPalette16 = new GfxPalette(_resMan, _gfxScreen);
+#ifdef ENABLE_SCI32
+ }
+#endif
+
+ _gfxCache = new GfxCache(_resMan, _gfxScreen, _gfxPalette16);
+ _gfxCursor = new GfxCursor(_resMan, _gfxPalette16, _gfxScreen);
#ifdef ENABLE_SCI32
if (getSciVersion() >= SCI_VERSION_2) {
@@ -639,12 +654,12 @@ void SciEngine::initGraphics() {
_gfxCoordAdjuster = new GfxCoordAdjuster32(_gamestate->_segMan);
_gfxCursor->init(_gfxCoordAdjuster, _eventMan);
_gfxCompare = new GfxCompare(_gamestate->_segMan, _gfxCache, _gfxScreen, _gfxCoordAdjuster);
- _gfxPaint32 = new GfxPaint32(_resMan, _gfxCoordAdjuster, _gfxScreen, _gfxPalette);
+ _gfxPaint32 = new GfxPaint32(_resMan, _gfxCoordAdjuster, _gfxScreen, _gfxPalette32);
_gfxPaint = _gfxPaint32;
_gfxText32 = new GfxText32(_gamestate->_segMan, _gfxCache, _gfxScreen);
_gfxControls32 = new GfxControls32(_gamestate->_segMan, _gfxCache, _gfxText32);
_robotDecoder = new RobotDecoder(getPlatform() == Common::kPlatformMacintosh);
- _gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette, _gfxPaint32);
+ _gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette32, _gfxPaint32);
} else {
#endif
// SCI0-SCI1.1 graphic objects creation
@@ -652,10 +667,10 @@ void SciEngine::initGraphics() {
_gfxCoordAdjuster = new GfxCoordAdjuster16(_gfxPorts);
_gfxCursor->init(_gfxCoordAdjuster, _eventMan);
_gfxCompare = new GfxCompare(_gamestate->_segMan, _gfxCache, _gfxScreen, _gfxCoordAdjuster);
- _gfxTransitions = new GfxTransitions(_gfxScreen, _gfxPalette);
- _gfxPaint16 = new GfxPaint16(_resMan, _gamestate->_segMan, _gfxCache, _gfxPorts, _gfxCoordAdjuster, _gfxScreen, _gfxPalette, _gfxTransitions, _audio);
+ _gfxTransitions = new GfxTransitions(_gfxScreen, _gfxPalette16);
+ _gfxPaint16 = new GfxPaint16(_resMan, _gamestate->_segMan, _gfxCache, _gfxPorts, _gfxCoordAdjuster, _gfxScreen, _gfxPalette16, _gfxTransitions, _audio);
_gfxPaint = _gfxPaint16;
- _gfxAnimate = new GfxAnimate(_gamestate, _gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen, _gfxPalette, _gfxCursor, _gfxTransitions);
+ _gfxAnimate = new GfxAnimate(_gamestate, _gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen, _gfxPalette16, _gfxCursor, _gfxTransitions);
_gfxText16 = new GfxText16(_gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen);
_gfxControls16 = new GfxControls16(_gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen);
_gfxMenu = new GfxMenu(_eventMan, _gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen, _gfxCursor);
@@ -670,7 +685,7 @@ void SciEngine::initGraphics() {
#endif
// Set default (EGA, amiga or resource 999) palette
- _gfxPalette->setDefault();
+ _gfxPalette16->setDefault();
}
void SciEngine::initStackBaseWithSelector(Selector selector) {
@@ -1022,4 +1037,9 @@ void SciEngine::loadMacExecutable() {
}
}
+// Note that SCI engine also has a corresponding TimeMgr::SetTickCount method
+// which is used by TimeMgr::SaveRestore when loading a save game.
+uint32 SciEngine::getTickCount() {
+ return (uint32) ((g_system->getMillis() * 60) / 1000);
+}
} // End of namespace Sci
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 15034d5e94..c5528e412a 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -79,6 +79,7 @@ class GfxTransitions;
#ifdef ENABLE_SCI32
class RobotDecoder;
class GfxFrameout;
+class GfxPalette32;
#endif
// our engine debug levels
@@ -235,6 +236,7 @@ public:
bool canLoadGameStateCurrently();
bool canSaveGameStateCurrently();
void syncSoundSettings();
+ uint32 getTickCount();
/**
* Syncs the audio options of the ScummVM launcher (speech, subtitles or
@@ -343,7 +345,8 @@ public:
GfxCoordAdjuster *_gfxCoordAdjuster;
GfxCursor *_gfxCursor;
GfxMenu *_gfxMenu; // Menu for 16-bit gfx
- GfxPalette *_gfxPalette;
+ GfxPalette *_gfxPalette16;
+ GfxPalette32 *_gfxPalette32; // Palette for 32-bit gfx
GfxPaint *_gfxPaint;
GfxPaint16 *_gfxPaint16; // Painting in 16-bit gfx
GfxPaint32 *_gfxPaint32; // Painting in 32-bit gfx