diff options
Diffstat (limited to 'engines/tsage/converse.cpp')
-rw-r--r-- | engines/tsage/converse.cpp | 119 |
1 files changed, 97 insertions, 22 deletions
diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp index de5ac62425..82feb314e6 100644 --- a/engines/tsage/converse.cpp +++ b/engines/tsage/converse.cpp @@ -416,7 +416,7 @@ SequenceManager *SequenceManager::globalManager() { ConversationChoiceDialog::ConversationChoiceDialog() { _stdColor = 23; _highlightColor = g_globals->_scenePalette._colors.background; - _fontNumber = 1; + _fontNumber = (g_vm->getGameID() == GType_Ringworld2) ? 3 : 1; _savedFgColor = _savedFontNumber = 0; _selectedIndex = 0; } @@ -424,15 +424,15 @@ ConversationChoiceDialog::ConversationChoiceDialog() { int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) { _gfxManager._font.setFontNumber(_fontNumber); - _bounds = Rect(20, 0, 20, 0); + _bounds = Rect(40, 0, 40, 0); _choiceList.clear(); // Set up the list of choices int yp = 0; for (uint idx = 0; idx < choiceList.size(); ++idx) { Rect tempRect; - _gfxManager._font.getStringBounds(choiceList[idx].c_str(), tempRect, 265); - tempRect.moveTo(25, yp + 10); + _gfxManager._font.getStringBounds(choiceList[idx].c_str(), tempRect, textMaxWidth()); + tempRect.moveTo(textLeft(), yp + 10); _choiceList.push_back(ChoiceEntry(choiceList[idx], tempRect)); yp += tempRect.height() + 5; @@ -444,7 +444,8 @@ int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) { _bounds.bottom -= 10; yp = 180 - _bounds.height(); _bounds.translate(0, yp); - _bounds.right = _bounds.left + 280; + _bounds.setWidth(textMaxWidth() + 15); + _bounds.moveTo(160 - (_bounds.width() / 2), _bounds.top); // Draw the dialog draw(); @@ -513,6 +514,7 @@ void ConversationChoiceDialog::draw() { // Fill in the contents of the entire dialog _gfxManager._bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + drawFrame(); _gfxManager._bounds = tempRect; @@ -524,7 +526,7 @@ void ConversationChoiceDialog::draw() { Common::String strNum = Common::String::format("%d", idx + 1); // Write the choice number - _gfxManager._font.setPosition(13, _choiceList[idx]._bounds.top); + _gfxManager._font.setPosition(numberLeft(), _choiceList[idx]._bounds.top); _gfxManager._font.writeString(strNum.c_str()); _gfxManager._font.writeLines(_choiceList[idx]._msg.c_str(), _choiceList[idx]._bounds, ALIGN_LEFT); @@ -533,6 +535,18 @@ void ConversationChoiceDialog::draw() { _gfxManager.deactivate(); } +int ConversationChoiceDialog::textLeft() const { + return (g_vm->getGameID() == GType_Ringworld2) ? 20 : 25; +} + +int ConversationChoiceDialog::textMaxWidth() const { + return (g_vm->getGameID() == GType_Ringworld2) ? 250 : 265; +} + +int ConversationChoiceDialog::numberLeft() const { + return (g_vm->getGameID() == GType_Ringworld2) ? 8 : 13; +} + /*--------------------------------------------------------------------------*/ void Obj44::load(const byte *dataP) { @@ -543,7 +557,7 @@ void Obj44::load(const byte *dataP) { _lookupValue = s.readSint16LE(); _lookupIndex = s.readSint16LE(); _field6 = s.readSint16LE(); - _field8 = s.readSint16LE(); + _speakerMode = s.readSint16LE(); } _id = s.readSint16LE(); @@ -551,8 +565,8 @@ void Obj44::load(const byte *dataP) { _callbackId[idx] = s.readSint16LE(); if (g_vm->getGameID() == GType_Ringworld2) { - _field16 = s.readSint16LE(); - s.skip(20); + for (int i = 0; i < 11; ++i) + _field16[i] = s.readSint16LE(); } else { s.skip(4); } @@ -579,8 +593,10 @@ void Obj44::synchronize(Serializer &s) { s.syncAsSint16LE(_lookupValue); s.syncAsSint16LE(_lookupIndex); s.syncAsSint16LE(_field6); - s.syncAsSint16LE(_field8); - s.syncAsSint16LE(_field16); + s.syncAsSint16LE(_speakerMode); + + for (int i = 0; i < 11; ++i) + s.syncAsSint16LE(_field16[i]); } } @@ -787,25 +803,65 @@ void StripManager::signal() { // Build up a list of script entries int idx; - if (g_vm->getGameID() == GType_Ringworld2 && obj44._field16) { + if ((g_vm->getGameID() == GType_Ringworld2) && obj44._field16[0]) { // Special loading mode used in Return to Ringworld for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) { - int objIndex = _lookupList[obj44._field16 - 1]; - - if (!obj44._list[objIndex]._id) + int f16Index = _lookupList[obj44._field16[0] - 1]; + Obj0A &entry = obj44._list[obj44._field16[f16Index]]; + if (!entry._id) break; // Get the next one - choiceList.push_back((const char *)&_script[0] + obj44._list[objIndex]._scriptOffset); + choiceList.push_back((const char *)&_script[0] + entry._scriptOffset); } } else { // Standard choices loading - for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) { + for (idx = 0; idx < OBJ0A_LIST_SIZE; ++idx) { if (!obj44._list[idx]._id) break; // Get the next one - choiceList.push_back((const char *)&_script[0] + obj44._list[idx]._scriptOffset); + const char *choiceStr = (const char *)&_script[0] + obj44._list[idx]._scriptOffset; + + if (!*choiceStr) { + // Choice is empty + assert(g_vm->getGameID() == GType_Ringworld2); + + if (obj44._list[1]._id) { + // it's a reference to another list slot + int listId = obj44._list[idx]._id; + + int obj44Idx = 0; + while (_obj44List[obj44Idx]._id != listId) + ++obj44Idx; + + if (_obj44List[obj44Idx]._field16[0]) { + int f16Index = _lookupList[_obj44List[obj44Idx]._field16[0] - 1]; + listId = _obj44List[obj44Idx]._field16[f16Index]; + + if (_lookupList[_obj44List[obj44Idx]._field16[0] - 1]) { + int listIdx = 0; + while (_obj44List[obj44Idx]._list[listIdx]._id != listId) + ++listIdx; + + choiceStr = (const char *)&_script[0] + _obj44List[obj44Idx]._list[listIdx]._scriptOffset; + } else { + for (int listIdx = 0; listIdx < OBJ0A_LIST_SIZE; ++listIdx) { + obj44._list[listIdx]._id = obj44._list[listIdx + 1]._id; + obj44._list[listIdx]._scriptOffset = obj44._list[listIdx + 1]._scriptOffset; + + if (!obj44._list[listIdx + 1]._id) + obj44._list[listIdx]._id = 0; + } + + continue; + } + } + } + } + + // Add entry to the list + choiceList.push_back(choiceStr); } } @@ -843,11 +899,28 @@ void StripManager::signal() { } } - if ((g_vm->getGameID() == GType_Ringworld2) && (_obj44List.size() > 0)) - static_cast<Ringworld2::VisualSpeaker *>(_activeSpeaker)->proc15(); + if (g_vm->getGameID() == GType_Ringworld2) { + Ringworld2::VisualSpeaker *speaker = static_cast<Ringworld2::VisualSpeaker *>(_activeSpeaker); + + if (speaker) { + speaker->_speakerMode = obj44._speakerMode; + if (choiceList[strIndex].empty()) + speaker->proc15(); + } - _textShown = true; - _activeSpeaker->setText(choiceList[strIndex]); + if (!choiceList[strIndex].empty()) { + _textShown = true; + _activeSpeaker->setText(choiceList[strIndex]); + } else if (!obj44._speakerMode) { + _delayFrames = 1; + } else { + _delayFrames = 0; + speaker->proc15(); + } + } else { + _textShown = true; + _activeSpeaker->setText(choiceList[strIndex]); + } } _obj44Index = getNewIndex(obj44._list[strIndex]._id); @@ -915,6 +988,8 @@ Speaker *StripManager::getSpeaker(const char *speakerName) { int StripManager::getNewIndex(int id) { if (id == 10000) return id; + if ((g_vm->getGameID() == GType_Ringworld2) && (id < 0)) + return id; for (uint idx = 0; idx < _obj44List.size(); ++idx) { if (_obj44List[idx]._id == id) { |