[Scummvm-git-logs] scummvm master -> bdb555d9a0d72db246084af119f88412f7563ca5
sev-
noreply at scummvm.org
Thu Mar 16 13:46:24 UTC 2023
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
04d26f4b01 DIRECTOR: LINGO: Start UnitTest Xlib
81cc30f8e4 DIRECTOR: Fix kInkTypeTransparent, kInkTypeNotTrans, kInkTypeGhost and kInkTypeNotGhost
3cb61c54d7 DIRECTOR: Fix kInkTypeBlend, remove redundant _blend field on Sprite
bdb555d9a0 DIRECTOR: Fix kInkTypeAdd, kInkTypeAddPin, kInkTypeSub and kInkTypeSubPin
Commit: 04d26f4b01bc9174bc318772039ba69e983f9511
https://github.com/scummvm/scummvm/commit/04d26f4b01bc9174bc318772039ba69e983f9511
Author: Scott Percival (code at moral.net.au)
Date: 2023-03-16T14:46:18+01:00
Commit Message:
DIRECTOR: LINGO: Start UnitTest Xlib
This is the start of a cross-platform testing framework for ScummVM and
Macromedia Director. The intention is to create a Xlib DLL for Director 4
with the same API, making it easier to prototype unit tests in the
Director editor.
This Xlib adds the UTScreenshot Lingo builtin, which dumps the current
screen surface to a subfolder in the game directory.
Changed paths:
A engines/director/lingo/xlibs/unittest.cpp
A engines/director/lingo/xlibs/unittest.h
engines/director/lingo/lingo-object.cpp
engines/director/module.mk
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 2158e0d5cbb..80e99b56f95 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -73,6 +73,7 @@
#include "director/lingo/xlibs/serialportxobj.h"
#include "director/lingo/xlibs/soundjam.h"
#include "director/lingo/xlibs/spacemgr.h"
+#include "director/lingo/xlibs/unittest.h"
#include "director/lingo/xlibs/videodiscxobj.h"
#include "director/lingo/xlibs/volumelist.h"
#include "director/lingo/xlibs/widgetxobj.h"
@@ -188,6 +189,7 @@ static struct XLibProto {
{ SerialPortXObj::fileNames, SerialPortXObj::open, SerialPortXObj::close, kXObj, 200 }, // D2
{ SoundJam::fileNames, SoundJam::open, SoundJam::close, kXObj, 400 }, // D4
{ SpaceMgr::fileNames, SpaceMgr::open, SpaceMgr::close, kXObj, 400 }, // D4
+ { UnitTest::fileNames, UnitTest::open, UnitTest::close, kXObj, 400 }, // D4
{ VolumeList::fileNames, VolumeList::open, VolumeList::close, kXObj, 300 }, // D3
{ WidgetXObj::fileNames, WidgetXObj::open, WidgetXObj::close, kXObj, 400 }, // D4
{ VideodiscXObj::fileNames, VideodiscXObj::open, VideodiscXObj::close, kXObj, 200 }, // D2
diff --git a/engines/director/lingo/xlibs/unittest.cpp b/engines/director/lingo/xlibs/unittest.cpp
new file mode 100644
index 00000000000..c27af2cc131
--- /dev/null
+++ b/engines/director/lingo/xlibs/unittest.cpp
@@ -0,0 +1,123 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*************************************
+ *
+ * ScummVM Unit Testing framework.
+ * Used in the Director Test suite - https://github.com/scummvm/director-tests
+ *
+ *************************************/
+
+#include "director/director.h"
+#include "director/archive.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/xlibs/unittest.h"
+#include "director/movie.h"
+#include "director/score.h"
+#include "director/window.h"
+#ifdef USE_PNG
+#include "image/png.h"
+#else
+#include "image/bmp.h"
+#endif
+
+namespace Director {
+
+const char *UnitTest::xlibName = "UnitTest";
+const char *UnitTest::fileNames[] = {
+ "UnitTest",
+ 0
+};
+
+static BuiltinProto builtins[] = {
+ { "UTScreenshot", UnitTest::m_UTScreenshot, 0, 1, 400, HBLTIN },
+ { nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+void UnitTest::open(int type) {
+ g_lingo->initBuiltIns(builtins);
+}
+
+void UnitTest::close(int type) {
+ g_lingo->cleanupBuiltIns(builtins);
+}
+
+void UnitTest::m_UTScreenshot(int nargs) {
+ Common::String filenameBase = g_director->getCurrentMovie()->getArchive()->getFileName();
+ if (filenameBase.hasSuffixIgnoreCase(".dir"))
+ filenameBase = filenameBase.substr(0, filenameBase.size() - 4);
+
+ if (nargs > 1) {
+ g_lingo->dropStack(nargs - 1);
+ }
+ if (nargs == 1) {
+ Datum name = g_lingo->pop();
+ if (name.type == STRING) {
+ filenameBase = *name.u.s;
+ } else if (name.type != VOID) {
+ warning("UnitTest::b_UTScreenshot(): expected string for arg 1, ignoring");
+ }
+ }
+
+ Common::FSNode gameDataDir = g_director->_gameDataDir;
+ Common::FSNode screenDir = gameDataDir.getChild("utscreen");
+ if (!screenDir.exists()) {
+ screenDir.createDirectory();
+ }
+
+ // force a full screen redraw before taking the screenshot
+ Score *score = g_director->getCurrentMovie()->getScore();
+ score->renderSprites(score->getCurrentFrame(), kRenderForceUpdate);
+ Window *window = g_director->getCurrentWindow();
+ window->render();
+ Graphics::ManagedSurface *windowSurface = window->getSurface();
+
+#ifdef USE_PNG
+ Common::FSNode file = screenDir.getChild(Common::String::format("%s.png", filenameBase.c_str()));
+#else
+ Common::FSNode file = screenDir.getChild(Common::String::format("%s.bmp", filenameBase.c_str()));
+#endif
+
+ Common::SeekableWriteStream *stream = file.createWriteStream();
+ if (!stream) {
+ warning("UnitTest::b_UTScreenshot(): could not open file %s", file.getPath().c_str());
+ return;
+ }
+
+ bool success = false;
+#ifdef USE_PNG
+ if (windowSurface->format.bytesPerPixel == 1) {
+ success = Image::writePNG(*stream, *windowSurface, g_director->getPalette());
+ } else {
+ success = Image::writePNG(*stream, *windowSurface);
+ }
+#else
+ success = Image::writeBMP(*stream, *windowSurface);
+#endif
+ if (!success) {
+ warning("UnitTest::b_UTScreenshot(): error writing screenshot data to file %s", file.getPath().c_str());
+ }
+ stream->finalize();
+ delete stream;
+}
+
+} // End of namespace Director
diff --git a/engines/director/lingo/xlibs/unittest.h b/engines/director/lingo/xlibs/unittest.h
new file mode 100644
index 00000000000..faa445d5523
--- /dev/null
+++ b/engines/director/lingo/xlibs/unittest.h
@@ -0,0 +1,41 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XLIBS_UNITTEST_H
+#define DIRECTOR_LINGO_XLIBS_UNITTEST_H
+
+namespace Director {
+
+namespace UnitTest {
+
+extern const char *xlibName;
+extern const char *fileNames[];
+
+void open(int type);
+void close(int type);
+
+void m_UTScreenshot(int nargs);
+
+} // End of namespace UnitTest
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 824d22e7d2b..e7c4d7f67b9 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -77,6 +77,7 @@ MODULE_OBJS = \
lingo/xlibs/serialportxobj.o \
lingo/xlibs/soundjam.o \
lingo/xlibs/spacemgr.o \
+ lingo/xlibs/unittest.o \
lingo/xlibs/videodiscxobj.o \
lingo/xlibs/volumelist.o \
lingo/xlibs/widgetxobj.o \
Commit: 81cc30f8e4d80e2537c0e888f949b4b4395c2d15
https://github.com/scummvm/scummvm/commit/81cc30f8e4d80e2537c0e888f949b4b4395c2d15
Author: Scott Percival (code at moral.net.au)
Date: 2023-03-16T14:46:18+01:00
Commit Message:
DIRECTOR: Fix kInkTypeTransparent, kInkTypeNotTrans, kInkTypeGhost and kInkTypeNotGhost
Changed paths:
engines/director/graphics.cpp
diff --git a/engines/director/graphics.cpp b/engines/director/graphics.cpp
index 2ca324f12f1..9eb693334b2 100644
--- a/engines/director/graphics.cpp
+++ b/engines/director/graphics.cpp
@@ -360,10 +360,18 @@ void inkDrawPixel(int x, int y, int src, void *data) {
}
break;
case kInkTypeTransparent:
- *dst = p->applyColor ? (~src | p->backColor) & (*dst | src) : *dst | src;
+ if (p->oneBitImage || p->applyColor) {
+ *dst = src == (int)p->colorBlack ? p->foreColor : *dst;
+ } else {
+ *dst = *dst | src;
+ }
break;
case kInkTypeNotTrans:
- *dst = p->applyColor ? (src | p->backColor) & (*dst | ~src) : (*dst | ~src);
+ if (p->oneBitImage || p->applyColor) {
+ *dst = src == (int)p->colorWhite ? p->foreColor : *dst;
+ } else {
+ *dst = *dst | ~src;
+ }
break;
case kInkTypeReverse:
*dst ^= src;
@@ -372,10 +380,18 @@ void inkDrawPixel(int x, int y, int src, void *data) {
*dst ^= ~(src);
break;
case kInkTypeGhost:
- *dst = p->applyColor ? (src & p->foreColor) | (*dst & ~src) : (*dst & ~src);
+ if (p->oneBitImage || p->applyColor) {
+ *dst = src == (int)p->colorBlack ? p->backColor : *dst;
+ } else {
+ *dst = *dst & ~src;
+ }
break;
case kInkTypeNotGhost:
- *dst = p->applyColor ? (~src & p->foreColor) | (*dst & src) : (*dst & src);
+ if (p->oneBitImage || p->applyColor) {
+ *dst = src == (int)p->colorWhite ? p->backColor : *dst;
+ } else {
+ *dst = *dst & src;
+ }
break;
// Arithmetic ink types
default: {
@@ -424,16 +440,28 @@ Graphics::MacDrawPixPtr DirectorEngine::getInkDrawPixel() {
}
void DirectorPlotData::setApplyColor() {
+ // Director has two ways of rendering an ink setting.
+ // The default is to incorporate the full range of colors in the image.
+ // "applyColor" is used to denote the other option; reduce the image
+ // to some combination of the currently set foreground and background color.
applyColor = false;
- if (foreColor != colorBlack) {
- if (ink != kInkTypeGhost && ink != kInkTypeNotGhost)
- applyColor = true;
- }
-
- if (backColor != colorWhite) {
- if (ink != kInkTypeTransparent && ink != kInkTypeNotTrans && ink != kInkTypeBackgndTrans)
- applyColor = true;
+ switch (ink) {
+ case kInkTypeMatte:
+ case kInkTypeMask:
+ case kInkTypeCopy:
+ case kInkTypeNotCopy:
+ applyColor = (foreColor != colorBlack) || (backColor != colorWhite);
+ break;
+ case kInkTypeTransparent:
+ case kInkTypeNotTrans:
+ case kInkTypeBackgndTrans:
+ case kInkTypeGhost:
+ case kInkTypeNotGhost:
+ applyColor = !((foreColor == colorBlack) && (backColor == colorWhite));
+ break;
+ default:
+ break;
}
}
Commit: 3cb61c54d749f385817fb8674236d4046af54271
https://github.com/scummvm/scummvm/commit/3cb61c54d749f385817fb8674236d4046af54271
Author: Scott Percival (code at moral.net.au)
Date: 2023-03-16T14:46:18+01:00
Commit Message:
DIRECTOR: Fix kInkTypeBlend, remove redundant _blend field on Sprite
Changed paths:
engines/director/channel.cpp
engines/director/frame.cpp
engines/director/graphics.cpp
engines/director/lingo/lingo-the.cpp
engines/director/score.cpp
engines/director/sprite.cpp
engines/director/sprite.h
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 3bf07254721..d4a43dc5136 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -106,7 +106,7 @@ Channel::~Channel() {
}
DirectorPlotData Channel::getPlotData() {
- DirectorPlotData pd(g_director, _sprite->_spriteType, _sprite->_ink, _sprite->_blend, _sprite->getBackColor(), _sprite->getForeColor());
+ DirectorPlotData pd(g_director, _sprite->_spriteType, _sprite->_ink, _sprite->_blendAmount, _sprite->getBackColor(), _sprite->getForeColor());
pd.colorWhite = 0;
pd.colorBlack = 255;
pd.dst = nullptr;
@@ -153,7 +153,7 @@ const Graphics::Surface *Channel::getMask(bool forceMatte) {
_sprite->_ink == kInkTypeLight ||
_sprite->_ink == kInkTypeSub ||
_sprite->_ink == kInkTypeDark ||
- _sprite->_blend > 0;
+ _sprite->_blendAmount > 0;
Common::Rect bbox(getBbox());
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 214b5144bbf..f3d58d92c02 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -412,7 +412,7 @@ Common::String Frame::formatChannelInfo() {
for (int i = 0; i < _numChannels; i++) {
Sprite &sprite = *_sprites[i + 1];
if (sprite._castId.member) {
- result += Common::String::format("CH: %-3d castId: %s, [inkData: 0x%02x [ink: %d, trails: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, flags2: 0x%x, unk2: 0x%x, unk3: 0x%x\n",
+ result += Common::String::format("CH: %-3d castId: %s, [inkData: 0x%02x [ink: %d, trails: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, colorcode: 0x%x, blendAmount: 0x%x, unk3: 0x%x\n",
i + 1, sprite._castId.asString().c_str(), sprite._inkData,
sprite._ink, sprite._trails, sprite._thickness, sprite._width, sprite._height,
sprite._startPoint.x, sprite._startPoint.y,
diff --git a/engines/director/graphics.cpp b/engines/director/graphics.cpp
index 9eb693334b2..fe76f7ddaf0 100644
--- a/engines/director/graphics.cpp
+++ b/engines/director/graphics.cpp
@@ -283,11 +283,9 @@ void inkDrawPixel(int x, int y, int src, void *data) {
wm->decomposeColor<T>(src, rSrc, gSrc, bSrc);
wm->decomposeColor<T>(*dst, rDst, gDst, bDst);
- double alpha = (double)p->alpha / 100.0;
- rDst = static_cast<byte>((rSrc * alpha) + (rDst * (1.0 - alpha)));
- gDst = static_cast<byte>((gSrc * alpha) + (gDst * (1.0 - alpha)));
- bDst = static_cast<byte>((bSrc * alpha) + (bDst * (1.0 - alpha)));
-
+ rDst = lerpByte(rSrc, rDst, p->alpha, 255);
+ gDst = lerpByte(gSrc, gDst, p->alpha, 255);
+ bDst = lerpByte(bSrc, bDst, p->alpha, 255);
*dst = wm->findBestColor(rDst, gDst, bDst);
return;
}
@@ -306,6 +304,9 @@ void inkDrawPixel(int x, int y, int src, void *data) {
// fall through
case kInkTypeMask:
// Only unmasked pixels make it here, so copy them straight
+ case kInkTypeBlend:
+ // If there's a blend factor set, it's dealt with in the alpha handling block.
+ // Otherwise, treat it like a Matte image.
case kInkTypeCopy: {
if (p->applyColor) {
if (sizeof(T) == 1) {
@@ -402,9 +403,6 @@ void inkDrawPixel(int x, int y, int src, void *data) {
wm->decomposeColor<T>(*dst, rDst, gDst, bDst);
switch (p->ink) {
- case kInkTypeBlend:
- *dst = wm->findBestColor((rSrc + rDst) / 2, (gSrc + gDst) / 2, (bSrc + bDst) / 2);
- break;
case kInkTypeAddPin:
*dst = wm->findBestColor(MIN((rSrc + rDst), 0xff), MIN((gSrc + gDst), 0xff), MIN((bSrc + bDst), 0xff));
break;
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 470ea0030f3..3c05ed2a730 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -21,6 +21,7 @@
#include "common/config-manager.h"
#include "common/fs.h"
+#include "common/util.h"
#include "graphics/macgui/macbutton.h"
#include "graphics/macgui/macmenu.h"
@@ -1275,7 +1276,7 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
d = (int)g_director->transformColor(sprite->_backColor);
break;
case kTheBlend:
- d = sprite->_blend;
+ d = (255 - sprite->_blendAmount) * 255 / 100;
break;
case kTheBottom:
d = channel->getBbox().bottom;
@@ -1428,9 +1429,13 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
}
break;
case kTheBlend:
- if (d.asInt() != sprite->_blend) {
- sprite->_blend = (d.asInt() == 100 ? 0 : d.asInt());
- channel->_dirty = true;
+ {
+ // Convert from (0, 100) range to (0xff, 0x00)
+ int blend = (100 - CLIP(d.asInt(), 0, 100)) * 255 / 100;
+ if (blend != sprite->_blendAmount) {
+ sprite->_blendAmount = blend;
+ channel->_dirty = true;
+ }
}
break;
case kTheCastNum:
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index e6dd62a31fc..70e68ae3d7e 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1519,7 +1519,7 @@ Common::String Score::formatChannelInfo() {
Channel &channel = *_channels[i + 1];
Sprite &sprite = *channel._sprite;
if (sprite._castId.member) {
- result += Common::String::format("CH: %-3d castId: %s, visible: %d, [inkData: 0x%02x [ink: %d, trails: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, flags2: 0x%x, unk2: 0x%x, unk3: 0x%x, constraint: %d, puppet: %d, stretch: %d\n",
+ result += Common::String::format("CH: %-3d castId: %s, visible: %d, [inkData: 0x%02x [ink: %d, trails: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, colorcode: 0x%x, blendAmount: 0x%x, unk3: 0x%x, constraint: %d, puppet: %d, stretch: %d\n",
i + 1, sprite._castId.asString().c_str(), channel._visible, sprite._inkData,
sprite._ink, sprite._trails, sprite._thickness, channel._width, channel._height,
channel._currentPoint.x, channel._currentPoint.y,
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index b6e0fbb7f76..745172ca217 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -64,8 +64,6 @@ Sprite::Sprite(Frame *frame) {
_backColor = g_director->_wm->_colorWhite;
_foreColor = g_director->_wm->_colorBlack;
- _blend = 0;
-
_volume = 0;
_stretch = 0;
}
@@ -109,8 +107,6 @@ Sprite& Sprite::operator=(const Sprite &sprite) {
_backColor = sprite._backColor;
_foreColor = sprite._foreColor;
- _blend = sprite._blend;
-
_volume = sprite._volume;
_stretch = sprite._stretch;
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 4e563a7f46d..340cd7f0756 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -117,8 +117,6 @@ public:
uint32 _backColor;
uint32 _foreColor;
- byte _blend;
-
byte _volume;
byte _stretch;
};
Commit: bdb555d9a0d72db246084af119f88412f7563ca5
https://github.com/scummvm/scummvm/commit/bdb555d9a0d72db246084af119f88412f7563ca5
Author: Scott Percival (code at moral.net.au)
Date: 2023-03-16T14:46:18+01:00
Commit Message:
DIRECTOR: Fix kInkTypeAdd, kInkTypeAddPin, kInkTypeSub and kInkTypeSubPin
Changed paths:
engines/director/graphics.cpp
diff --git a/engines/director/graphics.cpp b/engines/director/graphics.cpp
index fe76f7ddaf0..80288032129 100644
--- a/engines/director/graphics.cpp
+++ b/engines/director/graphics.cpp
@@ -364,6 +364,9 @@ void inkDrawPixel(int x, int y, int src, void *data) {
if (p->oneBitImage || p->applyColor) {
*dst = src == (int)p->colorBlack ? p->foreColor : *dst;
} else {
+ // OR dst palette index with src.
+ // Originally designed for 1-bit mode to make white pixels
+ // transparent.
*dst = *dst | src;
}
break;
@@ -371,19 +374,29 @@ void inkDrawPixel(int x, int y, int src, void *data) {
if (p->oneBitImage || p->applyColor) {
*dst = src == (int)p->colorWhite ? p->foreColor : *dst;
} else {
+ // OR dst palette index with the inverse of src.
*dst = *dst | ~src;
}
break;
case kInkTypeReverse:
+ // XOR dst palette index with src.
+ // Originally designed for 1-bit mode so that
+ // black pixels would appear white on a black
+ // background.
*dst ^= src;
break;
case kInkTypeNotReverse:
+ // XOR dst palette index with the inverse of src.
*dst ^= ~(src);
break;
case kInkTypeGhost:
if (p->oneBitImage || p->applyColor) {
*dst = src == (int)p->colorBlack ? p->backColor : *dst;
} else {
+ // AND dst palette index with the inverse of src.
+ // Originally designed for 1-bit mode so that
+ // black pixels would be invisible until they were
+ // over a black background, showing as white.
*dst = *dst & ~src;
}
break;
@@ -391,11 +404,12 @@ void inkDrawPixel(int x, int y, int src, void *data) {
if (p->oneBitImage || p->applyColor) {
*dst = src == (int)p->colorWhite ? p->backColor : *dst;
} else {
+ // AND dst palette index with src.
*dst = *dst & src;
}
break;
- // Arithmetic ink types
default: {
+ // Arithmetic ink types, based on real color values
byte rSrc, gSrc, bSrc;
byte rDst, gDst, bDst;
@@ -404,24 +418,28 @@ void inkDrawPixel(int x, int y, int src, void *data) {
switch (p->ink) {
case kInkTypeAddPin:
- *dst = wm->findBestColor(MIN((rSrc + rDst), 0xff), MIN((gSrc + gDst), 0xff), MIN((bSrc + bDst), 0xff));
+ // Add src to dst, but pinning each channel so it can't go above 0xff.
+ *dst = wm->findBestColor(rDst + MIN(0xff - rDst, (int)rSrc), gDst + MIN(0xff - gDst, (int)gSrc), bDst + MIN(0xff - bDst, (int)bSrc));
break;
case kInkTypeAdd:
- // in basilisk, D3.1 is exactly using this method, adding color directly without preventing the overflow.
- // but i think min(src + dst, 255) will give us a better visual effect
- *dst = wm->findBestColor(rSrc + rDst, gSrc + gDst, bSrc + bDst);
+ // Add src to dst, allowing each channel to overflow and wrap around.
+ *dst = wm->findBestColor(rDst + rSrc, gDst + gSrc, bDst + bSrc);
break;
case kInkTypeSubPin:
- *dst = wm->findBestColor(MAX(rSrc - rDst, 0), MAX(gSrc - gDst, 0), MAX(bSrc - bDst, 0));
+ // Subtract src from dst, but pinning each channel so it can't go below 0x00.
+ *dst = wm->findBestColor(MAX(rDst - rSrc, 1) - 1, MAX(gDst - gSrc, 1) - 1, MAX(bDst - bSrc, 1) - 1);
break;
case kInkTypeLight:
- *dst = wm->findBestColor(MAX(rSrc, rDst), MAX(gSrc, gDst), MAX(bSrc, bDst));
+ // Pick the higher of src and dst for each channel, lightening the image.
+ *dst = wm->findBestColor(MAX(rSrc, rDst), MAX(gSrc, gDst), MAX(bSrc, bDst));
break;
case kInkTypeSub:
- *dst = wm->findBestColor(abs(rSrc - rDst) % 0xff + 1, abs(gSrc - gDst) % 0xff + 1, abs(bSrc - bDst) % 0xff + 1);
+ // Subtract src from dst, allowing each channel to underflow and wrap around.
+ *dst = wm->findBestColor(rDst - rSrc, gDst - gSrc, bDst - bSrc);
break;
case kInkTypeDark:
- *dst = wm->findBestColor(MIN(rSrc, rDst), MIN(gSrc, gDst), MIN(bSrc, bDst));
+ // Pick the lower of src and dst for each channel, darkening the image.
+ *dst = wm->findBestColor(MIN(rSrc, rDst), MIN(gSrc, gDst), MIN(bSrc, bDst));
break;
default:
break;
More information about the Scummvm-git-logs
mailing list