FULLPIPE: Implement MessageQueue::chain()

This commit is contained in:
Eugene Sandulenko 2013-08-10 23:41:38 +03:00
parent d866e2aabf
commit 1ca1a5dfa0
5 changed files with 248 additions and 74 deletions

View File

@ -253,6 +253,9 @@ void FullpipeEngine::updateEvents() {
ex->_excFlags |= 3; ex->_excFlags |= 3;
ex->handle(); ex->handle();
} }
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
break; break;
case Common::EVENT_QUIT: case Common::EVENT_QUIT:
_gameContinue = false; _gameContinue = false;
@ -329,7 +332,7 @@ void FullpipeEngine::updateScreen() {
} }
} }
} else if (_currentScene) { } else if (_currentScene) {
_currentScene->update(42); // HACK. FIXME //_currentScene->update(42); // HACK. FIXME
_currentScene->draw(); _currentScene->draw();
if (_inventoryScene) if (_inventoryScene)

View File

@ -25,6 +25,7 @@
#include "fullpipe/objects.h" #include "fullpipe/objects.h"
#include "fullpipe/messages.h" #include "fullpipe/messages.h"
#include "fullpipe/modal.h" #include "fullpipe/modal.h"
#include "fullpipe/statics.h"
namespace Fullpipe { namespace Fullpipe {
@ -193,8 +194,8 @@ MessageQueue::MessageQueue(MessageQueue *src, int parId, int field_38) {
_counter = 0; _counter = 0;
_field_38 = (field_38 == 0); _field_38 = (field_38 == 0);
for (uint i = 0; i < src->_exCommands.size(); i++) { for (Common::List<ExCommand *>::iterator it = src->_exCommands.begin(); it != src->_exCommands.end(); ++it) {
ExCommand *ex = new ExCommand((ExCommand *)src->_exCommands[i]); ExCommand *ex = new ExCommand(*it);
ex->_excFlags |= 2; ex->_excFlags |= 2;
_exCommands.push_back(ex); _exCommands.push_back(ex);
@ -215,6 +216,28 @@ MessageQueue::MessageQueue(MessageQueue *src, int parId, int field_38) {
_isFinished = 0; _isFinished = 0;
} }
MessageQueue::~MessageQueue() {
for (Common::List<ExCommand *>::iterator it = _exCommands.begin(); it != _exCommands.end(); ++it) {
ExCommand *ex = (ExCommand *)*it;
if (ex && ex->_excFlags & 2)
delete ex;
}
_exCommands.clear();
if (_field_14)
delete _field_14;
if (_flags & 2) {
g_fullpipe->_globalMessageQueueList->removeQueueById(_id);
}
finish();
free(_queueName);
}
bool MessageQueue::load(MfcArchive &file) { bool MessageQueue::load(MfcArchive &file) {
debug(5, "MessageQueue::load()"); debug(5, "MessageQueue::load()");
@ -227,7 +250,7 @@ bool MessageQueue::load(MfcArchive &file) {
_queueName = file.readPascalString(); _queueName = file.readPascalString();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
CObject *tmp = file.readClass(); ExCommand *tmp = (ExCommand *)file.readClass();
_exCommands.push_back(tmp); _exCommands.push_back(tmp);
} }
@ -241,9 +264,23 @@ bool MessageQueue::load(MfcArchive &file) {
} }
bool MessageQueue::chain(StaticANIObject *ani) { bool MessageQueue::chain(StaticANIObject *ani) {
warning("STUB: MessageQueue::chain()"); if (ani)
ani->isIdle();
return true; if (checkGlobalExCommandList1() && checkGlobalExCommandList2()) {
if (!(getFlags() & 2)) {
g_fullpipe->_globalMessageQueueList->addMessageQueue(this);
_flags |= 2;
}
if (ani) {
ani->queueMessageQueue(this);
return true;
} else {
sendNextCommand();
return true;
}
}
return false;
} }
void MessageQueue::update() { void MessageQueue::update() {
@ -262,15 +299,29 @@ void MessageQueue::messageQueueCallback1(int par) {
warning("STUB: MessageQueue::messageQueueCallback1()"); warning("STUB: MessageQueue::messageQueueCallback1()");
} }
ExCommand *MessageQueue::getExCommandByIndex(uint idx) {
if (idx > _exCommands.size())
return 0;
Common::List<ExCommand *>::iterator it = _exCommands.begin();
while (idx) {
++it;
idx--;
}
return *it;
}
void MessageQueue::sendNextCommand() { void MessageQueue::sendNextCommand() {
if (_exCommands.size()) { if (_exCommands.size()) {
if (!(_flags & 4) && (_flags & 1)) { if (!(_flags & 4) && (_flags & 1)) {
messageQueueCallback1(16); messageQueueCallback1(16);
} }
ExCommand *ex = (ExCommand *)_exCommands.front(); ExCommand *ex = _exCommands.front();
_exCommands.remove_at(0);
_exCommands.pop_front();
ex->handleMessage();
_counter++; _counter++;
ex->_parId = _id; ex->_parId = _id;
ex->_excFlags |= (ex->_field_24 == 0 ? 1 : 0) | (ex->_field_3C != 0 ? 2 : 0); ex->_excFlags |= (ex->_field_24 == 0 ? 1 : 0) | (ex->_field_3C != 0 ? 2 : 0);
@ -283,6 +334,76 @@ void MessageQueue::sendNextCommand() {
} }
} }
bool MessageQueue::checkGlobalExCommandList1() {
ExCommand *ex, *ex1;
for (uint i = 0; i < getCount(); i++) {
ex = getExCommandByIndex(i);
if (ex->_messageKind != 1 && ex->_messageKind != 20 && ex->_messageKind != 5 && ex->_messageKind != 27)
continue;
for (Common::List<ExCommand *>::iterator it = g_fullpipe->_exCommandList.begin(); it != g_fullpipe->_exCommandList.end(); it++) {
ex1 = *it;
if (ex1->_messageKind != 1 && ex1->_messageKind != 20 && ex1->_messageKind != 5 && ex1->_messageKind != 27)
continue;
if (ex1->_keyCode != ex->_keyCode && ex1->_keyCode != -1 && ex->_keyCode != -1)
continue;
MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(ex1->_parId);
if (mq) {
if (mq->getFlags() & 1)
return false;
}
}
}
return true;
}
bool MessageQueue::checkGlobalExCommandList2() {
ExCommand *ex, *ex1;
for (uint i = 0; i < getCount(); i++) {
ex = getExCommandByIndex(i);
if (ex->_messageKind != 1 && ex->_messageKind != 20 && ex->_messageKind != 5 && ex->_messageKind != 27)
continue;
for (Common::List<ExCommand *>::iterator it = g_fullpipe->_exCommandList.begin(); it != g_fullpipe->_exCommandList.end();) {
ex1 = *it;
if (ex1->_messageKind != 1 && ex1->_messageKind != 20 && ex1->_messageKind != 5 && ex1->_messageKind != 27) {
it++;
continue;
}
if (ex1->_keyCode != ex->_keyCode && ex1->_keyCode != -1 && ex->_keyCode != -1) {
it++;
continue;
}
MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(ex1->_parId);
if (mq) {
if (mq->getFlags() & 1)
return false;
delete mq;
}
it = g_fullpipe->_exCommandList.erase(it);
if (ex1->_excFlags & 2) {
delete ex1;
}
}
}
return true;
}
void MessageQueue::finish() { void MessageQueue::finish() {
warning("STUB: MessageQueue::finish()"); warning("STUB: MessageQueue::finish()");
} }
@ -299,7 +420,18 @@ MessageQueue *GlobalMessageQueueList::getMessageQueueById(int id) {
void GlobalMessageQueueList::deleteQueueById(int id) { void GlobalMessageQueueList::deleteQueueById(int id) {
for (uint i = 0; i < size(); i++) for (uint i = 0; i < size(); i++)
if (((MessageQueue *)((*this).operator[](i)))->_id == id) { if (((MessageQueue *)((*this).operator[](i)))->_id == id) {
delete (MessageQueue *)remove_at(i); remove_at(i);
disableQueueById(id);
return;
}
}
void GlobalMessageQueueList::removeQueueById(int id) {
for (uint i = 0; i < size(); i++)
if (((MessageQueue *)((*this).operator[](i)))->_id == id) {
((MessageQueue *)((*this).operator[](i)))->_flags &= 0xFD; // It is quite pointless
remove_at(i);
disableQueueById(id); disableQueueById(id);
return; return;
@ -503,8 +635,8 @@ void processMessages() {
while (g_fullpipe->_exCommandList.size()) { while (g_fullpipe->_exCommandList.size()) {
ExCommand *ex = g_fullpipe->_exCommandList.front(); ExCommand *ex = g_fullpipe->_exCommandList.front();
ex->handleMessage();
g_fullpipe->_exCommandList.pop_front(); g_fullpipe->_exCommandList.pop_front();
ex->handleMessage();
} }
g_fullpipe->_isProcessingMessages = false; g_fullpipe->_isProcessingMessages = false;
} }

View File

@ -50,6 +50,8 @@ class Message : public CObject {
public: public:
Message(); Message();
Message(Message *src); Message(Message *src);
virtual ~Message() {}
Message(int16 parentId, int messageKind, int x, int y, int a6, int a7, int sceneClickX, int sceneClickY, int a10); Message(int16 parentId, int messageKind, int x, int y, int a6, int a7, int sceneClickX, int sceneClickY, int a10);
}; };
@ -84,18 +86,14 @@ class CObjstateCommand : public CObject {
}; };
class MessageQueue : public CObject { class MessageQueue : public CObject {
friend class GlobalMessageQueueList; public:
friend class CGameLoader;
friend class Scene;
protected:
int _id; int _id;
int _flags; int _flags;
char *_queueName; char *_queueName;
int16 _dataId; int16 _dataId;
int16 _field_12; int16 _field_12;
int _field_14; CObject *_field_14;
CPtrList _exCommands; Common::List<ExCommand *> _exCommands;
int _counter; int _counter;
int _field_38; int _field_38;
int _isFinished; int _isFinished;
@ -105,23 +103,33 @@ class MessageQueue : public CObject {
public: public:
MessageQueue(); MessageQueue();
MessageQueue(MessageQueue *src, int parId, int field_38); MessageQueue(MessageQueue *src, int parId, int field_38);
virtual ~MessageQueue();
virtual bool load(MfcArchive &file); virtual bool load(MfcArchive &file);
int getFlags() { return _flags; } int getFlags() { return _flags; }
void setFlags(int flags) { _flags = flags; } void setFlags(int flags) { _flags = flags; }
uint getCount() { return _exCommands.size(); }
ExCommand *getExCommandByIndex(uint idx);
bool chain(StaticANIObject *ani); bool chain(StaticANIObject *ani);
void update(); void update();
void sendNextCommand(); void sendNextCommand();
void finish(); void finish();
void messageQueueCallback1(int par); void messageQueueCallback1(int par);
bool checkGlobalExCommandList1();
bool checkGlobalExCommandList2();
}; };
class GlobalMessageQueueList : public CPtrList { class GlobalMessageQueueList : public CPtrList {
public: public:
MessageQueue *getMessageQueueById(int id); MessageQueue *getMessageQueueById(int id);
void deleteQueueById(int id); void deleteQueueById(int id);
void removeQueueById(int id);
void disableQueueById(int id); void disableQueueById(int id);
void addMessageQueue(MessageQueue *msg); void addMessageQueue(MessageQueue *msg);

View File

@ -214,6 +214,26 @@ void StaticANIObject::deleteFromGlobalMessageQueue() {
} }
} }
void StaticANIObject::queueMessageQueue(MessageQueue *mq) {
if (isIdle() && !(_flags & 0x80)) {
deleteFromGlobalMessageQueue();
_messageQueueId = 0;
_messageNum = 0;
if (_flags & 2) {
_flags ^= 2;
}
if (mq) {
_animExFlag = 0;
if (_movement)
_messageQueueId = mq->_id;
else
mq->sendNextCommand();
} else {
_messageQueueId = 0;
}
}
}
bool StaticANIObject::isIdle() { bool StaticANIObject::isIdle() {
if (_messageQueueId) { if (_messageQueueId) {
MessageQueue *m = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId); MessageQueue *m = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId);
@ -427,7 +447,7 @@ Common::Point *StaticANIObject::getCurrDimensions(Common::Point &p) {
void StaticANIObject::update(int counterdiff) { void StaticANIObject::update(int counterdiff) {
int mqid; int mqid;
debug(0, "StaticANIObject::update()"); debug(0, "StaticANIObject::update() (%x)", _flags);
if (_flags & 2) { if (_flags & 2) {
_messageNum--; _messageNum--;
@ -443,76 +463,86 @@ void StaticANIObject::update(int counterdiff) {
} }
Common::Point point; Common::Point point;
ExCommand *ex, *newex, *newex1, *newex2; ExCommand *ex, *newex;
if (_movement) { if (_movement) {
_movement->_counter += counterdiff; _movement->_counter += counterdiff;
if (_movement->_counter >= _movement->_counterMax) {
_movement->_counter = 0;
if (_flags & 1) { if (_movement->_counter < _movement->_counterMax)
if (_counter) { return;
_counter--;
} else { _movement->_counter = 0;
DynamicPhase *dyn = _movement->_currDynamicPhase;
if (dyn->_initialCountdown != dyn->_countdown) if (_flags & 1) {
goto LABEL_40; if (_counter) {
ex = dyn->getExCommand(); _counter--;
if (!ex || ex->_messageKind == 35)
goto LABEL_40; return;
}
DynamicPhase *dyn = _movement->_currDynamicPhase;
if (dyn->_initialCountdown == dyn->_countdown) {
ex = dyn->getExCommand();
if (ex && ex->_messageKind == 35) {
newex = new ExCommand(ex); newex = new ExCommand(ex);
newex->_excFlags |= 2; newex->_excFlags |= 2;
if (newex->_messageKind == 17) { if (newex->_messageKind == 17) {
newex->_parentId = _id; newex->_parentId = _id;
newex->_keyCode = _field_4; newex->_keyCode = _field_4;
} }
ex->sendMessage(); newex->sendMessage();
if (_movement) {
LABEL_40: if (!_movement)
if (dyn->_initialCountdown != dyn->_countdown return;
|| dyn->_field_68 == 0 }
|| (newex1 = new ExCommand(_id, 17, dyn->_field_68, 0, 0, 0, 1, 0, 0, 0)),
newex1->_excFlags = 2, if (dyn->_initialCountdown == dyn->_countdown && dyn->_field_68 == 0) {
newex1->_keyCode = _field_4, newex = new ExCommand(_id, 17, dyn->_field_68, 0, 0, 0, 1, 0, 0, 0);
newex1->sendMessage(), newex->_excFlags = 2;
(_movement != 0)) { newex->_keyCode = _field_4;
if (_movement->gotoNextFrame(_callback1, _callback2)) { newex->sendMessage();
setOXY(_movement->_ox, _movement->_oy);
_counter = _initialCounter; if (!_movement)
if (dyn->_initialCountdown == dyn->_countdown) { return;
ex = dyn->getExCommand(); }
if (ex) {
if (ex->_messageKind == 35) { if (!_movement->gotoNextFrame(_callback1, _callback2)) {
newex2 = new ExCommand(ex); stopAnim_maybe();
ex->_excFlags |= 2; } else {
ex->sendMessage(); setOXY(_movement->_ox, _movement->_oy);
} _counter = _initialCounter;
}
} if (dyn->_initialCountdown == dyn->_countdown) {
} else { ex = dyn->getExCommand();
stopAnim_maybe(); if (ex) {
} if (ex->_messageKind == 35) {
if (_movement) { newex = new ExCommand(ex);
_stepArray.getCurrPoint(&point); newex->_excFlags |= 2;
setOXY(point.x + _ox, point.y + _oy); newex->sendMessage();
_stepArray.gotoNextPoint();
if (_someDynamicPhaseIndex == _movement->_currDynamicPhaseIndex)
adjustSomeXY();
} }
} }
} }
} if (!_movement)
} else if (_flags & 0x20) { return;
_flags ^= 0x20;
_flags |= 1;
_movement->gotoFirstFrame();
_movement->getCurrDynamicPhaseXY(point);
Common::Point pointS; _stepArray.getCurrPoint(&point);
_statics->getSomeXY(pointS); setOXY(point.x + _ox, point.y + _oy);
setOXY(_ox + point.x + _movement->_mx - pointS.x, _stepArray.gotoNextPoint();
_oy + point.y + _movement->_my - pointS.y); if (_someDynamicPhaseIndex == _movement->_currDynamicPhaseIndex)
adjustSomeXY();
}
} }
} else if (_flags & 0x20) {
_flags ^= 0x20;
_flags |= 1;
_movement->gotoFirstFrame();
_movement->getCurrDynamicPhaseXY(point);
Common::Point pointS;
_statics->getSomeXY(pointS);
setOXY(_ox + point.x + _movement->_mx - pointS.x,
_oy + point.y + _movement->_my - pointS.y);
} }
} else { } else {
if (_statics) { if (_statics) {

View File

@ -200,6 +200,7 @@ class StaticANIObject : public GameObject {
bool isIdle(); bool isIdle();
void deleteFromGlobalMessageQueue(); void deleteFromGlobalMessageQueue();
void queueMessageQueue(MessageQueue *msg);
void initMovements(); void initMovements();
void loadMovementsPixelData(); void loadMovementsPixelData();