mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-17 15:18:11 +00:00
4ae7e06a1d
svn-id: r10711
644 lines
16 KiB
C++
644 lines
16 KiB
C++
/* ScummVM - Scumm Interpreter
|
|
* Copyright (C) 2003 The ScummVM project
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* $Header$
|
|
*
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "talk.h"
|
|
#include "graphics.h"
|
|
|
|
namespace Queen {
|
|
|
|
/*
|
|
Functions needed:
|
|
|
|
Data needed:
|
|
|
|
*/
|
|
|
|
void Talk::run(
|
|
const char *filename,
|
|
char *cutawayFilename,
|
|
Graphics *graphics,
|
|
Logic *logic,
|
|
Resource *resource) {
|
|
Talk *talk = new Talk(graphics, logic, resource);
|
|
talk->talk(filename, cutawayFilename);
|
|
delete talk;
|
|
}
|
|
|
|
Talk::Talk(
|
|
Graphics *graphics,
|
|
Logic *logic,
|
|
Resource *resource)
|
|
: _graphics(graphics), _logic(logic), _resource(resource), _fileData(NULL), _quit(false) {
|
|
|
|
//! TODO Move this to the Logic class later!
|
|
memset(_talkSelected, 0, sizeof(_talkSelected));
|
|
}
|
|
|
|
Talk::~Talk() {
|
|
delete[] _fileData;
|
|
}
|
|
|
|
|
|
|
|
void Talk::talk(const char *filename, char *cutawayFilename) {
|
|
_oldSelectedSentenceIndex = 0;
|
|
_oldSelectedSentenceValue = 0;
|
|
|
|
debug(0, "----- talk(\"%s\") -----", filename);
|
|
|
|
cutawayFilename[0] = '\0';
|
|
|
|
// XXX S=SUBJECT[1];
|
|
// XXX R=ROOM_DATA[ROOM];
|
|
// XXX if(OBJECT_DATA[NOUN2+R][0]<=0) return;
|
|
// XXX if(OBJECT_DATA[NOUN2+R][4]>0) return;
|
|
// XXX strcpy(Pstr,FIND_STATE(OBJECT_DATA[NOUN2+R][6],"TALK"));
|
|
|
|
// I cant talk to that.
|
|
|
|
// XXX if(seq(Pstr,"MUTE")) {
|
|
// XXX k=24+Rnd(2);
|
|
// XXX SPEAK(JOE_RESPstr[k],"JOE",find_cd_desc(k));
|
|
// XXX return;
|
|
// XXX }
|
|
// XXX panelflag=0;
|
|
|
|
|
|
|
|
load(filename);
|
|
|
|
char personName[MAX_STRING_SIZE];
|
|
// XXX SET_PERSON_DATA(N,NAMEstr,0);
|
|
int bobNum = 1; // XXX P_BNUM;
|
|
// XXX strcpy(PERstr,P_NAMEstr);
|
|
personName[0] = '\0';
|
|
|
|
int16 oldLevel = 0;
|
|
bool personWalking = false; // OWALK in talk.c
|
|
|
|
// Lines 828-846 in talk.c
|
|
for (int i = 1; i <= 4; i++) {
|
|
if (talkSelected()->values[i-1] > 0) {
|
|
// This option has been redefined so display new dialogue option
|
|
_dialogueTree[1][i].head = talkSelected()->values[i-1];
|
|
}
|
|
else if (talkSelected()->values[i-1] == -1) {
|
|
|
|
// Already selected so don't redisplay
|
|
if (_dialogueTree[1][i].gameStateIndex >= 0) {
|
|
_dialogueTree[1][i].head = -1;
|
|
_dialogueTree[1][i].dialogueNodeValue1 = -1;
|
|
_dialogueTree[1][i].gameStateIndex = -1;
|
|
_dialogueTree[1][i].gameStateValue = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
initialTalk();
|
|
|
|
// Lines 906-? in talk.c
|
|
// XXX drawmouseflag=1;
|
|
int16 level=1, retval=0;
|
|
int16 head = _dialogueTree[level][0].head;
|
|
|
|
// TODO: split this loop in several functions
|
|
while(retval != -1) {
|
|
// debug(0, "retval = %i", retval);
|
|
|
|
char otherVoiceFilePrefix [MAX_STRING_SIZE];
|
|
|
|
_talkString[0][0] = '\0';
|
|
|
|
if(talkSelected()->hasTalkedTo == 1 && head == 1)
|
|
strcpy(_talkString[0], _person2String);
|
|
else
|
|
findDialogueString(_person1Ptr, head, _talkString[0]);
|
|
|
|
if(talkSelected()->hasTalkedTo == 1 && head == 1)
|
|
sprintf(otherVoiceFilePrefix, "%2dXXXXP", _talkKey);
|
|
else
|
|
sprintf(otherVoiceFilePrefix, "%2d%4xP", _talkKey, head);
|
|
|
|
if (_talkString[0][0] == '\0' && retval > 1) {
|
|
findDialogueString(_person1Ptr, retval, _talkString[0]);
|
|
sprintf(otherVoiceFilePrefix,"%2d%4xP", _talkKey, retval);
|
|
}
|
|
|
|
// Joe dialogue
|
|
|
|
for (int i = 1; i <= 4; i++) {
|
|
findDialogueString(_joePtr, _dialogueTree[level][i].head, _talkString[i]);
|
|
|
|
int16 index = _dialogueTree[level][i].gameStateIndex;
|
|
|
|
if (index < 0 && _logic->gameState(abs(index)) != _dialogueTree[level][i].gameStateValue)
|
|
_talkString[i][0] = '\0';
|
|
|
|
sprintf(_joeVoiceFilePrefix[i], "%2d%4xJ", _talkKey, _dialogueTree[level][i].head);
|
|
}
|
|
|
|
// Check to see if(all the dialogue options have been selected.
|
|
// if this is the case, and the last one left is the exit option,
|
|
// then automatically set S to that and exit.
|
|
|
|
int choicesLeft = 0;
|
|
int selectedSentence = 0;
|
|
|
|
for (int i = 1; i <= 4; i++) {
|
|
if (_talkString[i][0] != '\0') {
|
|
choicesLeft++;
|
|
selectedSentence = i;
|
|
}
|
|
}
|
|
|
|
// debug(0, "choicesLeft = %i", choicesLeft);
|
|
|
|
if (1 == choicesLeft) {
|
|
// Automatically run the final dialogue option
|
|
if (speak(_talkString[0], personName, otherVoiceFilePrefix))
|
|
personWalking = true;
|
|
|
|
if (_quit)
|
|
break;
|
|
|
|
speak(_talkString[selectedSentence], personName, _joeVoiceFilePrefix[selectedSentence]);
|
|
}
|
|
else {
|
|
if (bobNum > 0) {
|
|
speak(_talkString[0], personName, otherVoiceFilePrefix);
|
|
selectedSentence = selectSentence();
|
|
}
|
|
else {
|
|
warning("bobBum is %i", bobNum);
|
|
selectedSentence = 0;
|
|
}
|
|
}
|
|
|
|
if (_quit)
|
|
break;
|
|
|
|
retval = _dialogueTree[level][selectedSentence].dialogueNodeValue1;
|
|
head = _dialogueTree[level][selectedSentence].head;
|
|
oldLevel = level;
|
|
level = 0;
|
|
|
|
// Set LEVEL to the selected child in dialogue tree
|
|
|
|
for (int i = 1; i <= _levelMax; i++)
|
|
if (_dialogueTree[i][0].head == head)
|
|
level = i;
|
|
|
|
if (0 == level) {
|
|
// No new level has been selected, so lets set LEVEL to the
|
|
// tree path pointed to by the RETVAL
|
|
|
|
for (int i = 1; i <= _levelMax; i++)
|
|
for (int j = 0; j <= 5; j++)
|
|
if (_dialogueTree[i][j].head == retval)
|
|
level = i;
|
|
|
|
disableSentence(oldLevel, selectedSentence);
|
|
}
|
|
else { // 0 != level
|
|
// Check to see if Person Return value is positive, if it is, then
|
|
// change the selected dialogue option to the Return value
|
|
|
|
if (_dialogueTree[level][0].dialogueNodeValue1 > 0) {
|
|
if (1 == oldLevel) {
|
|
_oldSelectedSentenceIndex = selectedSentence;
|
|
_oldSelectedSentenceValue = talkSelected()->values[selectedSentence-1];
|
|
talkSelected()->values[selectedSentence-1] = _dialogueTree[level][0].dialogueNodeValue1;
|
|
}
|
|
|
|
_dialogueTree[oldLevel][selectedSentence].head = _dialogueTree[level][0].dialogueNodeValue1;
|
|
_dialogueTree[level][0].dialogueNodeValue1 = -1;
|
|
}
|
|
else {
|
|
disableSentence(oldLevel, selectedSentence);
|
|
}
|
|
}
|
|
|
|
// Check selected person to see if any Gamestates need setting
|
|
|
|
int16 index = _dialogueTree[level][0].gameStateIndex;
|
|
|
|
if (index > 0)
|
|
_logic->gameState(index, _dialogueTree[level][0].gameStateValue);
|
|
|
|
// if the selected dialogue line has a POSITIVE game state value
|
|
// then set gamestate to Value = TALK(OLDLEVEL,S,3)
|
|
|
|
index = _dialogueTree[oldLevel][selectedSentence].gameStateIndex;
|
|
if (index > 0)
|
|
_logic->gameState(index, _dialogueTree[oldLevel][selectedSentence].gameStateValue);
|
|
|
|
|
|
// if(RETVAL = -1, then before we exit, check to see if(person
|
|
// has something final to say!
|
|
|
|
if (-1 == retval) {
|
|
findDialogueString(_person1Ptr, head, _talkString[0]);
|
|
if (_talkString[0][0] != '\0') {
|
|
sprintf(otherVoiceFilePrefix, "%2d%4xP", _talkKey, head);
|
|
if (speak(_talkString[0], personName, otherVoiceFilePrefix))
|
|
personWalking = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Talk::disableSentence(int oldLevel, int selectedSentence) {
|
|
// Mark off selected option
|
|
|
|
if (1 == oldLevel) {
|
|
if (_dialogueTree[oldLevel][selectedSentence].dialogueNodeValue1 != -1) {
|
|
// Make sure choice is not exit option
|
|
_oldSelectedSentenceIndex = selectedSentence;
|
|
_oldSelectedSentenceValue = talkSelected()->values[selectedSentence-1];
|
|
talkSelected()->values[selectedSentence-1] = -1;
|
|
}
|
|
}
|
|
|
|
// Cancel selected dialogue line, so that its no longer displayed
|
|
|
|
_dialogueTree[oldLevel][selectedSentence].head = -1;
|
|
_dialogueTree[oldLevel][selectedSentence].dialogueNodeValue1 = -1;
|
|
}
|
|
|
|
void Talk::findDialogueString(byte *ptr, int16 id, char *str) {
|
|
str[0] = '\0';
|
|
|
|
for (int i = 1; i <= _pMax; i++) {
|
|
ptr += 2;
|
|
int16 currentId = (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
if (id == currentId) {
|
|
ptr = getString(ptr, str, MAX_STRING_LENGTH, 4);
|
|
//debug(0, "Found string with ID %i: '%s'", id, str);
|
|
break;
|
|
}
|
|
else
|
|
ptr = getString(ptr, NULL, MAX_STRING_LENGTH, 4);
|
|
}
|
|
|
|
if (str[0] == '\0')
|
|
warning("Failed to find string with ID %i", id);
|
|
}
|
|
|
|
void Talk::load(const char *filename) {
|
|
byte *ptr = _fileData = _resource->loadFile(filename, 20);
|
|
if (!_fileData) {
|
|
error("Failed to load resource data file '%s'", filename);
|
|
}
|
|
|
|
bool canQuit;
|
|
|
|
//
|
|
// Load talk header
|
|
//
|
|
|
|
_levelMax = (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
|
|
//debug(0, "levelMax = %i", _levelMax);
|
|
|
|
if (_levelMax < 0) {
|
|
_levelMax = -_levelMax;
|
|
canQuit = false;
|
|
}
|
|
else
|
|
canQuit = true;
|
|
|
|
_uniqueKey = (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
_talkKey = (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
/*int16 jMax =*/ (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
_pMax = (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
/*int16 gameState1 =*/ (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
/*int16 testValue1 =*/ (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
/*int16 itemToInsert1 =*/ (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
/*int16 gameState2 =*/ (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
/*int16 testValue2 =*/ (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
/*int16 itemToInsert2 =*/ (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
|
|
//debug(0, "uniqueKey = %i", _uniqueKey);
|
|
//debug(0, "talkKey = %i", _talkKey);
|
|
|
|
_person1Ptr = _fileData + READ_BE_UINT16(ptr); ptr += 2;
|
|
/*byte *cutawayPtr = _fileData + READ_BE_UINT16(ptr);*/ ptr += 2;
|
|
_person2Ptr = _fileData + READ_BE_UINT16(ptr); ptr += 2;
|
|
|
|
if (ptr != (_fileData + 28))
|
|
error("ptr != (_fileData + 28))");
|
|
|
|
byte *dataPtr = _fileData + 32;
|
|
_joePtr = dataPtr + _levelMax * 96;
|
|
|
|
//
|
|
// Load dialogue tree
|
|
//
|
|
|
|
ptr = dataPtr;
|
|
|
|
for (int i = 1; i <= _levelMax; i++)
|
|
for (int j = 0; j <= 5; j++) {
|
|
ptr += 2;
|
|
_dialogueTree[i][j].head = (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
ptr += 2;
|
|
_dialogueTree[i][j].dialogueNodeValue1 = (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
ptr += 2;
|
|
_dialogueTree[i][j].gameStateIndex = (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
ptr += 2;
|
|
_dialogueTree[i][j].gameStateValue = (int16)READ_BE_UINT16(ptr); ptr += 2;
|
|
}
|
|
}
|
|
|
|
void Talk::initialTalk() {
|
|
// Lines 848-903 in talk.c
|
|
|
|
byte *ptr = _joePtr + 2;
|
|
|
|
uint16 hasString = READ_BE_UINT16(ptr); ptr += 2;
|
|
|
|
char joeString[MAX_STRING_SIZE];
|
|
if (hasString) {
|
|
ptr = getString(ptr, joeString, MAX_STRING_LENGTH);
|
|
//debug(0, "joeString = '%s'", joeString);
|
|
}
|
|
else
|
|
joeString[0] = '\0';
|
|
|
|
ptr = _person2Ptr;
|
|
ptr = getString(ptr, _person2String, MAX_STRING_LENGTH);
|
|
//debug(0, "person2String = '%s'", _person2String);
|
|
|
|
char joe2String[MAX_STRING_SIZE];
|
|
ptr = getString(ptr, joe2String, MAX_STRING_LENGTH);
|
|
//debug(0, "joe2String = '%s'", joe2String);
|
|
|
|
if (talkSelected()->hasTalkedTo == 0) {
|
|
|
|
// Not yet talked to this person
|
|
|
|
if (joeString[0] != '0') {
|
|
char voiceFilePrefix[MAX_STRING_SIZE];
|
|
sprintf(voiceFilePrefix, "%2dSSSSJ", _talkKey);
|
|
speak(joeString, "JOE", voiceFilePrefix);
|
|
}
|
|
}
|
|
else {
|
|
// Already spoken to them, choose second response
|
|
|
|
if (joe2String[0] != '0') {
|
|
char voiceFilePrefix[MAX_STRING_SIZE];
|
|
sprintf(voiceFilePrefix, "%2dSSSSJ", _talkKey);
|
|
speak(joe2String, "JOE", voiceFilePrefix);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool Talk::speak(const char *sentence, const char *person, const char *voiceFilePrefix) {
|
|
debug(0, "Sentence '%s' is said by person '%s' and voice files with prefix '%s' played",
|
|
sentence, person, voiceFilePrefix);
|
|
return false; // XXX
|
|
}
|
|
|
|
byte *Talk::getString(byte *ptr, char *str, int maxLength, int align) {
|
|
int length = *ptr;
|
|
ptr++;
|
|
|
|
if (length > maxLength) {
|
|
error("String too long. Length = %i, maxLength = %i, str = '%*s'",
|
|
length, maxLength, length, (const char*)ptr);
|
|
}
|
|
else if (length) {
|
|
if (str)
|
|
memcpy(str, (const char*)ptr, length);
|
|
ptr += length;
|
|
|
|
while ((int)ptr % align)
|
|
ptr++;
|
|
}
|
|
|
|
if (str)
|
|
str[length] = '\0';
|
|
|
|
return ptr;
|
|
}
|
|
|
|
Talk::TalkSelected *Talk::talkSelected() {
|
|
return _talkSelected + _uniqueKey;
|
|
}
|
|
|
|
int Talk::splitOption(const char *str, char optionText[5][MAX_STRING_SIZE]) {
|
|
|
|
//debug(0, "splitOption(\"%s\")", str);
|
|
|
|
// Check to see if option fits on one line, and exit early
|
|
|
|
/* XXX if (_logic->language() == ENGLISH || textWidth(str) <= MAX_TEXT_WIDTH)*/ {
|
|
strcpy(optionText[0], str);
|
|
return 1;
|
|
}
|
|
|
|
abort();
|
|
|
|
// Split up multiple line option at closest space character
|
|
// int optionLines = 0;
|
|
}
|
|
|
|
static char *removeStar(char *str) {
|
|
|
|
// The remove_star function in talk.c uses a static variable, but this
|
|
// modifies the string instead, so the caller should use a copy of the
|
|
// string.
|
|
|
|
char *p = strchr(str, '*');
|
|
if (p)
|
|
*p = '\0';
|
|
|
|
return str;
|
|
}
|
|
|
|
int16 Talk::selectSentence() {
|
|
// Function TALK_BOB (lines 577-739) in talk.c
|
|
int selectedSentence = 0;
|
|
|
|
int scrollX = 0; // XXX: global variable
|
|
int startOption = 1;
|
|
int optionLines = 0;
|
|
char optionText[5][MAX_STRING_SIZE];
|
|
|
|
// Change NORMAL_INK -> TALK_NORMAL_INK
|
|
|
|
_graphics->textCurrentColor(INK_TALK_NORMAL);
|
|
|
|
// These bobs are up and down arrows
|
|
|
|
BobSlot *bob1 = _graphics->bob(SENTENCE_BOB_1);
|
|
BobSlot *bob2 = _graphics->bob(SENTENCE_BOB_2);
|
|
|
|
bob1->x = 303 + 8 + scrollX;
|
|
bob1->y = 150 + 1;
|
|
bob1->frameNum = 3;
|
|
bob1->box.y2 = 199;
|
|
bob1->active = false;
|
|
|
|
bob2->x = 303 + scrollX;
|
|
bob2->y = 175;
|
|
bob2->frameNum = 4;
|
|
bob2->box.y2 = 199;
|
|
bob2->active = false;
|
|
|
|
bool rezone = true;
|
|
|
|
while (rezone) {
|
|
rezone = false;
|
|
|
|
// Set zones for UP/DOWN text arrows when not English version
|
|
// XXX ClearZones(1);
|
|
|
|
if (_logic->language() != ENGLISH) {
|
|
// XXX SetZone(1,5,MAXTEXTLEN+1, 0,319,24);
|
|
// XXX SetZone(1,6,MAXTEXTLEN+1,25,319,49);
|
|
}
|
|
|
|
_graphics->textClear(151,199);
|
|
|
|
int sentenceCount = 0;
|
|
int yOffset = 1;
|
|
|
|
for (int i = startOption; i <= 4; i++) {
|
|
// XXX TALK_ZONE[I] = 0;
|
|
if (_talkString[i][0] != '\0') {
|
|
sentenceCount++;
|
|
|
|
char temp[MAX_STRING_SIZE];
|
|
strcpy(temp, _talkString[i]);
|
|
optionLines = splitOption(removeStar(temp), optionText);
|
|
|
|
if (yOffset < 5)
|
|
/* XXX SetZone(
|
|
1,
|
|
I,
|
|
0,
|
|
(yofs * 10) - PUSHUP,
|
|
(VersionStr[1] =='E') ? 319 : MAX_TEXT_WIDTH,
|
|
10 * optionLines + (yOffset * 10) - PUSHUP) */;
|
|
|
|
for (int j = 0; j < optionLines; j++) {
|
|
if (yOffset < 5) {
|
|
debug(0, "Draw text '%s'", optionText[j]);
|
|
_graphics->textSet(
|
|
(j == 0) ? 0 : 24,
|
|
150 - PUSHUP + yOffset * 10,
|
|
optionText[j]);
|
|
}
|
|
yOffset++;
|
|
}
|
|
|
|
// XXX TALK_ZONE[i] = sentenceCount;
|
|
}
|
|
}
|
|
|
|
yOffset--;
|
|
|
|
// Up and down dialogue arrows
|
|
|
|
if (_logic->language() != ENGLISH) {
|
|
bob1->active = (startOption > 1);
|
|
bob2->active = (yOffset > 4);
|
|
}
|
|
|
|
// XXX KEYVERB=0;
|
|
if (sentenceCount > 0) {
|
|
int zone = 0;
|
|
int oldZone = 0;
|
|
|
|
while (0 == selectedSentence) {
|
|
|
|
if (_quit)
|
|
break;
|
|
|
|
_graphics->update();
|
|
|
|
// XXX zone = zone(1, mouseX, mouseY);
|
|
|
|
if (5 == zone || 6 == zone) {
|
|
// XXX Arrow zones
|
|
}
|
|
else {
|
|
if (oldZone != zone) {
|
|
// Changed zone, change text colors
|
|
|
|
if (zone > 0) {
|
|
|
|
// XXX for (int i = zones[1][zone].y1; i < zones[1][zone].y2; i += 10)
|
|
// XXX texts[i + 150].col = INK_JOE;
|
|
}
|
|
|
|
if (oldZone > 0) {
|
|
// XXX for (i = zones[1][oldZone].y1; i < zones[1][oldZone].y2; i += 10)
|
|
// XXX texts[i + 150].col = INK_TALK_NORMAL;
|
|
}
|
|
|
|
oldZone = zone;
|
|
}
|
|
|
|
}
|
|
|
|
// XXX make the loop exit as we can't get any input yet
|
|
selectedSentence = 1;
|
|
} // while()
|
|
}
|
|
}
|
|
|
|
|
|
// XXX Begin debug stuff
|
|
// debug(0, "----- Select a sentence of these -----");
|
|
for (int i = 1; i <= 4; i++) {
|
|
if (_talkString[i][0] != '\0') {
|
|
// XXX debug(0, "%i: %s", i, _talkString[i]);
|
|
if (!selectedSentence)
|
|
selectedSentence = i;
|
|
}
|
|
}
|
|
// XXX End debug stuff
|
|
|
|
|
|
debug(0, "Selected sentence %i", selectedSentence);
|
|
|
|
bob1->active = false;
|
|
bob2->active = false;
|
|
|
|
if (selectedSentence > 0) {
|
|
_graphics->textClear(0,198);
|
|
|
|
speak(_talkString[selectedSentence], "JOE", _joeVoiceFilePrefix[selectedSentence]);
|
|
}
|
|
|
|
_graphics->textClear(151,151);
|
|
|
|
return selectedSentence;
|
|
}
|
|
|
|
} // End of namespace Queen
|