From 9f52e9f65068e136680e5fbd4a55eb4ff69720c2 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Thu, 15 Aug 2013 00:46:19 +0300 Subject: FULLPIPE: More work on behaviors. Animations start to (buggy) work. --- engines/fullpipe/behavior.cpp | 92 ++++++++++++++++++++++++++++++++++++------- engines/fullpipe/behavior.h | 9 +++-- engines/fullpipe/gfx.cpp | 1 + engines/fullpipe/messages.cpp | 18 +++++++-- engines/fullpipe/messages.h | 2 + engines/fullpipe/objects.h | 2 +- engines/fullpipe/scenes.cpp | 2 +- engines/fullpipe/statics.cpp | 43 +++++++++++++++++++- 8 files changed, 144 insertions(+), 25 deletions(-) (limited to 'engines') diff --git a/engines/fullpipe/behavior.cpp b/engines/fullpipe/behavior.cpp index 5f26efabe4..2551133675 100644 --- a/engines/fullpipe/behavior.cpp +++ b/engines/fullpipe/behavior.cpp @@ -61,7 +61,7 @@ void BehaviorManager::initBehavior(Scene *sc, CGameVar *var) { for (CGameVar *subvar = behvar->_subVars; subvar; subvar = subvar->_nextVarObj) { if (!strcmp(subvar->_varName, "AMBIENT")) { behinfo = new BehaviorInfo; - behinfo->initAmbientBehavior(subvar); + behinfo->initAmbientBehavior(subvar, sc); _behaviors.push_back(behinfo); } else { @@ -83,6 +83,7 @@ void BehaviorManager::updateBehaviors() { if (!_isActive) return; + debug(0, "BehaviorManager::updateBehaviors()"); for (uint i = 0; i < _behaviors.size(); i++) { BehaviorInfo *beh = _behaviors[i]; @@ -121,17 +122,18 @@ void BehaviorManager::updateBehaviors() { } void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorEntry *entry) { + debug(0, "BehaviorManager::updateBehavior() %d", entry->_itemsCount); for (int i = 0; i < entry->_itemsCount; i++) { BehaviorEntryInfo *bhi = entry->_items[i]; if (!(bhi->_flags & 1)) { if (bhi->_flags & 2) { - MessageQueue *mq = new MessageQueue(entry->_items[i]->_messageQueue, 0, 1); + MessageQueue *mq = new MessageQueue(bhi->_messageQueue, 0, 1); mq->sendNextCommand(); - entry->_items[i]->_flags &= 0xFFFFFFFD; + bhi->_flags &= 0xFFFFFFFD; } else if (behaviorInfo->_counter >= bhi->_delay && bhi->_percent && g_fullpipe->_rnd->getRandomNumber(32767) <= entry->_items[i]->_percent) { - MessageQueue *mq = new MessageQueue(entry->_items[i]->_messageQueue, 0, 1); + MessageQueue *mq = new MessageQueue(bhi->_messageQueue, 0, 1); mq->sendNextCommand(); @@ -141,8 +143,40 @@ void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorEntry * } } -void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, unsigned int delay, BehaviorEntry *behaviorEntry) { - warning("STUB: BehaviorManager::updateStaticAniBehavior()"); +void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorEntry *bhe) { + debug(0, "BehaviorManager::updateStaticAniBehavior(%s)", transCyrillic((byte *)ani->_objectName)); + + MessageQueue *mq = 0; + + if (bhe->_flags & 1) { + uint rnd = g_fullpipe->_rnd->getRandomNumber(32767); + uint runPercent = 0; + for (int i = 0; i < bhe->_itemsCount; i++) { + if (!(bhe->_items[i]->_flags & 1) && bhe->_items[i]->_percent) { + if (rnd >= runPercent && rnd <= runPercent + bhe->_items[i]->_percent || i == bhe->_itemsCount - 1) { + mq = new MessageQueue(bhe->_items[i]->_messageQueue, 0, 1); + break; + } + runPercent += bhe->_items[i]->_percent; + } + } + } else { + for (int i = 0; i < bhe->_itemsCount; i++) { + if (!(bhe->_items[i]->_flags & 1) && delay >= bhe->_items[i]->_delay) { + if (bhe->_items[i]->_percent) { + if (g_fullpipe->_rnd->getRandomNumber(32767) <= bhe->_items[i]->_percent) { + mq = new MessageQueue(bhe->_items[i]->_messageQueue, 0, 1); + break; + } + } + } + } + } + + if (mq) { + mq->replaceKeyCode(-1, ani->_okeyCode); + mq->chain(ani); + } } void BehaviorInfo::clear() { @@ -157,8 +191,28 @@ void BehaviorInfo::clear() { _bheItems.clear(); } -void BehaviorInfo::initAmbientBehavior(CGameVar *var) { - warning("STUB: BehaviorInfo::initAmbientBehavior(%s)", transCyrillic((byte *)var->_varName)); +void BehaviorInfo::initAmbientBehavior(CGameVar *var, Scene *sc) { + debug(0, "BehaviorInfo::initAmbientBehavior(%s)", transCyrillic((byte *)var->_varName)); + + clear(); + _itemsCount = 1; + _counterMax = -1; + + BehaviorEntry *bi = new BehaviorEntry(); + + _bheItems.push_back(bi); + + bi->_itemsCount = var->getSubVarsCount(); + + bi->_items = (BehaviorEntryInfo**)calloc(bi->_itemsCount, sizeof(BehaviorEntryInfo *)); + + for (int i = 0; i < bi->_itemsCount; i++) { + int delay; + bi->_items[i] = new BehaviorEntryInfo(var->getSubVarByIndex(i), sc, &delay); + + if (bi->_items[i]->_delay <_counterMax) + _counterMax = bi->_items[i]->_delay; + } } void BehaviorInfo::initObjectBehavior(CGameVar *var, Scene *sc, StaticANIObject *ani) { @@ -189,16 +243,23 @@ void BehaviorInfo::initObjectBehavior(CGameVar *var, Scene *sc, StaticANIObject _bheItems.push_back(new BehaviorEntry(var->getSubVarByIndex(i), sc, ani, &maxDelay)); - if (maxDelay < _counterMax ) + if (maxDelay < _counterMax) _counterMax = maxDelay; } } +BehaviorEntry::BehaviorEntry() { + _staticsId = 0; + _itemsCount = 0; + _flags = 0; + _items = 0; +} + BehaviorEntry::BehaviorEntry(CGameVar *var, Scene *sc, StaticANIObject *ani, int *minDelay) { _staticsId = 0; _itemsCount = 0; - *minDelay = -1; + *minDelay = 100000000; int totalPercent = 0; _flags = 0; @@ -214,9 +275,10 @@ BehaviorEntry::BehaviorEntry(CGameVar *var, Scene *sc, StaticANIObject *ani, int for (int i = 0; i < _itemsCount; i++) { CGameVar *subvar = var->getSubVarByIndex(i); + int delay; - _items[i] = new BehaviorEntryInfo(subvar, sc); - totalPercent += _items[i]->_percent; + _items[i] = new BehaviorEntryInfo(subvar, sc, &delay); + totalPercent += delay; if (_items[i]->_delay < *minDelay) *minDelay = _items[i]->_delay; @@ -227,7 +289,7 @@ BehaviorEntry::BehaviorEntry(CGameVar *var, Scene *sc, StaticANIObject *ani, int } } -BehaviorEntryInfo::BehaviorEntryInfo(CGameVar *subvar, Scene *sc) { +BehaviorEntryInfo::BehaviorEntryInfo(CGameVar *subvar, Scene *sc, int *delay) { _messageQueue = 0; _delay = 0; _percent = 0; @@ -241,7 +303,9 @@ BehaviorEntryInfo::BehaviorEntryInfo(CGameVar *subvar, Scene *sc) { vart = subvar->getSubVarByName("dwPercent"); if (vart) _percent = 0x7FFF * vart->_value.intValue / 1000; - + + *delay = vart->_value.intValue; + vart = subvar->getSubVarByName("dwFlags"); if (vart && vart->_varType == 2 && strstr(vart->_value.stringValue, "QDESC_AUTOSTART")) _flags |= 2; diff --git a/engines/fullpipe/behavior.h b/engines/fullpipe/behavior.h index 210426ebc6..d9375d4d01 100644 --- a/engines/fullpipe/behavior.h +++ b/engines/fullpipe/behavior.h @@ -28,10 +28,10 @@ namespace Fullpipe { struct BehaviorEntryInfo { MessageQueue *_messageQueue; int _delay; - uint _percent; + uint32 _percent; int _flags; - BehaviorEntryInfo(CGameVar *subvar, Scene *sc); + BehaviorEntryInfo(CGameVar *subvar, Scene *sc, int *delay); }; struct BehaviorEntry { @@ -40,6 +40,7 @@ struct BehaviorEntry { int _flags; BehaviorEntryInfo **_items; + BehaviorEntry(); BehaviorEntry(CGameVar *var, Scene *sc, StaticANIObject *ani, int *minDelay); }; @@ -56,7 +57,7 @@ struct BehaviorInfo { BehaviorInfo() { clear(); } void clear(); - void initAmbientBehavior(CGameVar *var); + void initAmbientBehavior(CGameVar *var, Scene *sc); void initObjectBehavior(CGameVar *var, Scene *sc, StaticANIObject *ani); }; @@ -75,7 +76,7 @@ class BehaviorManager : public CObject { void updateBehaviors(); void updateBehavior(BehaviorInfo *behaviorInfo, BehaviorEntry *entry); - void updateStaticAniBehavior(StaticANIObject *ani, unsigned int delay, BehaviorEntry *behaviorEntry); + void updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorEntry *beh); }; } // End of namespace Fullpipe diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp index 6367407838..df48a1cb7d 100644 --- a/engines/fullpipe/gfx.cpp +++ b/engines/fullpipe/gfx.cpp @@ -199,6 +199,7 @@ GameObject::GameObject() { _oy = 0; _priority = 0; _field_20 = 0; + _field_6 = 0; _field_8 = 0; _objectName = 0; } diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp index 953b87c6af..22343af8f8 100644 --- a/engines/fullpipe/messages.cpp +++ b/engines/fullpipe/messages.cpp @@ -414,10 +414,20 @@ void MessageQueue::finish() { warning("STUB: MessageQueue::finish()"); } +void MessageQueue::replaceKeyCode(int key1, int key2) { + for (uint i = 0; i < getCount(); i++) { + ExCommand *ex = getExCommandByIndex(i); + int k = ex->_messageKind; + if ((k == 1 || k == 20 || k == 5 || k == 6 || k == 2 || k == 18 || k == 19 || k == 22 || k == 55) + && ex->_keyCode == key1) + ex->_keyCode = key2; + } +} + MessageQueue *GlobalMessageQueueList::getMessageQueueById(int id) { for (CPtrList::iterator s = begin(); s != end(); ++s) { - if (((MessageQueue *)s)->_id == id) - return (MessageQueue *)s; + if (((MessageQueue *)*s)->_id == id) + return (MessageQueue *)*s; } return 0; @@ -446,8 +456,8 @@ void GlobalMessageQueueList::removeQueueById(int id) { void GlobalMessageQueueList::disableQueueById(int id) { for (CPtrList::iterator s = begin(); s != end(); ++s) { - if (((MessageQueue *)s)->_parId == id) - ((MessageQueue *)s)->_parId = 0; + if (((MessageQueue *)*s)->_parId == id) + ((MessageQueue *)*s)->_parId = 0; } } diff --git a/engines/fullpipe/messages.h b/engines/fullpipe/messages.h index 03d30f2b7d..d202235f93 100644 --- a/engines/fullpipe/messages.h +++ b/engines/fullpipe/messages.h @@ -121,6 +121,8 @@ class MessageQueue : public CObject { ExCommand *getExCommandByIndex(uint idx); + void replaceKeyCode(int key1, int key2); + bool chain(StaticANIObject *ani); void update(); void sendNextCommand(); diff --git a/engines/fullpipe/objects.h b/engines/fullpipe/objects.h index 590e8ebcbc..dd1545ffb0 100644 --- a/engines/fullpipe/objects.h +++ b/engines/fullpipe/objects.h @@ -91,7 +91,7 @@ class Sc2Array : public Common::Array { union VarValue { float floatValue; - int intValue; + int32 intValue; char *stringValue; }; diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp index b6c05afb9d..843b098aab 100644 --- a/engines/fullpipe/scenes.cpp +++ b/engines/fullpipe/scenes.cpp @@ -141,7 +141,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) { for (CPtrList::iterator s = scene->_staticANIObjectList1.begin(); s != scene->_staticANIObjectList1.end(); ++s) { StaticANIObject *o = (StaticANIObject *)*s; - o->setFlags(o->_field_6 & 0xFE7F); + o->setFlags(o->_flags & 0xFE7F); } PictureObject *p = accessScene(SC_INV)->getPictureObjectById(PIC_INV_MENU, 0); diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp index de5d68983f..168ec90e27 100644 --- a/engines/fullpipe/statics.cpp +++ b/engines/fullpipe/statics.cpp @@ -1225,7 +1225,48 @@ bool Movement::gotoNextFrame(int callback1, int callback2) { } bool Movement::gotoPrevFrame() { - warning("STUB: Movement::gotoPrevFrame()"); + debug(8, "Movement::gotoPrevFrame()"); + + if (!_currDynamicPhaseIndex) { + gotoLastFrame(); + return false; + } + + Common::Point point; + + getCurrDynamicPhaseXY(point); + + _ox -= point.x; + _oy -= point.y; + + if (_currMovement) { + if (_currMovement->_framePosOffsets) { + _ox += _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x; + _ox += _currMovement->_framePosOffsets[_currDynamicPhaseIndex]->x; + _oy -= _currMovement->_framePosOffsets[_currDynamicPhaseIndex]->y; + } + + _currDynamicPhaseIndex--; + if (_currDynamicPhaseIndex < 0) + _currDynamicPhaseIndex = _currMovement->_dynamicPhases.size() - 1; + + _ox -= _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x; + } else { + if (_framePosOffsets) { + _ox -= _framePosOffsets[_currDynamicPhaseIndex]->x; + _oy -= _framePosOffsets[_currDynamicPhaseIndex]->y; + } + + _currDynamicPhaseIndex--; + if (_currDynamicPhaseIndex < 0) + _currDynamicPhaseIndex = _currMovement->_dynamicPhases.size() - 1; + } + + updateCurrDynamicPhase(); + getCurrDynamicPhaseXY(point); + + _ox += point.x; + _oy += point.y; return true; } -- cgit v1.2.3