mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-30 07:23:05 +00:00
603 lines
17 KiB
C++
603 lines
17 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#include "sherlock/scalpel/scalpel_talk.h"
|
|
#include "sherlock/scalpel/scalpel_map.h"
|
|
#include "sherlock/scalpel/scalpel_people.h"
|
|
#include "sherlock/scalpel/scalpel_scene.h"
|
|
#include "sherlock/scalpel/scalpel_user_interface.h"
|
|
#include "sherlock/sherlock.h"
|
|
#include "sherlock/screen.h"
|
|
#include "sherlock/scalpel/3do/movie_decoder.h"
|
|
|
|
namespace Sherlock {
|
|
|
|
namespace Scalpel {
|
|
|
|
const byte SCALPEL_OPCODES[] = {
|
|
128, // OP_SWITCH_SPEAKER
|
|
129, // OP_RUN_CANIMATION
|
|
130, // OP_ASSIGN_PORTRAIT_LOCATION
|
|
131, // OP_PAUSE
|
|
132, // OP_REMOVE_PORTRAIT
|
|
133, // OP_CLEAR_WINDOW
|
|
134, // OP_ADJUST_OBJ_SEQUENCE
|
|
135, // OP_WALK_TO_COORDS
|
|
136, // OP_PAUSE_WITHOUT_CONTROL
|
|
137, // OP_BANISH_WINDOW
|
|
138, // OP_SUMMON_WINDOW
|
|
139, // OP_SET_FLAG
|
|
140, // OP_SFX_COMMAND
|
|
141, // OP_TOGGLE_OBJECT
|
|
142, // OP_STEALTH_MODE_ACTIVE
|
|
143, // OP_IF_STATEMENT
|
|
144, // OP_ELSE_STATEMENT
|
|
145, // OP_END_IF_STATEMENT
|
|
146, // OP_STEALTH_MODE_DEACTIVATE
|
|
147, // OP_TURN_HOLMES_OFF
|
|
148, // OP_TURN_HOLMES_ON
|
|
149, // OP_GOTO_SCENE
|
|
150, // OP_PLAY_PROLOGUE
|
|
151, // OP_ADD_ITEM_TO_INVENTORY
|
|
152, // OP_SET_OBJECT
|
|
153, // OP_CALL_TALK_FILE
|
|
143, // OP_MOVE_MOUSE
|
|
155, // OP_DISPLAY_INFO_LINE
|
|
156, // OP_CLEAR_INFO_LINE
|
|
157, // OP_WALK_TO_CANIMATION
|
|
158, // OP_REMOVE_ITEM_FROM_INVENTORY
|
|
159, // OP_ENABLE_END_KEY
|
|
160, // OP_DISABLE_END_KEY
|
|
161, // OP_CARRIAGE_RETURN
|
|
0, // OP_MOUSE_ON_OFF
|
|
0, // OP_SET_WALK_CONTROL
|
|
0, // OP_SET_TALK_SEQUENCE
|
|
0, // OP_PLAY_SONG
|
|
0, // OP_WALK_HOLMES_AND_NPC_TO_CANIM
|
|
0, // OP_SET_NPC_PATH_DEST
|
|
0, // OP_NEXT_SONG
|
|
0, // OP_SET_NPC_PATH_PAUSE
|
|
0, // OP_PASSWORD
|
|
0, // OP_SET_SCENE_ENTRY_FLAG
|
|
0, // OP_WALK_NPC_TO_CANIM
|
|
0, // OP_WALK_HOLMES_AND_NPC_TO_COORDS
|
|
0, // OP_WALK_HOLMES_AND_NPC_TO_COORDS
|
|
0, // OP_SET_NPC_TALK_FILE
|
|
0, // OP_TURN_NPC_OFF
|
|
0, // OP_TURN_NPC_ON
|
|
0, // OP_NPC_DESC_ON_OFF
|
|
0, // OP_NPC_PATH_PAUSE_TAKING_NOTES
|
|
0, // OP_NPC_PATH_PAUSE_LOOKING_HOLMES
|
|
0, // OP_ENABLE_TALK_INTERRUPTS
|
|
0, // OP_DISABLE_TALK_INTERRUPTS
|
|
0, // OP_SET_NPC_INFO_LINE
|
|
0, // OP_SET_NPC_POSITION
|
|
0, // OP_NPC_PATH_LABEL
|
|
0, // OP_PATH_GOTO_LABEL
|
|
0, // OP_PATH_IF_FLAG_GOTO_LABEL
|
|
0, // OP_NPC_WALK_GRAPHICS
|
|
0, // OP_NPC_VERB
|
|
0, // OP_NPC_VERB_CANIM
|
|
0, // OP_NPC_VERB_SCRIPT
|
|
0, // OP_RESTORE_PEOPLE_SEQUENCE
|
|
0, // OP_NPC_VERB_TARGET
|
|
0, // OP_TURN_SOUNDS_OFF
|
|
0, // OP_NULL
|
|
0 // OP_END_TEXT_WINDOW
|
|
};
|
|
|
|
/*----------------------------------------------------------------*/
|
|
|
|
ScalpelTalk::ScalpelTalk(SherlockEngine *vm) : Talk(vm) {
|
|
static OpcodeMethod OPCODE_METHODS[] = {
|
|
(OpcodeMethod)&ScalpelTalk::cmdSwitchSpeaker,
|
|
(OpcodeMethod)&ScalpelTalk::cmdRunCAnimation,
|
|
(OpcodeMethod)&ScalpelTalk::cmdAssignPortraitLocation,
|
|
|
|
(OpcodeMethod)&ScalpelTalk::cmdPause,
|
|
(OpcodeMethod)&ScalpelTalk::cmdRemovePortrait,
|
|
(OpcodeMethod)&ScalpelTalk::cmdClearWindow,
|
|
(OpcodeMethod)&ScalpelTalk::cmdAdjustObjectSequence,
|
|
(OpcodeMethod)&ScalpelTalk::cmdWalkToCoords,
|
|
(OpcodeMethod)&ScalpelTalk::cmdPauseWithoutControl,
|
|
(OpcodeMethod)&ScalpelTalk::cmdBanishWindow,
|
|
(OpcodeMethod)&ScalpelTalk::cmdSummonWindow,
|
|
(OpcodeMethod)&ScalpelTalk::cmdSetFlag,
|
|
(OpcodeMethod)&ScalpelTalk::cmdSfxCommand,
|
|
|
|
(OpcodeMethod)&ScalpelTalk::cmdToggleObject,
|
|
(OpcodeMethod)&ScalpelTalk::cmdStealthModeActivate,
|
|
(OpcodeMethod)&ScalpelTalk::cmdIf,
|
|
(OpcodeMethod)&ScalpelTalk::cmdElse,
|
|
nullptr,
|
|
(OpcodeMethod)&ScalpelTalk::cmdStealthModeDeactivate,
|
|
(OpcodeMethod)&ScalpelTalk::cmdHolmesOff,
|
|
(OpcodeMethod)&ScalpelTalk::cmdHolmesOn,
|
|
(OpcodeMethod)&ScalpelTalk::cmdGotoScene,
|
|
(OpcodeMethod)&ScalpelTalk::cmdPlayPrologue,
|
|
|
|
(OpcodeMethod)&ScalpelTalk::cmdAddItemToInventory,
|
|
(OpcodeMethod)&ScalpelTalk::cmdSetObject,
|
|
(OpcodeMethod)&ScalpelTalk::cmdCallTalkFile,
|
|
(OpcodeMethod)&ScalpelTalk::cmdMoveMouse,
|
|
(OpcodeMethod)&ScalpelTalk::cmdDisplayInfoLine,
|
|
(OpcodeMethod)&ScalpelTalk::cmdClearInfoLine,
|
|
(OpcodeMethod)&ScalpelTalk::cmdWalkToCAnimation,
|
|
(OpcodeMethod)&ScalpelTalk::cmdRemoveItemFromInventory,
|
|
(OpcodeMethod)&ScalpelTalk::cmdEnableEndKey,
|
|
(OpcodeMethod)&ScalpelTalk::cmdDisableEndKey,
|
|
|
|
(OpcodeMethod)&ScalpelTalk::cmdCarriageReturn,
|
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
|
|
};
|
|
|
|
_opcodeTable = OPCODE_METHODS;
|
|
_opcodes = SCALPEL_OPCODES;
|
|
|
|
if (vm->getLanguage() == Common::DE_DEU || vm->getLanguage() == Common::ES_ESP) {
|
|
// The German and Spanish versions use a different opcode range
|
|
static byte opcodes[sizeof(SCALPEL_OPCODES)];
|
|
for (uint idx = 0; idx < sizeof(SCALPEL_OPCODES); ++idx)
|
|
opcodes[idx] = SCALPEL_OPCODES[idx] ? SCALPEL_OPCODES[idx] + 47 : 0;
|
|
|
|
_opcodes = opcodes;
|
|
}
|
|
|
|
}
|
|
|
|
void ScalpelTalk::talkInterface(const byte *&str) {
|
|
FixedText &fixedText = *_vm->_fixedText;
|
|
People &people = *_vm->_people;
|
|
Screen &screen = *_vm->_screen;
|
|
UserInterface &ui = *_vm->_ui;
|
|
|
|
// If the window isn't yet open, draw the window before printing starts
|
|
if (!ui._windowOpen && _noTextYet) {
|
|
_noTextYet = false;
|
|
drawInterface();
|
|
|
|
if (_talkTo != -1) {
|
|
Common::String fixedText_Exit = fixedText.getText(kFixedText_Window_Exit);
|
|
Common::String fixedText_Up = fixedText.getText(kFixedText_Window_Up);
|
|
Common::String fixedText_Down = fixedText.getText(kFixedText_Window_Down);
|
|
screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, false, fixedText_Exit);
|
|
screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, fixedText_Up);
|
|
screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, fixedText_Down);
|
|
}
|
|
}
|
|
|
|
// If it's the first line, display the speaker
|
|
if (!_line && _speaker >= 0 && _speaker < (int)people._characters.size()) {
|
|
// If the window is open, display the name directly on-screen.
|
|
// Otherwise, simply draw it on the back buffer
|
|
if (ui._windowOpen) {
|
|
screen.print(Common::Point(16, _yp), TALK_FOREGROUND, "%s",
|
|
people._characters[_speaker & 127]._name);
|
|
}
|
|
else {
|
|
screen.gPrint(Common::Point(16, _yp - 1), TALK_FOREGROUND, "%s",
|
|
people._characters[_speaker & 127]._name);
|
|
_openTalkWindow = true;
|
|
}
|
|
|
|
_yp += 9;
|
|
}
|
|
|
|
// Find amount of text that will fit on the line
|
|
int width = 0, idx = 0;
|
|
do {
|
|
width += screen.charWidth(str[idx]);
|
|
++idx;
|
|
++_charCount;
|
|
} while (width < 298 && str[idx] && str[idx] != '{' && (!isOpcode(str[idx])));
|
|
|
|
if (str[idx] || width >= 298) {
|
|
if ((!isOpcode(str[idx])) && str[idx] != '{') {
|
|
--idx;
|
|
--_charCount;
|
|
}
|
|
}
|
|
else {
|
|
_endStr = true;
|
|
}
|
|
|
|
// If word wrap is needed, find the start of the current word
|
|
if (width >= 298) {
|
|
while (str[idx] != ' ') {
|
|
--idx;
|
|
--_charCount;
|
|
}
|
|
}
|
|
|
|
// Print the line
|
|
Common::String lineStr((const char *)str, (const char *)str + idx);
|
|
|
|
// If the speaker indicates a description file, print it in yellow
|
|
if (_speaker != -1) {
|
|
if (ui._windowOpen) {
|
|
screen.print(Common::Point(16, _yp), COMMAND_FOREGROUND, "%s", lineStr.c_str());
|
|
}
|
|
else {
|
|
screen.gPrint(Common::Point(16, _yp - 1), COMMAND_FOREGROUND, "%s", lineStr.c_str());
|
|
_openTalkWindow = true;
|
|
}
|
|
}
|
|
else {
|
|
if (ui._windowOpen) {
|
|
screen.print(Common::Point(16, _yp), COMMAND_FOREGROUND, "%s", lineStr.c_str());
|
|
}
|
|
else {
|
|
screen.gPrint(Common::Point(16, _yp - 1), COMMAND_FOREGROUND, "%s", lineStr.c_str());
|
|
_openTalkWindow = true;
|
|
}
|
|
}
|
|
|
|
// Move to end of displayed line
|
|
str += idx;
|
|
|
|
// If line wrap occurred, then move to after the separating space between the words
|
|
if ((!isOpcode(str[0])) && str[0] != '{')
|
|
++str;
|
|
|
|
_yp += 9;
|
|
++_line;
|
|
|
|
// Certain different conditions require a wait
|
|
if ((_line == 4 && str < _scriptEnd && str[0] != _opcodes[OP_SFX_COMMAND] && str[0] != _opcodes[OP_PAUSE] && _speaker != -1) ||
|
|
(_line == 5 && str < _scriptEnd && str[0] != _opcodes[OP_PAUSE] && _speaker == -1) ||
|
|
_endStr) {
|
|
_wait = 1;
|
|
}
|
|
|
|
byte v = (str >= _scriptEnd ? 0 : str[0]);
|
|
if (v == _opcodes[OP_SWITCH_SPEAKER] || v == _opcodes[OP_ASSIGN_PORTRAIT_LOCATION] ||
|
|
v == _opcodes[OP_BANISH_WINDOW] || v == _opcodes[OP_IF_STATEMENT] ||
|
|
v == _opcodes[OP_ELSE_STATEMENT] || v == _opcodes[OP_END_IF_STATEMENT] ||
|
|
v == _opcodes[OP_GOTO_SCENE] || v == _opcodes[OP_CALL_TALK_FILE]) {
|
|
_wait = 1;
|
|
}
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdSwitchSpeaker(const byte *&str) {
|
|
ScalpelPeople &people = *(ScalpelPeople *)_vm->_people;
|
|
UserInterface &ui = *_vm->_ui;
|
|
|
|
if (!(_speaker & SPEAKER_REMOVE))
|
|
people.clearTalking();
|
|
if (_talkToAbort)
|
|
return RET_EXIT;
|
|
|
|
ui.clearWindow();
|
|
_yp = CONTROLS_Y + 12;
|
|
_charCount = _line = 0;
|
|
|
|
_speaker = *++str - 1;
|
|
people.setTalking(_speaker);
|
|
pullSequence();
|
|
pushSequence(_speaker);
|
|
people.setTalkSequence(_speaker);
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdGotoScene(const byte *&str) {
|
|
ScalpelMap &map = *(ScalpelMap *)_vm->_map;
|
|
People &people = *_vm->_people;
|
|
Scene &scene = *_vm->_scene;
|
|
scene._goToScene = str[1] - 1;
|
|
|
|
if (scene._goToScene != OVERHEAD_MAP) {
|
|
// Not going to the map overview
|
|
map._oldCharPoint = scene._goToScene;
|
|
map._overPos.x = (map[scene._goToScene].x - 6) * FIXED_INT_MULTIPLIER;
|
|
map._overPos.y = (map[scene._goToScene].y + 9) * FIXED_INT_MULTIPLIER;
|
|
|
|
// Run a canimation?
|
|
if (str[2] > 100) {
|
|
people._hSavedFacing = str[2];
|
|
people._hSavedPos = Point32(160, 100);
|
|
} else {
|
|
people._hSavedFacing = str[2] - 1;
|
|
int32 posX = (str[3] - 1) * 256 + str[4] - 1;
|
|
int32 posY = str[5] - 1;
|
|
people._hSavedPos = Point32(posX, posY);
|
|
}
|
|
} // if (scene._goToScene != 100)
|
|
|
|
str += 6;
|
|
|
|
_scriptMoreFlag = (scene._goToScene == 100) ? 2 : 1;
|
|
_scriptSaveIndex = str - _scriptStart;
|
|
_endStr = true;
|
|
_wait = 0;
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdAssignPortraitLocation(const byte *&str) {
|
|
People &people = *_vm->_people;
|
|
|
|
++str;
|
|
switch (str[0] & 15) {
|
|
case 1:
|
|
people._portraitSide = 20;
|
|
break;
|
|
case 2:
|
|
people._portraitSide = 220;
|
|
break;
|
|
case 3:
|
|
people._portraitSide = 120;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (str[0] > 15)
|
|
people._speakerFlip = true;
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdClearInfoLine(const byte *&str) {
|
|
UserInterface &ui = *_vm->_ui;
|
|
|
|
ui._infoFlag = true;
|
|
ui.clearInfo();
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdClearWindow(const byte *&str) {
|
|
UserInterface &ui = *_vm->_ui;
|
|
|
|
ui.clearWindow();
|
|
_yp = CONTROLS_Y + 12;
|
|
_charCount = _line = 0;
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdDisplayInfoLine(const byte *&str) {
|
|
Screen &screen = *_vm->_screen;
|
|
UserInterface &ui = *_vm->_ui;
|
|
Common::String tempString;
|
|
|
|
++str;
|
|
for (int idx = 0; idx < str[0]; ++idx)
|
|
tempString += str[idx + 1];
|
|
str += str[0];
|
|
|
|
screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", tempString.c_str());
|
|
ui._menuCounter = 30;
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdElse(const byte *&str) {
|
|
// If this is encountered here, it means that a preceeding IF statement was found,
|
|
// and evaluated to true. Now all the statements for the true block are finished,
|
|
// so skip over the block of code that would have executed if the result was false
|
|
_wait = 0;
|
|
do {
|
|
++str;
|
|
} while (str[0] && str[0] != _opcodes[OP_END_IF_STATEMENT]);
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdIf(const byte *&str) {
|
|
++str;
|
|
int flag = (str[0] - 1) * 256 + str[1] - 1 - (str[1] == 1 ? 1 : 0);
|
|
++str;
|
|
_wait = 0;
|
|
|
|
bool result = flag < 0x8000;
|
|
if (_vm->readFlags(flag & 0x7fff) != result) {
|
|
do {
|
|
++str;
|
|
} while (str[0] && str[0] != _opcodes[OP_ELSE_STATEMENT] && str[0] != _opcodes[OP_END_IF_STATEMENT]);
|
|
|
|
if (!str[0])
|
|
_endStr = true;
|
|
}
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdMoveMouse(const byte *&str) {
|
|
Events &events = *_vm->_events;
|
|
|
|
++str;
|
|
events.moveMouse(Common::Point((str[0] - 1) * 256 + str[1] - 1, str[2]));
|
|
if (_talkToAbort)
|
|
return RET_EXIT;
|
|
str += 3;
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdPlayPrologue(const byte *&str) {
|
|
Animation &anim = *_vm->_animation;
|
|
Common::String tempString;
|
|
|
|
++str;
|
|
for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx)
|
|
tempString += str[idx];
|
|
|
|
anim.play(tempString, false, 1, 3, true, 4);
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdRemovePortrait(const byte *&str) {
|
|
People &people = *_vm->_people;
|
|
|
|
if (_speaker >= 0 && _speaker < SPEAKER_REMOVE)
|
|
people.clearTalking();
|
|
pullSequence();
|
|
if (_talkToAbort)
|
|
return RET_EXIT;
|
|
|
|
_speaker |= SPEAKER_REMOVE;
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdWalkToCoords(const byte *&str) {
|
|
People &people = *_vm->_people;
|
|
++str;
|
|
|
|
people[HOLMES].walkToCoords(Point32(((str[0] - 1) * 256 + str[1] - 1) * FIXED_INT_MULTIPLIER,
|
|
str[2] * FIXED_INT_MULTIPLIER), str[3] - 1);
|
|
if (_talkToAbort)
|
|
return RET_EXIT;
|
|
|
|
str += 3;
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdSfxCommand(const byte *&str) {
|
|
Sound &sound = *_vm->_sound;
|
|
Common::String tempString;
|
|
|
|
++str;
|
|
if (sound._voices) {
|
|
for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx)
|
|
tempString += str[idx];
|
|
sound.playSound(tempString, WAIT_RETURN_IMMEDIATELY);
|
|
|
|
// Set voices to wait for more
|
|
sound._voices = 2;
|
|
sound._speechOn = (*sound._soundIsOn);
|
|
}
|
|
|
|
_wait = 1;
|
|
str += 7;
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdSummonWindow(const byte *&str) {
|
|
Events &events = *_vm->_events;
|
|
FixedText &fixedText = *_vm->_fixedText;
|
|
Screen &screen = *_vm->_screen;
|
|
|
|
drawInterface();
|
|
events._pressed = events._released = false;
|
|
events.clearKeyboard();
|
|
_noTextYet = false;
|
|
|
|
if (_speaker != -1) {
|
|
Common::String fixedText_Exit = fixedText.getText(kFixedText_Window_Exit);
|
|
Common::String fixedText_Up = fixedText.getText(kFixedText_Window_Up);
|
|
Common::String fixedText_Down = fixedText.getText(kFixedText_Window_Down);
|
|
screen.buttonPrint(Common::Point(119, CONTROLS_Y), COMMAND_NULL, false, fixedText_Exit);
|
|
screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, fixedText_Up);
|
|
screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, fixedText_Down);
|
|
}
|
|
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
OpcodeReturn ScalpelTalk::cmdCarriageReturn(const byte *&str) {
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
void ScalpelTalk::talkWait(const byte *&str) {
|
|
UserInterface &ui = *_vm->_ui;
|
|
bool pauseFlag = _pauseFlag;
|
|
|
|
Talk::talkWait(str);
|
|
|
|
// Clear the window unless the wait was due to a PAUSE command
|
|
if (!pauseFlag && _wait != -1 && str < _scriptEnd && str[0] != _opcodes[OP_SFX_COMMAND]) {
|
|
if (!_talkStealth)
|
|
ui.clearWindow();
|
|
_yp = CONTROLS_Y + 12;
|
|
_charCount = _line = 0;
|
|
}
|
|
}
|
|
|
|
void ScalpelTalk::talk3DOMovieTrigger(int subIndex) {
|
|
if (_vm->getPlatform() != Common::kPlatform3DO) {
|
|
// No 3DO? No movie!
|
|
return;
|
|
}
|
|
|
|
// Find out a few things that we need
|
|
int userSelector = _vm->_ui->_selector;
|
|
int scriptSelector = _scriptSelect;
|
|
int selector = 0;
|
|
int roomNr = _vm->_scene->_currentScene;
|
|
|
|
if (userSelector >= 0) {
|
|
// User-selected dialog
|
|
selector = userSelector;
|
|
} else {
|
|
if (scriptSelector >= 0) {
|
|
// Script-selected dialog
|
|
selector = scriptSelector;
|
|
subIndex--; // for scripts we adjust subIndex, b/c we won't get called from doTalkControl()
|
|
} else {
|
|
warning("talk3DOMovieTrigger: unable to find selector");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Make a quick update, so that current text is shown on screen
|
|
_vm->_screen->update();
|
|
|
|
// Figure out that movie filename
|
|
Common::String movieFilename;
|
|
|
|
movieFilename = _scriptName;
|
|
movieFilename.deleteChar(1); // remove 2nd character of scriptname
|
|
// cut scriptname to 6 characters
|
|
while (movieFilename.size() > 6) {
|
|
movieFilename.deleteChar(6);
|
|
}
|
|
|
|
movieFilename.insertChar(selector + 'a', movieFilename.size());
|
|
movieFilename.insertChar(subIndex + 'a', movieFilename.size());
|
|
movieFilename = Common::String::format("movies/%02d/%s.stream", roomNr, movieFilename.c_str());
|
|
|
|
warning("3DO movie player:");
|
|
warning("room: %d", roomNr);
|
|
warning("script: %s", _scriptName.c_str());
|
|
warning("selector: %d", selector);
|
|
warning("subindex: %d", subIndex);
|
|
|
|
Scalpel3DOMoviePlay(movieFilename.c_str(), Common::Point(5, 5));
|
|
|
|
// Restore screen HACK
|
|
_vm->_screen->makeAllDirty();
|
|
}
|
|
|
|
} // End of namespace Scalpel
|
|
|
|
} // End of namespace Sherlock
|