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 #include "common/debug.h"
24 #include "common/system.h"
25 
26 #include "toon/character.h"
27 #include "toon/drew.h"
28 #include "toon/flux.h"
29 #include "toon/path.h"
30 
31 namespace Toon {
32 
Character(ToonEngine * vm)33 Character::Character(ToonEngine *vm) : _vm(vm) {
34 	_animationInstance = NULL;
35 	_shadowAnimationInstance = NULL;
36 	_x = 0;
37 	_y = 0;
38 	_z = 0;
39 	_finalX = 0;
40 	_finalY = 0;
41 	_sceneAnimationId = -1;
42 
43 	_walkAnim = NULL;
44 	_idleAnim = NULL;
45 	_talkAnim = NULL;
46 	_shadowAnim = NULL;
47 	_specialAnim = NULL;
48 
49 	_facing = 0;
50 	_flags = 0;
51 	_animFlags = 0;
52 	_isTalking = false;
53 	_id = 0;
54 	_scale = 1024;
55 	_blockingWalk = false;
56 	_animScriptId = -1;
57 	_animSpecialId = -1;
58 	_animSpecialDefaultId = 0;
59 	_currentPathNode = 0;
60 	_currentWalkStamp = 0;
61 	_currentFacingStamp = 0;
62 	_visible = true;
63 	_speed = 150;   // 150 = nominal drew speed
64 	_lastWalkTime = 0;
65 	_numPixelToWalk = 0;
66 	_nextIdleTime = _vm->_system->getMillis() + (_vm->randRange(0, 600) + 300) * _vm->getTickLength();
67 	_lineToSayId = 0;
68 	_time = 0;
69 }
70 
~Character(void)71 Character::~Character(void) {
72 	delete _animationInstance;
73 	delete _shadowAnimationInstance;
74 
75 	delete _walkAnim;
76 	delete _idleAnim;
77 	delete _talkAnim;
78 	delete _shadowAnim;
79 	delete _specialAnim;
80 }
81 
init()82 void Character::init() {
83 }
84 
forceFacing(int32 facing)85 void Character::forceFacing(int32 facing) {
86 	debugC(4, kDebugCharacter, "forceFacing(%d)", facing);
87 	_facing = facing;
88 }
89 
setFacing(int32 facing)90 void Character::setFacing(int32 facing) {
91 	debugC(4, kDebugCharacter, "setFacing(%d)", facing);
92 
93 	if (facing == _facing)
94 		return;
95 
96 	if (!_visible) {
97 		_facing = facing;
98 		return;
99 	}
100 
101 	if (_blockingWalk) {
102 		_flags |= 2;
103 
104 		_currentFacingStamp++;
105 		int32 localFacingStamp = _currentFacingStamp;
106 
107 		int32 dir = 0;
108 
109 		_lastWalkTime = _vm->_system->getMillis();
110 		if ((_facing - facing + 8) % 8 > (facing - _facing + 8) % 8)
111 			dir = 1;
112 		else
113 			dir = -1;
114 
115 		while (_facing != facing) {
116 
117 			int32 elapsedTime = _vm->getOldMilli() - _lastWalkTime;
118 			while (elapsedTime > _vm->getTickLength() * 3 && _facing != facing) {
119 				_facing += dir;
120 
121 				while (_facing >= 8)
122 					_facing -= 8;
123 				while (_facing < 0)
124 					_facing += 8;
125 
126 				elapsedTime -= _vm->getTickLength() * 3;
127 				_lastWalkTime = _vm->getOldMilli();
128 			}
129 
130 			if (_currentPathNode == 0)
131 				playStandingAnim();
132 			else
133 				playWalkAnim(0, 0);
134 			_vm->doFrame();
135 
136 			if (_currentFacingStamp != localFacingStamp) {
137 				// another setFacing was started in doFrame, we need to cancel this one.
138 				return;
139 			}
140 		};
141 
142 		_flags &= ~2;
143 	}
144 
145 	_facing = facing;
146 }
147 
forcePosition(int16 x,int16 y)148 void Character::forcePosition(int16 x, int16 y) {
149 	debugC(5, kDebugCharacter, "forcePosition(%d, %d)", x, y);
150 
151 	setPosition(x, y);
152 	_finalX = x;
153 	_finalY = y;
154 }
155 
setPosition(int16 x,int16 y)156 void Character::setPosition(int16 x, int16 y) {
157 	debugC(5, kDebugCharacter, "setPosition(%d, %d)", x, y);
158 
159 	_x = x;
160 	_y = y;
161 	if (_animationInstance)
162 		_animationInstance->setPosition(_x, _y, _z);
163 	return;
164 }
165 
walkTo(int16 newPosX,int16 newPosY)166 bool Character::walkTo(int16 newPosX, int16 newPosY) {
167 	debugC(1, kDebugCharacter, "walkTo(%d, %d)", newPosX, newPosY);
168 
169 	if (!_visible)
170 		return true;
171 
172 	if (_x == newPosX && _y == newPosY)
173 		return true;
174 
175 	_vm->getPathFinding()->resetBlockingRects();
176 
177 	// don't allow flux to go at the same position as drew
178 	if (_id == 1) {
179 		int16 sizeX = MAX<int16>(5, 30 * _vm->getDrew()->getScale() / 1024);
180 		int16 sizeY = MAX<int16>(2, 20 * _vm->getDrew()->getScale() / 1024);
181 		_vm->getPathFinding()->addBlockingEllipse(_vm->getDrew()->getFinalX(), _vm->getDrew()->getFinalY(), sizeX, sizeY);
182 	}
183 
184 	_vm->getPathFinding()->findClosestWalkingPoint(newPosX, newPosY, &_finalX, &_finalY, _x, _y);
185 	if (_x == _finalX && _y == _finalY)
186 		return true;
187 
188 	if (_vm->getPathFinding()->findPath(_x, _y, _finalX, _finalY)) {
189 
190 		int16 localFinalX = _finalX;
191 		int16 localFinalY = _finalY;
192 		int32 smoothDx = 0;
193 		int32 smoothDy = 0;
194 
195 		_currentPath.clear();
196 		for (uint32 a = 0; a < _vm->getPathFinding()->getPathNodeCount(); a++)
197 			_currentPath.push_back(Common::Point(_vm->getPathFinding()->getPathNodeX(a), _vm->getPathFinding()->getPathNodeY(a)));
198 		_currentPathNode = 0;
199 		stopSpecialAnim();
200 
201 		_lastWalkTime = _vm->_system->getMillis();
202 
203 		_numPixelToWalk = 0;
204 
205 		_flags |= 0x1;
206 
207 		_currentWalkStamp++;
208 
209 		int32 localWalkStamp = _currentWalkStamp;
210 
211 		if (_blockingWalk) {
212 			while ((_x != newPosX || _y != newPosY) && _currentPathNode < _currentPath.size() && !_vm->shouldQuitGame()) {
213 				if (_currentPathNode < _currentPath.size() - 4) {
214 					int32 delta = MIN<int32>(4, _currentPath.size() - 1 - _currentPathNode);
215 
216 					int16 dx = _currentPath[_currentPathNode+delta].x - _x;
217 					int16 dy = _currentPath[_currentPathNode+delta].y - _y;
218 
219 					// smooth the facing computation. It prevents some ugly flickering from happening
220 					if (!smoothDx && !smoothDy) {
221 						smoothDx = dx;
222 						smoothDy = dy;
223 					} else {
224 						smoothDx = (dx + smoothDx * 3) / 4;
225 						smoothDy = (dy + smoothDy * 3) / 4;
226 					}
227 
228 					setFacing(getFacingFromDirection(smoothDx, smoothDy));
229 					if (_currentWalkStamp != localWalkStamp) {
230 						// another walkTo was started in setFacing, we need to cancel this one.
231 						return false;
232 					}
233 
234 					playWalkAnim(0, 0);
235 				}
236 
237 				// in 1/1000 pixels
238 				_numPixelToWalk += _speed * (_vm->_system->getMillis() - _lastWalkTime) * _scale / 1024;
239 				_lastWalkTime = _vm->_system->getMillis();
240 
241 				while (_numPixelToWalk >= 1000 && _currentPathNode < _currentPath.size()) {
242 					_x = _currentPath[_currentPathNode].x;
243 					_y = _currentPath[_currentPathNode].y;
244 					_currentPathNode += 1;
245 					_numPixelToWalk -= 1000;
246 				}
247 				setPosition(_x, _y);
248 
249 				_vm->doFrame();
250 				if (_currentWalkStamp != localWalkStamp) {
251 					// another walkTo was started in doFrame, we need to cancel this one.
252 					return false;
253 				}
254 
255 			}
256 			playStandingAnim();
257 			_flags &= ~0x1;
258 			_currentPathNode = 0;
259 			_currentPath.clear();
260 
261 			if (_x != localFinalX || _y != localFinalY) {
262 				return false;
263 			}
264 		}
265 	}
266 
267 	return true;
268 }
269 
setFlag(int flag)270 void Character::setFlag(int flag) {
271 	_flags = flag;
272 }
273 
getFlag()274 int32 Character::getFlag() {
275 	return _flags;
276 }
277 
getX()278 int16 Character::getX() {
279 	return _x;
280 }
281 
getY()282 int16 Character::getY() {
283 	return _y;
284 }
285 
getVisible()286 bool Character::getVisible() {
287 	return _visible;
288 }
289 
setVisible(bool visible)290 void Character::setVisible(bool visible) {
291 	debugC(1, kDebugCharacter, "setVisible(%d)", (visible) ? 1 : 0);
292 
293 	_visible = visible;
294 	if (_animationInstance)
295 		_animationInstance->setVisible(visible);
296 
297 	if (_shadowAnimationInstance)
298 		_shadowAnimationInstance->setVisible(visible);
299 
300 	return;
301 }
302 
getFacing()303 int32 Character::getFacing() {
304 	return _facing;
305 }
306 
loadWalkAnimation(const Common::String & animName)307 bool Character::loadWalkAnimation(const Common::String &animName) {
308 	debugC(1, kDebugCharacter, "loadWalkAnimation(%s)", animName.c_str());
309 	delete _walkAnim;
310 	_walkAnim = new Animation(_vm);
311 	return _walkAnim->loadAnimation(animName);
312 }
313 
loadIdleAnimation(const Common::String & animName)314 bool Character::loadIdleAnimation(const Common::String &animName) {
315 	debugC(1, kDebugCharacter, "loadIdleAnimation(%s)", animName.c_str());
316 	delete _idleAnim;
317 	_idleAnim = new Animation(_vm);
318 	return _idleAnim->loadAnimation(animName);
319 }
320 
loadTalkAnimation(const Common::String & animName)321 bool Character::loadTalkAnimation(const Common::String &animName) {
322 	debugC(1, kDebugCharacter, "loadTalkAnimation(%s)", animName.c_str());
323 	delete _talkAnim;
324 	_talkAnim = new Animation(_vm);
325 	return _talkAnim->loadAnimation(animName);
326 }
327 
setupPalette()328 bool Character::setupPalette() {
329 	return false; // only for Drew
330 }
331 
playStandingAnim()332 void Character::playStandingAnim() {
333 }
334 
updateTimers(int32 relativeAdd)335 void Character::updateTimers(int32 relativeAdd) {
336 	_nextIdleTime += relativeAdd;
337 	_lastWalkTime += relativeAdd;
338 }
339 
stopSpecialAnim()340 void Character::stopSpecialAnim() {
341 	debugC(4, kDebugCharacter, "stopSpecialAnim()");
342 	if (_animScriptId != -1)
343 		_vm->getSceneAnimationScript(_animScriptId)->_frozenForConversation = false;
344 
345 	//if (_sceneAnimationId != -1)
346 	//	_animationInstance->setAnimation(_vm->getSceneAnimation(_sceneAnimationId)->_animation);
347 
348 	bool needStandingAnim = (_animFlags & 0x40) != 0;
349 
350 	_animSpecialId = -1;
351 	_time = 0;
352 	_animFlags = 0;
353 	_flags &= ~1;
354 	_flags &= ~4;
355 
356 	if (needStandingAnim) {
357 		playStandingAnim();
358 	}
359 }
360 
update(int32 timeIncrement)361 void Character::update(int32 timeIncrement) {
362 	debugC(5, kDebugCharacter, "update(%d)", timeIncrement);
363 	if ((_flags & 0x1) && _currentPath.size() > 0) {
364 		if (_currentPathNode < _currentPath.size()) {
365 			if (_currentPathNode < _currentPath.size() - 10) {
366 				int32 delta = MIN<int32>(10, _currentPath.size() - 1 - _currentPathNode);
367 				int16 dx = _currentPath[_currentPathNode+delta].x - _x;
368 				int16 dy = _currentPath[_currentPathNode+delta].y - _y;
369 				setFacing(getFacingFromDirection(dx, dy));
370 				playWalkAnim(0, 0);
371 			}
372 
373 			// in 1/1000 pixels
374 			_numPixelToWalk += _speed * (_vm->_system->getMillis() - _lastWalkTime) * _scale / 1024;
375 			_lastWalkTime = _vm->_system->getMillis();
376 
377 			while (_numPixelToWalk > 1000 && _currentPathNode < _currentPath.size()) {
378 				_x = _currentPath[_currentPathNode].x;
379 				_y = _currentPath[_currentPathNode].y;
380 				_currentPathNode += 1;
381 				_numPixelToWalk -= 1000;
382 			}
383 			setPosition(_x, _y);
384 		} else {
385 			playStandingAnim();
386 			_flags &= ~0x1;
387 			_currentPath.clear();
388 		}
389 	}
390 
391 	updateIdle();
392 
393 #if 0
394 	// handle special anims
395 	if ((_flags & 4) == 0)
396 		return;
397 
398 	if (_animScriptId != -1) {
399 		_animationInstance = _vm->getSceneAnimation(this->)
400 #endif
401 
402 	int32 animId = _animSpecialId;
403 	if (animId >= 1000)
404 		animId = 0;
405 
406 	if (_animSpecialId < 0)
407 		return;
408 
409 	int32 currentFrame = _animationInstance->getFrame();
410 
411 	const SpecialCharacterAnimation *anim = getSpecialAnimation(_id, animId);
412 
413 	if ((_animFlags & 0x10) == 0) {
414 		if (_animScriptId != -1 && currentFrame > 0 && !_vm->getSceneAnimationScript(_animScriptId)->_frozen) {
415 			if (_vm->getCurrentLineToSay() != _lineToSayId && (_animFlags & 8))
416 				stopSpecialAnim();
417 			return;
418 		}
419 
420 		if (_id == 1 && (_animFlags & 4)) {
421 			if (_animFlags & 0x10)
422 				return;
423 		} else {
424 			if (_id == 1 && (_animFlags & 0x10) && _vm->getCurrentLineToSay() != -1) {
425 				return;
426 			}
427 			if ((_animFlags & 0x40) == 0 && _vm->getCurrentLineToSay() == -1) {
428 				stopSpecialAnim();
429 				return;
430 			}
431 
432 			if (_animScriptId != -1)
433 				_vm->getSceneAnimationScript(_animScriptId)->_frozenForConversation = true;
434 
435 			// TODO setup backup //
436 
437 			_animFlags |= 0x10;
438 			_animationInstance->setAnimation(_specialAnim);
439 			_animationInstance->setFrame(0);
440 			_time = _vm->getOldMilli() + 8 * _vm->getTickLength();
441 		}
442 
443 	}
444 
445 	if ((_animFlags & 3) == 2) {
446 		if ((((_animFlags & 8) == 8) && _vm->getCurrentLineToSay() != _lineToSayId) || !_vm->getAudioManager()->voiceStillPlaying())  // || (_flags & 8)) && _vm->getAudioManager()->voiceStillPlaying())
447 			_animFlags |= 1;
448 
449 	}
450 
451 	if (_time > _vm->getOldMilli())
452 		return;
453 
454 	int32 animFlag = anim->_unused;
455 	int32 nextFrame = currentFrame + 1;
456 	int32 nextTime = _time;
457 	int32 animDir = 1;
458 	if (!animFlag) {
459 		if (_animFlags & 1) {
460 			if (anim->_flags7 == 0xff) {
461 				if (currentFrame > anim->_flag1 / 2)
462 					animDir = 1;
463 				else
464 					animDir = -1;
465 			} else {
466 				if (currentFrame >= anim->_flags6) {
467 					if (currentFrame < anim->_flags7)
468 						currentFrame = anim->_flags7;
469 				}
470 				if (currentFrame > anim->_flags6)
471 					animDir = 1;
472 				else
473 					animDir = -1;
474 			}
475 
476 			nextFrame = currentFrame + animDir;
477 			nextTime = _vm->getOldMilli() + 6 * _vm->getTickLength();
478 		} else {
479 			if (_animFlags & 0x20) {
480 				nextFrame = currentFrame - 1;
481 				if (nextFrame == anim->_flags6 - 1) {
482 					if (anim->_flags8 != 1 && (_vm->randRange(0, 1) == 1 || anim->_flags8 == 2)) {
483 						_animFlags &= ~0x20;
484 						nextFrame += 2;
485 						if (nextFrame > anim->_flags7)
486 							nextFrame = anim->_flags7;
487 					} else {
488 						nextFrame = anim->_flags7;
489 					}
490 				}
491 			} else {
492 				nextFrame = currentFrame + 1;
493 				if (nextFrame == anim->_flags7 + 1 && (_animFlags & 0x40) == 0) {
494 					if (anim->_flags8 != 1 && (_vm->randRange(0, 1) || anim->_flags8 == 2)) {
495 						_animFlags |= 0x20;
496 						nextFrame -= 2;
497 						if (nextFrame < anim->_flags6)
498 							nextFrame = anim->_flags6;
499 					} else {
500 						nextFrame = anim->_flags6;
501 					}
502 				}
503 			}
504 
505 			nextTime = _vm->getOldMilli() + 8 * _vm->getTickLength();
506 		}
507 		// goto label78
508 	}
509 	// skipped all this part.
510 
511 	//label78
512 
513 #if 0
514 	if (_id == 0)
515 		debug(" drew animation name %s / flag %d / frame %d", _specialAnim->_name, _animFlags, nextFrame);
516 	if (_id == 1)
517 		debug(" flux animation flag %d / frame %d", _animFlags, nextFrame);
518 	if (_id == 7)
519 		debug(" footman animation flag %d / frame %d", _animFlags, nextFrame);
520 #endif
521 
522 	_time = nextTime;
523 	if (nextFrame < 0 || nextFrame >= anim->_flag1) {
524 		if ((_animFlags & 2) == 0 || _vm->getCurrentLineToSay() != _lineToSayId) {
525 			stopSpecialAnim();
526 			return;
527 		}
528 
529 		// lots skipped here
530 
531 		_animFlags &= ~0x10;
532 		_animationInstance->forceFrame(0);
533 		return;
534 
535 	}
536 
537 	//if ((_flags & 8) == 0 || !_vm->getAudioManager()->voiceStillPlaying( ) || )
538 	_animationInstance->forceFrame(nextFrame);
539 }
540 
541 // adapted from Kyra
542 int32 Character::getFacingFromDirection(int16 dx, int16 dy) {
543 	debugC(4, kDebugCharacter, "getFacingFromDirection(%d, %d)", dx, dy);
544 
545 	static const int facingTable[] = {
546 		//1, 0, 1, 2,  3, 4, 3, 2,  7, 0, 7, 6,  5, 4, 5, 6
547 		5, 6, 5, 4,  3, 2, 3, 4,  7, 6, 7, 0,  1, 2, 1, 0
548 	};
549 	dx = -dx;
550 
551 	int32 facingEntry = 0;
552 	int16 ydiff = dy;
553 	if (ydiff < 0) {
554 		++facingEntry;
555 		ydiff = -ydiff;
556 	}
557 	facingEntry *= 2;
558 
559 	int16 xdiff = dx;
560 	if (xdiff < 0) {
561 		++facingEntry;
562 		xdiff = -xdiff;
563 	}
564 
565 	facingEntry *= 2;
566 
567 	if (xdiff >= ydiff) {
568 		// Swap xdiff and ydiff
569 		int16 temp = ydiff;
570 		ydiff = xdiff;
571 		xdiff = temp;
572 	} else
573 		facingEntry++;
574 
575 	facingEntry *= 2;
576 
577 	if (xdiff < ((ydiff + 1) / 2))
578 		facingEntry++;
579 
580 	return facingTable[facingEntry];
581 }
582 
583 AnimationInstance *Character::getAnimationInstance() {
584 	return _animationInstance;
585 }
586 
587 void Character::setAnimationInstance(AnimationInstance *instance) {
588 	_animationInstance = instance;
589 }
590 
591 int32 Character::getScale() {
592 	return _scale;
593 }
594 
595 void Character::playWalkAnim(int32 startFrame, int32 endFrame) {
596 }
597 
598 void Character::setId(int32 id) {
599 	_id = id;
600 }
601 
602 int32 Character::getId() {
603 	return _id;
604 }
605 
606 void Character::save(Common::WriteStream *stream) {
607 	debugC(1, kDebugCharacter, "save(stream)");
608 
609 	// we have to save visibility too, put in flags to not invalidate old savegames.
610 	stream->writeSint32LE(_flags | ((_visible == false) ? 0x100 : 0));
611 	stream->writeSint32LE(_x);
612 	stream->writeSint32LE(_y);
613 	stream->writeSint32LE(_z);
614 	stream->writeSint32LE(_finalX);
615 	stream->writeSint32LE(_finalY);
616 	stream->writeSint32LE(_scale);
617 	stream->writeSint32LE(_id);
618 
619 	stream->writeSint32LE(_animScriptId);
620 	stream->writeSint32LE(_animFlags);
621 	stream->writeSint32LE(_animSpecialDefaultId);
622 	stream->writeSint32LE(_sceneAnimationId);
623 }
624 
625 void Character::load(Common::ReadStream *stream) {
626 	debugC(1, kDebugCharacter, "read(stream)");
627 
628 	_flags = stream->readSint32LE();
629 	_flags &= ~1; // characters are not walking when restoring.
630 
631 	_x = stream->readSint32LE();
632 	_y = stream->readSint32LE();
633 	_z = stream->readSint32LE();
634 	_finalX = stream->readSint32LE();
635 	_finalY = stream->readSint32LE();
636 	_scale = stream->readSint32LE();
637 	_id = stream->readSint32LE();
638 
639 	_animScriptId = stream->readSint32LE();
640 	_animFlags = stream->readSint32LE();
641 	_animSpecialDefaultId = stream->readSint32LE();
642 	_sceneAnimationId = stream->readSint32LE();
643 
644 	if (_sceneAnimationId > -1) {
645 		setAnimationInstance(_vm->getSceneAnimation(_sceneAnimationId)->_animInstance);
646 	}
647 
648 	// "not visible" flag.
649 	if (_flags & 0x100) {
650 		_flags &= ~0x100;
651 		setVisible(false);
652 	}
653 }
654 
655 void Character::setAnimScript(int32 animScriptId) {
656 	_animScriptId = animScriptId;
657 }
658 
659 void Character::setSceneAnimationId(int32 sceneAnimationId) {
660 	_sceneAnimationId = sceneAnimationId;
661 }
662 
663 int32 Character::getAnimScript() {
664 	return _animScriptId;
665 }
666 
667 void Character::playTalkAnim() {
668 }
669 
670 void Character::stopWalk() {
671 	debugC(1, kDebugCharacter, "stopWalk()");
672 
673 	_finalX = _x;
674 	_finalY = _y;
675 	_flags &= ~0x1;
676 	_currentPathNode = 0;
677 	_currentPath.clear();
678 }
679 
680 const SpecialCharacterAnimation *Character::getSpecialAnimation(int32 characterId, int32 animationId) {
681 	debugC(6, kDebugCharacter, "getSpecialAnimation(%d, %d)", characterId, animationId);
682 
683 	// very nice animation list hardcoded in the executable...
684 	static const SpecialCharacterAnimation anims[] = {
685 		{ "TLK547_?", 9, 0, 0, 0, 0, 0, 1, 5, 8, 1, 8, 0, 255 },
686 		{ "TLK555_?", 16, 0, 0, 0, 0, 6, 8, 10, 255, 6, 11, 2, 255 },
687 		{ "LST657_?", 14, 0, 0, 0, 0, 255, 255, 255, 255, 5, 11, 0, 255 },
688 		{ "TLK587_?", 18, 0, 0, 0, 0, 5, 7, 9, 11, 4, 13, 1, 255 },
689 		{ "LST659_?", 14, 0, 0, 0, 0, 255, 255, 255, 255, 6, 8, 0, 255 },
690 		{ "TLK595_?", 11, 0, 0, 0, 0, 3, 6, 255, 255, 1, 7, 0, 255 },
691 		{ "IDL165_?", 13, 0, 0, 0, 0, 255, 255, 255, 255, 6, 8, 0, 255 },
692 		{ "LST699_?", 10, 0, 0, 0, 0, 255, 255, 255, 255, 1, 9, 1, 255 },
693 		{ "LST713_?", 10, 0, 0, 0, 0, 255, 255, 255, 255, 4, 6, 0, 255 },
694 		{ "IDL169_?", 16, 0, 0, 0, 0, 255, 255, 255, 255, 5, 9, 2, 255 },
695 		{ "IDL173_?", 19, 0, 0, 0, 0, 255, 255, 255, 255, 4, 17, 1, 255 },
696 		{ "IDL187_?", 14, 0, 0, 0, 0, 255, 255, 255, 255, 4, 8, 0, 255 },
697 		{ "IDL185_?", 15, 0, 0, 0, 0, 255, 255, 255, 255, 6, 9, 1, 255 },
698 		{ "TLK635_?", 16, 0, 0, 0, 0, 5, 8, 10, 12, 4, 12, 0, 255 },
699 		{ "TLK637_?", 18, 0, 0, 0, 0, 5, 7, 9, 12, 4, 13, 0, 255 },
700 		{ "TLK551_?", 20, 0, 0, 0, 0, 5, 9, 11, 15, 4, 16, 0, 255 },
701 		{ "TLK553_?", 20, 0, 0, 0, 0, 7, 9, 11, 13, 6, 15, 0, 255 },
702 		{ "TLK619_?", 18, 0, 0, 0, 0, 5, 8, 11, 13, 5, 15, 0, 255 },
703 		{ "TLK601_?", 12, 0, 0, 0, 0, 2, 5, 6, 10, 2, 10, 1, 255 },
704 		{ "TLK559_?", 18, 0, 0, 0, 0, 4, 6, 10, 12, 4, 13, 0, 255 },
705 		{ "TLK557_?", 16, 0, 0, 0, 0, 6, 8, 10, 255, 6, 11, 0, 255 },
706 		{ "TLK561_?", 17, 0, 0, 0, 0, 6, 8, 10, 12, 5, 12, 0, 255 },
707 		{ "TLK623_?", 19, 0, 0, 0, 0, 6, 8, 10, 13, 6, 14, 0, 255 },
708 		{ "TLK591_?", 20, 0, 0, 0, 0, 10, 14, 255, 255, 7, 15, 0, 255 },
709 		{ "TLK567_?", 19, 0, 0, 0, 0, 6, 9, 11, 14, 5, 15, 0, 255 },
710 		{ "TLK629_?", 18, 0, 0, 0, 0, 6, 8, 10, 11, 6, 12, 0, 255 },
711 		{ "TLK627_?", 19, 0, 0, 0, 0, 7, 10, 12, 14, 4, 14, 0, 255 },
712 		{ "TLK631_?", 19, 0, 0, 0, 0, 8, 10, 255, 255, 8, 12, 0, 255 },
713 		{ "TLK565_?", 17, 0, 0, 0, 0, 4, 7, 9, 11, 3, 12, 0, 255 },
714 		{ "TLK603_?", 16, 0, 0, 0, 0, 5, 255, 255, 255, 3, 9, 0, 255 },
715 		{ "TLK573_?", 20, 0, 0, 0, 0, 6, 7, 10, 255, 6, 16, 2, 255 },
716 		{ "TLK615_?", 17, 0, 0, 0, 0, 6, 8, 10, 12, 5, 12, 0, 255 },
717 		{ "TLK609_?", 18, 0, 0, 0, 0, 6, 8, 10, 12, 5, 13, 0, 255 },
718 		{ "TLK611_?", 18, 0, 0, 0, 0, 8, 10, 12, 255, 7, 13, 0, 255 },
719 		{ "TLK607_?", 16, 0, 0, 0, 0, 4, 7, 9, 11, 4, 12, 0, 255 },
720 		{ "TLK581_?", 15, 0, 0, 0, 0, 7, 9, 11, 255, 6, 11, 0, 255 },
721 		{ "SHD107_?", 46, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
722 		{ "IHL106_?", 23, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 7 },
723 		{ "GLV106_?", 23, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 7 },
724 		{ "FXTKA_?", 11, 0, 0, 0, 0, 7, 255, 255, 255, 2, 9, 0, 255 },
725 		{ "FXTKF_?", 12, 0, 0, 0, 0, 6, 8, 255, 255, 5, 9, 0, 255 },
726 		{ "FXTKG_?", 9, 0, 0, 0, 0, 5, 255, 255, 255, 4, 7, 0, 255 },
727 		{ "FXTKI_?", 12, 0, 0, 0, 0, 6, 255, 255, 255, 5, 9, 0, 255 },
728 		{ "FXTKL_?", 14, 0, 0, 0, 0, 4, 6, 255, 255, 3, 10, 0, 255 },
729 		{ "FXTKO_?", 10, 0, 0, 0, 0, 4, 255, 255, 255, 4, 7, 0, 255 },
730 		{ "FXTKP_?", 9, 0, 0, 0, 0, 4, 6, 255, 255, 3, 7, 0, 255 },
731 		{ "FXTKQ_?", 10, 0, 0, 0, 0, 4, 6, 255, 255, 3, 7, 0, 255 },
732 		{ "FXLSA_?", 11, 0, 0, 0, 0, 255, 255, 255, 255, 4, 6, 0, 255 },
733 		{ "FXLSB_?", 9, 0, 0, 0, 0, 255, 255, 255, 255, 4, 5, 0, 255 },
734 		{ "FXLSK_?", 8, 0, 0, 0, 0, 255, 255, 255, 255, 5, 6, 0, 255 },
735 		{ "FXLSM_?", 7, 0, 0, 0, 0, 255, 255, 255, 255, 4, 4, 0, 255 },
736 		{ "FXLSP_?", 7, 0, 0, 0, 0, 255, 255, 255, 255, 3, 3, 0, 255 },
737 		{ "FXLSQ_?", 6, 0, 0, 0, 0, 255, 255, 255, 255, 3, 3, 0, 255 },
738 		{ "FXIDE_?", 10, 0, 0, 0, 0, 255, 255, 255, 255, 5, 7, 0, 255 },
739 		{ "FXIDI_?", 7, 0, 0, 0, 0, 255, 255, 255, 255, 1, 6, 1, 255 },
740 		{ "FXRCT1_?", 12, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
741 		{ "FXTKB_?", 11, 0, 0, 0, 0, 7, 255, 255, 255, 5, 9, 0, 255 },
742 		{ "FXTKC_?", 14, 0, 0, 0, 0, 2, 5, 8, 10, 1, 12, 2, 255 },
743 		{ "FXTKD_?", 14, 0, 0, 0, 0, 5, 7, 9, 255, 4, 11, 0, 255 },
744 		{ "FXTKE_?", 14, 0, 0, 0, 0, 2, 255, 255, 255, 1, 12, 1, 255 },
745 		{ "FXTKH_?", 11, 0, 0, 0, 0, 6, 8, 255, 255, 4, 9, 0, 255 },
746 		{ "FXTKJ_?", 8, 0, 0, 0, 0, 7, 255, 255, 255, 4, 7, 0, 255 },
747 		{ "FXTKK_?", 13, 0, 0, 0, 0, 6, 8, 255, 255, 5, 9, 0, 255 },
748 		{ "FXTKM_?", 11, 0, 0, 0, 0, 6, 255, 255, 255, 4, 7, 0, 255 },
749 		{ "FXTKN_?", 9, 0, 0, 0, 0, 5, 7, 255, 255, 4, 7, 0, 255 },
750 		{ "FXLSC_?", 9, 0, 0, 0, 0, 255, 255, 255, 255, 3, 6, 1, 255 },
751 		{ "FXLSD_?", 7, 0, 0, 0, 0, 255, 255, 255, 255, 4, 5, 0, 255 },
752 		{ "FXLSE_?", 9, 0, 0, 0, 0, 255, 255, 255, 255, 8, 8, 0, 255 },
753 		{ "FXLSG_?", 11, 0, 0, 0, 0, 255, 255, 255, 255, 6, 8, 2, 255 },
754 		{ "FXLSI_?", 8, 0, 0, 0, 0, 255, 255, 255, 255, 5, 6, 0, 255 },
755 		{ "FXLSJ_?", 5, 0, 0, 0, 0, 255, 255, 255, 255, 3, 4, 0, 255 },
756 		{ "FXLSO_?", 8, 0, 0, 0, 0, 255, 255, 255, 255, 4, 5, 0, 255 },
757 		{ "FXIDA_?", 15, 0, 0, 0, 0, 255, 255, 255, 255, 1, 12, 1, 255 },
758 		{ "FXIDB_?", 12, 0, 0, 0, 0, 255, 255, 255, 255, 4, 11, 1, 255 },
759 		{ "FXIDC_?", 11, 0, 0, 0, 0, 255, 255, 255, 255, 7, 7, 0, 255 },
760 		{ "FXIDD_?", 15, 0, 0, 0, 0, 255, 255, 255, 255, 6, 6, 0, 255 },
761 		{ "FXIDG_?", 6, 0, 0, 0, 0, 255, 255, 255, 255, 3, 4, 0, 255 },
762 		{ "FXVRA_?", 7, 0, 0, 0, 0, 255, 255, 255, 255, 2, 6, 2, 255 },
763 		{ "FXIDF_?", 15, 0, 0, 0, 0, 255, 255, 255, 255, 9, 11, 0, 255 },
764 		{ "FXEXA_?", 9, 0, 0, 0, 0, 255, 255, 255, 255, 5, 5, 0, 255 },
765 		{ "FXEXA_?", 9, 0, 0, 0, 0, 255, 255, 255, 255, 5, 5, 0, 255 },
766 		{ "FFNTK1", 8, 0, 0, 0, 0, 255, 255, 255, 255, 1, 7, 0, 255 },
767 		{ "FFTLK1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 1, 9, 0, 1 },
768 		{ "FFBLS1", 9, 0, 0, 0, 0, 255, 255, 255, 255, 3, 8, 0, 2 },
769 		{ "FFLOV2", 6, 0, 0, 0, 0, 255, 255, 255, 255, 3, 5, 0, 2 },
770 		{ "FFWOE1", 11, 0, 0, 0, 0, 255, 255, 255, 255, 3, 9, 0, 2 },
771 		{ "FFSNF1", 9, 0, 0, 0, 0, 255, 255, 255, 255, 4, 6, 0, 4 },
772 		{ "FFLAF1", 9, 0, 0, 0, 0, 255, 255, 255, 255, 2, 8, 0, 1 },
773 		{ "FFSKE1", 11, 0, 0, 0, 0, 255, 255, 255, 255, 3, 10, 0, 2 },
774 		{ "RGTLK2", 10, 0, 0, 0, 0, 4, 6, 255, 255, 2, 6, 0, 1 },
775 		{ "RGTLK1", 10, 0, 0, 0, 0, 4, 6, 255, 255, 2, 6, 0, 1 },
776 		{ "BRTLK1", 26, 0, 0, 0, 0, 255, 255, 255, 255, 2, 23, 0, 255 },
777 		{ "BREXT1", 14, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
778 		{ "BRLRT1", 19, 0, 0, 0, 0, 255, 255, 255, 255, 1, 15, 0, 255 },
779 		{ "BRBWV1", 12, 0, 0, 0, 0, 255, 255, 255, 255, 3, 8, 0, 255 },
780 		{ "BRPAT1", 11, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
781 		{ "BRBSP1", 7, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
782 		{ "BRBEX1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
783 		{ "BRBLK1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
784 		{ "BRBET1", 17, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
785 		{ "BRWEX1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
786 		{ "BBTLK2", 26, 0, 0, 0, 0, 255, 255, 255, 255, 2, 23, 1, 255 },
787 		{ "BBEXT2", 14, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 1, 255 },
788 		{ "BRLST1", 9, 0, 0, 0, 0, 255, 255, 255, 255, 2, 7, 0, 255 },
789 		{ "BRLSN1", 13, 0, 0, 0, 0, 255, 255, 255, 255, 1, 13, 2, 255 },
790 		{ "BRBNO1", 13, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
791 		{ "BRBND1", 8, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
792 		{ "BBLSN2", 13, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
793 		{ "CCTALK", 6, 0, 0, 0, 0, 2, 5, 255, 255, 1, 5, 0, 255 },
794 		{ "CCBIT1", 13, 0, 0, 0, 0, 3, 5, 9, 11, 2, 11, 2, 255 },
795 		{ "CCCMP1", 13, 0, 0, 0, 0, 6, 9, 255, 255, 5, 10, 1, 2 },
796 		{ "CCCOY1", 14, 0, 0, 0, 0, 6, 8, 255, 255, 4, 8, 0, 3 },
797 		{ "CCFNG1", 5, 0, 0, 0, 0, 255, 255, 255, 255, 4, 4, 0, 255 },
798 		{ "CCGRB1", 13, 0, 0, 0, 0, 6, 255, 255, 255, 6, 9, 0, 3 },
799 		{ "CCGST1", 9, 0, 0, 0, 0, 4, 255, 255, 255, 4, 7, 0, 2 },
800 		{ "CCHCN1", 10, 0, 0, 0, 0, 6, 9, 255, 255, 4, 9, 0, 0 },
801 		{ "CCHND1", 7, 0, 0, 0, 0, 6, 255, 255, 255, 2, 6, 0, 1 },
802 		{ "FTTLK2", 11, 0, 0, 0, 0, 1, 4, 6, 9, 1, 10, 0, 2 },
803 		{ "FTGNO2", 11, 0, 0, 0, 0, 4, 6, 8, 255, 4, 8, 1, 2 },
804 		{ "FTGST2", 6, 0, 0, 0, 0, 1, 2, 4, 5, 2, 5, 0, 1 },
805 		{ "FTHND2", 7, 0, 0, 0, 0, 2, 5, 255, 255, 1, 6, 1, 255 },
806 		{ "FTRNT2", 11, 0, 0, 0, 0, 3, 5, 7, 9, 2, 9, 1, 1 },
807 		{ "FTSRG2", 10, 0, 0, 0, 0, 4, 6, 8, 255, 3, 8, 1, 1 },
808 		{ "FTQOT2", 8, 0, 0, 0, 0, 1, 4, 8, 255, 1, 6, 1, 255 },
809 		{ "FMSTK1", 9, 0, 0, 0, 0, 255, 255, 255, 255, 1, 7, 0, 255 },
810 		{ "FMCRH1", 13, 0, 0, 0, 0, 255, 255, 255, 255, 3, 10, 0, 255 },
811 		{ "FMFGR1", 12, 0, 0, 0, 0, 255, 255, 255, 255, 1, 10, 0, 255 },
812 		{ "FMPRS1", 17, 0, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 255 },
813 		{ "FMAGR1", 12, 0, 0, 0, 0, 255, 255, 255, 255, 2, 9, 0, 255 },
814 		{ "FMWOE1", 11, 0, 0, 0, 0, 255, 255, 255, 255, 1, 9, 0, 255 },
815 		{ "FMTOE1", 17, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
816 		{ "FM1TK1", 12, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
817 		{ "FM2TK1", 6, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
818 		{ "FM3TK1", 8, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
819 		{ "FMTNB1", 4, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
820 		{ "FMLOK1", 6, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
821 		{ "FMCST1", 11, 0, 0, 0, 0, 255, 255, 255, 255, 3, 8, 0, 255 },
822 		{ "FMLUP3", 8, 0, 0, 0, 0, 255, 255, 255, 255, 2, 5, 0, 255 },
823 		{ "BDTLK1", 8, 0, 0, 0, 0, 255, 255, 255, 255, 1, 7, 0, 255 },
824 		{ "BDGLE1", 15, 0, 0, 0, 0, 255, 255, 255, 255, 6, 10, 0, 255 },
825 		{ "BDSHK1", 16, 0, 0, 0, 0, 255, 255, 255, 255, 5, 11, 0, 1 },
826 		{ "BDWOE1", 22, 0, 0, 0, 0, 255, 255, 255, 255, 9, 16, 0, 2 },
827 		{ "BDHIP1", 22, 0, 0, 0, 0, 255, 255, 255, 255, 8, 16, 0, 1 },
828 		{ "BDFLG1", 13, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
829 		{ "BDKLT1", 12, 0, 0, 0, 0, 255, 255, 255, 255, 5, 10, 0, 255 },
830 		{ "BDSWY1", 8, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
831 		{ "WPSNK1", 5, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
832 		{ "WPLAF1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 5, 9, 1, 1 },
833 		{ "DOTLK1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 1, 8, 0, 255 },
834 		{ "DOGST1", 15, 0, 0, 0, 0, 255, 255, 255, 255, 4, 11, 1, 255 },
835 		{ "DO2DF1", 14, 0, 0, 0, 0, 255, 255, 255, 255, 3, 11, 1, 255 },
836 		{ "DOSNG1", 11, 0, 0, 0, 0, 255, 255, 255, 255, 8, 9, 1, 255 },
837 		{ "DOWOE1", 12, 0, 0, 0, 0, 255, 255, 255, 255, 5, 10, 1, 255 },
838 		{ "DO2ME1", 18, 0, 0, 0, 0, 255, 255, 255, 255, 5, 13, 1, 255 },
839 		{ "DOGLP1", 9, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 1, 255 },
840 		{ "DOCRY1", 9, 0, 0, 0, 0, 255, 255, 255, 255, 3, 6, 1, 255 },
841 		{ "METLK1", 5, 0, 0, 0, 0, 255, 255, 255, 255, 1, 4, 0, 255 },
842 		{ "MECHT1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 2, 9, 1, 255 },
843 		{ "ME2DF1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 2, 9, 0, 255 },
844 		{ "MESNG1", 12, 0, 0, 0, 0, 255, 255, 255, 255, 5, 10, 2, 255 },
845 		{ "MEWOE1", 13, 0, 0, 0, 0, 255, 255, 255, 255, 3, 10, 1, 255 },
846 		{ "ME2DO1", 11, 0, 0, 0, 0, 255, 255, 255, 255, 2, 9, 1, 255 },
847 		{ "MEGLP1", 9, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 1, 255 },
848 		{ "MECRY1", 12, 0, 0, 0, 0, 255, 255, 255, 255, 6, 9, 1, 255 },
849 		{ "CSTLK1", 8, 0, 0, 0, 0, 255, 255, 255, 255, 1, 7, 0, 0 },
850 		{ "CSNUD1", 14, 0, 0, 0, 0, 255, 255, 255, 255, 5, 11, 0, 2 },
851 		{ "CSSPR1", 11, 0, 0, 0, 0, 255, 255, 255, 255, 4, 8, 0, 2 },
852 		{ "CSWVE1", 13, 0, 0, 0, 0, 255, 255, 255, 255, 4, 9, 0, 1 },
853 		{ "CSYEL1", 9, 0, 0, 0, 0, 255, 255, 255, 255, 2, 6, 0, 1 },
854 		{ "JMTLK1", 7, 0, 0, 0, 0, 1, 4, 255, 255, 1, 6, 0, 0 },
855 		{ "JMEGO1", 11, 0, 0, 0, 0, 6, 255, 255, 255, 3, 8, 0, 1 },
856 		{ "JMARS1", 7, 0, 0, 0, 0, 4, 6, 255, 255, 3, 6, 0, 2 },
857 		{ "JMHIP1", 8, 0, 0, 0, 0, 3, 5, 7, 255, 2, 7, 0, 1 },
858 		{ "JMBNK1", 2, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
859 		{ "MRTLK1", 9, 0, 0, 0, 0, 4, 7, 255, 255, 2, 7, 0, 1 },
860 		{ "MRHOF1", 8, 0, 0, 0, 0, 3, 5, 255, 255, 2, 5, 0, 255 },
861 		{ "MRMRN1", 11, 0, 0, 0, 0, 3, 7, 255, 255, 1, 8, 0, 0 },
862 		{ "MRDPR1", 11, 0, 0, 0, 0, 1, 5, 9, 255, 1, 8, 0, 255 },
863 		{ "MRGLE1", 13, 0, 0, 0, 0, 5, 9, 255, 255, 3, 10, 0, 2 },
864 		{ "MRTDF1", 11, 0, 0, 0, 0, 3, 7, 9, 255, 3, 9, 0, 1 },
865 		{ "MREDF1", 11, 0, 0, 0, 0, 4, 255, 255, 255, 1, 10, 1, 255 },
866 		{ "MREPL1", 12, 0, 0, 0, 0, 5, 6, 7, 9, 2, 9, 1, 1 },
867 		{ "MRAPL1", 12, 0, 0, 0, 0, 4, 8, 9, 255, 2, 9, 0, 1 },
868 		{ "MREVL1", 8, 0, 0, 0, 0, 5, 255, 255, 255, 1, 5, 1, 255 },
869 		{ "BWDMR1", 16, 0, 0, 0, 0, 4, 7, 9, 11, 3, 14, 0, 1 },
870 		{ "BWBUF1", 12, 0, 0, 0, 0, 5, 8, 255, 255, 3, 11, 0, 1 },
871 		{ "BWHIP1", 12, 0, 0, 0, 0, 3, 6, 255, 255, 1, 9, 2, 0 },
872 		{ "BWHWL1", 14, 0, 0, 0, 0, 255, 255, 255, 255, 1, 4, 2, 255 },
873 		{ "BWLEN1", 10, 0, 0, 0, 0, 3, 6, 255, 255, 2, 7, 0, 1 },
874 		{ "BWSRL1", 6, 0, 0, 0, 0, 255, 255, 255, 255, 2, 5, 0, 1 },
875 		{ "BWWAG1", 6, 0, 0, 0, 0, 4, 10, 14, 18, 1, 4, 0, 0 },
876 		{ "BWYEL1", 8, 0, 0, 0, 0, 4, 255, 255, 255, 2, 7, 0, 1 },
877 		{ "BWTLK1", 15, 0, 0, 0, 0, 5, 8, 255, 255, 5, 9, 0, 1 },
878 		{ "SLTLK1", 19, 0, 0, 0, 0, 255, 255, 255, 255, 1, 18, 0, 255 },
879 		{ "SLPND1", 12, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
880 		{ "SLPNT1", 8, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
881 		{ "SLPTR1", 14, 0, 0, 0, 0, 255, 255, 255, 255, 6, 13, 1, 255 },
882 		{ "SDTLK1", 7, 0, 0, 0, 0, 255, 255, 255, 255, 1, 5, 0, 255 },
883 		{ "SDPDF1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 3, 6, 0, 255 },
884 		{ "SDPNT1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 2, 7, 0, 255 },
885 		{ "SDSLF1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 2, 7, 0, 255 },
886 		{ "SDSTG1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
887 		{ "SDWVE1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 1, 8, 0, 255 },
888 		{ "SDSTK1", 9, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
889 		{ "SDSMK1", 22, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
890 		{ "SDGLN1", 5, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
891 		{ "SDLAF1", 8, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
892 		{ "RMHIP1", 12, 0, 0, 0, 0, 7, 255, 255, 255, 1, 10, 2, 255 },
893 		{ "RMGES1", 19, 0, 0, 0, 0, 11, 255, 255, 255, 8, 13, 2, 2 },
894 		{ "RMPCH1", 18, 0, 0, 0, 0, 12, 255, 255, 255, 6, 13, 0, 2 },
895 		{ "RMSTH1", 12, 0, 0, 0, 0, 5, 255, 255, 255, 3, 6, 0, 2 },
896 		{ "RMHND1", 7, 0, 0, 0, 0, 5, 255, 255, 255, 5, 5, 1, 255 },
897 		{ "RMSTH1", 12, 0, 0, 0, 0, 5, 255, 255, 255, 5, 6, 1, 2 },
898 		{ "SGHND1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 1, 9, 0, 0 },
899 		{ "SGSTF1", 13, 0, 0, 0, 0, 255, 255, 255, 255, 1, 12, 0, 255 },
900 		{ "SGSLP1", 16, 0, 0, 0, 0, 255, 255, 255, 255, 1, 15, 0, 255 },
901 		{ "SGPHC1", 12, 0, 0, 0, 0, 255, 255, 255, 255, 4, 9, 0, 255 },
902 		{ "SGHALT", 22, 0, 0, 0, 0, 255, 255, 255, 255, 7, 15, 0, 255 },
903 		{ "STTLK1", 13, 0, 0, 0, 0, 5, 9, 255, 255, 3, 10, 0, 2 },
904 		{ "STTNM1", 13, 0, 0, 0, 0, 5, 9, 255, 255, 3, 10, 0, 2 },
905 		{ "STFST1", 11, 0, 0, 0, 0, 3, 8, 255, 255, 1, 9, 0, 255 },
906 		{ "STLAF1", 20, 0, 0, 0, 0, 255, 255, 255, 255, 11, 15, 1, 2 },
907 		{ "STGES1", 13, 0, 0, 0, 0, 5, 7, 255, 255, 3, 7, 0, 2 },
908 		{ "STFNT1", 10, 0, 0, 0, 0, 4, 6, 255, 255, 255, 255, 0, 2 },
909 		{ "STSRK1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 1, 3, 2, 0 },
910 		{ "STRED1", 11, 0, 0, 0, 0, 255, 255, 255, 255, 2, 10, 0, 255 },
911 		{ "STLKU1", 6, 0, 0, 0, 0, 3, 255, 255, 255, 2, 5, 0, 0 },
912 		{ "STKEY1", 15, 0, 0, 0, 0, 9, 11, 255, 255, 9, 14, 0, 255 },
913 		{ "STMKTD1", 7, 0, 0, 0, 0, 3, 6, 255, 255, 1, 6, 0, 255 },
914 		{ "STTKM1", 21, 0, 0, 0, 0, 12, 13, 15, 16, 12, 17, 0, 1 },
915 		{ "STMSZ1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 1, 3, 2, 255 },
916 		{ "STPNV1", 14, 0, 0, 0, 0, 6, 11, 255, 255, 4, 11, 0, 1 },
917 		{ "STSOM1", 10, 0, 0, 0, 0, 255, 255, 255, 255, 1, 3, 2, 255 },
918 		{ "MYTLK1", 9, 0, 0, 0, 0, 2, 4, 255, 255, 1, 4, 0, 0 },
919 		{ "MYSQUAWK", 5, 0, 0, 0, 0, 255, 255, 255, 255, 3, 3, 1, 255 },
920 		{ "SPTLK", 12, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
921 		{ "SPARM", 16, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
922 		{ "SPHOP", 18, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
923 		{ "SPLNT", 16, 0, 0, 0, 0, 255, 255, 255, 255, 3, 13, 0, 255 },
924 		{ "SPLAF", 11, 0, 0, 0, 0, 255, 255, 255, 255, 5, 10, 2, 255 },
925 		{ "SPTFN", 10, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
926 		{ "SPPIN", 14, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
927 		{ "SPINH1", 21, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
928 		{ "SPSFTCOM", 10, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 255 },
929 		{ "MFTMZ1", 9, 0, 0, 0, 0, 255, 255, 255, 255, 1, 8, 1, 255 },
930 		{ "MFTLK1", 13, 0, 0, 0, 0, 2, 7, 255, 255, 1, 12, 1, 255 },
931 		{ "VGCIR1", 15, 0, 0, 0, 0, 5, 9, 255, 255, 2, 13, 1, 255 },
932 		{ "VGBIT1", 12, 0, 0, 0, 0, 6, 9, 255, 255, 2, 9, 1, 255 },
933 		{ "VGANG1", 10, 0, 0, 0, 0, 9, 255, 255, 255, 1, 9, 0, 255 },
934 		{ "VGCOM1", 13, 0, 0, 0, 0, 5, 11, 255, 255, 2, 11, 0, 255 },
935 		{ "VGCUR1", 8, 0, 0, 0, 0, 4, 8, 255, 255, 2, 7, 0, 255 },
936 		{ "VGTLK1", 11, 0, 0, 0, 0, 3, 6, 255, 255, 3, 10, 0, 255 },
937 		{ "VGEXP1", 10, 0, 0, 0, 0, 5, 9, 255, 255, 3, 9, 0, 255 },
938 		{ "WFTLK1", 8, 0, 0, 0, 0, 255, 255, 255, 255, 1, 7, 0, 1 },
939 		{ "WFPNT1", 20, 0, 0, 0, 0, 255, 255, 255, 255, 6, 16, 0, 1 },
940 		{ "WFFST1", 13, 0, 0, 0, 0, 255, 255, 255, 255, 2, 8, 0, 2 },
941 		{ "WFTNO1", 8, 0, 0, 0, 0, 255, 255, 255, 255, 2, 5, 0, 2 },
942 		{ "WFSRG1", 11, 0, 0, 0, 0, 255, 255, 255, 255, 3, 8, 0, 1 },
943 		{ "WFGTK1", 16, 0, 0, 0, 0, 255, 255, 255, 255, 1, 15, 0, 255 },
944 		{ "WFPAW1", 24, 0, 0, 0, 0, 255, 255, 255, 255, 4, 22, 0, 1 },
945 		{ "LGTLK", 20, 0, 0, 0, 0, 4, 8, 11, 15, 1, 17, 0, 255 },
946 		{ "LGSHOUT", 16, 0, 0, 0, 0, 12, 255, 255, 255, 6, 12, 0, 255 },
947 		{ "POMRN1", 12, 0, 0, 0, 0, 3, 5, 7, 255, 3, 9, 0, 2 },
948 		{ "POGLE1", 14, 0, 0, 0, 0, 7, 10, 255, 255, 5, 10, 0, 2 },
949 		{ "PLMRG1", 16, 0, 0, 0, 0, 9, 255, 255, 255, 8, 12, 0, 1 },
950 		{ "PLCMR1", 16, 0, 0, 0, 0, 8, 10, 255, 255, 8, 12, 0, 3 },
951 		{ "PLEVL1", 17, 0, 0, 0, 0, 9, 255, 255, 255, 7, 9, 0, 1 },
952 		{ "PLEDF1", 9, 0, 0, 0, 0, 4, 6, 255, 255, 5, 7, 0, 2 },
953 		{ "PLTLK1", 11, 0, 0, 0, 0, 5, 8, 255, 255, 5, 8, 0, 1 },
954 		{ "ELTLK1", 8, 0, 0, 0, 0, 3, 5, 7, 255, 2, 7, 0, 255 },
955 		{ "ELSNR1", 7, 0, 0, 0, 0, 3, 255, 255, 255, 1, 5, 0, 255 },
956 		{ "RG2TK1", 10, 0, 0, 0, 0, 4, 6, 255, 255, 2, 6, 0, 1 },
957 		{ "RG2TK1", 10, 0, 0, 0, 0, 4, 6, 255, 255, 2, 6, 0, 1 },
958 		{ "C2TALK", 6, 0, 0, 0, 0, 2, 5, 255, 255, 1, 5, 0, 255 },
959 		{ "C2BIT1", 13, 0, 0, 0, 0, 3, 5, 9, 11, 2, 11, 2, 255 },
960 		{ "C2CMP1", 13, 0, 0, 0, 0, 6, 9, 255, 255, 5, 10, 1, 2 },
961 		{ "C2COY1", 14, 0, 0, 0, 0, 6, 8, 255, 255, 4, 8, 0, 3 },
962 		{ "C2FNG1", 5, 0, 0, 0, 0, 255, 255, 255, 255, 4, 4, 0, 255 },
963 		{ "C2GRB1", 13, 0, 0, 0, 0, 6, 255, 255, 255, 6, 9, 0, 3 },
964 		{ "C2GST1", 9, 0, 0, 0, 0, 4, 255, 255, 255, 4, 7, 0, 2 },
965 		{ "C2HCN1", 10, 0, 0, 0, 0, 6, 9, 255, 255, 4, 9, 0, 0 },
966 		{ "C2HND1", 7, 0, 0, 0, 0, 6, 255, 255, 255, 2, 6, 0, 1 },
967 		{ "666TKBB3", 21, 0, 0, 0, 0, 9, 14, 255, 255, 6, 16, 0, 255 },
968 		{ "665TFLX3", 27, 0, 0, 0, 0, 10, 14, 17, 255, 10, 18, 0, 255 },
969 		{ "664FXTK3", 18, 0, 0, 0, 0, 5, 7, 11, 13, 3, 15, 0, 255 },
970 		{ "FDTALK", 15, 0, 0, 0, 0, 9, 255, 255, 255, 7, 9, 0, 255 },
971 		{ "FDYELL", 16, 0, 0, 0, 0, 10, 255, 255, 255, 8, 10, 0, 255 },
972 		{ "GLTLK", 20, 0, 0, 0, 0, 6, 12, 18, 255, 1, 19, 0, 255 },
973 		{ "GLTRN", 4, 0, 0, 0, 0, 3, 255, 255, 255, 1, 2, 0, 255 },
974 		{ "RAYTALK1", 10, 0, 0, 0, 0, 3, 5, 8, 255, 1, 9, 0, 255 },
975 		{ "BRTKB1", 17, 0, 0, 0, 0, 255, 255, 255, 255, 2, 14, 0, 255 }
976 	};
977 
978 	static const int32 characterAnims[] = {
979 		0,   39,  81,  89,  91,  108, 117, 124, 138, 146,
980 		148, 156, 164, 169, 174, 179, 184, 193, 197, 207,
981 		213, 218, 233, 235, 244, 245, 246, 246, 246, 246,
982 		253, 253, 253, 253, 260, 262, 264, 269, 271, 273,
983 		282, 284, 285, 287, 289, 290, 291, 291, 291, 291,
984 		289, 289, 289, 289, 289, 289, 289, 289, 289, 289
985 	};
986 
987 	return &anims[characterAnims[characterId] + animationId];
988 }
989 
990 bool Character::loadShadowAnimation(const Common::String &animName) {
991 	debugC(1, kDebugCharacter, "loadShadowAnimation(%s)", animName.c_str());
992 
993 	delete _shadowAnim;
994 	_shadowAnim = new Animation(_vm);
995 	if (!_shadowAnim->loadAnimation(animName))
996 		return false;
997 
998 	delete _shadowAnimationInstance;
999 	_shadowAnimationInstance = _vm->getAnimationManager()->createNewInstance(kAnimationCharacter);
1000 	_vm->getAnimationManager()->addInstance(_shadowAnimationInstance);
1001 	_shadowAnimationInstance->setAnimation(_shadowAnim);
1002 	_shadowAnimationInstance->setVisible(true);
1003 	_shadowAnimationInstance->setUseMask(true);
1004 
1005 	return true;
1006 }
1007 
1008 void Character::plotPath(Graphics::Surface& surface) {
1009 	for (uint32 i = 0; i < _currentPath.size(); i++) {
1010 		 *(byte *)surface.getBasePtr(_currentPath[i].x, _currentPath[i].y) = (i < _currentPathNode);
1011 	}
1012 }
1013 
1014 void Character::playAnim(int32 animId, int32 unused, int32 flags) {
1015 	debugC(3, kDebugCharacter, "playAnim(%d, unused, %d)", animId, flags);
1016 
1017 	if (animId == 0)
1018 		animId = _animSpecialDefaultId;
1019 
1020 	// get the anim to load
1021 	const SpecialCharacterAnimation *anim = getSpecialAnimation(_id, animId);
1022 
1023 	Common::String animNameStr = anim->_filename;
1024 
1025 	int32 facing = _facing;
1026 	if (_id == 1) {
1027 		// flux special case... some animations are not for every facing
1028 		facing = CharacterFlux::fixFacingForAnimation(facing, animId);
1029 	}
1030 
1031 	Common::replace(animNameStr, Common::String('?'), Common::String('0' + facing));
1032 	animNameStr += ".CAF";
1033 
1034 	if (_animScriptId != -1 && (flags & 8) == 0)
1035 		_vm->getSceneAnimationScript(_animScriptId)->_frozenForConversation = true;
1036 
1037 	stopSpecialAnim();
1038 
1039 	if (flags & 8) {
1040 		// talker
1041 		_lineToSayId = _vm->getCurrentLineToSay();
1042 
1043 		// make the talker busy
1044 		_flags |= 1;
1045 
1046 		// old special anim was talking anim ? in this case we don't wait for the character to be ready
1047 		bool wasTalkAnim = _specialAnim && Common::String(_specialAnim->_name).contains("TLK");
1048 
1049 		// wait for the character to be ready
1050 		while (_animScriptId != -1 && _animationInstance && _animationInstance->getFrame() > 0 && !wasTalkAnim && (_specialAnim && _animationInstance->getAnimation() != _specialAnim)) {
1051 			_vm->simpleUpdate(false);
1052 		}
1053 	}
1054 
1055 	if (_sceneAnimationId > -1)
1056 		setAnimationInstance(_vm->getSceneAnimation(_sceneAnimationId)->_animInstance);
1057 
1058 	_animFlags |= flags;
1059 
1060 	delete _specialAnim;
1061 	_specialAnim = new Animation(_vm);
1062 	_specialAnim->loadAnimation(animNameStr.c_str());
1063 
1064 	_animSpecialId = animId;
1065 
1066 	if (_animationInstance) {
1067 		_animationInstance->setAnimation(_specialAnim);
1068 		_animationInstance->setAnimationRange(0, _specialAnim->_numFrames - 1);
1069 		_animationInstance->reset();
1070 		_animationInstance->stopAnimation();
1071 		_animationInstance->setLooping(false);
1072 	}
1073 }
1074 
1075 int32 Character::getAnimFlag() {
1076 	return _animFlags;
1077 }
1078 
1079 void Character::setAnimFlag(int32 flag) {
1080 	_animFlags = flag;
1081 }
1082 
1083 int32 Character::getSceneAnimationId() {
1084 	return _sceneAnimationId;
1085 }
1086 
1087 void Character::setDefaultSpecialAnimationId(int32 defaultAnimationId) {
1088 	_animSpecialDefaultId = defaultAnimationId;
1089 }
1090 
1091 int16 Character::getFinalX() {
1092 	return _finalX;
1093 }
1094 
1095 int16 Character::getFinalY() {
1096 	return _finalY;
1097 }
1098 
1099 void Character::updateIdle() {
1100 	debugC(5, kDebugCharacter, "updateIdle()");
1101 
1102 	// only flux and drew
1103 	if (_id > 1)
1104 		return;
1105 
1106 	if (_vm->state()->_mouseHidden)
1107 		_nextIdleTime = _vm->getOldMilli() + (300 + _vm->randRange(0, 600)) * _vm->getTickLength();
1108 
1109 	if (_vm->getOldMilli() > _nextIdleTime) {
1110 		if (((_flags & 1) == 0) || ((_flags & 2) != 0)) {
1111 			if (!_vm->state()->_inCloseUp && !_vm->state()->_inCutaway && _animSpecialId == -1) {
1112 				if (!_vm->state()->_mouseHidden) {
1113 					_nextIdleTime = _vm->getOldMilli() + (300 + _vm->randRange(0, 600)) * _vm->getTickLength();
1114 					playAnim(getRandomIdleAnim(), 0, 0x40);
1115 					_flags |= 0x4;
1116 				}
1117 			}
1118 		}
1119 	}
1120 }
1121 } // End of namespace Toon
1122