1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 /*
24 * This code is based on original Tony Tough source code
25 *
26 * Copyright (c) 1997-2003 Nayma Software
27 */
28
29 #include "tony/mpal/memory.h"
30 #include "tony/mpal/mpalutils.h"
31 #include "tony/game.h"
32 #include "tony/tonychar.h"
33 #include "tony/tony.h"
34
35 namespace Tony {
36
37 bool RMTony::_bAction = false;
38
initStatics()39 void RMTony::initStatics() {
40 _bAction = false;
41 }
42
RMTony()43 RMTony::RMTony() {
44 _bShow = false;
45 _bShowShadow = false;
46 _bBodyFront = false;
47 _bActionPending = false;
48 _actionItem = NULL;
49 _action = 0;
50 _actionParm = 0;
51 _bShepherdess = false;
52 _bIsStaticTalk = false;
53 _bIsTalking = false;
54 _nPatB4Talking = 0;
55 _nTalkType = TALK_NORMAL;
56 _talkDirection = UP;
57 _nTimeLastStep = 0;
58 _hActionThread = CORO_INVALID_PID_VALUE;
59 }
60
waitEndOfAction(CORO_PARAM,const void * param)61 void RMTony::waitEndOfAction(CORO_PARAM, const void *param) {
62 CORO_BEGIN_CONTEXT;
63 CORO_END_CONTEXT(_ctx);
64
65 uint32 pid = *(const uint32 *)param;
66
67 CORO_BEGIN_CODE(_ctx);
68
69 CORO_INVOKE_2(CoroScheduler.waitForSingleObject, pid, CORO_INFINITE);
70
71 _bAction = false;
72
73 CORO_END_CODE;
74 }
75
newItemSpriteBuffer(int dimx,int dimy,bool bPreRLE)76 RMGfxSourceBuffer *RMTony::newItemSpriteBuffer(int dimx, int dimy, bool bPreRLE) {
77 RMGfxSourceBuffer8RLE *spr;
78
79 assert(_cm == CM_256);
80 spr = new RMGfxSourceBuffer8RLEByteAA;
81 spr->setAlphaBlendColor(1);
82 if (bPreRLE)
83 spr->setAlreadyCompressed();
84 return spr;
85 }
86
init()87 void RMTony::init() {
88 RMRes tony(0);
89 RMRes body(9999);
90
91 // Tony is shown by default
92 _bShow = _bShowShadow = true;
93
94 // No action pending
95 _bActionPending = false;
96 _bAction = false;
97
98 _bShepherdess = false;
99 _bIsTalking = false;
100 _bIsStaticTalk = false;
101
102 // Opens the buffer
103 Common::SeekableReadStream *ds = tony.getReadStream();
104
105 // Reads his details from the stream
106 readFromStream(*ds, true);
107
108 // Closes the buffer
109 delete ds;
110
111 // Reads Tony's body
112 ds = body.getReadStream();
113 _body.readFromStream(*ds, true);
114 delete ds;
115 _body.setPattern(0);
116
117 _nTimeLastStep = g_vm->getTime();
118 }
119
120
close()121 void RMTony::close() {
122 // Deallocation of missing item
123 //_shadow.destroy();
124 }
125
doFrame(CORO_PARAM,RMGfxTargetBuffer * bigBuf,int curLoc)126 void RMTony::doFrame(CORO_PARAM, RMGfxTargetBuffer *bigBuf, int curLoc) {
127 CORO_BEGIN_CONTEXT;
128 int time;
129 CORO_END_CONTEXT(_ctx);
130
131 CORO_BEGIN_CODE(_ctx);
132
133 if (!_nInList && _bShow)
134 bigBuf->addPrim(new RMGfxPrimitive(this));
135
136 setSpeed(GLOBALS._nCfgTonySpeed);
137
138 // Runs the normal character movement
139 _ctx->time = g_vm->getTime();
140
141 do {
142 _nTimeLastStep += (1000 / 40);
143 CORO_INVOKE_2(RMCharacter::doFrame, bigBuf, curLoc);
144 } while (_ctx->time > _nTimeLastStep + (1000 / 40));
145
146 // Check if we are at the end of a path
147 if (endOfPath() && _bActionPending) {
148 // Must perform the action on which we clicked
149 _bActionPending = false;
150 }
151
152 if (_bIsTalking || _bIsStaticTalk)
153 _body.doFrame(bigBuf, false);
154
155 CORO_END_CODE;
156 }
157
show()158 void RMTony::show() {
159 _bShow = true;
160 _bShowShadow = true;
161 }
162
hide(bool bShowShadow)163 void RMTony::hide(bool bShowShadow) {
164 _bShow = false;
165 _bShowShadow = bShowShadow;
166 }
167
draw(CORO_PARAM,RMGfxTargetBuffer & bigBuf,RMGfxPrimitive * prim)168 void RMTony::draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
169 CORO_BEGIN_CONTEXT;
170 CORO_END_CONTEXT(_ctx);
171
172 CORO_BEGIN_CODE(_ctx);
173
174 // Call the Draw() of the parent class if Tony is visible
175 if (_bShow && _bDrawNow) {
176 if (_bBodyFront) {
177 prim->getDst().setEmpty();
178 prim->getDst().offset(-44, -134);
179 if (_bShepherdess)
180 prim->getDst().offset(1, 4);
181 CORO_INVOKE_2(RMCharacter::draw, bigBuf, prim);
182 }
183
184 if (_bIsTalking || _bIsStaticTalk) {
185 // Offest direction from scrolling
186 prim->getDst().setEmpty();
187 prim->getDst().offset(-_curScroll);
188 prim->getDst().offset(_pos);
189 prim->getDst().offset(-44, -134);
190 prim->getDst() += _nBodyOffset;
191 CORO_INVOKE_2(_body.draw, bigBuf, prim);
192 }
193
194 if (!_bBodyFront) {
195 prim->getDst().setEmpty();
196 prim->getDst().offset(-44, -134);
197 if (_bShepherdess)
198 prim->getDst().offset(0, 3);
199 CORO_INVOKE_2(RMCharacter::draw, bigBuf, prim);
200 }
201 }
202
203 CORO_END_CODE;
204 }
205
moveAndDoAction(CORO_PARAM,RMPoint dst,RMItem * item,int nAction,int nActionParm)206 void RMTony::moveAndDoAction(CORO_PARAM, RMPoint dst, RMItem *item, int nAction, int nActionParm) {
207 CORO_BEGIN_CONTEXT;
208 bool result;
209 CORO_END_CONTEXT(_ctx);
210
211 CORO_BEGIN_CODE(_ctx);
212
213 // Makes normal movement, but remember if you must then perform an action
214 if (item == NULL) {
215 _bActionPending = false;
216 _actionItem = NULL;
217 } else {
218 _actionItem = item;
219 _action = nAction;
220 _actionParm = nActionParm;
221 _bActionPending = true;
222 }
223
224 CORO_INVOKE_2(RMCharacter::move, dst, &_ctx->result);
225 if (!_ctx->result) {
226 _bActionPending = false;
227 _actionItem = NULL;
228 }
229
230 CORO_END_CODE;
231 }
232
executeAction(int nAction,int nActionItem,int nParm)233 void RMTony::executeAction(int nAction, int nActionItem, int nParm) {
234 uint32 pid;
235
236 if (nAction == TA_COMBINE) {
237 pid = mpalQueryDoAction(TA_COMBINE, nParm, nActionItem);
238
239 // If you failed the combine, we have RECEIVECOMBINE as a fallback
240 if (pid == CORO_INVALID_PID_VALUE) {
241 pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, nParm);
242
243 // If you failed with that, go with the generic
244 // @@@ CombineGive!
245 if (pid == CORO_INVALID_PID_VALUE) {
246 pid = mpalQueryDoAction(TA_COMBINE, nParm, 0);
247
248 if (pid == CORO_INVALID_PID_VALUE) {
249 pid = mpalQueryDoAction(TA_RECEIVECOMBINE, nActionItem, 0);
250 }
251 }
252 }
253 } else {
254 // Perform the action
255 pid = mpalQueryDoAction(nAction, nActionItem, 0);
256 }
257
258 if (pid != CORO_INVALID_PID_VALUE) {
259 _bAction = true;
260 CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
261 _hActionThread = pid;
262 } else if (nAction != TA_GOTO) {
263 if (nAction == TA_TALK) {
264 pid = mpalQueryDoAction(6, 1, 0);
265 _bAction = true;
266 CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
267 _hActionThread = pid;
268 } else if (nAction == TA_PERORATE) {
269 pid = mpalQueryDoAction(7, 1, 0);
270 _bAction = true;
271 CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
272 _hActionThread = pid;
273 } else {
274 pid = mpalQueryDoAction(5, 1, 0);
275 _bAction = true;
276 CoroScheduler.createProcess(waitEndOfAction, &pid, sizeof(uint32));
277 _hActionThread = pid;
278 }
279 }
280 }
281
stopNoAction(CORO_PARAM)282 void RMTony::stopNoAction(CORO_PARAM) {
283 CORO_BEGIN_CONTEXT;
284 CORO_END_CONTEXT(_ctx);
285
286 CORO_BEGIN_CODE(_ctx);
287
288 if (_bAction)
289 CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _hActionThread, CORO_INFINITE);
290
291 _bActionPending = false;
292 _actionItem = NULL;
293 CORO_INVOKE_0(stop);
294
295 CORO_END_CODE;
296 }
297
stop(CORO_PARAM)298 void RMTony::stop(CORO_PARAM) {
299 CORO_BEGIN_CONTEXT;
300 uint32 pid;
301 CORO_END_CONTEXT(_ctx);
302
303 CORO_BEGIN_CODE(_ctx);
304
305 if (_actionItem != NULL) {
306 // Call MPAL to choose the direction
307 _ctx->pid = mpalQueryDoAction(21, _actionItem->mpalCode(), 0);
308
309 if (_ctx->pid == CORO_INVALID_PID_VALUE)
310 CORO_INVOKE_0(RMCharacter::stop);
311 else {
312 _bNeedToStop = false; // If we make the OnWhichDirection, we don't need at least after the Stop().
313 _bMoving = false;
314 CORO_INVOKE_2(CoroScheduler.waitForSingleObject, _ctx->pid, CORO_INFINITE); // @@@ Put an assert after 10 seconds
315 }
316 } else {
317 CORO_INVOKE_0(RMCharacter::stop);
318 }
319
320 if (!_bActionPending)
321 return;
322
323 _bActionPending = false;
324
325 executeAction(_action, _actionItem->mpalCode(), _actionParm);
326
327 _actionItem = NULL;
328
329 CORO_END_CODE;
330 }
331
getCurPattern()332 int RMTony::getCurPattern() {
333 int nPatt = RMCharacter::getCurPattern();
334
335 if (!_bShepherdess)
336 return nPatt;
337
338 switch (nPatt) {
339 case PAT_PAST_STANDUP:
340 return PAT_STANDUP;
341 case PAT_PAST_STANDDOWN:
342 return PAT_STANDDOWN;
343 case PAT_PAST_STANDLEFT:
344 return PAT_STANDLEFT;
345 case PAT_PAST_STANDRIGHT:
346 return PAT_STANDRIGHT;
347 case PAT_PAST_WALKUP:
348 return PAT_WALKUP;
349 case PAT_PAST_WALKDOWN:
350 return PAT_WALKDOWN;
351 case PAT_PAST_WALKLEFT:
352 return PAT_WALKLEFT;
353 case PAT_PAST_WALKRIGHT:
354 return PAT_WALKRIGHT;
355 default:
356 break;
357 }
358
359 return nPatt;
360 }
361
setPattern(int nPatt,bool bPlayP0)362 void RMTony::setPattern(int nPatt, bool bPlayP0) {
363 if (_bShepherdess) {
364 switch (nPatt) {
365 case PAT_STANDUP:
366 nPatt = PAT_PAST_STANDUP;
367 break;
368 case PAT_STANDDOWN:
369 nPatt = PAT_PAST_STANDDOWN;
370 break;
371 case PAT_STANDLEFT:
372 nPatt = PAT_PAST_STANDLEFT;
373 break;
374 case PAT_STANDRIGHT:
375 nPatt = PAT_PAST_STANDRIGHT;
376 break;
377 case PAT_WALKUP:
378 nPatt = PAT_PAST_WALKUP;
379 break;
380 case PAT_WALKDOWN:
381 nPatt = PAT_PAST_WALKDOWN;
382 break;
383 case PAT_WALKLEFT:
384 nPatt = PAT_PAST_WALKLEFT;
385 break;
386 case PAT_WALKRIGHT:
387 nPatt = PAT_PAST_WALKRIGHT;
388 break;
389 default:
390 break;
391 }
392 }
393
394 RMCharacter::setPattern(nPatt, bPlayP0);
395 }
396
take(int nWhere,int nPart)397 void RMTony::take(int nWhere, int nPart) {
398 if (nPart == 0) {
399 switch (getCurPattern()) {
400 case PAT_STANDDOWN:
401 assert(0); // Not while you're doing a StandDown
402 break;
403
404 case PAT_STANDUP:
405 switch (nWhere) {
406 case 0:
407 setPattern(PAT_TAKEUP_UP1);
408 break;
409 case 1:
410 setPattern(PAT_TAKEUP_MID1);
411 break;
412 case 2:
413 setPattern(PAT_TAKEUP_DOWN1);
414 break;
415 default:
416 break;
417 }
418 break;
419
420 case PAT_STANDRIGHT:
421 switch (nWhere) {
422 case 0:
423 setPattern(PAT_TAKERIGHT_UP1);
424 break;
425 case 1:
426 setPattern(PAT_TAKERIGHT_MID1);
427 break;
428 case 2:
429 setPattern(PAT_TAKERIGHT_DOWN1);
430 break;
431 default:
432 break;
433 }
434 break;
435
436 case PAT_STANDLEFT:
437 switch (nWhere) {
438 case 0:
439 setPattern(PAT_TAKELEFT_UP1);
440 break;
441 case 1:
442 setPattern(PAT_TAKELEFT_MID1);
443 break;
444 case 2:
445 setPattern(PAT_TAKELEFT_DOWN1);
446 break;
447 default:
448 break;
449 }
450 break;
451
452 default:
453 break;
454 }
455 } else if (nPart == 1) {
456 setPattern(getCurPattern() + 1);
457 } else if (nPart == 2) {
458 switch (getCurPattern()) {
459 case PAT_TAKEUP_UP2:
460 case PAT_TAKEUP_MID2:
461 case PAT_TAKEUP_DOWN2:
462 setPattern(PAT_STANDUP);
463 break;
464
465 case PAT_TAKELEFT_UP2:
466 case PAT_TAKELEFT_MID2:
467 case PAT_TAKELEFT_DOWN2:
468 setPattern(PAT_STANDLEFT);
469 break;
470
471 case PAT_TAKERIGHT_UP2:
472 case PAT_TAKERIGHT_MID2:
473 case PAT_TAKERIGHT_DOWN2:
474 setPattern(PAT_STANDRIGHT);
475 break;
476
477 default:
478 break;
479 }
480 }
481 }
482
put(int nWhere,int nPart)483 void RMTony::put(int nWhere, int nPart) {
484 if (nPart == 0) {
485 switch (getCurPattern()) {
486 case PAT_STANDDOWN:
487 break;
488
489 case PAT_STANDUP:
490 switch (nWhere) {
491 case 0:
492 setPattern(PAT_PUTUP_UP1);
493 break;
494 case 1:
495 setPattern(PAT_PUTUP_MID1);
496 break;
497 case 2:
498 setPattern(PAT_PUTUP_DOWN1);
499 break;
500 default:
501 break;
502 }
503 break;
504
505 case PAT_STANDRIGHT:
506 switch (nWhere) {
507 case 0:
508 setPattern(PAT_PUTRIGHT_UP1);
509 break;
510 case 1:
511 setPattern(PAT_PUTRIGHT_MID1);
512 break;
513 case 2:
514 setPattern(PAT_PUTRIGHT_DOWN1);
515 break;
516 default:
517 break;
518 }
519 break;
520
521 case PAT_STANDLEFT:
522 switch (nWhere) {
523 case 0:
524 setPattern(PAT_PUTLEFT_UP1);
525 break;
526 case 1:
527 setPattern(PAT_PUTLEFT_MID1);
528 break;
529 case 2:
530 setPattern(PAT_PUTLEFT_DOWN1);
531 break;
532 default:
533 break;
534 }
535 break;
536
537 default:
538 break;
539 }
540 } else if (nPart == 1) {
541 setPattern(getCurPattern() + 1);
542 } else if (nPart == 2) {
543 switch (getCurPattern()) {
544 case PAT_PUTUP_UP2:
545 case PAT_PUTUP_MID2:
546 case PAT_PUTUP_DOWN2:
547 setPattern(PAT_STANDUP);
548 break;
549
550 case PAT_PUTLEFT_UP2:
551 case PAT_PUTLEFT_MID2:
552 case PAT_PUTLEFT_DOWN2:
553 setPattern(PAT_STANDLEFT);
554 break;
555
556 case PAT_PUTRIGHT_UP2:
557 case PAT_PUTRIGHT_MID2:
558 case PAT_PUTRIGHT_DOWN2:
559 setPattern(PAT_STANDRIGHT);
560 break;
561
562 default:
563 break;
564 }
565 }
566 }
567
startTalkCalculate(CharacterTalkType nTalkType,int & headStartPat,int & bodyStartPat,int & headLoopPat,int & bodyLoopPat)568 bool RMTony::startTalkCalculate(CharacterTalkType nTalkType, int &headStartPat, int &bodyStartPat,
569 int &headLoopPat, int &bodyLoopPat) {
570 assert(!_bIsTalking);
571
572 _bIsTalking = true;
573 _nPatB4Talking = getCurPattern();
574 _nTalkType = nTalkType;
575
576 // Set the direction of speech ONLY if we are not in a static animation (since it would have already been done)
577 if (!_bIsStaticTalk) {
578 switch (_nPatB4Talking) {
579 case PAT_STANDDOWN:
580 _talkDirection = DOWN;
581 break;
582
583 case PAT_TAKELEFT_UP2:
584 case PAT_TAKELEFT_MID2:
585 case PAT_TAKELEFT_DOWN2:
586 case PAT_GETUPLEFT:
587 case PAT_STANDLEFT:
588 _talkDirection = LEFT;
589 break;
590
591 case PAT_TAKERIGHT_UP2:
592 case PAT_TAKERIGHT_MID2:
593 case PAT_TAKERIGHT_DOWN2:
594 case PAT_GETUPRIGHT:
595 case PAT_STANDRIGHT:
596 _talkDirection = RIGHT;
597 break;
598
599 case PAT_TAKEUP_UP2:
600 case PAT_TAKEUP_MID2:
601 case PAT_TAKEUP_DOWN2:
602 case PAT_STANDUP:
603 _talkDirection = UP;
604 break;
605
606 default:
607 break;
608 }
609
610 // Puts the body in front by default
611 _bBodyFront = true;
612 }
613
614 if (_bShepherdess) {
615 // Talking whilst a shepherdess
616 switch (_talkDirection) {
617 case UP:
618 setPattern(PAT_PAST_TALKUP);
619 break;
620
621 case DOWN:
622 setPattern(PAT_PAST_TALKDOWN);
623 break;
624
625 case LEFT:
626 setPattern(PAT_PAST_TALKLEFT);
627 break;
628
629 case RIGHT:
630 setPattern(PAT_PAST_TALKRIGHT);
631 break;
632
633 default:
634 break;
635 }
636 return false;
637 }
638
639 headStartPat = bodyStartPat = 0;
640 bodyLoopPat = 0;
641
642 switch (nTalkType) {
643 case TALK_NORMAL:
644 _bBodyFront = false;
645 headStartPat = 0;
646 bodyStartPat = 0;
647
648 switch (_talkDirection) {
649 case DOWN:
650 headLoopPat = PAT_TALK_DOWN;
651 bodyLoopPat = BPAT_STANDDOWN;
652 _nBodyOffset.set(4, 53);
653 break;
654
655 case LEFT:
656 headLoopPat = PAT_TALK_LEFT;
657 bodyLoopPat = BPAT_STANDLEFT;
658 _nBodyOffset.set(6, 56);
659 break;
660
661 case RIGHT:
662 headLoopPat = PAT_TALK_RIGHT;
663 bodyLoopPat = BPAT_STANDRIGHT;
664 _nBodyOffset.set(6, 56);
665 break;
666
667 case UP:
668 headLoopPat = PAT_TALK_UP;
669 bodyLoopPat = BPAT_STANDUP;
670 _nBodyOffset.set(6, 53);
671 break;
672
673 default:
674 break;
675 }
676 break;
677
678 case TALK_HIPS:
679 _bBodyFront = false;
680 switch (_talkDirection) {
681 case UP:
682 _nBodyOffset.set(2, 42);
683 headStartPat = PAT_HEAD_UP;
684 bodyStartPat = BPAT_HIPSUP_START;
685 headLoopPat = PAT_TALK_UP;
686 bodyLoopPat = BPAT_HIPSUP_LOOP;
687 break;
688
689 case DOWN:
690 _nBodyOffset.set(2, 48);
691 headStartPat = PAT_HEAD_DOWN;
692 bodyStartPat = BPAT_HIPSDOWN_START;
693 headLoopPat = PAT_TALK_DOWN;
694 bodyLoopPat = BPAT_HIPSDOWN_LOOP;
695 break;
696
697 case LEFT:
698 _nBodyOffset.set(-3, 53);
699 headStartPat = PAT_HEAD_LEFT;
700 bodyStartPat = BPAT_HIPSLEFT_START;
701 headLoopPat = PAT_TALK_LEFT;
702 bodyLoopPat = BPAT_HIPSLEFT_LOOP;
703 break;
704
705 case RIGHT:
706 _nBodyOffset.set(2, 53);
707 headStartPat = PAT_HEAD_RIGHT;
708 bodyStartPat = BPAT_HIPSRIGHT_START;
709 headLoopPat = PAT_TALK_RIGHT;
710 bodyLoopPat = BPAT_HIPSRIGHT_LOOP;
711 break;
712
713 default:
714 break;
715 }
716 break;
717
718 case TALK_SING:
719 _nBodyOffset.set(-10, 25);
720 headStartPat = PAT_HEAD_LEFT;
721 bodyStartPat = BPAT_SINGLEFT_START;
722 headLoopPat = PAT_TALK_LEFT;
723 bodyLoopPat = BPAT_SINGLEFT_LOOP;
724 break;
725
726 case TALK_LAUGH:
727 _bBodyFront = false;
728 switch (_talkDirection) {
729 case UP:
730 case DOWN:
731 case LEFT:
732 _nBodyOffset.set(6, 56);
733 headStartPat = PAT_LAUGHLEFT_START;
734 bodyStartPat = BPAT_STANDLEFT;
735 headLoopPat = PAT_LAUGHLEFT_LOOP;
736 bodyLoopPat = BPAT_LAUGHLEFT;
737 break;
738
739 case RIGHT:
740 _nBodyOffset.set(6, 56);
741 headStartPat = PAT_LAUGHRIGHT_START;
742 bodyStartPat = BPAT_STANDRIGHT;
743 headLoopPat = PAT_LAUGHRIGHT_LOOP;
744 bodyLoopPat = BPAT_LAUGHRIGHT;
745 break;
746
747 default:
748 break;
749 }
750 break;
751
752 case TALK_LAUGH2:
753 _bBodyFront = false;
754 switch (_talkDirection) {
755 case UP:
756 case DOWN:
757 case LEFT:
758 _nBodyOffset.set(6, 56);
759 headStartPat = PAT_LAUGHLEFT_START;
760 bodyStartPat = BPAT_STANDLEFT;
761 headLoopPat = PAT_LAUGHLEFT_LOOP;
762 break;
763
764 case RIGHT:
765 _nBodyOffset.set(6, 56);
766 headStartPat = PAT_LAUGHRIGHT_START;
767 bodyStartPat = BPAT_STANDRIGHT;
768 headLoopPat = PAT_LAUGHRIGHT_LOOP;
769 bodyLoopPat = BPAT_LAUGHRIGHT;
770 break;
771
772 default:
773 break;
774 }
775 break;
776
777 case TALK_INDICATE:
778 switch (_talkDirection) {
779 case UP:
780 case DOWN:
781 case LEFT:
782 _nBodyOffset.set(-4, 40);
783 headLoopPat = PAT_TALK_LEFT;
784 bodyLoopPat = BPAT_INDICATELEFT;
785 break;
786
787 case RIGHT:
788 _nBodyOffset.set(5, 40);
789 headLoopPat = PAT_TALK_RIGHT;
790 bodyLoopPat = BPAT_INDICATERIGHT;
791 break;
792
793 default:
794 break;
795 }
796 break;
797
798 case TALK_SCARED:
799 switch (_talkDirection) {
800 case UP:
801 _nBodyOffset.set(-4, -11);
802 headStartPat = PAT_HEAD_UP;
803 bodyStartPat = BPAT_SCAREDUP_START;
804 headLoopPat = PAT_TALK_UP;
805 bodyLoopPat = BPAT_SCAREDUP_LOOP;
806 break;
807
808 case DOWN:
809 _nBodyOffset.set(-5, 45);
810 headStartPat = PAT_SCAREDDOWN_START;
811 bodyStartPat = BPAT_SCAREDDOWN_START;
812 headLoopPat = PAT_SCAREDDOWN_LOOP;
813 bodyLoopPat = BPAT_SCAREDDOWN_LOOP;
814 break;
815
816 case RIGHT:
817 _nBodyOffset.set(-4, 41);
818 headStartPat = PAT_SCAREDRIGHT_START;
819 bodyStartPat = BPAT_SCAREDRIGHT_START;
820 headLoopPat = PAT_SCAREDRIGHT_LOOP;
821 bodyLoopPat = BPAT_SCAREDRIGHT_LOOP;
822 break;
823
824 case LEFT:
825 _nBodyOffset.set(-10, 41);
826 headStartPat = PAT_SCAREDLEFT_START;
827 bodyStartPat = BPAT_SCAREDLEFT_START;
828 headLoopPat = PAT_SCAREDLEFT_LOOP;
829 bodyLoopPat = BPAT_SCAREDLEFT_LOOP;
830 break;
831
832 default:
833 break;
834 }
835 break;
836
837 case TALK_SCARED2:
838 _bBodyFront = false;
839 switch (_talkDirection) {
840 case UP:
841 bodyStartPat = BPAT_STANDUP;
842 bodyLoopPat = BPAT_STANDUP;
843 _nBodyOffset.set(6, 53);
844
845 headStartPat = PAT_HEAD_UP;
846 headLoopPat = PAT_TALK_UP;
847 break;
848
849 case DOWN:
850 bodyStartPat = BPAT_STANDDOWN;
851 bodyLoopPat = BPAT_STANDDOWN;
852 _nBodyOffset.set(4, 53);
853
854 headStartPat = PAT_SCAREDDOWN_START;
855 headLoopPat = PAT_SCAREDDOWN_LOOP;
856 break;
857
858 case RIGHT:
859 bodyStartPat = BPAT_STANDRIGHT;
860 bodyLoopPat = BPAT_STANDRIGHT;
861 _nBodyOffset.set(6, 56);
862
863 headStartPat = PAT_SCAREDRIGHT_START;
864 headLoopPat = PAT_SCAREDRIGHT_LOOP;
865 break;
866
867 case LEFT:
868 bodyStartPat = BPAT_STANDLEFT;
869 bodyLoopPat = BPAT_STANDLEFT;
870 _nBodyOffset.set(6, 56);
871
872 headStartPat = PAT_SCAREDLEFT_START;
873 headLoopPat = PAT_SCAREDLEFT_LOOP;
874 break;
875
876 default:
877 break;
878 }
879 break;
880
881 case TALK_WITHGLASSES:
882 _nBodyOffset.set(4, 53);
883 headLoopPat = PAT_TALK_DOWN;
884 bodyLoopPat = BPAT_GLASS;
885 break;
886 case TALK_WITHWORM:
887 _nBodyOffset.set(9, 56);
888 headLoopPat = PAT_TALK_RIGHT;
889 bodyLoopPat = BPAT_WORM;
890 break;
891 case TALK_WITHHAMMER:
892 _nBodyOffset.set(6, 56);
893 headLoopPat = PAT_TALK_LEFT;
894 bodyLoopPat = BPAT_HAMMER;
895 break;
896 case TALK_WITHROPE:
897 _nBodyOffset.set(-3, 38);
898 headLoopPat = PAT_TALK_RIGHT;
899 bodyLoopPat = BPAT_ROPE;
900 break;
901 case TALK_WITHSECRETARY:
902 _nBodyOffset.set(-17, 12);
903 headLoopPat = PAT_TALK_RIGHT;
904 bodyLoopPat = BPAT_WITHSECRETARY;
905 break;
906
907 case TALK_WITHRABBIT:
908 switch (_talkDirection) {
909 case LEFT:
910 case UP:
911 _nBodyOffset.set(-21, -5);
912 bodyStartPat = BPAT_WITHRABBITLEFT_START;
913 headLoopPat = PAT_TALK_LEFT;
914 bodyLoopPat = BPAT_WITHRABBITLEFT_LOOP;
915 break;
916
917 case DOWN:
918 case RIGHT:
919 _nBodyOffset.set(-4, -5);
920 bodyStartPat = BPAT_WITHRABBITRIGHT_START;
921 headLoopPat = PAT_TALK_RIGHT;
922 bodyLoopPat = BPAT_WITHRABBITRIGHT_LOOP;
923 break;
924
925 default:
926 break;
927 }
928 break;
929
930 case TALK_WITHRECIPE:
931 switch (_talkDirection) {
932 case LEFT:
933 case UP:
934 _nBodyOffset.set(-61, -7);
935 bodyStartPat = BPAT_WITHRECIPELEFT_START;
936 headLoopPat = PAT_TALK_LEFT;
937 bodyLoopPat = BPAT_WITHRECIPELEFT_LOOP;
938 break;
939
940 case DOWN:
941 case RIGHT:
942 _nBodyOffset.set(-5, -7);
943 bodyStartPat = BPAT_WITHRECIPERIGHT_START;
944 headLoopPat = PAT_TALK_RIGHT;
945 bodyLoopPat = BPAT_WITHRECIPERIGHT_LOOP;
946 break;
947
948 default:
949 break;
950 }
951 break;
952
953 case TALK_WITHCARDS:
954 switch (_talkDirection) {
955 case LEFT:
956 case UP:
957 _nBodyOffset.set(-34, -2);
958 bodyStartPat = BPAT_WITHCARDSLEFT_START;
959 headLoopPat = PAT_TALK_LEFT;
960 bodyLoopPat = BPAT_WITHCARDSLEFT_LOOP;
961 break;
962
963 case DOWN:
964 case RIGHT:
965 _nBodyOffset.set(-4, -2);
966 bodyStartPat = BPAT_WITHCARDSRIGHT_START;
967 headLoopPat = PAT_TALK_RIGHT;
968 bodyLoopPat = BPAT_WITHCARDSRIGHT_LOOP;
969 break;
970
971 default:
972 break;
973 }
974 break;
975
976 case TALK_WITHSNOWMAN:
977 switch (_talkDirection) {
978 case LEFT:
979 case UP:
980 _nBodyOffset.set(-35, 2);
981 bodyStartPat = BPAT_WITHSNOWMANLEFT_START;
982 headLoopPat = PAT_TALK_LEFT;
983 bodyLoopPat = BPAT_WITHSNOWMANLEFT_LOOP;
984 break;
985
986 case DOWN:
987 case RIGHT:
988 _nBodyOffset.set(-14, 2);
989 bodyStartPat = BPAT_WITHSNOWMANRIGHT_START;
990 headLoopPat = PAT_TALK_RIGHT;
991 bodyLoopPat = BPAT_WITHSNOWMANRIGHT_LOOP;
992 break;
993
994 default:
995 break;
996 }
997 break;
998
999 case TALK_WITHSNOWMANSTATIC:
1000 case TALK_WITHRECIPESTATIC:
1001 case TALK_WITHRABBITSTATIC:
1002 case TALK_WITHCARDSSTATIC:
1003 case TALK_WITH_NOTEBOOK:
1004 case TALK_WITHMEGAPHONESTATIC:
1005 switch (_talkDirection) {
1006 case LEFT:
1007 case UP:
1008 headLoopPat = PAT_TALK_LEFT;
1009 break;
1010
1011 case DOWN:
1012 case RIGHT:
1013 headLoopPat = PAT_TALK_RIGHT;
1014 break;
1015
1016 default:
1017 break;
1018 }
1019 break;
1020
1021 // The beard is the only case in which the head is animated separately while the body is the standard
1022 case TALK_WITHBEARDSTATIC:
1023 switch (_talkDirection) {
1024 case LEFT:
1025 case UP:
1026 headLoopPat = PAT_TALKBEARD_LEFT;
1027 bodyLoopPat = BPAT_STANDLEFT;
1028 _nBodyOffset.set(6, 56);
1029 break;
1030
1031 case DOWN:
1032 case RIGHT:
1033 headLoopPat = PAT_TALKBEARD_RIGHT;
1034 bodyLoopPat = BPAT_STANDRIGHT;
1035 _nBodyOffset.set(6, 56);
1036 break;
1037
1038 default:
1039 break;
1040 }
1041 break;
1042
1043 case TALK_DISGUSTED:
1044 switch (_talkDirection) {
1045 case LEFT:
1046 case UP:
1047 _nBodyOffset.set(6, 56);
1048 headStartPat = PAT_DISGUSTEDLEFT_START;
1049 bodyStartPat = BPAT_STANDLEFT;
1050 headLoopPat = PAT_DISGUSTEDLEFT_LOOP;
1051 break;
1052
1053 case DOWN:
1054 case RIGHT:
1055 _nBodyOffset.set(6, 56);
1056 headStartPat = PAT_DISGUSTEDRIGHT_START;
1057 bodyStartPat = BPAT_STANDRIGHT;
1058 headLoopPat = PAT_DISGUSTEDRIGHT_LOOP;
1059 break;
1060
1061 default:
1062 break;
1063 }
1064 break;
1065
1066 case TALK_SARCASTIC:
1067 switch (_talkDirection) {
1068 case LEFT:
1069 case UP:
1070 _nBodyOffset.set(6, 56);
1071 headStartPat = PAT_SARCASTICLEFT_START;
1072 bodyStartPat = BPAT_STANDLEFT;
1073 headLoopPat = PAT_SARCASTICLEFT_LOOP;
1074 break;
1075
1076 case DOWN:
1077 case RIGHT:
1078 _nBodyOffset.set(6, 56);
1079 headStartPat = PAT_SARCASTICRIGHT_START;
1080 bodyStartPat = BPAT_STANDRIGHT;
1081 headLoopPat = PAT_SARCASTICRIGHT_LOOP;
1082 break;
1083
1084 default:
1085 break;
1086 }
1087 break;
1088
1089 case TALK_MACBETH1:
1090 _nBodyOffset.set(-33, -1);
1091 headLoopPat = PAT_TALK_LEFT;
1092 bodyLoopPat = BPAT_MACBETH1;
1093 break;
1094 case TALK_MACBETH2:
1095 _nBodyOffset.set(-33, -1);
1096 headLoopPat = PAT_TALK_LEFT;
1097 bodyLoopPat = BPAT_MACBETH2;
1098 break;
1099 case TALK_MACBETH3:
1100 _nBodyOffset.set(-33, -1);
1101 headLoopPat = PAT_TALK_LEFT;
1102 bodyLoopPat = BPAT_MACBETH3;
1103 break;
1104 case TALK_MACBETH4:
1105 _nBodyOffset.set(-33, -1);
1106 headLoopPat = PAT_TALK_LEFT;
1107 bodyLoopPat = BPAT_MACBETH4;
1108 break;
1109 case TALK_MACBETH5:
1110 _nBodyOffset.set(-33, -1);
1111 headLoopPat = PAT_TALK_LEFT;
1112 bodyLoopPat = BPAT_MACBETH5;
1113 break;
1114 case TALK_MACBETH6:
1115 _nBodyOffset.set(-33, -1);
1116 headLoopPat = PAT_TALK_LEFT;
1117 bodyLoopPat = BPAT_MACBETH6;
1118 break;
1119 case TALK_MACBETH7:
1120 _nBodyOffset.set(-33, -1);
1121 headLoopPat = PAT_TALK_LEFT;
1122 bodyLoopPat = BPAT_MACBETH7;
1123 break;
1124 case TALK_MACBETH8:
1125 _nBodyOffset.set(-33, -1);
1126 headLoopPat = PAT_TALK_LEFT;
1127 bodyLoopPat = BPAT_MACBETH8;
1128 break;
1129 case TALK_MACBETH9:
1130 _nBodyOffset.set(-33, -1);
1131 headLoopPat = PAT_TALK_LEFT;
1132 bodyLoopPat = BPAT_MACBETH9;
1133 break;
1134
1135 case TALK_SCAREDSTATIC:
1136 _bBodyFront = false;
1137 switch (_talkDirection) {
1138 case DOWN:
1139 bodyStartPat = BPAT_STANDDOWN;
1140 bodyLoopPat = BPAT_STANDDOWN;
1141 _nBodyOffset.set(4, 53);
1142
1143 headStartPat = PAT_SCAREDDOWN_STAND;
1144 headLoopPat = PAT_SCAREDDOWN_LOOP;
1145 break;
1146
1147 case RIGHT:
1148 bodyStartPat = BPAT_STANDRIGHT;
1149 bodyLoopPat = BPAT_STANDRIGHT;
1150 _nBodyOffset.set(6, 56);
1151
1152 headStartPat = PAT_SCAREDRIGHT_STAND;
1153 headLoopPat = PAT_SCAREDRIGHT_LOOP;
1154 break;
1155
1156 case LEFT:
1157 bodyStartPat = BPAT_STANDLEFT;
1158 bodyLoopPat = BPAT_STANDLEFT;
1159 _nBodyOffset.set(6, 56);
1160
1161 headStartPat = PAT_SCAREDLEFT_STAND;
1162 headLoopPat = PAT_SCAREDLEFT_LOOP;
1163 break;
1164
1165 default:
1166 break;
1167 }
1168 break;
1169
1170 default:
1171 break;
1172 }
1173
1174 return true;
1175 }
1176
startTalk(CORO_PARAM,CharacterTalkType nTalkType)1177 void RMTony::startTalk(CORO_PARAM, CharacterTalkType nTalkType) {
1178 CORO_BEGIN_CONTEXT;
1179 int headStartPat, bodyStartPat;
1180 int headLoopPat, bodyLoopPat;
1181 CORO_END_CONTEXT(_ctx);
1182
1183 CORO_BEGIN_CODE(_ctx);
1184
1185 _ctx->headStartPat = _ctx->bodyStartPat = 0;
1186 _ctx->headLoopPat = _ctx->bodyLoopPat = 0;
1187
1188 if (!startTalkCalculate(nTalkType, _ctx->headStartPat, _ctx->bodyStartPat,
1189 _ctx->headLoopPat, _ctx->bodyLoopPat))
1190 return;
1191
1192 // Perform the set pattern
1193 if (_ctx->headStartPat != 0 || _ctx->bodyStartPat != 0) {
1194 setPattern(_ctx->headStartPat);
1195 _body.setPattern(_ctx->bodyStartPat);
1196
1197 if (_ctx->bodyStartPat != 0)
1198 CORO_INVOKE_0(_body.waitForEndPattern);
1199 if (_ctx->headStartPat != 0)
1200 CORO_INVOKE_0(waitForEndPattern);
1201 }
1202
1203 setPattern(_ctx->headLoopPat);
1204 if (_ctx->bodyLoopPat)
1205 _body.setPattern(_ctx->bodyLoopPat);
1206
1207 CORO_END_CODE;
1208 }
1209
endTalkCalculate(int & headStandPat,int & headEndPat,int & bodyEndPat,int & finalPat,bool & bStatic)1210 bool RMTony::endTalkCalculate(int &headStandPat, int &headEndPat, int &bodyEndPat, int &finalPat, bool &bStatic) {
1211 bodyEndPat = 0;
1212 headEndPat = 0;
1213
1214 switch (_talkDirection) {
1215 case UP:
1216 finalPat = PAT_STANDUP;
1217 headStandPat = PAT_HEAD_UP;
1218 break;
1219
1220 case DOWN:
1221 finalPat = PAT_STANDDOWN;
1222 headStandPat = PAT_HEAD_DOWN;
1223 break;
1224
1225 case LEFT:
1226 finalPat = PAT_STANDLEFT;
1227 headStandPat = PAT_HEAD_LEFT;
1228 break;
1229
1230 case RIGHT:
1231 finalPat = PAT_STANDRIGHT;
1232 headStandPat = PAT_HEAD_RIGHT;
1233 break;
1234
1235 default:
1236 break;
1237 }
1238
1239 if (_bShepherdess) {
1240 setPattern(finalPat);
1241 _bIsTalking = false;
1242 return false;
1243 }
1244
1245 bStatic = false;
1246 switch (_nTalkType) {
1247 case TALK_NORMAL:
1248 bodyEndPat = 0;
1249 break;
1250
1251 case TALK_HIPS:
1252 switch (_talkDirection) {
1253 case UP:
1254 bodyEndPat = BPAT_HIPSUP_END;
1255 break;
1256
1257 case DOWN:
1258 bodyEndPat = BPAT_HIPSDOWN_END;
1259 break;
1260
1261 case LEFT:
1262 bodyEndPat = BPAT_HIPSLEFT_END;
1263 break;
1264
1265 case RIGHT:
1266 bodyEndPat = BPAT_HIPSRIGHT_END;
1267 break;
1268
1269 default:
1270 break;
1271 }
1272 break;
1273
1274 case TALK_SING:
1275 bodyEndPat = BPAT_SINGLEFT_END;
1276 break;
1277
1278 case TALK_LAUGH:
1279 case TALK_LAUGH2:
1280 if (_talkDirection == LEFT)
1281 headEndPat = PAT_LAUGHLEFT_END;
1282 else if (_talkDirection == RIGHT)
1283 headEndPat = PAT_LAUGHRIGHT_END;
1284
1285 bodyEndPat = 0;
1286 break;
1287
1288 case TALK_DISGUSTED:
1289 switch (_talkDirection) {
1290 case UP:
1291 case LEFT:
1292 headEndPat = PAT_DISGUSTEDLEFT_END;
1293 break;
1294
1295 case DOWN:
1296 case RIGHT:
1297 headEndPat = PAT_DISGUSTEDRIGHT_END;
1298 break;
1299
1300 default:
1301 break;
1302 }
1303
1304 bodyEndPat = 0;
1305 break;
1306
1307 case TALK_SARCASTIC:
1308 switch (_talkDirection) {
1309 case UP:
1310 case LEFT:
1311 headEndPat = PAT_SARCASTICLEFT_END;
1312 break;
1313
1314 case DOWN:
1315 case RIGHT:
1316 headEndPat = PAT_SARCASTICRIGHT_END;
1317 break;
1318
1319 default:
1320 break;
1321 }
1322
1323 bodyEndPat = 0;
1324 break;
1325
1326 case TALK_INDICATE:
1327 break;
1328
1329 case TALK_SCARED:
1330 switch (_talkDirection) {
1331 case UP:
1332 bodyEndPat = BPAT_SCAREDUP_END;
1333 break;
1334
1335 case DOWN:
1336 headEndPat = PAT_SCAREDDOWN_END;
1337 bodyEndPat = BPAT_SCAREDDOWN_END;
1338 break;
1339
1340 case RIGHT:
1341 headEndPat = PAT_SCAREDRIGHT_END;
1342 bodyEndPat = BPAT_SCAREDRIGHT_END;
1343 break;
1344
1345 case LEFT:
1346 headEndPat = PAT_SCAREDLEFT_END;
1347 bodyEndPat = BPAT_SCAREDLEFT_END;
1348 break;
1349
1350 default:
1351 break;
1352 }
1353 break;
1354
1355 case TALK_SCARED2:
1356 switch (_talkDirection) {
1357 case UP:
1358 bodyEndPat = 0;
1359 break;
1360
1361 case DOWN:
1362 headEndPat = PAT_SCAREDDOWN_END;
1363 bodyEndPat = 0;
1364 break;
1365
1366 case RIGHT:
1367 headEndPat = PAT_SCAREDRIGHT_END;
1368 bodyEndPat = 0;
1369 break;
1370
1371 case LEFT:
1372 headEndPat = PAT_SCAREDLEFT_END;
1373 bodyEndPat = 0;
1374 break;
1375
1376 default:
1377 break;
1378 }
1379 break;
1380
1381 case TALK_WITHRABBIT:
1382 switch (_talkDirection) {
1383 case UP:
1384 case LEFT:
1385 finalPat = PAT_STANDLEFT;
1386 bodyEndPat = BPAT_WITHRABBITLEFT_END;
1387 break;
1388
1389 case RIGHT:
1390 case DOWN:
1391 finalPat = PAT_STANDRIGHT;
1392 bodyEndPat = BPAT_WITHRABBITRIGHT_END;
1393 break;
1394
1395 default:
1396 break;
1397 }
1398 break;
1399
1400 case TALK_WITHRECIPE:
1401 switch (_talkDirection) {
1402 case UP:
1403 case LEFT:
1404 finalPat = PAT_STANDLEFT;
1405 bodyEndPat = BPAT_WITHRECIPELEFT_END;
1406 break;
1407
1408 case RIGHT:
1409 case DOWN:
1410 finalPat = PAT_STANDRIGHT;
1411 bodyEndPat = BPAT_WITHRECIPERIGHT_END;
1412 break;
1413
1414 default:
1415 break;
1416 }
1417 break;
1418
1419 case TALK_WITHCARDS:
1420 switch (_talkDirection) {
1421 case UP:
1422 case LEFT:
1423 finalPat = PAT_STANDLEFT;
1424 bodyEndPat = BPAT_WITHCARDSLEFT_END;
1425 break;
1426
1427 case RIGHT:
1428 case DOWN:
1429 finalPat = PAT_STANDRIGHT;
1430 bodyEndPat = BPAT_WITHCARDSRIGHT_END;
1431 break;
1432
1433 default:
1434 break;
1435 }
1436 break;
1437
1438 case TALK_WITHSNOWMAN:
1439 switch (_talkDirection) {
1440 case UP:
1441 case LEFT:
1442 finalPat = PAT_STANDLEFT;
1443 bodyEndPat = BPAT_WITHSNOWMANLEFT_END;
1444 break;
1445
1446 case RIGHT:
1447 case DOWN:
1448 finalPat = PAT_STANDRIGHT;
1449 bodyEndPat = BPAT_WITHSNOWMANRIGHT_END;
1450 break;
1451
1452 default:
1453 break;
1454 }
1455 break;
1456
1457 case TALK_WITHWORM:
1458 finalPat = PAT_WITHWORM;
1459 break;
1460 case TALK_WITHROPE:
1461 finalPat = PAT_WITHROPE;
1462 break;
1463 case TALK_WITHSECRETARY:
1464 finalPat = PAT_WITHSECRETARY;
1465 break;
1466 case TALK_WITHHAMMER:
1467 finalPat = PAT_WITHHAMMER;
1468 break;
1469 case TALK_WITHGLASSES:
1470 finalPat = PAT_WITHGLASSES;
1471 break;
1472
1473 case TALK_MACBETH1:
1474 case TALK_MACBETH2:
1475 case TALK_MACBETH3:
1476 case TALK_MACBETH4:
1477 case TALK_MACBETH5:
1478 case TALK_MACBETH6:
1479 case TALK_MACBETH7:
1480 case TALK_MACBETH8:
1481 finalPat = 0;
1482 break;
1483
1484 case TALK_SCAREDSTATIC:
1485 switch (_talkDirection) {
1486 case DOWN:
1487 headStandPat = PAT_SCAREDDOWN_STAND;
1488 bodyEndPat = 0;
1489 break;
1490
1491 case RIGHT:
1492 headStandPat = PAT_SCAREDRIGHT_STAND;
1493 bodyEndPat = 0;
1494 break;
1495
1496 case LEFT:
1497 headStandPat = PAT_SCAREDLEFT_STAND;
1498 bodyEndPat = 0;
1499 break;
1500
1501
1502 default:
1503 break;
1504 }
1505 break;
1506
1507 default:
1508 break;
1509 }
1510
1511 return true;
1512 }
1513
endTalk(CORO_PARAM)1514 void RMTony::endTalk(CORO_PARAM) {
1515 CORO_BEGIN_CONTEXT;
1516 int headStandPat, headEndPat;
1517 int bodyEndPat, finalPat;
1518 bool bStatic;
1519 CORO_END_CONTEXT(_ctx);
1520
1521 CORO_BEGIN_CODE(_ctx);
1522
1523 _ctx->headStandPat = _ctx->headEndPat = 0;
1524 _ctx->bodyEndPat = _ctx->finalPat = 0;
1525 _ctx->bStatic = false;
1526
1527 _ctx->bodyEndPat = 0;
1528 _ctx->headEndPat = 0;
1529
1530 if (!endTalkCalculate(_ctx->headStandPat, _ctx->headEndPat, _ctx->bodyEndPat, _ctx->finalPat, _ctx->bStatic))
1531 return;
1532
1533 // Handles the end of an animated and static, leaving everything unchanged
1534 if (_bIsStaticTalk) {
1535 if (_nTalkType == TALK_WITHBEARDSTATIC) {
1536 setPattern(0);
1537 if (_talkDirection == UP || _talkDirection == LEFT) {
1538 _body.setPattern(BPAT_WITHBEARDLEFT_STATIC);
1539 _nBodyOffset.set(-41, -14);
1540 } else if (_talkDirection == DOWN || _talkDirection == RIGHT) {
1541 _body.setPattern(BPAT_WITHBEARDRIGHT_STATIC);
1542 _nBodyOffset.set(-26, -14);
1543 }
1544 } else {
1545 setPattern(_ctx->headStandPat);
1546
1547 CORO_INVOKE_0(_body.waitForEndPattern);
1548 }
1549
1550 _bIsTalking = false;
1551 return;
1552 }
1553
1554 // Set the pattern
1555 if (_ctx->headEndPat != 0 && _ctx->bodyEndPat != 0) {
1556 setPattern(_ctx->headEndPat);
1557
1558 CORO_INVOKE_0(_body.waitForEndPattern);
1559
1560 _body.setPattern(_ctx->bodyEndPat);
1561
1562 CORO_INVOKE_0(waitForEndPattern);
1563 CORO_INVOKE_0(_body.waitForEndPattern);
1564 } else if (_ctx->bodyEndPat != 0) {
1565 setPattern(_ctx->headStandPat);
1566
1567 CORO_INVOKE_0(_body.waitForEndPattern);
1568
1569 _body.setPattern(_ctx->bodyEndPat);
1570
1571 CORO_INVOKE_0(_body.waitForEndPattern);
1572 } else if (_ctx->headEndPat != 0) {
1573 CORO_INVOKE_0(_body.waitForEndPattern);
1574
1575 setPattern(_ctx->headEndPat);
1576
1577 CORO_INVOKE_0(waitForEndPattern);
1578 } else {
1579 CORO_INVOKE_0(_body.waitForEndPattern);
1580 }
1581
1582 if (_ctx->finalPat != 0) {
1583 _body.setPattern(0);
1584 setPattern(_ctx->finalPat);
1585 }
1586
1587 _bIsTalking = false;
1588
1589 CORO_END_CODE;
1590 }
1591
startStaticCalculate(CharacterTalkType nTalk,int & headPat,int & headLoopPat,int & bodyStartPat,int & bodyLoopPat)1592 void RMTony::startStaticCalculate(CharacterTalkType nTalk, int &headPat, int &headLoopPat,
1593 int &bodyStartPat, int &bodyLoopPat) {
1594 int nPat = getCurPattern();
1595
1596 headLoopPat = -1;
1597
1598 switch (nPat) {
1599 case PAT_STANDDOWN:
1600 _talkDirection = DOWN;
1601 headPat = PAT_HEAD_RIGHT;
1602 break;
1603
1604 case PAT_TAKELEFT_UP2:
1605 case PAT_TAKELEFT_MID2:
1606 case PAT_TAKELEFT_DOWN2:
1607 case PAT_GETUPLEFT:
1608 case PAT_STANDLEFT:
1609 _talkDirection = LEFT;
1610 headPat = PAT_HEAD_LEFT;
1611 break;
1612
1613 case PAT_TAKERIGHT_UP2:
1614 case PAT_TAKERIGHT_MID2:
1615 case PAT_TAKERIGHT_DOWN2:
1616 case PAT_GETUPRIGHT:
1617 case PAT_STANDRIGHT:
1618 _talkDirection = RIGHT;
1619 headPat = PAT_HEAD_RIGHT;
1620 break;
1621
1622 case PAT_TAKEUP_UP2:
1623 case PAT_TAKEUP_MID2:
1624 case PAT_TAKEUP_DOWN2:
1625 case PAT_STANDUP:
1626 _talkDirection = UP;
1627 headPat = PAT_HEAD_LEFT;
1628 break;
1629
1630 default:
1631 break;
1632 }
1633
1634 _bBodyFront = true;
1635
1636 switch (nTalk) {
1637 case TALK_WITHRABBITSTATIC:
1638 switch (_talkDirection) {
1639 case UP:
1640 case LEFT:
1641 _nBodyOffset.set(-21, -5);
1642 bodyStartPat = BPAT_WITHRABBITLEFT_START;
1643 bodyLoopPat = BPAT_WITHRABBITLEFT_LOOP;
1644 break;
1645
1646 case DOWN:
1647 case RIGHT:
1648 _nBodyOffset.set(-4, -5);
1649 bodyStartPat = BPAT_WITHRABBITRIGHT_START;
1650 bodyLoopPat = BPAT_WITHRABBITRIGHT_LOOP;
1651 break;
1652
1653 default:
1654 break;
1655 }
1656 break;
1657
1658 case TALK_WITHCARDSSTATIC:
1659 switch (_talkDirection) {
1660 case UP:
1661 case LEFT:
1662 _nBodyOffset.set(-34, -2);
1663 bodyStartPat = BPAT_WITHCARDSLEFT_START;
1664 bodyLoopPat = BPAT_WITHCARDSLEFT_LOOP;
1665 break;
1666
1667 case DOWN:
1668 case RIGHT:
1669 _nBodyOffset.set(-4, -2);
1670 bodyStartPat = BPAT_WITHCARDSRIGHT_START;
1671 bodyLoopPat = BPAT_WITHCARDSRIGHT_LOOP;
1672 break;
1673
1674 default:
1675 break;
1676 }
1677 break;
1678
1679 case TALK_WITHRECIPESTATIC:
1680 switch (_talkDirection) {
1681 case UP:
1682 case LEFT:
1683 _nBodyOffset.set(-61, -7);
1684 bodyStartPat = BPAT_WITHRECIPELEFT_START;
1685 bodyLoopPat = BPAT_WITHRECIPELEFT_LOOP;
1686 break;
1687
1688 case DOWN:
1689 case RIGHT:
1690 _nBodyOffset.set(-5, -7);
1691 bodyStartPat = BPAT_WITHRECIPERIGHT_START;
1692 bodyLoopPat = BPAT_WITHRECIPERIGHT_LOOP;
1693 break;
1694
1695 default:
1696 break;
1697 }
1698 break;
1699
1700 case TALK_WITHSNOWMANSTATIC:
1701 switch (_talkDirection) {
1702 case UP:
1703 case LEFT:
1704 _nBodyOffset.set(-35, 2);
1705 bodyStartPat = BPAT_WITHSNOWMANLEFT_START;
1706 bodyLoopPat = BPAT_WITHSNOWMANLEFT_LOOP;
1707 break;
1708
1709 case DOWN:
1710 case RIGHT:
1711 _nBodyOffset.set(-14, 2);
1712 bodyStartPat = BPAT_WITHSNOWMANRIGHT_START;
1713 bodyLoopPat = BPAT_WITHSNOWMANRIGHT_LOOP;
1714 break;
1715
1716 default:
1717 break;
1718 }
1719 break;
1720
1721 case TALK_WITH_NOTEBOOK:
1722 switch (_talkDirection) {
1723 case UP:
1724 case LEFT:
1725 _nBodyOffset.set(-16, -9);
1726 bodyStartPat = BPAT_WITHNOTEBOOKLEFT_START;
1727 bodyLoopPat = BPAT_WITHNOTEBOOKLEFT_LOOP;
1728 break;
1729
1730 case DOWN:
1731 case RIGHT:
1732 _nBodyOffset.set(-6, -9);
1733 bodyStartPat = BPAT_WITHNOTEBOOKRIGHT_START;
1734 bodyLoopPat = BPAT_WITHNOTEBOOKRIGHT_LOOP;
1735 break;
1736
1737 default:
1738 break;
1739 }
1740 break;
1741
1742 case TALK_WITHMEGAPHONESTATIC:
1743 switch (_talkDirection) {
1744 case UP:
1745 case LEFT:
1746 _nBodyOffset.set(-41, -8);
1747 bodyStartPat = BPAT_WITHMEGAPHONELEFT_START;
1748 bodyLoopPat = BPAT_WITHMEGAPHONELEFT_LOOP;
1749 break;
1750
1751 case DOWN:
1752 case RIGHT:
1753 _nBodyOffset.set(-14, -8);
1754 bodyStartPat = BPAT_WITHMEGAPHONERIGHT_START;
1755 bodyLoopPat = BPAT_WITHMEGAPHONERIGHT_LOOP;
1756 break;
1757
1758 default:
1759 break;
1760 }
1761 break;
1762
1763 case TALK_WITHBEARDSTATIC:
1764 switch (_talkDirection) {
1765 case UP:
1766 case LEFT:
1767 _nBodyOffset.set(-41, -14);
1768 bodyStartPat = BPAT_WITHBEARDLEFT_START;
1769 bodyLoopPat = BPAT_STANDLEFT;
1770 headLoopPat = PAT_TALKBEARD_LEFT;
1771 headPat = 0;
1772 break;
1773
1774 case DOWN:
1775 case RIGHT:
1776 _nBodyOffset.set(-26, -14);
1777 bodyStartPat = BPAT_WITHBEARDRIGHT_START;
1778 bodyLoopPat = BPAT_STANDRIGHT;
1779 headLoopPat = PAT_TALKBEARD_RIGHT;
1780 headPat = 0;
1781 break;
1782
1783 default:
1784 break;
1785 }
1786 break;
1787
1788 case TALK_SCAREDSTATIC:
1789 switch (_talkDirection) {
1790 case DOWN:
1791 headPat = PAT_SCAREDDOWN_START;
1792 bodyLoopPat = BPAT_STANDDOWN;
1793 bodyStartPat = BPAT_STANDDOWN;
1794 headLoopPat = PAT_SCAREDDOWN_STAND;
1795 _nBodyOffset.set(4, 53);
1796 break;
1797
1798 case LEFT:
1799 headPat = PAT_SCAREDLEFT_START;
1800 bodyLoopPat = BPAT_STANDLEFT;
1801 bodyStartPat = BPAT_STANDLEFT;
1802 headLoopPat = PAT_SCAREDLEFT_STAND;
1803 _nBodyOffset.set(6, 56);
1804 break;
1805
1806 case RIGHT:
1807 headPat = PAT_SCAREDRIGHT_START;
1808 bodyLoopPat = BPAT_STANDRIGHT;
1809 bodyStartPat = BPAT_STANDRIGHT;
1810 headLoopPat = PAT_SCAREDRIGHT_STAND;
1811 _nBodyOffset.set(6, 56);
1812 break;
1813
1814 case UP:
1815 default:
1816 break;
1817 }
1818
1819 default:
1820 break;
1821 }
1822 }
1823
startStatic(CORO_PARAM,CharacterTalkType nTalk)1824 void RMTony::startStatic(CORO_PARAM, CharacterTalkType nTalk) {
1825 CORO_BEGIN_CONTEXT;
1826 int headPat, headLoopPat;
1827 int bodyStartPat, bodyLoopPat;
1828 CORO_END_CONTEXT(_ctx);
1829
1830 CORO_BEGIN_CODE(_ctx);
1831
1832 _ctx->headPat = _ctx->headLoopPat = 0;
1833 _ctx->bodyStartPat = _ctx->bodyLoopPat = 0;
1834
1835 startStaticCalculate(nTalk, _ctx->headPat, _ctx->headLoopPat,
1836 _ctx->bodyStartPat, _ctx->bodyLoopPat);
1837
1838 // e vai con i pattern
1839 _bIsStaticTalk = true;
1840
1841 setPattern(_ctx->headPat);
1842 _body.setPattern(_ctx->bodyStartPat);
1843
1844 CORO_INVOKE_0(_body.waitForEndPattern);
1845 CORO_INVOKE_0(waitForEndPattern);
1846
1847 if (_ctx->headLoopPat != -1)
1848 setPattern(_ctx->headLoopPat);
1849 _body.setPattern(_ctx->bodyLoopPat);
1850
1851 CORO_END_CODE;
1852 }
1853
endStaticCalculate(CharacterTalkType nTalk,int & bodyEndPat,int & finalPat,int & headEndPat)1854 void RMTony::endStaticCalculate(CharacterTalkType nTalk, int &bodyEndPat, int &finalPat, int &headEndPat) {
1855 switch (_talkDirection) {
1856 case UP:
1857 case LEFT:
1858 finalPat = PAT_STANDLEFT;
1859 break;
1860
1861 case RIGHT:
1862 case DOWN:
1863 finalPat = PAT_STANDRIGHT;
1864 break;
1865
1866 default:
1867 break;
1868 }
1869
1870 switch (nTalk) {
1871 case TALK_WITHSNOWMANSTATIC:
1872 switch (_talkDirection) {
1873 case UP:
1874 case LEFT:
1875 bodyEndPat = BPAT_WITHSNOWMANLEFT_END;
1876 break;
1877
1878 case DOWN:
1879 case RIGHT:
1880 bodyEndPat = BPAT_WITHSNOWMANRIGHT_END;
1881 break;
1882
1883 default:
1884 break;
1885 }
1886 break;
1887
1888 case TALK_WITHRECIPESTATIC:
1889 switch (_talkDirection) {
1890 case UP:
1891 case LEFT:
1892 bodyEndPat = BPAT_WITHRECIPELEFT_END;
1893 break;
1894
1895 case DOWN:
1896 case RIGHT:
1897 bodyEndPat = BPAT_WITHRECIPERIGHT_END;
1898 break;
1899
1900 default:
1901 break;
1902 }
1903 break;
1904
1905 case TALK_WITHRABBITSTATIC:
1906 switch (_talkDirection) {
1907 case UP:
1908 case LEFT:
1909 bodyEndPat = BPAT_WITHRABBITLEFT_END;
1910 break;
1911
1912 case DOWN:
1913 case RIGHT:
1914 bodyEndPat = BPAT_WITHRABBITRIGHT_END;
1915 break;
1916
1917 default:
1918 break;
1919 }
1920 break;
1921
1922 case TALK_WITHCARDSSTATIC:
1923 switch (_talkDirection) {
1924 case UP:
1925 case LEFT:
1926 bodyEndPat = BPAT_WITHCARDSLEFT_END;
1927 break;
1928
1929 case DOWN:
1930 case RIGHT:
1931 bodyEndPat = BPAT_WITHCARDSRIGHT_END;
1932 break;
1933
1934 default:
1935 break;
1936 }
1937 break;
1938
1939 case TALK_WITH_NOTEBOOK:
1940 switch (_talkDirection) {
1941 case UP:
1942 case LEFT:
1943 bodyEndPat = BPAT_WITHNOTEBOOKLEFT_END;
1944 break;
1945
1946 case DOWN:
1947 case RIGHT:
1948 bodyEndPat = BPAT_WITHNOTEBOOKRIGHT_END;
1949 break;
1950
1951 default:
1952 break;
1953 }
1954 break;
1955
1956 case TALK_WITHMEGAPHONESTATIC:
1957 switch (_talkDirection) {
1958 case UP:
1959 case LEFT:
1960 bodyEndPat = BPAT_WITHMEGAPHONELEFT_END;
1961 break;
1962
1963 case DOWN:
1964 case RIGHT:
1965 bodyEndPat = BPAT_WITHMEGAPHONERIGHT_END;
1966 break;
1967
1968 default:
1969 break;
1970 }
1971 break;
1972
1973 case TALK_WITHBEARDSTATIC:
1974 switch (_talkDirection) {
1975 case UP:
1976 case LEFT:
1977 bodyEndPat = BPAT_WITHBEARDLEFT_END;
1978 break;
1979
1980 case DOWN:
1981 case RIGHT:
1982 bodyEndPat = BPAT_WITHBEARDRIGHT_END;
1983 break;
1984
1985 default:
1986 break;
1987 }
1988 break;
1989
1990 case TALK_SCAREDSTATIC:
1991 switch (_talkDirection) {
1992 case LEFT:
1993 headEndPat = PAT_SCAREDLEFT_END;
1994 break;
1995
1996 case DOWN:
1997 headEndPat = PAT_SCAREDDOWN_END;
1998 break;
1999
2000 case RIGHT:
2001 headEndPat = PAT_SCAREDRIGHT_END;
2002 break;
2003
2004 case UP:
2005 default:
2006 break;
2007 }
2008 break;
2009
2010 default:
2011 break;
2012 }
2013 }
2014
endStatic(CORO_PARAM,CharacterTalkType nTalk)2015 void RMTony::endStatic(CORO_PARAM, CharacterTalkType nTalk) {
2016 CORO_BEGIN_CONTEXT;
2017 int bodyEndPat;
2018 int finalPat;
2019 int headEndPat;
2020 CORO_END_CONTEXT(_ctx);
2021
2022 CORO_BEGIN_CODE(_ctx);
2023
2024 _ctx->bodyEndPat = 0;
2025 _ctx->finalPat = 0;
2026 _ctx->headEndPat = 0;
2027
2028 endStaticCalculate(nTalk, _ctx->bodyEndPat, _ctx->finalPat, _ctx->headEndPat);
2029
2030 if (_ctx->headEndPat != 0) {
2031 setPattern(_ctx->headEndPat);
2032
2033 CORO_INVOKE_0(waitForEndPattern);
2034 } else {
2035 // Play please
2036 _body.setPattern(_ctx->bodyEndPat);
2037
2038 CORO_INVOKE_0(_body.waitForEndPattern);
2039 }
2040
2041 setPattern(_ctx->finalPat);
2042 _body.setPattern(0);
2043
2044 _bIsStaticTalk = false;
2045
2046 CORO_END_CODE;
2047 }
2048
2049 /**
2050 * Waits until the end of a pattern
2051 */
waitForEndPattern(CORO_PARAM,uint32 hCustomSkip)2052 void RMTony::waitForEndPattern(CORO_PARAM, uint32 hCustomSkip) {
2053 RMCharacter::waitForEndPattern(coroParam, hCustomSkip);
2054 }
2055
2056 /**
2057 * Check if currently in an action
2058 */
inAction()2059 bool RMTony::inAction() {
2060 return (_bActionPending && _action != 0) | _bAction;
2061 }
2062
2063 /**
2064 * Check if there needs to be an update for scrolling movement
2065 */
mustUpdateScrolling()2066 bool RMTony::mustUpdateScrolling() {
2067 return ((!inAction()) || (isMoving()));
2068 }
2069
2070 /**
2071 * Returns Tony's position
2072 */
position()2073 RMPoint RMTony::position() {
2074 return _pos;
2075 }
2076
2077 /**
2078 * Set the scrolling position
2079 */
setScrollPosition(const RMPoint & pt)2080 void RMTony::setScrollPosition(const RMPoint &pt) {
2081 RMCharacter::setScrollPosition(pt);
2082 }
2083
2084 /**
2085 * Tony disguises himself!
2086 */
setShepherdess(bool bIsPast)2087 void RMTony::setShepherdess(bool bIsPast) {
2088 _bShepherdess = bIsPast;
2089 }
2090
getShepherdess()2091 int RMTony::getShepherdess() {
2092 return _bShepherdess;
2093 }
2094
playSfx(int nSfx)2095 void RMTony::playSfx(int nSfx) {
2096 RMItem::playSfx(nSfx);
2097 }
2098
2099 } // End of namespace Tony
2100