diff options
author | Strangerke | 2013-09-11 21:33:10 +0200 |
---|---|---|
committer | Strangerke | 2013-09-11 21:33:10 +0200 |
commit | da1a427e794434a09cd39ab45e32ae7afca9a170 (patch) | |
tree | 85b4700515bc7853e4f90ddae22bc3b785c4ab3a /engines/fullpipe/statics.cpp | |
parent | 49dbac6a2a5cde294a4c4c9a47467e7b5d95e08b (diff) | |
parent | 5c6ee7573c0cf05bbbb154d4734e94e478f453e5 (diff) | |
download | scummvm-rg350-da1a427e794434a09cd39ab45e32ae7afca9a170.tar.gz scummvm-rg350-da1a427e794434a09cd39ab45e32ae7afca9a170.tar.bz2 scummvm-rg350-da1a427e794434a09cd39ab45e32ae7afca9a170.zip |
Merge branch 'master' of https://github.com/urukgit/scummvm into avalanche
Diffstat (limited to 'engines/fullpipe/statics.cpp')
-rw-r--r-- | engines/fullpipe/statics.cpp | 1720 |
1 files changed, 1720 insertions, 0 deletions
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp new file mode 100644 index 0000000000..1fd02f8eb6 --- /dev/null +++ b/engines/fullpipe/statics.cpp @@ -0,0 +1,1720 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "fullpipe/fullpipe.h" + +#include "fullpipe/objects.h" +#include "fullpipe/ngiarchive.h" +#include "fullpipe/statics.h" +#include "fullpipe/messages.h" +#include "fullpipe/interaction.h" + +#include "fullpipe/constants.h" +#include "fullpipe/objectnames.h" + +namespace Fullpipe { + +CStepArray::CStepArray() { + _points = 0; + _maxPointIndex = 0; + _currPointIndex = 0; + _pointsCount = 0; + _isEos = 0; +} + +CStepArray::~CStepArray() { + if (_pointsCount) { + for (int i = 0; i < _pointsCount; i++) + delete _points[i]; + + delete _points; + + _points = 0; + } +} + +void CStepArray::clear() { + _currPointIndex = 0; + _maxPointIndex = 0; + _isEos = 0; + + for (int i = 0; i < _pointsCount; i++) { + _points[i]->x = 0; + _points[i]->y = 0; + } +} + +Common::Point *CStepArray::getCurrPoint(Common::Point *point) { + if (_isEos || _points == 0) { + point->x = 0; + point->y = 0; + } else { + point = _points[_currPointIndex]; + } + return point; +} + +bool CStepArray::gotoNextPoint() { + if (_currPointIndex < _maxPointIndex) { + _currPointIndex++; + return true; + } else { + _isEos = 1; + return false; + } +} + +StaticANIObject::StaticANIObject() { + _shadowsOn = 1; + _field_30 = 0; + _field_34 = 1; + _initialCounter = 0; + _messageQueueId = 0; + _animExFlag = 0; + _counter = 0; + _movement = 0; + _statics = 0; + _flags = 0; + _callback1 = 0; + _callback2 = 0; + _sceneId = -1; + _someDynamicPhaseIndex = -1; + + _field_32 = 0; + _field_96 = 0; + _messageNum = 0; + _objtype = kObjTypeStaticANIObject; +} + +StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) { + _shadowsOn = src->_shadowsOn; + _field_30 = src->_field_30; + _field_34 = 1; + _initialCounter = 0; + + _field_32 = 0; + _field_96 = 0; + _messageNum = 0; + + _messageQueueId = 0; + _animExFlag = 0; + _counter = 0; + _someDynamicPhaseIndex = -1; + _sceneId = src->_sceneId; + _callback1 = src->_callback1; + _callback2 = src->_callback2; + _objtype = kObjTypeStaticANIObject; + + for (uint i = 0; i < src->_staticsList.size(); i++) + _staticsList.push_back(new Statics((Statics *)src->_staticsList[i], 0)); + + _movement = 0; + _statics = 0; + + for (uint i = 0; i < src->_movements.size(); i++) { + Movement *mov; + if (((Movement *)src->_movements[i])->_currMovement) { + mov = new Movement(getMovementById(src->getMovementIdById(((Movement *)src->_movements[i])->_id)), this); + mov->_id = ((Movement *)src->_movements[i])->_id; + } else { + mov = new Movement(((Movement *)src->_movements[i]), 0, -1, this); + } + + _movements.push_back(mov); + } +} + +bool StaticANIObject::load(MfcArchive &file) { + debug(5, "StaticANIObject::load()"); + + GameObject::load(file); + + int count = file.readUint16LE(); + + for (int i = 0; i < count; i++) { + Statics *st = new Statics(); + + st->load(file); + _staticsList.push_back(st); + } + + count = file.readUint16LE(); + debug(7, "Movements: %d", count); + + for (int i = 0; i < count; i++) { + int movNum = file.readUint16LE(); + + char *movname = genFileName(_id, movNum, "mov"); + + Common::SeekableReadStream *f = g_fullpipe->_currArchive->createReadStreamForMember(movname); + + Movement *mov = new Movement(); + + MfcArchive archive(f); + + mov->load(archive, this); + + _movements.push_back(mov); + + delete f; + free(movname); + } + + Common::Point pt; + if (count) { // We have movements + ((Movement *)_movements[0])->getCurrDynamicPhaseXY(pt); + } else { + pt.x = pt.y = 100; + } + + setOXY(pt.x, pt.y); + + return true; +} + +void StaticANIObject::setOXY(int x, int y) { + _ox = x; + _oy = y; + + if (_movement) + _movement->setOXY(x, y); +} + +void StaticANIObject::clearFlags() { + _flags = 0; + + deleteFromGlobalMessageQueue(); + _messageQueueId = 0; + _movement = 0; + _statics = 0; + _animExFlag = 0; + _counter = 0; + _messageNum = 0; + _stepArray.clear(); +} + +void StaticANIObject::setFlags40(bool state) { + if (state) { + _flags |= 0x40; + } else { + if (_flags & 0x40) + _flags ^= 0x40; + } +} + +void StaticANIObject::deleteFromGlobalMessageQueue() { + while (_messageQueueId) { + if (g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId)) { + if (!isIdle()) + return; + + g_fullpipe->_globalMessageQueueList->deleteQueueById(_messageQueueId); + } else { + _messageQueueId = 0; + } + } +} + +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; + } + } +} + +MessageQueue *StaticANIObject::getMessageQueue() { + if (this->_messageQueueId <= 0) + return 0; + + return g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId); +} + +bool StaticANIObject::trySetMessageQueue(int msgNum, int qId) { + if (_messageQueueId || !msgNum) { + updateGlobalMessageQueue(qId, _id); + return false; + } + + _flags |= 2; + + _messageNum = msgNum; + _messageQueueId = qId; + + return true; +} + +bool StaticANIObject::isIdle() { + if (_messageQueueId) { + MessageQueue *m = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId); + + if (m && m->getFlags() & 1) + return false; + } + + return true; +} + +Statics *StaticANIObject::getStaticsById(int itemId) { + for (uint i = 0; i < _staticsList.size(); i++) + if (((Statics *)_staticsList[i])->_staticsId == itemId) + return (Statics *)_staticsList[i]; + + return 0; +} + +Statics *StaticANIObject::getStaticsByName(char *name) { + for (uint i = 0; i < _staticsList.size(); i++) + if (!strcmp(((Statics *)_staticsList[i])->_staticsName, name)) + return (Statics *)_staticsList[i]; + + return 0; +} + +Movement *StaticANIObject::getMovementById(int itemId) { + for (uint i = 0; i < _movements.size(); i++) + if (((Movement *)_movements[i])->_id == itemId) + return (Movement *)_movements[i]; + + return 0; +} + +int StaticANIObject::getMovementIdById(int itemId) { + for (uint i = 0; i < _movements.size(); i++) { + Movement *mov = (Movement *)_movements[i]; + if (mov->_currMovement) { + if (mov->_id == itemId) + return mov->_id; + if (mov->_currMovement->_id == itemId) + return mov->_id; + } + } + + return 0; +} + +Movement *StaticANIObject::getMovementByName(char *name) { + for (uint i = 0; i < _movements.size(); i++) + if (!strcmp(((Movement *)_movements[i])->_objectName, name)) + return (Movement *)_movements[i]; + + return 0; +} + +bool StaticANIObject::getPixelAtPos(int x, int y, int *pixel) { + bool res = false; + Picture *pic; + + if (_movement) + pic = _movement->_currDynamicPhase; + else + pic = _statics; + + if (!pic) + return false; + + int ongoing; + int xani, yani; + int oxani, oyani; + Common::Point point; + + if (_movement) + ongoing = _movement->_currMovement != 0; + else + ongoing = _statics->_staticsId & 0x4000; + + if (_movement) { + _movement->getCurrDynamicPhaseXY(point); + xani = point.x; + yani = point.y; + oxani = _movement->_ox; + oyani = _movement->_oy; + } else { + _statics->getSomeXY(point); + xani = point.x; + yani = point.y; + oxani = _ox; + oyani = _oy; + } + + int xtarget = x - (oxani - xani); + int ytarget = y - (oyani - yani); + + if (ongoing && _movement) + xtarget = pic->getDimensions(&point)->x - xtarget; + + x = pic->_x; + y = pic->_y; + pic->_x = 0; + pic->_y = 0; + if (pic->isPixelHitAtPos(xtarget, ytarget)) { + *pixel = pic->getPixelAtPos(xtarget, ytarget); + + res = true; + } else { + res = false; + } + pic->_x = x; + pic->_y = y; + + return res; +} + +void Movement::draw(bool flipFlag, int angle) { + debug(3, "Movement::draw(%d, %d)", flipFlag, angle); + + Common::Point point; + + getCurrDynamicPhaseXY(point); + + int x = _ox - point.x; + int y = _oy - point.y; + + if (_currDynamicPhase->getPaletteData()) + g_fullpipe->_globalPalette = _currDynamicPhase->getPaletteData(); + + if (_currDynamicPhase->getAlpha() < 0xFF) { + warning("Movement::draw: alpha < 0xff: %d", _currDynamicPhase->getAlpha()); + //vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, _currDynamicPhase->getAlpha()); + } + + Bitmap *bmp; + if (_currMovement) { + bmp = _currDynamicPhase->getPixelData()->reverseImage(); + } else { + bmp = _currDynamicPhase->getPixelData(); + } + + if (flipFlag) { + bmp->flipVertical()->drawShaded(1, x, y + 30 + _currDynamicPhase->_rect->bottom, _currDynamicPhase->_paletteData); + } if (angle) { + bmp->drawRotated(x, y, angle, _currDynamicPhase->_paletteData); + } else { + bmp->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData); + } + + if (_currDynamicPhase->_rect->top) { + if (!_currDynamicPhase->_convertedBitmap) { + //v12 = Picture_getPixelData(v5); + //v13 = Bitmap_convertTo16Bit565(v12, (unsigned int *)&_currDynamicPhase->rect); + //_currDynamicPhase->convertedBitmap = v13; + } + + if (_currDynamicPhase->_convertedBitmap) { + if (_currMovement) { + //vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, LOBYTE(_currDynamicPhase->rect.top)); + _currDynamicPhase->_convertedBitmap->reverseImage()->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData); + //vrtSetAlphaBlendMode(g_vrtDrawHandle, 0, 255); + } else { + //vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, LOBYTE(_currDynamicPhase->rect.top)); + _currDynamicPhase->_convertedBitmap->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData); + //vrtSetAlphaBlendMode(g_vrtDrawHandle, 0, 255); + } + } + } +} + + +void StaticANIObject::loadMovementsPixelData() { + for (uint i = 0; i < _movements.size(); i++) + ((Movement *)_movements[i])->loadPixelData(); +} + +Statics *StaticANIObject::addReverseStatics(Statics *st) { + Statics *res = getStaticsById(st->_staticsId ^ 0x4000); + + if (!res) { + res = new Statics(st, true); + + _staticsList.push_back(res); + } + + return res; +} + +void StaticANIObject::draw() { + if ((_flags & 4) == 0) + return; + + Common::Point point; + Common::Rect rect; + + debug(0, "StaticANIObject::draw() (%s) [%d] [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy); + + if (_shadowsOn && g_fullpipe->_currentScene && g_fullpipe->_currentScene->_shadows + && (getCurrDimensions(point)->x != 1 || getCurrDimensions(point)->y != 1)) { + + DynamicPhase *dyn; + + if (!_movement || _flags & 0x20) + dyn = _statics; + else + dyn = _movement->_currDynamicPhase; + + if (!dyn) { + warning("HACK: StaticANIObject::draw(): dyn is missing"); + return; + } + + if (dyn->getDynFlags() & 4) { + rect = *dyn->_rect; + + DynamicPhase *shd = g_fullpipe->_currentScene->_shadows->findSize(rect.width(), rect.height()); + if (shd) { + shd->getDimensions(&point); + int midx = _ox - point.x / 2 - dyn->_someX; + int midy = _oy - point.y / 2 - dyn->_someY + rect.bottom - 3; + int shdw = point.y; + + int px; + if (!_movement || (_flags & 0x20)) + px = _statics->getCenter(&point)->x; + else + px = _movement->getCenter(&point)->x; + + if (_shadowsOn != 1) + midy = _shadowsOn - shdw / 2; + + shd->draw(px + midx, midy, 0, 0); + } + } + } + + int angle = 0; + if (_field_30 & 0xC000) { + if (_field_30 & 0x8000) + angle = -(_field_30 ^ 0x8000); + else + angle = _field_30 ^ 0x4000; + } + + if (!_movement || (_flags & 0x20)) { + _statics->getSomeXY(point); + _statics->_x = _ox - point.x; + _statics->_y = _oy - point.y; + _statics->draw(_statics->_x, _statics->_y, 0, angle); + } else { + _movement->draw(0, angle); + } +} + +void StaticANIObject::draw2() { + debug(0, "StatciANIObject::draw2(): id: (%s) %d [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy); + + if ((_flags & 4) && (_flags & 0x10)) { + if (_movement) { + _movement->draw(1, 0); + } else { + Common::Point point; + + _statics->getSomeXY(point); + + _statics->draw(_ox - point.x, _oy - point.y, 1, 0); + } + } +} + +MovTable *StaticANIObject::countMovements() { + CGameVar *preloadSubVar = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(getName())->getSubVarByName("PRELOAD"); + + if (preloadSubVar || preloadSubVar->getSubVarsCount() == 0) + return 0; + + MovTable *movTable = new MovTable; + + movTable->count = _movements.size(); + movTable->movs = (int16 *)calloc(_movements.size(), sizeof(int16)); + + for (uint i = 0; i < _movements.size(); i++) { + GameObject *obj = (GameObject *)_movements[i]; + movTable->movs[i] = 2; + + for (CGameVar *sub = preloadSubVar->_subVars; sub; sub = sub->_nextVarObj) { + if (scumm_stricmp(obj->getName(), sub->_varName) == 0) { + movTable->movs[i] = 1; + break; + } + } + } + + return movTable; +} + +void StaticANIObject::setSpeed(int speed) { + CGameVar *var = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(getName())->getSubVarByName("SpeedUp"); + + if (!var) + return; + + for (var = var->_subVars; var; var = var->_nextVarObj) { + Movement *mov = getMovementById(var->_value.intValue); + + if (mov) { + if (speed) { + if (mov->_counterMax == 83) + mov->_counterMax = 41; + } else if (mov->_counterMax == 41) { + mov->_counterMax = 83; + } + } + } + +} + +void StaticANIObject::setAlpha(int alpha) { + for (uint i = 0; i < _movements.size(); i++) + ((Movement *)_movements[i])->setAlpha(alpha); + + for (uint i = 0; i < _staticsList.size(); i++) + ((Statics *)_staticsList[i])->setAlpha(alpha); +} + +void StaticANIObject::initMovements() { + for (uint i = 0; i < _movements.size(); i++) + ((Movement *)_movements[i])->removeFirstPhase(); +} + +Common::Point *StaticANIObject::getCurrDimensions(Common::Point &p) { + Picture *pic; + + if (_movement) + pic = _movement->_currDynamicPhase; + else + pic = _statics; + + if (pic) { + Common::Point point; + + pic->getDimensions(&point); + p.x = point.x; + p.y = point.y; + } else { + p.x = 0; + p.y = 0; + } + + return &p; +} + +void StaticANIObject::update(int counterdiff) { + int mqid; + + debug(6, "StaticANIObject::update() (%s) [%d] [%d, %d] fl: %x", transCyrillic((byte *)_objectName), _id, _ox, _oy, _flags); + + if (_flags & 2) { + _messageNum--; + if (_messageNum) + return; + + mqid = _messageQueueId; + _messageQueueId = 0; + _flags ^= 2; + + updateGlobalMessageQueue(mqid, _id); + return; + } + + Common::Point point; + ExCommand *ex, *newex; + + if (_movement) { + _movement->_counter += counterdiff; + + if (_movement->_counter < _movement->_counterMax) + return; + + _movement->_counter = 0; + + if (_flags & 1) { + if (_counter) { + _counter--; + + return; + } + + DynamicPhase *dyn = _movement->_currDynamicPhase; + if (dyn->_initialCountdown == dyn->_countdown) { + + ex = dyn->getExCommand(); + if (ex && ex->_messageKind != 35) { + newex = new ExCommand(ex); + newex->_excFlags |= 2; + if (newex->_messageKind == 17) { + newex->_parentId = _id; + newex->_keyCode = _okeyCode; + } + newex->sendMessage(); + + if (!_movement) + return; + } + } + + if (dyn->_initialCountdown != dyn->_countdown || dyn->_field_68 == 0) { + newex = new ExCommand(_id, 17, dyn->_field_68, 0, 0, 0, 1, 0, 0, 0); + newex->_excFlags = 2; + newex->_keyCode = _okeyCode; + newex->sendMessage(); + + if (!_movement) + return; + } + + if (!_movement->gotoNextFrame(_callback1, _callback2)) { + stopAnim_maybe(); + } else { + setOXY(_movement->_ox, _movement->_oy); + _counter = _initialCounter; + + if (dyn->_initialCountdown == dyn->_countdown) { + ex = dyn->getExCommand(); + if (ex) { + if (ex->_messageKind == 35) { + newex = new ExCommand(ex); + newex->_excFlags |= 2; + newex->sendMessage(); + } + } + } + if (!_movement) + return; + + _stepArray.getCurrPoint(&point); + setOXY(point.x + _ox, point.y + _oy); + _stepArray.gotoNextPoint(); + if (_someDynamicPhaseIndex == _movement->_currDynamicPhaseIndex) + adjustSomeXY(); + } + } else if (_flags & 0x20) { + _flags ^= 0x20; + _flags |= 1; + + _movement->gotoFirstFrame(); + _movement->getCurrDynamicPhaseXY(point); + + Common::Point pointS; + _statics->getSomeXY(pointS); + _movement->setOXY(_ox + point.x + _movement->_mx - pointS.x, + _oy + point.y + _movement->_my - pointS.y); + } + } else { + if (_statics) { + if (_messageQueueId) { + if (_statics->_countdown) { + _statics->_countdown--; + return; + } + mqid = _messageQueueId; + _messageQueueId = 0; + updateGlobalMessageQueue(mqid, _id); + } + } + } +} + +void StaticANIObject::stopAnim_maybe() { + debug(6, "StaticANIObject::stopAnim_maybe()"); + + if (!(_flags & 1)) + return; + + _flags ^= 1; + + int oid = 0; + int oldmqid = _messageQueueId; + Common::Point point; + + if (_movement) { + setOXY(_movement->_ox, _movement->_oy); + + if (_flags & 0x40) { + if (!_movement->_currMovement && !_movement->_currDynamicPhaseIndex) { + _statics = _movement->_staticsObj1; + _movement->getCurrDynamicPhaseXY(point); + _ox -= point.x; + _oy -= point.y; + + _ox -= _movement->_mx; + _oy -= _movement->_my; + + _statics->getSomeXY(point); + if (_movement->_currMovement) { + _oy += point.y; + _ox -= point.x; + _ox += _statics->getDimensions(&point)->x; + } else { + _ox += point.x; + _oy += point.y; + } + } + } + + if (_movement->_currDynamicPhaseIndex || !(_flags & 0x40)) + _statics = _movement->_staticsObj2; + + _statics->getSomeXY(point); + + _statics->_x = _ox - point.x; + _statics->_y = _oy - point.y; + oid = _movement->_id; + _movement = 0; + + ExCommand *ex = new ExCommand(_id, 17, 24, 0, 0, 0, 1, 0, 0, 0); + ex->_keyCode = _okeyCode; + ex->_excFlags = 2; + ex->postMessage(); + } + + int mqid = _messageQueueId; + + if (_animExFlag) { + _messageQueueId = 0; + startAnimEx(oid, mqid, -1, -1); + } else { + if (_messageQueueId == oldmqid) { + _messageQueueId = 0; + if (_field_34 == 1) + updateGlobalMessageQueue(mqid, _id); + } + } +} + +void StaticANIObject::adjustSomeXY() { + warning("STUB: StaticANIObject::adjustSomeXY()"); +} + +MessageQueue *StaticANIObject::changeStatics1(int msgNum) { + warning("STUB: StaticANIObject::changeStatics1(%d)", msgNum); + + return 0; +} + +void StaticANIObject::changeStatics2(int objId) { + warning("STUB: StaticANIObject::changeStatics2(%d)", objId); +} + +void StaticANIObject::hide() { + if (!_messageQueueId) { + if (_flags & 4) + _flags ^= 4; + } +} + +void StaticANIObject::show1(int x, int y, int movId, int mqId) { + debug(0, "StaticANIObject::show1(%d, %d, %d, %d)", x, y, movId, mqId); + + if (_messageQueueId) + return; + + if (movId == -1) { + _flags |= 4u; + if (x != -1 && y != -1) { + setOXY(x, y); + } + + return; + } + + Movement *mov = getMovementById(movId); + if (!mov) + return; + + if (x != -1 && y != -1) { + setOXY(x, y); + } + + _statics = mov->_staticsObj1; + + Common::Point point; + + mov->_staticsObj1->getSomeXY(point); + _statics->_x = x - point.x; + _statics->_y = y - point.y; + + _statics->_countdown = _statics->_initialCountdown; + + _flags |= 4; + _ox = x; + _oy = y; + _movement = 0; + + if (mov->_currMovement) + _flags |= 8; + else if (_flags & 8) + _flags ^= 8; + + if (_flags & 1) + _flags ^= 1; + + _messageQueueId = mqId; +} + +void StaticANIObject::show2(int x, int y, int movementId, int mqId) { + warning("STUB: StaticANIObject::show2(%d, %d, %d, %d)", x, y, movementId, mqId); +} + +void StaticANIObject::playIdle() { + if (isIdle()) + adjustSomeXY(); +} + +void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x, int y, Common::Point **points, int pointsCount, int someDynamicPhaseIndex) { + warning("STUB: StaticANIObject::startAnimSteps()"); +} + +bool StaticANIObject::startAnimEx(int movid, int parId, int flag1, int flag2) { + bool res = startAnim(movid, parId, -1); + if (res) + _animExFlag = 1; + + _someDynamicPhaseIndex = -1; + return res; +} + +bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhaseIdx) { + if (_flags & 0x80) + return false; + + debug(0, "StaticANIObject::startAnim(%d, %d, %d) (%s [%d]) [%d, %d]", movementId, messageQueueId, dynPhaseIdx, transCyrillic((byte *)_objectName), _id, _ox, _oy); + + if (_messageQueueId) { + updateGlobalMessageQueue(messageQueueId, _id); + return false; + } + + Movement *mov = 0; + + for (uint i = 0; i < _movements.size(); i++) { + + if (((Movement *)_movements[i])->_id == movementId) { + mov = (Movement *)_movements[i]; + break; + } + } + + if (!mov) { + updateGlobalMessageQueue(messageQueueId, _id); + return false; + } + + if (mov == _movement) { + _flags |= 1; + _messageQueueId = messageQueueId; + + return true; + } + + int newx = _ox; + int newy = _oy; + Common::Point point; + + debug(0, "0 %d %d", newx, newy); + if (_movement) { + _movement->getCurrDynamicPhaseXY(point); + + newx -= point.x; + newy -= point.y; + + debug(0, "1 %d %d", newx, newy); + } else if (_statics) { + _statics->getSomeXY(point); + + newx -= point.x; + newy -= point.y; + debug(0, "2 %d %d - %d %d assa", newx, newy, point.x, point.y); + } + + _movement = mov; + + _stepArray.clear(); + + if (_flags & 0x40) + _movement->gotoLastFrame(); + else + _movement->gotoFirstFrame(); + + if (!(_flags & 0x40)) { + if (!_movement->_currDynamicPhaseIndex) { + _stepArray.getCurrPoint(&point); + newx += point.x + _movement->_mx; + newy += point.y + _movement->_my; + + debug(0, "3 %d %d", newx, newy); + _stepArray.gotoNextPoint(); + + ExCommand *ex = _movement->_currDynamicPhase->getExCommand(); + if (ex) { + if (ex->_messageKind == 35) { + ExCommand *newex = new ExCommand(ex); + newex->_excFlags |= 2; + newex->sendMessage(); + } + } + } + } + + _movement->getCurrDynamicPhaseXY(point); + setOXY(point.x + newx, point.y + newy); + + if (_movement->_staticsObj2->_staticsId & 0x4000) + _flags |= 8; + else + _flags &= 0xFFF7; + + _flags |= 1; + + _messageQueueId = messageQueueId; + _movement->_currDynamicPhase->_countdown = _movement->_currDynamicPhase->_initialCountdown; + _movement->_counter = 0; + + _counter = _initialCounter; + _someDynamicPhaseIndex = dynPhaseIdx; + + _stepArray.clear(); + + ExCommand *newex = new ExCommand(_id, 17, 23, 0, 0, movementId, 1, 0, 0, 0); + + newex->_keyCode = _okeyCode; + newex->_excFlags = 2; + + newex->postMessage(); + + return true; +} + +Statics::Statics() { + _staticsId = 0; + _picture = 0; + _staticsName = 0; +} + +Statics::Statics(Statics *src, bool reverse) : DynamicPhase(src, reverse) { + _staticsId = src->_staticsId; + + if (reverse) { + _staticsId ^= 0x4000; + int newlen = strlen(src->_staticsName) + strlen(sO_MirroredTo) + 1; + _staticsName = (char *)calloc(newlen, 1); + + snprintf(_staticsName, newlen, "%s%s", sO_MirroredTo, src->_staticsName); + } else { + _staticsName = (char *)calloc(strlen(src->_staticsName) + 1, 1); + strncpy(_staticsName, src->_staticsName, strlen(src->_staticsName) + 1); + } + + _memfilename = (char *)calloc(strlen(src->_memfilename) + 1, 1); + strncpy(_memfilename, src->_memfilename, strlen(src->_memfilename) + 1); + + _picture = new Picture(); +} + +bool Statics::load(MfcArchive &file) { + debug(5, "Statics::load()"); + + DynamicPhase::load(file); + + _staticsId = file.readUint16LE(); + + _staticsName = file.readPascalString(); + debug(7, "statics: <%s> id: %d (%x)", transCyrillic((byte *)_staticsName), _staticsId, _staticsId); + + _picture = new Picture(); + _picture->load(file); + + return true; +} + +Common::Point *Statics::getSomeXY(Common::Point &p) { + p.x = _someX; + p.y = _someY; + + return &p; +} + +Common::Point *Statics::getCenter(Common::Point *p) { + Common::Rect rect; + + rect = *_rect; + + if (_staticsId & 0x4000) { + Common::Point point; + + getDimensions(&point); + rect.moveTo(point.x - _rect->right, _rect->top); + } + + p->x = rect.left + _rect->width() / 2; + p->y = rect.top + _rect->height() / 2; + + return p; +} + +Movement::Movement() { + _lastFrameSpecialFlag = 0; + _flipFlag = 0; + _updateFlag1 = 0; + _staticsObj1 = 0; + _staticsObj2 = 0; + _mx = 0; + _my = 0; + _m2x = 0; + _m2y = 0; + _field_50 = 1; + _field_78 = 0; + _framePosOffsets = 0; + _field_84 = 0; + _currDynamicPhase = 0; + _field_8C = 0; + _currDynamicPhaseIndex = 0; + _field_94 = 0; + _currMovement = 0; + _counter = 0; + _counterMax = 83; + + _field_24 = 0; + _field_28 = 0; +} + +Movement::Movement(Movement *src, StaticANIObject *ani) { + _lastFrameSpecialFlag = 0; + _flipFlag = src->_flipFlag; + _updateFlag1 = src->_updateFlag1; + _staticsObj1 = 0; + _staticsObj2 = 0; + _mx = 0; + _my = 0; + _m2x = 0; + _m2y = 0; + + _field_78 = 0; + _framePosOffsets = 0; + _field_84 = 0; + _currDynamicPhase = 0; + _field_8C = 0; + _currDynamicPhaseIndex = src->_currDynamicPhaseIndex; + _field_94 = 0; + + _currMovement = src; + _ox = src->_ox; + _oy = src->_oy; + + initStatics(ani); + + _counterMax = src->_counterMax; + _counter = src->_counter; + _field_50 = src->_field_50; + + updateCurrDynamicPhase(); +} + +Movement::Movement(Movement *src, int *flag1, int flag2, StaticANIObject *ani) { + warning("STUB: Movement(src, %p, %d, ani)", (void *)flag1, flag2); +} + +bool Movement::load(MfcArchive &file) { + warning("STUB: Movement::load"); + return true; +} + +bool Movement::load(MfcArchive &file, StaticANIObject *ani) { + GameObject::load(file); + + int dynCount = file.readUint16LE(); + + debug(7, "dynCount: %d _id: %d", dynCount, _id); + if (dynCount != 0xffff || _id == MV_MAN_TURN_LU) { + _framePosOffsets = (Common::Point **)calloc(dynCount + 2, sizeof(Common::Point *)); + + for (int i = 0; i < dynCount + 2; i++) + _framePosOffsets[i] = new Common::Point(); + + for (int i = 0; i < dynCount; i++) { + DynamicPhase *ph = new DynamicPhase(); + ph->load(file); + + _dynamicPhases.push_back(ph); + + _framePosOffsets[i]->x = ph->_x; + _framePosOffsets[i]->y = ph->_y; + } + + int staticsid = file.readUint16LE(); + + _staticsObj1 = ani->getStaticsById(staticsid); + + if (!_staticsObj1 && (staticsid & 0x4000)) { + Statics *s = ani->getStaticsById(staticsid ^ 0x4000); + _staticsObj1 = ani->addReverseStatics(s); + } + + _mx = file.readUint32LE(); + _my = file.readUint32LE(); + + staticsid = file.readUint16LE(); + + _staticsObj2 = ani->getStaticsById(staticsid); + + if (!_staticsObj2 && (staticsid & 0x4000)) { + Statics *s = ani->getStaticsById(staticsid ^ 0x4000); + _staticsObj2 = ani->addReverseStatics(s); + } + + _m2x = file.readUint32LE(); + _m2y = file.readUint32LE(); + + if (_staticsObj2) { + _dynamicPhases.push_back(_staticsObj2); + + _framePosOffsets[_dynamicPhases.size() - 1]->x = _m2x; + _framePosOffsets[_dynamicPhases.size() - 1]->y = _m2y; + } + + } else { + int movid = file.readUint16LE(); + + _currMovement = ani->getMovementById(movid); + _staticsObj1 = 0; + _staticsObj2 = 0; + + initStatics(ani); + } + + if (_staticsObj1 && _staticsObj2) { + if ((_staticsObj1->_staticsId ^ _staticsObj2->_staticsId) & 0x4000) + _flipFlag = 1; + } + + if (g_fullpipe->_gameProjectVersion >= 8) + _field_50 = file.readUint32LE(); + + if (g_fullpipe->_gameProjectVersion < 12) + _counterMax = 83; + else + _counterMax = file.readUint32LE(); + + _counter = 0; + updateCurrDynamicPhase(); + + return true; +} + +Common::Point *Movement::getCurrDynamicPhaseXY(Common::Point &p) { + p.x = _currDynamicPhase->_someX; + p.y = _currDynamicPhase->_someY; + + return &p; +} + +void Movement::setAlpha(int alpha) { + if (_currMovement) + for (uint i = 0; i < _currMovement->_dynamicPhases.size(); i++) { + ((DynamicPhase *)_currMovement->_dynamicPhases[i])->setAlpha(alpha); + } + else + for (uint i = 0; i < _dynamicPhases.size(); i++) { + ((DynamicPhase *)_dynamicPhases[i])->setAlpha(alpha); + } +} + +Common::Point *Movement::getDimensionsOfPhase(Common::Point *p, int phaseIndex) { + int idx = phaseIndex; + + if (idx == -1) + idx = _currDynamicPhaseIndex; + + DynamicPhase *dyn; + + if (_currMovement) + dyn = (DynamicPhase *)_currMovement->_dynamicPhases[idx]; + else + dyn = (DynamicPhase *)_dynamicPhases[idx]; + + Common::Point point; + + dyn->getDimensions(&point); + + *p = point; + + return p; +} + +void Movement::initStatics(StaticANIObject *ani) { + if (!_currMovement) + return; + + debug(7, "Movement::initStatics()"); + + _staticsObj2 = ani->addReverseStatics(_currMovement->_staticsObj2); + _staticsObj1 = ani->addReverseStatics(_currMovement->_staticsObj1); + + _mx = _currMovement->_mx; + _my = _currMovement->_my; + + _currMovement->setDynamicPhaseIndex(_currMovement->_updateFlag1 != 0 ? 1 : 0); + + Common::Point point; + + int x1 = _currMovement->_staticsObj1->getDimensions(&point)->x - _mx; + + _mx = x1 - _currMovement->_currDynamicPhase->getDimensions(&point)->x; + + _currMovement->setDynamicPhaseIndex(_currMovement->_currDynamicPhaseIndex); + + _m2x = _currMovement->_m2x; + _m2y = _currMovement->_m2y; + _currMovement->gotoLastFrame(); + + x1 = _currMovement->_staticsObj2->getDimensions(&point)->x; + _m2x = _currMovement->_currDynamicPhase->getDimensions(&point)->x - _m2x - x1; +} + +void Movement::updateCurrDynamicPhase() { + debug(7, "Movement::updateCurrDynamicPhase()"); + + if (_currMovement) { + if (_currMovement->_dynamicPhases.size() == 0 || (uint)_currDynamicPhaseIndex >= _currMovement->_dynamicPhases.size()) + return; + + if (_currMovement->_dynamicPhases[_currDynamicPhaseIndex]) + _currDynamicPhase = (DynamicPhase *)_currMovement->_dynamicPhases[_currDynamicPhaseIndex]; + } else { + if (_dynamicPhases.size() == 0 || (uint)_currDynamicPhaseIndex >= _dynamicPhases.size()) + return; + + if (_dynamicPhases[_currDynamicPhaseIndex]) + _currDynamicPhase = (DynamicPhase *)_dynamicPhases[_currDynamicPhaseIndex]; + } +} + +int Movement::calcDuration() { + int res = 0; + + if (_currMovement) + for (uint i = 0; i < _currMovement->_dynamicPhases.size(); i++) { + res += ((DynamicPhase *)_currMovement->_dynamicPhases[i])->_initialCountdown; + } + else + for (uint i = 0; i < _dynamicPhases.size(); i++) { + res += ((DynamicPhase *)_dynamicPhases[i])->_initialCountdown; + } + + return res; +} + +void Movement::setDynamicPhaseIndex(int index) { + debug(7, "Movement::setDynamicPhaseIndex(%d)", index); + while (_currDynamicPhaseIndex < index) + gotoNextFrame(0, 0); + + while (_currDynamicPhaseIndex > index) + gotoPrevFrame(); +} + +DynamicPhase *Movement::getDynamicPhaseByIndex(int idx) { + debug(7, "Movement::updateCurrDynamicPhase()"); + + if (_currMovement) { + if (_currMovement->_dynamicPhases.size() == 0 || (uint)idx >= _currMovement->_dynamicPhases.size()) + return 0; + + return (DynamicPhase *)_currMovement->_dynamicPhases[idx]; + } else { + if (_dynamicPhases.size() == 0 || (uint)idx >= _dynamicPhases.size()) + return 0; + + return (DynamicPhase *)_dynamicPhases[idx]; + } +} + +void Movement::loadPixelData() { + Movement *mov = this; + for (Movement *i = _currMovement; i; i = i->_currMovement) + mov = i; + + for (uint i = 0; i < _dynamicPhases.size(); i++) { + if ((Statics *)_dynamicPhases[i] != mov->_staticsObj2 || !(mov->_staticsObj2->_staticsId & 0x4000)) + ((Statics *)_dynamicPhases[i])->getPixelData(); + } + + if (!(mov->_staticsObj1->_staticsId & 0x4000)) + mov->_staticsObj1->getPixelData(); +} + +void Movement::removeFirstPhase() { + if (_updateFlag1) { + if (!_currDynamicPhaseIndex) + gotoNextFrame(0, 0); + + if (!_currMovement) { + _dynamicPhases.remove_at(0); + + for (uint i = 0; i < _dynamicPhases.size(); i++) { + _framePosOffsets[i - 1]->x = _framePosOffsets[i]->x; + _framePosOffsets[i - 1]->y = _framePosOffsets[i]->y; + } + } + _currDynamicPhaseIndex--; + } + + updateCurrDynamicPhase(); + _updateFlag1 = 0; +} + +bool Movement::gotoNextFrame(int callback1, void (*callback2)(int *)) { + debug(8, "Movement::gotoNextFrame()"); + + if (!callback2) { + if (_currMovement) { + if ((uint)_currDynamicPhaseIndex == _currMovement->_dynamicPhases.size() - 1 + && !(((DynamicPhase *)(_currMovement->_dynamicPhases.back()))->_countdown)) { + return false; + } + } else if ((uint)_currDynamicPhaseIndex == _dynamicPhases.size() - 1 + && !(((DynamicPhase *)(_dynamicPhases.back()))->_countdown)) { + return false; + } + } + + if (_currDynamicPhase->_countdown) { + _currDynamicPhase->_countdown--; + return true; + } + + Common::Point point; + + getCurrDynamicPhaseXY(point); + _ox -= point.x; + _oy -= point.y; + + int deltax = 0; + + if (_currMovement) + deltax = _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x; + + int oldDynIndex = _currDynamicPhaseIndex; + + if (callback2) + callback2(&_currDynamicPhaseIndex); + else + _currDynamicPhaseIndex++; + + bool result = true; + + if (_currMovement) { + if (_currMovement->_dynamicPhases.size() <= (uint)_currDynamicPhaseIndex) { + _currDynamicPhaseIndex = _currMovement->_dynamicPhases.size() - 1; + result = (callback2 == 0); + } + if (_currDynamicPhaseIndex < 0) { + _currDynamicPhaseIndex = 0; + result = false; + } + if (_currMovement->_framePosOffsets) { + if (callback1) { + point = *_currMovement->_framePosOffsets[_currDynamicPhaseIndex]; + //callback1(_currDynamicPhaseIndex, &point, _ox, _oy); + + _ox += deltax - point.x; + _oy += point.y; + + _ox -= _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x; + } else if (oldDynIndex >= _currDynamicPhaseIndex) { + while (oldDynIndex > _currDynamicPhaseIndex) { + _ox += deltax; + deltax = _currMovement->getDimensionsOfPhase(&point, oldDynIndex)->x; + + _ox += _currMovement->_framePosOffsets[oldDynIndex]->x; + _oy -= _currMovement->_framePosOffsets[oldDynIndex]->y; + oldDynIndex--; + + _ox -= _currMovement->getDimensionsOfPhase(&point, oldDynIndex)->x; + } + } else { + for (int i = oldDynIndex + 1; i <= _currDynamicPhaseIndex; i++) { + _ox += deltax; + deltax = _currMovement->getDimensionsOfPhase(&point, i)->x; + _ox -= _currMovement->_framePosOffsets[i]->x; + _oy += _currMovement->_framePosOffsets[i]->y; + _ox -= _currMovement->getDimensionsOfPhase(&point, i)->x; + } + } + } + } else { + if (_dynamicPhases.size() <= (uint)_currDynamicPhaseIndex) { + _currDynamicPhaseIndex = _dynamicPhases.size() - 1; + result = (callback2 == 0); + } + if (_currDynamicPhaseIndex < 0) { + _currDynamicPhaseIndex = 0; + result = false; + } + + if (_framePosOffsets) { + if (callback1) { + point.x = _framePosOffsets[_currDynamicPhaseIndex]->x; + point.y = _framePosOffsets[_currDynamicPhaseIndex]->y; + + //callback1(_currDynamicPhaseIndex, &point, _ox, _oy); + _ox += point.x; + _oy += point.y; + } else if (oldDynIndex >= _currDynamicPhaseIndex) { + for (int i = oldDynIndex; i > _currDynamicPhaseIndex; i--) { + _ox -= _framePosOffsets[i]->x; + _oy -= _framePosOffsets[i]->y; + } + } else { + for (int i = oldDynIndex + 1; i <= _currDynamicPhaseIndex; i++) { + _ox += _framePosOffsets[i]->x; + _oy += _framePosOffsets[i]->y; + } + } + } + } + + updateCurrDynamicPhase(); + getCurrDynamicPhaseXY(point); + _ox += point.x; + _oy += point.y; + + _currDynamicPhase->_countdown = _currDynamicPhase->_initialCountdown; + + return result; +} + +bool 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; +} + +void Movement::gotoFirstFrame() { + while (_currDynamicPhaseIndex) + gotoPrevFrame(); +} + +void Movement::gotoLastFrame() { + if (_currMovement) { + while ((uint)_currDynamicPhaseIndex != _currMovement->_dynamicPhases.size() - 1) + gotoNextFrame(0, 0); + } else { + while ((uint)_currDynamicPhaseIndex != _dynamicPhases.size() - 1) + gotoNextFrame(0, 0); + } +} + +Common::Point *Movement::getCenter(Common::Point *p) { + Common::Rect rect; + + rect = *_currDynamicPhase->_rect; + + if (_currMovement) { + Common::Point point; + + _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex); + + rect.moveTo(point.x - _currDynamicPhase->_rect->right, _currDynamicPhase->_rect->top); + } + + p->x = rect.left + _currDynamicPhase->_rect->width() / 2; + p->y = rect.top + _currDynamicPhase->_rect->height() / 2; + + return p; +} + +DynamicPhase::DynamicPhase() { + _someX = 0; + _rect = 0; + _field_7C = 0; + _field_7E = 0; + _dynFlags = 0; + _someY = 0; +} + +DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) { + _field_7C = src->_field_7C; + _field_7E = 0; + _rect = new Common::Rect(); + + debug(0, "DynamicPhase::DynamicPhase(src, %d)", reverse); + + if (reverse) { + if (!src->_bitmap) + src->init(); + + _bitmap = src->_bitmap->reverseImage(); + _data = _bitmap->_pixels; + _dataSize = src->_dataSize; + + if (g_fullpipe->_currArchive) { + _mfield_14 = 0; + _libHandle = g_fullpipe->_currArchive; + } + + _mflags |= 1; + + _someX = src->_someX; + _someY = src->_someY; + } else { + _mfield_14 = src->_mfield_14; + _mfield_8 = src->_mfield_8; + _mflags = src->_mflags; + + _memfilename = (char *)calloc(strlen(src->_memfilename) + 1, 1); + strncpy(_memfilename, src->_memfilename, strlen(src->_memfilename) + 1); + _dataSize = src->_dataSize; + _mfield_10 = src->_mfield_10; + _libHandle = src->_libHandle; + + _bitmap = src->_bitmap; + if (_bitmap) + _field_54 = 1; + + _someX = src->_someX; + _someY = src->_someY; + } + + *_rect = *src->_rect; + + _width = src->_width; + _height = src->_height; + _field_7C = src->_field_7C; + + if (src->getExCommand()) + _exCommand = new ExCommand(src->getExCommand()); + else + _exCommand = 0; + + _initialCountdown = src->_initialCountdown; + _field_6A = src->_field_6A; + _dynFlags = src->_dynFlags; + + setPaletteData(src->getPaletteData()); + + copyMemoryObject2(src); +} + +bool DynamicPhase::load(MfcArchive &file) { + debug(5, "DynamicPhase::load()"); + + StaticPhase::load(file); + + _field_7C = file.readUint16LE(); + _rect = new Common::Rect(); + _rect->left = file.readUint32LE(); + _rect->top = file.readUint32LE(); + _rect->right = file.readUint32LE(); + _rect->bottom = file.readUint32LE(); + + assert (g_fullpipe->_gameProjectVersion >= 1); + + _someX = file.readUint32LE(); + _someY = file.readUint32LE(); + + assert (g_fullpipe->_gameProjectVersion >= 12); + + _dynFlags = file.readUint32LE(); + + return true; +} + +StaticPhase::StaticPhase() { + _field_6A = 1; + _initialCountdown = 0; + _countdown = 0; + _field_68 = 0; + _exCommand = 0; +} + +bool StaticPhase::load(MfcArchive &file) { + debug(5, "StaticPhase::load()"); + + Picture::load(file); + + _initialCountdown = file.readUint16LE(); + _field_6A = file.readUint16LE(); + + if (g_fullpipe->_gameProjectVersion >= 12) { + _exCommand = (ExCommand *)file.readClass(); + + return true; + } + + assert (g_fullpipe->_gameProjectVersion >= 12); + + return true; +} + +} // End of namespace Fullpipe |