diff options
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/engine/kernel.h | 3 | ||||
-rw-r--r-- | engines/sci/engine/kernel_tables.h | 12 | ||||
-rw-r--r-- | engines/sci/engine/kgraphics32.cpp | 17 | ||||
-rw-r--r-- | engines/sci/graphics/celobj32.cpp | 32 | ||||
-rw-r--r-- | engines/sci/graphics/celobj32.h | 2 |
5 files changed, 65 insertions, 1 deletions
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index d1dce37e48..baa891650e 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -636,6 +636,9 @@ reg_t kCelInfo(EngineState *s, int argc, reg_t *argv); reg_t kCelInfoGetOriginX(EngineState *s, int argc, reg_t *argv); reg_t kCelInfoGetOriginY(EngineState *s, int argc, reg_t *argv); reg_t kCelInfoGetPixel(EngineState *s, int argc, reg_t *argv); +reg_t kCelLink(EngineState *s, int argc, reg_t *argv); +reg_t kCelLinkGetX(EngineState *s, int argc, reg_t *argv); +reg_t kCelLinkGetY(EngineState *s, int argc, reg_t *argv); reg_t kSetLanguage(EngineState *s, int argc, reg_t *argv); reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index c65356470a..ac932199d3 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -575,6 +575,16 @@ static const SciKernelMapSubEntry kCelInfo_subops[] = { }; // version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kCelLink_subops[] = { + { SIG_SINCE_SCI21MID, 0, MAP_DUMMY(CelLink0), "", NULL }, + { SIG_SINCE_SCI21MID, 1, MAP_DUMMY(CelLink1), "", NULL }, + { SIG_SINCE_SCI21MID, 2, MAP_CALL(CelLinkGetX), "iiii", NULL }, + { SIG_SINCE_SCI21MID, 3, MAP_CALL(CelLinkGetY), "iiii", NULL }, + { SIG_SINCE_SCI21MID, 4, MAP_DUMMY(CelLink4), "", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds static const SciKernelMapSubEntry kScrollWindow_subops[] = { { SIG_SCI32, 0, MAP_CALL(ScrollWindowCreate), "oi", NULL }, { SIG_SCI32, 1, MAP_CALL(ScrollWindowAdd), "iriii(i)", kScrollWindowAdd_workarounds }, @@ -988,7 +998,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_DUMMY(FindClass), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_DUMMY(CelRect), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_DUMMY(BaseLineSpan), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_DUMMY(CelLink), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(CelLink), SIG_SINCE_SCI21MID, SIGFOR_ALL, "(.*)", kCelLink_subops, NULL }, { MAP_DUMMY(AddPolygon), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_DUMMY(DeletePolygon), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_DUMMY(UpdatePolygon), SIG_EVERYWHERE, "(.*)", NULL, NULL }, diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp index 44a3517458..c07282f53e 100644 --- a/engines/sci/engine/kgraphics32.cpp +++ b/engines/sci/engine/kgraphics32.cpp @@ -449,6 +449,23 @@ reg_t kCelInfoGetPixel(EngineState *s, int argc, reg_t *argv) { return make_reg(0, view.readPixel(argv[3].toSint16(), argv[4].toSint16(), view._mirrorX)); } +// Used by Lighthouse, room 800, script 16, when in the weapon-building puzzle +reg_t kCelLink(EngineState *s, int argc, reg_t *argv) { + if (!s) + return make_reg(0, getSciVersion()); + error("not supposed to call this"); +} + +reg_t kCelLinkGetX(EngineState *s, int argc, reg_t *argv) { + CelObjView view(argv[0].toUint16(), argv[1].toSint16(), argv[2].toSint16()); + return make_reg(0, view.getLinkPosition(argv[3].toSint16()).x); +} + +reg_t kCelLinkGetY(EngineState *s, int argc, reg_t *argv) { + CelObjView view(argv[0].toUint16(), argv[1].toSint16(), argv[2].toSint16()); + return make_reg(0, view.getLinkPosition(argv[3].toSint16()).y); +} + reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) { if (!s) return make_reg(0, getSciVersion()); diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp index 49b3b0053b..687ecd64f3 100644 --- a/engines/sci/graphics/celobj32.cpp +++ b/engines/sci/graphics/celobj32.cpp @@ -1081,6 +1081,38 @@ const SciSpan<const byte> CelObjView::getResPointer() const { return *resource; } +Common::Point CelObjView::getLinkPosition(const int16 linkId) const { + const SciSpan<const byte> resource = getResPointer(); + + if (resource[18] < 0x84) { + error("%s unsupported version %u for Links", _info.toString().c_str(), resource[18]); + } + + const SciSpan<const byte> celHeader = resource.subspan(_celHeaderOffset); + const int16 numLinks = celHeader.getInt16SEAt(40); + + if (numLinks) { + const int recordSize = 6; + SciSpan<const byte> linkTable = resource.subspan(celHeader.getInt32SEAt(36), recordSize * numLinks); + for (int16 i = 0; i < numLinks; ++i) { + if (linkTable[4] == linkId) { + Common::Point point; + point.x = linkTable.getInt16SEAt(0); + if (_mirrorX) { + // NOTE: SSCI had an off-by-one error here (missing -1) + point.x = _width - point.x - 1; + } + point.y = linkTable.getInt16SEAt(2); + return point; + } + + linkTable += recordSize; + } + } + + return Common::Point(-1, -1); +} + #pragma mark - #pragma mark CelObjPic diff --git a/engines/sci/graphics/celobj32.h b/engines/sci/graphics/celobj32.h index d51913473c..6e50f7232e 100644 --- a/engines/sci/graphics/celobj32.h +++ b/engines/sci/graphics/celobj32.h @@ -540,6 +540,8 @@ public: virtual CelObjView *duplicate() const override; virtual const SciSpan<const byte> getResPointer() const override; + + Common::Point getLinkPosition(const int16 linkId) const; }; #pragma mark - |