aboutsummaryrefslogtreecommitdiff
path: root/engines/avalanche/animation.cpp
diff options
context:
space:
mode:
authorStrangerke2013-09-07 19:09:06 +0200
committerStrangerke2013-09-07 19:11:34 +0200
commitd96555406ec215f390904d15c729ab6528f8b28f (patch)
tree20073574e9e06a22897634bf6297fd7adfe8e638 /engines/avalanche/animation.cpp
parent9097e801537e0e80f2d7df7938f79d145ee362df (diff)
downloadscummvm-rg350-d96555406ec215f390904d15c729ab6528f8b28f.tar.gz
scummvm-rg350-d96555406ec215f390904d15c729ab6528f8b28f.tar.bz2
scummvm-rg350-d96555406ec215f390904d15c729ab6528f8b28f.zip
AVALANCHE: Rename trip into animation, some more renaming
Diffstat (limited to 'engines/avalanche/animation.cpp')
-rw-r--r--engines/avalanche/animation.cpp1632
1 files changed, 1632 insertions, 0 deletions
diff --git a/engines/avalanche/animation.cpp b/engines/avalanche/animation.cpp
new file mode 100644
index 0000000000..5679e1b715
--- /dev/null
+++ b/engines/avalanche/animation.cpp
@@ -0,0 +1,1632 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* TRIP5 Trippancy V - the sprite animation subsystem */
+
+#include "avalanche/avalanche.h"
+
+#include "avalanche/animation.h"
+#include "avalanche/scrolls2.h"
+#include "avalanche/lucerna2.h"
+#include "avalanche/visa2.h"
+#include "avalanche/gyro2.h"
+#include "avalanche/celer2.h"
+#include "avalanche/sequence2.h"
+#include "avalanche/timeout2.h"
+#include "avalanche/enid2.h"
+
+#include "common/scummsys.h"
+#include "common/textconsole.h"
+#include "common/file.h"
+
+namespace Avalanche {
+
+void AnimationType::init(byte spritenum, bool do_check, Animation *tr) {
+ _tr = tr;
+
+ const int32 idshould = -1317732048;
+ byte fv;
+ int32 id;
+ Common::File inf;
+
+ if (spritenum == 177)
+ return; // Already running!
+
+ Common::String filename;
+ filename = filename.format("sprite%d.avd", spritenum);
+ if (!inf.open(filename)) {
+ warning("AVALANCHE: Trip: File not found: %s", filename.c_str());
+ return;
+ }
+
+ inf.seek(177);
+
+ id = inf.readSint32LE();
+ if (id != idshould) {
+ //output << '\7';
+ inf.close();
+ return;
+ }
+
+ inf.skip(2); // Replace variable named 'soa' in the original code.
+
+ if (!_stat._name.empty())
+ _stat._name.clear();
+ byte nameSize = inf.readByte();
+ for (byte i = 0; i < nameSize; i++)
+ _stat._name += inf.readByte();
+ inf.skip(12 - nameSize);
+
+ //inf.skip(1); // Same as above.
+ byte commentSize = inf.readByte();
+ for (byte i = 0; i < commentSize; i++)
+ _stat._comment += inf.readByte();
+ inf.skip(16 - commentSize);
+
+ _stat._frameNum = inf.readByte();
+ _info._xLength = inf.readByte();
+ _info._yLength = inf.readByte();
+ _stat.seq = inf.readByte();
+ _info._size = inf.readUint16LE();
+ _stat._fgBubbleCol = inf.readByte();
+ _stat._bgBubbleCol = inf.readByte();
+ _stat.accinum = inf.readByte();
+
+ totalnum = 0; // = 1;
+ _info._xWidth = _info._xLength / 8;
+ if ((_info._xLength % 8) > 0)
+ _info._xWidth++;
+ for (byte aa = 0; aa < _stat._frameNum; aa++) {
+
+ _info._sil[totalnum] = new SilType[11 * (_info._yLength + 1)];
+ //getmem(sil[totalnum-1], 11 * (a.yl + 1));
+ _info._mani[totalnum] = new ManiType[_info._size - 6];
+ //getmem(mani[totalnum-1], a.size - 6);
+ for (fv = 0; fv <= _info._yLength; fv++)
+ inf.read((*_info._sil[totalnum])[fv], _info._xWidth);
+ //blockread(inf, (*sil[totalnum-1])[fv], xw);
+ inf.read(*_info._mani[totalnum], _info._size - 6);
+ //blockread(inf, *mani[totalnum-1], a.size - 6);
+
+ totalnum++;
+ }
+ totalnum++;
+
+ // on;
+ _x = 0;
+ _y = 0;
+ quick = true;
+ _visible = false;
+ xs = 3;
+ ys = 1;
+ if (spritenum == 1)
+ _tr->newspeed(); // Just for the lights.
+
+ homing = false;
+ ix = 0;
+ iy = 0;
+ step = 0;
+ check_me = do_check;
+ count = 0;
+ whichsprite = spritenum;
+ vanishifstill = false;
+ call_eachstep = false;
+
+ inf.close();
+}
+
+void AnimationType::original() {
+ quick = false;
+ whichsprite = 177;
+}
+
+void AnimationType::andexor() {
+ if ((vanishifstill) && (ix == 0) && (iy == 0))
+ return;
+ byte picnum = face * _stat.seq + step; // There'll maybe problem because of the different array indexes in Pascal (starting from 1).
+
+ _tr->_vm->_graphics->drawSprite(_info, picnum, _x, _y);
+}
+
+void AnimationType::turn(byte whichway) {
+ if (whichway == 8)
+ face = Animation::kDirUp;
+ else
+ face = whichway;
+}
+
+void AnimationType::appear(int16 wx, int16 wy, byte wf) {
+ _x = (wx / 8) * 8;
+ _y = wy;
+ _oldX[_tr->_vm->_gyro->_cp] = wx;
+ _oldY[_tr->_vm->_gyro->_cp] = wy;
+ turn(wf);
+ _visible = true;
+ ix = 0;
+ iy = 0;
+}
+
+bool AnimationType::collision_check() {
+ for (byte fv = 0; fv < _tr->kSpriteNumbMax; fv++)
+ if (_tr->tr[fv].quick && (_tr->tr[fv].whichsprite != whichsprite) &&
+ ((_x + _info._xLength) > _tr->tr[fv]._x) &&
+ (_x < (_tr->tr[fv]._x + _tr->tr[fv]._info._xLength)) &&
+ (_tr->tr[fv]._y == _y))
+ return true;
+
+ return false;
+}
+
+void AnimationType::walk() {
+ byte tc;
+ ByteField r;
+
+
+ if (_visible) {
+ r._x1 = (_x / 8) - 1;
+ if (r._x1 == 255)
+ r._x1 = 0;
+ r._y1 = _y - 2;
+ r._x2 = ((_x + _info._xLength) / 8) + 1;
+ r._y2 = _y + _info._yLength + 2;
+
+ _tr->getset[1 - _tr->_vm->_gyro->_cp].remember(r);
+ }
+
+ if (!_tr->_vm->_gyro->_doingSpriteRun) {
+ _oldX[_tr->_vm->_gyro->_cp] = _x;
+ _oldY[_tr->_vm->_gyro->_cp] = _y;
+ if (homing)
+ homestep();
+ _x = _x + ix;
+ _y = _y + iy;
+ }
+
+ if (check_me) {
+ if (collision_check()) {
+ bounce();
+ return;
+ }
+
+ tc = _tr->checkfeet(_x, _x + _info._xLength, _oldY[_tr->_vm->_gyro->_cp], _y, _info._yLength) - 1;
+ // -1 is because the modified array indexes of magics[] compared to Pascal .
+
+ if ((tc != 255) & (!_tr->_vm->_gyro->_doingSpriteRun)) {
+ switch (_tr->_vm->_gyro->_magics[tc]._operation) {
+ case Gyro::kMagicExclaim: {
+ bounce();
+ _tr->mustexclaim = true;
+ _tr->saywhat = _tr->_vm->_gyro->_magics[tc]._data;
+ }
+ break;
+ case Gyro::kMagicBounce:
+ bounce();
+ break;
+ case Gyro::kMagicTransport:
+ _tr->fliproom(_tr->_vm->_gyro->_magics[tc]._data >> 8, _tr->_vm->_gyro->_magics[tc]._data & 0xff);
+ break;
+ case Gyro::kMagicUnfinished: {
+ bounce();
+ _tr->_vm->_scrolls->display("\7Sorry.\3\rThis place is not available yet!");
+ }
+ break;
+ case Gyro::kMagicSpecial:
+ _tr->call_special(_tr->_vm->_gyro->_magics[tc]._data);
+ break;
+ case Gyro::kMagicOpenDoor:
+ _tr->open_the_door(_tr->_vm->_gyro->_magics[tc]._data >> 8, _tr->_vm->_gyro->_magics[tc]._data & 0xff, tc);
+ break;
+ }
+ }
+ }
+
+ if (!_tr->_vm->_gyro->_doingSpriteRun) {
+ count++;
+ if (((ix != 0) || (iy != 0)) && (count > 1)) {
+ step++;
+ if (step == _stat.seq)
+ step = 0;
+ count = 0;
+ }
+ }
+}
+
+void AnimationType::bounce() {
+ _x = _oldX[_tr->_vm->_gyro->_cp];
+ _y = _oldY[_tr->_vm->_gyro->_cp];
+ if (check_me)
+ _tr->stopwalking();
+ else
+ stopwalk();
+ _tr->_vm->_gyro->_onCanDoPageSwap = false;
+ _tr->_vm->_lucerna->drawDirection();
+ _tr->_vm->_gyro->_onCanDoPageSwap = true;
+}
+
+int8 AnimationType::sgn(int16 val) {
+ if (val > 0)
+ return 1;
+ else if (val < 0)
+ return -1;
+ else
+ return 0;
+}
+
+void AnimationType::walkto(byte pednum) {
+ pednum--; // Pascal -> C conversion: different array indexes.
+ speed(sgn(_tr->_vm->_gyro->_peds[pednum]._x - _x) * 4, sgn(_tr->_vm->_gyro->_peds[pednum]._y - _y));
+ hx = _tr->_vm->_gyro->_peds[pednum]._x - _info._xLength / 2;
+ hy = _tr->_vm->_gyro->_peds[pednum]._y - _info._yLength;
+ homing = true;
+}
+
+void AnimationType::stophoming() {
+ homing = false;
+}
+
+void AnimationType::homestep() {
+ int16 temp;
+
+ if ((hx == _x) && (hy == _y)) {
+ // touching the target
+ stopwalk();
+ return;
+ }
+ ix = 0;
+ iy = 0;
+ if (hy != _y) {
+ temp = hy - _y;
+ if (temp > 4)
+ iy = 4;
+ else if (temp < -4)
+ iy = -4;
+ else
+ iy = temp;
+ }
+ if (hx != _x) {
+ temp = hx - _x;
+ if (temp > 4)
+ ix = 4;
+ else if (temp < -4)
+ ix = -4;
+ else
+ ix = temp;
+ }
+}
+
+void AnimationType::speed(int8 xx, int8 yy) {
+ ix = xx;
+ iy = yy;
+ if ((ix == 0) && (iy == 0))
+ return; // no movement
+ if (ix == 0) {
+ // No horz movement
+ if (iy < 0)
+ turn(_tr->kDirUp);
+ else
+ turn(_tr->kDirDown);
+ } else {
+ if (ix < 0)
+ turn(_tr->kDirLeft);
+ else
+ turn(_tr->kDirRight);
+ }
+}
+
+void AnimationType::stopwalk() {
+ ix = 0;
+ iy = 0;
+ homing = false;
+}
+
+void AnimationType::chatter() {
+ _tr->_vm->_gyro->_talkX = _x + _info._xLength / 2;
+ _tr->_vm->_gyro->_talkY = _y;
+ _tr->_vm->_gyro->_talkFontColor = _stat._fgBubbleCol;
+ _tr->_vm->_gyro->_talkBackgroundColor = _stat._bgBubbleCol;
+}
+
+void AnimationType::set_up_saver(trip_saver_type &v) {
+ v.whichsprite = whichsprite;
+ v.face = face;
+ v.step = step;
+ v.x = _x;
+ v.y = _y;
+ v.ix = ix;
+ v.iy = iy;
+ v.visible = _visible;
+ v.homing = homing;
+ v.check_me = check_me;
+ v.count = count;
+ v.xw = _info._xWidth;
+ v.xs = xs;
+ v.ys = ys;
+ v.totalnum = totalnum;
+ v.hx = hx;
+ v.hy = hy;
+ v.call_eachstep = call_eachstep;
+ v.eachstep = eachstep;
+ v.vanishifstill = vanishifstill;
+}
+
+void AnimationType::unload_saver(trip_saver_type v) {
+ whichsprite = v.whichsprite;
+ face = v.face;
+ step = v.step;
+ _x = v.x;
+ _y = v.y;
+ ix = v.ix;
+ iy = v.iy;
+ _visible = v.visible;
+ homing = v.homing;
+ check_me = v.check_me;
+ count = v.count;
+ _info._xWidth = v.xw;
+ xs = v.xs;
+ ys = v.ys;
+ totalnum = v.totalnum;
+ hx = v.hx;
+ hy = v.hy;
+ call_eachstep = v.call_eachstep;
+ eachstep = v.eachstep;
+ vanishifstill = v.vanishifstill;
+}
+
+void AnimationType::savedata(Common::File &f) {
+ warning("STUB: triptype::savedata()");
+}
+
+void AnimationType::loaddata(Common::File &f) {
+ warning("STUB: triptype::loaddata()");
+}
+
+void AnimationType::save_data_to_mem(uint16 &where) {
+ warning("STUB: triptype::save_data_to_mem()");
+}
+
+void AnimationType::load_data_from_mem(uint16 &where) {
+ warning("STUB: triptype::load_data_from_mem()");
+}
+
+AnimationType *AnimationType::done() {
+ Common::String xx;
+
+ // nds:=num div seq;
+ totalnum--;
+ _info._xWidth = _info._xLength / 8;
+ if ((_info._xLength % 8) > 0)
+ _info._xWidth++;
+ for (byte aa = 0; aa < _stat._frameNum; aa++) {
+ totalnum--;
+ delete[] _info._mani[totalnum];
+ delete[] _info._sil[totalnum];
+ }
+
+ quick = false;
+ whichsprite = 177;
+ return this;
+}
+
+getsettype *getsettype::init() {
+ numleft = 0; // initialize array pointer
+ return this;
+}
+
+void getsettype::remember(ByteField r) {
+ numleft++;
+ //if (numleft > maxgetset)
+ // error("Trip::remember() : runerr_Getset_Overflow");
+ gs[numleft] = r;
+}
+
+void getsettype::recall(ByteField &r) {
+ r = gs[numleft];
+ numleft--;
+}
+
+
+
+
+
+
+Animation::Animation(AvalancheEngine *vm) {
+ _vm = vm;
+
+ getsetclear();
+ mustexclaim = false;
+}
+
+Animation::~Animation() {
+ for (byte i = 0; i < kSpriteNumbMax; i++) {
+ if (tr[i].quick)
+ tr[i].done();
+ }
+}
+
+void Animation::loadtrip() {
+ for (int16 gm = 0; gm < kSpriteNumbMax; gm++)
+ tr[gm].original();
+
+ for (uint16 i = 0; i < sizeof(aa); i++)
+ aa[i] = 0;
+}
+
+byte Animation::checkfeet(int16 x1, int16 x2, int16 oy, int16 y, byte yl) {
+ byte a, c;
+ int16 fv, ff;
+
+ // if not alive then begin checkfeet:=0; exit; end;
+ a = 0;
+
+ //setactivepage(2);
+ if (x1 < 0)
+ x1 = 0;
+ if (x2 > 639)
+ x2 = 639;
+ if (oy < y) {
+ for (fv = x1; fv <= x2; fv++) {
+ for (ff = oy + yl; ff <= y + yl; ff++) {
+ c = *(byte *)_vm->_graphics->_magics.getBasePtr(fv, ff);
+ if (c > a)
+ a = c;
+ }
+ }
+ } else {
+ for (fv = x1; fv <= x2; fv++) {
+ for (ff = y + yl; ff <= oy + yl; ff++) {
+ c = *(byte *)_vm->_graphics->_magics.getBasePtr(fv, ff);
+ if (c > a)
+ a = c;
+ }
+ }
+ }
+
+ //setactivepage(1 - cp);
+ return a;
+}
+
+byte Animation::geida_ped(byte which) {
+ switch (which) {
+ case 1:
+ return 7;
+ case 2:
+ case 6:
+ return 8;
+ case 3:
+ case 5:
+ return 9;
+ case 4:
+ return 10;
+ default:
+ return 0;
+ }
+}
+
+void Animation::catamove(byte ped) {
+/* When you enter a new position in the catacombs, this procedure should
+ be called. It changes the Also codes so that they may match the picture
+ on the screen. (Coming soon: It draws up the screen, too.) */
+
+ int32 here;
+ uint16 xy_uint16;
+ byte fv;
+
+ // XY_uint16 is cat_x+cat_y*256. Thus, every room in the
+ // catacombs has a different number for it.
+
+
+
+ xy_uint16 = _vm->_gyro->_dna._catacombX + _vm->_gyro->_dna._catacombY * 256;
+ _vm->_gyro->_dna._geidaSpin = 0;
+
+ switch (xy_uint16) {
+ case 1801: // Exit catacombs
+ fliproom(r__lustiesroom, 4);
+ _vm->_scrolls->display("Phew! Nice to be out of there!");
+ return;
+ case 1033: // Oubliette
+ fliproom(r__oubliette, 1);
+ _vm->_scrolls->display(Common::String("Oh, NO!") + _vm->_scrolls->kControlRegister + '1' + _vm->_scrolls->kControlSpeechBubble);
+ return;
+ case 4:
+ fliproom(r__geidas, 1);
+ return;
+ case 2307:
+ fliproom(r__lusties, 5);
+ _vm->_scrolls->display("Oh no... here we go again...");
+ _vm->_gyro->_dna._userMovesAvvy = false;
+ tr[0].iy = 1;
+ tr[0].ix = 0;
+ return;
+ }
+
+ if (!_vm->_gyro->_dna._enterCatacombsFromLustiesRoom)
+ _vm->_lucerna->loadRoom(29);
+ here = _vm->_gyro->kCatacombMap[_vm->_gyro->_dna._catacombY - 1][_vm->_gyro->_dna._catacombX - 1];
+
+ switch (here & 0xf) { // West.
+ case 0: // no connection (wall)
+ _vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicNothing; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 28);
+ break;
+ case 0x1: // no connection (wall + shield),
+ _vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicNothing; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 29); // ...shield.
+ break;
+ case 0x2: // wall with door
+ _vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicSpecial; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 30); // ...door.
+ break;
+ case 0x3: // wall with door and shield
+ _vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicSpecial; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 30); // ...door, and...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 29); // ...shield.
+ break;
+ case 0x4: // no connection (wall + window),
+ _vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicNothing; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 5); // ...window.
+ break;
+ case 0x5: // wall with door and window
+ _vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicSpecial; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 30); // ...door, and...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 5); // ...window.
+ break;
+ case 0x6: // no connection (wall + torches),
+ _vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicNothing; // No door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 7); // ...torches.
+ break;
+ case 0x7: // wall with door and torches
+ _vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[4]._operation = _vm->_gyro->kMagicSpecial; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 28); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 30); // ...door, and...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 7); // ...torches.
+ break;
+ case 0xf: // straight-through corridor.
+ _vm->_gyro->_magics[1]._operation = _vm->_gyro->kMagicNothing; // Sloping wall.
+ _vm->_gyro->_magics[2]._operation = _vm->_gyro->kMagicSpecial; // Straight wall.
+ break;
+ }
+
+ /* ---- */
+
+ switch ((here & 0xf0) >> 4) { // East
+ case 0: // no connection (wall)
+ _vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicNothing; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 19);
+ break;
+ case 0x1: // no connection (wall + window),
+ _vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicNothing; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 19); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 20); // ...window.
+ break;
+ case 0x2: // wall with door
+ _vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicSpecial; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 19); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 21); // ...door.
+ break;
+ case 0x3: // wall with door and window
+ _vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicSpecial; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 19); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 20); // ...door, and...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 21); // ...window.
+ break;
+ case 0x6: // no connection (wall + torches),
+ _vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicNothing; // No door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 19); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 18); // ...torches.
+ break;
+ case 0x7: // wall with door and torches
+ _vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Sloping wall.
+ _vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicNothing; // Straight wall.
+ _vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicSpecial; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 19); // Wall, plus...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 21); // ...door, and...
+ _vm->_celer->drawBackgroundSprite(-1, -1, 18); // ...torches.
+ break;
+ case 0xf: // straight-through corridor.
+ _vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicNothing; // Sloping wall.
+ _vm->_gyro->_magics[5]._operation = _vm->_gyro->kMagicSpecial; // Straight wall.
+ _vm->_gyro->_portals[6]._operation = _vm->_gyro->kMagicNothing; // Door.
+ break;
+ }
+
+ /* ---- */
+
+ switch ((here & 0xf00) >> 8) { // South
+ case 0: // No connection.
+ _vm->_gyro->_magics[6]._operation = _vm->_gyro->kMagicBounce;
+ _vm->_gyro->_magics[11]._operation = _vm->_gyro->kMagicBounce;
+ _vm->_gyro->_magics[12]._operation = _vm->_gyro->kMagicBounce;
+ break;
+ case 0x1:
+ _vm->_celer->drawBackgroundSprite(-1, -1, 22);
+
+ if ((xy_uint16 == 2051) && (_vm->_gyro->_dna._geidaFollows))
+ _vm->_gyro->_magics[12]._operation = _vm->_gyro->kMagicExclaim;
+ else
+ _vm->_gyro->_magics[12]._operation = _vm->_gyro->kMagicSpecial; // Right exit south.
+
+ _vm->_gyro->_magics[6]._operation = _vm->_gyro->kMagicBounce;
+ _vm->_gyro->_magics[11]._operation = _vm->_gyro->kMagicBounce;
+ break;
+ case 0x2:
+ _vm->_celer->drawBackgroundSprite(-1, -1, 23);
+ _vm->_gyro->_magics[6]._operation = _vm->_gyro->kMagicSpecial; // Middle exit south.
+ _vm->_gyro->_magics[11]._operation = _vm->_gyro->kMagicBounce;
+ _vm->_gyro->_magics[12]._operation = _vm->_gyro->kMagicBounce;
+ break;
+ case 0x3:
+ _vm->_celer->drawBackgroundSprite(-1, -1, 24);
+ _vm->_gyro->_magics[11]._operation = _vm->_gyro->kMagicSpecial; // Left exit south.
+ _vm->_gyro->_magics[6]._operation = _vm->_gyro->kMagicBounce;
+ _vm->_gyro->_magics[12]._operation = _vm->_gyro->kMagicBounce;
+ break;
+ }
+
+ switch ((here & 0xf000) >> 12) { // North
+ case 0: // No connection
+ _vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicBounce;
+ _vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicNothing; // Door.
+ break;
+ // LEFT handles:
+#if 0
+ case 0x1:
+ _vm->_celer->show_one(-1, -1, 4);
+ _vm->_gyro->magics[1].op = _vm->_gyro->bounces; // { Left exit north. } { Change magic number! }
+ _vm->_gyro->portals[12].op = _vm->_gyro->special; // { Door. }
+ break;
+#endif
+ case 0x2:
+ _vm->_celer->drawBackgroundSprite(-1, -1, 4);
+ _vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicBounce; // Middle exit north.
+ _vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicSpecial; // Door.
+ break;
+#if 0
+ case 0x3:
+ _vm->_celer->show_one(-1, -1, 4);
+ _vm->_gyro->magics[1].op = _vm->_gyro->bounces; // { Right exit north. } { Change magic number! }
+ _vm->_gyro->portals[12].op = _vm->_gyro->special; // { Door. }
+ break;
+ // RIGHT handles:
+ case 0x4:
+ _vm->_celer->show_one(-1, -1, 3);
+ _vm->_gyro->magics[1].op = _vm->_gyro->bounces; // { Left exit north. } { Change magic number! }
+ _vm->_gyro->portals[12].op = _vm->_gyro->special; // { Door. }
+ break;
+#endif
+ case 0x5:
+ _vm->_celer->drawBackgroundSprite(-1, -1, 3);
+ _vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicBounce; // Middle exit north.
+ _vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicSpecial; // Door.
+ break;
+#if 0
+ case 0x6:
+ _vm->_celer->show_one(-1, -1, 3);
+ _vm->_gyro->magics[1].op = _vm->_gyro->bounces; // { Right exit north. }
+ _vm->_gyro->portals[12].op = _vm->_gyro->special; // { Door. }
+ break;
+#endif
+ // ARCHWAYS:
+ case 0x7:
+ case 0x8:
+ case 0x9: {
+ _vm->_celer->drawBackgroundSprite(-1, -1, 6);
+
+ if (((here & 0xf000) >> 12) > 0x7)
+ _vm->_celer->drawBackgroundSprite(-1, -1, 31);
+ if (((here & 0xf000) >> 12) == 0x9)
+ _vm->_celer->drawBackgroundSprite(-1, -1, 32);
+
+ _vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicSpecial; // Middle arch north.
+ _vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicNothing; // Door.
+ }
+ break;
+ // DECORATIONS:
+ case 0xd: // No connection + WINDOW
+ _vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicBounce;
+ _vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicNothing; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 14);
+ break;
+ case 0xe: // No connection + TORCH
+ _vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicBounce;
+ _vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicNothing; // Door.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 8);
+ break;
+ // Recessed door:
+ case 0xf:
+ _vm->_gyro->_magics[0]._operation = _vm->_gyro->kMagicNothing; // Door to Geida's room.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 1);
+ _vm->_gyro->_portals[3]._operation = _vm->_gyro->kMagicSpecial; // Door.
+ break;
+ }
+
+ switch (xy_uint16) {
+ case 514:
+ _vm->_celer->drawBackgroundSprite(-1, -1, 17);
+ break; // [2,2] : "Art Gallery" sign over door.
+ case 264:
+ _vm->_celer->drawBackgroundSprite(-1, -1, 9);
+ break; // [8,1] : "The Wrong Way!" sign.
+ case 1797:
+ _vm->_celer->drawBackgroundSprite(-1, -1, 2);
+ break; // [5,7] : "Ite Mingite" sign.
+ case 258:
+ for (fv = 0; fv <= 2; fv++) { // [2,1] : Art gallery - pictures
+ _vm->_celer->drawBackgroundSprite(130 + fv * 120, 70, 15);
+ _vm->_celer->drawBackgroundSprite(184 + fv * 120, 78, 16);
+ }
+ break;
+ case 1287:
+ for (fv = 10; fv <= 13; fv++)
+ _vm->_celer->drawBackgroundSprite(-1, -1, fv);
+ break; // [7,5] : 4 candles.
+ case 776:
+ _vm->_celer->drawBackgroundSprite(-1, -1, 10);
+ break; // [8,3] : 1 candle.
+ case 2049:
+ _vm->_celer->drawBackgroundSprite(-1, -1, 11);
+ break; // [1,8] : another candle.
+ case 257:
+ _vm->_celer->drawBackgroundSprite(-1, -1, 12);
+ _vm->_celer->drawBackgroundSprite(-1, -1, 13);
+ break; // [1,1] : the other two.
+ }
+
+ if ((_vm->_gyro->_dna._geidaFollows) && (ped > 0)) {
+ if (!tr[1].quick) // If we don't already have her...
+ tr[1].init(5, true, this); // ...Load Geida.
+ apped(2, geida_ped(ped));
+ tr[1].call_eachstep = true;
+ tr[1].eachstep = procgeida_procs;
+ }
+}
+
+
+
+// This proc gets called whenever you touch a line defined as _vm->_gyro->special.
+void Animation::dawndelay() {
+ _vm->_timeout->set_up_timer(2, _vm->_timeout->procdawn_delay, _vm->_timeout->reason_dawndelay);
+}
+
+void Animation::call_special(uint16 which) {
+ switch (which) {
+ case 1: // _vm->_gyro->special 1: Room 22: top of stairs.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 1);
+ _vm->_gyro->_dna._brummieStairs = 1;
+ _vm->_gyro->_magics[9]._operation = _vm->_gyro->kMagicNothing;
+ _vm->_timeout->set_up_timer(10, _vm->_timeout->procstairs, _vm->_timeout->reason_brummiestairs);
+ stopwalking();
+ _vm->_gyro->_dna._userMovesAvvy = false;
+ break;
+ case 2: // _vm->_gyro->special 2: Room 22: bottom of stairs.
+ _vm->_gyro->_dna._brummieStairs = 3;
+ _vm->_gyro->_magics[10]._operation = _vm->_gyro->kMagicNothing;
+ _vm->_gyro->_magics[11]._operation = _vm->_gyro->kMagicExclaim;
+ _vm->_gyro->_magics[11]._data = 5;
+ _vm->_gyro->_magics[3]._operation = _vm->_gyro->kMagicBounce; // Now works as planned!
+ stopwalking();
+ _vm->_visa->dixi('q', 26);
+ _vm->_gyro->_dna._userMovesAvvy = true;
+ break;
+ case 3: // _vm->_gyro->special 3: Room 71: triggers dart.
+ tr[0].bounce(); // Must include that.
+
+ if (!_vm->_gyro->_dna._arrowTriggered) {
+ _vm->_gyro->_dna._arrowTriggered = true;
+ apped(2, 4); // The dart starts at ped 4, and...
+ tr[1].walkto(5); // flies to ped 5.
+ tr[1].face = kDirUp; // Only face.
+ // Should call some kind of Eachstep procedure which will deallocate
+ // the sprite when it hits the wall, and replace it with the chunk
+ // graphic of the arrow buried in the plaster. */
+
+ // OK!
+ tr[1].call_eachstep = true;
+ tr[1].eachstep = procarrow_procs;
+ }
+ break;
+ case 4: // This is the ghost room link.
+ _vm->_lucerna->dusk();
+ tr[0].turn(kDirRight); // you'll see this after we get back from bootstrap
+ _vm->_timeout->set_up_timer(1, _vm->_timeout->procghost_room_phew, _vm->_timeout->reason_ghost_room_phew);
+ _vm->_enid->backToBootstrap(3);
+ break;
+ case 5:
+ if (_vm->_gyro->_dna._friarWillTieYouUp) {
+ // _vm->_gyro->special 5: Room 42: touched tree, and get tied up.
+ _vm->_gyro->_magics[4]._operation = _vm->_gyro->kMagicBounce; // Boundary effect is now working again.
+ _vm->_visa->dixi('q', 35);
+ tr[0].done();
+ //tr[1].vanishifstill:=true;
+ _vm->_celer->drawBackgroundSprite(-1, -1, 2);
+ _vm->_visa->dixi('q', 36);
+ _vm->_gyro->_dna._tiedUp = true;
+ _vm->_gyro->_dna._friarWillTieYouUp = false;
+ tr[1].walkto(3);
+ tr[1].vanishifstill = true;
+ tr[1].check_me = true; // One of them must have Check_Me switched on.
+ _vm->_gyro->_whereIs[_vm->_gyro->kPeopleFriarTuck - 150] = 177; // Not here, then.
+ _vm->_timeout->set_up_timer(364, _vm->_timeout->prochang_around, _vm->_timeout->reason_hanging_around);
+ }
+ break;
+ case 6: // _vm->_gyro->special 6: fall down oubliette.
+ _vm->_gyro->_dna._userMovesAvvy = false;
+ tr[0].ix = 3;
+ tr[0].iy = 0;
+ tr[0].face = kDirRight;
+ _vm->_timeout->set_up_timer(1, _vm->_timeout->procfall_down_oubliette, _vm->_timeout->reason_falling_down_oubliette);
+ break;
+ case 7: // _vm->_gyro->special 7: stop falling down oubliette.
+ tr[0]._visible = false;
+ _vm->_gyro->_magics[9]._operation = _vm->_gyro->kMagicNothing;
+ stopwalking();
+ _vm->_timeout->lose_timer(_vm->_timeout->reason_falling_down_oubliette);
+ //_vm->_lucerna->mblit(12, 80, 38, 160, 3, 0);
+ //_vm->_lucerna->mblit(12, 80, 38, 160, 3, 1);
+ _vm->_scrolls->display("Oh dear, you seem to be down the bottom of an oubliette.");
+ _vm->_timeout->set_up_timer(200, _vm->_timeout->procmeet_avaroid, _vm->_timeout->reason_meeting_avaroid);
+ break;
+ case 8: // _vm->_gyro->special 8: leave du Lustie's room.
+ if ((_vm->_gyro->_dna._geidaFollows) && (!_vm->_gyro->_dna._lustieIsAsleep)) {
+ _vm->_visa->dixi('q', 63);
+ tr[1].turn(kDirDown);
+ tr[1].stopwalk();
+ tr[1].call_eachstep = false; // Geida
+ _vm->_lucerna->gameOver();
+ }
+ break;
+ case 9: // _vm->_gyro->special 9: lose Geida to Robin Hood...
+ if (!_vm->_gyro->_dna._geidaFollows)
+ return; // DOESN'T COUNT: no Geida.
+ tr[1].call_eachstep = false; // She no longer follows Avvy around.
+ tr[1].walkto(4); // She walks to somewhere...
+ tr[0].done(); // Lose Avvy.
+ _vm->_gyro->_dna._userMovesAvvy = false;
+ _vm->_timeout->set_up_timer(40, _vm->_timeout->procrobin_hood_and_geida, _vm->_timeout->reason_robin_hood_and_geida);
+ break;
+ case 10: // _vm->_gyro->special 10: transfer north in catacombs.
+ if ((_vm->_gyro->_dna._catacombX == 4) && (_vm->_gyro->_dna._catacombY == 1)) {
+ // Into Geida's room.
+ if (_vm->_gyro->_dna._objects[_vm->_gyro->kObjectKey - 1])
+ _vm->_visa->dixi('q', 62);
+ else {
+ _vm->_visa->dixi('q', 61);
+ return;
+ }
+ }
+ _vm->_lucerna->dusk();
+ _vm->_gyro->_dna._catacombY--;
+ catamove(4);
+ if (_vm->_gyro->_dna._room != r__catacombs)
+ return;
+ switch ((_vm->_gyro->kCatacombMap[_vm->_gyro->_dna._catacombY - 1][_vm->_gyro->_dna._catacombX - 1] & 0xf00) >> 8) {
+ case 0x1:
+ apped(1, 12);
+ break;
+ case 0x3:
+ apped(1, 11);
+ break;
+ default:
+ apped(1, 4);
+ }
+ getback();
+ dawndelay();
+ break;
+ case 11: // _vm->_gyro->special 11: transfer east in catacombs.
+ _vm->_lucerna->dusk();
+ _vm->_gyro->_dna._catacombX++;
+ catamove(1);
+ if (_vm->_gyro->_dna._room != r__catacombs)
+ return;
+ apped(1, 1);
+ getback();
+ dawndelay();
+ break;
+ case 12: // _vm->_gyro->special 12: transfer south in catacombs.
+ _vm->_lucerna->dusk();
+ _vm->_gyro->_dna._catacombY += 1;
+ catamove(2);
+ if (_vm->_gyro->_dna._room != r__catacombs)
+ return;
+ apped(1, 2);
+ getback();
+ dawndelay();
+ break;
+ case 13: // _vm->_gyro->special 13: transfer west in catacombs.
+ _vm->_lucerna->dusk();
+ _vm->_gyro->_dna._catacombX--;
+ catamove(3);
+ if (_vm->_gyro->_dna._room != r__catacombs)
+ return;
+ apped(1, 3);
+ getback();
+ dawndelay();
+ break;
+ }
+}
+
+
+
+void Animation::open_the_door(byte whither, byte ped, byte magicnum) {
+// This slides the door open. (The data really ought to be saved in
+// the Also file, and will be next time. However, for now, they're
+// here.)
+ switch (_vm->_gyro->_dna._room) {
+ case r__outsideyours:
+ case r__outsidenottspub:
+ case r__outsideducks:
+ _vm->_sequence->first_show(1);
+ _vm->_sequence->then_show(2);
+ _vm->_sequence->then_show(3);
+ break;
+ case r__insidecardiffcastle:
+ _vm->_sequence->first_show(1);
+ _vm->_sequence->then_show(5);
+ break;
+ case r__avvysgarden:
+ case r__entrancehall:
+ case r__insideabbey:
+ case r__yourhall:
+ _vm->_sequence->first_show(1);
+ _vm->_sequence->then_show(2);
+ break;
+ case r__musicroom:
+ case r__outsideargentpub:
+ _vm->_sequence->first_show(5);
+ _vm->_sequence->then_show(6);
+ break;
+ case r__lusties:
+ switch (magicnum) {
+ case 14:
+ if (_vm->_gyro->_dna._avvysInTheCupboard) {
+ hide_in_the_cupboard();
+ _vm->_sequence->first_show(8);
+ _vm->_sequence->then_show(7);
+ _vm->_sequence->start_to_close();
+ return;
+ } else {
+ apped(1, 6);
+ tr[0].face = kDirRight; // added by TT 12/3/1995
+ _vm->_sequence->first_show(8);
+ _vm->_sequence->then_show(9);
+ }
+ break;
+ case 12:
+ _vm->_sequence->first_show(4);
+ _vm->_sequence->then_show(5);
+ _vm->_sequence->then_show(6);
+ break;
+ }
+ break;
+ }
+
+ _vm->_sequence->then_flip(whither, ped);
+ _vm->_sequence->start_to_open();
+}
+
+void Animation::newspeed() {
+ // Given that you've just changed the speed in triptype.xs, this adjusts ix.
+ const ByteField lightspace = {40, 199, 47, 199};
+ byte page_;
+
+ tr[0].ix = (tr[0].ix / 3) * tr[0].xs;
+
+ //setactivepage(3);
+
+ if (tr[0].xs == _vm->_gyro->kRun)
+ _vm->_graphics->_surface.drawLine(371, 199, 373, 199, kColorYellow);
+ else
+ _vm->_graphics->_surface.drawLine(336, 199, 338, 199, kColorYellow);
+
+ if (tr[0].xs == _vm->_gyro->kRun)
+ _vm->_graphics->_surface.drawLine(336, 199, 338, 199, kColorLightblue);
+ else
+ _vm->_graphics->_surface.drawLine(371, 199, 373, 199, kColorLightblue);
+
+ //setactivepage(1 - cp);
+
+ for (page_ = 0; page_ <= 1; page_++)
+ getset[page_].remember(lightspace);
+
+}
+
+void Animation::rwsp(byte t, byte dir) {
+ switch (dir) {
+ case kDirUp:
+ tr[t].speed(0, -tr[t].ys);
+ break;
+ case kDirDown:
+ tr[t].speed(0, tr[t].ys);
+ break;
+ case kDirLeft:
+ tr[t].speed(-tr[t].xs, 0);
+ break;
+ case kDirRight:
+ tr[t].speed(tr[t].xs, 0);
+ break;
+ case kDirUpLeft:
+ tr[t].speed(-tr[t].xs, -tr[t].ys);
+ break;
+ case kDirUpRight:
+ tr[t].speed(tr[t].xs, -tr[t].ys);
+ break;
+ case kDirDownLeft:
+ tr[t].speed(-tr[t].xs, tr[t].ys);
+ break;
+ case kDirDownRight:
+ tr[t].speed(tr[t].xs, tr[t].ys);
+ break;
+ }
+}
+
+void Animation::apped(byte trn, byte np) {
+ trn--;
+ np--;
+ tr[trn].appear(_vm->_gyro->_peds[np]._x - tr[trn]._info._xLength / 2, _vm->_gyro->_peds[np]._y - tr[trn]._info._yLength, _vm->_gyro->_peds[np]._direction);
+ rwsp(trn, _vm->_gyro->_peds[np]._direction);
+}
+
+#if 0
+ function overlap(x1,y1,x2,y2,x3,y3,x4,y4:uint16):bool;
+ begin // By De Morgan's law:
+ overlap:=(x2>=x3) and (x4>=x1) and (y2>=y3) and (y4>=y1);
+ end;
+#endif
+ //x1,x2 - as _vm->_gyro->bytefield, but *8. y1,y2 - as _vm->_gyro->bytefield.
+ //x3,y3 = mx,my. x4,y4 = mx+16,my+16.
+
+void Animation::getback() {
+ // Super_Off;
+#if 0
+ while (getset[1 - _vm->_gyro->cp].numleft > 0) {
+ getset[1 - _vm->_gyro->cp].recall(r);
+
+
+ bool endangered = false;
+ if overlaps_with_mouse and not endangered then
+ begin
+ endangered:=true;
+ blitfix;
+ Super_Off;
+ end;
+
+ //_vm->_lucerna->mblit(r.x1, r.y1, r.x2, r.y2, 3, 1 - _vm->_gyro->cp);
+ }
+
+ if endangered then
+ Super_On;
+#endif
+}
+
+// Eachstep procedures:
+void Animation::follow_avvy_y(byte tripnum) {
+ if (tr[0].face == kDirLeft)
+ return;
+ if (tr[tripnum].homing)
+ tr[tripnum].hy = tr[1]._y;
+ else {
+ if (tr[tripnum]._y < tr[1]._y)
+ tr[tripnum]._y += 1;
+ else if (tr[tripnum]._y > tr[1]._y)
+ tr[tripnum]._y -= 1;
+ else
+ return;
+ if (tr[tripnum].ix == 0) {
+ tr[tripnum].step += 1;
+ if (tr[tripnum].step == tr[tripnum]._stat.seq)
+ tr[tripnum].step = 0;
+ tr[tripnum].count = 0;
+ }
+ }
+}
+
+void Animation::back_and_forth(byte tripnum) {
+ if (!tr[tripnum].homing) {
+ if (tr[tripnum].face == kDirRight)
+ tr[tripnum].walkto(4);
+ else
+ tr[tripnum].walkto(5);
+ }
+}
+
+void Animation::face_avvy(byte tripnum) {
+ if (!tr[tripnum].homing) {
+ if (tr[0]._x >= tr[tripnum]._x)
+ tr[tripnum].face = kDirRight;
+ else
+ tr[tripnum].face = kDirLeft;
+ }
+}
+
+void Animation::arrow_procs(byte tripnum) {
+ if (tr[tripnum].homing) {
+ // Arrow is still in flight.
+ // We must check whether or not the arrow has collided tr[tripnum] Avvy's head.
+ // This is so if: a) the bottom of the arrow is below Avvy's head,
+ // b) the left of the arrow is left of the right of Avvy's head, and
+ // c) the right of the arrow is right of the left of Avvy's head.
+ if (((tr[tripnum]._y + tr[tripnum]._info._yLength) >= tr[0]._y) // A
+ && (tr[tripnum]._x <= (tr[0]._x + tr[0]._info._xLength)) // B
+ && ((tr[tripnum]._x + tr[tripnum]._info._xLength) >= tr[0]._x)) { // C
+ // OK, it's hit him... what now?
+
+ tr[1].call_eachstep = false; // prevent recursion.
+ _vm->_visa->dixi('Q', 47); // Complaint!
+ tr[tripnum].done(); // Deallocate the arrow.
+#if 0
+ tr[1].done; { Deallocate normal pic of Avvy. }
+
+ off;
+ for byte fv:=0 to 1 do
+ begin
+ cp:=1-cp;
+ getback;
+ end;
+ on;
+#endif
+ _vm->_lucerna->gameOver();
+
+ _vm->_gyro->_dna._userMovesAvvy = false; // Stop the user from moving him.
+ _vm->_timeout->set_up_timer(55, _vm->_timeout->procnaughty_duke, _vm->_timeout->reason_naughty_duke);
+ }
+ } else { // Arrow has hit the wall!
+ tr[tripnum].done(); // Deallocate the arrow.
+ _vm->_celer->drawBackgroundSprite(-1, -1, 3); // Show pic of arrow stuck into the door.
+ _vm->_gyro->_dna._arrowInTheDoor = true; // So that we can pick it up.
+ }
+
+}
+
+#if 0
+procedure Spludwick_procs(tripnum:byte);
+var fv:byte;
+begin
+ with tr[tripnum] do
+ if not homing then { We only need to do anything if Spludwick *stops*
+ walking. }
+ with _vm->_gyro->dna do
+ begin
+ inc(DogfoodPos);
+ if DogfoodPos=8 then DogfoodPos:=1;
+ walkto(DogfoodPos);
+ end;
+end;
+#endif
+
+void Animation::grab_avvy(byte tripnum) { // For Friar Tuck, in Nottingham.
+ int16 tox = tr[0]._x + 17;
+ int16 toy = tr[0]._y - 1;
+ if ((tr[tripnum]._x == tox) && (tr[tripnum]._y == toy)) {
+ tr[tripnum].call_eachstep = false;
+ tr[tripnum].face = kDirLeft;
+ tr[tripnum].stopwalk();
+ // ... whatever ...
+ } else {
+ // Still some way to go.
+ if (tr[tripnum]._x < tox) {
+ tr[tripnum]._x += 5;
+ if (tr[tripnum]._x > tox)
+ tr[tripnum]._x = tox;
+ }
+ if (tr[tripnum]._y < toy)
+ tr[tripnum]._y++;
+ tr[tripnum].step++;
+ if (tr[tripnum].step == tr[tripnum]._stat.seq)
+ tr[tripnum].step = 0;
+ }
+}
+
+void Animation::take_a_step(byte &tripnum) {
+ if (tr[tripnum].ix == 0) {
+ tr[tripnum].step++;
+ if (tr[tripnum].step == tr[tripnum]._stat.seq)
+ tr[tripnum].step = 0;
+ tr[tripnum].count = 0;
+ }
+}
+
+void Animation::spin(byte whichway, byte &tripnum) {
+ if (tr[tripnum].face != whichway) {
+ tr[tripnum].face = whichway;
+ if (tr[tripnum].whichsprite == 2)
+ return; // Not for Spludwick
+
+ _vm->_gyro->_dna._geidaSpin += 1;
+ _vm->_gyro->_dna._geidaTime = 20;
+ if (_vm->_gyro->_dna._geidaSpin == 5) {
+ _vm->_scrolls->display("Steady on, Avvy, you'll make the poor girl dizzy!");
+ _vm->_gyro->_dna._geidaSpin = 0;
+ _vm->_gyro->_dna._geidaTime = 0; // knock out records
+ }
+ }
+}
+
+void Animation::geida_procs(byte tripnum) {
+ if (_vm->_gyro->_dna._geidaTime > 0) {
+ _vm->_gyro->_dna._geidaTime--;
+ if (_vm->_gyro->_dna._geidaTime == 0)
+ _vm->_gyro->_dna._geidaSpin = 0;
+ }
+
+ if (tr[tripnum]._y < (tr[0]._y - 2)) {
+ // Geida is further from the screen than Avvy.
+ spin(kDirDown, tripnum);
+ tr[tripnum].iy = 1;
+ tr[tripnum].ix = 0;
+ take_a_step(tripnum);
+ return;
+ } else if (tr[tripnum]._y > (tr[0]._y + 2)) {
+ // Avvy is further from the screen than Geida.
+ spin(kDirUp, tripnum);
+ tr[tripnum].iy = -1;
+ tr[tripnum].ix = 0;
+ take_a_step(tripnum);
+ return;
+ }
+
+ tr[tripnum].iy = 0;
+ // These 12-s are not in the original, I added them to make the following method more "smooth".
+ // Now the NPC which is following Avvy won't block his way and will walk next to him properly.
+ if (tr[tripnum]._x < tr[0]._x - tr[0].xs * 8 - 12) {
+ tr[tripnum].ix = tr[0].xs;
+ spin(kDirRight, tripnum);
+ take_a_step(tripnum);
+ } else if (tr[tripnum]._x > tr[0]._x + tr[0].xs * 8 + 12) {
+ tr[tripnum].ix = -tr[0].xs;
+ spin(kDirLeft, tripnum);
+ take_a_step(tripnum);
+ } else
+ tr[tripnum].ix = 0;
+}
+
+// That's all...
+
+void Animation::call_andexors() {
+ int8 order[5];
+ byte fv, temp;
+ bool ok;
+
+ for (int i = 0; i < 5; i++)
+ order[i] = -1;
+
+ for (fv = 0; fv < kSpriteNumbMax; fv++) {
+ if (tr[fv].quick && tr[fv]._visible)
+ order[fv] = fv;
+ }
+
+ do {
+ ok = true;
+ for (fv = 0; fv < 4; fv++) {
+ if (((order[fv] != -1) && (order[fv + 1] != -1))
+ && (tr[order[fv]]._y > tr[order[fv + 1]]._y)) {
+ // Swap them!
+ temp = order[fv];
+ order[fv] = order[fv + 1];
+ order[fv + 1] = temp;
+ ok = false;
+ }
+ }
+ } while (!ok);
+
+
+ _vm->_graphics->refreshBackground();
+
+ for (fv = 0; fv < 5; fv++) {
+ if (order[fv] > -1)
+ tr[order[fv]].andexor();
+ }
+}
+
+void Animation::trippancy_link() {
+ byte fv;
+
+ if (_vm->_gyro->_dropdownActive | _vm->_gyro->_onToolbar | _vm->_gyro->_seeScroll)
+ return;
+ for (fv = 0; fv < kSpriteNumbMax; fv++) {
+ if (tr[fv].quick && tr[fv]._visible)
+ tr[fv].walk();
+ }
+
+ call_andexors();
+
+ for (fv = 0; fv < kSpriteNumbMax; fv++) {
+ if (tr[fv].quick && tr[fv].call_eachstep) {
+ switch (tr[fv].eachstep) {
+ case procfollow_avvy_y :
+ follow_avvy_y(fv);
+ break;
+ case procback_and_forth :
+ back_and_forth(fv);
+ break;
+ case procface_avvy :
+ face_avvy(fv);
+ break;
+ case procarrow_procs :
+ arrow_procs(fv);
+ break;
+ // PROCSpludwick_procs : spludwick_procs(fv);
+ case procgrab_avvy :
+ grab_avvy(fv);
+ break;
+ case procgeida_procs :
+ geida_procs(fv);
+ break;
+ }
+ }
+ }
+
+ if (mustexclaim) {
+ mustexclaim = false;
+ _vm->_visa->dixi('x', saywhat);
+ }
+}
+
+void Animation::get_back_loretta() {
+ byte fv;
+
+ for (fv = 0; fv < kSpriteNumbMax; fv++) {
+ if (tr[fv].quick) {
+ getback();
+ return;
+ }
+ }
+ // for fv:=0 to 1 do begin cp:=1-cp; getback; end;
+}
+
+void Animation::stopwalking() {
+ tr[0].stopwalk();
+ _vm->_gyro->_dna._direction = kDirStopped;
+ if (_vm->_gyro->_alive)
+ tr[0].step = 1;
+}
+
+void Animation::tripkey(char dir) {
+ warning("Replaced by Trip::handleMoveKey!");
+}
+
+void Animation::readstick() {
+ warning("STUB: Trip::readstick()");
+}
+
+void Animation::getsetclear() {
+ for (byte fv = 0; fv <= 1; fv++)
+ getset[fv].init();
+}
+
+void Animation::hide_in_the_cupboard() {
+ if (_vm->_gyro->_dna._avvysInTheCupboard) {
+ if (_vm->_gyro->_dna._wearing == Acci::kNothing)
+ _vm->_scrolls->display(Common::String(_vm->_scrolls->kControlItalic) + "AVVY!" + _vm->_scrolls->kControlRoman + "Get dressed first!");
+ else {
+ tr[0]._visible = true;
+ _vm->_gyro->_dna._userMovesAvvy = true;
+ apped(1, 3); // Walk out of the cupboard.
+ _vm->_scrolls->display("You leave the cupboard. Nice to be out of there!");
+ _vm->_gyro->_dna._avvysInTheCupboard = false;
+ _vm->_sequence->first_show(8);
+ _vm->_sequence->then_show(7);
+ _vm->_sequence->start_to_close();
+ }
+ } else {
+ // Not hiding in the cupboard
+ tr[0]._visible = false;
+ _vm->_gyro->_dna._userMovesAvvy = false;
+ _vm->_scrolls->display(Common::String("You walk into the room...") + _vm->_scrolls->kControlParagraph
+ + "It seems to be an empty, but dusty, cupboard. Hmmmm... you leave the door slightly open to avoid suffocation.");
+ _vm->_gyro->_dna._avvysInTheCupboard = true;
+ _vm->_celer->drawBackgroundSprite(-1, -1, 8);
+ }
+}
+
+void Animation::fliproom(byte room, byte ped) {
+ byte fv;
+
+ if (!_vm->_gyro->_alive) {
+ // You can't leave the room if you're dead.
+ tr[0].ix = 0;
+ tr[0].iy = 0; // Stop him from moving.
+ return;
+ }
+
+ if ((room == 177) && (_vm->_gyro->_dna._room == r__lusties)) {
+ hide_in_the_cupboard();
+ return;
+ }
+
+ if ((_vm->_gyro->_dna._jumpStatus > 0) && (_vm->_gyro->_dna._room == r__insidecardiffcastle)) {
+ // You can't *jump* out of Cardiff Castle!
+ tr[0].ix = 0;
+ return;
+ }
+
+ _vm->_lucerna->exitRoom(_vm->_gyro->_dna._room);
+ _vm->_lucerna->dusk();
+ getsetclear();
+
+
+ for (fv = 1; fv < kSpriteNumbMax; fv++) {
+ if (tr[fv].quick)
+ tr[fv].done();
+ } // Deallocate sprite
+
+ if (_vm->_gyro->_dna._room == r__lustiesroom)
+ _vm->_gyro->_dna._enterCatacombsFromLustiesRoom = true;
+
+ _vm->_lucerna->enterRoom(room, ped);
+ apped(1, ped);
+ _vm->_gyro->_dna._enterCatacombsFromLustiesRoom = false;
+ _vm->_gyro->_oldDirection = _vm->_gyro->_dna._direction;
+ _vm->_gyro->_dna._direction = tr[0].face;
+ _vm->_lucerna->drawDirection();
+
+ for (fv = 0; fv <= 1; fv++) {
+ _vm->_gyro->_cp = 1 - _vm->_gyro->_cp;
+ getback();
+ }
+ _vm->_lucerna->dawn();
+
+ // Tidy up after mouse. I know it's a kludge...
+ // tidy_after_mouse;
+}
+
+bool Animation::infield(byte which) {
+ which--; // Pascal -> C: different array indexes.
+
+ int16 yy = tr[0]._y + tr[0]._info._yLength;
+
+ return (tr[0]._x >= _vm->_gyro->_fields[which]._x1) && (tr[0]._x <= _vm->_gyro->_fields[which]._x2)
+ && (yy >= _vm->_gyro->_fields[which]._y1) && (yy <= _vm->_gyro->_fields[which]._y2);
+
+}
+
+bool Animation::neardoor() {
+ if (_vm->_gyro->_fieldNum < 8) {
+ // there ARE no doors here!
+ return false;
+ }
+
+ int16 ux = tr[0]._x;
+ int16 uy = tr[0]._y + tr[0]._info._yLength;
+ bool nd = false;
+ for (byte fv = 8; fv < _vm->_gyro->_fieldNum; fv++)
+ if ((ux >= _vm->_gyro->_fields[fv]._x1) && (ux <= _vm->_gyro->_fields[fv]._x2)
+ && (uy >= _vm->_gyro->_fields[fv]._y1) && (uy <= _vm->_gyro->_fields[fv]._y2))
+ nd = true;
+ return nd;
+}
+
+void Animation::new_game_for_trippancy() { // Called by gyro.newgame
+ tr[0]._visible = false;
+}
+
+void Animation::handleMoveKey(const Common::Event &event) {
+ if (!_vm->_gyro->_dna._userMovesAvvy)
+ return;
+
+ if (_vm->_dropdown->_activeMenuItem._activeNow)
+ _vm->_parser->tryDropdown();
+ else {
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_UP:
+ if (_vm->_gyro->_dna._direction != kDirUp) {
+ _vm->_gyro->_dna._direction = kDirUp;
+ rwsp(0, _vm->_gyro->_dna._direction);
+ } else
+ stopwalking();
+ break;
+ case Common::KEYCODE_DOWN:
+ if (_vm->_gyro->_dna._direction != kDirDown) {
+ _vm->_gyro->_dna._direction = kDirDown;
+ rwsp(0, _vm->_gyro->_dna._direction);
+ } else
+ stopwalking();
+ break;
+ case Common::KEYCODE_LEFT:
+ if (_vm->_gyro->_dna._direction != kDirLeft) {
+ _vm->_gyro->_dna._direction = kDirLeft;
+ rwsp(0, _vm->_gyro->_dna._direction);
+ } else
+ stopwalking();
+ break;
+ case Common::KEYCODE_RIGHT:
+ if (_vm->_gyro->_dna._direction != kDirRight) {
+ _vm->_gyro->_dna._direction = kDirRight;
+ rwsp(0, _vm->_gyro->_dna._direction);
+ } else
+ stopwalking();
+ break;
+ case Common::KEYCODE_PAGEUP:
+ if (_vm->_gyro->_dna._direction != kDirUpRight) {
+ _vm->_gyro->_dna._direction = kDirUpRight;
+ rwsp(0, _vm->_gyro->_dna._direction);
+ } else
+ stopwalking();
+ break;
+ case Common::KEYCODE_PAGEDOWN:
+ if (_vm->_gyro->_dna._direction != kDirDownRight) {
+ _vm->_gyro->_dna._direction = kDirDownRight;
+ rwsp(0, _vm->_gyro->_dna._direction);
+ } else
+ stopwalking();
+ break;
+ case Common::KEYCODE_END:
+ if (_vm->_gyro->_dna._direction != kDirDownLeft) {
+ _vm->_gyro->_dna._direction = kDirDownLeft;
+ rwsp(0, _vm->_gyro->_dna._direction);
+ } else
+ stopwalking();
+ break;
+ case Common::KEYCODE_HOME:
+ if (_vm->_gyro->_dna._direction != kDirUpLeft) {
+ _vm->_gyro->_dna._direction = kDirUpLeft;
+ rwsp(0, _vm->_gyro->_dna._direction);
+ } else
+ stopwalking();
+ break;
+ case Common::KEYCODE_KP5:
+ stopwalking();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+} // End of namespace Avalanche.