aboutsummaryrefslogtreecommitdiff
path: root/engines/tony/tonychar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/tony/tonychar.cpp')
-rw-r--r--engines/tony/tonychar.cpp1945
1 files changed, 1945 insertions, 0 deletions
diff --git a/engines/tony/tonychar.cpp b/engines/tony/tonychar.cpp
new file mode 100644
index 0000000000..c7fa1e4a7b
--- /dev/null
+++ b/engines/tony/tonychar.cpp
@@ -0,0 +1,1945 @@
+/* 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 original Tony Tough source code
+ *
+ * Copyright (c) 1997-2003 Nayma Software
+ */
+
+#include "tony/mpal/memory.h"
+#include "tony/mpal/mpalutils.h"
+#include "tony/game.h"
+#include "tony/tonychar.h"
+#include "tony/tony.h"
+
+namespace Tony {
+
+bool RMTony::_bAction = false;
+
+void RMTony::initStatics() {
+ _bAction = false;
+}
+
+RMTony::RMTony() {
+ _bShow = false;
+ _bShowShadow = false;
+ _bBodyFront = false;
+ _bActionPending = false;
+ _actionItem = NULL;
+ _action = 0;
+ _actionParm = 0;
+ _bShepherdess = false;
+ _bIsStaticTalk = false;
+ _bIsTalking = false;
+ _nPatB4Talking = 0;
+ _nTalkType = TALK_NORMAL;
+ _talkDirection = UP;
+ _nTimeLastStep = 0;
+ _hActionThread = CORO_INVALID_PID_VALUE;
+}
+
+void RMTony::waitEndOfAction(CORO_PARAM, const void *param) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ uint32 pid = *(const uint32 *)param;
+
+ CORO_BEGIN_CODE(_ctx);
+
+ CORO_INVOKE_2(CoroScheduler.waitForSingleObject, pid, CORO_INFINITE);
+
+ _bAction = false;
+
+ CORO_END_CODE;
+}
+
+RMGfxSourceBuffer *RMTony::newItemSpriteBuffer(int dimx, int dimy, bool bPreRLE) {
+ RMGfxSourceBuffer8RLE *spr;
+
+ assert(_cm == CM_256);
+ spr = new RMGfxSourceBuffer8RLEByteAA;
+ spr->setAlphaBlendColor(1);
+ if (bPreRLE)
+ spr->setAlreadyCompressed();
+ return spr;
+}
+
+void RMTony::init() {
+ RMRes tony(0);
+ RMRes body(9999);
+
+ // Tony is shown by default
+ _bShow = _bShowShadow = true;
+
+ // No action pending
+ _bActionPending = false;
+ _bAction = false;
+
+ _bShepherdess = false;
+ _bIsTalking = false;
+ _bIsStaticTalk = false;
+
+ // Opens the buffer
+ Common::SeekableReadStream *ds = tony.getReadStream();
+
+ // Reads his details from the stream
+ readFromStream(*ds, true);
+
+ // Closes the buffer
+ delete ds;
+
+ // Reads Tony's body
+ ds = body.getReadStream();
+ _body.readFromStream(*ds, true);
+ delete ds;
+ _body.setPattern(0);
+
+ _nTimeLastStep = g_vm->getTime();
+}
+
+
+void RMTony::close() {
+ // Deallocation of missing item
+// _shadow.destroy();
+}
+
+void RMTony::doFrame(CORO_PARAM, RMGfxTargetBuffer *bigBuf, int curLoc) {
+ CORO_BEGIN_CONTEXT;
+ int time;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ if (!_nInList && _bShow)
+ bigBuf->addPrim(new RMGfxPrimitive(this));
+
+ setSpeed(GLOBALS._nCfgTonySpeed);
+
+ // Runs the normal character movement
+ _ctx->time = g_vm->getTime();
+
+ do {
+ _nTimeLastStep += (1000 / 40);
+ CORO_INVOKE_2(RMCharacter::doFrame, bigBuf, curLoc);
+ } while (_ctx->time > _nTimeLastStep + (1000 / 40));
+
+ // Check if we are at the end of a path
+ if (endOfPath() && _bActionPending) {
+ // Must perform the action on which we clicked
+ _bActionPending = false;
+ }
+
+ if (_bIsTalking || _bIsStaticTalk)
+ _body.doFrame(bigBuf, false);
+
+ CORO_END_CODE;
+}
+
+void RMTony::show() {
+ _bShow = true;
+ _bShowShadow = true;
+}
+
+void RMTony::hide(bool bShowShadow) {
+ _bShow = false;
+ _bShowShadow = bShowShadow;
+}
+
+
+void RMTony::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ // Call the Draw() of the parent class if Tony is visible
+ if (_bShow && _bDrawNow) {
+ if (_bBodyFront) {
+ prim->getDst().setEmpty();
+ prim->getDst().offset(-44, -134);
+ if (_bShepherdess)
+ prim->getDst().offset(1, 4);
+ CORO_INVOKE_2(RMCharacter::draw, bigBuf, prim);
+ }
+
+ if (_bIsTalking || _bIsStaticTalk) {
+ // Offest direction from scrolling
+ prim->getDst().setEmpty();
+ prim->getDst().offset(-_curScroll);
+ prim->getDst().offset(_pos);
+ prim->getDst().offset(-44, -134);
+ prim->getDst() += _nBodyOffset;
+ CORO_INVOKE_2(_body.draw, bigBuf, prim);
+ }
+
+ if (!_bBodyFront) {
+ prim->getDst().setEmpty();
+ prim->getDst().offset(-44, -134);
+ if (_bShepherdess)
+ prim->getDst().offset(0, 3);
+ CORO_INVOKE_2(RMCharacter::draw, bigBuf, prim);
+ }
+ }
+
+ CORO_END_CODE;
+}
+
+void RMTony::moveAndDoAction(CORO_PARAM, RMPoint dst, RMItem *item, int nAction, int nActionParm) {
+ CORO_BEGIN_CONTEXT;
+ bool result;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ // Makes normal movement, but remember if you must then perform an action
+ if (item == NULL) {
+ _bActionPending = false;
+ _actionItem = NULL;
+ } else {
+ _actionItem = item;
+ _action = nAction;
+ _actionParm = nActionParm;
+ _bActionPending = true;
+ }
+
+ CORO_INVOKE_2(RMCharacter::move, dst, &_ctx->result);
+ if (!_ctx->result) {
+ _bActionPending = false;
+ _actionItem = NULL;
+ }
+
+ CORO_END_CODE;
+}
+
+
+void RMTony::executeAction(int nAction, int nActionItem, int nParm) {
+ uint32 pid;
+
+ if (nAction == TA_COMBINE) {
+ pid = mpalQueryDoAction(TA_COMBINE, nParm, nActionItem);
+
+ // If you failed the combine, we have RECEIVECOMBINE as a fallback
+ if (pid == CORO_INVALID_PID_VALUE) {
+ pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, nParm);
+
+ // If you failed with that, go with the generic
+ // @@@ CombineGive!
+ if (pid == CORO_INVALID_PID_VALUE) {
+ pid = mpalQueryDoAction(TA_COMBINE, nParm, 0);
+
+ if (pid == CORO_INVALID_PID_VALUE) {
+ pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, 0);
+ }
+ }
+ }
+ } else {
+ // Perform the action
+ pid = mpalQueryDoAction(nAction, nActionItem, 0);
+ }
+
+ if (pid != CORO_INVALID_PID_VALUE) {
+ _bAction = true;
+ CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
+ _hActionThread = pid;
+ } else if (nAction != TA_GOTO) {
+ if (nAction == TA_TALK) {
+ pid = mpalQueryDoAction(6, 1, 0);
+ _bAction = true;
+ CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
+ _hActionThread = pid;
+ } else if (nAction == TA_PERORATE) {
+ pid = mpalQueryDoAction(7, 1, 0);
+ _bAction = true;
+ CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
+ _hActionThread = pid;
+ } else {
+ pid = mpalQueryDoAction(5, 1, 0);
+ _bAction = true;
+ CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
+ _hActionThread = pid;
+ }
+ }
+}
+
+
+void RMTony::stopNoAction(CORO_PARAM) {
+ CORO_BEGIN_CONTEXT;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ if (_bAction)
+ CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _hActionThread, CORO_INFINITE);
+
+ _bActionPending = false;
+ _actionItem = NULL;
+ CORO_INVOKE_0(stop);
+
+ CORO_END_CODE;
+}
+
+void RMTony::stop(CORO_PARAM) {
+ CORO_BEGIN_CONTEXT;
+ uint32 pid;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ if (_actionItem != NULL) {
+ // Call MPAL to choose the direction
+ _ctx->pid = mpalQueryDoAction(21, _actionItem->mpalCode(), 0);
+
+ if (_ctx->pid == CORO_INVALID_PID_VALUE)
+ CORO_INVOKE_0(RMCharacter::stop);
+ else {
+ _bNeedToStop = false; // If we make the OnWhichDirection, we don't need at least after the Stop().
+ _bMoving = false;
+ CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->pid, CORO_INFINITE); // @@@ Put an assert after 10 seconds
+ }
+ } else {
+ CORO_INVOKE_0(RMCharacter::stop);
+ }
+
+ if (!_bActionPending)
+ return;
+
+ _bActionPending = false;
+
+ executeAction(_action, _actionItem->mpalCode(), _actionParm);
+
+ _actionItem = NULL;
+
+ CORO_END_CODE;
+}
+
+
+int RMTony::getCurPattern() {
+ int nPatt = RMCharacter::getCurPattern();
+
+ if (!_bShepherdess)
+ return nPatt;
+
+ switch (nPatt) {
+ case PAT_PAST_STANDUP:
+ return PAT_STANDUP;
+ case PAT_PAST_STANDDOWN:
+ return PAT_STANDDOWN;
+ case PAT_PAST_STANDLEFT:
+ return PAT_STANDLEFT;
+ case PAT_PAST_STANDRIGHT:
+ return PAT_STANDRIGHT;
+ case PAT_PAST_WALKUP:
+ return PAT_WALKUP;
+ case PAT_PAST_WALKDOWN:
+ return PAT_WALKDOWN;
+ case PAT_PAST_WALKLEFT:
+ return PAT_WALKLEFT;
+ case PAT_PAST_WALKRIGHT:
+ return PAT_WALKRIGHT;
+ }
+
+ return nPatt;
+}
+
+void RMTony::setPattern(int nPatt, bool bPlayP0) {
+ if (_bShepherdess) {
+ switch (nPatt) {
+ case PAT_STANDUP:
+ nPatt = PAT_PAST_STANDUP;
+ break;
+ case PAT_STANDDOWN:
+ nPatt = PAT_PAST_STANDDOWN;
+ break;
+ case PAT_STANDLEFT:
+ nPatt = PAT_PAST_STANDLEFT;
+ break;
+ case PAT_STANDRIGHT:
+ nPatt = PAT_PAST_STANDRIGHT;
+ break;
+ case PAT_WALKUP:
+ nPatt = PAT_PAST_WALKUP;
+ break;
+ case PAT_WALKDOWN:
+ nPatt = PAT_PAST_WALKDOWN;
+ break;
+ case PAT_WALKLEFT:
+ nPatt = PAT_PAST_WALKLEFT;
+ break;
+ case PAT_WALKRIGHT:
+ nPatt = PAT_PAST_WALKRIGHT;
+ break;
+ }
+ }
+
+ RMCharacter::setPattern(nPatt, bPlayP0);
+}
+
+
+void RMTony::take(int nWhere, int nPart) {
+ if (nPart == 0) {
+ switch (getCurPattern()) {
+ case PAT_STANDDOWN:
+ assert(0); // Not while you're doing a StandDown
+ break;
+
+ case PAT_STANDUP:
+ switch (nWhere) {
+ case 0:
+ setPattern(PAT_TAKEUP_UP1);
+ break;
+ case 1:
+ setPattern(PAT_TAKEUP_MID1);
+ break;
+ case 2:
+ setPattern(PAT_TAKEUP_DOWN1);
+ break;
+ }
+ break;
+
+ case PAT_STANDRIGHT:
+ switch (nWhere) {
+ case 0:
+ setPattern(PAT_TAKERIGHT_UP1);
+ break;
+ case 1:
+ setPattern(PAT_TAKERIGHT_MID1);
+ break;
+ case 2:
+ setPattern(PAT_TAKERIGHT_DOWN1);
+ break;
+ }
+ break;
+
+ case PAT_STANDLEFT:
+ switch (nWhere) {
+ case 0:
+ setPattern(PAT_TAKELEFT_UP1);
+ break;
+ case 1:
+ setPattern(PAT_TAKELEFT_MID1);
+ break;
+ case 2:
+ setPattern(PAT_TAKELEFT_DOWN1);
+ break;
+ }
+ break;
+ }
+ } else if (nPart == 1) {
+ setPattern(getCurPattern() + 1);
+ } else if (nPart == 2) {
+ switch (getCurPattern()) {
+ case PAT_TAKEUP_UP2:
+ case PAT_TAKEUP_MID2:
+ case PAT_TAKEUP_DOWN2:
+ setPattern(PAT_STANDUP);
+ break;
+
+ case PAT_TAKELEFT_UP2:
+ case PAT_TAKELEFT_MID2:
+ case PAT_TAKELEFT_DOWN2:
+ setPattern(PAT_STANDLEFT);
+ break;
+
+ case PAT_TAKERIGHT_UP2:
+ case PAT_TAKERIGHT_MID2:
+ case PAT_TAKERIGHT_DOWN2:
+ setPattern(PAT_STANDRIGHT);
+ break;
+ }
+ }
+}
+
+
+void RMTony::put(int nWhere, int nPart) {
+ if (nPart == 0) {
+ switch (getCurPattern()) {
+ case PAT_STANDDOWN:
+ break;
+
+ case PAT_STANDUP:
+ switch (nWhere) {
+ case 0:
+ setPattern(PAT_PUTUP_UP1);
+ break;
+ case 1:
+ setPattern(PAT_PUTUP_MID1);
+ break;
+ case 2:
+ setPattern(PAT_PUTUP_DOWN1);
+ break;
+ }
+ break;
+
+ case PAT_STANDRIGHT:
+ switch (nWhere) {
+ case 0:
+ setPattern(PAT_PUTRIGHT_UP1);
+ break;
+ case 1:
+ setPattern(PAT_PUTRIGHT_MID1);
+ break;
+ case 2:
+ setPattern(PAT_PUTRIGHT_DOWN1);
+ break;
+ }
+ break;
+
+ case PAT_STANDLEFT:
+ switch (nWhere) {
+ case 0:
+ setPattern(PAT_PUTLEFT_UP1);
+ break;
+ case 1:
+ setPattern(PAT_PUTLEFT_MID1);
+ break;
+ case 2:
+ setPattern(PAT_PUTLEFT_DOWN1);
+ break;
+ }
+ break;
+ }
+ } else if (nPart == 1) {
+ setPattern(getCurPattern() + 1);
+ } else if (nPart == 2) {
+ switch (getCurPattern()) {
+ case PAT_PUTUP_UP2:
+ case PAT_PUTUP_MID2:
+ case PAT_PUTUP_DOWN2:
+ setPattern(PAT_STANDUP);
+ break;
+
+ case PAT_PUTLEFT_UP2:
+ case PAT_PUTLEFT_MID2:
+ case PAT_PUTLEFT_DOWN2:
+ setPattern(PAT_STANDLEFT);
+ break;
+
+ case PAT_PUTRIGHT_UP2:
+ case PAT_PUTRIGHT_MID2:
+ case PAT_PUTRIGHT_DOWN2:
+ setPattern(PAT_STANDRIGHT);
+ break;
+ }
+ }
+}
+
+
+bool RMTony::startTalkCalculate(CharacterTalkType nTalkType, int &headStartPat, int &bodyStartPat,
+ int &headLoopPat, int &bodyLoopPat) {
+ assert(!_bIsTalking);
+
+ _bIsTalking = true;
+ _nPatB4Talking = getCurPattern();
+ _nTalkType = nTalkType;
+
+ // Set the direction of speech ONLY if we are not in a static animation (since it would have already been done)
+ if (!_bIsStaticTalk) {
+ switch (_nPatB4Talking) {
+ case PAT_STANDDOWN:
+ _talkDirection = DOWN;
+ break;
+
+ case PAT_TAKELEFT_UP2:
+ case PAT_TAKELEFT_MID2:
+ case PAT_TAKELEFT_DOWN2:
+ case PAT_GETUPLEFT:
+ case PAT_STANDLEFT:
+ _talkDirection = LEFT;
+ break;
+
+ case PAT_TAKERIGHT_UP2:
+ case PAT_TAKERIGHT_MID2:
+ case PAT_TAKERIGHT_DOWN2:
+ case PAT_GETUPRIGHT:
+ case PAT_STANDRIGHT:
+ _talkDirection = RIGHT;
+ break;
+
+ case PAT_TAKEUP_UP2:
+ case PAT_TAKEUP_MID2:
+ case PAT_TAKEUP_DOWN2:
+ case PAT_STANDUP:
+ _talkDirection = UP;
+ break;
+ }
+
+ // Puts the body in front by default
+ _bBodyFront = true;
+ }
+
+ if (_bShepherdess) {
+ // Talking whilst a shepherdess
+ switch (_talkDirection) {
+ case UP:
+ setPattern(PAT_PAST_TALKUP);
+ break;
+
+ case DOWN:
+ setPattern(PAT_PAST_TALKDOWN);
+ break;
+
+ case LEFT:
+ setPattern(PAT_PAST_TALKLEFT);
+ break;
+
+ case RIGHT:
+ setPattern(PAT_PAST_TALKRIGHT);
+ break;
+ }
+ return false;
+ }
+
+ headStartPat = bodyStartPat = 0;
+ bodyLoopPat = 0;
+
+ switch (nTalkType) {
+ case TALK_NORMAL:
+ _bBodyFront = false;
+ headStartPat = 0;
+ bodyStartPat = 0;
+
+ switch (_talkDirection) {
+ case DOWN:
+ headLoopPat = PAT_TALK_DOWN;
+ bodyLoopPat = BPAT_STANDDOWN;
+ _nBodyOffset.set(4, 53);
+ break;
+
+ case LEFT:
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_STANDLEFT;
+ _nBodyOffset.set(6, 56);
+ break;
+
+ case RIGHT:
+ headLoopPat = PAT_TALK_RIGHT;
+ bodyLoopPat = BPAT_STANDRIGHT;
+ _nBodyOffset.set(6, 56);
+ break;
+
+ case UP:
+ headLoopPat = PAT_TALK_UP;
+ bodyLoopPat = BPAT_STANDUP;
+ _nBodyOffset.set(6, 53);
+ break;
+ }
+ break;
+
+ case TALK_HIPS:
+ _bBodyFront = false;
+ switch (_talkDirection) {
+ case UP:
+ _nBodyOffset.set(2, 42);
+ headStartPat = PAT_HEAD_UP;
+ bodyStartPat = BPAT_HIPSUP_START;
+ headLoopPat = PAT_TALK_UP;
+ bodyLoopPat = BPAT_HIPSUP_LOOP;
+ break;
+
+ case DOWN:
+ _nBodyOffset.set(2, 48);
+ headStartPat = PAT_HEAD_DOWN;
+ bodyStartPat = BPAT_HIPSDOWN_START;
+ headLoopPat = PAT_TALK_DOWN;
+ bodyLoopPat = BPAT_HIPSDOWN_LOOP;
+ break;
+
+ case LEFT:
+ _nBodyOffset.set(-3, 53);
+ headStartPat = PAT_HEAD_LEFT;
+ bodyStartPat = BPAT_HIPSLEFT_START;
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_HIPSLEFT_LOOP;
+ break;
+
+ case RIGHT:
+ _nBodyOffset.set(2, 53);
+ headStartPat = PAT_HEAD_RIGHT;
+ bodyStartPat = BPAT_HIPSRIGHT_START;
+ headLoopPat = PAT_TALK_RIGHT;
+ bodyLoopPat = BPAT_HIPSRIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_SING:
+ _nBodyOffset.set(-10, 25);
+ headStartPat = PAT_HEAD_LEFT;
+ bodyStartPat = BPAT_SINGLEFT_START;
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_SINGLEFT_LOOP;
+ break;
+
+ case TALK_LAUGH:
+ _bBodyFront = false;
+ switch (_talkDirection) {
+ case UP:
+ case DOWN:
+ case LEFT:
+ _nBodyOffset.set(6, 56);
+ headStartPat = PAT_LAUGHLEFT_START;
+ bodyStartPat = BPAT_STANDLEFT;
+ headLoopPat = PAT_LAUGHLEFT_LOOP;
+ bodyLoopPat = BPAT_LAUGHLEFT;
+ break;
+
+ case RIGHT:
+ _nBodyOffset.set(6, 56);
+ headStartPat = PAT_LAUGHRIGHT_START;
+ bodyStartPat = BPAT_STANDRIGHT;
+ headLoopPat = PAT_LAUGHRIGHT_LOOP;
+ bodyLoopPat = BPAT_LAUGHRIGHT;
+ break;
+ }
+ break;
+
+ case TALK_LAUGH2:
+ _bBodyFront = false;
+ switch (_talkDirection) {
+ case UP:
+ case DOWN:
+ case LEFT:
+ _nBodyOffset.set(6, 56);
+ headStartPat = PAT_LAUGHLEFT_START;
+ bodyStartPat = BPAT_STANDLEFT;
+ headLoopPat = PAT_LAUGHLEFT_LOOP;
+ break;
+
+ case RIGHT:
+ _nBodyOffset.set(6, 56);
+ headStartPat = PAT_LAUGHRIGHT_START;
+ bodyStartPat = BPAT_STANDRIGHT;
+ headLoopPat = PAT_LAUGHRIGHT_LOOP;
+ bodyLoopPat = BPAT_LAUGHRIGHT;
+ break;
+ }
+ break;
+
+ case TALK_INDICATE:
+ switch (_talkDirection) {
+ case UP:
+ case DOWN:
+ case LEFT:
+ _nBodyOffset.set(-4, 40);
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_INDICATELEFT;
+ break;
+
+ case RIGHT:
+ _nBodyOffset.set(5, 40);
+ headLoopPat = PAT_TALK_RIGHT;
+ bodyLoopPat = BPAT_INDICATERIGHT;
+ break;
+ }
+ break;
+
+ case TALK_SCARED:
+ switch (_talkDirection) {
+ case UP:
+ _nBodyOffset.set(-4, -11);
+ headStartPat = PAT_HEAD_UP;
+ bodyStartPat = BPAT_SCAREDUP_START;
+ headLoopPat = PAT_TALK_UP;
+ bodyLoopPat = BPAT_SCAREDUP_LOOP;
+ break;
+
+ case DOWN:
+ _nBodyOffset.set(-5, 45);
+ headStartPat = PAT_SCAREDDOWN_START;
+ bodyStartPat = BPAT_SCAREDDOWN_START;
+ headLoopPat = PAT_SCAREDDOWN_LOOP;
+ bodyLoopPat = BPAT_SCAREDDOWN_LOOP;
+ break;
+
+ case RIGHT:
+ _nBodyOffset.set(-4, 41);
+ headStartPat = PAT_SCAREDRIGHT_START;
+ bodyStartPat = BPAT_SCAREDRIGHT_START;
+ headLoopPat = PAT_SCAREDRIGHT_LOOP;
+ bodyLoopPat = BPAT_SCAREDRIGHT_LOOP;
+ break;
+
+ case LEFT:
+ _nBodyOffset.set(-10, 41);
+ headStartPat = PAT_SCAREDLEFT_START;
+ bodyStartPat = BPAT_SCAREDLEFT_START;
+ headLoopPat = PAT_SCAREDLEFT_LOOP;
+ bodyLoopPat = BPAT_SCAREDLEFT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_SCARED2:
+ _bBodyFront = false;
+ switch (_talkDirection) {
+ case UP:
+ bodyStartPat = BPAT_STANDUP;
+ bodyLoopPat = BPAT_STANDUP;
+ _nBodyOffset.set(6, 53);
+
+ headStartPat = PAT_HEAD_UP;
+ headLoopPat = PAT_TALK_UP;
+ break;
+
+ case DOWN:
+ bodyStartPat = BPAT_STANDDOWN;
+ bodyLoopPat = BPAT_STANDDOWN;
+ _nBodyOffset.set(4, 53);
+
+ headStartPat = PAT_SCAREDDOWN_START;
+ headLoopPat = PAT_SCAREDDOWN_LOOP;
+ break;
+
+ case RIGHT:
+ bodyStartPat = BPAT_STANDRIGHT;
+ bodyLoopPat = BPAT_STANDRIGHT;
+ _nBodyOffset.set(6, 56);
+
+ headStartPat = PAT_SCAREDRIGHT_START;
+ headLoopPat = PAT_SCAREDRIGHT_LOOP;
+ break;
+
+ case LEFT:
+ bodyStartPat = BPAT_STANDLEFT;
+ bodyLoopPat = BPAT_STANDLEFT;
+ _nBodyOffset.set(6, 56);
+
+ headStartPat = PAT_SCAREDLEFT_START;
+ headLoopPat = PAT_SCAREDLEFT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_WITHGLASSES:
+ _nBodyOffset.set(4, 53);
+ headLoopPat = PAT_TALK_DOWN;
+ bodyLoopPat = BPAT_GLASS;
+ break;
+ case TALK_WITHWORM:
+ _nBodyOffset.set(9, 56);
+ headLoopPat = PAT_TALK_RIGHT;
+ bodyLoopPat = BPAT_WORM;
+ break;
+ case TALK_WITHHAMMER:
+ _nBodyOffset.set(6, 56);
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_HAMMER;
+ break;
+ case TALK_WITHROPE:
+ _nBodyOffset.set(-3, 38);
+ headLoopPat = PAT_TALK_RIGHT;
+ bodyLoopPat = BPAT_ROPE;
+ break;
+ case TALK_WITHSECRETARY:
+ _nBodyOffset.set(-17, 12);
+ headLoopPat = PAT_TALK_RIGHT;
+ bodyLoopPat = BPAT_WITHSECRETARY;
+ break;
+
+ case TALK_WITHRABBIT:
+ switch (_talkDirection) {
+ case LEFT:
+ case UP:
+ _nBodyOffset.set(-21, -5);
+ bodyStartPat = BPAT_WITHRABBITLEFT_START;
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_WITHRABBITLEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(-4, -5);
+ bodyStartPat = BPAT_WITHRABBITRIGHT_START;
+ headLoopPat = PAT_TALK_RIGHT;
+ bodyLoopPat = BPAT_WITHRABBITRIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_WITHRECIPE:
+ switch (_talkDirection) {
+ case LEFT:
+ case UP:
+ _nBodyOffset.set(-61, -7);
+ bodyStartPat = BPAT_WITHRECIPELEFT_START;
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_WITHRECIPELEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(-5, -7);
+ bodyStartPat = BPAT_WITHRECIPERIGHT_START;
+ headLoopPat = PAT_TALK_RIGHT;
+ bodyLoopPat = BPAT_WITHRECIPERIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_WITHCARDS:
+ switch (_talkDirection) {
+ case LEFT:
+ case UP:
+ _nBodyOffset.set(-34, -2);
+ bodyStartPat = BPAT_WITHCARDSLEFT_START;
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_WITHCARDSLEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(-4, -2);
+ bodyStartPat = BPAT_WITHCARDSRIGHT_START;
+ headLoopPat = PAT_TALK_RIGHT;
+ bodyLoopPat = BPAT_WITHCARDSRIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_WITHSNOWMAN:
+ switch (_talkDirection) {
+ case LEFT:
+ case UP:
+ _nBodyOffset.set(-35, 2);
+ bodyStartPat = BPAT_WITHSNOWMANLEFT_START;
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_WITHSNOWMANLEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(-14, 2);
+ bodyStartPat = BPAT_WITHSNOWMANRIGHT_START;
+ headLoopPat = PAT_TALK_RIGHT;
+ bodyLoopPat = BPAT_WITHSNOWMANRIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_WITHSNOWMANSTATIC:
+ case TALK_WITHRECIPESTATIC:
+ case TALK_WITHRABBITSTATIC:
+ case TALK_WITHCARDSSTATIC:
+ case TALK_WITH_NOTEBOOK:
+ case TALK_WITHMEGAPHONESTATIC:
+ switch (_talkDirection) {
+ case LEFT:
+ case UP:
+ headLoopPat = PAT_TALK_LEFT;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ headLoopPat = PAT_TALK_RIGHT;
+ break;
+ }
+ break;
+
+ // The beard is the only case in which the head is animated separately while the body is the standard
+ case TALK_WITHBEARDSTATIC:
+ switch (_talkDirection) {
+ case LEFT:
+ case UP:
+ headLoopPat = PAT_TALKBEARD_LEFT;
+ bodyLoopPat = BPAT_STANDLEFT;
+ _nBodyOffset.set(6, 56);
+ break;
+
+ case DOWN:
+ case RIGHT:
+ headLoopPat = PAT_TALKBEARD_RIGHT;
+ bodyLoopPat = BPAT_STANDRIGHT;
+ _nBodyOffset.set(6, 56);
+ break;
+ }
+ break;
+
+ case TALK_DISGUSTED:
+ switch (_talkDirection) {
+ case LEFT:
+ case UP:
+ _nBodyOffset.set(6, 56);
+ headStartPat = PAT_DISGUSTEDLEFT_START;
+ bodyStartPat = BPAT_STANDLEFT;
+ headLoopPat = PAT_DISGUSTEDLEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(6, 56);
+ headStartPat = PAT_DISGUSTEDRIGHT_START;
+ bodyStartPat = BPAT_STANDRIGHT;
+ headLoopPat = PAT_DISGUSTEDRIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_SARCASTIC:
+ switch (_talkDirection) {
+ case LEFT:
+ case UP:
+ _nBodyOffset.set(6, 56);
+ headStartPat = PAT_SARCASTICLEFT_START;
+ bodyStartPat = BPAT_STANDLEFT;
+ headLoopPat = PAT_SARCASTICLEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(6, 56);
+ headStartPat = PAT_SARCASTICRIGHT_START;
+ bodyStartPat = BPAT_STANDRIGHT;
+ headLoopPat = PAT_SARCASTICRIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_MACBETH1:
+ _nBodyOffset.set(-33, -1);
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_MACBETH1;
+ break;
+ case TALK_MACBETH2:
+ _nBodyOffset.set(-33, -1);
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_MACBETH2;
+ break;
+ case TALK_MACBETH3:
+ _nBodyOffset.set(-33, -1);
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_MACBETH3;
+ break;
+ case TALK_MACBETH4:
+ _nBodyOffset.set(-33, -1);
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_MACBETH4;
+ break;
+ case TALK_MACBETH5:
+ _nBodyOffset.set(-33, -1);
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_MACBETH5;
+ break;
+ case TALK_MACBETH6:
+ _nBodyOffset.set(-33, -1);
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_MACBETH6;
+ break;
+ case TALK_MACBETH7:
+ _nBodyOffset.set(-33, -1);
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_MACBETH7;
+ break;
+ case TALK_MACBETH8:
+ _nBodyOffset.set(-33, -1);
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_MACBETH8;
+ break;
+ case TALK_MACBETH9:
+ _nBodyOffset.set(-33, -1);
+ headLoopPat = PAT_TALK_LEFT;
+ bodyLoopPat = BPAT_MACBETH9;
+ break;
+
+ case TALK_SCAREDSTATIC:
+ _bBodyFront = false;
+ switch (_talkDirection) {
+ case DOWN:
+ bodyStartPat = BPAT_STANDDOWN;
+ bodyLoopPat = BPAT_STANDDOWN;
+ _nBodyOffset.set(4, 53);
+
+ headStartPat = PAT_SCAREDDOWN_STAND;
+ headLoopPat = PAT_SCAREDDOWN_LOOP;
+ break;
+
+ case RIGHT:
+ bodyStartPat = BPAT_STANDRIGHT;
+ bodyLoopPat = BPAT_STANDRIGHT;
+ _nBodyOffset.set(6, 56);
+
+ headStartPat = PAT_SCAREDRIGHT_STAND;
+ headLoopPat = PAT_SCAREDRIGHT_LOOP;
+ break;
+
+ case LEFT:
+ bodyStartPat = BPAT_STANDLEFT;
+ bodyLoopPat = BPAT_STANDLEFT;
+ _nBodyOffset.set(6, 56);
+
+ headStartPat = PAT_SCAREDLEFT_STAND;
+ headLoopPat = PAT_SCAREDLEFT_LOOP;
+ break;
+
+ default:
+ break;
+ }
+ break;
+ }
+
+ return true;
+}
+
+void RMTony::startTalk(CORO_PARAM, CharacterTalkType nTalkType) {
+ CORO_BEGIN_CONTEXT;
+ int headStartPat, bodyStartPat;
+ int headLoopPat, bodyLoopPat;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ _ctx->headStartPat = _ctx->bodyStartPat = 0;
+ _ctx->headLoopPat = _ctx->bodyLoopPat = 0;
+
+ if (!startTalkCalculate(nTalkType, _ctx->headStartPat, _ctx->bodyStartPat,
+ _ctx->headLoopPat, _ctx->bodyLoopPat))
+ return;
+
+ // Perform the set pattern
+ if (_ctx->headStartPat != 0 || _ctx->bodyStartPat != 0) {
+ setPattern(_ctx->headStartPat);
+ _body.setPattern(_ctx->bodyStartPat);
+
+ if (_ctx->bodyStartPat != 0)
+ CORO_INVOKE_0(_body.waitForEndPattern);
+ if (_ctx->headStartPat != 0)
+ CORO_INVOKE_0(waitForEndPattern);
+ }
+
+ setPattern(_ctx->headLoopPat);
+ if (_ctx->bodyLoopPat)
+ _body.setPattern(_ctx->bodyLoopPat);
+
+ CORO_END_CODE;
+}
+
+
+bool RMTony::endTalkCalculate(int &headStandPat, int &headEndPat, int &bodyEndPat, int &finalPat, bool &bStatic) {
+ bodyEndPat = 0;
+ headEndPat = 0;
+
+ switch (_talkDirection) {
+ case UP:
+ finalPat = PAT_STANDUP;
+ headStandPat = PAT_HEAD_UP;
+ break;
+
+ case DOWN:
+ finalPat = PAT_STANDDOWN;
+ headStandPat = PAT_HEAD_DOWN;
+ break;
+
+ case LEFT:
+ finalPat = PAT_STANDLEFT;
+ headStandPat = PAT_HEAD_LEFT;
+ break;
+
+ case RIGHT:
+ finalPat = PAT_STANDRIGHT;
+ headStandPat = PAT_HEAD_RIGHT;
+ break;
+ }
+
+ if (_bShepherdess) {
+ setPattern(finalPat);
+ _bIsTalking = false;
+ return false;
+ }
+
+ bStatic = false;
+ switch (_nTalkType) {
+ case TALK_NORMAL:
+ bodyEndPat = 0;
+ break;
+
+ case TALK_HIPS:
+ switch (_talkDirection) {
+ case UP:
+ bodyEndPat = BPAT_HIPSUP_END;
+ break;
+
+ case DOWN:
+ bodyEndPat = BPAT_HIPSDOWN_END;
+ break;
+
+ case LEFT:
+ bodyEndPat = BPAT_HIPSLEFT_END;
+ break;
+
+ case RIGHT:
+ bodyEndPat = BPAT_HIPSRIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_SING:
+ bodyEndPat = BPAT_SINGLEFT_END;
+ break;
+
+ case TALK_LAUGH:
+ case TALK_LAUGH2:
+ if (_talkDirection == LEFT)
+ headEndPat = PAT_LAUGHLEFT_END;
+ else if (_talkDirection == RIGHT)
+ headEndPat = PAT_LAUGHRIGHT_END;
+
+ bodyEndPat = 0;
+ break;
+
+ case TALK_DISGUSTED:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ headEndPat = PAT_DISGUSTEDLEFT_END;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ headEndPat = PAT_DISGUSTEDRIGHT_END;
+ break;
+ }
+
+ bodyEndPat = 0;
+ break;
+
+ case TALK_SARCASTIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ headEndPat = PAT_SARCASTICLEFT_END;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ headEndPat = PAT_SARCASTICRIGHT_END;
+ break;
+ }
+
+ bodyEndPat = 0;
+ break;
+
+ case TALK_INDICATE:
+ break;
+
+ case TALK_SCARED:
+ switch (_talkDirection) {
+ case UP:
+ bodyEndPat = BPAT_SCAREDUP_END;
+ break;
+
+ case DOWN:
+ headEndPat = PAT_SCAREDDOWN_END;
+ bodyEndPat = BPAT_SCAREDDOWN_END;
+ break;
+
+ case RIGHT:
+ headEndPat = PAT_SCAREDRIGHT_END;
+ bodyEndPat = BPAT_SCAREDRIGHT_END;
+ break;
+
+ case LEFT:
+ headEndPat = PAT_SCAREDLEFT_END;
+ bodyEndPat = BPAT_SCAREDLEFT_END;
+ break;
+ }
+ break;
+
+ case TALK_SCARED2:
+ switch (_talkDirection) {
+ case UP:
+ bodyEndPat = 0;
+ break;
+
+ case DOWN:
+ headEndPat = PAT_SCAREDDOWN_END;
+ bodyEndPat = 0;
+ break;
+
+ case RIGHT:
+ headEndPat = PAT_SCAREDRIGHT_END;
+ bodyEndPat = 0;
+ break;
+
+ case LEFT:
+ headEndPat = PAT_SCAREDLEFT_END;
+ bodyEndPat = 0;
+ break;
+ }
+ break;
+
+ case TALK_WITHRABBIT:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ finalPat = PAT_STANDLEFT;
+ bodyEndPat = BPAT_WITHRABBITLEFT_END;
+ break;
+
+ case RIGHT:
+ case DOWN:
+ finalPat = PAT_STANDRIGHT;
+ bodyEndPat = BPAT_WITHRABBITRIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_WITHRECIPE:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ finalPat = PAT_STANDLEFT;
+ bodyEndPat = BPAT_WITHRECIPELEFT_END;
+ break;
+
+ case RIGHT:
+ case DOWN:
+ finalPat = PAT_STANDRIGHT;
+ bodyEndPat = BPAT_WITHRECIPERIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_WITHCARDS:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ finalPat = PAT_STANDLEFT;
+ bodyEndPat = BPAT_WITHCARDSLEFT_END;
+ break;
+
+ case RIGHT:
+ case DOWN:
+ finalPat = PAT_STANDRIGHT;
+ bodyEndPat = BPAT_WITHCARDSRIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_WITHSNOWMAN:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ finalPat = PAT_STANDLEFT;
+ bodyEndPat = BPAT_WITHSNOWMANLEFT_END;
+ break;
+
+ case RIGHT:
+ case DOWN:
+ finalPat = PAT_STANDRIGHT;
+ bodyEndPat = BPAT_WITHSNOWMANRIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_WITHWORM:
+ finalPat = PAT_WITHWORM;
+ break;
+ case TALK_WITHROPE:
+ finalPat = PAT_WITHROPE;
+ break;
+ case TALK_WITHSECRETARY:
+ finalPat = PAT_WITHSECRETARY;
+ break;
+ case TALK_WITHHAMMER:
+ finalPat = PAT_WITHHAMMER;
+ break;
+ case TALK_WITHGLASSES:
+ finalPat = PAT_WITHGLASSES;
+ break;
+
+ case TALK_MACBETH1:
+ case TALK_MACBETH2:
+ case TALK_MACBETH3:
+ case TALK_MACBETH4:
+ case TALK_MACBETH5:
+ case TALK_MACBETH6:
+ case TALK_MACBETH7:
+ case TALK_MACBETH8:
+ finalPat = 0;
+ break;
+
+ case TALK_SCAREDSTATIC:
+ switch (_talkDirection) {
+ case DOWN:
+ headStandPat = PAT_SCAREDDOWN_STAND;
+ bodyEndPat = 0;
+ break;
+
+ case RIGHT:
+ headStandPat = PAT_SCAREDRIGHT_STAND;
+ bodyEndPat = 0;
+ break;
+
+ case LEFT:
+ headStandPat = PAT_SCAREDLEFT_STAND;
+ bodyEndPat = 0;
+ break;
+
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+void RMTony::endTalk(CORO_PARAM) {
+ CORO_BEGIN_CONTEXT;
+ int headStandPat, headEndPat;
+ int bodyEndPat, finalPat;
+ bool bStatic;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ _ctx->headStandPat = _ctx->headEndPat = 0;
+ _ctx->bodyEndPat = _ctx->finalPat = 0;
+ _ctx->bStatic = false;
+
+ _ctx->bodyEndPat = 0;
+ _ctx->headEndPat = 0;
+
+ if (!endTalkCalculate(_ctx->headStandPat, _ctx->headEndPat, _ctx->bodyEndPat, _ctx->finalPat, _ctx->bStatic))
+ return;
+
+ // Handles the end of an animated and static, leaving everything unchanged
+ if (_bIsStaticTalk) {
+ if (_nTalkType == TALK_WITHBEARDSTATIC) {
+ setPattern(0);
+ if (_talkDirection == UP || _talkDirection == LEFT) {
+ _body.setPattern(BPAT_WITHBEARDLEFT_STATIC);
+ _nBodyOffset.set(-41, -14);
+ } else if (_talkDirection == DOWN || _talkDirection == RIGHT) {
+ _body.setPattern(BPAT_WITHBEARDRIGHT_STATIC);
+ _nBodyOffset.set(-26, -14);
+ }
+ } else {
+ setPattern(_ctx->headStandPat);
+
+ CORO_INVOKE_0(_body.waitForEndPattern);
+ }
+
+ _bIsTalking = false;
+ return;
+ }
+
+ // Set the pattern
+ if (_ctx->headEndPat != 0 && _ctx->bodyEndPat != 0) {
+ setPattern(_ctx->headEndPat);
+
+ CORO_INVOKE_0(_body.waitForEndPattern);
+
+ _body.setPattern(_ctx->bodyEndPat);
+
+ CORO_INVOKE_0(waitForEndPattern);
+ CORO_INVOKE_0(_body.waitForEndPattern);
+ } else if (_ctx->bodyEndPat != 0) {
+ setPattern(_ctx->headStandPat);
+
+ CORO_INVOKE_0(_body.waitForEndPattern);
+
+ _body.setPattern(_ctx->bodyEndPat);
+
+ CORO_INVOKE_0(_body.waitForEndPattern);
+ } else if (_ctx->headEndPat != 0) {
+ CORO_INVOKE_0(_body.waitForEndPattern);
+
+ setPattern(_ctx->headEndPat);
+
+ CORO_INVOKE_0(waitForEndPattern);
+ } else {
+ CORO_INVOKE_0(_body.waitForEndPattern);
+ }
+
+ if (_ctx->finalPat != 0) {
+ _body.setPattern(0);
+ setPattern(_ctx->finalPat);
+ }
+
+ _bIsTalking = false;
+
+ CORO_END_CODE;
+}
+
+void RMTony::startStaticCalculate(CharacterTalkType nTalk, int &headPat, int &headLoopPat,
+ int &bodyStartPat, int &bodyLoopPat) {
+ int nPat = getCurPattern();
+
+ headLoopPat = -1;
+
+ switch (nPat) {
+ case PAT_STANDDOWN:
+ _talkDirection = DOWN;
+ headPat = PAT_HEAD_RIGHT;
+ break;
+
+ case PAT_TAKELEFT_UP2:
+ case PAT_TAKELEFT_MID2:
+ case PAT_TAKELEFT_DOWN2:
+ case PAT_GETUPLEFT:
+ case PAT_STANDLEFT:
+ _talkDirection = LEFT;
+ headPat = PAT_HEAD_LEFT;
+ break;
+
+ case PAT_TAKERIGHT_UP2:
+ case PAT_TAKERIGHT_MID2:
+ case PAT_TAKERIGHT_DOWN2:
+ case PAT_GETUPRIGHT:
+ case PAT_STANDRIGHT:
+ _talkDirection = RIGHT;
+ headPat = PAT_HEAD_RIGHT;
+ break;
+
+ case PAT_TAKEUP_UP2:
+ case PAT_TAKEUP_MID2:
+ case PAT_TAKEUP_DOWN2:
+ case PAT_STANDUP:
+ _talkDirection = UP;
+ headPat = PAT_HEAD_LEFT;
+ break;
+ }
+
+ _bBodyFront = true;
+
+ switch (nTalk) {
+ case TALK_WITHRABBITSTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ _nBodyOffset.set(-21, -5);
+ bodyStartPat = BPAT_WITHRABBITLEFT_START;
+ bodyLoopPat = BPAT_WITHRABBITLEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(-4, -5);
+ bodyStartPat = BPAT_WITHRABBITRIGHT_START;
+ bodyLoopPat = BPAT_WITHRABBITRIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_WITHCARDSSTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ _nBodyOffset.set(-34, -2);
+ bodyStartPat = BPAT_WITHCARDSLEFT_START;
+ bodyLoopPat = BPAT_WITHCARDSLEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(-4, -2);
+ bodyStartPat = BPAT_WITHCARDSRIGHT_START;
+ bodyLoopPat = BPAT_WITHCARDSRIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_WITHRECIPESTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ _nBodyOffset.set(-61, -7);
+ bodyStartPat = BPAT_WITHRECIPELEFT_START;
+ bodyLoopPat = BPAT_WITHRECIPELEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(-5, -7);
+ bodyStartPat = BPAT_WITHRECIPERIGHT_START;
+ bodyLoopPat = BPAT_WITHRECIPERIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_WITHSNOWMANSTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ _nBodyOffset.set(-35, 2);
+ bodyStartPat = BPAT_WITHSNOWMANLEFT_START;
+ bodyLoopPat = BPAT_WITHSNOWMANLEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(-14, 2);
+ bodyStartPat = BPAT_WITHSNOWMANRIGHT_START;
+ bodyLoopPat = BPAT_WITHSNOWMANRIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_WITH_NOTEBOOK:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ _nBodyOffset.set(-16, -9);
+ bodyStartPat = BPAT_WITHNOTEBOOKLEFT_START;
+ bodyLoopPat = BPAT_WITHNOTEBOOKLEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(-6, -9);
+ bodyStartPat = BPAT_WITHNOTEBOOKRIGHT_START;
+ bodyLoopPat = BPAT_WITHNOTEBOOKRIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_WITHMEGAPHONESTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ _nBodyOffset.set(-41, -8);
+ bodyStartPat = BPAT_WITHMEGAPHONELEFT_START;
+ bodyLoopPat = BPAT_WITHMEGAPHONELEFT_LOOP;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(-14, -8);
+ bodyStartPat = BPAT_WITHMEGAPHONERIGHT_START;
+ bodyLoopPat = BPAT_WITHMEGAPHONERIGHT_LOOP;
+ break;
+ }
+ break;
+
+ case TALK_WITHBEARDSTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ _nBodyOffset.set(-41, -14);
+ bodyStartPat = BPAT_WITHBEARDLEFT_START;
+ bodyLoopPat = BPAT_STANDLEFT;
+ headLoopPat = PAT_TALKBEARD_LEFT;
+ headPat = 0;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ _nBodyOffset.set(-26, -14);
+ bodyStartPat = BPAT_WITHBEARDRIGHT_START;
+ bodyLoopPat = BPAT_STANDRIGHT;
+ headLoopPat = PAT_TALKBEARD_RIGHT;
+ headPat = 0;
+ break;
+ }
+ break;
+
+ case TALK_SCAREDSTATIC:
+ switch (_talkDirection) {
+ case DOWN:
+ headPat = PAT_SCAREDDOWN_START;
+ bodyLoopPat = BPAT_STANDDOWN;
+ bodyStartPat = BPAT_STANDDOWN;
+ headLoopPat = PAT_SCAREDDOWN_STAND;
+ _nBodyOffset.set(4, 53);
+ break;
+
+ case LEFT:
+ headPat = PAT_SCAREDLEFT_START;
+ bodyLoopPat = BPAT_STANDLEFT;
+ bodyStartPat = BPAT_STANDLEFT;
+ headLoopPat = PAT_SCAREDLEFT_STAND;
+ _nBodyOffset.set(6, 56);
+ break;
+
+ case RIGHT:
+ headPat = PAT_SCAREDRIGHT_START;
+ bodyLoopPat = BPAT_STANDRIGHT;
+ bodyStartPat = BPAT_STANDRIGHT;
+ headLoopPat = PAT_SCAREDRIGHT_STAND;
+ _nBodyOffset.set(6, 56);
+ break;
+
+ default:
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+void RMTony::startStatic(CORO_PARAM, CharacterTalkType nTalk) {
+ CORO_BEGIN_CONTEXT;
+ int headPat, headLoopPat;
+ int bodyStartPat, bodyLoopPat;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ _ctx->headPat = _ctx->headLoopPat = 0;
+ _ctx->bodyStartPat = _ctx->bodyLoopPat = 0;
+
+ startStaticCalculate(nTalk, _ctx->headPat, _ctx->headLoopPat,
+ _ctx->bodyStartPat, _ctx->bodyLoopPat);
+
+ // e vai con i pattern
+ _bIsStaticTalk = true;
+
+ setPattern(_ctx->headPat);
+ _body.setPattern(_ctx->bodyStartPat);
+
+ CORO_INVOKE_0(_body.waitForEndPattern);
+ CORO_INVOKE_0(waitForEndPattern);
+
+ if (_ctx->headLoopPat != -1)
+ setPattern(_ctx->headLoopPat);
+ _body.setPattern(_ctx->bodyLoopPat);
+
+ CORO_END_CODE;
+}
+
+void RMTony::endStaticCalculate(CharacterTalkType nTalk, int &bodyEndPat, int &finalPat, int &headEndPat) {
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ finalPat = PAT_STANDLEFT;
+ break;
+
+ case RIGHT:
+ case DOWN:
+ finalPat = PAT_STANDRIGHT;
+ break;
+ }
+
+ switch (nTalk) {
+ case TALK_WITHSNOWMANSTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ bodyEndPat = BPAT_WITHSNOWMANLEFT_END;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ bodyEndPat = BPAT_WITHSNOWMANRIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_WITHRECIPESTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ bodyEndPat = BPAT_WITHRECIPELEFT_END;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ bodyEndPat = BPAT_WITHRECIPERIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_WITHRABBITSTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ bodyEndPat = BPAT_WITHRABBITLEFT_END;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ bodyEndPat = BPAT_WITHRABBITRIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_WITHCARDSSTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ bodyEndPat = BPAT_WITHCARDSLEFT_END;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ bodyEndPat = BPAT_WITHCARDSRIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_WITH_NOTEBOOK:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ bodyEndPat = BPAT_WITHNOTEBOOKLEFT_END;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ bodyEndPat = BPAT_WITHNOTEBOOKRIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_WITHMEGAPHONESTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ bodyEndPat = BPAT_WITHMEGAPHONELEFT_END;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ bodyEndPat = BPAT_WITHMEGAPHONERIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_WITHBEARDSTATIC:
+ switch (_talkDirection) {
+ case UP:
+ case LEFT:
+ bodyEndPat = BPAT_WITHBEARDLEFT_END;
+ break;
+
+ case DOWN:
+ case RIGHT:
+ bodyEndPat = BPAT_WITHBEARDRIGHT_END;
+ break;
+ }
+ break;
+
+ case TALK_SCAREDSTATIC:
+ switch (_talkDirection) {
+ case LEFT:
+ headEndPat = PAT_SCAREDLEFT_END;
+ break;
+
+ case DOWN:
+ headEndPat = PAT_SCAREDDOWN_END;
+ break;
+
+ case RIGHT:
+ headEndPat = PAT_SCAREDRIGHT_END;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void RMTony::endStatic(CORO_PARAM, CharacterTalkType nTalk) {
+ CORO_BEGIN_CONTEXT;
+ int bodyEndPat;
+ int finalPat;
+ int headEndPat;
+ CORO_END_CONTEXT(_ctx);
+
+ CORO_BEGIN_CODE(_ctx);
+
+ _ctx->bodyEndPat = 0;
+ _ctx->finalPat = 0;
+ _ctx->headEndPat = 0;
+
+ endStaticCalculate(nTalk, _ctx->bodyEndPat, _ctx->finalPat, _ctx->headEndPat);
+
+ if (_ctx->headEndPat != 0) {
+ setPattern(_ctx->headEndPat);
+
+ CORO_INVOKE_0(waitForEndPattern);
+ } else {
+ // Play please
+ _body.setPattern(_ctx->bodyEndPat);
+
+ CORO_INVOKE_0(_body.waitForEndPattern);
+ }
+
+ setPattern(_ctx->finalPat);
+ _body.setPattern(0);
+
+ _bIsStaticTalk = false;
+
+ CORO_END_CODE;
+}
+
+/**
+ * Waits until the end of a pattern
+ */
+void RMTony::waitForEndPattern(CORO_PARAM, uint32 hCustomSkip) {
+ RMCharacter::waitForEndPattern(coroParam, hCustomSkip);
+}
+
+/**
+ * Check if currently in an action
+ */
+bool RMTony::inAction() {
+ return (_bActionPending && _action != 0) | _bAction;
+}
+
+/**
+ * Check if there needs to be an update for scrolling movement
+ */
+bool RMTony::mustUpdateScrolling() {
+ return ((!inAction()) || (isMoving()));
+}
+
+/**
+ * Returns Tony's position
+ */
+RMPoint RMTony::position() {
+ return _pos;
+}
+
+/**
+ * Set the scrolling position
+ */
+void RMTony::setScrollPosition(const RMPoint &pt) {
+ RMCharacter::setScrollPosition(pt);
+}
+
+/**
+ * Tony disguises himself!
+ */
+void RMTony::setShepherdess(bool bIsPast) {
+ _bShepherdess = bIsPast;
+}
+
+int RMTony::getShepherdess() {
+ return _bShepherdess;
+}
+
+void RMTony::playSfx(int nSfx) {
+ RMItem::playSfx(nSfx);
+}
+
+} // End of namespace Tony