diff options
Diffstat (limited to 'queen/logic.cpp')
-rw-r--r-- | queen/logic.cpp | 2221 |
1 files changed, 0 insertions, 2221 deletions
diff --git a/queen/logic.cpp b/queen/logic.cpp deleted file mode 100644 index a535907dd9..0000000000 --- a/queen/logic.cpp +++ /dev/null @@ -1,2221 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2003-2006 The ScummVM project - * - * 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. - * - * $URL$ - * $Id$ - * - */ - -#include "common/stdafx.h" -#include "queen/logic.h" - -#include "common/config-manager.h" -#include "queen/bankman.h" -#include "queen/command.h" -#include "queen/credits.h" -#include "queen/cutaway.h" -#include "queen/debug.h" -#include "queen/defs.h" -#include "queen/display.h" -#include "queen/graphics.h" -#include "queen/grid.h" -#include "queen/input.h" -#include "queen/journal.h" -#include "queen/queen.h" -#include "queen/resource.h" -#include "queen/sound.h" -#include "queen/state.h" -#include "queen/talk.h" -#include "queen/walk.h" - -namespace Queen { - -static Common::String trim(const Common::String &s) { - const char *p; - - p = s.c_str(); - while (*p == ' ') ++p; - int start = p - s.c_str(); - - p = s.c_str() + s.size() - 1; - while (p != s.c_str() && *p == ' ') --p; - int end = p - s.c_str(); - - return Common::String(s.c_str() + start, end - start + 1); -} - -Logic::Logic(QueenEngine *vm) - : _credits(NULL), _objectData(NULL), _roomData(NULL), _sfxName(NULL), - _itemData(NULL), _graphicData(NULL), _walkOffData(NULL), _objectDescription(NULL), - _furnitureData(NULL), _actorData(NULL), _graphicAnim(NULL), _vm(vm) { - _joe.x = _joe.y = 0; - _joe.scale = 100; - _joe.walk = JWM_NORMAL; - memset(_gameState, 0, sizeof(_gameState)); - memset(_talkSelected, 0, sizeof(_talkSelected)); - _puzzleAttemptCount = 0; - _journal = new Journal(vm); - _scene = 0; - initialise(); -} - -Logic::~Logic() { - delete _journal; - delete _credits; - delete[] _objectData; - delete[] _roomData; - delete[] _sfxName; - delete[] _itemData; - delete[] _graphicData; - delete[] _walkOffData; - delete[] _objectDescription; - delete[] _furnitureData; - delete[] _actorData; - delete[] _graphicAnim; -} - -void Logic::initialise() { - int16 i; - - uint8 *jas = _vm->resource()->loadFile("QUEEN.JAS", 20); - uint8 *ptr = jas; - - _numRooms = READ_BE_UINT16(ptr); ptr += 2; - _numNames = READ_BE_UINT16(ptr); ptr += 2; - _numObjects = READ_BE_UINT16(ptr); ptr += 2; - _numDescriptions = READ_BE_UINT16(ptr); ptr += 2; - - _objectData = new ObjectData[_numObjects + 1]; - memset(&_objectData[0], 0, sizeof(ObjectData)); - for (i = 1; i <= _numObjects; i++) { - _objectData[i].readFromBE(ptr); - } - - _roomData = new uint16[_numRooms + 2]; - _roomData[0] = 0; - for (i = 1; i <= (_numRooms + 1); i++) { - _roomData[i] = READ_BE_UINT16(ptr); ptr += 2; - } - _roomData[_numRooms + 1] = _numObjects; - - if (_vm->resource()->isDemo()) { - _sfxName = NULL; - } else { - _sfxName = new uint16[_numRooms + 1]; - _sfxName[0] = 0; - for (i = 1; i <= _numRooms; i++) { - _sfxName[i] = READ_BE_UINT16(ptr); ptr += 2; - } - } - - _numItems = READ_BE_UINT16(ptr); ptr += 2; - _itemData = new ItemData[_numItems + 1]; - memset(&_itemData[0], 0, sizeof(ItemData)); - for (i = 1; i <= _numItems; i++) { - _itemData[i].readFromBE(ptr); - } - - _numGraphics = READ_BE_UINT16(ptr); ptr += 2; - _graphicData = new GraphicData[_numGraphics + 1]; - memset(&_graphicData[0], 0, sizeof(GraphicData)); - for (i = 1; i <= _numGraphics; i++) { - _graphicData[i].readFromBE(ptr); - } - - _vm->grid()->readDataFrom(_numObjects, _numRooms, ptr); - - _numWalkOffs = READ_BE_UINT16(ptr); ptr += 2; - _walkOffData = new WalkOffData[_numWalkOffs + 1]; - memset(&_walkOffData[0], 0, sizeof(WalkOffData)); - for (i = 1; i <= _numWalkOffs; i++) { - _walkOffData[i].readFromBE(ptr); - } - - _numObjDesc = READ_BE_UINT16(ptr); ptr += 2; - _objectDescription = new ObjectDescription[_numObjDesc + 1]; - memset(&_objectDescription[0], 0, sizeof(ObjectDescription)); - for (i = 1; i <= _numObjDesc; i++) { - _objectDescription[i].readFromBE(ptr); - } - - _vm->command()->readCommandsFrom(ptr); - - _entryObj = READ_BE_UINT16(ptr); ptr += 2; - - _numFurniture = READ_BE_UINT16(ptr); ptr += 2; - _furnitureData = new FurnitureData[_numFurniture + 1]; - memset(&_furnitureData[0], 0, sizeof(FurnitureData)); - for (i = 1; i <= _numFurniture; i++) { - _furnitureData[i].readFromBE(ptr); - } - - // Actors - _numActors = READ_BE_UINT16(ptr); ptr += 2; - _numAAnim = READ_BE_UINT16(ptr); ptr += 2; - _numAName = READ_BE_UINT16(ptr); ptr += 2; - _numAFile = READ_BE_UINT16(ptr); ptr += 2; - - _actorData = new ActorData[_numActors + 1]; - memset(&_actorData[0], 0, sizeof(ActorData)); - for (i = 1; i <= _numActors; i++) { - _actorData[i].readFromBE(ptr); - } - - _numGraphicAnim = READ_BE_UINT16(ptr); ptr += 2; - - _graphicAnim = new GraphicAnim[_numGraphicAnim + 1]; - if (_numGraphicAnim == 0) { - _graphicAnim[0].readFromBE(ptr); - } else { - memset(&_graphicAnim[0], 0, sizeof(GraphicAnim)); - for (i = 1; i <= _numGraphicAnim; i++) { - _graphicAnim[i].readFromBE(ptr); - } - } - - _currentRoom = _objectData[_entryObj].room; - _entryObj = 0; - - if (memcmp(ptr, _vm->resource()->JASVersion(), 5) != 0) { - warning("Unexpected queen.jas file format"); - } - - delete[] jas; - - uint32 size; - char *buf = (char *)_vm->resource()->loadFile("QUEEN2.JAS", 0, &size); - LineReader queen2jas(buf, size); - - _objDescription.push_back(""); - for (i = 1; i <= _numDescriptions; i++) { - _objDescription.push_back(queen2jas.nextLine()); - } - - // Patch for German text bug - if (_vm->resource()->getLanguage() == GERMAN) { - _objDescription[296] = "Es bringt nicht viel, das festzubinden."; - } - - _objName.push_back(""); - for (i = 1; i <= _numNames; i++) { - _objName.push_back(queen2jas.nextLine()); - } - - _roomName.push_back(""); - for (i = 1; i <= _numRooms; i++) { - _roomName.push_back(queen2jas.nextLine()); - } - - _verbName.push_back(""); - for (i = 1; i <= 12; i++) { - _verbName.push_back(queen2jas.nextLine()); - } - - _joeResponse.push_back(""); - for (i = 1; i <= JOE_RESPONSE_MAX; i++) { - _joeResponse.push_back(queen2jas.nextLine()); - } - - // FIXME - the spanish version adds some space characters (0x20) at the - // beginning and the end of the journal button captions. As we don't need - // that 'trick' to center horizontally the texts, we simply trim them. - if (_vm->resource()->getLanguage() == SPANISH) { - for (i = 30; i <= 35; i++) { - _joeResponse[i] = trim(_joeResponse[i]); - } - } - - _aAnim.push_back(""); - for (i = 1; i <= _numAAnim; i++) { - _aAnim.push_back(queen2jas.nextLine()); - } - - _aName.push_back(""); - for (i = 1; i <= _numAName; i++) { - _aName.push_back(queen2jas.nextLine()); - } - - _aFile.push_back(""); - for (i = 1; i <= _numAFile; i++) { - _aFile.push_back(queen2jas.nextLine()); - } -} - -void Logic::start() { - _vm->command()->clear(false); - _vm->display()->setupPanel(); - _vm->graphics()->unpackControlBank(); - _vm->graphics()->setupMouseCursor(); - setupJoe(); - _vm->grid()->setupPanel(); - inventorySetup(); - - _oldRoom = 0; - _newRoom = _currentRoom; -} - -ObjectData* Logic::objectData(int index) const { - assert(index >= 0 && index <= _numObjects); - return &_objectData[index]; -} - -uint16 Logic::findBob(uint16 obj) const { - assert(obj <= _numObjects); - - uint16 room = _objectData[obj].room; - assert(room <= _numRooms); - - uint16 bobnum = 0; - int16 img = _objectData[obj].image; - if (img != 0) { - if (img == -3 || img == -4) { - // a person object - bobnum = findPersonNumber(obj, room); - } else { - uint16 bobtype = 0; // 1 for animated, 0 for static - - if (img <= -10) { - // object has been turned off, but the image order hasn't been updated - if (_graphicData[-(img + 10)].lastFrame != 0) { - bobtype = 1; - } - } else if (img == -2) { - // -1 static, -2 animated - bobtype = 1; - } else if (img > 0) { - if (_graphicData[img].lastFrame != 0) { - bobtype = 1; - } - } - - uint16 idxAnimated = 0; - uint16 idxStatic = 0; - for (uint16 i = _roomData[room] + 1; i <= obj; ++i) { - img = _objectData[i].image; - if (img <= -10) { - if (_graphicData[-(img + 10)].lastFrame != 0) { - ++idxAnimated; - } else { - ++idxStatic; - } - } else if (img > 0) { - if (img > 5000) { - img -= 5000; - } - - assert (img <= _numGraphics); - - if (_graphicData[img].lastFrame != 0) { - ++idxAnimated; - } else { - ++idxStatic; - } - } else if (img == -1) { - ++idxStatic; - } else if (img == -2) { - ++idxAnimated; - } - } - if (bobtype == 0) { - // static bob - if (idxStatic > 0) { - bobnum = 19 + _vm->graphics()->numStaticFurniture() + idxStatic; - } - } else { - // animated bob - if (idxAnimated > 0) { - bobnum = 4 + _vm->graphics()->numAnimatedFurniture() + idxAnimated; - } - } - } - } - return bobnum; -} - -uint16 Logic::findFrame(uint16 obj) const { - uint16 framenum = 0; - uint16 room = _objectData[obj].room; - int16 img = _objectData[obj].image; - if (img == -3 || img == -4) { - uint16 bobnum = findPersonNumber(obj, room); - if (bobnum <= 3) { - framenum = 31 + bobnum; - } - } else { - uint16 idx = 0; - for (uint16 i = _roomData[room] + 1; i < obj; ++i) { - img = _objectData[i].image; - if (img <= -10) { - const GraphicData* pgd = &_graphicData[-(img + 10)]; - if (pgd->lastFrame != 0) { - // skip all the frames of the animation - idx += ABS(pgd->lastFrame) - pgd->firstFrame + 1; - } else { - // static bob, skip one frame - ++idx; - } - } else if (img == -1) { - ++idx; - } else if (img > 0) { - if (img > 5000) { - img -= 5000; - } - const GraphicData* pgd = &_graphicData[img]; - uint16 lastFrame = ABS(pgd->lastFrame); - if (pgd->firstFrame < 0) { - idx += lastFrame; - } else if (lastFrame != 0) { - idx += (lastFrame - pgd->firstFrame) + 1; - } else { - ++idx; - } - } - } - - img = _objectData[obj].image; - if (img <= -10) { - const GraphicData* pgd = &_graphicData[-(img + 10)]; - if (pgd->lastFrame != 0) { - idx += ABS(pgd->lastFrame) - pgd->firstFrame + 1; - } else { - ++idx; - } - } else if (img == -1 || img > 0) { - ++idx; - } - - // calculate only if there are person frames - if (idx > 0) { - framenum = FRAMES_JOE + _vm->graphics()->numFurnitureFrames() + idx; - } - } - return framenum; -} - -uint16 Logic::objectForPerson(uint16 bobNum) const { - uint16 bobcur = 0; - // first object number in the room - uint16 cur = currentRoomData() + 1; - // last object number in the room - uint16 last = _roomData[_currentRoom + 1]; - for (; cur <= last; ++cur) { - int16 image = _objectData[cur].image; - if (image == -3 || image == -4) { - // the object is a bob - ++bobcur; - } - if (bobcur == bobNum) { - return cur; - } - } - return 0; -} - -WalkOffData *Logic::walkOffPointForObject(int16 obj) const { - for (uint16 i = 1; i <= _numWalkOffs; ++i) { - if (_walkOffData[i].entryObj == obj) { - return &_walkOffData[i]; - } - } - return NULL; -} - -void Logic::joeWalk(JoeWalkMode walking) { - _joe.walk = walking; - // Do this so that Input doesn't need to know the walk value - _vm->input()->dialogueRunning(JWM_SPEAK == walking); -} - -int16 Logic::gameState(int index) const { - assert(index >= 0 && index < GAME_STATE_COUNT); - return _gameState[index]; -} - -void Logic::gameState(int index, int16 newValue) { - assert(index >= 0 && index < GAME_STATE_COUNT); - debug(8, "Logic::gameState() [%d] = %d", index, newValue); - _gameState[index] = newValue; -} - -const char *Logic::roomName(uint16 roomNum) const { - assert(roomNum >= 1 && roomNum <= _numRooms); - return _roomName[roomNum].c_str(); -} - -const char *Logic::objectName(uint16 objNum) const { - assert(objNum >= 1 && objNum <= _numNames); - return _objName[objNum].c_str(); -} - -const char *Logic::objectTextualDescription(uint16 objNum) const { - assert(objNum >= 1 && objNum <= _numDescriptions); - return _objDescription[objNum].c_str(); -} - -const char *Logic::joeResponse(int i) const { - assert(i >= 1 && i <= JOE_RESPONSE_MAX); - return _joeResponse[i].c_str(); -} - -const char *Logic::verbName(Verb v) const { - assert(v >= 0 && v <= 12); - return _verbName[v].c_str(); -} - -void Logic::eraseRoom() { - _vm->bankMan()->eraseFrames(false); - _vm->bankMan()->close(15); - _vm->bankMan()->close(11); - _vm->bankMan()->close(10); - _vm->bankMan()->close(12); - - _vm->display()->palFadeOut(_currentRoom); - - // invalidates all persons animations - _vm->graphics()->clearPersonFrames(); - _vm->graphics()->eraseAllAnims(); - - uint16 cur = _roomData[_oldRoom] + 1; - uint16 last = _roomData[_oldRoom + 1]; - for (; cur <= last; ++cur) { - ObjectData *pod = &_objectData[cur]; - if (pod->name == 0) { - // object has been deleted, invalidate image - pod->image = 0; - } else if (pod->image > -4000 && pod->image <= -10) { - if (_graphicData[ABS(pod->image + 10)].lastFrame == 0) { - // static Bob - pod->image = -1; - } else { - // animated Bob - pod->image = -2; - } - } - } -} - -void Logic::setupRoom(const char *room, int comPanel, bool inCutaway) { - // load backdrop image, init dynalum, setup colors - _vm->display()->setupNewRoom(room, _currentRoom); - - // setup graphics to enter fullscreen/panel mode - _vm->display()->screenMode(comPanel, inCutaway); - - _vm->grid()->setupNewRoom(_currentRoom, _roomData[_currentRoom]); - - int16 furn[9]; - uint16 furnTot = 0; - for (uint16 i = 1; i <= _numFurniture; ++i) { - if (_furnitureData[i].room == _currentRoom) { - ++furnTot; - furn[furnTot] = _furnitureData[i].objNum; - } - } - _vm->graphics()->setupNewRoom(room, _currentRoom, furn, furnTot); - - _vm->display()->forceFullRefresh(); -} - -void Logic::displayRoom(uint16 room, RoomDisplayMode mode, uint16 scale, int comPanel, bool inCutaway) { - debug(6, "Logic::displayRoom(%d, %d, %d, %d, %d)", room, mode, scale, comPanel, inCutaway); - - eraseRoom(); - - if (_credits) - _credits->nextRoom(); - - setupRoom(roomName(room), comPanel, inCutaway); - if (mode != RDM_FADE_NOJOE) { - setupJoeInRoom(mode != RDM_FADE_JOE_XY, scale); - } - if (mode != RDM_NOFADE_JOE) { - _vm->update(); - BobSlot *joe = _vm->graphics()->bob(0); - _vm->display()->palFadeIn(_currentRoom, joe->active, joe->x, joe->y); - } - if (mode != RDM_FADE_NOJOE && joeX() != 0 && joeY() != 0) { - int16 jx = joeX(); - int16 jy = joeY(); - joePos(0, 0); - _vm->walk()->moveJoe(0, jx, jy, inCutaway); - } -} - -ActorData *Logic::findActor(uint16 noun, const char *name) const { - uint16 obj = currentRoomData() + noun; - int16 img = objectData(obj)->image; - if (img != -3 && img != -4) { - warning("Logic::findActor() - Object %d is not a person", obj); - return NULL; - } - - // search Bob number for the person - uint16 bobNum = findPersonNumber(obj, _currentRoom); - - // search for a matching actor - if (bobNum > 0) { - for (uint16 i = 1; i <= _numActors; ++i) { - ActorData *pad = &_actorData[i]; - if (pad->room == _currentRoom && gameState(pad->gsSlot) == pad->gsValue) { - if (bobNum == pad->bobNum || (name && _aName[pad->name] == name)) { - return pad; - } - } - } - } - return NULL; -} - -bool Logic::initPerson(uint16 noun, const char *actorName, bool loadBank, Person *pp) { - const ActorData *pad = findActor(noun, actorName); - if (pad != NULL) { - pp->actor = pad; - pp->name = _aName[pad->name].c_str(); - if (pad->anim != 0) { - pp->anim = _aAnim[pad->anim].c_str(); - } else { - pp->anim = NULL; - } - if (loadBank && pad->file != 0) { - _vm->bankMan()->load(_aFile[pad->file].c_str(), pad->bankNum); - // if there is no valid actor file (ie pad->file is 0), the person - // data is already loaded as it is included in objects room bank (.bbk) - } - pp->bobFrame = 31 + pp->actor->bobNum; - } - return pad != NULL; -} - -uint16 Logic::findPersonNumber(uint16 obj, uint16 room) const { - uint16 num = 0; - for (uint16 i = _roomData[room] + 1; i <= obj; ++i) { - int16 img = _objectData[i].image; - if (img == -3 || img == -4) { - ++num; - } - } - return num; -} - -void Logic::loadJoeBanks(const char *animBank, const char *standBank) { - _vm->bankMan()->load(animBank, 13); - for (int i = 11; i < 31; ++i) { - _vm->bankMan()->unpack(i - 10, i, 13); - } - _vm->bankMan()->close(13); - - _vm->bankMan()->load(standBank, 7); - _vm->bankMan()->unpack(1, 35, 7); - _vm->bankMan()->unpack(3, 36, 7); - _vm->bankMan()->unpack(5, 37, 7); -} - -void Logic::setupJoe() { - loadJoeBanks("joe_a.BBK", "joe_b.BBK"); - joePrevFacing(DIR_FRONT); - joeFacing(DIR_FRONT); -} - -void Logic::setupJoeInRoom(bool autoPosition, uint16 scale) { - debug(9, "Logic::setupJoeInRoom(%d, %d) joe.x=%d joe.y=%d", autoPosition, scale, _joe.x, _joe.y); - - int16 oldx, oldy; - if (!autoPosition || joeX() != 0 || joeY() != 0) { - oldx = joeX(); - oldy = joeY(); - joePos(0, 0); - } else { - const ObjectData *pod = objectData(_entryObj); - // find the walk off point for the entry object and make - // Joe walking to that point - const WalkOffData *pwo = walkOffPointForObject(_entryObj); - if (pwo != NULL) { - oldx = pwo->x; - oldy = pwo->y; - // entryObj has a walk off point, then walk from there to object x,y - joePos(pod->x, pod->y); - } else { - // no walk off point, use object position - oldx = pod->x; - oldy = pod->y; - joePos(0, 0); - } - } - - debug(6, "Logic::setupJoeInRoom() - oldx=%d, oldy=%d scale=%d", oldx, oldy, scale); - - if (scale > 0 && scale < 100) { - joeScale(scale); - } else { - uint16 a = _vm->grid()->findAreaForPos(GS_ROOM, oldx, oldy); - if (a > 0) { - joeScale(_vm->grid()->area(_currentRoom, a)->calcScale(oldy)); - } else { - joeScale(100); - } - } - - if (joeCutFacing() > 0) { - joeFacing(joeCutFacing()); - joeCutFacing(0); - } else { - // check to see which way Joe entered room - const ObjectData *pod = objectData(_entryObj); - switch (State::findDirection(pod->state)) { - case DIR_BACK: - joeFacing(DIR_FRONT); - break; - case DIR_FRONT: - joeFacing(DIR_BACK); - break; - case DIR_LEFT: - joeFacing(DIR_RIGHT); - break; - case DIR_RIGHT: - joeFacing(DIR_LEFT); - break; - } - } - joePrevFacing(joeFacing()); - - BobSlot *pbs = _vm->graphics()->bob(0); - pbs->scale = joeScale(); - - if (_currentRoom == 108) { - _vm->graphics()->putCameraOnBob(-1); - _vm->bankMan()->load("joe_e.act", 7); - _vm->bankMan()->unpack(2, 31, 7); - - _vm->display()->horizontalScroll(320); - - joeFacing(DIR_RIGHT); - joeCutFacing(DIR_RIGHT); - joePrevFacing(DIR_RIGHT); - } - - joeFace(); - pbs->curPos(oldx, oldy); - pbs->frameNum = 31; -} - -uint16 Logic::joeFace() { - debug(9, "Logic::joeFace() - curFace = %d, prevFace = %d", _joe.facing, _joe.prevFacing); - BobSlot *pbs = _vm->graphics()->bob(0); - uint16 frame; - if (_currentRoom == 108) { - frame = 1; - } else { - frame = 35; - if (joeFacing() == DIR_FRONT) { - if (joePrevFacing() == DIR_BACK) { - pbs->frameNum = 35; - _vm->update(); - } - frame = 36; - } else if (joeFacing() == DIR_BACK) { - if (joePrevFacing() == DIR_FRONT) { - pbs->frameNum = 35; - _vm->update(); - } - frame = 37; - } else if ((joeFacing() == DIR_LEFT && joePrevFacing() == DIR_RIGHT) - || (joeFacing() == DIR_RIGHT && joePrevFacing() == DIR_LEFT)) { - pbs->frameNum = 36; - _vm->update(); - } - pbs->frameNum = frame; - pbs->scale = joeScale(); - pbs->xflip = (joeFacing() == DIR_LEFT); - _vm->update(); - joePrevFacing(joeFacing()); - switch (frame) { - case 35: - frame = 1; - break; - case 36: - frame = 3; - break; - case 37: - frame = 5; - break; - } - } - pbs->frameNum = 31; - _vm->bankMan()->unpack(frame, pbs->frameNum, 7); - return frame; -} - -void Logic::joeGrab(int16 grabState) { - uint16 frame = 0; - BobSlot *bobJoe = _vm->graphics()->bob(0); - - switch (grabState) { - case STATE_GRAB_NONE: - break; - case STATE_GRAB_MID: - if (joeFacing() == DIR_BACK) { - frame = 6; - } else if (joeFacing() == DIR_FRONT) { - frame = 4; - } else { - frame = 2; - } - break; - case STATE_GRAB_DOWN: - if (joeFacing() == DIR_BACK) { - frame = 9; - } else { - frame = 8; - } - break; - case STATE_GRAB_UP: - // turn back - _vm->bankMan()->unpack(5, 31, 7); - bobJoe->xflip = (joeFacing() == DIR_LEFT); - bobJoe->scale = joeScale(); - _vm->update(); - // grab up - _vm->bankMan()->unpack(7, 31, 7); - bobJoe->xflip = (joeFacing() == DIR_LEFT); - bobJoe->scale = joeScale(); - _vm->update(); - // turn back - frame = 7; - break; - } - - if (frame != 0) { - _vm->bankMan()->unpack(frame, 31, 7); - bobJoe->xflip = (joeFacing() == DIR_LEFT); - bobJoe->scale = joeScale(); - _vm->update(); - - // extra delay for grab down - if (grabState == STATE_GRAB_DOWN) { - _vm->update(); - _vm->update(); - } - } -} - -void Logic::joeUseDress(bool showCut) { - if (showCut) { - joeFacing(DIR_FRONT); - joeFace(); - if (gameState(VAR_JOE_DRESSING_MODE) == 0) { - playCutaway("cdres.CUT"); - inventoryInsertItem(ITEM_CLOTHES); - } else { - playCutaway("cudrs.CUT"); - } - } - _vm->display()->palSetJoeDress(); - loadJoeBanks("JoeD_A.BBK", "JoeD_B.BBK"); - inventoryDeleteItem(ITEM_DRESS); - gameState(VAR_JOE_DRESSING_MODE, 2); -} - -void Logic::joeUseClothes(bool showCut) { - if (showCut) { - joeFacing(DIR_FRONT); - joeFace(); - playCutaway("cdclo.CUT"); - inventoryInsertItem(ITEM_DRESS); - } - _vm->display()->palSetJoeNormal(); - loadJoeBanks("Joe_A.BBK", "Joe_B.BBK"); - inventoryDeleteItem(ITEM_CLOTHES); - gameState(VAR_JOE_DRESSING_MODE, 0); -} - -void Logic::joeUseUnderwear() { - _vm->display()->palSetJoeNormal(); - loadJoeBanks("JoeU_A.BBK", "JoeU_B.BBK"); - gameState(VAR_JOE_DRESSING_MODE, 1); -} - -void Logic::makePersonSpeak(const char *sentence, Person *person, const char *voiceFilePrefix) { - _vm->command()->clear(false); - Talk::speak(sentence, person, voiceFilePrefix, _vm); -} - -void Logic::startDialogue(const char *dlgFile, int personInRoom, char *cutaway) { - ObjectData *data = objectData(_roomData[_currentRoom] + personInRoom); - if (data->name > 0 && data->entryObj <= 0) { - if (State::findTalk(data->state) == STATE_TALK_MUTE) { - // 'I can't talk to that' - makeJoeSpeak(24 + _vm->randomizer.getRandomNumber(2)); - } else { - char cutawayFile[20]; - if (cutaway == NULL) { - cutaway = cutawayFile; - } - _vm->display()->fullscreen(true); - Talk::talk(dlgFile, personInRoom, cutaway, _vm); - if (!cutaway[0]) { - _vm->display()->fullscreen(false); - } - } - } -} - -void Logic::playCutaway(const char *cutFile, char *next) { - char nextFile[20]; - if (next == NULL) { - next = nextFile; - } - _vm->display()->clearTexts(CmdText::COMMAND_Y_POS, CmdText::COMMAND_Y_POS); - Cutaway::run(cutFile, next, _vm); -} - -void Logic::makeJoeSpeak(uint16 descNum, bool objectType) { - const char *text = objectType ? _objDescription[descNum].c_str() : _joeResponse[descNum].c_str(); - if (objectType) { - descNum += JOE_RESPONSE_MAX; - } - char descFilePrefix[10]; - sprintf(descFilePrefix, "JOE%04i", descNum); - makePersonSpeak(text, NULL, descFilePrefix); -} - -uint16 Logic::findInventoryItem(int invSlot) const { - // queen.c l.3894-3898 - if (invSlot >= 0 && invSlot < 4) { - return _inventoryItem[invSlot]; - } - return 0; -} - -void Logic::inventorySetup() { - _vm->bankMan()->load("objects.BBK", 14); - if (_vm->resource()->isInterview()) { - _inventoryItem[0] = 1; - _inventoryItem[1] = 2; - _inventoryItem[2] = 3; - _inventoryItem[3] = 4; - } else { - _inventoryItem[0] = ITEM_BAT; - _inventoryItem[1] = ITEM_JOURNAL; - _inventoryItem[2] = ITEM_NONE; - _inventoryItem[3] = ITEM_NONE; - } -} - -void Logic::inventoryRefresh() { - uint16 x = 182; - for (int i = 0; i < 4; ++i) { - uint16 itemNum = _inventoryItem[i]; - if (itemNum != 0) { - // 1st object in inventory uses frame 9, - // whereas 2nd, 3rd and 4th uses frame 8 - uint16 dstFrame = (itemNum != 0) ? 8 : 9; - // unpack frame for object and draw it - _vm->bankMan()->unpack(_itemData[itemNum].frame, dstFrame, 14); - _vm->graphics()->drawInventoryItem(dstFrame, x, 14); - } else { - // no object, clear the panel - _vm->graphics()->drawInventoryItem(0, x, 14); - } - x += 35; - } -} - -int16 Logic::previousInventoryItem(int16 first) const { - int i; - for (i = first - 1; i >= 1; i--) - if (_itemData[i].name > 0) - return i; - for (i = _numItems; i > first; i--) - if (_itemData[i].name > 0) - return i; - - return 0; //nothing found -} - -int16 Logic::nextInventoryItem(int16 first) const { - int i; - for (i = first + 1; i < _numItems; i++) - if (_itemData[i].name > 0) - return i; - for (i = 1; i < first; i++) - if (_itemData[i].name > 0) - return i; - - return 0; //nothing found -} - -void Logic::removeDuplicateItems() { - for (int i = 0; i < 4; i++) - for (int j = i + 1; j < 4; j++) - if (_inventoryItem[i] == _inventoryItem[j]) - _inventoryItem[j] = ITEM_NONE; -} - -uint16 Logic::numItemsInventory() const { - uint16 count = 0; - for (int i = 1; i < _numItems; i++) - if (_itemData[i].name > 0) - count++; - - return count; -} - -void Logic::inventoryInsertItem(uint16 itemNum, bool refresh) { - int16 item = _inventoryItem[0] = (int16)itemNum; - _itemData[itemNum].name = ABS(_itemData[itemNum].name); //set visible - for (int i = 1; i < 4; i++) { - item = nextInventoryItem(item); - _inventoryItem[i] = item; - removeDuplicateItems(); - } - - if (refresh) - inventoryRefresh(); -} - -void Logic::inventoryDeleteItem(uint16 itemNum, bool refresh) { - int16 item = (int16)itemNum; - _itemData[itemNum].name = -ABS(_itemData[itemNum].name); //set invisible - for (int i = 0; i < 4; i++) { - item = nextInventoryItem(item); - _inventoryItem[i] = item; - removeDuplicateItems(); - } - - if (refresh) - inventoryRefresh(); -} - -void Logic::inventoryScroll(uint16 count, bool up) { - if (!(numItemsInventory() > 4)) - return; - while (count--) { - if (up) { - for (int i = 3; i > 0; i--) - _inventoryItem[i] = _inventoryItem[i - 1]; - _inventoryItem[0] = previousInventoryItem(_inventoryItem[0]); - } else { - for (int i = 0; i < 3; i++) - _inventoryItem[i] = _inventoryItem[i + 1]; - _inventoryItem[3] = nextInventoryItem(_inventoryItem[3]); - } - } - - inventoryRefresh(); -} - -void Logic::removeHotelItemsFromInventory() { - if (currentRoom() == 1 && gameState(VAR_HOTEL_ITEMS_REMOVED) == 0) { - inventoryDeleteItem(ITEM_CROWBAR, false); - inventoryDeleteItem(ITEM_DRESS, false); - inventoryDeleteItem(ITEM_CLOTHES, false); - inventoryDeleteItem(ITEM_HAY, false); - inventoryDeleteItem(ITEM_OIL, false); - inventoryDeleteItem(ITEM_CHICKEN, false); - gameState(VAR_HOTEL_ITEMS_REMOVED, 1); - inventoryRefresh(); - } -} - -void Logic::objectCopy(int dummyObjectIndex, int realObjectIndex) { - // copy data from dummy object to real object, if COPY_FROM object - // images are greater than COPY_TO Object images then swap the objects around. - - ObjectData *dummyObject = objectData(dummyObjectIndex); - ObjectData *realObject = objectData(realObjectIndex); - - int fromState = (dummyObject->name < 0) ? -1 : 0; - - int frameCountReal = 1; - int frameCountDummy = 1; - - int graphic = realObject->image; - if (graphic > 0) { - if (graphic > 5000) - graphic -= 5000; - - GraphicData *data = graphicData(graphic); - - if (data->lastFrame > 0) - frameCountReal = data->lastFrame - data->firstFrame + 1; - - graphic = dummyObject->image; - if (graphic > 0) { - if (graphic > 5000) - graphic -= 5000; - - data = graphicData(graphic); - - if (data->lastFrame > 0) - frameCountDummy = data->lastFrame - data->firstFrame + 1; - } - } - - ObjectData temp = *realObject; - *realObject = *dummyObject; - - if (frameCountDummy > frameCountReal) - *dummyObject = temp; - - realObject->name = ABS(realObject->name); - - if (fromState == -1) - dummyObject->name = -ABS(dummyObject->name); - - for (int i = 1; i <= _numWalkOffs; i++) { - WalkOffData *walkOff = &_walkOffData[i]; - if (walkOff->entryObj == (int16)dummyObjectIndex) { - walkOff->entryObj = (int16)realObjectIndex; - break; - } - } -} - -void Logic::handleSpecialArea(Direction facing, uint16 areaNum, uint16 walkDataNum) { - // queen.c l.2838-2911 - debug(9, "handleSpecialArea(%d, %d, %d)\n", facing, areaNum, walkDataNum); - - // Stop animating Joe - _vm->graphics()->bob(0)->animating = false; - - // Make Joe face the right direction - joeFacing(facing); - joeFace(); - - _newRoom = 0; - _entryObj = 0; - - char nextCut[20]; - memset(nextCut, 0, sizeof(nextCut)); - - switch (_currentRoom) { - case ROOM_JUNGLE_BRIDGE: - makeJoeSpeak(16); - break; - case ROOM_JUNGLE_GORILLA_1: - playCutaway("c6c.CUT", nextCut); - break; - case ROOM_JUNGLE_GORILLA_2: - playCutaway("c14b.CUT", nextCut); - break; - case ROOM_AMAZON_ENTRANCE: - if (areaNum == 3) { - playCutaway("c16a.CUT", nextCut); - } - break; - case ROOM_AMAZON_HIDEOUT: - if (walkDataNum == 4) { - playCutaway("c17a.CUT", nextCut); - } else if (walkDataNum == 2) { - playCutaway("c17b.CUT", nextCut); - } - break; - case ROOM_FLODA_OUTSIDE: - playCutaway("c22a.CUT", nextCut); - break; - case ROOM_FLODA_KITCHEN: - playCutaway("c26b.CUT", nextCut); - break; - case ROOM_FLODA_KLUNK: - playCutaway("c30a.CUT", nextCut); - break; - case ROOM_FLODA_HENRY: - playCutaway("c32c.CUT", nextCut); - break; - case ROOM_TEMPLE_ZOMBIES: - if (areaNum == 6) { - switch (gameState(VAR_BYPASS_ZOMBIES)) { - case 0: - playCutaway("c50d.CUT", nextCut); - while (nextCut[0] != '\0') { - playCutaway(nextCut, nextCut); - } - gameState(VAR_BYPASS_ZOMBIES, 1); - break; - case 1: - playCutaway("c50h.CUT", nextCut); - break; - } - } - break; - case ROOM_TEMPLE_SNAKE: - playCutaway("c53b.CUT", nextCut); - break; - case ROOM_TEMPLE_LIZARD_LASER: - makeJoeSpeak(19); - break; - case ROOM_HOTEL_DOWNSTAIRS: - makeJoeSpeak(21); - break; - case ROOM_HOTEL_LOBBY: - switch (gameState(VAR_HOTEL_ESCAPE_STATE)) { - case 0: - playCutaway("c73a.CUT"); - joeUseUnderwear(); - joeFace(); - gameState(VAR_HOTEL_ESCAPE_STATE, 1); - break; - case 1: - playCutaway("c73b.CUT"); - gameState(VAR_HOTEL_ESCAPE_STATE, 2); - break; - case 2: - playCutaway("c73c.CUT"); - break; - } - break; - case ROOM_TEMPLE_MAZE_5: - if (areaNum == 7) { - makeJoeSpeak(17); - } - break; - case ROOM_TEMPLE_MAZE_6: - if (areaNum == 5 && gameState(187) == 0) { - playCutaway("c101b.CUT", nextCut); - } - break; - case ROOM_FLODA_FRONTDESK: - if (areaNum == 3) { - switch (gameState(VAR_BYPASS_FLODA_RECEPTIONIST)) { - case 0: - playCutaway("c103b.CUT", nextCut); - gameState(VAR_BYPASS_FLODA_RECEPTIONIST, 1); - break; - case 1: - playCutaway("c103e.CUT", nextCut); - break; - } - } - break; - } - - while (strlen(nextCut) > 4 && - scumm_stricmp(nextCut + strlen(nextCut) - 4, ".cut") == 0) { - playCutaway(nextCut, nextCut); - } -} - -void Logic::handlePinnacleRoom() { - // camera does not follow Joe anymore - _vm->graphics()->putCameraOnBob(-1); - displayRoom(ROOM_JUNGLE_PINNACLE, RDM_NOFADE_JOE, 100, 2, true); - - BobSlot *joe = _vm->graphics()->bob(6); - BobSlot *piton = _vm->graphics()->bob(7); - - // set scrolling value to mouse position to avoid glitch - _vm->display()->horizontalScroll(_vm->input()->mousePosX()); - - joe->x = piton->x = 3 * _vm->input()->mousePosX() / 4 + 200; - joe->frameNum = _vm->input()->mousePosX() / 36 + 45; - - // bobs have been unpacked from animating objects, we don't need them - // to animate anymore ; so turn animation off - joe->animating = piton->animating = false; - - _vm->update(); - _vm->display()->palFadeIn(ROOM_JUNGLE_PINNACLE, joe->active, joe->x, joe->y); - - _entryObj = 0; - uint16 prevObj = 0; - CmdText cmdText((_vm->resource()->getLanguage() == HEBREW), 5, _vm); - cmdText.setVerb(VERB_WALK_TO); - while (_vm->input()->mouseButton() == 0 || _entryObj == 0) { - - _vm->update(); - int mx = _vm->input()->mousePosX(); - int my = _vm->input()->mousePosY(); - - // update screen scrolling - _vm->display()->horizontalScroll(mx); - - // update bobs position / frame - joe->x = piton->x = 3 * mx / 4 + 200; - joe->frameNum = mx / 36 + 45; - - _vm->display()->clearTexts(5, 5); - - uint16 curObj = _vm->grid()->findObjectUnderCursor(mx, my); - if (curObj != 0 && curObj != prevObj) { - _entryObj = 0; - curObj += currentRoomData(); // global object number - ObjectData *objData = objectData(curObj); - if (objData->name > 0) { - _entryObj = objData->entryObj; - cmdText.displayTemp(INK_PINNACLE_ROOM, objectName(objData->name), true); - } - prevObj = curObj; - } - } - _vm->input()->clearMouseButton(); - - _newRoom = objectData(_entryObj)->room; - - // FIXME - only a few commands can be triggered from this room : - // piton -> crash : 0x216 (obj1=0x2a, song=3) - // piton -> floda : 0x217 (obj1=0x29, song=16) - // piton -> bob : 0x219 (obj1=0x2f, song=6) - // piton -> embark : 0x218 (obj1=0x2c, song=7) - // piton -> jungle : 0x20B (obj1=0x2b, song=3) - // piton -> amazon : 0x21A (obj1=0x30, song=3) - // - // Because none of these update objects/areas/gamestate, the EXECUTE_ACTION() - // call, as the original does, is useless. All we have to do is the playsong - // call (all songs have the PLAY_BEFORE type). This way we could get rid of - // the hack described in execute.c l.334-339. - struct { - uint16 obj; - int16 song; - } cmds[] = { - { 0x2A, 3 }, - { 0x29, 16 }, - { 0x2F, 6 }, - { 0x2C, 7 }, - { 0x2B, 3 }, - { 0x30, 3 } - }; - for (int i = 0; i < ARRAYSIZE(cmds); ++i) { - if (cmds[i].obj == prevObj) { - _vm->sound()->playSong(cmds[i].song); - break; - } - } - - joe->active = piton->active = false; - _vm->display()->clearTexts(5, 5); - - // camera follows Joe again - _vm->graphics()->putCameraOnBob(0); - - _vm->display()->palFadeOut(ROOM_JUNGLE_PINNACLE); -} - -void Logic::update() { - if (_credits) - _credits->update(); - - if (_vm->debugger()->flags() & Debugger::DF_DRAW_AREAS) { - _vm->grid()->drawZones(); - } -} - -void Logic::saveState(byte *&ptr) { - uint16 i; - for (i = 0; i < 4; i++) { - WRITE_BE_UINT16(ptr, _inventoryItem[i]); ptr += 2; - } - - WRITE_BE_UINT16(ptr, _vm->graphics()->bob(0)->x); ptr += 2; - WRITE_BE_UINT16(ptr, _vm->graphics()->bob(0)->y); ptr += 2; - - WRITE_BE_UINT16(ptr, _currentRoom); ptr += 2; - - for (i = 1; i <= _numObjects; i++) - _objectData[i].writeToBE(ptr); - - for (i = 1; i <= _numItems; i++) - _itemData[i].writeToBE(ptr); - - for (i = 0; i < GAME_STATE_COUNT; i++) { - WRITE_BE_UINT16(ptr, _gameState[i]); ptr += 2; - } - - for (i = 0; i < TALK_SELECTED_COUNT; i++) - _talkSelected[i].writeToBE(ptr); - - for (i = 1; i <= _numWalkOffs; i++) - _walkOffData[i].writeToBE(ptr); - - WRITE_BE_UINT16(ptr, _joe.facing); ptr += 2; - - // V1 - WRITE_BE_UINT16(ptr, _puzzleAttemptCount); ptr += 2; - for (i = 1; i <= _numObjDesc; i++) - _objectDescription[i].writeToBE(ptr); -} - -void Logic::loadState(uint32 ver, byte *&ptr) { - uint16 i; - for (i = 0; i < 4; i++) { - _inventoryItem[i] = (int16)READ_BE_INT16(ptr); ptr += 2; - } - - _joe.x = (int16)READ_BE_INT16(ptr); ptr += 2; - _joe.y = (int16)READ_BE_INT16(ptr); ptr += 2; - - _currentRoom = READ_BE_UINT16(ptr); ptr += 2; - - for (i = 1; i <= _numObjects; i++) - _objectData[i].readFromBE(ptr); - - for (i = 1; i <= _numItems; i++) - _itemData[i].readFromBE(ptr); - - for (i = 0; i < GAME_STATE_COUNT; i++) { - _gameState[i] = (int16)READ_BE_INT16(ptr); ptr += 2; - } - - for (i = 0; i < TALK_SELECTED_COUNT; i++) - _talkSelected[i].readFromBE(ptr); - - for (i = 1; i <= _numWalkOffs; i++) - _walkOffData[i].readFromBE(ptr); - - _joe.facing = READ_BE_UINT16(ptr); ptr += 2; - - if (ver >= 1) { - _puzzleAttemptCount = READ_BE_UINT16(ptr); ptr += 2; - - for (i = 1; i <= _numObjDesc; i++) - _objectDescription[i].readFromBE(ptr); - } -} - -void Logic::setupRestoredGame() { - _vm->sound()->playLastSong(); - - switch (gameState(VAR_JOE_DRESSING_MODE)) { - case 0: - _vm->display()->palSetJoeNormal(); - loadJoeBanks("Joe_A.BBK", "Joe_B.BBK"); - break; - case 1: - _vm->display()->palSetJoeNormal(); - loadJoeBanks("JoeU_A.BBK", "JoeU_B.BBK"); - break; - case 2: - _vm->display()->palSetJoeDress(); - loadJoeBanks("JoeD_A.BBK", "JoeD_B.BBK"); - break; - } - - BobSlot *pbs = _vm->graphics()->bob(0); - pbs->xflip = (joeFacing() == DIR_LEFT); - joePrevFacing(joeFacing()); - joeCutFacing(joeFacing()); - switch (joeFacing()) { - case DIR_FRONT: - pbs->frameNum = 36; - _vm->bankMan()->unpack(3, 31, 7); - break; - case DIR_BACK: - pbs->frameNum = 37; - _vm->bankMan()->unpack(5, 31, 7); - break; - default: - pbs->frameNum = 35; - _vm->bankMan()->unpack(1, 31, 7); - break; - } - - _oldRoom = 0; - _newRoom = _currentRoom; - _entryObj = 0; - - if (_vm->bam()->_flag != BamScene::F_STOP) { - _vm->bam()->prepareAnimation(); - } - - inventoryRefresh(); -} - -void Logic::sceneStart() { - debug(6, "[Logic::sceneStart] _scene = %i", _scene); - _scene++; - - _vm->display()->showMouseCursor(false); - - if (1 == _scene) { - _vm->display()->palGreyPanel(); - } - - _vm->update(); -} - -void Logic::sceneStop() { - debug(6, "[Logic::sceneStop] _scene = %i", _scene); - _scene--; - - if (_scene > 0) - return; - - _vm->display()->palSetAllDirty(); - _vm->display()->showMouseCursor(true); - _vm->grid()->setupPanel(); -} - -void Logic::changeRoom() { - if (!preChangeRoom()) - displayRoom(currentRoom(), RDM_FADE_JOE, 100, 1, false); - _vm->display()->showMouseCursor(true); -} - -void Logic::executeSpecialMove(uint16 sm) { - debug(6, "Special move: %d", sm); - if (!handleSpecialMove(sm)) - warning("unhandled / invalid special move : %d", sm); -} - -void Logic::asmMakeJoeUseDress() { - joeUseDress(false); -} - -void Logic::asmMakeJoeUseNormalClothes() { - joeUseClothes(false); -} - -void Logic::asmMakeJoeUseUnderwear() { - joeUseUnderwear(); -} - -void Logic::asmSwitchToDressPalette() { - _vm->display()->palSetJoeDress(); -} - -void Logic::asmSwitchToNormalPalette() { - _vm->display()->palSetJoeNormal(); -} - -void Logic::asmStartCarAnimation() { - _vm->bam()->_flag = BamScene::F_PLAY; - _vm->bam()->prepareAnimation(); -} - -void Logic::asmStopCarAnimation() { - _vm->bam()->_flag = BamScene::F_STOP; - _vm->graphics()->bob(findBob(594))->active = false; // oil object - _vm->graphics()->bob(7)->active = false; // gun shots -} - -void Logic::asmStartFightAnimation() { - _vm->bam()->_flag = BamScene::F_PLAY; - _vm->bam()->prepareAnimation(); - gameState(148, 1); -} - -void Logic::asmWaitForFrankPosition() { - _vm->bam()->_flag = BamScene::F_REQ_STOP; - while (_vm->bam()->_flag != BamScene::F_STOP) { - _vm->update(); - } -} - -void Logic::asmMakeFrankGrowing() { - _vm->bankMan()->unpack(1, 38, 15); - BobSlot *bobFrank = _vm->graphics()->bob(5); - bobFrank->frameNum = 38; - bobFrank->curPos(160, 200); - - int i; - for (i = 10; i <= 100; i += 4) { - bobFrank->scale = i; - _vm->update(); - } - for (i = 0; i <= 20; ++i) { - _vm->update(); - } - - objectData(521)->name = ABS(objectData(521)->name); // Dinoray - objectData(526)->name = ABS(objectData(526)->name); // Frank obj - objectData(522)->name = -ABS(objectData(522)->name); // TMPD object off - objectData(525)->name = -ABS(objectData(525)->name); // Floda guards off - objectData(523)->name = -ABS(objectData(523)->name); // Sparky object off - gameState(157, 1); // No more Ironstein -} - -void Logic::asmMakeRobotGrowing() { - _vm->bankMan()->unpack(1, 38, 15); - BobSlot *bobRobot = _vm->graphics()->bob(5); - bobRobot->frameNum = 38; - bobRobot->curPos(160, 200); - - int i; - for (i = 10; i <= 100; i += 4) { - bobRobot->scale = i; - _vm->update(); - } - for (i = 0; i <= 20; ++i) { - _vm->update(); - } - - objectData(524)->name = -ABS(objectData(524)->name); // Azura object off - objectData(526)->name = -ABS(objectData(526)->name); // Frank object off -} - -void Logic::asmShrinkRobot() { - int i; - BobSlot *robot = _vm->graphics()->bob(6); - for (i = 100; i >= 35; i -= 5) { - robot->scale = i; - _vm->update(); - } -} - -void Logic::asmEndGame() { - int n = 40; - while (n--) { - _vm->update(); - } - debug(0, "Game completed."); - _vm->quitGame(); -} - -void Logic::asmPutCameraOnDino() { - _vm->graphics()->putCameraOnBob(-1); - int16 scrollx = _vm->display()->horizontalScroll(); - while (scrollx < 320) { - scrollx += 16; - if (scrollx > 320) { - scrollx = 320; - } - _vm->display()->horizontalScroll(scrollx); - _vm->update(); - } - _vm->graphics()->putCameraOnBob(1); -} - -void Logic::asmPutCameraOnJoe() { - _vm->graphics()->putCameraOnBob(0); -} - -void Logic::asmAltIntroPanRight() { - _vm->graphics()->putCameraOnBob(-1); - _vm->input()->fastMode(true); - _vm->update(); - int16 scrollx = _vm->display()->horizontalScroll(); - while (scrollx < 285 && !_vm->input()->cutawayQuit()) { - ++scrollx; - if (scrollx > 285) { - scrollx = 285; - } - _vm->display()->horizontalScroll(scrollx); - _vm->update(); - } - _vm->input()->fastMode(false); -} - -void Logic::asmAltIntroPanLeft() { - _vm->graphics()->putCameraOnBob(-1); - _vm->input()->fastMode(true); - int16 scrollx = _vm->display()->horizontalScroll(); - while (scrollx > 0 && !_vm->input()->cutawayQuit()) { - scrollx -= 4; - if (scrollx < 0) { - scrollx = 0; - } - _vm->display()->horizontalScroll(scrollx); - _vm->update(); - } - _vm->input()->fastMode(false); -} - -void Logic::asmSetAzuraInLove() { - gameState(VAR_AZURA_IN_LOVE, 1); -} - -void Logic::asmPanRightFromJoe() { - _vm->graphics()->putCameraOnBob(-1); - int16 scrollx = _vm->display()->horizontalScroll(); - while (scrollx < 320) { - scrollx += 16; - if (scrollx > 320) { - scrollx = 320; - } - _vm->display()->horizontalScroll(scrollx); - _vm->update(); - } -} - -void Logic::asmSetLightsOff() { - _vm->display()->palCustomLightsOff(currentRoom()); -} - -void Logic::asmSetLightsOn() { - _vm->display()->palCustomLightsOn(currentRoom()); -} - -void Logic::asmSetManequinAreaOn() { - Area *a = _vm->grid()->area(ROOM_FLODA_FRONTDESK, 7); - a->mapNeighbours = ABS(a->mapNeighbours); -} - -void Logic::asmPanToJoe() { - int i = _vm->graphics()->bob(0)->x - 160; - if (i < 0) { - i = 0; - } else if (i > 320) { - i = 320; - } - _vm->graphics()->putCameraOnBob(-1); - int16 scrollx = _vm->display()->horizontalScroll(); - if (i < scrollx) { - while (scrollx > i) { - scrollx -= 16; - if (scrollx < i) { - scrollx = i; - } - _vm->display()->horizontalScroll(scrollx); - _vm->update(); - } - } else { - while (scrollx < i) { - scrollx += 16; - if (scrollx > i) { - scrollx = i; - } - _vm->display()->horizontalScroll(scrollx); - _vm->update(); - } - _vm->update(); - } - _vm->graphics()->putCameraOnBob(0); -} - -void Logic::asmTurnGuardOn() { - gameState(VAR_GUARDS_TURNED_ON, 1); -} - -void Logic::asmPanLeft320To144() { - _vm->graphics()->putCameraOnBob(-1); - int16 scrollx = _vm->display()->horizontalScroll(); - while (scrollx > 144) { - scrollx -= 8; - if (scrollx < 144) { - scrollx = 144; - } - _vm->display()->horizontalScroll(scrollx); - _vm->update(); - } -} - -void Logic::asmSmooch() { - _vm->graphics()->putCameraOnBob(-1); - BobSlot *bobAzura = _vm->graphics()->bob(5); - BobSlot *bobJoe = _vm->graphics()->bob(6); - int16 scrollx = _vm->display()->horizontalScroll(); - while (scrollx < 320) { - scrollx += 8; - _vm->display()->horizontalScroll(scrollx); - if (bobJoe->x - bobAzura->x > 128) { - bobAzura->x += 10; - bobJoe->x += 6; - } else { - bobAzura->x += 8; - bobJoe->x += 8; - } - _vm->update(); - } -} - -void Logic::asmMakeLightningHitPlane() { - _vm->graphics()->putCameraOnBob(-1); - short iy = 0, x, ydir = -1, j, k; - - BobSlot *planeBob = _vm->graphics()->bob(5); - BobSlot *lightningBob = _vm->graphics()->bob(20); - - planeBob->y = 135; - - planeBob->scale = 20; - - for (x = 660; x > 163; x -= 6) { - planeBob->x = x; - planeBob->y = 135 + iy; - - iy -= ydir; - if (iy < -9 || iy > 9) - ydir = -ydir; - - planeBob->scale++; - if (planeBob->scale > 100) - planeBob->scale = 100; - - int scrollX = x - 163; - if (scrollX > 320) - scrollX = 320; - _vm->display()->horizontalScroll(scrollX); - _vm->update(); - } - - planeBob->scale = 100; - _vm->display()->horizontalScroll(0); - - planeBob->x += 8; - planeBob->y += 6; - - lightningBob->x = 160; - lightningBob->y = 0; - - _vm->sound()->playSfx(currentRoomSfx(), false); - - _vm->bankMan()->unpack(18, lightningBob->frameNum, 15); - _vm->bankMan()->unpack(4, planeBob ->frameNum, 15); - - // Plane plunges into the jungle! - BobSlot *fireBob = _vm->graphics()->bob(6); - - fireBob->animating = true; - fireBob->x = planeBob->x; - fireBob->y = planeBob->y + 10; - - _vm->bankMan()->unpack(19, fireBob->frameNum, 15); - _vm->update(); - - k = 20; - j = 1; - - for (x = 163; x > -30; x -= 10) { - planeBob->y += 4; - fireBob->y += 4; - planeBob->x = fireBob->x = x; - - if (k < 40) { - _vm->bankMan()->unpack(j, planeBob->frameNum, 15); - _vm->bankMan()->unpack(k, fireBob ->frameNum, 15); - k++; - j++; - - if (j == 4) - j = 1; - } - - _vm->update(); - } - - _vm->graphics()->putCameraOnBob(0); -} - -void Logic::asmScaleBlimp() { - int16 z = 256; - BobSlot *bob = _vm->graphics()->bob(7); - int16 x = bob->x; - int16 y = bob->y; - while (bob->x > 150) { - bob->x = x * 256 / z + 150; - bob->y = y * 256 / z + 112; - bob->scale = 100 * 256 / z; - - ++z; - if (z % 6 == 0) { - --x; - } - - _vm->update(); - } -} - -void Logic::asmScaleEnding() { - _vm->graphics()->bob(7)->active = false; // Turn off blimp - BobSlot *b = _vm->graphics()->bob(20); - b->x = 160; - b->y = 100; - int i; - for (i = 5; i <= 100; i += 5) { - b->scale = i; - _vm->update(); - } - for (i = 0; i < 50; ++i) { - _vm->update(); - } - _vm->display()->palFadeOut(_currentRoom); -} - -void Logic::asmWaitForCarPosition() { - // Wait for car to reach correct position before pouring oil - while (_vm->bam()->_index != 60) { - _vm->update(); - } -} - -void Logic::asmShakeScreen() { - _vm->display()->shake(false); - _vm->update(); - _vm->display()->shake(true); - _vm->update(); -} - -void Logic::asmAttemptPuzzle() { - ++_puzzleAttemptCount; - if (_puzzleAttemptCount == 4) { - makeJoeSpeak(226, true); - _puzzleAttemptCount = 0; - } -} - -void Logic::asmScaleTitle() { - BobSlot *bob = _vm->graphics()->bob(5); - bob->animating = false; - bob->x = 161; - bob->y = 200; - bob->scale = 100; - - int i; - for (i = 5; i <= 100; i +=5) { - bob->scale = i; - bob->y -= 4; - _vm->update(); - } -} - -void Logic::asmPanRightToHugh() { - BobSlot *bob_thugA1 = _vm->graphics()->bob(20); - BobSlot *bob_thugA2 = _vm->graphics()->bob(21); - BobSlot *bob_thugA3 = _vm->graphics()->bob(22); - BobSlot *bob_hugh1 = _vm->graphics()->bob(1); - BobSlot *bob_hugh2 = _vm->graphics()->bob(23); - BobSlot *bob_hugh3 = _vm->graphics()->bob(24); - BobSlot *bob_thugB1 = _vm->graphics()->bob(25); - BobSlot *bob_thugB2 = _vm->graphics()->bob(26); - - _vm->graphics()->putCameraOnBob(-1); - _vm->input()->fastMode(true); - _vm->update(); - - // Adjust thug1 gun so it matches rest of body - bob_thugA1->x += 160 - 45; - bob_thugA2->x += 160; - bob_thugA3->x += 160; - - bob_hugh1->x += 160 * 2; - bob_hugh2->x += 160 * 2; - bob_hugh3->x += 160 * 2; - - bob_thugB1->x += 160 * 3; - bob_thugB2->x += 160 * 3; - - int horizontalScroll = 0; - while (horizontalScroll < 160 && !_vm->input()->cutawayQuit()) { - - horizontalScroll += 8; - if (horizontalScroll > 160) - horizontalScroll = 160; - - _vm->display()->horizontalScroll(horizontalScroll); - - bob_thugA1->x -= 16; - bob_thugA2->x -= 16; - bob_thugA3->x -= 16; - - bob_hugh1->x -= 24; - bob_hugh2->x -= 24; - bob_hugh3->x -= 24; - - bob_thugB1->x -= 32; - bob_thugB2->x -= 32; - - _vm->update(); - } - - _vm->input()->fastMode(false); -} - -void Logic::asmMakeWhiteFlash() { - _vm->display()->palCustomFlash(); -} - -void Logic::asmPanRightToJoeAndRita() { // cdint.cut - BobSlot *bob_box = _vm->graphics()->bob(20); - BobSlot *bob_beam = _vm->graphics()->bob(21); - BobSlot *bob_crate = _vm->graphics()->bob(22); - BobSlot *bob_clock = _vm->graphics()->bob(23); - BobSlot *bob_hands = _vm->graphics()->bob(24); - - _vm->graphics()->putCameraOnBob(-1); - _vm->input()->fastMode(true); - - _vm->update(); - - bob_box ->x += 280 * 2; - bob_beam ->x += 30; - bob_crate->x += 180 * 3; - - int horizontalScroll = _vm->display()->horizontalScroll(); - - while (horizontalScroll < 290 && !_vm->input()->cutawayQuit()) { - - ++horizontalScroll; - if (horizontalScroll > 290) - horizontalScroll = 290; - - _vm->display()->horizontalScroll(horizontalScroll); - - bob_box ->x -= 2; - bob_beam ->x -= 1; - bob_crate->x -= 3; - bob_clock->x -= 2; - bob_hands->x -= 2; - - _vm->update(); - } - _vm->input()->fastMode(false); -} - -void Logic::asmPanLeftToBomb() { - BobSlot *bob21 = _vm->graphics()->bob(21); - BobSlot *bob22 = _vm->graphics()->bob(22); - - _vm->graphics()->putCameraOnBob(-1); - _vm->input()->fastMode(true); - - int horizontalScroll = _vm->display()->horizontalScroll(); - - while ((horizontalScroll > 0 || bob21->x < 136) && !_vm->input()->cutawayQuit()) { - - horizontalScroll -= 5; - if (horizontalScroll < 0) - horizontalScroll = 0; - - _vm->display()->horizontalScroll(horizontalScroll); - - if (horizontalScroll < 272 && bob21->x < 136) - bob21->x += 2; - - bob22->x += 5; - - _vm->update(); - } - - _vm->input()->fastMode(false); -} - -void Logic::asmEndDemo() { - debug(0, "Flight of the Amazon Queen, released January 95."); - _vm->quitGame(); -} - -void Logic::asmInterviewIntro() { - // put camera on airship - _vm->graphics()->putCameraOnBob(5); - BobSlot *bas = _vm->graphics()->bob(5); - - bas->curPos(-30, 40); - - bas->move(700, 10, 3); - int scale = 450; - while (bas->moving && !_vm->input()->cutawayQuit()) { - bas->scale = 256 * 100 / scale; - --scale; - if (scale < 256) { - scale = 256; - } - _vm->update(); - } - - bas->scale = 90; - bas->xflip = true; - - bas->move(560, 25, 4); - while (bas->moving && !_vm->input()->cutawayQuit()) { - _vm->update(); - } - - bas->move(545, 65, 2); - while (bas->moving && !_vm->input()->cutawayQuit()) { - _vm->update(); - } - - bas->move(540, 75, 2); - while (bas->moving && !_vm->input()->cutawayQuit()) { - _vm->update(); - } - - // put camera on Joe - _vm->graphics()->putCameraOnBob(0); -} - -void Logic::asmEndInterview() { - debug(0, "Interactive Interview copyright (c) 1995, IBI."); - _vm->quitGame(); -} - -void Logic::startCredits(const char *filename) { - stopCredits(); - _credits = new Credits(_vm, filename); -} - -void Logic::stopCredits() { - if (_credits) { - _vm->display()->clearTexts(0, 199); - delete _credits; - _credits = NULL; - } -} - -void LogicDemo::useJournal() { - makePersonSpeak("This is a demo, so I can't load or save games*14", NULL, ""); -} - -bool LogicDemo::preChangeRoom() { - if (currentRoom() == FOTAQ_LOGO && gameState(VAR_INTRO_PLAYED) == 0) { - currentRoom(79); - displayRoom(currentRoom(), RDM_FADE_NOJOE, 100, 2, true); - playCutaway("clogo.cut"); - sceneReset(); - currentRoom(ROOM_HOTEL_LOBBY); - entryObj(584); - displayRoom(currentRoom(), RDM_FADE_JOE, 100, 2, true); - playCutaway("c70d.cut"); - gameState(VAR_INTRO_PLAYED, 1); - inventoryRefresh(); - return true; - } - return false; -} - -bool LogicDemo::handleSpecialMove(uint16 sm) { - switch (sm) { - case 4: - asmMakeJoeUseUnderwear(); - break; - case 5: - asmSwitchToDressPalette(); - break; - case 14: - asmEndDemo(); - break; - default: - return false; - } - return true; -} - -void LogicInterview::useJournal() { - // no-op -} - -bool LogicInterview::preChangeRoom() { - if (currentRoom() == 2 && gameState(2) == 0) { - currentRoom(6); - displayRoom(currentRoom(), RDM_FADE_NOJOE, 100, 2, true); - playCutaway("start.cut"); - gameState(2, 1); - inventoryRefresh(); - return true; - } - return false; -} - -bool LogicInterview::handleSpecialMove(uint16 sm) { - switch (sm) { - case 1: - asmInterviewIntro(); - break; - case 2: - asmEndInterview(); - break; - default: - return false; - } - return true; -} - -void LogicGame::useJournal() { - _vm->command()->clear(false); - _journal->use(); - _vm->walk()->stopJoe(); -} - -bool LogicGame::preChangeRoom() { - if (currentRoom() == ROOM_JUNGLE_PINNACLE) { - handlePinnacleRoom(); - return true; - } else if (currentRoom() == FOTAQ_LOGO && gameState(VAR_INTRO_PLAYED) == 0) { - displayRoom(currentRoom(), RDM_FADE_NOJOE, 100, 2, true); - playCutaway("copy.cut"); - playCutaway("clogo.cut"); - - if (ConfMan.getBool("alt_intro") && _vm->resource()->isCD()) { - playCutaway("cintr.cut"); - } else { - playCutaway("cdint.cut"); - } - - playCutaway("cred.cut"); - _vm->display()->palSetPanel(); - sceneReset(); - currentRoom(ROOM_HOTEL_LOBBY); - entryObj(584); - displayRoom(currentRoom(), RDM_FADE_JOE, 100, 2, true); - playCutaway("c70d.cut"); - gameState(VAR_INTRO_PLAYED, 1); - inventoryRefresh(); - return true; - } - return false; -} - -bool LogicGame::handleSpecialMove(uint16 sm) { - typedef void (LogicGame::*SpecialMoveProc)(); - static const SpecialMoveProc asmTable[] = { - /* 00 */ - 0, - 0, - &LogicGame::asmMakeJoeUseDress, - &LogicGame::asmMakeJoeUseNormalClothes, - /* 04 */ - &LogicGame::asmMakeJoeUseUnderwear, - &LogicGame::asmSwitchToDressPalette, - &LogicGame::asmSwitchToNormalPalette, - &LogicGame::asmStartCarAnimation, // room 74 - /* 08 */ - &LogicGame::asmStopCarAnimation, // room 74 - &LogicGame::asmStartFightAnimation, // room 69 - &LogicGame::asmWaitForFrankPosition, // c69e.cut - &LogicGame::asmMakeFrankGrowing, // c69z.cut - /* 12 */ - &LogicGame::asmMakeRobotGrowing, // c69z.cut - &LogicGame::asmShrinkRobot, - &LogicGame::asmEndGame, - &LogicGame::asmPutCameraOnDino, - /* 16 */ - &LogicGame::asmPutCameraOnJoe, - &LogicGame::asmAltIntroPanRight, // cintr.cut - &LogicGame::asmAltIntroPanLeft, // cintr.cut - &LogicGame::asmSetAzuraInLove, - /* 20 */ - &LogicGame::asmPanRightFromJoe, - &LogicGame::asmSetLightsOff, - &LogicGame::asmSetLightsOn, - &LogicGame::asmSetManequinAreaOn, - /* 24 */ - &LogicGame::asmPanToJoe, - &LogicGame::asmTurnGuardOn, - &LogicGame::asmPanLeft320To144, - &LogicGame::asmSmooch, - /* 28 */ - &LogicGame::asmMakeLightningHitPlane, - &LogicGame::asmScaleBlimp, - &LogicGame::asmScaleEnding, - &LogicGame::asmWaitForCarPosition, - /* 32 */ - &LogicGame::asmShakeScreen, - &LogicGame::asmAttemptPuzzle, - &LogicGame::asmScaleTitle, - 0, - /* 36 */ - &LogicGame::asmPanRightToHugh, - &LogicGame::asmMakeWhiteFlash, - &LogicGame::asmPanRightToJoeAndRita, - &LogicGame::asmPanLeftToBomb // cdint.cut - }; - if (sm >= ARRAYSIZE(asmTable) || asmTable[sm] == 0) - return false; - (this->*asmTable[sm])(); - return true; -} - -} // End of namespace Queen |