mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 06:08:35 +00:00
258 lines
11 KiB
C++
258 lines
11 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.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* Based on the Reverse Engineering work of Christophe Fontanel,
|
|
* maintainer of the Dungeon Master Encyclopaedia (http://dmweb.free.fr/)
|
|
*/
|
|
|
|
#include "dm/dialog.h"
|
|
#include "dm/gfx.h"
|
|
#include "dm/text.h"
|
|
#include "dm/eventman.h"
|
|
|
|
namespace DM {
|
|
|
|
DialogMan::DialogMan(DMEngine *vm) : _vm(vm) {
|
|
_selectedDialogChoice = 0;
|
|
}
|
|
|
|
void DialogMan::dialogDraw(const char *msg1, const char *msg2, const char *choice1, const char *choice2, const char *choice3, const char *choice4, bool screenDialog, bool clearScreen, bool fading) {
|
|
static Box constBox1 = Box(0, 223, 101, 125);
|
|
static Box constBox2 = Box(0, 223, 76, 100);
|
|
static Box constBox3 = Box(0, 223, 51, 75);
|
|
static Box dialog2ChoicesPatch = Box(102, 122, 89, 125);
|
|
static Box dialog4ChoicesPatch = Box(102, 122, 62, 97);
|
|
|
|
_vm->_displayMan->loadIntoBitmap(k0_dialogBoxGraphicIndice, _vm->_displayMan->_bitmapViewport);
|
|
//Strangerke: the version should be replaced by a ScummVM/RogueVM (?) string
|
|
// TODO: replace with ScummVM version string
|
|
_vm->_textMan->printTextToBitmap(_vm->_displayMan->_bitmapViewport, k112_byteWidthViewport, 192, 7, k2_ColorLightGray, k1_ColorDarkGary, "V2.2", k136_heightViewport);
|
|
int16 choiceCount = 1;
|
|
if (choice2)
|
|
choiceCount++;
|
|
|
|
if (choice3)
|
|
choiceCount++;
|
|
|
|
if (choice4)
|
|
choiceCount++;
|
|
|
|
if (fading)
|
|
_vm->_displayMan->startEndFadeToPalette(_vm->_displayMan->_blankBuffer);
|
|
|
|
if (clearScreen)
|
|
_vm->_displayMan->fillScreen(k0_ColorBlack);
|
|
|
|
_vm->_displayMan->_useByteBoxCoordinates = false;
|
|
if (choiceCount == 1) {
|
|
_vm->_displayMan->blitToBitmap(_vm->_displayMan->_bitmapViewport, _vm->_displayMan->_bitmapViewport, constBox1, 0, 64, k112_byteWidthViewport, k112_byteWidthViewport, kM1_ColorNoTransparency, k136_heightViewport, k136_heightViewport);
|
|
_vm->_displayMan->blitToBitmap(_vm->_displayMan->_bitmapViewport, _vm->_displayMan->_bitmapViewport, constBox2, 0, 39, k112_byteWidthViewport, k112_byteWidthViewport, kM1_ColorNoTransparency, k136_heightViewport, k136_heightViewport);
|
|
_vm->_displayMan->blitToBitmap(_vm->_displayMan->_bitmapViewport, _vm->_displayMan->_bitmapViewport, constBox3, 0, 14, k112_byteWidthViewport, k112_byteWidthViewport, kM1_ColorNoTransparency, k136_heightViewport, k136_heightViewport);
|
|
printCenteredChoice(_vm->_displayMan->_bitmapViewport, choice1, 112, 114);
|
|
} else if (choiceCount == 2) {
|
|
_vm->_displayMan->blitToBitmap(_vm->_displayMan->_bitmapViewport, _vm->_displayMan->_bitmapViewport, dialog2ChoicesPatch, 102, 52, k112_byteWidthViewport, k112_byteWidthViewport, kM1_ColorNoTransparency, k136_heightViewport, k136_heightViewport);
|
|
printCenteredChoice(_vm->_displayMan->_bitmapViewport, choice1, 112, 77);
|
|
printCenteredChoice(_vm->_displayMan->_bitmapViewport, choice2, 112, 114);
|
|
} else if (choiceCount == 3) {
|
|
printCenteredChoice(_vm->_displayMan->_bitmapViewport, choice1, 112, 77);
|
|
printCenteredChoice(_vm->_displayMan->_bitmapViewport, choice2, 59, 114);
|
|
printCenteredChoice(_vm->_displayMan->_bitmapViewport, choice3, 166, 114);
|
|
} else if (choiceCount == 4) {
|
|
_vm->_displayMan->blitToBitmap(_vm->_displayMan->_bitmapViewport, _vm->_displayMan->_bitmapViewport, dialog4ChoicesPatch, 102, 99, k112_byteWidthViewport, k112_byteWidthViewport, kM1_ColorNoTransparency, k136_heightViewport, k136_heightViewport);
|
|
printCenteredChoice(_vm->_displayMan->_bitmapViewport, choice1, 59, 77);
|
|
printCenteredChoice(_vm->_displayMan->_bitmapViewport, choice2, 166, 77);
|
|
printCenteredChoice(_vm->_displayMan->_bitmapViewport, choice3, 59, 114);
|
|
printCenteredChoice(_vm->_displayMan->_bitmapViewport, choice4, 166, 114);
|
|
}
|
|
|
|
int16 textPosX;
|
|
int16 textPosY = 29;
|
|
if (msg1) {
|
|
char L1312_ac_StringPart1[70];
|
|
char L1313_ac_StringPart2[70];
|
|
if (isMessageOnTwoLines(msg1, L1312_ac_StringPart1, L1313_ac_StringPart2)) {
|
|
textPosY = 21;
|
|
textPosX = 113 - ((strlen(L1312_ac_StringPart1) * 6) >> 1);
|
|
_vm->_textMan->printTextToBitmap(_vm->_displayMan->_bitmapViewport, k112_byteWidthViewport, textPosX, textPosY, k11_ColorYellow, k5_ColorLightBrown, L1312_ac_StringPart1, k136_heightViewport);
|
|
textPosY += 8;
|
|
textPosX = 113 - ((strlen(L1313_ac_StringPart2) * 6) >> 1);
|
|
_vm->_textMan->printTextToBitmap(_vm->_displayMan->_bitmapViewport, k112_byteWidthViewport, textPosX, textPosY, k11_ColorYellow, k5_ColorLightBrown, L1313_ac_StringPart2, k136_heightViewport);
|
|
textPosY += 8;
|
|
} else {
|
|
textPosX = 113 - ((strlen(msg1) * 6) >> 1);
|
|
_vm->_textMan->printTextToBitmap(_vm->_displayMan->_bitmapViewport, k112_byteWidthViewport, textPosX, textPosY, k11_ColorYellow, k5_ColorLightBrown, msg1, k136_heightViewport);
|
|
textPosY += 8;
|
|
}
|
|
}
|
|
if (msg2) {
|
|
char L1312_ac_StringPart1[70];
|
|
char L1313_ac_StringPart2[70];
|
|
if (isMessageOnTwoLines(msg2, L1312_ac_StringPart1, L1313_ac_StringPart2)) {
|
|
textPosX = 113 - ((strlen(L1312_ac_StringPart1) * 6) >> 1);
|
|
_vm->_textMan->printTextToBitmap(_vm->_displayMan->_bitmapViewport, k112_byteWidthViewport, textPosX, textPosY, k9_ColorGold, k5_ColorLightBrown, L1312_ac_StringPart1, k136_heightViewport);
|
|
textPosY += 8;
|
|
textPosX = 113 - ((strlen(L1313_ac_StringPart2) * 6) >> 1);
|
|
_vm->_textMan->printTextToBitmap(_vm->_displayMan->_bitmapViewport, k112_byteWidthViewport, textPosX, textPosY, k9_ColorGold, k5_ColorLightBrown, L1313_ac_StringPart2, k136_heightViewport);
|
|
} else {
|
|
textPosX = 113 - ((strlen(msg2) * 6) >> 1);
|
|
_vm->_textMan->printTextToBitmap(_vm->_displayMan->_bitmapViewport, k112_byteWidthViewport, textPosX, textPosY, k9_ColorGold, k5_ColorLightBrown, msg2, k136_heightViewport);
|
|
}
|
|
}
|
|
if (screenDialog) {
|
|
Box displayBox;
|
|
displayBox._y1 = 33;
|
|
displayBox._y2 = 168;
|
|
displayBox._x1 = 47;
|
|
displayBox._x2 = 270;
|
|
_vm->_eventMan->showMouse();
|
|
_vm->_displayMan->blitToScreen(_vm->_displayMan->_bitmapViewport, &displayBox, k112_byteWidthViewport, kM1_ColorNoTransparency, k136_heightViewport);
|
|
_vm->_eventMan->hideMouse();
|
|
} else {
|
|
_vm->_displayMan->drawViewport(k0_viewportNotDungeonView);
|
|
_vm->delay(1);
|
|
}
|
|
|
|
if (fading)
|
|
_vm->_displayMan->startEndFadeToPalette(_vm->_displayMan->_paletteTopAndBottomScreen);
|
|
|
|
_vm->_displayMan->_drawFloorAndCeilingRequested = true;
|
|
_vm->_displayMan->updateScreen();
|
|
}
|
|
|
|
void DialogMan::printCenteredChoice(byte *bitmap, const char *str, int16 posX, int16 posY) {
|
|
if (str) {
|
|
posX -= (strlen(str) * 6) >> 1;
|
|
_vm->_textMan->printTextToBitmap(bitmap, k112_byteWidthViewport, posX, posY, k9_ColorGold, k5_ColorLightBrown, str, k136_heightViewport);
|
|
}
|
|
}
|
|
|
|
bool DialogMan::isMessageOnTwoLines(const char *str, char *part1, char *part2) {
|
|
uint16 strLength = strlen(str);
|
|
if (strLength <= 30)
|
|
return false;
|
|
|
|
strcpy(part1, str);
|
|
uint16 splitPosition = strLength >> 1;
|
|
while ((splitPosition < strLength) && (part1[splitPosition] != ' '))
|
|
splitPosition++;
|
|
|
|
part1[splitPosition] = '\0';
|
|
strcpy(part2, &part1[splitPosition + 1]);
|
|
return true;
|
|
}
|
|
|
|
int16 DialogMan::getChoice(uint16 choiceCount, uint16 dialogSetIndex, int16 driveType, int16 automaticChoiceIfFlopyInDrive) {
|
|
_vm->_eventMan->hideMouse();
|
|
MouseInput *primaryMouseInputBackup = _vm->_eventMan->_primaryMouseInput;
|
|
MouseInput *secondaryMouseInputBackup = _vm->_eventMan->_secondaryMouseInput;
|
|
KeyboardInput *primaryKeyboardInputBackup = _vm->_eventMan->_primaryKeyboardInput;
|
|
KeyboardInput *secondaryKeyboardInputBackup = _vm->_eventMan->_secondaryKeyboardInput;
|
|
_vm->_eventMan->_secondaryMouseInput = nullptr;
|
|
_vm->_eventMan->_primaryKeyboardInput = nullptr;
|
|
_vm->_eventMan->_secondaryKeyboardInput = nullptr;
|
|
_vm->_eventMan->_primaryMouseInput = _vm->_eventMan->_primaryMouseInputDialogSets[dialogSetIndex][choiceCount - 1];
|
|
_vm->_eventMan->discardAllInput();
|
|
_selectedDialogChoice = 99;
|
|
do {
|
|
Common::Event key;
|
|
Common::EventType eventType = _vm->_eventMan->processInput(&key);
|
|
_vm->_eventMan->processCommandQueue();
|
|
_vm->delay(1);
|
|
_vm->_displayMan->updateScreen();
|
|
if ((_selectedDialogChoice == 99) && (choiceCount == 1)
|
|
&& (eventType != Common::EVENT_INVALID) && key.kbd.keycode == Common::KEYCODE_RETURN) {
|
|
/* If a choice has not been made yet with the mouse and the dialog has only one possible choice and carriage return was pressed on the keyboard */
|
|
_selectedDialogChoice = kDMDialogChoice1;
|
|
}
|
|
} while (_selectedDialogChoice == 99);
|
|
_vm->_displayMan->_useByteBoxCoordinates = false;
|
|
Box boxA = _vm->_eventMan->_primaryMouseInput[_selectedDialogChoice - 1]._hitbox;
|
|
boxA._x1 -= 3;
|
|
boxA._x2 += 3;
|
|
boxA._y1 -= 3;
|
|
boxA._y2 += 4;
|
|
_vm->_eventMan->showMouse();
|
|
_vm->_displayMan->_drawFloorAndCeilingRequested = true;
|
|
Box boxB(0, 0, boxA._x2 - boxA._x1 + 3, boxA._y2 - boxA._y1 + 3);
|
|
_vm->_displayMan->blitToBitmap(_vm->_displayMan->_bitmapScreen, _vm->_displayMan->_bitmapViewport,
|
|
boxB, boxA._x1, boxA._y1, k160_byteWidthScreen, k160_byteWidthScreen, kM1_ColorNoTransparency, 200, 25);
|
|
_vm->delay(1);
|
|
boxB = boxA;
|
|
boxB._y2 = boxB._y1;
|
|
_vm->_displayMan->fillScreenBox(boxB, k5_ColorLightBrown);
|
|
boxB = boxA;
|
|
boxB._x2 = boxB._x1;
|
|
boxB._y2--;
|
|
_vm->_displayMan->fillScreenBox(boxB, k5_ColorLightBrown);
|
|
boxB = boxA;
|
|
boxB._y2--;
|
|
boxB._y1 = boxB._y2;
|
|
boxB._x1 -= 2;
|
|
_vm->_displayMan->fillScreenBox(boxB, k0_ColorBlack);
|
|
boxB = boxA;
|
|
boxB._x1 = boxB._x2;
|
|
_vm->_displayMan->fillScreenBox(boxB, k0_ColorBlack);
|
|
_vm->delay(2);
|
|
boxB = boxA;
|
|
boxB._y1++;
|
|
boxB._y2 = boxB._y1;
|
|
boxB._x2 -= 2;
|
|
_vm->_displayMan->fillScreenBox(boxB, k5_ColorLightBrown);
|
|
boxB = boxA;
|
|
boxB._x1++;
|
|
boxB._x2 = boxB._x1;
|
|
boxB._y2--;
|
|
_vm->_displayMan->fillScreenBox(boxB, k5_ColorLightBrown);
|
|
boxB = boxA;
|
|
boxB._x2--;
|
|
boxB._x1 = boxB._x2;
|
|
_vm->_displayMan->fillScreenBox(boxB, k0_ColorBlack);
|
|
boxB = boxA;
|
|
boxB._y1 = boxB._y2 = boxB._y2 - 2;
|
|
boxB._x1++;
|
|
_vm->_displayMan->fillScreenBox(boxB, k0_ColorBlack);
|
|
boxB = boxA;
|
|
boxB._y1 = boxB._y2 = boxB._y2 + 2;
|
|
boxB._x1--;
|
|
boxB._x2 += 2;
|
|
_vm->_displayMan->fillScreenBox(boxB, k13_ColorLightestGray);
|
|
boxB = boxA;
|
|
boxB._x1 = boxB._x2 = boxB._x2 + 3;
|
|
boxB._y2 += 2;
|
|
_vm->_displayMan->fillScreenBox(boxB, k13_ColorLightestGray);
|
|
_vm->delay(2);
|
|
boxA._x2 += 3;
|
|
boxA._y2 += 3;
|
|
_vm->_displayMan->blitToBitmap(_vm->_displayMan->_bitmapViewport, _vm->_displayMan->_bitmapScreen,
|
|
boxA, 0, 0, k160_byteWidthScreen, k160_byteWidthScreen, kM1_ColorNoTransparency, 25, k200_heightScreen);
|
|
_vm->_eventMan->hideMouse();
|
|
_vm->_eventMan->_primaryMouseInput = primaryMouseInputBackup;
|
|
_vm->_eventMan->_secondaryMouseInput = secondaryMouseInputBackup;
|
|
_vm->_eventMan->_primaryKeyboardInput = primaryKeyboardInputBackup;
|
|
_vm->_eventMan->_secondaryKeyboardInput = secondaryKeyboardInputBackup;
|
|
_vm->_eventMan->discardAllInput();
|
|
_vm->_eventMan->showMouse();
|
|
return _selectedDialogChoice;
|
|
}
|
|
}
|