aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kiewitz2010-06-25 10:04:31 +0000
committerMartin Kiewitz2010-06-25 10:04:31 +0000
commitc6b0a5e8962297cfd808c708ff3e1022a875fd18 (patch)
tree263dd37a86da18c36c08484c8e66fed23da43052
parent550209d1e6468a575fa980144389eda64eddb730 (diff)
downloadscummvm-rg350-c6b0a5e8962297cfd808c708ff3e1022a875fd18.tar.gz
scummvm-rg350-c6b0a5e8962297cfd808c708ff3e1022a875fd18.tar.bz2
scummvm-rg350-c6b0a5e8962297cfd808c708ff3e1022a875fd18.zip
SCI: detect, if SCI1.1 game is merging or copying palette instead of using gameIds. Also prints method used, when using debug command "version"
svn-id: r50261
-rw-r--r--engines/sci/console.cpp1
-rw-r--r--engines/sci/graphics/palette.cpp121
-rw-r--r--engines/sci/graphics/palette.h6
-rw-r--r--engines/sci/resource.cpp15
-rw-r--r--engines/sci/resource.h2
-rw-r--r--engines/sci/sci.cpp11
6 files changed, 90 insertions, 66 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index cf87b34bba..b987450d3a 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -436,6 +436,7 @@ bool Console::cmdGetVersion(int argc, const char **argv) {
DebugPrintf("Move count type: %s\n", (_engine->_features->handleMoveCount()) ? "increment" : "ignore");
DebugPrintf("SetCursor type: %s\n", getSciVersionDesc(_engine->_features->detectSetCursorType()));
DebugPrintf("View type: %s\n", viewTypeDesc[g_sci->getResMan()->getViewType()]);
+ DebugPrintf("Uses palette merging: %s\n", g_sci->_gfxPalette->isMerging() ? "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");
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index 28edfae24b..9c64c21743 100644
--- a/engines/sci/graphics/palette.cpp
+++ b/engines/sci/graphics/palette.cpp
@@ -38,7 +38,7 @@
namespace Sci {
-GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen)
+GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen, bool useMerging)
: _resMan(resMan), _screen(screen) {
int16 color;
@@ -59,7 +59,6 @@ GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen)
_sysPalette.colors[255].b = 255;
_sysPaletteChanged = false;
- _alwaysForceRealMerge = false;
// Pseudo-WORKAROUND
// Quest for Glory 3 demo, Eco Quest 1 demo, Laura Bow 2 demo, Police Quest 1 vga and all Nick's Picks
@@ -67,14 +66,7 @@ GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen)
// It's not using the SCI1.1 palette merging (copying over all the colors) but the real merging
// If we use the copying over, we will get issues because some views have marked all colors as being used
// and those will overwrite the current palette in that case
- Common::String gameId = g_sci->getGameId();
- if (g_sci->isDemo()) {
- if (gameId == "laurabow2" || gameId == "qfg3" || gameId == "ecoquest")
- _alwaysForceRealMerge = true;
- } else {
- if (gameId == "pq1sci" || gameId == "cnick-sq" || gameId == "cnick-longbow" || gameId == "cnick-kq" || gameId == "cnick-laurabow" || gameId == "cnick-lsl")
- _alwaysForceRealMerge = true;
- }
+ _useMerging = useMerging;
palVaryInit();
}
@@ -82,6 +74,10 @@ GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen)
GfxPalette::~GfxPalette() {
}
+bool GfxPalette::isMerging() {
+ return _useMerging;
+}
+
// meant to get called only once during init of engine
void GfxPalette::setDefault() {
if (_resMan->getViewType() == kViewEga)
@@ -231,7 +227,14 @@ void GfxPalette::set(Palette *newPalette, bool force, bool forceRealMerge) {
uint32 systime = _sysPalette.timestamp;
if (force || newPalette->timestamp != systime) {
- _sysPaletteChanged |= merge(newPalette, force, forceRealMerge);
+ // SCI1.1+ doesnt do real merging anymore, but simply copying over the used colors from other palettes
+ // There are some games with inbetween SCI1.1 interpreters, use real merging for them (e.g. laura bow 2 demo)
+ if ((forceRealMerge) || (_useMerging))
+ _sysPaletteChanged |= merge(newPalette, force, forceRealMerge);
+ else
+ _sysPaletteChanged |= insert(newPalette, &_sysPalette);
+
+ // Adjust timestamp on newPalette, so it wont get merged/inserted w/o need
newPalette->timestamp = _sysPalette.timestamp;
bool updatePalette = _sysPaletteChanged && _screen->_picNotValid == 0;
@@ -265,6 +268,7 @@ bool GfxPalette::insert(Palette *newPalette, Palette *destPalette) {
newPalette->mapping[i] = i;
}
}
+ // We don't update the timestamp for SCI1.1, it's only updated on kDrawPic calls
return paletteChanged;
}
@@ -273,59 +277,50 @@ bool GfxPalette::merge(Palette *newPalette, bool force, bool forceRealMerge) {
int i,j;
bool paletteChanged = false;
- if ((!forceRealMerge) && (!_alwaysForceRealMerge) && (getSciVersion() >= SCI_VERSION_1_1)) {
- // SCI1.1+ doesnt do real merging anymore, but simply copying over the used colors from other palettes
- // There are some games with inbetween SCI1.1 interpreters, use real merging for them (e.g. laura bow 2 demo)
-
- // We don't update the timestamp for SCI1.1, it's only updated on kDrawPic calls
- return insert(newPalette, &_sysPalette);
-
- } else {
- // colors 0 (black) and 255 (white) are not affected by merging
- for (i = 1 ; i < 255; i++) {
- if (!newPalette->colors[i].used)// color is not used - so skip it
- continue;
- // forced palette merging or dest color is not used yet
- if (force || (!_sysPalette.colors[i].used)) {
- _sysPalette.colors[i].used = newPalette->colors[i].used;
- if ((newPalette->colors[i].r != _sysPalette.colors[i].r) || (newPalette->colors[i].g != _sysPalette.colors[i].g) || (newPalette->colors[i].b != _sysPalette.colors[i].b)) {
- _sysPalette.colors[i].r = newPalette->colors[i].r;
- _sysPalette.colors[i].g = newPalette->colors[i].g;
- _sysPalette.colors[i].b = newPalette->colors[i].b;
- paletteChanged = true;
- }
- newPalette->mapping[i] = i;
- continue;
- }
- // is the same color already at the same position? -> match it directly w/o lookup
- // this fixes games like lsl1demo/sq5 where the same rgb color exists multiple times and where we would
- // otherwise match the wrong one (which would result into the pixels affected (or not) by palette changes)
- if ((_sysPalette.colors[i].r == newPalette->colors[i].r) && (_sysPalette.colors[i].g == newPalette->colors[i].g) && (_sysPalette.colors[i].b == newPalette->colors[i].b)) {
- newPalette->mapping[i] = i;
- continue;
- }
- // check if exact color could be matched
- res = matchColor(newPalette->colors[i].r, newPalette->colors[i].g, newPalette->colors[i].b);
- if (res & 0x8000) { // exact match was found
- newPalette->mapping[i] = res & 0xFF;
- continue;
+ // colors 0 (black) and 255 (white) are not affected by merging
+ for (i = 1 ; i < 255; i++) {
+ if (!newPalette->colors[i].used)// color is not used - so skip it
+ continue;
+ // forced palette merging or dest color is not used yet
+ if (force || (!_sysPalette.colors[i].used)) {
+ _sysPalette.colors[i].used = newPalette->colors[i].used;
+ if ((newPalette->colors[i].r != _sysPalette.colors[i].r) || (newPalette->colors[i].g != _sysPalette.colors[i].g) || (newPalette->colors[i].b != _sysPalette.colors[i].b)) {
+ _sysPalette.colors[i].r = newPalette->colors[i].r;
+ _sysPalette.colors[i].g = newPalette->colors[i].g;
+ _sysPalette.colors[i].b = newPalette->colors[i].b;
+ paletteChanged = true;
}
- // no exact match - see if there is an unused color
- for (j = 1; j < 256; j++)
- if (!_sysPalette.colors[j].used) {
- _sysPalette.colors[j].used = newPalette->colors[i].used;
- _sysPalette.colors[j].r = newPalette->colors[i].r;
- _sysPalette.colors[j].g = newPalette->colors[i].g;
- _sysPalette.colors[j].b = newPalette->colors[i].b;
- newPalette->mapping[i] = j;
- paletteChanged = true;
- break;
- }
- // if still no luck - set an approximate color
- if (j == 256) {
- newPalette->mapping[i] = res & 0xFF;
- _sysPalette.colors[res & 0xFF].used |= 0x10;
+ newPalette->mapping[i] = i;
+ continue;
+ }
+ // is the same color already at the same position? -> match it directly w/o lookup
+ // this fixes games like lsl1demo/sq5 where the same rgb color exists multiple times and where we would
+ // otherwise match the wrong one (which would result into the pixels affected (or not) by palette changes)
+ if ((_sysPalette.colors[i].r == newPalette->colors[i].r) && (_sysPalette.colors[i].g == newPalette->colors[i].g) && (_sysPalette.colors[i].b == newPalette->colors[i].b)) {
+ newPalette->mapping[i] = i;
+ continue;
+ }
+ // check if exact color could be matched
+ res = matchColor(newPalette->colors[i].r, newPalette->colors[i].g, newPalette->colors[i].b);
+ if (res & 0x8000) { // exact match was found
+ newPalette->mapping[i] = res & 0xFF;
+ continue;
+ }
+ // no exact match - see if there is an unused color
+ for (j = 1; j < 256; j++)
+ if (!_sysPalette.colors[j].used) {
+ _sysPalette.colors[j].used = newPalette->colors[i].used;
+ _sysPalette.colors[j].r = newPalette->colors[i].r;
+ _sysPalette.colors[j].g = newPalette->colors[i].g;
+ _sysPalette.colors[j].b = newPalette->colors[i].b;
+ newPalette->mapping[i] = j;
+ paletteChanged = true;
+ break;
}
+ // if still no luck - set an approximate color
+ if (j == 256) {
+ newPalette->mapping[i] = res & 0xFF;
+ _sysPalette.colors[res & 0xFF].used |= 0x10;
}
}
@@ -337,7 +332,7 @@ bool GfxPalette::merge(Palette *newPalette, bool force, bool forceRealMerge) {
// This is called for SCI1.1, when kDrawPic got done. We update sysPalette timestamp this way for SCI1.1 and also load
// target-palette, if palvary is active
void GfxPalette::drewPicture(GuiResourceId pictureId) {
- if (!_alwaysForceRealMerge) // Don't do this on inbetween SCI1.1 games
+ if (!_useMerging) // Don't do this on inbetween SCI1.1 games
_sysPalette.timestamp++;
if (_palVaryResourceId != -1) {
diff --git a/engines/sci/graphics/palette.h b/engines/sci/graphics/palette.h
index e640d9b39d..1fa8c16d26 100644
--- a/engines/sci/graphics/palette.h
+++ b/engines/sci/graphics/palette.h
@@ -36,9 +36,11 @@ class Screen;
*/
class GfxPalette {
public:
- GfxPalette(ResourceManager *resMan, GfxScreen *screen);
+ GfxPalette(ResourceManager *resMan, GfxScreen *screen, bool useMerging);
~GfxPalette();
+ bool isMerging();
+
void setDefault();
void createFromData(byte *data, int bytesLeft, Palette *paletteOut);
bool setAmiga();
@@ -88,7 +90,7 @@ private:
ResourceManager *_resMan;
bool _sysPaletteChanged;
- bool _alwaysForceRealMerge;
+ bool _useMerging;
Common::Array<PalSchedule> _schedules;
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 718c675db1..2958ca1e3b 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -1949,6 +1949,21 @@ bool ResourceManager::detectFontExtended() {
return false;
}
+// detects, if SCI1.1 game uses palette merging or copying - this is supposed to only get used on SCI1.1 games
+bool ResourceManager::detectForPaletteMergingForSci11() {
+ // Load palette 999 (default palette)
+ Resource *res = findResource(ResourceId(kResourceTypePalette, 999), false);
+
+ if ((res) && (res->size > 30)) {
+ byte *data = res->data;
+ // Old palette format used in palette resource? -> it's merging
+ if ((data[0] == 0 && data[1] == 1) || (data[0] == 0 && data[1] == 0 && READ_LE_UINT16(data + 29) == 0))
+ return true;
+ return false;
+ }
+ return false;
+}
+
// Functions below are based on PD code by Brian Provinciano (SCI Studio)
bool ResourceManager::hasOldScriptHeader() {
Resource *res = findResource(ResourceId(kResourceTypeScript, 0), 0);
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 591273b252..00197876d8 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -328,6 +328,8 @@ public:
bool detectHires();
// Detects, if standard font of current game includes extended characters (>0x80)
bool detectFontExtended();
+ // Detects, if SCI1.1 game uses palette merging
+ bool detectForPaletteMergingForSci11();
/**
* Finds the internal Sierra ID of the current game from script 0.
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index b8c541fc03..f2ea0e67af 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -224,7 +224,16 @@ Common::Error SciEngine::run() {
if (_resMan->isSci11Mac() && getSciVersion() == SCI_VERSION_1_1)
_gfxMacIconBar = new GfxMacIconBar();
- _gfxPalette = new GfxPalette(_resMan, _gfxScreen);
+ bool paletteMerging = true;
+ if (getSciVersion() >= SCI_VERSION_1_1) {
+ // there are some games that use inbetween SCI1.1 interpreter, so we have to detect if it's merging or copying
+ if (getSciVersion() == SCI_VERSION_1_1)
+ paletteMerging = _resMan->detectForPaletteMergingForSci11();
+ else
+ paletteMerging = false;
+ }
+
+ _gfxPalette = new GfxPalette(_resMan, _gfxScreen, paletteMerging);
_gfxCache = new GfxCache(_resMan, _gfxScreen, _gfxPalette);
_gfxCursor = new GfxCursor(_resMan, _gfxPalette, _gfxScreen);