diff options
author | Kamil Zbróg | 2013-11-18 16:19:47 +0000 |
---|---|---|
committer | Kamil Zbróg | 2013-11-18 16:19:47 +0000 |
commit | 446c57d281e592653c9935c896d33334d23f0519 (patch) | |
tree | ec3d5de5c92d10038890d72fd565e339f6bb46f4 /engines | |
parent | 3d1d1884324a240b73fea6de3b5df6f7310eeb53 (diff) | |
parent | 6244b6afe2e4634946ede4f971f664e7213014ed (diff) | |
download | scummvm-rg350-446c57d281e592653c9935c896d33334d23f0519.tar.gz scummvm-rg350-446c57d281e592653c9935c896d33334d23f0519.tar.bz2 scummvm-rg350-446c57d281e592653c9935c896d33334d23f0519.zip |
Merge remote-tracking branch 'sync/master' into prince-malik
Diffstat (limited to 'engines')
-rw-r--r-- | engines/avalanche/avalot.cpp | 1 | ||||
-rw-r--r-- | engines/avalanche/timer.cpp | 20 | ||||
-rw-r--r-- | engines/avalanche/timer.h | 2 | ||||
-rw-r--r-- | engines/engines.mk | 10 | ||||
-rw-r--r-- | engines/fullpipe/messages.cpp | 13 | ||||
-rw-r--r-- | engines/fullpipe/messages.h | 1 | ||||
-rw-r--r-- | engines/fullpipe/motion.cpp | 171 | ||||
-rw-r--r-- | engines/fullpipe/motion.h | 29 | ||||
-rw-r--r-- | engines/sci/engine/script_patches.cpp | 96 | ||||
-rw-r--r-- | engines/sci/engine/workarounds.cpp | 3 | ||||
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_scenes1.cpp | 94 | ||||
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_scenes1.h | 7 | ||||
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_scenes2.cpp | 25 | ||||
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_scenes2.h | 1 | ||||
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_speakers.cpp | 2 | ||||
-rw-r--r-- | engines/wintermute/base/base_file_manager.cpp | 43 | ||||
-rw-r--r-- | engines/wintermute/base/font/base_font_truetype.cpp | 17 | ||||
-rw-r--r-- | engines/wintermute/base/font/base_font_truetype.h | 2 | ||||
-rw-r--r-- | engines/wintermute/detection.cpp | 1 | ||||
-rw-r--r-- | engines/wintermute/detection_tables.h | 16 |
20 files changed, 374 insertions, 180 deletions
diff --git a/engines/avalanche/avalot.cpp b/engines/avalanche/avalot.cpp index 5d360d1c3f..87b2b7aef0 100644 --- a/engines/avalanche/avalot.cpp +++ b/engines/avalanche/avalot.cpp @@ -1486,6 +1486,7 @@ void AvalancheEngine::resetVariables() { _sequence->resetVariables(); _background->resetVariables(); _menu->resetVariables(); + _timer->resetVariables(); } void AvalancheEngine::newGame() { diff --git a/engines/avalanche/timer.cpp b/engines/avalanche/timer.cpp index 8a4ee7ed22..93889b76b7 100644 --- a/engines/avalanche/timer.cpp +++ b/engines/avalanche/timer.cpp @@ -35,12 +35,7 @@ namespace Avalanche { Timer::Timer(AvalancheEngine *vm) { _vm = vm; - for (int i = 0; i < 7; i++) { - _times[i]._timeLeft = 0; - _times[i]._action = 0; - _times[i]._reason = 0; - } - _timerLost = false; + resetVariables(); } /** @@ -48,7 +43,7 @@ Timer::Timer(AvalancheEngine *vm) { * @remarks Originally called 'set_up_timer' */ void Timer::addTimer(int32 duration, byte action, byte reason) { - if ((_vm->_ableToAddTimer == false) || (_timerLost == true)) { + if (_vm->_ableToAddTimer) { byte i = 0; while ((i < 7) && (_times[i]._timeLeft != 0)) i++; @@ -61,7 +56,7 @@ void Timer::addTimer(int32 duration, byte action, byte reason) { _times[i]._action = action; _times[i]._reason = reason; } else { - _vm->_ableToAddTimer = false; + _vm->_ableToAddTimer = true; return; } } @@ -218,7 +213,6 @@ void Timer::loseTimer(byte which) { _times[i]._timeLeft = 0; // Cancel this one! } - _timerLost = true; } void Timer::openDrawbridge() { @@ -690,4 +684,12 @@ void Timer::giveLuteToGeida() { // Moved here from Acci. _vm->_sequence->startGeidaLuteSeq(); } +void Timer::resetVariables() { + for (int i = 0; i < 7; i++) { + _times[i]._timeLeft = 0; + _times[i]._action = 0; + _times[i]._reason = 0; + } +} + } // End of namespace Avalanche. diff --git a/engines/avalanche/timer.h b/engines/avalanche/timer.h index 6cd894b0a5..9a91c4d24b 100644 --- a/engines/avalanche/timer.h +++ b/engines/avalanche/timer.h @@ -119,10 +119,10 @@ public: }; TimerType _times[7]; - bool _timerLost; // Is the timer "lost"? (Because of using loseTimer()) Timer(AvalancheEngine *vm); + void resetVariables(); void addTimer(int32 duration, byte action, byte reason); void updateTimer(); void loseTimer(byte which); diff --git a/engines/engines.mk b/engines/engines.mk index c15b0ad43c..ff43c5403c 100644 --- a/engines/engines.mk +++ b/engines/engines.mk @@ -140,16 +140,16 @@ DEFINES += -DENABLE_RIVEN endif endif -ifdef ENABLE_NEVERHOOD -DEFINES += -DENABLE_NEVERHOOD=$(ENABLE_NEVERHOOD) -MODULES += engines/neverhood -endif - ifdef ENABLE_MORTEVIELLE DEFINES += -DENABLE_MORTEVIELLE=$(ENABLE_MORTEVIELLE) MODULES += engines/mortevielle endif +ifdef ENABLE_NEVERHOOD +DEFINES += -DENABLE_NEVERHOOD=$(ENABLE_NEVERHOOD) +MODULES += engines/neverhood +endif + ifdef ENABLE_PARALLACTION DEFINES += -DENABLE_PARALLACTION=$(ENABLE_PARALLACTION) MODULES += engines/parallaction diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp index cad1934c5f..4abf2ef56f 100644 --- a/engines/fullpipe/messages.cpp +++ b/engines/fullpipe/messages.cpp @@ -201,6 +201,19 @@ MessageQueue::MessageQueue() { _flag1 = 0; } +MessageQueue::MessageQueue(int dataId) { + _field_14 = 0; + _parId = 0; + _dataId = dataId; + _id = g_fullpipe->_globalMessageQueueList->compact(); + _isFinished = 0; + _flags = 0; + _queueName = 0; + _counter = 0; + _field_38 = 0; + _flag1 = 0; +} + MessageQueue::MessageQueue(MessageQueue *src, int parId, int field_38) { _counter = 0; _field_38 = (field_38 == 0); diff --git a/engines/fullpipe/messages.h b/engines/fullpipe/messages.h index 3e0da292d5..326f05cef3 100644 --- a/engines/fullpipe/messages.h +++ b/engines/fullpipe/messages.h @@ -109,6 +109,7 @@ class MessageQueue : public CObject { public: MessageQueue(); + MessageQueue(int dataId); MessageQueue(MessageQueue *src, int parId, int field_38); virtual ~MessageQueue(); diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp index ebb838e2fb..c1977c0ac3 100644 --- a/engines/fullpipe/motion.cpp +++ b/engines/fullpipe/motion.cpp @@ -371,8 +371,8 @@ void MovGraph::calcNodeDistancesAndAngles() { } int MovGraph2::getItemIndexByGameObjectId(int objectId) { - for (uint i = 0; i < _items.size(); i++) - if (_items[i]->_objectId == objectId) + for (uint i = 0; i < _items2.size(); i++) + if (_items2[i]->_objectId == objectId) return i; return -1; @@ -380,7 +380,7 @@ int MovGraph2::getItemIndexByGameObjectId(int objectId) { int MovGraph2::getItemSubIndexByStaticsId(int idx, int staticsId) { for (int i = 0; i < 4; i++) - if (_items[idx]->_subItems[i]._staticsId1 == staticsId || _items[idx]->_subItems[i]._staticsId2 == staticsId) + if (_items2[idx]->_subItems[i]._staticsId1 == staticsId || _items2[idx]->_subItems[i]._staticsId2 == staticsId) return i; return -1; @@ -388,8 +388,8 @@ int MovGraph2::getItemSubIndexByStaticsId(int idx, int staticsId) { int MovGraph2::getItemSubIndexByMovementId(int idx, int movId) { for (int i = 0; i < 4; i++) - if (_items[idx]->_subItems[i]._walk[0]._movementId == movId || _items[idx]->_subItems[i]._turn[0]._movementId == movId || - _items[idx]->_subItems[i]._turnS[0]._movementId == movId) + if (_items2[idx]->_subItems[i]._walk[0]._movementId == movId || _items2[idx]->_subItems[i]._turn[0]._movementId == movId || + _items2[idx]->_subItems[i]._turnS[0]._movementId == movId) return i; return -1; @@ -536,12 +536,12 @@ void MovGraph2::addObject(StaticANIObject *obj) { int id = getItemIndexByGameObjectId(obj->_id); if (id >= 0) { - _items[id]->_obj = obj; + _items2[id]->_obj = obj; } else { MovGraph2Item *item = new MovGraph2Item; if (initDirections(obj, item)) { - _items.push_back(item); + _items2.push_back(item); } else { delete item; } @@ -658,129 +658,121 @@ void MovGraph2::buildMovInfo1SubItems(MovInfo1 *movinfo, Common::Array<MovGraphL } MessageQueue *MovGraph2::buildMovInfo1MessageQueue(MovInfo1 *movInfo) { -#if 0 MovInfo1 movinfo; - memcpy(movinfo, movInfo, sizeof(movinfo)); + memcpy(&movinfo, movInfo, sizeof(movinfo)); - curX = movInfo->pt1.x; - curY = movInfo->pt1.y; - curDistance = movInfo->distance1; + int curX = movInfo->pt1.x; + int curY = movInfo->pt1.y; + int curDistance = movInfo->distance1; - mq = new MessageQueue(g_fullpipe->globalMessageQueueList->compact()); + MessageQueue *mq = new MessageQueue(g_fullpipe->_globalMessageQueueList->compact()); - for (int i = 0; i < movInfo->_itemsCount - 1; i++) { - v10 = movInfo->items[i + 1].subIndex; + for (int i = 0; i < movInfo->itemsCount - 1; i++) { + if (movInfo->items[i + 1]->subIndex != 10) { + MG2I *mg2i; - if (v10 != 10) { - if (i >= movInfo->itemsCount - 2 || movInfo->items[i + 2].subIndex != 10) { - v17 = (char *)_items[1] + 16 * (v10 + 8); + if (i >= movInfo->itemsCount - 2 || movInfo->items[i + 2]->subIndex != 10) { movinfo.flags = 0; - subidx = 8 * 93 * movInfo->field_0; - v15 = (MovGraph2Item *)(&v17[184 * movInfo->items[i].subIndex] + subidx); + mg2i = &_items2[movInfo->field_0]->_subItems[movInfo->items[i]->subIndex]._turnS[movInfo->items[i + 1]->subIndex]; } else { - v12 = (char *)_items[1] + 16 * (v10 + 4); movinfo.flags = 2; - subidx = 8 * 93 * movInfo->field_0; - v15 = (MovGraph2Item *)(&v12[184 * movInfo->items[i].subIndex] + subidx); + mg2i = &_items2[movInfo->field_0]->_subItems[movInfo->items[i]->subIndex]._turn[movInfo->items[i + 1]->subIndex]; } if (i < movInfo->itemsCount - 2 - || (v19 = movInfo->items[i + 1].x, v20 = (char *)&movInfo->items[i].x, v47 = (int *)v20, v21 = *(_DWORD *)v20, v21 == v19) - && movInfo->items[i].y == movInfo->items[i + 1].y - || v21 == -1 - || movInfo->items[i].y == -1 - || v19 == -1 - || movInfo->items[i + 1].y == -1) { + || (movInfo->items[i]->x == movInfo->items[i + 1]->x + && movInfo->items[i]->y == movInfo->items[i + 1]->y) + || movInfo->items[i]->x == -1 + || movInfo->items[i]->y == -1 + || movInfo->items[i + 1]->x == -1 + || movInfo->items[i + 1]->y == -1) { - ExCommand *ex = new ExCommand(_items[1][movInfo->field_0].objectId, 1, v15->_objectId, 0, 0, 0, 1, 0, 0, 0); + ExCommand *ex = new ExCommand(_items2[movInfo->field_0]->_objectId, 1, mg2i->_movementId, 0, 0, 0, 1, 0, 0, 0); - ex->_excFlags |= 2u; - ex->_keyCode = _items[1][movInfo->field_0].obj->GameObject.okeyCode; + ex->_excFlags |= 2; + ex->_keyCode = _items2[movInfo->field_0]->_obj->_okeyCode; ex->_field_24 = 1; ex->_field_14 = -1; mq->_exCommands.push_back(ex); - curX += v15->_subItems[0].staticsId2; - curY += v15->_subItems[0].staticsId1; + curX += mg2i->_mx; + curY += mg2i->_my; } else { - memset(mgminfo, 0, sizeof(mgminfo)); - - HIWORD(v22) = 0; - v23 = (Movement *)v15->obj; - mgminfo.ani = *(StaticANIObject **)((char *)&this->items[1]->obj + v14); - LOWORD(v22) = v23->staticsObj2->staticsId; - mgminfo.staticsId2 = v22; - mgminfo.x1 = movInfo->items[i + 1].x; - mgminfo.y1 = movInfo->items[i + 1].y; - mgminfo.field_1C = movInfo->items[i + 1].field_C; - mgminfo.staticsId1 = v23->staticsObj1->staticsId; - - mgminfo.x2 = *v47; - mgminfo.y2 = movInfo->items[i].y; + MGMInfo mgminfo; + + memset(&mgminfo, 0, sizeof(mgminfo)); + + mgminfo.ani = _items2[movInfo->field_0]->_obj; + mgminfo.staticsId2 = mg2i->_mov->_staticsObj2->_staticsId; + mgminfo.x1 = movInfo->items[i + 1]->x; + mgminfo.y1 = movInfo->items[i + 1]->y; + mgminfo.field_1C = movInfo->items[i + 1]->distance; + mgminfo.staticsId1 = mg2i->_mov->_staticsObj1->_staticsId; + + mgminfo.x2 = movInfo->items[i]->x; + mgminfo.y2 = movInfo->items[i]->y; mgminfo.field_10 = 1; mgminfo.flags = 0x7f; - mgminfo.movementId = v15->_objectId; + mgminfo.movementId = mg2i->_movementId; - v25 = (MessageQueue *)MGM_sub_445330((MGM *)&this->movGraph.mgm, &mgminfo); - mq->transferExCommands(v25); + MessageQueue *mq2 = _mgm.genMovement(&mgminfo); + mq->transferExCommands(mq2); - if (v25) - (*(void (__thiscall **)(MessageQueue *, signed int))(v25->CObject.vmt + 4))(v25, 1); + delete mq2; - v26 = (MovInfo1Sub *)movInfo->items; - curX = v26[i + 1].x; - curY = v26[i + 1].y; + curX = movInfo->items[i + 1]->x; + curY = movInfo->items[i + 1]->y; } } else { - movinfo.item1Index = movInfo->items[i].subIndex; + movinfo.item1Index = movInfo->items[i]->subIndex; movinfo.subIndex = movinfo.item1Index; movinfo.pt1.y = curY; movinfo.pt1.x = curX; movinfo.distance1 = curDistance; - movinfo.pt2.x = movInfo->items[i + 2].x; - movinfo.pt2.y = movInfo->items[i + 2].y; - movinfo.distance2 = movInfo->items[i + 2].field_C; + movinfo.pt2.x = movInfo->items[i + 2]->x; + movinfo.pt2.y = movInfo->items[i + 2]->y; + movinfo.distance2 = movInfo->items[i + 2]->distance; if (i >= movInfo->itemsCount - 4 - || movInfo->items[i + 2].subIndex == 10 - || movInfo->items[i + 3].subIndex == 10 - || movInfo->items[i + 2].subIndex == movInfo->items[i + 3].subIndex - || movInfo->items[i + 4].subIndex != 10) { + || movInfo->items[i + 2]->subIndex == 10 + || movInfo->items[i + 3]->subIndex == 10 + || movInfo->items[i + 2]->subIndex == movInfo->items[i + 3]->subIndex + || movInfo->items[i + 4]->subIndex != 10) { if (i >= movInfo->itemsCount - 3 - || movInfo->items[i + 2].subIndex == 10 - || movInfo->items[i + 3].subIndex == 10 - || movInfo->items[i + 2].subIndex == movInfo->items[i + 3].subIndex) { + || movInfo->items[i + 2]->subIndex == 10 + || movInfo->items[i + 3]->subIndex == 10 + || movInfo->items[i + 2]->subIndex == movInfo->items[i + 3]->subIndex) { movinfo.flags &= 3; } else { - v35 = (MovInfo1 *)((char *)&_items[1][movInfo->field_0] + 184 * movInfo->items[i + 2].subIndex + 16 * (movInfo->items[i + 3].subIndex + 8)); - movinfo.pt2.x -= v35->pt1.y; - movinfo.pt2.y -= v35->pt2.x; + MG2I *m = &_items2[movInfo->field_0]->_subItems[movInfo->items[i + 2]->subIndex]._turnS[movInfo->items[i + 3]->subIndex]; + movinfo.pt2.x -= m->_mx; + movinfo.pt2.y -= m->_my; movinfo.flags &= 3; } } else { - v32 = (MovInfo1 *)((char *)&_items[1][movInfo->field_0] + 184 * movInfo->items[i + 2].subIndex + 16 * (movInfo->items[i + 3].subIndex + 4)); + MG2I *m = &_items2[movInfo->field_0]->_subItems[movInfo->items[i + 2]->subIndex]._turn[movInfo->items[i + 3]->subIndex]; if (movinfo.item1Index && movinfo.item1Index != 1) { - movinfo.pt2.y -= v32->pt2.x; + movinfo.pt2.y -= m->_my; movinfo.flags = (movinfo.flags & 2) | 1; } else { - movinfo.pt2.x -= v32->pt1.y; + movinfo.pt2.x -= m->_mx; movinfo.flags = (movinfo.flags & 2) | 1; } } i++; // intentional - v36 = sub1(&movinfo); + MessageQueue *mq2 = genMovement(&movinfo); - if (!v36) { + if (mq2) { delete mq; return 0; } - mq->transferExCommands(v36); + mq->transferExCommands(mq2); - delete v36; + delete mq2; curX = movinfo.pt2.x; curY = movinfo.pt2.y; @@ -792,11 +784,6 @@ MessageQueue *MovGraph2::buildMovInfo1MessageQueue(MovInfo1 *movInfo) { movInfo->pt2.y = movinfo.pt2.y; return mq; - -#endif - warning("STUB: MovGraph2::buildMovInfo1MessageQueue()"); - - return 0; } int MovGraph2::removeObject(StaticANIObject *obj) { @@ -894,7 +881,7 @@ MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int if (subMgm) { obj->_messageQueueId = 0; - obj->changeStatics2(_items[idx]->_subItems[idxsub]._staticsId1); + obj->changeStatics2(_items2[idx]->_subItems[idxsub]._staticsId1); newx = obj->_ox; newy = obj->_oy; } else { @@ -929,7 +916,7 @@ MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int return 0; } - ExCommand *ex = new ExCommand(picAniInfo.objectId, 1, _items[idx]->_subItems[idxsub]._walk[idxwalk]._movementId, 0, 0, 0, 1, 0, 0, 0); + ExCommand *ex = new ExCommand(picAniInfo.objectId, 1, _items2[idx]->_subItems[idxsub]._walk[idxwalk]._movementId, 0, 0, 0, 1, 0, 0, 0); ex->_field_24 = 1; ex->_keyCode = picAniInfo.field_8; @@ -1044,7 +1031,7 @@ MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int movInfo1.flags = fuzzyMatch != 0; - if (_items[idx]->_subItems[idxsub]._staticsId1 != obj->_statics->_staticsId) + if (_items2[idx]->_subItems[idxsub]._staticsId1 != obj->_statics->_staticsId) movInfo1.flags |= 2; buildMovInfo1SubItems(&movInfo1, &tempLinkList, &linkInfoSource, &linkInfoDest); @@ -1071,7 +1058,7 @@ MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int ex->_excFlags |= 2; mq->addExCommand(ex); - ex = new ExCommand(picAniInfo.objectId, 22, _items[idx]->_subItems[idxsub]._staticsId1, 0, 0, 0, 1, 0, 0, 0); + ex = new ExCommand(picAniInfo.objectId, 22, _items2[idx]->_subItems[idxsub]._staticsId1, 0, 0, 0, 1, 0, 0, 0); ex->_keyCode = picAniInfo.field_8; ex->_excFlags |= 3; @@ -1168,6 +1155,12 @@ int MovGraph2::findLink(Common::Array<MovGraphLink *> *linkList, int idx, Common return node3->_x >= node2->_x; } +MessageQueue *MovGraph2::genMovement(MovInfo1 *movinfo) { + warning("STUB: MovGraph2::genMovement()"); + + return 0; +} + MovGraphLink *MovGraph2::findLink1(int x, int y, int idx, int fuzzyMatch) { Common::Point point; MovGraphLink *res = 0; @@ -1394,6 +1387,12 @@ int MGM::getItemIndexById(int objId) { return -1; } +MessageQueue *MGM::genMovement(MGMInfo *mgminfo) { + warning("STUB: MGM::genMovement()"); + + return 0; +} + MovGraphLink::MovGraphLink() { _distance = 0; _angle = 0; diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h index 0df520ce4a..bab0ffc8ca 100644 --- a/engines/fullpipe/motion.h +++ b/engines/fullpipe/motion.h @@ -78,7 +78,7 @@ public: class MctlCompoundArrayItem : public CObject { friend class MctlCompound; - protected: +protected: MotionController *_motionControllerObj; MovGraphReact *_movGraphReactObj; Common::Array<MctlConnectionPoint *> _connectionPoints; @@ -86,7 +86,7 @@ class MctlCompoundArrayItem : public CObject { int _field_24; int _field_28; - public: +public: MctlCompoundArrayItem() : _movGraphReactObj(0), _motionControllerObj(0), _field_20(0), _field_24(0), _field_28(0) {} }; @@ -134,6 +134,19 @@ struct MGMItem { MGMItem(); }; +struct MGMInfo { + StaticANIObject *ani; + int staticsId1; + int staticsId2; + int movementId; + int field_10; + int x1; + int y1; + int field_1C; + int x2; + int y2; + int flags; +}; class MGM : public CObject { public: @@ -144,6 +157,8 @@ public: void addItem(int objId); void rebuildTables(int objId); int getItemIndexById(int objId); + + MessageQueue *genMovement(MGMInfo *mgminfo); }; class MovGraphNode : public CObject { @@ -232,7 +247,7 @@ struct MovGraphItem { }; class MovGraph : public MotionController { - public: +public: ObList _nodes; ObList _links; int _field_44; @@ -240,7 +255,7 @@ class MovGraph : public MotionController { int (*_callback1)(int, int, int); MGM _mgm; - public: +public: MovGraph(); virtual bool load(MfcArchive &file); @@ -303,7 +318,7 @@ struct MovInfo1 { int flags; }; -struct MovGraph2Item { +struct MovGraph2Item { // 744 int _objectId; StaticANIObject *_obj; MovGraph2ItemSub _subItems[4]; // 184 @@ -311,7 +326,7 @@ struct MovGraph2Item { class MovGraph2 : public MovGraph { public: - Common::Array<MovGraph2Item *> _items; + Common::Array<MovGraph2Item *> _items2; public: virtual void addObject(StaticANIObject *obj); @@ -336,6 +351,8 @@ public: MovGraphLink *findLink1(int x, int y, int idx, int fuzzyMatch); MovGraphLink *findLink2(int x, int y); double findMinPath(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Common::Array<MovGraphLink *> *listObj); + + MessageQueue *genMovement(MovInfo1 *movinfo); }; class MctlConnectionPoint : public CObject { diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 9bf284d543..4a829c2457 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -121,23 +121,23 @@ struct SciScriptPatcherSelector { }; SciScriptPatcherSelector selectorTable[] = { - "cycles", -1, // system selector - "seconds", -1, // system selector - "init", -1, // system selector - "dispose", -1, // system selector - "new", -1, // system selector - "curEvent", -1, // system selector - "disable", -1, // system selector - "show", -1, // system selector - "x", -1, // system selector - "cel", -1, // system selector - "setMotion", -1, // system selector - "deskSarg", -1, // Gabriel Knight - "localize", -1, // Freddy Pharkas - "put", -1, // Police Quest 1 VGA - "solvePuzzle", -1, // Quest For Glory 3 - "timesShownID", -1, // Space Quest 1 VGA - NULL, -1 + { "cycles", -1, }, // system selector + { "seconds", -1, }, // system selector + { "init", -1, }, // system selector + { "dispose", -1, }, // system selector + { "new", -1, }, // system selector + { "curEvent", -1, }, // system selector + { "disable", -1, }, // system selector + { "show", -1, }, // system selector + { "x", -1, }, // system selector + { "cel", -1, }, // system selector + { "setMotion", -1, }, // system selector + { "deskSarg", -1, }, // Gabriel Knight + { "localize", -1, }, // Freddy Pharkas + { "put", -1, }, // Police Quest 1 VGA + { "solvePuzzle", -1, }, // Quest For Glory 3 + { "timesShownID", -1, }, // Space Quest 1 VGA + { NULL, -1 } }; enum ScriptPatcherSelectors { @@ -1738,6 +1738,65 @@ SciScriptPatcherEntry sq1vgaSignatures[] = { { 58, "Sarien armory droid zapping ego first time", 1, 0, 0, sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard }, SCI_SIGNATUREENTRY_TERMINATOR}; +// =========================================================================== +// The toolbox in sq5 is buggy. When you click on the upper part of the "put +// in inventory"-button (some items only - for example the hole puncher - at the +// upper left), points will get awarded correctly and the item will get put into +// the player's inventory, but you will then get a "not here" message and the +// item will also remain to be the current mouse cursor. +// The bug report also says that items may get lost. I wasn't able to reproduce +// that part. +// This is caused by the mouse-click event getting reprocessed (which wouldn't +// be a problem by itself) and during this reprocessing coordinates are not +// processed the same as during the first click (script 226 includes a local +// subroutine, which checks coordinates in a hardcoded way w/o port-adjustment). +// Because of this, the hotspot for the button is lower than it should be, which +// then results in the game thinking that the user didn't click on the button +// and also results in the previously mentioned message. +// This happened in Sierra SCI as well (of course). +// We fix it by combining state 0 + 1 of takeTool::changeState and so stopping +// the event to get reprocessed. This was the only way possible, because everything +// else is done in SCI system scripts and I don't want to touch those. +// Applies to at least: English/German/French PC floppy +// Responsible method: takeTool::changeState +// Fixes bug #6457 +const uint16 sq5SignatureToolboxFix[] = { + 0x31, 0x13, // bnt [check for state 1] + SIG_MAGICDWORD, + 0x38, SIG_UINT16 + 0xaa, 0x00, // pushi 00aa + 0x39, 0x05, // pushi 05 + 0x39, 0x16, // pushi 16 + 0x76, // push0 + 0x39, 0x03, // pushi 03 + 0x76, // push0 + 0x7c, // pushSelf + 0x81, 0x5b, // lag 5b + 0x4a, 0x0e, // send 0e + 0x32, SIG_UINT16 + 0x88, 0x00, // jmp [end-of-method] + 0x3c, // dup + 0x35, 0x01, // ldi 01 + 0x1a, // eq? + 0x31, 0x28, // bnt [check for state 2] + SIG_END +}; + +const uint16 sq5PatchToolboxFix[] = { + 0x31, 0x41, // bnt [check for state 2] + PATCH_ADDTOOFFSET +16, // skip to jmp offset + 0x35, 0x01, // ldi 01 + 0x65, 0x14, // aTop [state] + 0x36, 0x00, 0x00, // ldi 0000 (waste 3 bytes) + 0x35, 0x00, // ldi 00 (waste 2 bytes) + PATCH_END +}; + +// script, description, signature patch +SciScriptPatcherEntry sq5Signatures[] = { + { 226, "toolbox fix", 1, 0, 0, sq5SignatureToolboxFix, sq5PatchToolboxFix }, + SCI_SIGNATUREENTRY_TERMINATOR +}; + + // will actually patch previously found signature area void Script::patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, const bool isMacSci11) { const uint16 *patchData = patchEntry->patchData; @@ -2132,6 +2191,9 @@ void Script::patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint3 case GID_SQ4: signatureTable = sq4Signatures; break; + case GID_SQ5: + signatureTable = sq5Signatures; + break; default: break; } diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index 14fbee8e93..6c92f07272 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -180,6 +180,9 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = { { GID_SQ1, -1, 703, 0, "firePulsar", "changeState", 0x18a, 0, { WORKAROUND_FAKE, 0 } }, // export 1, but called locally (when shooting at aliens) { GID_SQ4, -1, 398, 0, "showBox", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // CD: called when rummaging in Software Excess bargain bin { GID_SQ4, -1, 928, -1, "Narrator", "startText", -1, 1000, { WORKAROUND_FAKE, 1 } }, // CD: happens in the options dialog and in-game when speech and subtitles are used simultaneously + { GID_SQ4, -1, 708, -1, "exitBut", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "close" button in the sq4 hintbook - bug #6447 + { GID_SQ4, -1, 708, -1, "prevBut", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "previous" button in the sq4 hintbook - bug #6447 + { GID_SQ4, -1, 708, -1, "nextBut", "doVerb", -1, 0, { WORKAROUND_FAKE, 0 } }, // Floppy: happens, when looking at the "next" button in the sq4 hintbook - bug #6447 { GID_SQ5, 201, 201, 0, "buttonPanel", "doVerb", -1, 0, { WORKAROUND_FAKE, 1 } }, // when looking at the orange or red button - bug #3038563 { GID_SQ6, -1, 0, 0, "SQ6", "init", -1, 2, { WORKAROUND_FAKE, 0 } }, // Demo and full version: called when the game starts (demo: room 0, full: room 100) { GID_SQ6, -1, 64950, -1, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // called when pressing "Start game" in the main menu, when entering the Orion's Belt bar (room 300), and perhaps other places diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.cpp b/engines/tsage/ringworld2/ringworld2_scenes1.cpp index 08b2783b8b..eaa60cadd7 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes1.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes1.cpp @@ -683,6 +683,7 @@ bool Scene1100::Seeker::startAction(CursorType action, Event &event) { Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene; if (R2_GLOBALS.getFlag(52)) { + // The trouper is dead R2_GLOBALS._player.disableControl(); if (R2_GLOBALS._player._characterIndex == R2_QUINN) scene->_nextStripNum = 327; @@ -691,6 +692,7 @@ bool Scene1100::Seeker::startAction(CursorType action, Event &event) { scene->_sceneMode = 53; scene->setAction(&scene->_sequenceManager1, scene, 1122, &R2_GLOBALS._player, NULL); } else { + // The trouper is not dead R2_GLOBALS._player.disableControl(); scene->_sceneMode = 55; if (R2_GLOBALS._stripModifier >= 3) { @@ -716,6 +718,7 @@ bool Scene1100::Trooper::startAction(CursorType action, Event &event) { switch (action) { case R2_NEGATOR_GUN: if (_visage == 1105) { + // Trooper wears the stasis shield R2_GLOBALS._player.disableControl(); scene->_sceneMode = 1114; scene->setAction(&scene->_sequenceManager1, scene, 1114, &R2_GLOBALS._player, &scene->_trooper, NULL); @@ -728,6 +731,7 @@ bool Scene1100::Trooper::startAction(CursorType action, Event &event) { // No break on purpose case R2_PHOTON_STUNNER: if (_visage == 1105) { + // If trooper wears the stasis shield R2_GLOBALS._player.disableControl(); if (R2_GLOBALS._player._characterIndex == R2_QUINN) { scene->_sceneMode = 1112; @@ -738,6 +742,7 @@ bool Scene1100::Trooper::startAction(CursorType action, Event &event) { } return true; } else if (_strip == 2) { + // Trooper wears his black uniform R2_GLOBALS._player.disableControl(); scene->_sceneMode = 1113; if (R2_GLOBALS._player._characterIndex == R2_QUINN) { @@ -757,7 +762,9 @@ bool Scene1100::Trooper::startAction(CursorType action, Event &event) { } bool Scene1100::Chief::startAction(CursorType action, Event &event) { + // CHECKME: Flag 54 is never set. Guess: the flag means "Chief is dead" if ((action == CURSOR_TALK) && (!R2_GLOBALS.getFlag(54)) && (R2_GLOBALS.getFlag(52))) { + // Talk to chief after the trooper dies Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene; scene->_nextStripNum = 0; @@ -842,6 +849,7 @@ void Scene1100::postInit(SceneObjectList *OwnerList) { _chief.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL); _trooper.postInit(); + // Trooper wears his stasis shield _trooper.setup(1105, 3, 1); _trooper.setPosition(Common::Point(312, 165)); _trooper._numFrames = 5; @@ -900,8 +908,10 @@ void Scene1100::postInit(SceneObjectList *OwnerList) { } else { _cloud.setPosition(Common::Point(180, 30)); if (R2_GLOBALS.getFlag(52)) + // Trooper is dead R2_GLOBALS._sound1.play(98); else + // Trooper is alive R2_GLOBALS._sound1.play(95); R2_GLOBALS._player.postInit(); @@ -910,6 +920,7 @@ void Scene1100::postInit(SceneObjectList *OwnerList) { _seeker.postInit(); if (R2_GLOBALS.getFlag(52)) { + // Trooper is dead if (R2_GLOBALS._player._characterIndex == R2_QUINN) { R2_GLOBALS._player.setup(19, 7, 1); _seeker.setup(29, 6, 1); @@ -921,6 +932,7 @@ void Scene1100::postInit(SceneObjectList *OwnerList) { _seeker.setPosition(Common::Point(237, 134)); R2_GLOBALS._player.enableControl(); } else { + // Trooper is alive if (R2_GLOBALS._player._characterIndex == R2_QUINN) { R2_GLOBALS._player.setup(1107, 2, 1); _seeker.setup(1107, 4, 1); @@ -952,16 +964,20 @@ void Scene1100::postInit(SceneObjectList *OwnerList) { _chief.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL); if (!R2_GLOBALS.getFlag(52)) { + // If trooper is alive, initialize him _trooper.postInit(); if (R2_GLOBALS.getFlag(53)) + // Trooper wears his black uniform _trooper.setup(1106, 2, 4); else + // Trooper wears a stasis shield _trooper.setup(1105, 4, 4); _trooper.setPosition(Common::Point(17, 54)); _trooper._numFrames = 5; if (R2_GLOBALS.getFlag(53)) + // Trooper isn't wearing the stasis shield _trooper.setDetails(1100, 28, -1, -1, 1, (SceneItem *) NULL); else _trooper.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL); @@ -1164,6 +1180,7 @@ void Scene1100::signal() { R2_GLOBALS._player._canWalk = false; break; case 51: + // Trooper no longer wears a statis shield R2_GLOBALS.setFlag(53); _trooper.setDetails(1100, 28, -1, -1, 3, (SceneItem *) NULL); @@ -1171,6 +1188,7 @@ void Scene1100::signal() { R2_GLOBALS._player._canWalk = false; break; case 52: + // Trooper is shot to death R2_GLOBALS._sound1.play(98); R2_GLOBALS.setFlag(52); R2_GLOBALS._player.disableControl(); @@ -10835,11 +10853,6 @@ void Scene1750::SpeedSlider::calculateSlider() { scene->_speed = scene->_direction * tmpVar2; } -void Scene1750::SpeedSlider::remove() { - // Function kept to match IDA. Could be removed. - SceneActor::remove(); -} - void Scene1750::SpeedSlider::process(Event &event) { if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) && (_bounds.contains(event.mousePos))) { @@ -10963,22 +10976,22 @@ void Scene1750::postInit(SceneObjectList *OwnerList) { _radarSweep.fixPriority(7); _radarSweep.setDetails(1750, 30, -1, -1, 1, (SceneItem *) NULL); - _scannerIcon1.postInit(); - _scannerIcon1.setup(1750, 2, 1); - _scannerIcon1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._rimLocation % 800) * 4) - 1440)); - _scannerIcon1.fixPriority(8); + _scannerIcon.postInit(); + _scannerIcon.setup(1750, 2, 1); + _scannerIcon.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._rimLocation % 800) * 4) - 1440)); + _scannerIcon.fixPriority(8); - _scannerIcon2.postInit(); - _scannerIcon2.setup(1750, 1, 4); + _redLights.postInit(); + _redLights.setup(1750, 1, 4); - int tmpVar = ABS(_scannerIcon1._position.y - 158) / 100; + int tmpVar = ABS(_scannerIcon._position.y - 158) / 100; if (tmpVar >= 8) - _scannerIcon2.hide(); - else if (_scannerIcon1._position.y <= 158) - _scannerIcon2.setPosition(Common::Point(137, (tmpVar * 7) + 122)); + _redLights.hide(); + else if (_scannerIcon._position.y <= 158) + _redLights.setPosition(Common::Point(137, (tmpVar * 7) + 122)); else - _scannerIcon2.setPosition(Common::Point(148, (tmpVar * 7) + 122)); + _redLights.setPosition(Common::Point(148, (tmpVar * 7) + 122)); _speedSlider.setupSlider(1, 286, 143, 41, 15); _speedSlider.setDetails(1750, 24, 1, -1, 1, (SceneItem *) NULL); @@ -11008,7 +11021,7 @@ void Scene1750::postInit(SceneObjectList *OwnerList) { _speed = 0; _rotationSegment = ((_rotation->_currIndex - 218) / 4) % 4; - _redLights.setDetails(Rect(129, 112, 155, 175), 1750, 21, -1, -1, 1, NULL); + _redLightsDescr.setDetails(Rect(129, 112, 155, 175), 1750, 21, -1, -1, 1, NULL); _greenLights.setDetails(Rect(93, 122, 126, 172), 1750, 15, -1, -1, 1, NULL); _frontView.setDetails(Rect(3, 3, 157, 99), 1750, 9, -1, -1, 1, NULL); _rearView.setDetails(Rect(162, 3, 316, 99), 1750, 12, -1, -1, 1, NULL); @@ -11078,7 +11091,7 @@ void Scene1750::dispatch() { --_speedDelta; _rotationSegCurrent = _rotationSegment; - _rotationSegment = ((_rotation->_currIndex - 218) / 4) / 4; + _rotationSegment = ((_rotation->_currIndex - 218) / 4) % 4; if ((_rotationSegCurrent + 1) == _rotationSegment || (_rotationSegCurrent - 3) == _rotationSegment) { if (R2_GLOBALS._rimLocation < 2400) { @@ -11093,19 +11106,21 @@ void Scene1750::dispatch() { } if (_rotation->_currIndex != _newRotation) { + // Handle setting the position of the lift icon in the scanner display _newRotation = _rotation->_currIndex; - _scannerIcon1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + + _scannerIcon.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._rimLocation % 800) * 4) - 1440)); } } - int v = ABS(_scannerIcon1._position.y - 158) / 100; + int v = ABS(_scannerIcon._position.y - 158) / 100; if (v < 8) { - _scannerIcon2.show(); - _scannerIcon2.setPosition(Common::Point((_scannerIcon1._position.y <= 158) ? 137 : 148, + // Show how close the user is to the lift on the second column of lights + _redLights.show(); + _redLights.setPosition(Common::Point((_scannerIcon._position.y <= 158) ? 137 : 148, v * 7 + 122)); } else { - _scannerIcon2.hide(); + _redLights.hide(); } } @@ -11201,8 +11216,11 @@ bool Scene1800::Doors::startAction(CursorType action, Event &event) { R2_GLOBALS.setFlag(14); } } else { + // Seeker failing to force open doors scene->_sceneMode = 1813; - scene->setAction(&scene->_sequenceManager, scene, 1813, &R2_GLOBALS._player, NULL); + // Original was using 1813 in setAction too, but it somewhat broken. + // Seeker goes 2 pixels to high, hiding behind the door + scene->setAction(&scene->_sequenceManager, scene, 1808, &R2_GLOBALS._player, &scene->_doors, NULL); } } else if (R2_GLOBALS.getFlag(14)) { return SceneActor::startAction(action, event); @@ -11567,6 +11585,29 @@ void Scene1800::signal() { R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); R2_GLOBALS._player.enableControl(CURSOR_USE); break; + // Cases 23 and 24 have been added to fix missing hardcoded logic in the original, + // when Seeker tries to open the door + case 23: + _sceneMode = 24; + R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); + R2_GLOBALS._player.setup(1801, 5, 1); + R2_GLOBALS._player.animate(ANIM_MODE_8, NULL); + _stripManager.start(550, this); + break; + case 24: + R2_GLOBALS._player.disableControl(); + R2_GLOBALS._player.setup(1507, 4, 1); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player.enableControl(CURSOR_USE); + + _doors.setup(1801, 3, 1); + _doors.setPosition(Common::Point(160, 139)); + _doors.setDetails(1800, 6, -1, -1, 1, (SceneItem *) NULL); + _doors.show(); + + R2_GLOBALS._player._position.y += 2; + R2_GLOBALS._player.show(); + break; case 1800: R2_GLOBALS._walkRegions.disableRegion(8); if (R2_GLOBALS.getFlag(63)) @@ -11615,6 +11656,11 @@ void Scene1800::signal() { _sceneMode = 13; R2_GLOBALS._player.animate(ANIM_MODE_5, this); break; + // Case 1813 has been added to fix Seeker missing animation in the original game + case 1813: + _sceneMode = 23; + R2_GLOBALS._player.animate(ANIM_MODE_5, this); + break; case 1814: // No break on purpose case 1815: diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.h b/engines/tsage/ringworld2/ringworld2_scenes1.h index 98cd172142..cc114b2033 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes1.h +++ b/engines/tsage/ringworld2/ringworld2_scenes1.h @@ -768,7 +768,6 @@ class Scene1750 : public SceneExt { void setupSlider(int incrAmount, int xp, int ys, int height, int thumbHeight); void calculateSlider(); - virtual void remove(); virtual void process(Event &event); virtual bool startAction(CursorType action, Event &event); }; @@ -785,12 +784,12 @@ class Scene1750 : public SceneExt { public: NamedHotspot _background; - NamedHotspot _redLights; + NamedHotspot _redLightsDescr; NamedHotspot _greenLights; NamedHotspot _frontView; NamedHotspot _rearView; - SceneActor _scannerIcon1; - SceneActor _scannerIcon2; + SceneActor _scannerIcon; + SceneActor _redLights; SceneActor _radarSweep; SpeedSlider _speedSlider; Button _forwardButton; diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.cpp b/engines/tsage/ringworld2/ringworld2_scenes2.cpp index 7785fe6aec..f928f3635c 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes2.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes2.cpp @@ -1061,8 +1061,9 @@ bool Scene2350::Balloon::startAction(CursorType action, Event &event) { void Scene2350::ExitUp::changeScene() { Scene2350 *scene = (Scene2350 *)R2_GLOBALS._sceneManager._scene; + _enabled = false; - R2_GLOBALS._player.disableControl(CURSOR_CROSSHAIRS); + R2_GLOBALS._player.disableControl(CURSOR_WALK); scene->_sceneMode = 12; if (R2_GLOBALS._player._characterIndex == R2_QUINN) scene->setAction(&scene->_sequenceManager, scene, 2350, &R2_GLOBALS._player, NULL); @@ -1139,7 +1140,7 @@ void Scene2350::postInit(SceneObjectList *OwnerList) { R2_GLOBALS._player.disableControl(); if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) { - if (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] == 34) { + if (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] != 34) { if (R2_GLOBALS._player._characterIndex == R2_QUINN) _sceneMode = 2351; else @@ -1201,17 +1202,6 @@ void Scene2350::signal() { } } -void Scene2350::process(Event &event) { - if ((R2_GLOBALS._player._canWalk) && (event.eventType != EVENT_BUTTON_DOWN) && - (R2_GLOBALS._events.getCursor() == CURSOR_CROSSHAIRS)){ - Common::Point pt(event.mousePos.x, 129); - PlayerMover *mover = new PlayerMover(); - R2_GLOBALS._player.addMover(mover, &pt); - event.handled = true; - } - Scene::process(event); -} - /*-------------------------------------------------------------------------- * Scene 2400 - Spill Mountains: Large empty room * @@ -2995,6 +2985,8 @@ void Scene2600::postInit(SceneObjectList *OwnerList) { loadScene(2600); R2_GLOBALS._uiElements._active = false; SceneExt::postInit(); + R2_GLOBALS._interfaceY = SCREEN_HEIGHT; + R2_GLOBALS._sound1.fadeSound(214); R2_GLOBALS._sound2.play(215); _rotation = R2_GLOBALS._scenePalette.addRotation(176, 191, 1); @@ -3009,6 +3001,7 @@ void Scene2600::postInit(SceneObjectList *OwnerList) { void Scene2600::remove() { R2_GLOBALS._sound1.fadeOut2(NULL); R2_GLOBALS._sound2.fadeOut2(NULL); + R2_GLOBALS._uiElements._visible = true; // _rotation->remove(); SceneExt::remove(); } @@ -3962,7 +3955,8 @@ void Scene2750::postInit(SceneObjectList *OwnerList) { R2_GLOBALS._player.setStrip(6); R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL); R2_GLOBALS._player.setPosition(Common::Point(81, 165)); - R2_GLOBALS._events.setCursor(CURSOR_WALK); + + R2_GLOBALS._events.setCursor(CURSOR_ARROW); _stripNumber = 1204; _sceneMode = 11; _stripManager.start(_stripNumber, this); @@ -3982,6 +3976,7 @@ void Scene2750::postInit(SceneObjectList *OwnerList) { R2_GLOBALS._player.enableControl(); } } + void Scene2750::signal() { switch (_sceneMode) { case 10: @@ -4332,7 +4327,7 @@ void Scene2800::Action2::signal() { R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper()); - Common::Point pt(100, 64); + Common::Point pt(64, 100); NpcMover *mover = new NpcMover(); R2_GLOBALS._player.addMover(mover, &pt, this); break; diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.h b/engines/tsage/ringworld2/ringworld2_scenes2.h index d474297d79..3960d93f94 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes2.h +++ b/engines/tsage/ringworld2/ringworld2_scenes2.h @@ -120,7 +120,6 @@ public: virtual void postInit(SceneObjectList *OwnerList = NULL); virtual void remove(); virtual void signal(); - virtual void process(Event &event); }; class Scene2400 : public SceneExt { diff --git a/engines/tsage/ringworld2/ringworld2_speakers.cpp b/engines/tsage/ringworld2/ringworld2_speakers.cpp index 61a4840fa5..675511ac10 100644 --- a/engines/tsage/ringworld2/ringworld2_speakers.cpp +++ b/engines/tsage/ringworld2/ringworld2_speakers.cpp @@ -1441,7 +1441,7 @@ void SpeakerQuinn2750::animateSpeaker() { _object1.setup(4022, 5, 1); break; case 2752: - _object1.setup(2752, 1, 1); + _object1.setup(2752, 3, 1); break; default: break; diff --git a/engines/wintermute/base/base_file_manager.cpp b/engines/wintermute/base/base_file_manager.cpp index bea7e53445..ae4c891c03 100644 --- a/engines/wintermute/base/base_file_manager.cpp +++ b/engines/wintermute/base/base_file_manager.cpp @@ -168,6 +168,11 @@ bool BaseFileManager::initPaths() { if (languageSubFolder.exists()) { addPath(PATH_PACKAGE, languageSubFolder); } + // Also add languages/ for Reversion1. + languageSubFolder = gameData.getChild("languages"); + if (languageSubFolder.exists()) { + addPath(PATH_PACKAGE, languageSubFolder); + } return STATUS_OK; } @@ -187,6 +192,9 @@ bool BaseFileManager::registerPackages(const Common::FSList &fslist) { bool BaseFileManager::registerPackages() { debugC(kWintermuteDebugFileAccess | kWintermuteDebugLog, "Scanning packages"); + // We need the target name as a Common::String to perform some game-specific hacks. + Common::String targetName = BaseEngine::instance().getGameTargetName(); + // Register without using SearchMan, as otherwise the FSNode-based lookup in openPackage will fail // and that has to be like that to support the detection-scheme. Common::FSList files; @@ -199,20 +207,43 @@ bool BaseFileManager::registerPackages() { if (!fileIt->getName().hasSuffix(".dcp")) { continue; } + // HACK: for Reversion1, avoid loading xlanguage_pt.dcp from the main folder: + if (_language != Common::PT_BRA && targetName.hasPrefix("reversion1")) { + if (fileIt->getName() == "xlanguage_pt.dcp") { + continue; + } + } // Avoid registering all the language files // TODO: Select based on the gameDesc. - if (_language != Common::UNK_LANG && fileIt->getParent().getName() == "language") { + if (_language != Common::UNK_LANG && (fileIt->getParent().getName() == "language" || fileIt->getParent().getName() == "languages")) { Common::String parentName = fileIt->getParent().getName(); Common::String dcpName = fileIt->getName(); - if (_language == Common::EN_ANY && fileIt->getName() != "english.dcp") { + // English + if (_language == Common::EN_ANY && (fileIt->getName() != "english.dcp" && fileIt->getName() != "xlanguage_en.dcp")) { + continue; + // Chinese + } else if (_language == Common::ZH_CNA && (fileIt->getName() != "chinese.dcp" && fileIt->getName() != "xlanguage_nz.dcp")) { + continue; + // Czech + } else if (_language == Common::CZ_CZE && (fileIt->getName() != "czech.dcp" && fileIt->getName() != "xlanguage_cz.dcp")) { + continue; + // French + } else if (_language == Common::FR_FRA && (fileIt->getName() != "french.dcp" && fileIt->getName() != "xlanguage_fr.dcp")) { + continue; + // German + } else if (_language == Common::DE_DEU && (fileIt->getName() != "german.dcp" && fileIt->getName() != "xlanguage_de.dcp")) { continue; - } else if (_language == Common::CZ_CZE && fileIt->getName() != "czech.dcp") { + // Italian + } else if (_language == Common::IT_ITA && (fileIt->getName() != "italian.dcp" && fileIt->getName() != "xlanguage_it.dcp")) { continue; - } else if (_language == Common::IT_ITA && fileIt->getName() != "italian.dcp") { + // Polish + } else if (_language == Common::PL_POL && (fileIt->getName() != "polish.dcp" && fileIt->getName() != "xlanguage_po.dcp")) { continue; - } else if (_language == Common::PL_POL && fileIt->getName() != "polish.dcp") { + // Portuguese + } else if (_language == Common::PT_BRA && (fileIt->getName() != "portuguese.dcp" && fileIt->getName() != "xlanguage_pt.dcp")) { continue; - } else if (_language == Common::RU_RUS && fileIt->getName() != "russian.dcp") { + // Russian + } else if (_language == Common::RU_RUS && (fileIt->getName() != "russian.dcp" && fileIt->getName() != "xlanguage_ru.dcp")) { continue; } } diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp index 55481c7c03..d6f09141c9 100644 --- a/engines/wintermute/base/font/base_font_truetype.cpp +++ b/engines/wintermute/base/font/base_font_truetype.cpp @@ -568,13 +568,22 @@ bool BaseFontTT::initFont() { return STATUS_FAILED; } #ifdef USE_FREETYPE2 + Common::String fallbackFilename; + // Handle Bold atleast for the fallback-case. + // TODO: Handle italic. (Needs a test-case) + if (_isBold) { + fallbackFilename = "FreeSansBold.ttf"; + } else { + fallbackFilename = "FreeSans.ttf"; + } + Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(_fontFile); if (!file) { if (Common::String(_fontFile) != "arial.ttf") { warning("%s has no replacement font yet, using FreeSans for now (if available)", _fontFile); } // Fallback1: Try to find FreeSans.ttf - file = SearchMan.createReadStreamForMember("FreeSans.ttf"); + file = SearchMan.createReadStreamForMember(fallbackFilename); } if (file) { @@ -601,9 +610,9 @@ bool BaseFontTT::initFont() { } if (themeFile) { Common::Archive *themeArchive = Common::makeZipArchive(themeFile); - if (themeArchive->hasFile("FreeSans.ttf")) { + if (themeArchive->hasFile(fallbackFilename)) { file = nullptr; - file = themeArchive->createReadStreamForMember("FreeSans.ttf"); + file = themeArchive->createReadStreamForMember(fallbackFilename); _deletableFont = Graphics::loadTTFFont(*file, 96, _fontHeight); // Use the same dpi as WME (96 vs 72). _font = _deletableFont; } @@ -618,7 +627,7 @@ bool BaseFontTT::initFont() { // Fallback3: Try to ask FontMan for the FreeSans.ttf ScummModern.zip uses: if (!_font) { // Really not desireable, as we will get a font with dpi-72 then - Common::String fontName = Common::String::format("%s-%s@%d", "FreeSans.ttf", "ASCII", _fontHeight); + Common::String fontName = Common::String::format("%s-%s@%d", fallbackFilename.c_str(), "ASCII", _fontHeight); warning("Looking for %s", fontName.c_str()); _font = FontMan.getFontByName(fontName); } diff --git a/engines/wintermute/base/font/base_font_truetype.h b/engines/wintermute/base/font/base_font_truetype.h index 2d7ebba691..7a96cdf1b7 100644 --- a/engines/wintermute/base/font/base_font_truetype.h +++ b/engines/wintermute/base/font/base_font_truetype.h @@ -135,7 +135,7 @@ private: size_t _maxCharWidth; size_t _maxCharHeight; -public: +private: bool _isBold; bool _isItalic; bool _isUnderline; diff --git a/engines/wintermute/detection.cpp b/engines/wintermute/detection.cpp index ac21d78ef5..f4bd437803 100644 --- a/engines/wintermute/detection.cpp +++ b/engines/wintermute/detection.cpp @@ -68,6 +68,7 @@ static char s_fallbackGameIdBuf[256]; static const char *directoryGlobs[] = { "language", // To detect the various languages + "languages", // To detect the various languages 0 }; diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h index a47f921571..46e05f2768 100644 --- a/engines/wintermute/detection_tables.h +++ b/engines/wintermute/detection_tables.h @@ -209,6 +209,22 @@ static const ADGameDescription gameDescriptions[] = { ADGF_TESTING, GUIO0() }, + // Dead City (Czech) + { + "deadcity", + "", + { + // The Czech data are in data.dcp, so in this case we'll have to + // just detect the english version twice, to give the user a choice. + {"english.dcp", 0, "c591046d6de7e381d76f70e0787b2b1f", 415935}, + {"data.dcp", 0, "7ebfd50d1a22370ed7b079bcaa631d62", 9070205}, + AD_LISTEND + }, + Common::CZ_CZE, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, // Dead City (English) { "deadcity", |