mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-13 21:31:53 +00:00
Further implementation of dialog/message script language
svn-id: r46418
This commit is contained in:
parent
ae50fdca72
commit
63350a0ecc
@ -364,13 +364,15 @@ bool Console::cmdMessage(int argc, const char **argv) {
|
||||
if (argc == 1)
|
||||
DebugPrintf("message 'objnum'\n");
|
||||
else {
|
||||
int messageId = strToInt(argv[1]);
|
||||
int idx = _vm->_globals->messageIndexOf(messageId);
|
||||
if (idx == -1)
|
||||
int messageIdx = strToInt(argv[1]);
|
||||
if ((argc == 3) && !strcmp(argv[2], "id"))
|
||||
messageIdx = _vm->_globals->messageIndexOf(messageIdx);
|
||||
|
||||
if (messageIdx == -1)
|
||||
DebugPrintf("Unknown message");
|
||||
else
|
||||
{
|
||||
const char *msg = _vm->_globals->loadMessage(idx);
|
||||
const char *msg = _vm->_globals->loadMessage(messageIdx);
|
||||
Dialog *dlg = new Dialog(_vm, msg, "TEST DIALOG");
|
||||
|
||||
_vm->_viewManager->addView(dlg);
|
||||
|
@ -35,6 +35,13 @@ static void strToUpper(char *s) {
|
||||
}
|
||||
}
|
||||
|
||||
static void strToLower(char *s) {
|
||||
while (*s) {
|
||||
*s = tolower(*s);
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
const RGB8 DIALOG_PALETTE[8] = {
|
||||
{0x80, 0x80, 0x80, 0xff}, {0x90, 0x90, 0x90, 0xff}, {0x70, 0x70, 0x70, 0xff}, {0x9c, 0x9c, 0x9c, 0xff},
|
||||
{0x80, 0x80, 0x80, 0xff}, {0x90, 0x90, 0x90, 0xff}, {0xDC, 0xDC, 0xDC, 0xff}, {0x00, 0x00, 0x00, 0xff}
|
||||
@ -44,10 +51,16 @@ const RGB8 DIALOG_PALETTE[8] = {
|
||||
|
||||
const int DIALOG_SPACING = 1;
|
||||
|
||||
/**
|
||||
* Handles any dialog initialisation
|
||||
*/
|
||||
void Dialog::initDialog() {
|
||||
incLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new line to the dialog output
|
||||
*/
|
||||
void Dialog::incLine() {
|
||||
_lineX = 0;
|
||||
_widthX = 0;
|
||||
@ -56,6 +69,10 @@ void Dialog::incLine() {
|
||||
assert(_lines.size() <= 20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes some text to the dialog output, taking care of word wrapping if the text size
|
||||
* exceeds the dialog's width
|
||||
*/
|
||||
void Dialog::writeChars(const char *srcLine) {
|
||||
char wordStr[80];
|
||||
char line[80];
|
||||
@ -124,6 +141,9 @@ void Dialog::writeChars(const char *srcLine) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends some text to the current dialog line
|
||||
*/
|
||||
void Dialog::appendText(const char *line) {
|
||||
_lineX += strlen(line);
|
||||
_widthX += _vm->_font->getWidth(line, DIALOG_SPACING);
|
||||
@ -131,6 +151,9 @@ void Dialog::appendText(const char *line) {
|
||||
strcat(_lines[_lines.size() - 1].data, line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a line of text to the dialog lines list
|
||||
*/
|
||||
void Dialog::addLine(const char *line, bool underlineP) {
|
||||
if ((_widthX > 0) || (_lineX > 0))
|
||||
incLine();
|
||||
@ -141,7 +164,7 @@ void Dialog::addLine(const char *line, bool underlineP) {
|
||||
if ((lineWidth > _dialogWidth) || (lineLen >= _widthChars))
|
||||
writeChars(line);
|
||||
else {
|
||||
_lines[_lines.size() - 1].xp = (_dialogWidth - lineWidth) / 2;
|
||||
_lines[_lines.size() - 1].xp = (_dialogWidth - 10 - lineWidth) / 2;
|
||||
strcpy(_lines[_lines.size() - 1].data, line);
|
||||
}
|
||||
|
||||
@ -151,12 +174,97 @@ void Dialog::addLine(const char *line, bool underlineP) {
|
||||
incLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a bar separation line to the dialog lines list
|
||||
*/
|
||||
void Dialog::addBarLine() {
|
||||
if ((_widthX > 0) || (_lineX > 0))
|
||||
incLine();
|
||||
|
||||
// Flag the line as being a bar separator
|
||||
_lines[_lines.size() - 1].barLine = true;
|
||||
incLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a specified vocab entry
|
||||
*/
|
||||
void Dialog::getVocab(int vocabId, char **line) {
|
||||
assert(vocabId > 0);
|
||||
const char *vocabStr = _vm->_globals->getVocab(vocabId);
|
||||
strcpy(*line, vocabStr);
|
||||
|
||||
if (_commandCase)
|
||||
strToUpper(*line);
|
||||
else
|
||||
strToLower(*line);
|
||||
|
||||
// Move the string pointer to after the added string
|
||||
while (!**line)
|
||||
++*line;
|
||||
}
|
||||
|
||||
bool Dialog::handleNounSuffix(char *destP, int nounNum, const char *srcP) {
|
||||
char srcLine[40];
|
||||
|
||||
// The next source character must be a colon in front of the first verb
|
||||
if (*srcP != ':')
|
||||
return false;
|
||||
|
||||
// Copy the remainder of the line into a temporary buffer to get the seperate verbs
|
||||
strcpy(srcLine, ++srcP);
|
||||
char *altP = strchr(srcLine, ':');
|
||||
if (altP)
|
||||
*altP = '\0';
|
||||
|
||||
if (*srcP != '\0') {
|
||||
while (*srcP != ':') {
|
||||
++srcP;
|
||||
if (!*srcP) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*srcP != '\0')
|
||||
++srcP;
|
||||
|
||||
//
|
||||
char var_FC[40];
|
||||
char tempLine[40];
|
||||
strcpy(var_FC, srcP);
|
||||
char *tmpP = &tempLine[0];
|
||||
char *tmp2P = tmpP;
|
||||
|
||||
uint16 _vocabIds[2] = {1, 1}; // FIXME/TODO: Proper vocab ids
|
||||
getVocab(_vocabIds[nounNum], &tmpP);
|
||||
|
||||
if ((*(tmpP - 1) != 'S') && (*(tmpP - 1) != 's')) {
|
||||
// Singular object
|
||||
tmpP = &var_FC[0];
|
||||
} else if (!strcmp(tempLine, "a ")) {
|
||||
// Pontially plural
|
||||
char ch = tolower(*tmp2P);
|
||||
|
||||
if (!((ch > 'U') || ((ch != 'A') && (ch != 'E') && (ch != 'I') && (ch != 'O'))))
|
||||
strcpy(tempLine, "an ");
|
||||
}
|
||||
|
||||
strcpy(destP, tmpP);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the start of an extracted command matches a specified given command constant
|
||||
*/
|
||||
bool Dialog::matchCommand(const char *s1, const char *s2) {
|
||||
return strncmp(s1, s2, strlen(s2)) == 0;
|
||||
bool result = scumm_strnicmp(s1, s2, strlen(s2)) == 0;
|
||||
_commandCase = isupper(*s1);
|
||||
return result;
|
||||
}
|
||||
|
||||
Dialog::Dialog(M4Engine *vm, const char *msgData, const char *title): View(vm, Common::Rect(0, 0, 0, 0)) {
|
||||
assert(msgData);
|
||||
_vm->_font->setFont(FONT_INTERFACE_MADS);
|
||||
|
||||
const char *srcP = msgData;
|
||||
bool skipLine = false;
|
||||
bool initFlag = false;
|
||||
@ -172,6 +280,7 @@ Dialog::Dialog(M4Engine *vm, const char *msgData, const char *title): View(vm, C
|
||||
_lineX = 0;
|
||||
_widthX = 0;
|
||||
_dialogWidth = 0;
|
||||
_commandCase = false;
|
||||
|
||||
char dialogLine[256];
|
||||
char cmdText[80];
|
||||
@ -226,7 +335,7 @@ Dialog::Dialog(M4Engine *vm, const char *msgData, const char *title): View(vm, C
|
||||
if (id > 0) {
|
||||
// Suffix provided - specifies the dialog width in number of chars
|
||||
_widthChars = id * 2;
|
||||
_dialogWidth = id * (_vm->_font->getMaxWidth() + 1) + 10;
|
||||
_dialogWidth = id * (_vm->_font->getMaxWidth() + DIALOG_SPACING) + 10;
|
||||
}
|
||||
} else if (matchCommand(cmdText, "SENTENCE")) {
|
||||
// Sentence command - loads the title into the line buffer
|
||||
@ -234,31 +343,45 @@ Dialog::Dialog(M4Engine *vm, const char *msgData, const char *title): View(vm, C
|
||||
strToUpper(dialogLine);
|
||||
lineP += strlen(dialogLine) + 1;
|
||||
|
||||
} else if (matchCommand(cmdText, "BAR")) {
|
||||
// Adds a full-width line instead of normal text
|
||||
addBarLine();
|
||||
|
||||
} else if (matchCommand(cmdText, "CENTER")) {
|
||||
// Center command
|
||||
skipLine = true;
|
||||
|
||||
} else if (matchCommand(cmdText, "CR")) {
|
||||
// CR command
|
||||
if (skipLine)
|
||||
crFlag = true;
|
||||
else {
|
||||
else if (!initFlag) {
|
||||
initDialog();
|
||||
initFlag = true;
|
||||
}
|
||||
|
||||
} else if (matchCommand(cmdText, "NOUN1")) {
|
||||
// Noun command 1
|
||||
handleNounSuffix(lineP, 1, cmdText + 5);
|
||||
|
||||
} else if (matchCommand(cmdText, "NOUN1")) {
|
||||
// Noun command 2
|
||||
handleNounSuffix(lineP, 2, cmdText + 5);
|
||||
|
||||
} else if (matchCommand(cmdText, "VERB")) {
|
||||
// Verb/vocab retrieval
|
||||
int verbId = 1; // TODO: Get correct vocab
|
||||
getVocab(verbId, &lineP);
|
||||
|
||||
} else if (matchCommand(cmdText, "UNDER")) {
|
||||
// Underline command
|
||||
underline = true;
|
||||
|
||||
} else if (matchCommand(cmdText, "ASK")) {
|
||||
// doAsk();
|
||||
} else if (matchCommand(cmdText, "CENTER")) {
|
||||
// Center command
|
||||
skipLine = true;
|
||||
} else if (matchCommand(cmdText, "VERB")) {
|
||||
// Verb/vocab retrieval
|
||||
/*getVocab(); */
|
||||
} else if (matchCommand(cmdText, "INDEX")) {
|
||||
// Index command
|
||||
_dialogIndex = atoi(cmdText + 5);
|
||||
} else if (matchCommand(cmdText, "NOUN")) {
|
||||
// Noun command
|
||||
} else {
|
||||
error("Unknown dialog command '%s' encountered", cmdText);
|
||||
}
|
||||
@ -279,19 +402,13 @@ Dialog::~Dialog() {
|
||||
}
|
||||
|
||||
void Dialog::draw() {
|
||||
_vm->_font->setFont(FONT_INTERFACE_MADS);
|
||||
assert(_widthChars != 0);
|
||||
|
||||
// Set up the palette for this view
|
||||
_palette = new RGBList(8, NULL);
|
||||
_palette->setRange(0, 8, DIALOG_PALETTE);
|
||||
_vm->_palette->addRange(_palette);
|
||||
|
||||
// Validation
|
||||
if (_widthChars == 0) {
|
||||
warning("Dialog being shown without TITLE specified");
|
||||
_widthChars = 30;
|
||||
}
|
||||
|
||||
// Calculate bounds
|
||||
int dlgWidth = _dialogWidth;
|
||||
int dlgHeight = _lines.size() * (_vm->_font->getHeight() + 1) + 10;
|
||||
@ -338,10 +455,12 @@ void Dialog::draw() {
|
||||
|
||||
for (uint lineCtr = 0, yp = 5; lineCtr < _lines.size(); ++lineCtr, yp += _vm->_font->getHeight() + 1) {
|
||||
|
||||
if (_lines[lineCtr].xp == 0xff) {
|
||||
hLine(2, width() - 6, ((_vm->_font->getHeight() + 1) >> 1) + yp);
|
||||
if (_lines[lineCtr].barLine) {
|
||||
// Bar separation line
|
||||
hLine(5, width() - 6, ((_vm->_font->getHeight() + 1) >> 1) + yp);
|
||||
} else {
|
||||
Common::Point pt((_lines[lineCtr].xp & 0x7f) + 5, yp);
|
||||
// Standard line
|
||||
Common::Point pt(_lines[lineCtr].xp + 5, yp);
|
||||
if (_lines[lineCtr].xp & 0x40)
|
||||
++pt.y;
|
||||
|
||||
|
@ -37,8 +37,9 @@ public:
|
||||
char data[100];
|
||||
uint8 xp;
|
||||
bool underline;
|
||||
bool barLine;
|
||||
|
||||
DialogLine() { data[0] = '\0'; xp = 0; underline = false; }
|
||||
DialogLine() { data[0] = '\0'; xp = 0; underline = barLine = false; }
|
||||
};
|
||||
|
||||
class Dialog: public View {
|
||||
@ -51,7 +52,7 @@ private:
|
||||
RGBList *_palette;
|
||||
int _lineX;
|
||||
int _widthX;
|
||||
|
||||
bool _commandCase;
|
||||
|
||||
void initDialog();
|
||||
void incLine();
|
||||
@ -59,6 +60,9 @@ private:
|
||||
void writeChars(const char *line);
|
||||
void addLine(const char *line, bool underlineP = false);
|
||||
void appendText(const char *line);
|
||||
void addBarLine();
|
||||
void getVocab(int vocabId, char **line);
|
||||
bool handleNounSuffix(char *destP, int nounNum, const char *srcP);
|
||||
void draw();
|
||||
public:
|
||||
Dialog(M4Engine *vm, const char *msgData, const char *title = NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user