aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/kernel.h12
-rw-r--r--engines/sci/engine/kernel_tables.h47
-rw-r--r--engines/sci/engine/kgraphics32.cpp81
-rw-r--r--engines/sci/engine/savegame.cpp87
-rw-r--r--engines/sci/engine/savegame.h3
5 files changed, 197 insertions, 33 deletions
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index d9e42cb3ee..f62c43840f 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -474,8 +474,16 @@ reg_t kMakeSaveCatName(EngineState *s, int argc, reg_t *argv);
reg_t kMakeSaveFileName(EngineState *s, int argc, reg_t *argv);
reg_t kSetScroll(EngineState *s, int argc, reg_t *argv);
reg_t kPalCycle(EngineState *s, int argc, reg_t *argv);
-reg_t kPalVaryUnknown(EngineState *s, int argc, reg_t *argv);
-reg_t kPalVaryUnknown2(EngineState *s, int argc, reg_t *argv);
+reg_t kPaletteSetFade(EngineState *s, int argc, reg_t *argv);
+reg_t kPalVarySetVary(EngineState *s, int argc, reg_t *argv);
+reg_t kPalVarySetPercent(EngineState *s, int argc, reg_t *argv);
+reg_t kPalVaryGetPercent(EngineState *s, int argc, reg_t *argv);
+reg_t kPalVaryOff(EngineState *s, int argc, reg_t *argv);
+reg_t kPalVaryMergeTarget(EngineState *s, int argc, reg_t *argv);
+reg_t kPalVarySetTime(EngineState *s, int argc, reg_t *argv);
+reg_t kPalVarySetTarget(EngineState *s, int argc, reg_t *argv);
+reg_t kPalVarySetStart(EngineState *s, int argc, reg_t *argv);
+reg_t kPalVaryMergeStart(EngineState *s, int argc, reg_t *argv);
// SCI2.1 Kernel Functions
reg_t kMorphOn(EngineState *s, int argc, reg_t *argv);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index b89797f348..b1df235cb0 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -201,31 +201,42 @@ static const SciKernelMapSubEntry kGraph_subops[] = {
// version, subId, function-mapping, signature, workarounds
static const SciKernelMapSubEntry kPalVary_subops[] = {
- { SIG_SINCE_SCI21, 0, MAP_CALL(PalVaryInit), "ii(i)(i)(i)", NULL },
- { SIG_SCIALL, 0, MAP_CALL(PalVaryInit), "ii(i)(i)", NULL },
- { SIG_SCIALL, 1, MAP_CALL(PalVaryReverse), "(i)(i)(i)", NULL },
- { SIG_SCIALL, 2, MAP_CALL(PalVaryGetCurrentStep), "", NULL },
- { SIG_SCIALL, 3, MAP_CALL(PalVaryDeinit), "", NULL },
- { SIG_SCIALL, 4, MAP_CALL(PalVaryChangeTarget), "i", NULL },
- { SIG_SCIALL, 5, MAP_CALL(PalVaryChangeTicks), "i", NULL },
- { SIG_SCIALL, 6, MAP_CALL(PalVaryPauseResume), "i", NULL },
+ { SIG_SCI16, 0, MAP_CALL(PalVaryInit), "ii(i)(i)", NULL },
+ { SIG_SCI16, 1, MAP_CALL(PalVaryReverse), "(i)(i)(i)", NULL },
+ { SIG_SCI16, 2, MAP_CALL(PalVaryGetCurrentStep), "", NULL },
+ { SIG_SCI16, 3, MAP_CALL(PalVaryDeinit), "", NULL },
+ { SIG_SCI16, 4, MAP_CALL(PalVaryChangeTarget), "i", NULL },
+ { SIG_SCI16, 5, MAP_CALL(PalVaryChangeTicks), "i", NULL },
+ { SIG_SCI16, 6, MAP_CALL(PalVaryPauseResume), "i", NULL },
#ifdef ENABLE_SCI32
- { SIG_SCI32, 8, MAP_CALL(PalVaryUnknown), "i", NULL },
- { SIG_SCI32, 9, MAP_CALL(PalVaryUnknown2), "i", NULL },
+ { SIG_SCI32, 0, MAP_CALL(PalVarySetVary), "i(i)(i)(ii)", NULL },
+ { SIG_SCI32, 1, MAP_CALL(PalVarySetPercent), "(i)(i)", NULL },
+ { SIG_SCI32, 2, MAP_CALL(PalVaryGetPercent), "", NULL },
+ { SIG_SCI32, 3, MAP_CALL(PalVaryOff), "", NULL },
+ { SIG_SCI32, 4, MAP_CALL(PalVaryMergeTarget), "i", NULL },
+ { SIG_SCI32, 5, MAP_CALL(PalVarySetTime), "i", NULL },
+ { SIG_SCI32, 6, MAP_CALL(PalVaryPauseResume), "i", NULL },
+ { SIG_SCI32, 7, MAP_CALL(PalVarySetTarget), "i", NULL },
+ { SIG_SCI32, 8, MAP_CALL(PalVarySetStart), "i", NULL },
+ { SIG_SCI32, 9, MAP_CALL(PalVaryMergeStart), "i", NULL },
#endif
SCI_SUBOPENTRY_TERMINATOR
};
// version, subId, function-mapping, signature, workarounds
static const SciKernelMapSubEntry kPalette_subops[] = {
- { SIG_SCIALL, 1, MAP_CALL(PaletteSetFromResource), "i(i)", NULL },
- { SIG_SCIALL, 2, MAP_CALL(PaletteSetFlag), "iii", NULL },
- { SIG_SCIALL, 3, MAP_CALL(PaletteUnsetFlag), "iii", kPaletteUnsetFlag_workarounds },
- { SIG_SCIALL, 4, MAP_CALL(PaletteSetIntensity), "iii(i)", NULL },
- { SIG_SCIALL, 5, MAP_CALL(PaletteFindColor), "iii", NULL },
- { SIG_SCIALL, 6, MAP_CALL(PaletteAnimate), "i*", NULL },
- { SIG_SCIALL, 7, MAP_CALL(PaletteSave), "", NULL },
- { SIG_SCIALL, 8, MAP_CALL(PaletteRestore), "[r0]", NULL },
+ { SIG_SCIALL, 1, MAP_CALL(PaletteSetFromResource), "i(i)", NULL },
+ { SIG_SCI16, 2, MAP_CALL(PaletteSetFlag), "iii", NULL },
+ { SIG_SCI16, 3, MAP_CALL(PaletteUnsetFlag), "iii", kPaletteUnsetFlag_workarounds },
+#ifdef ENABLE_SCI32
+ { SIG_SCI32, 2, MAP_CALL(PaletteSetFade), "iii", NULL },
+ { SIG_SCI32, 3, MAP_CALL(PaletteFindColor), "iii", NULL },
+#endif
+ { SIG_SCI16, 4, MAP_CALL(PaletteSetIntensity), "iii(i)", NULL },
+ { SIG_SCI16, 5, MAP_CALL(PaletteFindColor), "iii", NULL },
+ { SIG_SCI16, 6, MAP_CALL(PaletteAnimate), "i*", NULL },
+ { SIG_SCI16, 7, MAP_CALL(PaletteSave), "", NULL },
+ { SIG_SCI16, 8, MAP_CALL(PaletteRestore), "[r0]", NULL },
SCI_SUBOPENTRY_TERMINATOR
};
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index ddb6106c8c..e87849201e 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -737,21 +737,78 @@ reg_t kMorphOn(EngineState *s, int argc, reg_t *argv) {
// palMorphIsOn flag back to false.
kStub(s, argc, argv);
return NULL_REG;
+}
-reg_t kPalVaryUnknown(EngineState *s, int argc, reg_t *argv) {
- // TODO: Unknown (seems to be SCI32 exclusive)
- return kStub(s, argc, argv);
+reg_t kPaletteSetFade(EngineState *s, int argc, reg_t *argv) {
+ uint16 fromColor = argv[0].toUint16();
+ uint16 toColor = argv[1].toUint16();
+ uint16 percent = argv[2].toUint16();
+ g_sci->_gfxPalette32->setFade(percent, fromColor, toColor);
+ return NULL_REG;
}
-reg_t kPalVaryUnknown2(EngineState *s, int argc, reg_t *argv) {
- // TODO: Unknown (seems to be SCI32 exclusive)
- // It seems to be related to the day/night palette effects in QFG4, and
- // accepts a palette resource ID. It is triggered right when the night
- // effect is initially applied (when exiting the caves).
- // In QFG4, there are two scene palettes: 790 for night, and 791 for day.
- // Initially, the game starts at night time, but this is called with the
- // ID of the day time palette (i.e. 791).
- return kStub(s, argc, argv);
+reg_t kPalVarySetVary(EngineState *s, int argc, reg_t *argv) {
+ GuiResourceId paletteId = argv[0].toUint16();
+ int time = argc > 1 ? argv[1].toSint16() * 60 : 0;
+ int16 percent = argc > 2 ? argv[2].toSint16() : 100;
+ int16 fromColor;
+ int16 toColor;
+
+ if (argc > 4) {
+ fromColor = argv[3].toSint16();
+ toColor = argv[4].toSint16();
+ } else {
+ fromColor = toColor = -1;
+ }
+
+ g_sci->_gfxPalette32->kernelPalVarySet(paletteId, percent, time, fromColor, toColor);
+ return NULL_REG;
+}
+
+reg_t kPalVarySetPercent(EngineState *s, int argc, reg_t *argv) {
+ int time = argc > 1 ? argv[1].toSint16() * 60 : 0;
+ int16 percent = argc > 2 ? argv[2].toSint16() : 0;
+ g_sci->_gfxPalette32->setVaryPercent(percent, time, -1, -1);
+ return NULL_REG;
+}
+
+reg_t kPalVaryGetPercent(EngineState *s, int argc, reg_t *argv) {
+ return make_reg(0, g_sci->_gfxPalette32->getVaryPercent());
+}
+
+reg_t kPalVaryOff(EngineState *s, int argc, reg_t *argv) {
+ g_sci->_gfxPalette32->varyOff();
+ return NULL_REG;
+}
+
+reg_t kPalVaryMergeTarget(EngineState *s, int argc, reg_t *argv) {
+ GuiResourceId paletteId = argv[1].toUint16();
+ g_sci->_gfxPalette32->kernelPalVaryMergeTarget(paletteId);
+ return make_reg(0, g_sci->_gfxPalette32->getVaryPercent());
+}
+
+reg_t kPalVarySetTime(EngineState *s, int argc, reg_t *argv) {
+ int time = argv[1].toSint16() * 60;
+ g_sci->_gfxPalette32->setVaryTime(time);
+ return NULL_REG;
+}
+
+reg_t kPalVarySetTarget(EngineState *s, int argc, reg_t *argv) {
+ GuiResourceId paletteId = argv[1].toUint16();
+ g_sci->_gfxPalette32->kernelPalVarySetTarget(paletteId);
+ return make_reg(0, g_sci->_gfxPalette32->getVaryPercent());
+}
+
+reg_t kPalVarySetStart(EngineState *s, int argc, reg_t *argv) {
+ GuiResourceId paletteId = argv[1].toUint16();
+ g_sci->_gfxPalette32->kernelPalVarySetStart(paletteId);
+ return make_reg(0, g_sci->_gfxPalette32->getVaryPercent());
+}
+
+reg_t kPalVaryMergeStart(EngineState *s, int argc, reg_t *argv) {
+ GuiResourceId paletteId = argv[1].toUint16();
+ g_sci->_gfxPalette32->kernelPalVaryMergeStart(paletteId);
+ return make_reg(0, g_sci->_gfxPalette32->getVaryPercent());
}
enum {
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 09ccff39ac..3103be1463 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -47,6 +47,7 @@
#include "sci/sound/music.h"
#ifdef ENABLE_SCI32
+#include "sci/graphics/palette32.h"
#include "sci/graphics/frameout.h"
#endif
@@ -304,6 +305,7 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) {
_segMan->saveLoadWithSerializer(s);
g_sci->_soundCmd->syncPlayList(s);
+ // NOTE: This will be GfxPalette32 for SCI32 engine games
g_sci->_gfxPalette16->saveLoadWithSerializer(s);
}
@@ -721,6 +723,91 @@ void GfxPalette::saveLoadWithSerializer(Common::Serializer &s) {
}
}
+#ifdef ENABLE_SCI32
+void saveLoadPalette32(Common::Serializer &s, Palette *const palette) {
+ s.syncAsUint32LE(palette->timestamp);
+ for (int i = 0; i < ARRAYSIZE(palette->colors); ++i) {
+ s.syncAsByte(palette->colors[i].used);
+ s.syncAsByte(palette->colors[i].r);
+ s.syncAsByte(palette->colors[i].g);
+ s.syncAsByte(palette->colors[i].b);
+ }
+}
+
+void saveLoadOptionalPalette32(Common::Serializer &s, Palette **const palette) {
+ bool hasPalette;
+ if (s.isSaving()) {
+ hasPalette = (*palette != nullptr);
+ }
+ s.syncAsByte(hasPalette);
+ if (hasPalette) {
+ if (s.isLoading()) {
+ *palette = new Palette;
+ }
+ saveLoadPalette32(s, *palette);
+ }
+}
+
+void GfxPalette32::saveLoadWithSerializer(Common::Serializer &s) {
+ if (s.getVersion() < 34) {
+ return;
+ }
+
+ if (s.isLoading()) {
+ ++_version;
+ }
+
+ s.syncAsSint16LE(_varyDirection);
+ s.syncAsSint16LE(_varyPercent);
+ s.syncAsSint16LE(_varyTargetPercent);
+ s.syncAsSint16LE(_varyFromColor);
+ s.syncAsSint16LE(_varyToColor);
+ s.syncAsUint16LE(_varyNumTimesPaused);
+ s.syncAsByte(_versionUpdated);
+ s.syncAsSint32LE(_varyTime);
+ s.syncAsUint32LE(_varyLastTick);
+
+ for (int i = 0; i < ARRAYSIZE(_fadeTable); ++i) {
+ s.syncAsByte(_fadeTable[i]);
+ }
+ for (int i = 0; i < ARRAYSIZE(_cycleMap); ++i) {
+ s.syncAsByte(_cycleMap[i]);
+ }
+
+ saveLoadOptionalPalette32(s, &_varyTargetPalette);
+ saveLoadOptionalPalette32(s, &_varyStartPalette);
+ // NOTE: _sourcePalette and _nextPalette are not saved
+ // by SCI engine
+
+ for (int i = 0; i < ARRAYSIZE(_cyclers); ++i) {
+ PalCycler *cycler;
+
+ bool hasCycler;
+ if (s.isSaving()) {
+ cycler = _cyclers[i];
+ hasCycler = (cycler != nullptr);
+ }
+ s.syncAsByte(hasCycler);
+
+ if (hasCycler) {
+ if (s.isLoading()) {
+ _cyclers[i] = cycler = new PalCycler;
+ }
+
+ s.syncAsByte(cycler->fromColor);
+ s.syncAsUint16LE(cycler->numColorsToCycle);
+ s.syncAsByte(cycler->currentCycle);
+ s.syncAsByte(cycler->direction);
+ s.syncAsUint32LE(cycler->lastUpdateTick);
+ s.syncAsSint16LE(cycler->delay);
+ s.syncAsUint16LE(cycler->numTimesPaused);
+ }
+ }
+
+ // TODO: _clutTable
+}
+#endif
+
void GfxPorts::saveLoadWithSerializer(Common::Serializer &s) {
// reset() is called directly way earlier in gamestate_restore()
if (s.getVersion() >= 27) {
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index 5512b90fa8..1062433d24 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -37,6 +37,7 @@ struct EngineState;
*
* Version - new/changed feature
* =============================
+ * 34 - SCI32 palettes
* 33 - new overridePriority flag in MusicEntry
* 32 - new playBed flag in MusicEntry
* 31 - priority for sound effects/music is now a signed int16, instead of a byte
@@ -58,7 +59,7 @@ struct EngineState;
*/
enum {
- CURRENT_SAVEGAME_VERSION = 33,
+ CURRENT_SAVEGAME_VERSION = 34,
MINIMUM_SAVEGAME_VERSION = 14
};