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 #include "common/rect.h"
25 #include "common/textconsole.h"
26
27 #include "queen/talk.h"
28
29 #include "queen/bankman.h"
30 #include "queen/display.h"
31 #include "queen/graphics.h"
32 #include "queen/grid.h"
33 #include "queen/input.h"
34 #include "queen/logic.h"
35 #include "queen/queen.h"
36 #include "queen/resource.h"
37 #include "queen/sound.h"
38 #include "queen/state.h"
39 #include "queen/walk.h"
40
41 #include "common/file.h"
42
43 namespace Queen {
44
talk(const char * filename,int personInRoom,char * cutawayFilename,QueenEngine * vm)45 void Talk::talk(
46 const char *filename,
47 int personInRoom,
48 char *cutawayFilename,
49 QueenEngine *vm) {
50 Talk *talk = new Talk(vm);
51 talk->talk(filename, personInRoom, cutawayFilename);
52 delete talk;
53 }
54
speak(const char * sentence,Person * person,const char * voiceFilePrefix,QueenEngine * vm)55 bool Talk::speak(
56 const char *sentence,
57 Person *person,
58 const char *voiceFilePrefix,
59 QueenEngine *vm) {
60 Talk *talk = new Talk(vm);
61 bool result;
62 if (sentence)
63 result = talk->speak(sentence, person, voiceFilePrefix);
64 else
65 result = false;
66 delete talk;
67 return result;
68 }
69
Talk(QueenEngine * vm)70 Talk::Talk(QueenEngine *vm)
71 : _vm(vm), _fileData(NULL) {
72 _vm->input()->talkQuitReset();
73 }
74
~Talk()75 Talk::~Talk() {
76 delete[] _fileData;
77 }
78
talk(const char * filename,int personInRoom,char * cutawayFilename)79 void Talk::talk(const char *filename, int personInRoom, char *cutawayFilename) {
80 int i;
81 _oldSelectedSentenceIndex = 0;
82 _oldSelectedSentenceValue = 0;
83
84 debug(6, "----- talk(\"%s\") -----", filename);
85
86 cutawayFilename[0] = '\0';
87
88 load(filename);
89
90 Person person;
91 memset(&person, 0, sizeof(Person));
92 _vm->logic()->initPerson(personInRoom, "", false, &person);
93
94 if (NULL == person.name) {
95 error("Invalid person object");
96 }
97
98 int16 oldLevel = 0;
99
100 // Lines 828-846 in talk.c
101 for (i = 1; i <= 4; i++) {
102 if (selectedValue(i) > 0) {
103 // This option has been redefined so display new dialogue option
104 _dialogueTree[1][i].head = selectedValue(i);
105 } else if (selectedValue(i) == -1) {
106 // Already selected so don't redisplay
107 if (_dialogueTree[1][i].gameStateIndex >= 0) {
108 _dialogueTree[1][i].head = -1;
109 _dialogueTree[1][i].dialogueNodeValue1 = -1;
110 _dialogueTree[1][i].gameStateIndex = -1;
111 _dialogueTree[1][i].gameStateValue = -1;
112 }
113 }
114 }
115
116 initialTalk();
117
118 // Lines 906-? in talk.c
119 _vm->display()->showMouseCursor(true);
120
121 int16 level=1, retval=0;
122 int16 head = _dialogueTree[level][0].head;
123
124 // TODO: split this loop in several functions
125 while (retval != -1) {
126 char otherVoiceFilePrefix[MAX_STRING_SIZE];
127
128 _talkString[0][0] = '\0';
129
130 if (hasTalkedTo() && head == 1)
131 strcpy(_talkString[0], _person2String);
132 else
133 findDialogueString(_person1PtrOff, head, _pMax, _talkString[0]);
134
135 if (hasTalkedTo() && head == 1)
136 sprintf(otherVoiceFilePrefix, "%2dXXXXP", _talkKey);
137 else
138 sprintf(otherVoiceFilePrefix, "%2d%4xP", _talkKey, head);
139
140 if (_talkString[0][0] == '\0' && retval > 1) {
141 findDialogueString(_person1PtrOff, retval, _pMax, _talkString[0]);
142 sprintf(otherVoiceFilePrefix,"%2d%4xP", _talkKey, retval);
143 }
144
145 // Joe dialogue
146
147 for (i = 1; i <= 4; i++) {
148 findDialogueString(_joePtrOff, _dialogueTree[level][i].head, _jMax, _talkString[i]);
149
150 int16 index = _dialogueTree[level][i].gameStateIndex;
151
152 if (index < 0 && _vm->logic()->gameState(ABS(index)) != _dialogueTree[level][i].gameStateValue)
153 _talkString[i][0] = '\0';
154
155 sprintf(_joeVoiceFilePrefix[i], "%2d%4xJ", _talkKey, _dialogueTree[level][i].head);
156 }
157
158 // Check to see if (all the dialogue options have been selected.
159 // if this is the case, and the last one left is the exit option,
160 // then automatically set S to that and exit.
161
162 int choicesLeft = 0;
163 int selectedSentence = 0;
164
165 for (i = 1; i <= 4; i++) {
166 if (_talkString[i][0] != '\0') {
167 choicesLeft++;
168 selectedSentence = i;
169 }
170 }
171
172 debug(6, "choicesLeft = %i", choicesLeft);
173
174 if (1 == choicesLeft) {
175 // Automatically run the final dialogue option
176 speak(_talkString[0], &person, otherVoiceFilePrefix);
177
178 if (_vm->input()->talkQuit())
179 break;
180
181 speak(_talkString[selectedSentence], NULL, _joeVoiceFilePrefix[selectedSentence]);
182 } else {
183 if (person.actor->bobNum > 0) {
184 speak(_talkString[0], &person, otherVoiceFilePrefix);
185 selectedSentence = selectSentence();
186 } else {
187 warning("bobBum is %i", person.actor->bobNum);
188 selectedSentence = 0;
189 }
190 }
191
192 if (_vm->input()->talkQuit() || _vm->shouldQuit())
193 break;
194
195 retval = _dialogueTree[level][selectedSentence].dialogueNodeValue1;
196 head = _dialogueTree[level][selectedSentence].head;
197 oldLevel = level;
198 level = 0;
199
200 // Set LEVEL to the selected child in dialogue tree
201
202 for (i = 1; i <= _levelMax; i++)
203 if (_dialogueTree[i][0].head == head)
204 level = i;
205
206 if (0 == level) {
207 // No new level has been selected, so lets set LEVEL to the
208 // tree path pointed to by the RETVAL
209
210 for (i = 1; i <= _levelMax; i++)
211 for (int j = 0; j <= 5; j++)
212 if (_dialogueTree[i][j].head == retval)
213 level = i;
214
215 disableSentence(oldLevel, selectedSentence);
216 } else { // 0 != level
217 // Check to see if Person Return value is positive, if it is, then
218 // change the selected dialogue option to the Return value
219
220 if (_dialogueTree[level][0].dialogueNodeValue1 > 0) {
221 if (1 == oldLevel) {
222 _oldSelectedSentenceIndex = selectedSentence;
223 _oldSelectedSentenceValue = selectedValue(selectedSentence);
224 selectedValue(selectedSentence, _dialogueTree[level][0].dialogueNodeValue1);
225 }
226
227 _dialogueTree[oldLevel][selectedSentence].head = _dialogueTree[level][0].dialogueNodeValue1;
228 _dialogueTree[level][0].dialogueNodeValue1 = -1;
229 } else {
230 disableSentence(oldLevel, selectedSentence);
231 }
232 }
233
234 // Check selected person to see if any Gamestates need setting
235
236 int16 index = _dialogueTree[level][0].gameStateIndex;
237 if (index > 0)
238 _vm->logic()->gameState(index, _dialogueTree[level][0].gameStateValue);
239
240 // if the selected dialogue line has a POSITIVE game state value
241 // then set gamestate to Value = TALK(OLDLEVEL,S,3)
242
243 index = _dialogueTree[oldLevel][selectedSentence].gameStateIndex;
244 if (index > 0)
245 _vm->logic()->gameState(index, _dialogueTree[oldLevel][selectedSentence].gameStateValue);
246
247 // check to see if person has something final to say
248 if (-1 == retval) {
249 findDialogueString(_person1PtrOff, head, _pMax, _talkString[0]);
250 if (_talkString[0][0] != '\0') {
251 sprintf(otherVoiceFilePrefix, "%2d%4xP", _talkKey, head);
252 speak(_talkString[0], &person, otherVoiceFilePrefix);
253 }
254 }
255 }
256
257 cutawayFilename[0] = '\0';
258
259 for (i = 0; i < 2; i++) {
260 if (_gameState[i] > 0) {
261 if (_vm->logic()->gameState(_gameState[i]) == _testValue[i]) {
262 if (_itemNumber[i] > 0)
263 _vm->logic()->inventoryInsertItem(_itemNumber[i]);
264 else
265 _vm->logic()->inventoryDeleteItem(ABS(_itemNumber[i]));
266 }
267 }
268 }
269
270 _vm->grid()->setupPanel();
271
272 uint16 offset = _cutawayPtrOff;
273
274 int16 cutawayGameState = (int16)READ_BE_INT16(_fileData + offset); offset += 2;
275 int16 cutawayTestValue = (int16)READ_BE_INT16(_fileData + offset); offset += 2;
276
277 if (_vm->logic()->gameState(cutawayGameState) == cutawayTestValue) {
278 getString(_fileData, offset, cutawayFilename, 20);
279 if (cutawayFilename[0]) {
280 //CR 2 - 7/3/95, If we're executing a cutaway scene, then make sure
281 // Joe can talk, so set TALKQUIT to 0 just in case we exit on the
282 // line that set's the cutaway game states.
283 _vm->input()->talkQuitReset();
284 }
285 }
286 if (_vm->input()->talkQuit()) {
287 if (_oldSelectedSentenceIndex > 0)
288 selectedValue(_oldSelectedSentenceIndex, _oldSelectedSentenceValue);
289 _vm->input()->talkQuitReset();
290 _vm->display()->clearTexts(0, 198);
291 _vm->logic()->makeJoeSpeak(15, false);
292 } else {
293 setHasTalkedTo();
294 }
295
296 _vm->logic()->joeFace();
297
298 if (cutawayFilename[0] == '\0') {
299 BobSlot *pbs = _vm->graphics()->bob(person.actor->bobNum);
300
301 pbs->x = person.actor->x;
302 pbs->y = person.actor->y;
303
304 // Better kick start the persons anim sequence
305 _vm->graphics()->resetPersonAnim(person.actor->bobNum);
306 }
307
308 _vm->logic()->joeWalk(JWM_NORMAL);
309 }
310
disableSentence(int oldLevel,int selectedSentence)311 void Talk::disableSentence(int oldLevel, int selectedSentence) {
312 // Mark off selected option
313
314 if (1 == oldLevel) {
315 if (_dialogueTree[oldLevel][selectedSentence].dialogueNodeValue1 != -1) {
316 // Make sure choice is not exit option
317 _oldSelectedSentenceIndex = selectedSentence;
318 _oldSelectedSentenceValue = selectedValue(selectedSentence);
319 selectedValue(selectedSentence, -1);
320 }
321 }
322
323 // Cancel selected dialogue line, so that its no longer displayed
324 _dialogueTree[oldLevel][selectedSentence].head = -1;
325 _dialogueTree[oldLevel][selectedSentence].dialogueNodeValue1 = -1;
326 }
327
findDialogueString(uint16 offset,int16 id,int16 max,char * str)328 void Talk::findDialogueString(uint16 offset, int16 id, int16 max, char *str) {
329 str[0] = '\0';
330 for (int i = 1; i <= max; i++) {
331 offset += 2;
332 int16 currentId = (int16)READ_BE_INT16(_fileData + offset);
333 offset += 2;
334 if (id == currentId) {
335 getString(_fileData, offset, str, MAX_STRING_LENGTH, 4);
336 break;
337 } else {
338 getString(_fileData, offset, NULL, MAX_STRING_LENGTH, 4);
339 }
340 }
341 }
342
loadDialogFile(const char * filename)343 byte *Talk::loadDialogFile(const char *filename) {
344 static const struct {
345 const char *filename;
346 Common::Language language;
347 } dogFiles[] = {
348 { "CHIEF1.DOG", Common::FR_FRA },
349 { "CHIEF2.DOG", Common::FR_FRA },
350 { "BUD1.DOG", Common::IT_ITA }
351 };
352 for (int i = 0; i < ARRAYSIZE(dogFiles); ++i) {
353 if (!scumm_stricmp(filename, dogFiles[i].filename) &&
354 _vm->resource()->getLanguage() == dogFiles[i].language) {
355 Common::File fdog;
356 fdog.open(filename);
357 if (fdog.isOpen()) {
358 debug(6, "Loading dog file '%s' from game data path", filename);
359 uint32 size = fdog.size() - DOG_HEADER_SIZE;
360 byte *buf = new byte[size];
361 fdog.seek(DOG_HEADER_SIZE);
362 fdog.read(buf, size);
363 return buf;
364 }
365 }
366 }
367 return _vm->resource()->loadFile(filename, DOG_HEADER_SIZE);
368 }
369
load(const char * filename)370 void Talk::load(const char *filename) {
371 int i;
372 byte *ptr = _fileData = loadDialogFile(filename);
373
374 // Load talk header
375
376 _levelMax = (int16)READ_BE_INT16(ptr); ptr += 2;
377
378 if (_levelMax < 0) {
379 _levelMax = -_levelMax;
380 _vm->input()->canQuit(false);
381 } else {
382 _vm->input()->canQuit(true);
383 }
384
385 _uniqueKey = (int16)READ_BE_INT16(ptr); ptr += 2;
386 _talkKey = (int16)READ_BE_INT16(ptr); ptr += 2;
387 _jMax = (int16)READ_BE_INT16(ptr); ptr += 2;
388 _pMax = (int16)READ_BE_INT16(ptr); ptr += 2;
389
390 for (i = 0; i < 2; i++) {
391 _gameState [i] = (int16)READ_BE_INT16(ptr); ptr += 2;
392 _testValue [i] = (int16)READ_BE_INT16(ptr); ptr += 2;
393 _itemNumber[i] = (int16)READ_BE_INT16(ptr); ptr += 2;
394 }
395
396 _person1PtrOff = READ_BE_UINT16(ptr); ptr += 2;
397 _cutawayPtrOff = READ_BE_UINT16(ptr); ptr += 2;
398 _person2PtrOff = READ_BE_UINT16(ptr); ptr += 2;
399 _joePtrOff = 32 + _levelMax * 96;
400
401 // Load dialogue tree
402 ptr = _fileData + 32;
403 memset(&_dialogueTree[0], 0, sizeof(_dialogueTree[0]));
404 for (i = 1; i <= _levelMax; i++)
405 for (int j = 0; j <= 5; j++) {
406 ptr += 2;
407 _dialogueTree[i][j].head = (int16)READ_BE_INT16(ptr); ptr += 2;
408 ptr += 2;
409 _dialogueTree[i][j].dialogueNodeValue1 = (int16)READ_BE_INT16(ptr); ptr += 2;
410 ptr += 2;
411 _dialogueTree[i][j].gameStateIndex = (int16)READ_BE_INT16(ptr); ptr += 2;
412 ptr += 2;
413 _dialogueTree[i][j].gameStateValue = (int16)READ_BE_INT16(ptr); ptr += 2;
414 }
415 }
416
initialTalk()417 void Talk::initialTalk() {
418 // Lines 848-903 in talk.c
419
420 uint16 offset = _joePtrOff + 2;
421 uint16 hasNotString = READ_BE_UINT16(_fileData + offset); offset += 2;
422
423 char joeString[MAX_STRING_SIZE];
424 if (!hasNotString) {
425 getString(_fileData, offset, joeString, MAX_STRING_LENGTH);
426 } else {
427 joeString[0] = '\0';
428 }
429
430 offset = _person2PtrOff;
431 char joe2String[MAX_STRING_SIZE];
432 getString(_fileData, offset, _person2String, MAX_STRING_LENGTH);
433 getString(_fileData, offset, joe2String, MAX_STRING_LENGTH);
434
435 if (!hasTalkedTo()) {
436 // Not yet talked to this person
437 if (joeString[0] != '0') {
438 char voiceFilePrefix[MAX_STRING_SIZE];
439 sprintf(voiceFilePrefix, "%2dSSSSJ", _talkKey);
440 speak(joeString, NULL, voiceFilePrefix);
441 }
442 } else {
443 // Already spoken to them, choose second response
444 if (joe2String[0] != '0') {
445 char voiceFilePrefix[MAX_STRING_SIZE];
446 sprintf(voiceFilePrefix, "%2dXXXXJ", _talkKey);
447 speak(joe2String, NULL, voiceFilePrefix);
448 }
449 }
450 }
451
getSpeakCommand(const Person * person,const char * sentence,unsigned & index)452 int Talk::getSpeakCommand(const Person *person, const char *sentence, unsigned &index) {
453 // Lines 1299-1362 in talk.c
454 int commandCode = SPEAK_DEFAULT;
455 uint16 id = (sentence[index] << 8) | sentence[index + 1];
456 switch (id) {
457 case 'AO':
458 commandCode = SPEAK_AMAL_ON;
459 break;
460 case 'FL':
461 commandCode = SPEAK_FACE_LEFT;
462 break;
463 case 'FF':
464 commandCode = SPEAK_FACE_FRONT;
465 break;
466 case 'FB':
467 commandCode = SPEAK_FACE_BACK;
468 break;
469 case 'FR':
470 commandCode = SPEAK_FACE_RIGHT;
471 break;
472 case 'GD':
473 _vm->logic()->joeGrab(STATE_GRAB_DOWN);
474 commandCode = SPEAK_NONE;
475 break;
476 case 'GM':
477 _vm->logic()->joeGrab(STATE_GRAB_MID);
478 commandCode = SPEAK_NONE;
479 break;
480 case 'WT':
481 commandCode = SPEAK_PAUSE;
482 break;
483 case 'XY':
484 // For example *XY00(237,112)
485 {
486 commandCode = atoi(sentence + index + 2);
487 int x = atoi(sentence + index + 5);
488 int y = atoi(sentence + index + 9);
489 if (0 == strcmp(person->name, "JOE"))
490 _vm->walk()->moveJoe(0, x, y, _vm->input()->cutawayRunning());
491 else
492 _vm->walk()->movePerson(person, x, y, _vm->graphics()->numFrames(), 0);
493 index += 11;
494 // if (JOEWALK==3) CUTQUIT=0;
495 // XXX personWalking = true;
496 }
497 break;
498 default:
499 if (sentence[index + 0] >= '0' && sentence[index + 0] <= '9' &&
500 sentence[index + 1] >= '0' && sentence[index + 1] <= '9') {
501 commandCode = (sentence[index] - '0') * 10 + (sentence[index + 1] - '0');
502 } else
503 warning("Unknown command string: '%2s'", sentence + index);
504 }
505
506 index += 2;
507
508 return commandCode;
509 }
510
511
speak(const char * sentence,Person * person,const char * voiceFilePrefix)512 bool Talk::speak(const char *sentence, Person *person, const char *voiceFilePrefix) {
513 // Function SPEAK, lines 1266-1384 in talk.c
514 bool personWalking = false;
515 unsigned segmentIndex = 0;
516 unsigned segmentStart = 0;
517 unsigned i;
518
519 Person joe_person;
520 ActorData joe_actor;
521
522 _vm->logic()->joeWalk(JWM_SPEAK);
523
524 if (!person) {
525 // Fill in values for use by speakSegment() etc.
526 memset(&joe_person, 0, sizeof(Person));
527 memset(&joe_actor, 0, sizeof(ActorData));
528
529 joe_actor.bobNum = 0;
530 joe_actor.color = 14;
531 joe_actor.bankNum = 7;
532
533 joe_person.actor = &joe_actor;
534 joe_person.name = "JOE";
535
536 person = &joe_person;
537 }
538
539 debug(6, "Sentence '%s' is said by person '%s' and voice files with prefix '%s' played",
540 sentence, person->name, voiceFilePrefix);
541
542 if (sentence[0] == '\0') {
543 return personWalking;
544 }
545
546 if (0 == strcmp(person->name, "FAYE-H") ||
547 0 == strcmp(person->name, "FRANK-H") ||
548 0 == strcmp(person->name, "AZURA-H") ||
549 0 == strcmp(person->name, "X3_RITA") ||
550 (0 == strcmp(person->name, "JOE") && _vm->logic()->currentRoom() == FAYE_HEAD) ||
551 (0 == strcmp(person->name, "JOE") && _vm->logic()->currentRoom() == AZURA_HEAD) ||
552 (0 == strcmp(person->name, "JOE") && _vm->logic()->currentRoom() == FRANK_HEAD))
553 _talkHead = true;
554 else
555 _talkHead = false;
556
557 for (i = 0; i < strlen(sentence); ) {
558 if (sentence[i] == '*') {
559 int segmentLength = i - segmentStart;
560
561 i++;
562 int command = getSpeakCommand(person, sentence, i);
563
564 if (SPEAK_NONE != command) {
565 speakSegment(
566 sentence + segmentStart,
567 segmentLength,
568 person,
569 command,
570 voiceFilePrefix,
571 segmentIndex);
572 // XXX if (JOEWALK == 2) break
573 }
574
575 segmentIndex++;
576 segmentStart = i;
577 } else
578 i++;
579
580 if (_vm->input()->cutawayQuit() || _vm->input()->talkQuit())
581 return personWalking;
582 }
583
584 if (segmentStart != i) {
585 speakSegment(
586 sentence + segmentStart,
587 i - segmentStart,
588 person,
589 0,
590 voiceFilePrefix,
591 segmentIndex);
592 }
593
594 return personWalking;
595 }
596
countSpaces(const char * segment)597 int Talk::countSpaces(const char *segment) {
598 int tmp = 0;
599
600 while (*segment++)
601 tmp++;
602
603 if (tmp < 10)
604 tmp = 10;
605
606 return (tmp * 2) / (_vm->talkSpeed() / 3);
607 }
608
headStringAnimation(const SpeechParameters * parameters,int bobNum,int bankNum)609 void Talk::headStringAnimation(const SpeechParameters *parameters, int bobNum, int bankNum) {
610 // talk.c lines 1612-1635
611 BobSlot *bob2 = _vm->graphics()->bob(2);
612
613 if (parameters->animation[0] == 'E') {
614 int offset = 1;
615
616 BobSlot *bob = _vm->graphics()->bob(bobNum);
617 int16 x = bob->x;
618 int16 y = bob->y;
619
620 for (;;) {
621 uint16 frame;
622
623 frame = atoi(parameters->animation + offset);
624 if (!frame)
625 break;
626
627 offset += 4;
628
629 _vm->bankMan()->unpack(frame, _vm->graphics()->numFrames(), bankNum);
630
631 bob2->frameNum = _vm->graphics()->numFrames();
632 bob2->scale = 100;
633 bob2->active = true;
634 bob2->x = x;
635 bob2->y = y;
636
637 _vm->update();
638 }
639 } else
640 bob2->active = false;
641 }
642
stringAnimation(const SpeechParameters * parameters,int startFrame,int bankNum)643 void Talk::stringAnimation(const SpeechParameters *parameters, int startFrame, int bankNum) {
644 // lines 1639-1690 in talk.c
645
646 int offset = 0;
647 bool torso;
648
649 if (parameters->animation[0] == 'T') {
650 // Torso animation
651 torso = true;
652 _vm->bankMan()->overpack(parameters->body, startFrame, bankNum);
653 offset++;
654 } else if (parameters->animation[0] == 'E') {
655 // Talking head animation
656 return;
657 } else if (!Common::isDigit(parameters->animation[0])) {
658 debug(6, "Error in speak string animation: '%s'", parameters->animation);
659 return;
660 } else
661 torso = false;
662
663 for (;;) {
664 uint16 frame;
665
666 frame = atoi(parameters->animation + offset);
667 if (!frame)
668 break;
669
670 offset += 4;
671
672 if (frame > 500) {
673 frame -= 500;
674 _vm->sound()->playSfx(_vm->logic()->currentRoomSfx());
675 }
676
677 if (torso) {
678 _vm->bankMan()->overpack(frame, startFrame, bankNum);
679 } else {
680 _vm->bankMan()->unpack(frame, startFrame, bankNum);
681 // XXX bobs[BNUM].scale=SF;
682 }
683
684 _vm->update();
685 }
686 }
687
defaultAnimation(const char * segment,bool isJoe,const SpeechParameters * parameters,int startFrame,int bankNum)688 void Talk::defaultAnimation(
689 const char *segment,
690 bool isJoe,
691 const SpeechParameters *parameters,
692 int startFrame,
693 int bankNum) {
694 // lines 1730-1823 in talk.c
695
696 if (segment[0] != 0) {
697
698 // Why on earth would someone name a variable qzx?
699 short qzx = 0;
700
701 int len = countSpaces(segment);
702 while (1) {
703 if (parameters != NULL) {
704
705 int bf;
706 if (segment[0] == ' ')
707 bf = 0;
708 else
709 bf = parameters->bf;
710
711 int head;
712 if (parameters->rf > 0)
713 head = bf + _vm->randomizer.getRandomNumber(parameters->rf);
714 else
715 head = bf;
716
717 if (bf > 0) {
718 // Make the head move
719 qzx ^= 1;
720 if (parameters->af && qzx)
721 _vm->bankMan()->overpack(parameters->af + head, startFrame, bankNum);
722 else {
723 _vm->bankMan()->overpack(head, startFrame, bankNum);
724 }
725 } else {
726 debug(6, "[Talk::defaultAnimation] Body action");
727 // Just do a body action
728 _vm->bankMan()->overpack(parameters->body, startFrame, bankNum);
729 }
730
731 if (!_talkHead)
732 _vm->update();
733 } else { // (_talkHead && isJoe)
734 _vm->update();
735 }
736
737 if (_vm->input()->talkQuit()) {
738 _vm->sound()->stopSpeech();
739 break;
740 }
741
742 if (_vm->logic()->joeWalk() == JWM_SPEAK) {
743 _vm->update();
744 } else {
745 _vm->update(true);
746 if (_vm->logic()->joeWalk() == JWM_EXECUTE)
747 // Selected a command, so exit
748 break;
749 }
750
751 // Skip through text more quickly
752 if (_vm->input()->keyVerb() == VERB_SKIP_TEXT) {
753 _vm->input()->clearKeyVerb();
754 _vm->sound()->stopSpeech();
755 break;
756 }
757
758 if (_vm->sound()->speechOn() && _vm->sound()->speechSfxExists()) {
759 // sfx is finished, stop the speak animation
760 if (!_vm->sound()->isSpeechActive()) {
761 break;
762 }
763 } else {
764 // no sfx, stop the animation when speak segment 'length' is 0
765 --len;
766 if (len <= 0) {
767 break;
768 }
769 }
770 }
771 }
772
773 // Make sure that Person closes their mouth
774 if (!isJoe && parameters && parameters->ff > 0)
775 _vm->bankMan()->overpack(parameters->ff, startFrame, bankNum);
776 }
777
778
speakSegment(const char * segmentStart,int length,Person * person,int command,const char * voiceFilePrefix,int index)779 void Talk::speakSegment(
780 const char *segmentStart,
781 int length,
782 Person *person,
783 int command,
784 const char *voiceFilePrefix,
785 int index)
786 {
787 int i;
788 char segment[MAX_STRING_SIZE];
789 memcpy(segment, segmentStart, length);
790 segment[length] = '\0';
791
792 char voiceFileName[MAX_STRING_SIZE];
793 sprintf(voiceFileName, "%s%1x", voiceFilePrefix, index + 1);
794
795 // French talkie version has a useless voice file ; c30e_102 file is the same as c30e_101,
796 // so there is no need to play it. This voice was used in room 30 (N8) when talking to Klunk.
797 if (!(_vm->resource()->getLanguage() == Common::FR_FRA && !strcmp(voiceFileName, "c30e_102")))
798 _vm->sound()->playSpeech(voiceFileName);
799
800 int faceDirectionCommand = 0;
801
802 switch (command) {
803 case SPEAK_PAUSE:
804 for (i = 0; i < 10 && !_vm->input()->talkQuit() && !_vm->shouldQuit(); i++) {
805 _vm->update();
806 }
807 return;
808
809 case SPEAK_FACE_LEFT:
810 case SPEAK_FACE_RIGHT:
811 case SPEAK_FACE_FRONT:
812 case SPEAK_FACE_BACK:
813 faceDirectionCommand = command;
814 command = 0;
815 break;
816 }
817
818 bool isJoe = (0 == person->actor->bobNum);
819
820 int16 bobNum = person->actor->bobNum;
821 uint16 color = person->actor->color;
822 uint16 bankNum = person->actor->bankNum;
823
824 BobSlot *bob = _vm->graphics()->bob(bobNum);
825
826 bool oracle = false;
827 int textX = 0;
828 int textY = 0;
829
830 if (!isJoe) {
831 if (SPEAK_AMAL_ON == command) {
832 // It's the oracle!
833 // Don't turn AMAL animation off, and don't manually anim person
834 command = SPEAK_ORACLE;
835 oracle = true;
836 uint16 frameNum = _vm->graphics()->personFrames(bobNum);
837 for (i = 5; i <= 8; ++i) {
838 _vm->bankMan()->unpack(i, frameNum, bankNum);
839 ++frameNum;
840 }
841 } else {
842 bob->animating = false;
843 bob->frameNum = 31 + bobNum;
844 }
845 }
846
847 if (_talkHead) {
848 // talk.c lines 1491-1533
849 switch (_vm->logic()->currentRoom()) {
850 case FAYE_HEAD:
851 textX = 15;
852 if (_vm->resource()->getPlatform() == Common::kPlatformAmiga) {
853 color = isJoe ? 15 : 29;
854 }
855 break;
856 case AZURA_HEAD:
857 textX = 15;
858 if (_vm->resource()->getPlatform() == Common::kPlatformAmiga) {
859 color = isJoe ? 6 : 30;
860 }
861 break;
862 default: // FRANK_HEAD
863 textX = 150;
864 if (_vm->resource()->getPlatform() == Common::kPlatformAmiga) {
865 color = 17;
866 }
867 break;
868 }
869 textY = isJoe ? 30 : 60;
870 } else {
871 textX = bob->x;
872 textY = bob->y;
873 }
874
875 // Set the focus rectangle
876 // FIXME: This may not be correct!
877 BobFrame *pbf = _vm->bankMan()->fetchFrame(bob->frameNum);
878
879 int height = (pbf->height * bob->scale) / 100;
880
881 Common::Rect focus(textX - 96, textY - height - 64, textX + 96, textY + height + 64);
882 _vm->display()->setFocusRect(focus);
883
884
885 //int SF = _vm->grid()->findScale(textX, textY);
886
887 const SpeechParameters *parameters = NULL;
888 int startFrame = 0;
889
890 if (_talkHead && isJoe) {
891 if (_vm->subtitles())
892 _vm->graphics()->setBobText(bob, segment, textX, textY, color, true);
893 defaultAnimation(segment, isJoe, parameters, startFrame, bankNum);
894 } else {
895 if (SPEAK_UNKNOWN_6 == command)
896 return;
897
898 if (isJoe) {
899 if (_vm->logic()->currentRoom() == 108)
900 parameters = findSpeechParameters("JOE-E", command, 0);
901 else
902 parameters = findSpeechParameters("JOE", command, _vm->logic()->joeFacing());
903 }
904 else
905 parameters = findSpeechParameters(person->name, command, 0);
906
907 startFrame = 31 + bobNum;
908 int faceDirection = 0;
909
910 if (isJoe && _vm->logic()->joeFacing() == DIR_LEFT)
911 faceDirection = DIR_LEFT;
912 else if (!isJoe) {
913 ObjectData *data = _vm->logic()->objectData(_vm->logic()->objectForPerson(bobNum));
914
915 if (data->image == -3)
916 faceDirection = DIR_LEFT;
917
918 if (faceDirectionCommand == SPEAK_FACE_LEFT)
919 data->image = -3;
920 else if (faceDirectionCommand == SPEAK_FACE_RIGHT)
921 data->image = -4;
922 }
923
924 if (faceDirectionCommand) {
925 switch (faceDirectionCommand) {
926 case SPEAK_FACE_LEFT:
927 faceDirection = DIR_LEFT;
928 break;
929 case SPEAK_FACE_RIGHT:
930 faceDirection = DIR_RIGHT;
931 break;
932 case SPEAK_FACE_FRONT:
933 faceDirection = DIR_FRONT;
934 break;
935 case SPEAK_FACE_BACK:
936 faceDirection = DIR_BACK;
937 break;
938 }
939 if (isJoe)
940 _vm->logic()->joeFacing(faceDirection);
941 }
942
943 if (!isJoe) {
944 bob->xflip = (faceDirection == DIR_LEFT);
945 }
946
947 // Run animated sequence if SANIMstr is primed
948
949 if (_talkHead) {
950 // talk.c lines 1612-1635
951 headStringAnimation(parameters, bobNum, bankNum);
952 }
953
954 if (_vm->subtitles())
955 _vm->graphics()->setBobText(bob, segment, textX, textY, color, _talkHead);
956
957 if (parameters->animation[0] != '\0' && parameters->animation[0] != 'E') {
958 stringAnimation(parameters, startFrame, bankNum);
959 } else {
960 _vm->bankMan()->unpack(parameters->body, startFrame, bankNum);
961
962 if (length == 0 && !isJoe && parameters->bf > 0) {
963 _vm->bankMan()->overpack(parameters->bf, startFrame, bankNum);
964 _vm->update();
965 }
966
967 if (-1 == parameters->rf) {
968 // Setup the Torso frames
969 _vm->bankMan()->overpack(parameters->bf, startFrame, bankNum);
970 if (isJoe)
971 parameters = findSpeechParameters(person->name, 0, _vm->logic()->joeFacing());
972 else
973 parameters = findSpeechParameters(person->name, 0, 0);
974 }
975
976 if (-2 == parameters->rf) {
977 // Setup the Torso frames
978 _vm->bankMan()->overpack(parameters->bf, startFrame, bankNum);
979 if (isJoe)
980 parameters = findSpeechParameters(person->name, 14, _vm->logic()->joeFacing());
981 else
982 parameters = findSpeechParameters(person->name, 14, 0);
983 }
984
985 defaultAnimation(segment, isJoe, parameters, startFrame, bankNum);
986 }
987 }
988
989 // Moved here so that Text is cleared when a Torso command done!
990 _vm->display()->clearTexts(0,198);
991
992 if (oracle) {
993 uint16 frameNum = _vm->graphics()->personFrames(bobNum);
994 for (i = 1; i <= 4; ++i) {
995 _vm->bankMan()->unpack(i, frameNum, bankNum);
996 ++frameNum;
997 }
998 }
999
1000 // Ensure that the correct buffer frame is selected
1001
1002 if (isJoe && !_talkHead) {
1003 if (_vm->logic()->joeFacing() == DIR_FRONT ||
1004 _vm->logic()->joeFacing() == DIR_BACK) {
1005 // Joe is facing either Front or Back!
1006 // - Don't FACE_JOE in room 69, because Joe is probably
1007 // holding the Dino Ray gun.
1008 if (_vm->logic()->currentRoom() != 69)
1009 _vm->logic()->joeFace();
1010 } else {
1011 if (command == SPEAK_DEFAULT ||
1012 command == 6 ||
1013 command == 7) {
1014 _vm->logic()->joeFace();
1015 } else if (command != 5) {
1016 // 7/11/94, Ensure that correct mouth closed frame is used!
1017 if (parameters->rf != -1)
1018 // XXX should really be just "bf", but it is not always calculated... :-(
1019 _vm->bankMan()->overpack(parameters->bf, startFrame, bankNum);
1020
1021 if (parameters->ff == 0)
1022 _vm->bankMan()->overpack(10, startFrame, bankNum);
1023 else
1024 _vm->bankMan()->overpack(parameters->ff, startFrame, bankNum);
1025 }
1026 }
1027 }
1028
1029 _vm->update();
1030 }
1031
findSpeechParameters(const char * name,int state,int faceDirection)1032 const Talk::SpeechParameters *Talk::findSpeechParameters(
1033 const char *name,
1034 int state,
1035 int faceDirection) {
1036 const SpeechParameters *iterator = _speechParameters;
1037 if (faceDirection == DIR_RIGHT)
1038 faceDirection = DIR_LEFT;
1039 while (iterator->name[0] != '*') {
1040 if (0 == scumm_stricmp(iterator->name, name) &&
1041 iterator->state == state &&
1042 iterator->faceDirection == faceDirection)
1043 break;
1044 iterator++;
1045 }
1046 return iterator;
1047 }
1048
getString(const byte * ptr,uint16 & offset,char * str,int maxLength,int align)1049 void Talk::getString(const byte *ptr, uint16 &offset, char *str, int maxLength, int align) {
1050 assert((align & 1) == 0);
1051 int length = *(ptr + offset);
1052 ++offset;
1053
1054 if (length > maxLength) {
1055 error("String too long. Length = %i, maxLength = %i", length, maxLength);
1056 } else if (length) {
1057 if (str) {
1058 memcpy(str, ptr + offset, length);
1059 str[length] = '\0';
1060 }
1061 offset = (offset + length + (align - 1)) & ~(align - 1);
1062 } else {
1063 if (str) {
1064 str[0] = '\0';
1065 }
1066 }
1067 }
1068
talkSelected()1069 TalkSelected *Talk::talkSelected() {
1070 return _vm->logic()->talkSelected(_uniqueKey);
1071 }
1072
splitOption(const char * str,char optionText[5][MAX_STRING_SIZE])1073 int Talk::splitOption(const char *str, char optionText[5][MAX_STRING_SIZE]) {
1074 char option[MAX_STRING_SIZE];
1075 strcpy(option, str);
1076 // option text ends at '*' char
1077 char *p = strchr(option, '*');
1078 if (p) {
1079 *p = '\0';
1080 }
1081 int lines;
1082 memset(optionText, 0, 5 * MAX_STRING_SIZE);
1083 if (_vm->resource()->getLanguage() == Common::EN_ANY || _vm->display()->textWidth(option) <= MAX_TEXT_WIDTH) {
1084 strcpy(optionText[0], option);
1085 lines = 1;
1086 } else if (_vm->resource()->getLanguage() == Common::HE_ISR) {
1087 lines = splitOptionHebrew(option, optionText);
1088 } else {
1089 lines = splitOptionDefault(option, optionText);
1090 }
1091 return lines;
1092 }
1093
splitOptionHebrew(const char * str,char optionText[5][MAX_STRING_SIZE])1094 int Talk::splitOptionHebrew(const char *str, char optionText[5][MAX_STRING_SIZE]) {
1095 char tmpString[MAX_STRING_SIZE] = "";
1096 uint16 len = 0;
1097 uint16 spaceCharWidth = _vm->display()->textWidth(" ");
1098 uint16 width = 0;
1099 uint16 optionLines = 0;
1100 uint16 maxTextLen = MAX_TEXT_WIDTH;
1101 const char *p = strchr(str, '\0');
1102 while (p != str - 1) {
1103 while (*p != ' ' && p != str - 1) {
1104 --p;
1105 ++len;
1106 }
1107 if (p != str - 1) {
1108 uint16 wordWidth = _vm->display()->textWidth(p, len);
1109 width += wordWidth;
1110 if (width > maxTextLen) {
1111 ++optionLines;
1112 strncpy(optionText[optionLines], p, len);
1113 optionText[optionLines][len] = '\0';
1114 width = wordWidth;
1115 maxTextLen = MAX_TEXT_WIDTH - OPTION_TEXT_MARGIN;
1116 } else {
1117 strcpy(tmpString, optionText[optionLines]);
1118 strncpy(optionText[optionLines], p, len);
1119 optionText[optionLines][len] = '\0';
1120 strcat(optionText[optionLines], tmpString);
1121 }
1122 --p;
1123 len = 1;
1124 width += spaceCharWidth;
1125 } else {
1126 if (len > 1) {
1127 if (width + _vm->display()->textWidth(p + 1, len) > maxTextLen) {
1128 ++optionLines;
1129 }
1130 strcpy(tmpString, optionText[optionLines]);
1131 strncpy(optionText[optionLines], p + 1, len);
1132 optionText[optionLines][len] = '\0';
1133 strcat(optionText[optionLines], tmpString);
1134 }
1135 ++optionLines;
1136 }
1137 }
1138 return optionLines;
1139 }
1140
splitOptionDefault(const char * str,char optionText[5][MAX_STRING_SIZE])1141 int Talk::splitOptionDefault(const char *str, char optionText[5][MAX_STRING_SIZE]) {
1142 // Split up multiple line option at closest space character
1143 uint16 spaceCharWidth = _vm->display()->textWidth(" ");
1144 uint16 width = 0;
1145 uint16 optionLines = 0;
1146 uint16 maxTextLen = MAX_TEXT_WIDTH;
1147 const char *p = str;
1148 while (p) {
1149 p = strchr(str, ' ');
1150 if (p) {
1151 uint16 len = p - str;
1152 uint16 wordWidth = _vm->display()->textWidth(str, len);
1153 width += wordWidth;
1154 if (width > maxTextLen) {
1155 ++optionLines;
1156 strncpy(optionText[optionLines], str, len + 1);
1157 width = wordWidth;
1158 maxTextLen = MAX_TEXT_WIDTH - OPTION_TEXT_MARGIN;
1159 } else {
1160 strncat(optionText[optionLines], str, len + 1);
1161 }
1162 width += spaceCharWidth;
1163 str = p + 1;
1164 } else {
1165 if (str[0]) {
1166 if (width + _vm->display()->textWidth(str) > maxTextLen) {
1167 ++optionLines;
1168 }
1169 strcat(optionText[optionLines], str);
1170 }
1171 ++optionLines;
1172 }
1173 }
1174 return optionLines;
1175 }
1176
selectSentence()1177 int16 Talk::selectSentence() {
1178 int selectedSentence = 0;
1179
1180 int startOption = 1;
1181 int optionLines = 0;
1182 char optionText[5][MAX_STRING_SIZE];
1183 int talkZone[5];
1184 int i;
1185
1186 _vm->display()->textCurrentColor(_vm->display()->getInkColor(INK_TALK_NORMAL));
1187
1188 _vm->graphics()->setupArrows();
1189 BobSlot *arrowBobUp = _vm->graphics()->bob(Graphics::ARROW_BOB_UP);
1190 arrowBobUp->active = false;
1191 BobSlot *arrowBobDown = _vm->graphics()->bob(Graphics::ARROW_BOB_DOWN);
1192 arrowBobDown->active = false;
1193
1194 bool rezone = true;
1195
1196 while (rezone) {
1197 rezone = false;
1198
1199 // Set zones for UP/DOWN text arrows when not English version
1200
1201 _vm->grid()->clear(GS_PANEL);
1202
1203 if (_vm->resource()->getLanguage() != Common::EN_ANY) {
1204 _vm->grid()->setZone(GS_PANEL, ARROW_ZONE_UP, MAX_TEXT_WIDTH + 1, 0, 319, 24);
1205 _vm->grid()->setZone(GS_PANEL, ARROW_ZONE_DOWN, MAX_TEXT_WIDTH + 1, 25, 319, 49);
1206 }
1207
1208 _vm->display()->clearTexts(151, 199);
1209
1210 int sentenceCount = 0;
1211 int yOffset = 1;
1212
1213 for (i = startOption; i <= 4; i++) {
1214 talkZone[i] = 0;
1215
1216 if (_talkString[i][0] != '\0') {
1217 sentenceCount++;
1218 optionLines = splitOption(_talkString[i], optionText);
1219
1220 if (yOffset < 5) {
1221 _vm->grid()->setZone(
1222 GS_PANEL,
1223 i,
1224 0,
1225 yOffset * LINE_HEIGHT - PUSHUP,
1226 (_vm->resource()->getLanguage() == Common::EN_ANY) ? 319 : MAX_TEXT_WIDTH,
1227 (yOffset + optionLines) * LINE_HEIGHT - PUSHUP);
1228 }
1229
1230 int j;
1231 for (j = 0; j < optionLines; j++) {
1232 if (yOffset < 5) {
1233 _vm->display()->setText(
1234 (j == 0) ? 0 : OPTION_TEXT_MARGIN,
1235 150 - PUSHUP + yOffset * LINE_HEIGHT,
1236 optionText[j]);
1237 }
1238 yOffset++;
1239 }
1240
1241 talkZone[i] = sentenceCount;
1242 }
1243 }
1244
1245 yOffset--;
1246
1247 // Up and down dialogue arrows
1248
1249 if (_vm->resource()->getLanguage() != Common::EN_ANY) {
1250 arrowBobUp->active = (startOption > 1);
1251 arrowBobDown->active = (yOffset > 4);
1252 }
1253
1254 _vm->input()->clearKeyVerb();
1255 _vm->input()->clearMouseButton();
1256
1257 if (sentenceCount > 0) {
1258 int oldZone = 0;
1259
1260 while (0 == selectedSentence && !_vm->input()->talkQuit() && !_vm->shouldQuit()) {
1261 _vm->update();
1262
1263 Common::Point mouse = _vm->input()->getMousePos();
1264 int zone = _vm->grid()->findZoneForPos(GS_PANEL, mouse.x, mouse.y);
1265
1266 int mouseButton = _vm->input()->mouseButton();
1267 _vm->input()->clearMouseButton();
1268
1269 if (ARROW_ZONE_UP == zone || ARROW_ZONE_DOWN == zone) {
1270 if (oldZone > 0) {
1271 int16 y;
1272 const Box *b = _vm->grid()->zone(GS_PANEL, oldZone);
1273 for (y = b->y1; y < b->y2; y += 10)
1274 _vm->display()->textColor(150 + y, _vm->display()->getInkColor(INK_TALK_NORMAL));
1275 oldZone = 0;
1276 }
1277 if (mouseButton != 0) {
1278 if (zone == ARROW_ZONE_UP && arrowBobUp->active) {
1279 startOption--;
1280 } else if (zone == ARROW_ZONE_DOWN && arrowBobDown->active) {
1281 startOption++;
1282 }
1283 }
1284 rezone = true;
1285 break;
1286 } else {
1287 if (oldZone != zone) {
1288 // Changed zone, change text colors
1289 int y;
1290
1291 debug(6, "Changed zone. oldZone = %i, zone = %i",
1292 oldZone, zone);
1293
1294 if (zone > 0) {
1295 const Box *b = _vm->grid()->zone(GS_PANEL, zone);
1296 for (y = b->y1; y < b->y2; y += 10)
1297 _vm->display()->textColor(150 + y, _vm->display()->getInkColor(INK_JOE));
1298 }
1299
1300 if (oldZone > 0) {
1301 const Box *b = _vm->grid()->zone(GS_PANEL, oldZone);
1302 for (y = b->y1; y < b->y2; y += 10)
1303 _vm->display()->textColor(150 + y, _vm->display()->getInkColor(INK_TALK_NORMAL));
1304 }
1305
1306 oldZone = zone;
1307 }
1308
1309 }
1310
1311 Verb v = _vm->input()->keyVerb();
1312 if (v >= VERB_DIGIT_FIRST && v <= VERB_DIGIT_LAST) {
1313 int n = v - VERB_DIGIT_FIRST + 1;
1314 for (i = 1; i <= 4; i++) {
1315 if (talkZone[i] == n) {
1316 selectedSentence = i;
1317 break;
1318 }
1319 }
1320
1321 _vm->input()->clearKeyVerb();
1322 } else if (mouseButton) {
1323 selectedSentence = zone;
1324 }
1325
1326 } // while ()
1327 }
1328 }
1329
1330 _vm->input()->clearKeyVerb();
1331 _vm->input()->clearMouseButton();
1332
1333 debug(6, "Selected sentence %i", selectedSentence);
1334
1335 arrowBobUp->active = false;
1336 arrowBobDown->active = false;
1337
1338 if (selectedSentence > 0) {
1339 _vm->display()->clearTexts(0, 198);
1340
1341 speak(_talkString[selectedSentence], NULL, _joeVoiceFilePrefix[selectedSentence]);
1342 }
1343
1344 _vm->display()->clearTexts(151, 151);
1345
1346 return selectedSentence;
1347 }
1348
1349 const Talk::SpeechParameters Talk::_speechParameters[] = {
1350 { "JOE", 0, 1, 1, 10, 2, 3, "", 0 },
1351 { "JOE", 0, 3, 3, 28, 2, 3, "", 0 },
1352 { "JOE", 0, 4, 5, 38, 1, 0, "", 0 },
1353
1354 { "JOE", 1, 1, 1, 45, -1, 0, "", 0 },
1355 { "JOE", 1, 3, 3, 28, 2, 3, "", 0 },
1356 { "JOE", 1, 4, 5, 38, 1, 0, "", 0 },
1357
1358 { "JOE", 2, 1, 1, 46, -1, 0, "", 0 },
1359 { "JOE", 2, 3, 3, 28, 2, 3, "", 0 },
1360 { "JOE", 2, 4, 5, 38, 1, 0, "", 0 },
1361
1362 { "JOE", 3, 1, 1, 47, -1, 0, "", 0 },
1363 { "JOE", 3, 3, 3, 28, 2, 3, "", 0 },
1364 { "JOE", 3, 4, 5, 38, 1, 0, "", 0 },
1365
1366 { "JOE", 4, 1, 1, 50, -1, 0, "", 0 },
1367 { "JOE", 4, 3, 3, 28, 2, 3, "", 0 },
1368 { "JOE", 4, 4, 5, 38, 1, 0, "", 0 },
1369
1370 { "JOE", 5, 1, 2, 0, 0, 0, "", 0 },
1371 { "JOE", 5, 3, 4, 0, 0, 0, "", 0 },
1372 { "JOE", 5, 4, 6, 0, 0, 0, "", 0 },
1373
1374 { "JOE", 6, 1, 1, 48, 0, 1, "", 0 },
1375 { "JOE", 6, 3, 3, 28, 2, 3, "", 0 },
1376 { "JOE", 6, 4, 5, 38, 1, 0, "", 0 },
1377
1378 { "JOE", 7, 1, 1, 51, 0, 1, "", 0 },
1379 { "JOE", 7, 3, 3, 28, 2, 3, "", 0 },
1380 { "JOE", 7, 4, 5, 38, 1, 0, "", 0 },
1381
1382 { "JOE", 8, 1, 1, 26, 0, 0, "", 0 },
1383 { "JOE", 8, 3, 3, 28, 2, 3, "", 0 },
1384 { "JOE", 8, 4, 5, 38, 1, 0, "", 0 },
1385
1386 { "JOE", 9, 1, 1, 29, 0, 0, "", 0 },
1387 { "JOE", 9, 3, 3, 28, 0, 0, "", 0 },
1388 { "JOE", 9, 4, 5, 38, 0, 0, "", 0 },
1389
1390 { "JOE", 10, 1, 1, 12, 0, 0, "T046,010,010,010,012,012,012,012,012,012,012,012,012,012,012,012,012,012,010,000", 0 },
1391 { "JOE", 10, 3, 3, 18, 0, 0, "", 0 },
1392 { "JOE", 10, 4, 5, 44, 0, 0, "", 0 },
1393
1394 { "JOE", 11, 1, 1, 53, -1, 0, "", 0 },
1395 { "JOE", 11, 3, 3, 28, 2, 3, "", 0 },
1396 { "JOE", 11, 4, 5, 38, 1, 0, "", 0 },
1397
1398 { "JOE", 12, 1, 1, 10, 2, 3, "", 0 },
1399 { "JOE", 12, 3, 3, 28, 2, 0, "", 0 },
1400 { "JOE", 12, 4, 5, 38, 1, 0, "", 0 },
1401
1402 { "JOE", 13, 1, 1, 10, 2, 3, "T012,013,019,019,019,019,019,019,019,019,019,019,013,010,000", 0 },
1403 { "JOE", 13, 3, 3, 28, 2, 3, "", 0 },
1404 { "JOE", 13, 4, 5, 38, 1, 0, "", 0 },
1405
1406 { "JOE", 14, 1, 1, 16, 2, 3, "", 16 },
1407 { "JOE", 14, 3, 3, 28, 2, 3, "", 0 },
1408 { "JOE", 14, 4, 5, 38, 1, 0, "", 0 },
1409
1410 { "JOE", 15, 1, 1, 58, -1, 0, "", 0 },
1411 { "JOE", 15, 3, 3, 28, 2, 3, "", 0 },
1412 { "JOE", 15, 4, 5, 38, 1, 0, "", 0 },
1413
1414 { "JOE", 16, 1, 1, 59, -1, 0, "", 0 },
1415 { "JOE", 16, 3, 3, 28, 2, 3, "", 0 },
1416 { "JOE", 16, 4, 5, 38, 1, 0, "", 0 },
1417
1418 { "JOE", 17, 1, 1, 56, -1, 0, "", 0 },
1419 { "JOE", 17, 3, 3, 28, 2, 3, "", 0 },
1420 { "JOE", 17, 4, 5, 38, 1, 0, "", 0 },
1421
1422 { "JOE", 18, 1, 56, 16, 2, 3, "T056,057,057,057,056,056,000", 0 },
1423 { "JOE", 18, 3, 3, 28, 2, 3, "", 0 },
1424 { "JOE", 18, 4, 5, 38, 1, 0, "", 0 },
1425
1426 { "JOE", 19, 1, 54, 16, 2, 3, "T054,055,057,056,000", 0 },
1427 { "JOE", 19, 3, 3, 28, 2, 3, "", 0 },
1428 { "JOE", 19, 4, 5, 38, 1, 0, "", 0 },
1429
1430 { "JOE", 20, 1, 56, 16, 2, 3, "T056,057,055,054,001,000", 0 },
1431 { "JOE", 20, 3, 3, 28, 2, 3, "", 0 },
1432 { "JOE", 20, 4, 5, 38, 1, 0, "", 0 },
1433
1434 { "JOE", 21, 1, 1, 60, -1, 0, "", 0 },
1435 { "JOE", 21, 3, 3, 28, 2, 3, "", 0 },
1436 { "JOE", 21, 4, 61, 38, 1, 0, "", 0 },
1437
1438 { "JOE", 22, 1, 1, 16, 2, 3, "T063,060,000", 0 },
1439 { "JOE", 22, 3, 3, 28, 2, 3, "", 0 },
1440 { "JOE", 22, 4, 5, 38, 1, 0, "", 0 },
1441
1442 { "JOE", 23, 1, 1, 16, 2, 3, "T060,063,001,000", 0 },
1443 { "JOE", 23, 3, 3, 28, 2, 3, "", 0 },
1444 { "JOE", 23, 4, 5, 38, 1, 0, "", 0 },
1445
1446 { "JOE", 24, 1, 1, 47, -2, 0, "", 0 },
1447 { "JOE", 24, 3, 3, 28, 2, 3, "", 0 },
1448 { "JOE", 24, 4, 5, 38, 1, 0, "", 0 },
1449
1450 { "RICO", 0, 0, 1, 7, 1, 3, "", 7 },
1451 { "RICO", 1, 0, 1, 5, -1, 0, "", 7 },
1452 { "RICO", 2, 0, 1, 9, 0, 3, "", 7 },
1453 { "RICO", 3, 0, 1, 4, -1, 0, "", 7 },
1454
1455 { "EDDY", 0, 0, 14, 18, 1, 3, "", 18 },
1456 { "EDDY", 1, 0, 14, 0, 0, 0, "T016,017,017,016,016,017,017,016,016,017,017,000", 18 },
1457
1458 { "MIKE", 0, 0, 1, 2, 2, 3, "", 2 },
1459
1460 { "LOLA", 0, 0, 30, 33, 2, 3, "", 33 },
1461 { "LOLA", 1, 0, 9, 10, 2, 3, "", 33 },
1462 { "LOLA", 2, 0, 30, 33, 2, 3, "", 33 },
1463 { "LOLA", 3, 0, 32, 33, 2, 3, "", 33 },
1464 { "LOLA", 4, 0, 8, 0, 0, 0, "", 33 },
1465 { "LOLA", 5, 0, 31, 0, 0, 0, "", 0 },
1466 { "LOLA", 6, 0, 31, 0, 0, 0, "047,048,049,050,000", 33 },
1467
1468 { "LOLA_SHOWER", 0, 0, 7, 10, 2, 3, "", 10 },
1469 { "LOLA_SHOWER", 1, 0, 9, 10, 2, 3, "", 10 },
1470 { "LOLA_SHOWER", 2, 0, 30, 33, 2, 3, "", 10 },
1471 { "LOLA_SHOWER", 3, 0, 32, 33, 2, 3, "", 10 },
1472 { "LOLA_SHOWER", 4, 0, 8, 0, 0, 0, "", 0 },
1473 { "LOLA_SHOWER", 5, 0, 61, 0, 0, 0, "", 0 },
1474 { "LOLA_SHOWER", 6, 0, 64, 10, 2, 3, "", 0 },
1475 { "LOLA_SHOWER", 7, 0, 31, 0, 0, 0, "062,063,064,000", 0 },
1476
1477 { "SECRETARY", 0, 0, 1, 12, 2, 3, "", 12 },
1478 { "SECRETARY", 1, 0, 1, 12, 2, 0, "", 12 },
1479 { "SECRETARY", 2, 0, 1, 12, 2, 0, "", 12 },
1480
1481 { "SPARKY", 0, 0, 21, 23, 2, 3, "", 23 },
1482 { "SPARKY", 1, 0, 21, 22, 0, 0, "", 0 },
1483 { "SPARKY", 2, 0, 21, 22, 0, 0, "021,042,043,000", 0 },
1484 { "SPARKY", 3, 0, 21, 22, 0, 0, "043,042,021,000", 0 },
1485 { "SPARKY", 4, 0, 43, 43, 1, 0, "", 0 },
1486 { "SPARKY", 14, 0, 21, 29, 5, 0, "", 29 },
1487
1488 { "SPARKY-F", 0, 0, 45, 23, 5, 0, "", 23 },
1489 { "SPARKY-F", 1, 0, 45, 47, 0, 0, "", 0 },
1490 { "SPARKY-F", 2, 0, 45, 23, 5, 0, "045,046,046,045,000", 23 },
1491 { "SPARKY-F", 14, 0, 45, 29, 5, 0, "", 29 },
1492
1493 { "FAYE", 0, 0, 19, 35, 2, 3, "", 35 },
1494 { "FAYE", 1, 0, 19, 41, 2, 3, "", 35 },
1495 { "FAYE", 2, 0, 19, 28, -1, 0, "", 35 },
1496 { "FAYE", 3, 0, 19, 20, 0, 0, "", 0 },
1497 { "FAYE", 4, 0, 19, 27, -1, 0, "", 35 },
1498 { "FAYE", 5, 0, 19, 29, -1, 0, "", 35 },
1499 { "FAYE", 6, 0, 59, 35, 2, 3, "", 35 },
1500 { "FAYE", 7, 0, 19, 30, -1, 0, "", 35 },
1501 { "FAYE", 8, 0, 19, 31, -1, 0, "", 35 },
1502
1503 { "BOB", 0, 0, 27, 34, 2, 3, "", 34 },
1504 { "BOB", 1, 0, 27, 28, -1, 0, "", 34 },
1505 { "BOB", 2, 0, 30, 0, 0, 0, "", 0 },
1506 { "BOB", 3, 0, 31, 0, 0, 0, "", 0 },
1507 { "BOB", 4, 0, 27, 61, -1, 0, "", 34 },
1508 { "BOB", 5, 0, 27, 42, 1, 0, "", 42 },
1509
1510 { "PYGMY", 0, 0, 20, 21, 2, 6, "", 0 },
1511 { "PYGMY", 1, 0, 20, 21, 2, 6, "020,068,068,068,068,068,068,068,068,020,000", 0 },
1512 { "PYGMY", 2, 0, 20, 21, 2, 6, "T028,029,030,031,031,031,031,030,029,028,035,000", 0 },
1513 { "PYGMY", 3, 0, 20, 21, 2, 6, "T035,036,037,038,037,038,037,038,036,035,000", 0 },
1514 { "PYGMY", 4, 0, 20, 21, 2, 6, "T032,033,032,033,032,033,035,000", 0 },
1515 { "PYGMY", 5, 0, 20, 21, 2, 6, "T023,022,021,022,023,024,025,026,027,026,025,024,023,000", 0 },
1516 { "PYGMY", 6, 0, 20, 21, 2, 6, "T034,034,034,035,000", 0 },
1517
1518 { "WITCH", 0, 0, 39, 40, 2, 6, "", 40 },
1519 { "WITCH", 1, 0, 39, 40, 2, 6, "073,074,000", 40 },
1520 { "WITCH", 2, 0, 39, 40, 2, 6, "074,073,000", 40 },
1521 { "WITCH", 3, 0, 39, 40, 2, 6, "T047,048,049,050,051,000", 40 },
1522 { "WITCH", 4, 0, 39, 40, 2, 6, "T052,053,054,055,056,057,058,057,056,056,056,055,054,053,052,000", 40 },
1523 { "WITCH", 5, 0, 39, 40, 2, 6, "069,070,071,072,073,074,000", 40 },
1524 { "WITCH", 6, 0, 39, 40, 2, 6, "074,073,072,071,070,069,070,000", 40 },
1525 { "WITCH", 7, 0, 39, 51, -1, 0, "", 40 },
1526 { "WITCH", 8, 0, 39, 40, 2, 6, "T051,050,049,048,047,000", 40 },
1527
1528 { "CHIEF", 0, 0, 1, 7, 1, 7, "", 3 },
1529 { "CHIEF", 1, 0, 1, 2, 2, 6, "062,063,064,065,066,000", 0 },
1530 { "CHIEF", 2, 0, 1, 2, 2, 6, "066,065,064,063,062,000", 0 },
1531 { "CHIEF", 3, 0, 1, 17, -1, 0, "", 3 },
1532 { "CHIEF", 4, 0, 1, 18, -1, 0, "", 3 },
1533 { "CHIEF", 5, 0, 1, 19, -1, 0, "", 3 },
1534
1535 { "NAOMI", 0, 0, 1, 2, 2, 3, "", 2 },
1536 { "NAOMI", 1, 0, 1, 2, 2, 6, "048,049,050,051,052,053,054,055,000", 0 },
1537 { "NAOMI", 2, 0, 1, 2, 2, 6, "055,054,053,052,051,050,049,048,000", 0 },
1538 { "NAOMI", 3, 0, 1, 13, -1, 0, "", 2 },
1539 { "NAOMI", 4, 0, 1, 14, -1, 0, "", 2 },
1540 { "NAOMI", 5, 0, 1, 10, -1, 0, "", 2 },
1541 { "NAOMI", 6, 0, 1, 12, -1, 0, "", 2 },
1542 { "NAOMI", 7, 0, 1, 12, -1, 0, "T008,008,008,002,000", 2 },
1543
1544 { "WEDGEWOOD", 0, 0, 8, 1, 2, 0, "", 8 },
1545 { "WEDGEWOOD", 1, 0, 1, 1, 3, 0, "", 1 },
1546
1547 { "BUD", 0, 0, 1, 2, 3, 2, "", 2 },
1548 { "BUD", 1, 0, 1, 2, 4, 2, "T017,018,000", 2 },
1549 { "BUD", 2, 0, 1, 21, -1, 0, "", 2 },
1550 { "BUD", 3, 0, 1, 14, -1, 0, "", 2 },
1551 { "BUD", 4, 0, 1, 15, -1, 0, "", 2 },
1552 { "BUD", 5, 0, 1, 20, -1, 0, "", 2 },
1553 { "BUD", 6, 0, 1, 16, -1, 0, "", 2 },
1554 { "BUD", 7, 0, 1, 19, -1, 0, "", 2 },
1555 { "BUD", 8, 0, 1, 17, -1, 0, "", 2 },
1556 { "BUD", 9, 0, 1, 14, -1, 0, "T014,008,008,003,003,008,008,003,003,010,010,012,012,000", 2 },
1557
1558 { "LOU", 0, 0, 1, 2, 2, 3, "", 2 },
1559 { "LOU", 1, 0, 1, 2, 4, 2, "013,014,015,016,017,018,000", 2 },
1560 { "LOU", 2, 0, 1, 2, 4, 2, "018,017,016,015,014,013,000", 2 },
1561
1562 { "JIMMY", 0, 0, 16, 17, 2, 3, "", 17 },
1563 { "JIMMY", 1, 0, 16, 25, -1, 0, "", 17 },
1564 { "JIMMY", 2, 0, 16, 26, -1, 0, "", 17 },
1565 { "JIMMY", 3, 0, 16, 27, -1, 0, "", 17 },
1566 { "JIMMY", 4, 0, 16, 28, -1, 0, "", 17 },
1567 { "JIMMY", 5, 0, 16, 29, -1, 0, "", 17 },
1568
1569 { "TAMMY", 0, 0, 1, 2, 2, 3, "", 2 },
1570 { "TAMMY", 1, 0, 1, 2, 2, 3, "T008,008,009,009,008,008,009,009,008,008,009,009,002,000", 2 },
1571 { "TAMMY", 2, 0, 1, 2, 2, 3, "T002,010,010,010,002,000", 2 },
1572 { "TAMMY", 3, 0, 1, 2, 2, 3, "T011,011,011,011,011,002,000", 2 },
1573 { "TAMMY", 4, 0, 1, 2, 2, 3, "T013,014,015,013,014,015,013,009,001,000", 2 },
1574
1575 { "SKULL", 0, 0, 9, 9, 4, 0, "", 0 },
1576 { "SKULL", 1, 0, 1, 9, 4, 0, "001,002,003,004,005,006,007,008,009,000", 0 },
1577 { "SKULL", 2, 0, 1, 9, 4, 0, "009,008,007,006,005,004,003,002,001,000", 0 },
1578
1579 { "APE", 0, 0, 1, 6, 7, 0, "", 6 },
1580 { "APE", 1, 0, 1, 6, 7, 0, "002,001,000", 6 },
1581 { "APE", 2, 0, 1, 6, 7, 0, "002,003,001,000", 6 },
1582 { "APE", 3, 0, 1, 6, 7, 0, "004,005,004,005,004,001,000", 6 },
1583 { "APE", 4, 0, 1, 6, 7, 0, "001,003,005,004,005,004,001,000", 6 },
1584
1585 { "APE1", 0, 0, 15, 16, 7, 0, "", 16 },
1586 { "APE2", 0, 0, 14, 6, 7, 0, "", 6 },
1587
1588 { "SHOWERAM", 0, 0, 1, 2, 3, 0, "", 2 },
1589 { "SHOWERAM", 1, 0, 1, 2, 3, 0, "026,027,028,029,001,000", 2 },
1590 { "SHOWERAM", 2, 0, 1, 2, 3, 0, "001,029,028,027,026,000", 2 },
1591
1592 { "PRINCESS1", 0, 0, 19, 23, 2, 3, "", 23 },
1593 { "PRINCESS1", 1, 0, 19, 41, -1, 0, "", 23 },
1594 { "PRINCESS1", 2, 0, 19, 42, -1, 0, "", 23 },
1595 { "PRINCESS1", 3, 0, 19, 45, -1, 0, "", 23 },
1596 { "PRINCESS1", 4, 0, 19, 40, -1, 0, "", 23 },
1597 { "PRINCESS1", 5, 0, 19, 45, 2, 3, "T40,043,044,045,000", 45 },
1598 { "PRINCESS1", 6, 0, 19, 45, -1, 0, "T041,038,000", 38 },
1599 { "PRINCESS1", 7, 0, 22, 0, 0, 0, "", 0 },
1600 { "PRINCESS1", 8, 0, 19, 45, 2, 3, "T045,044,043,040,039,000", 39 },
1601
1602 { "PRINCESS2", 0, 0, 46, 23, 2, 3, "", 23 },
1603 { "PRINCESS2", 1, 0, 46, 29, 2, 3, "", 29 },
1604 { "PRINCESS2", 2, 0, 46, 29, 2, 3, "T029,036,035,000", 35 },
1605
1606 { "GUARDS", 0, 0, 7, 7, 0, 0, "", 7 },
1607
1608 { "AMGUARD", 0, 0, 19, 22, 2, 3, "", 22 },
1609
1610 { "MAN1", 0, 0, 2, 3, 2, 3, "", 3 },
1611 { "MAN2", 0, 0, 9, 10, 1, 2, "", 10 },
1612
1613 { "DOG", 0, 0, 6, 6, 1, 0, "", 0 },
1614 { "DOG", 1, 0, 6, 6, 1, 0, "010,009,008,000", 0 },
1615 { "DOG", 2, 0, 6, 6, 1, 0, "008,009,010,000", 0 },
1616
1617 { "CHEF", 0, 0, 5, 6, 2, 3, "", 6 },
1618
1619 { "HENRY", 0, 0, 7, 9, 2, 3, "", 9 },
1620 { "HENRY", 1, 0, 7, 21, -1, 0, "", 9 },
1621 { "HENRY", 2, 0, 7, 19, -1, 0, "", 9 },
1622 { "HENRY", 3, 0, 7, 20, -1, 0, "", 9 },
1623 { "HENRY", 4, 0, 8, 9, 2, 3, "", 9 },
1624 { "HENRY", 5, 0, 23, 9, -1, 0, "", 9 },
1625 { "HENRY", 6, 0, 7, 9, 2, 3, "T019,015,017,017,017,017,017,017,017,015,009,000", 9 },
1626 { "HENRY", 7, 0, 7, 9, 2, 3, "T018,010,000", 10 },
1627 { "HENRY", 8, 0, 7, 9, 2, 3, "T018,016,000", 16 },
1628 { "HENRY", 9, 0, 7, 9, 2, 3, "T018,011,000", 11 },
1629 { "HENRY", 10, 0, 29, 33, 1, 1, "", 33 },
1630 { "HENRY", 11, 0, 7, 30, 2, 0, "", 9 },
1631 { "HENRY", 12, 0, 7, 9, 2, 3, "025,026,000", 26 },
1632 { "HENRY", 13, 0, 7, 9, 2, 3, "027,028,027,028,000", 28 },
1633 { "HENRY", 14, 0, 7, 9, 2, 3, "026,025,007,000", 9 },
1634
1635 { "JOHAN", 0, 0, 1, 15, 2, 3, "", 15 },
1636 { "JOHAN", 1, 0, 1, 0, 0, 0, "T006,007,008,000", 15 },
1637 { "JOHAN", 2, 0, 1, 15, 2, 3, "T002,003,004,005,004,005,004,005,004,005,004,005,004,003,002,000", 15 },
1638 { "JOHAN", 3, 0, 1, 8, -1, 0, "", 15 },
1639 { "JOHAN", 4, 0, 1, 0, 0, 0, "T008,007,006,001,000", 15 },
1640
1641 { "KLUNK", 0, 0, 1, 2, 2, 3, "", 2 },
1642 { "KLUNK", 1, 0, 1, 2, 2, 3, "019,020,021,022,001,000", 2 },
1643 { "KLUNK", 2, 0, 1, 2, 2, 3, "001,022,021,020,019,016,517,000", 2 },
1644 { "KLUNK", 3, 0, 1, 2, 2, 3, "T010,011,010,011,010,011,009,000", 2 },
1645
1646 { "FRANK", 0, 0, 13, 14, 2, 3, "", 14 },
1647 { "FRANK", 1, 0, 13, 20, 0, 1, "", 14 },
1648 { "FRANK", 2, 0, 13, 14, 2, 3, "025,026,027,027,027,026,026,026,027,027,026,026,027,025,013,000", 14 },
1649 { "FRANK", 3, 0, 28, 14, 2, 3, "", 14 },
1650
1651 { "DEATH", 0, 0, 1, 2, 2, 3, "", 2 },
1652 { "DEATH", 1, 0, 1, 2, 2, 3, "013,014,015,016,017,001,000", 0 },
1653 { "DEATH", 2, 0, 1, 2, 2, 3, "001,017,016,015,014,013,000", 0 },
1654 { "DEATH", 3, 0, 1, 2, 2, 3, "T018,019,020,021,021,022,022,020,021,022,020,021,022,023,024,524,000", 2 },
1655 { "DEATH", 4, 0, 1, 2, 2, 3, "T025,026,027,028,028,028,028,028,028,028,028,028,029,035,000", 2 },
1656 { "DEATH", 5, 0, 1, 2, 2, 3, "T030,031,032,033,033,033,033,033,033,033,033,033,034,035,000", 2 },
1657 { "DEATH", 6, 0, 1, 2, 2, 3, "T023,022,020,019,018,001,000", 2 },
1658
1659 { "JASPAR", 0, 0, 1, 1, 22, 0, "026,027,028,029,028,029,028,029,030,023,000", 0 },
1660 { "JASPAR", 1, 0, 1, 1, 22, 0, "023,026,000", 0 },
1661
1662 { "ORACLE", 0, 0, 1, 5, 3, 0, "", 0 },
1663
1664 { "ZOMBIE", 0, 0, 1, 5, 2, 3, "", 5 },
1665 { "ZOMBIE", 1, 0, 1, 12, -1, 0, "", 5 },
1666 { "ZOMBIE", 2, 0, 1, 13, -1, 0, "", 5 },
1667 { "ZOMBIE", 3, 0, 1, 1, 5, 5, "", 5 },
1668
1669 { "ZOMBIE2", 0, 0, 14, 14, 0, 0, "", 0 },
1670 { "ZOMBIE3", 0, 0, 18, 18, 0, 0, "", 0 },
1671
1672 { "ANDERSON", 0, 0, 7, 8, 2, 3, "", 8 },
1673 { "ANDERSON", 1, 0, 7, 8, 1, 0, "", 8 },
1674 { "ANDERSON", 2, 0, 7, 16, -1, 0, "", 8 },
1675 { "ANDERSON", 3, 0, 7, 18, -1, 0, "", 8 },
1676 { "ANDERSON", 4, 0, 7, 19, -1, 0, "", 8 },
1677 { "ANDERSON", 5, 0, 7, 20, -1, 0, "", 8 },
1678 { "ANDERSON", 6, 0, 7, 21, 1, 0, "", 8 },
1679
1680 { "COMPY", 0, 0, 12, 12, -1, 0, "", 0 },
1681 { "COMPY", 1, 0, 10, 10, 10, 0, "010,011,012,012,013,014,014,000", 0 },
1682 { "COMPY", 2, 0, 10, 10, 10, 0, "014,013,012,000", 0 },
1683
1684 { "DEINO", 0, 0, 13, 13, -1, 0, "", 0 },
1685 { "DEINO", 1, 0, 9, 9, 9, 0, "009,010,000", 0 },
1686
1687 { "TMPD", 0, 0, 19, 22, 2, 3, "", 22 },
1688
1689 { "IAN", 0, 0, 7, 9, 2, 3, "", 9 },
1690 { "IAN", 1, 0, 8, 25, 3, 0, "", 25 },
1691 { "IAN", 2, 0, 7, 21, -1, 0, "", 9 },
1692 { "IAN", 3, 0, 7, 22, 1, 0, "", 9 },
1693 { "IAN", 4, 0, 7, 22, -1, 0, "", 9 },
1694 { "IAN", 5, 0, 7, 24, -1, 0, "", 9 },
1695 { "IAN", 6, 0, 7, 9, 2, 3, "034,034,034,035,035,036,036,035,035,036,035,036,035,000", 9 },
1696 { "IAN", 7, 0, 7, 31, -1, 0, "", 9 },
1697
1698 { "FAYE-H", 0, 0, 1, 1, 4, 1, "", 1 },
1699 { "FAYE-H", 1, 0, 1, 1, 4, 1, "007,000", 7 },
1700 { "FAYE-H", 2, 0, 1, 1, 4, 1, "009,010,011,009,001,000", 1 },
1701 { "FAYE-H", 3, 0, 1, 1, 4, 1, "E012,013,000", 1 },
1702 { "FAYE-H", 4, 0, 1, 1, 4, 1, "E015,000", 1 },
1703 { "FAYE-H", 5, 0, 1, 1, 4, 1, "E014,000", 1 },
1704
1705 { "AZURA-H", 0, 0, 1, 1, 4, 1, "", 1 },
1706 { "AZURA-H", 1, 0, 1, 1, 4, 1, "007,000", 7 },
1707 { "AZURA-H", 2, 0, 1, 1, 4, 1, "009,010,011,009,001,000", 1 },
1708 { "AZURA-H", 3, 0, 1, 1, 4, 1, "E012,013, 000", 1 },
1709 { "AZURA-H", 4, 0, 1, 1, 4, 1, "E015,000", 1 },
1710 { "AZURA-H", 5, 0, 1, 1, 4, 1, "E014,000", 1 },
1711
1712 { "FRANK-H", 0, 0, 1, 1, 4, 1, "", 1 },
1713 { "FRANK-H", 1, 0, 1, 1, 4, 1, "E009,000", 1 },
1714 { "FRANK-H", 2, 0, 1, 1, 4, 1, "E007,000", 1 },
1715 { "FRANK-H", 3, 0, 1, 1, 4, 1, "010,011,012,013,014,015,010,000", 1 },
1716
1717 { "JOE-E", 0, 0, 1, 2, 4, 1, "", 2 },
1718 { "JOE-E", 6, 0, 1, 2, 4, 1, "008,009,008,002,000", 2 },
1719
1720 { "AZURA-E", 0, 0, 1, 1, 5, 1, "", 1 },
1721 { "AZURA-E", 1, 0, 1, 1, 5, 1, "009,010,009,008,000", 1 },
1722
1723 { "FAYE-E", 0, 0, 1, 4, 4, 1, "", 1 },
1724 { "FAYE-E", 1, 0, 1, 4, 4, 1, "002,003,002,001,000", 1 },
1725
1726 { "ANDSON-E", 0, 0, 1, 3, 4, 1, "", 1 },
1727 { "ANDSON-E", 1, 0, 1, 3, 4, 1, "002,001,000", 1 },
1728
1729 { "JOE-H", 0, 0, 1, 1, 4, 4, "", 1 },
1730 { "JOE-H", 1, 0, 1, 1, 2, 3, "012,013,014,000", 14 },
1731 { "JOE-H", 2, 0, 1, 1, 2, 3, "010,011,000", 11 },
1732 { "JOE-H", 3, 0, 1, 1, 2, 3, "014,013,012,001,000", 1 },
1733 { "JOE-H", 4, 0, 1, 13, 1, 0, "", 13 },
1734
1735 { "RITA-H", 0, 0, 7, 1, 2, 3, "", 1 },
1736 { "RITA-H", 1, 0, 7, 0, 0, 0, "009,010,011,012,013,000", 13 },
1737 { "RITA-H", 2, 0, 7, 0, 0, 0, "014,015,016,000", 16 },
1738 { "RITA-H", 3, 0, 7, 0, 0, 0, "013,012,011,010,000", 10 },
1739 { "RITA-H", 4, 0, 7, 0, 0, 0, "009,007,008,007,009,000", 9 },
1740 { "RITA-H", 5, 0, 7, 0, 0, 0, "016,015,014,000", 14 },
1741
1742 { "RITA", 0, 0, 1, 4, 2, 3, "", 4 },
1743 { "RITA", 1, 0, 2, 4, 2, 3, "", 4 },
1744
1745 { "SPARKY-H", 0, 0, 1, 1, 2, 3, "", 1 },
1746
1747 { "HUGH", 0, 0, 1, 1, 2, 3, "", 1 },
1748 { "HUGH", 1, 0, 7, 7, 2, 3, "", 7 },
1749
1750 { "X2_JOE", 0, 0, 1, 1, 2, 3, "", 1 },
1751 { "X2_JOE", 1, 0, 1, 1, 2, 3, "001,007,008,008,007,001,000", 1 },
1752
1753 { "X2_RITA", 0, 0, 1, 1, 2, 3, "", 1 },
1754 { "X2_RITA", 1, 0, 1, 1, 2, 3, "001,007,008,008,007,001,000", 1 },
1755
1756 { "X3_RITA", 0, 0, 1, 1, 4, 1, "", 1 },
1757 { "X3_RITA", 1, 0, 1, 1, 4, 1, "007,000", 7 },
1758 { "X3_RITA", 2, 0, 1, 1, 4, 1, "009,010,011,009,001,000", 1 },
1759 { "X3_RITA", 3, 0, 1, 1, 4, 1, "E012,013,000", 1 },
1760 { "X3_RITA", 4, 0, 1, 1, 4, 1, "E015,000", 1 },
1761 { "X3_RITA", 5, 0, 1, 1, 4, 1, "E014,000", 1 },
1762
1763 { "X4_JOE", 0, 0, 1, 1, 3, 4, "", 1 },
1764 { "X4_JOE", 1, 0, 1, 13, 2, 3, "", 13 },
1765 { "X4_JOE", 2, 0, 1, 1, 3, 4, "009, 010, 011, 012, 013, 000", 13 },
1766 { "X4_JOE", 3, 0, 1, 1, 3, 4, "012, 011, 010, 009, 000", 9 },
1767 { "X4_JOE", 4, 0, 1, 1, 3, 4, "001, 019, 000", 19 },
1768
1769 { "X4_RITA", 0, 0, 1, 1, 0, 1, "", 1 },
1770 { "X4_RITA", 1, 0, 1, 7, 0, 1, "", 7 },
1771 { "X4_RITA", 2, 0, 1, 1, 3, 4, "004,005,006,006,006,006,007,000", 7 },
1772 { "X4_RITA", 3, 0, 1, 1, 3, 4, "005,004,001,000", 1 },
1773 { "X4_RITA", 4, 0, 1, 1, 3, 4, "001,003,000", 3 },
1774
1775 { "X5_SPARKY", 0, 0, 1, 1, 2, 3, "", 1 },
1776 { "X5_SPARKY", 1, 0, 1, 1, 2, 3, "001,010,011,011,001,000", 1 },
1777 { "X5_SPARKY", 2, 0, 1, 1, 2, 3, "001,007,008,009,000", 9 },
1778
1779 { "X6_HUGH", 0, 0, 1, 1, 2, 3, "", 1 },
1780 { "X6_HUGH", 1, 0, 1, 1, 2, 3, "007,007,007,007,,001,000", 1 },
1781 { "X6_HUGH", 2, 0, 1, 1, 2, 3, "008,008,008,008,008,009,009,008,008,008,009,008,000", 8 },
1782
1783 { "X10_JOE", 0, 0, 1, 2, 2, 3, "", 2 },
1784 { "X10_JOE", 1, 0, 1, 8, 2, 3, "", 8 },
1785 { "X10_JOE", 2, 0, 1, 2, 2, 3, "014,014,014,015,015,014,014,015,015,000", 2 },
1786
1787 { "X10_RITA", 0, 0, 1, 2, 2, 3, "", 2 },
1788
1789 { "X11_JOE", 0, 0, 1, 2, 0, 1, "", 2 },
1790
1791 { "X11_RITA", 0, 0, 1, 2, 0, 1, "", 2 },
1792 { "X11_RITA", 1, 0, 1, 2, 1, 0, "003,004,000", 4 },
1793
1794 { "JOHN", 0, 0, 1, 2, 2, 3, "", 1 },
1795 { "JOHN", 1, 0, 1, 15, -1, 0, "", 1 },
1796 { "JOHN", 2, 0, 1, 16, -1, 0, "", 1 },
1797 { "JOHN", 3, 0, 1, 17, -1, 0, "", 1 },
1798
1799 { "STEVE", 0, 0, 8, 2, 2, 3, "", 2 },
1800 { "STEVE", 1, 0, 8, 16, -1, 0, "", 2 },
1801 { "STEVE", 2, 0, 9, 18, -1, 0, "T016,017,017,016,008,000", 2 },
1802 { "STEVE", 3, 0, 8, 18, -1, 0, "", 2 },
1803
1804 { "TONY", 0, 0, 1, 2, 2, 3, "", 1 },
1805 { "TONY", 1, 0, 1, 12, -1, 0, "", 1 },
1806
1807 { "*", 0, 0, 0, 0, 0, 0, "", 0 }
1808 };
1809
1810 } // End of namespace Queen
1811