aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/avalanche/avalot.cpp1
-rw-r--r--engines/avalanche/timer.cpp20
-rw-r--r--engines/avalanche/timer.h2
-rw-r--r--engines/engines.mk10
-rw-r--r--engines/fullpipe/messages.cpp13
-rw-r--r--engines/fullpipe/messages.h1
-rw-r--r--engines/fullpipe/motion.cpp171
-rw-r--r--engines/fullpipe/motion.h29
-rw-r--r--engines/sci/engine/script_patches.cpp96
-rw-r--r--engines/sci/engine/workarounds.cpp3
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.cpp94
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.h7
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.cpp25
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.h1
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.cpp2
-rw-r--r--engines/wintermute/base/base_file_manager.cpp43
-rw-r--r--engines/wintermute/base/font/base_font_truetype.cpp17
-rw-r--r--engines/wintermute/base/font/base_font_truetype.h2
-rw-r--r--engines/wintermute/detection.cpp1
-rw-r--r--engines/wintermute/detection_tables.h16
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",