[Scummvm-git-logs] scummvm master -> cd1639019874e2c8e8ad209aa2cfb9f26c0076f3
sluicebox
noreply at scummvm.org
Wed Mar 2 06:18:53 UTC 2022
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
4c369d5adf SCI: Fix incorrect values in vector texture table
44b6050915 SCI: Fix vector pattern clipping behavior
cd16390198 SCI: Fix SQ3 ScumSoft announcements never appearing
Commit: 4c369d5adfe2ddc5b9e5fd1f715b068695b0be2a
https://github.com/scummvm/scummvm/commit/4c369d5adfe2ddc5b9e5fd1f715b068695b0be2a
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2022-03-02T00:55:51-05:00
Commit Message:
SCI: Fix incorrect values in vector texture table
Fixes incorrect values that trace back to SCI Decoder in 1992.
These caused subtle inaccuracies when drawing EGA vector pictures
with certain texture patterns. In SQ3 there are two of these
surrounding the escape pod in picture 2 in the first room.
Thanks to @eientei95 for spotting the picture discrepancy!
Changed paths:
engines/sci/graphics/picture.cpp
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index 5483e6f5357..00feb134a19 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -1036,7 +1036,7 @@ static const bool vectorPatternTextures[32 * 8 * 2] = {
// Bit offsets into pattern_textures
static const byte vectorPatternTextureOffset[128] = {
0x00, 0x18, 0x30, 0xc4, 0xdc, 0x65, 0xeb, 0x48,
- 0x60, 0xbd, 0x89, 0x05, 0x0a, 0xf4, 0x7d, 0x7d,
+ 0x60, 0xbd, 0x89, 0x04, 0x0a, 0xf4, 0x7d, 0x6d,
0x85, 0xb0, 0x8e, 0x95, 0x1f, 0x22, 0x0d, 0xdf,
0x2a, 0x78, 0xd5, 0x73, 0x1c, 0xb4, 0x40, 0xa1,
0xb9, 0x3c, 0xca, 0x58, 0x92, 0x34, 0xcc, 0xce,
@@ -1049,7 +1049,7 @@ static const byte vectorPatternTextureOffset[128] = {
0xbe, 0x05, 0xf5, 0x6e, 0x19, 0xc5, 0x66, 0x49,
0xf0, 0xd1, 0x54, 0xa9, 0x70, 0x4b, 0xa4, 0xe2,
0xe6, 0xe5, 0xab, 0xe4, 0xd2, 0xaa, 0x4c, 0xe3,
- 0x06, 0x6f, 0xc6, 0x4a, 0xa4, 0x75, 0x97, 0xe1
+ 0x06, 0x6f, 0xc6, 0x4a, 0x75, 0xa3, 0x97, 0xe1
};
void GfxPicture::vectorPatternBox(Common::Rect box, byte color, byte prio, byte control) {
Commit: 44b6050915ed6012f9e2e14c8ffa81d9e366529d
https://github.com/scummvm/scummvm/commit/44b6050915ed6012f9e2e14c8ffa81d9e366529d
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2022-03-02T01:00:57-05:00
Commit Message:
SCI: Fix vector pattern clipping behavior
Vector patterns weren't drawn accurately if the pattern's box touched
the right edge of the screen. This was due to clipping behavior that
differed from the original:
- The pattern's box was re-positioned one pixel too far to the right.
- The pattern's box was clipped to the screen and then drawn.
Patterns require evaluating all pixels (consuming pattern and texture
data) even if a pixel has to be skipped for being out of bounds.
Fixes a subtle inaccuracy in picture 2 of SQ3.
Unrelated to 4c369d5adfe2ddc5b9e5fd1f715b068695b0be2a
Thanks again to @eientei95 for spotting this!
Changed paths:
engines/sci/graphics/picture.cpp
engines/sci/graphics/picture.h
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index 00feb134a19..640271b9995 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -1052,10 +1052,11 @@ static const byte vectorPatternTextureOffset[128] = {
0x06, 0x6f, 0xc6, 0x4a, 0x75, 0xa3, 0x97, 0xe1
};
-void GfxPicture::vectorPatternBox(Common::Rect box, byte color, byte prio, byte control) {
+void GfxPicture::vectorPatternBox(Common::Rect box, Common::Rect clipBox, byte color, byte prio, byte control) {
byte flag = _screen->getDrawingMask(color, prio, control);
int y, x;
+ box.clip(clipBox);
for (y = box.top; y < box.bottom; y++) {
for (x = box.left; x < box.right; x++) {
_screen->vectorPutPixel(x, y, flag, color, prio, control);
@@ -1063,7 +1064,7 @@ void GfxPicture::vectorPatternBox(Common::Rect box, byte color, byte prio, byte
}
}
-void GfxPicture::vectorPatternTexturedBox(Common::Rect box, byte color, byte prio, byte control, byte texture) {
+void GfxPicture::vectorPatternTexturedBox(Common::Rect box, Common::Rect clipBox, byte color, byte prio, byte control, byte texture) {
byte flag = _screen->getDrawingMask(color, prio, control);
const bool *textureData = &vectorPatternTextures[vectorPatternTextureOffset[texture]];
int y, x;
@@ -1071,14 +1072,16 @@ void GfxPicture::vectorPatternTexturedBox(Common::Rect box, byte color, byte pri
for (y = box.top; y < box.bottom; y++) {
for (x = box.left; x < box.right; x++) {
if (*textureData) {
- _screen->vectorPutPixel(x, y, flag, color, prio, control);
+ if (clipBox.contains(x, y)) {
+ _screen->vectorPutPixel(x, y, flag, color, prio, control);
+ }
}
textureData++;
}
}
}
-void GfxPicture::vectorPatternCircle(Common::Rect box, byte size, byte color, byte prio, byte control) {
+void GfxPicture::vectorPatternCircle(Common::Rect box, Common::Rect clipBox, byte size, byte color, byte prio, byte control) {
byte flag = _screen->getDrawingMask(color, prio, control);
assert(size < ARRAYSIZE(vectorPatternCircles));
const byte *circleData = vectorPatternCircles[size];
@@ -1094,7 +1097,9 @@ void GfxPicture::vectorPatternCircle(Common::Rect box, byte size, byte color, by
bitNo = 0;
}
if (bitmap & 1) {
- _screen->vectorPutPixel(x, y, flag, color, prio, control);
+ if (clipBox.contains(x, y)) {
+ _screen->vectorPutPixel(x, y, flag, color, prio, control);
+ }
}
bitNo++;
bitmap >>= 1;
@@ -1102,7 +1107,7 @@ void GfxPicture::vectorPatternCircle(Common::Rect box, byte size, byte color, by
}
}
-void GfxPicture::vectorPatternTexturedCircle(Common::Rect box, byte size, byte color, byte prio, byte control, byte texture) {
+void GfxPicture::vectorPatternTexturedCircle(Common::Rect box, Common::Rect clipBox, byte size, byte color, byte prio, byte control, byte texture) {
byte flag = _screen->getDrawingMask(color, prio, control);
assert(size < ARRAYSIZE(vectorPatternCircles));
const byte *circleData = vectorPatternCircles[size];
@@ -1120,7 +1125,9 @@ void GfxPicture::vectorPatternTexturedCircle(Common::Rect box, byte size, byte c
}
if (bitmap & 1) {
if (*textureData) {
- _screen->vectorPutPixel(x, y, flag, color, prio, control);
+ if (clipBox.contains(x, y)) {
+ _screen->vectorPutPixel(x, y, flag, color, prio, control);
+ }
}
textureData++;
}
@@ -1132,34 +1139,49 @@ void GfxPicture::vectorPatternTexturedCircle(Common::Rect box, byte size, byte c
void GfxPicture::vectorPattern(int16 x, int16 y, byte color, byte priority, byte control, byte code, byte texture) {
byte size = code & SCI_PATTERN_CODE_PENSIZE;
- Common::Rect rect;
-
- // We need to adjust the given coordinates, because the ones given us do not define upper left but somewhat middle
- y -= size; if (y < 0) y = 0;
- x -= size; if (x < 0) x = 0;
- rect.top = y; rect.left = x;
- rect.setHeight((size*2)+1); rect.setWidth((size*2)+2);
- _ports->offsetRect(rect);
- rect.clip(_screen->getScriptWidth(), _screen->getScriptHeight());
+ // The vector box is centered on x,y and one pixel wider than high
+ Common::Rect box(x - size, y - size, x + size + 2, y + size + 1);
+ _ports->offsetRect(box);
+
+ // Adjust the vector box's position if it goes off the screen.
+ // Although, if it goes off the right edge, leave the last column
+ // beyond the screen edge even though it won't get drawn.
+ // We also can't just clip the box to the screen here, because the
+ // texture and circle data can only be properly consumed by evaluating
+ // every pixel during drawing, even the pixels that are then skipped
+ // for being out of bounds. (Example: SQ3 picture 2)
+ if (box.left < 0) {
+ box.moveTo(0, box.top);
+ } else if (box.right >= _screen->getScriptWidth()) {
+ box.moveTo(_screen->getScriptWidth() - box.width() + 1, box.top);
+ }
+ if (box.top < 0) {
+ box.moveTo(box.left, 0);
+ } else if (box.bottom >= _screen->getScriptHeight()) {
+ box.moveTo(box.left, _screen->getScriptHeight() - box.height());
+ }
+ _screen->vectorAdjustCoordinate(&box.left, &box.top);
+ _screen->vectorAdjustCoordinate(&box.right, &box.bottom);
- _screen->vectorAdjustCoordinate(&rect.left, &rect.top);
- _screen->vectorAdjustCoordinate(&rect.right, &rect.bottom);
+ // Create a box for the pattern drawing functions to clip to
+ Common::Rect clipBox(0, 0, _screen->getScriptWidth(), _screen->getScriptHeight());
+ _screen->vectorAdjustCoordinate(&clipBox.right, &clipBox.bottom);
if (code & SCI_PATTERN_CODE_RECTANGLE) {
// Rectangle
if (code & SCI_PATTERN_CODE_USE_TEXTURE) {
- vectorPatternTexturedBox(rect, color, priority, control, texture);
+ vectorPatternTexturedBox(box, clipBox, color, priority, control, texture);
} else {
- vectorPatternBox(rect, color, priority, control);
+ vectorPatternBox(box, clipBox, color, priority, control);
}
} else {
// Circle
if (code & SCI_PATTERN_CODE_USE_TEXTURE) {
- vectorPatternTexturedCircle(rect, size, color, priority, control, texture);
+ vectorPatternTexturedCircle(box, clipBox, size, color, priority, control, texture);
} else {
- vectorPatternCircle(rect, size, color, priority, control);
+ vectorPatternCircle(box, clipBox, size, color, priority, control);
}
}
}
diff --git a/engines/sci/graphics/picture.h b/engines/sci/graphics/picture.h
index 8599b5935c4..261e1d11ccf 100644
--- a/engines/sci/graphics/picture.h
+++ b/engines/sci/graphics/picture.h
@@ -69,10 +69,10 @@ private:
void vectorGetPatternTexture(const SciSpan<const byte> &data, uint &curPos, int16 pattern_Code, int16 &pattern_Texture);
void vectorFloodFill(int16 x, int16 y, byte color, byte prio, byte control);
void vectorPattern(int16 x, int16 y, byte pic_color, byte pic_priority, byte pic_control, byte code, byte texture);
- void vectorPatternBox(Common::Rect box, byte color, byte prio, byte control);
- void vectorPatternTexturedBox(Common::Rect box, byte color, byte prio, byte control, byte texture);
- void vectorPatternCircle(Common::Rect box, byte size, byte color, byte prio, byte control);
- void vectorPatternTexturedCircle(Common::Rect box, byte size, byte color, byte prio, byte control, byte texture);
+ void vectorPatternBox(Common::Rect box, Common::Rect clipBox, byte color, byte prio, byte control);
+ void vectorPatternTexturedBox(Common::Rect box, Common::Rect clipBox, byte color, byte prio, byte control, byte texture);
+ void vectorPatternCircle(Common::Rect box, Common::Rect clipBox, byte size, byte color, byte prio, byte control);
+ void vectorPatternTexturedCircle(Common::Rect box, Common::Rect clipBox, byte size, byte color, byte prio, byte control, byte texture);
ResourceManager *_resMan;
GfxCoordAdjuster16 *_coordAdjuster;
Commit: cd1639019874e2c8e8ad209aa2cfb9f26c0076f3
https://github.com/scummvm/scummvm/commit/cd1639019874e2c8e8ad209aa2cfb9f26c0076f3
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2022-03-02T01:15:43-05:00
Commit Message:
SCI: Fix SQ3 ScumSoft announcements never appearing
Fixes bug #13318
Thanks to @Doomlazer for reporting this!
Changed paths:
engines/sci/engine/script_patches.cpp
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 046e0c21302..39e70f1ec47 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -104,6 +104,8 @@ static const char *const selectorNameTable[] = {
"handsOff", // system selector
"handsOn", // system selector
"type", // system selector
+ "client", // system selector
+ "state", // system selector
"localize", // Freddy Pharkas
"roomFlags", // Iceman
"put", // Police Quest 1 VGA
@@ -189,7 +191,6 @@ static const char *const selectorNameTable[] = {
"saveFilePtr", // RAMA
"priority", // RAMA
"plane", // RAMA
- "state", // RAMA
"getSubscriberObj", // RAMA
"advanceCurIcon", // QFG4
"amount", // QFG4
@@ -234,6 +235,8 @@ enum ScriptPatcherSelectors {
SELECTOR_handsOff,
SELECTOR_handsOn,
SELECTOR_type,
+ SELECTOR_client,
+ SELECTOR_state,
SELECTOR_localize,
SELECTOR_roomFlags,
SELECTOR_put,
@@ -320,7 +323,6 @@ enum ScriptPatcherSelectors {
SELECTOR_saveFilePtr,
SELECTOR_priority,
SELECTOR_plane,
- SELECTOR_state,
SELECTOR_getSubscriberObj,
SELECTOR_advanceCurIcon,
SELECTOR_amount,
@@ -18369,6 +18371,57 @@ static const uint16 sq3EndCreditsPatch[] = {
PATCH_END
};
+// In the ScumSoft office there are two announcement messages which randomly
+// appear at most once per game, but they never appear in the later versions.
+// This is due to a script bug that was exposed when Sierra upgraded the Script
+// class in SQ3 version 1.018. The messages are displayed by the `announce`
+// Script object, but announce is never properly initialized with setScript.
+// This happened to work at first, but the newer Script:cue requires the client
+// property to be set. This prevents announce:changeState from ever running.
+//
+// We fix this by setting announce:client when initializing the scumSoft region
+// so that announce:changeState runs in all versions. We set announce as its
+// own client since any object will do and this ensures there are no conflicts.
+//
+// Responsible method: scumSoft:init
+// Applies to: English PC 1.018, French PC, German PC, German Amiga, Macintosh
+// Fixes bug: #13318
+static const uint16 sq3AnnouncementsSignature[] = {
+ 0x39, SIG_SELECTOR8(state), // pushi state
+ SIG_MAGICDWORD,
+ 0x78, // push1
+ 0x89, 0xf2, // lsg f2
+ 0x72, SIG_ADDTOOFFSET(+2), // lofsa announce
+ 0x4a, 0x06, // send 06 [ announce state: global242 ]
+ 0x81, 0xe9, // lag e9
+ 0x30, SIG_ADDTOOFFSET(+2), // bnt [ end of method ]
+ 0x89, 0x0c, // lsg 0c
+ 0x35, 0x5a, // ldi 5a
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x000f), // bnt 000f
+ 0x35, 0x00, // ldi 00
+ 0xa1, 0xe9, // sag e9
+ 0x35, 0x00, // ldi 00 [ redundant ]
+ SIG_END
+};
+
+static const uint16 sq3AnnouncementsPatch[] = {
+ PATCH_ADDTOOFFSET(+8),
+ 0x39, PATCH_SELECTOR8(client), // pushi client
+ 0x78, // push1
+ 0x36, // push
+ 0x4a, 0x0c, // send 0c [ announce state: global242, client: announce ]
+ 0x81, 0xe9, // lag e9
+ 0x30, PATCH_GETORIGINALUINT16ADJUST(+13, -04), // bnt [ end of method ]
+ 0x89, 0x0c, // lsg 0c
+ 0x35, 0x5a, // ldi 5a
+ 0x1a, // eq?
+ 0x31, 0x0c, // bnt 0c
+ 0x18, // not [ acc = 0 ]
+ 0xa1, 0xe9, // sag e9
+ PATCH_END
+};
+
// Space Quest 3 has some strings hard coded in the scripts file
// We need to patch them for the Hebrew translation
@@ -18400,6 +18453,7 @@ static const uint16 sq3HebrewStatusBarNamePatch[] = {
static const SciScriptPatcherEntry sq3Signatures[] = {
{ false, 0, "Hebrew: Replace name in status bar", 1, sq3HebrewStatusBarNameSignature, sq3HebrewStatusBarNamePatch },
{ true, 117, "Fix end credits", 1, sq3EndCreditsSignature, sq3EndCreditsPatch },
+ { true, 702, "Fix scumsoft announcements", 1, sq3AnnouncementsSignature, sq3AnnouncementsPatch },
{ false, 996, "Hebrew: Replace 'Enter input' prompt", 1, sq3HebrewEnterInputSignature, sq3HebrewEnterInputPatch },
SCI_SIGNATUREENTRY_TERMINATOR
};
More information about the Scummvm-git-logs
mailing list