aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/text_lol.cpp
diff options
context:
space:
mode:
authorFlorian Kagerer2009-02-01 19:27:01 +0000
committerFlorian Kagerer2009-02-01 19:27:01 +0000
commit784c99b3dac507c5ee0686cc314c96caa7349ef3 (patch)
tree1dbcd6a62bc25505623ed693161b935389ea5498 /engines/kyra/text_lol.cpp
parentf90e4545c27fa92cc6ba835f80551556929df43d (diff)
downloadscummvm-rg350-784c99b3dac507c5ee0686cc314c96caa7349ef3.tar.gz
scummvm-rg350-784c99b3dac507c5ee0686cc314c96caa7349ef3.tar.bz2
scummvm-rg350-784c99b3dac507c5ee0686cc314c96caa7349ef3.zip
svn-id: r36178
Diffstat (limited to 'engines/kyra/text_lol.cpp')
-rw-r--r--engines/kyra/text_lol.cpp573
1 files changed, 573 insertions, 0 deletions
diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp
new file mode 100644
index 0000000000..fe7ac6d81d
--- /dev/null
+++ b/engines/kyra/text_lol.cpp
@@ -0,0 +1,573 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "kyra/lol.h"
+#include "kyra/screen_lol.h"
+#include "kyra/util.h"
+
+namespace Kyra {
+
+TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen) : _vm(vm), _screen(screen),
+ _scriptParameter(0), _stringLength(0), _animWidth(0), _animColour1(0), _animColour2(0), _animFlag(true),
+ _printFlag(false), _lineWidth(0), _numChars(0), _numCharsPrinted(0), _posX(0), _posY(0), _colour1(0), _colour2(0) {
+
+ memset(_stringParameters, 0, 15 * sizeof(char*));
+ _buffer = new char[600];
+ memset(_buffer, 0, 600);
+
+ _out = new char[1024];
+ memset(_out, 0, 1024);
+
+ _backupBuffer = new char[40];
+ memset(_out, 0, 40);
+
+ _currentLine = new char[85];
+ memset(_out, 0, 85);
+
+ _pageBuffer1 = new uint8[0xfa00];
+ _pageBuffer2 = new uint8[0xfa00];
+}
+
+TextDisplayer_LoL::~TextDisplayer_LoL() {
+ delete[] _buffer;
+ delete[] _out;
+ delete[] _backupBuffer;
+ delete[] _currentLine;
+ delete[] _pageBuffer1;
+ delete[] _pageBuffer2;
+}
+
+void TextDisplayer_LoL::setupField(bool mode) {
+ if (_vm->textEnabled()) {
+ if (mode) {
+ _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _pageBuffer1);
+ _screen->copyRegion(80, 142, 0, 0, 240, 37, 0, 3, Screen::CR_NO_P_CHECK);
+ _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _pageBuffer2);
+ _screen->copyBlockToPage(3, 0, 0, 320, 200, _pageBuffer1);
+ } else {
+ _screen->clearDim(4);
+ int cp = _screen->setCurPage(2);
+ _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _pageBuffer1);
+ _screen->copyBlockToPage(3, 0, 0, 320, 200, _pageBuffer2);
+ _screen->copyRegion(80, 142, 0, 0, 240, 37, 3, 2, Screen::CR_NO_P_CHECK);
+
+ for (int i = 177; i > 141; i--) {
+ uint32 endTime = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->hideMouse();
+ _screen->copyRegion(83, i, 83, i - 1, 235, 3, 0, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(83, i + 1, 83, i + 1, 235, 1, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _screen->showMouse();
+ _vm->delayUntil(endTime);
+ }
+
+ _screen->copyBlockToPage(3, 0, 0, 320, 200, _pageBuffer1);
+ _screen->setCurPage(cp);
+
+ _vm->_updateFlags &= 0xfffd;
+ }
+ } else {
+ if (!mode)
+ _screen->clearDim(4);
+ _vm->toggleSelectedCharacterFrame(1);
+ }
+}
+
+void TextDisplayer_LoL::expandField() {
+ if (_vm->textEnabled()) {
+ _vm->_restorePalette = 0;
+ _vm->_updateCharV4 = 0;
+ //_vm->toggleGuiUnk(11, 0);
+ _screen->clearDim(3);
+ _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _pageBuffer1);
+ _screen->copyRegion(83, 140, 0, 0, 235, 3, 0, 2, Screen::CR_NO_P_CHECK);
+
+ for (int i = 140; i < 177; i++) {
+ uint32 endTime = _vm->_system->getMillis() + _vm->_tickLength;
+ _screen->hideMouse();
+ _screen->copyRegion(0, 0, 83, i, 235, 3, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ _screen->showMouse();
+ _vm->delayUntil(endTime);
+ }
+
+ _screen->copyBlockToPage(3, 0, 0, 320, 200, _pageBuffer1);
+ _vm->_updateFlags |= 2;
+
+ } else {
+ _screen->clearDim(3);
+ _vm->toggleSelectedCharacterFrame(0);
+ }
+}
+void TextDisplayer_LoL::setAnimParameters(const char *str, int x, uint8 col1, uint8 col2) {
+ static const char defaultStr[] = "<MORE>";
+
+ if (str) {
+ _animString = str;
+ _animWidth = x;
+ _animColour1 = col1;
+ _animColour2 = col2;
+ } else {
+ _animString = defaultStr;
+ _animWidth = 7;
+ _animColour1 = 0;
+ _animColour2 = 0;
+ }
+}
+
+void TextDisplayer_LoL::play(int dim, char *str, EMCState *script, int16 *paramList, int16 paramIndex) {
+ memcpy(_curPara, _stringParameters, 15 * sizeof(char*));
+ char *cmds = _curPara[0];
+
+ if (dim == 3) {
+ if (_vm->_updateFlags & 2) {
+ _screen->clearDim(4);
+ dim = _screen->curDimIndex();
+ _colour1 = 254;
+ } else {
+ _screen->clearDim(3);
+ dim = _screen->curDimIndex();
+ _colour1 = 192;
+ uint8 col[3];
+ _screen->loadColour254(col);
+ _screen->setPaletteIndex(192, col[0], col[1], col[2]);
+ //toggleGuiUnk(11, 1);
+ _vm->_updateCharV4 = 0;
+ _vm->_restorePalette = 0;
+ }
+
+ } else {
+ _screen->setScreenDim(dim);
+ _colour1 = 254;
+ }
+
+ int cp = _screen->setCurPage(0);
+ Screen::FontId of = _screen->setFont(Screen::FID_9_FNT);
+
+ memset(_backupBuffer, 0, 40);
+
+ if (preprocessString(str, script, paramList, paramIndex)) {
+ vsnprintf(_out, 1024, str, cmds);
+ _stringLength = strlen(_out);
+ displayText(_out);
+ } else {
+ _stringLength = strlen(str);
+ displayText(str);
+ displayText(str);
+ }
+
+ for (int i = 0; i < 10; i++) {
+ if (!_backupBuffer[i << 1])
+ break;
+ str[_backupBuffer[(i << 1) + 1]] = _backupBuffer[i << 1];
+ }
+
+ _screen->setScreenDim(dim);
+ _screen->setCurPage(cp);
+ _screen->setFont(of);
+
+ _vm->_restorePalette = 0;
+}
+
+bool TextDisplayer_LoL::preprocessString(char *str, EMCState *script, int16 *paramList, int16 paramIndex) {
+ int cnt = 0;
+ bool res = false;
+ char *tmpd = _buffer;
+ char **cmds = _curPara;
+
+ for (char *s = str; *s;) {
+ if (*s++ != '%')
+ continue;
+
+ char pos = *s;
+ char para1 = 0;
+ bool eos = false;
+
+ switch (pos) {
+ case '\0':
+ eos = true;
+ break;
+ case '#':
+ para1 = *++s;
+ switch (para1) {
+ case 'E':
+ case 'G':
+ case 'X':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 's':
+ case 'u':
+ case 'x':
+ break;
+ default:
+ eos = true;
+ break;
+ }
+ break;
+ case ' ':
+ case '+':
+ case '-':
+ ++s;
+ default:
+ break;
+ }
+
+ if (eos)
+ continue;
+
+ char para2 = *s;
+
+ switch (para2) {
+ case '\0':
+ eos = true;
+ break;
+ case '0':
+ ++s;
+ break;
+ default:
+ while(para2 && para2 > 47 && para2 < 58)
+ para2 = *++s;
+ break;
+ }
+
+ if (eos)
+ continue;
+
+ char para3 = *++s;
+
+ switch (para3) {
+ case 'a':
+ _backupBuffer[cnt++] = para3;
+ _backupBuffer[cnt++] = (int16) (s - str);
+ snprintf(tmpd, 7, "%d", _scriptParameter);
+ *cmds++ = tmpd;
+ tmpd += strlen(tmpd) + 1;
+ res = true;
+ *s++ = 's';
+ break;
+
+ case 'n':
+ _backupBuffer[cnt++] = para3;
+ _backupBuffer[cnt++] = (int16) (s - str);
+ *cmds++ = _vm->_characters[script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]].name;
+ paramIndex++;
+ res = true;
+ *s++ = 's';
+ break;
+
+ case 's':
+ *cmds++ = _vm->getLangString(script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]);
+ paramIndex++;
+ res = true;
+ s++;
+ break;
+
+ case 'X':
+ case 'd':
+ case 'u':
+ case 'x':
+ snprintf(tmpd, 7, "%d", script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]);
+ *cmds++ = tmpd;
+ tmpd += strlen(tmpd) + 1;
+ paramIndex++;
+ res = true;
+ *s++ = 's';
+ break;
+
+ case '\0':
+ default:
+ continue;
+ }
+ }
+
+ return res;
+}
+
+void TextDisplayer_LoL::displayText(char *str, ...) {
+ _printFlag = false;
+
+ _lineWidth = 0;
+ _numChars = 0;
+ _numCharsPrinted = 0;
+
+ _tempString1 = str;
+ _tempString2 = 0;
+
+ _currentLine[0] = 0;
+
+ memset(_ctrl, 0, 3);
+
+ _colour1 = _screen->_curDim->unk8;
+ _colour2 = _screen->_curDim->unkA;
+ _posX = _screen->_curDim->unkC;
+ _posY = _screen->_curDim->unkE;
+
+ char c = parseCommand();
+
+ va_list args;
+ va_start(args, str);
+
+ const ScreenDim *sd = _screen->_curDim;
+
+ while (c) {
+ char a = tolower(_ctrl[1]);
+
+ if (!_tempString2 && c == '%' ) {
+ if (a == 'd') {
+ snprintf(_scriptParaString, 11, "%d", va_arg(args, int));
+ _tempString2 = _scriptParaString;
+ } else if (a == 's') {
+ _tempString2 = va_arg(args, char*);
+ } else {
+ break;
+ }
+
+ _ctrl[0] = _ctrl[2];
+ _ctrl[2] = _ctrl[1] = 0;
+ c = parseCommand();
+ }
+
+ switch (c - 1) {
+ case 0:
+ printLine(_currentLine);
+ //if (!_dlgAnimCallback)
+ // break;
+
+ portraitAnimation2();
+ _numCharsPrinted = 0;
+ break;
+
+ case 1:
+ printLine(_currentLine);
+ _colour2 = parseCommand();
+ break;
+
+ case 5:
+ printLine(_currentLine);
+ _colour1 = parseCommand();
+ break;
+
+ case 8:
+ //TODO
+ break;
+
+ case 11:
+ //TODO
+ break;
+
+ case 12:
+ printLine(_currentLine);
+ _screen->_dimLineCount++;
+ _posX = 0;
+ _posY++;
+ break;
+
+ case 18:
+ //TODO
+ break;
+
+ case 23:
+ //TODO
+ break;
+
+ case 24:
+ //TODO
+ break;
+
+ case 26:
+ //TODO
+ break;
+
+ case 28:
+ //TODO
+ break;
+
+ default:
+ _lineWidth += _screen->getCharWidth(c);
+ _currentLine[_numChars++] = c;
+ _currentLine[_numChars] = 0;
+
+ if ((_posX + _lineWidth) > (sd->w << 3))
+ printLine(_currentLine);
+
+ break;
+ }
+
+ c = parseCommand();
+ }
+
+ va_end(args);
+
+ if (_numChars)
+ printLine(_currentLine);
+}
+
+char TextDisplayer_LoL::parseCommand() {
+ if (!_ctrl[1])
+ readNextPara();
+
+ char res = _ctrl[1];
+ _ctrl[1] = _ctrl[2];
+ _ctrl[2] = 0;
+
+ if (!_ctrl[1])
+ readNextPara();
+
+ return res;
+}
+
+void TextDisplayer_LoL::readNextPara() {
+ char d = 0;
+
+ if (_tempString2) {
+ if (*_tempString2) {
+ d = *_tempString2++;
+ } else {
+ _tempString2 = 0;
+ d = _ctrl[0];
+ }
+ }
+
+ if (!d && _tempString1) {
+ if (*_tempString1)
+ d = *_tempString1++;
+ else
+ _tempString1 = 0;
+ }
+
+ _ctrl[1] = d;
+ _ctrl[2] = 0;
+}
+
+void TextDisplayer_LoL::printLine(char *str) {
+ const ScreenDim *sd = _screen->_curDim;
+
+ int fh = (_screen->getFontHeight() + _screen->_charOffset);
+ int lines = (sd->h - _screen->_charOffset) / fh;
+
+ while (_posY >= lines) {
+ if (lines <= _screen->_dimLineCount && _animFlag) {
+ _screen->_dimLineCount = 0;
+ //if (_dlgAnimCallback) {
+ portraitAnimation2();
+ _numCharsPrinted = 0;
+ //}
+ }
+
+ int h1 = ((sd->h / fh) - 1) * fh;
+ int h2 = sd->h - fh;
+
+ if (h2)
+ _screen->copyRegion(sd->sx << 3, sd->sy + fh, sd->sx << 3, sd->sy, sd->w << 3, h2, _screen->_curPage, _screen->_curPage, Screen::CR_NO_P_CHECK);
+
+ _screen->fillRect(sd->sx << 3, sd->sy + h1, (sd->sx + sd->w - 1) << 3, sd->sy + sd->h - 1, _colour2);
+
+ _posY--;
+ }
+
+ int x1 = (sd->sx << 3) + _posX;
+ int y = sd->sy + fh * _posY;
+ int w = sd->w << 3;
+ int lw = _lineWidth;
+ int s = _numChars;
+ char c = 0;
+
+ if ((lw + _posX) > w) {
+ if ((lines - 1) <= _screen->_dimLineCount && _animFlag)
+ w -= (_animWidth * (_screen->getFontWidth() + _screen->_charWidth));
+
+ w -= _posX;
+
+ int n2 = 0;
+ int n1 = s - 1;
+
+ while (n1 > 0) {
+ //cut off line after last space
+ c = str[n1];
+ lw -= _screen->getCharWidth(c);
+
+ if (!n2 && lw <= w)
+ n2 = n1;
+
+ if (n2 && c == ' ') {
+ s = n1;
+ _printFlag = false;
+ break;
+ }
+
+ n1--;
+ }
+
+ if (!n1) {
+ if (_posX && !_printFlag) {
+ s = lw = 0;
+ _printFlag = true;
+ } else {
+ s = n2;
+ }
+ }
+ }
+
+ c = str[s];
+ str[s] = 0;
+
+ _screen->printText(str, x1, y, _colour1, _colour2);
+ _posX += lw;
+ _numCharsPrinted += strlen(str);
+
+ str[s] = c;
+
+ if (c == ' ')
+ s++;
+
+ if (str[s] == ' ')
+ s++;
+
+ strcpy(str, &str[s]);
+ _numChars = strlen(str);
+ _lineWidth = _screen->getTextWidth(str);
+
+ if (!_numChars && _posX < (sd->w << 3))
+ return;
+
+ _posX = 0;
+ _posY++;
+ _screen->_dimLineCount++;
+
+ printLine(str);
+}
+
+/*void TextDisplayer_LoL::portraitAnimation1(const char *str, uint16 lineWidth, uint8 col1, uint8 col2, uint16 numCharsPrinted) {
+
+}*/
+
+void TextDisplayer_LoL::portraitAnimation2() {
+ // TODO
+}
+
+} // end of namespace Kyra