mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
Trying to make this code a bit less ugly. It has been hacked up by basically every Japanese and Chinese version in different ways. This is a start to revert some of the hacks.
363 lines
9.1 KiB
C++
363 lines
9.1 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#ifdef ENABLE_LOL
|
|
|
|
#include "kyra/text/text_lol.h"
|
|
#include "kyra/engine/lol.h"
|
|
#include "kyra/graphics/screen_lol.h"
|
|
#include "kyra/engine/timer.h"
|
|
#include "kyra/sound/sound.h"
|
|
|
|
#include "common/system.h"
|
|
|
|
namespace Kyra {
|
|
|
|
TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *engine, Screen_LoL *screenLoL) : TextDisplayer_rpg(engine, screenLoL),
|
|
_vm(engine), _screen(screenLoL), _scriptTextParameter(0) {
|
|
|
|
memset(_stringParameters, 0, 15 * sizeof(char *));
|
|
_buffer = new char[600]();
|
|
|
|
_waitButtonSpace = 0;
|
|
}
|
|
|
|
TextDisplayer_LoL::~TextDisplayer_LoL() {
|
|
delete[] _buffer;
|
|
}
|
|
|
|
void TextDisplayer_LoL::setupField(bool mode) {
|
|
if (_vm->textEnabled()) {
|
|
|
|
int y = 142;
|
|
int h = 37;
|
|
int stepY = 3;
|
|
int stepH = 1;
|
|
|
|
if (_vm->gameFlags().use16ColorMode) {
|
|
y = 140;
|
|
h = 39;
|
|
stepY = 4;
|
|
stepH = 2;
|
|
}
|
|
|
|
if (mode) {
|
|
_screen->copyRegionToBuffer(3, 0, 0, 320, 40, _vm->_pageBuffer1);
|
|
_screen->copyRegion(80, y, 0, 0, 240, h, 0, 3, Screen::CR_NO_P_CHECK);
|
|
_screen->copyRegionToBuffer(3, 0, 0, 320, 40, _vm->_pageBuffer2);
|
|
_screen->copyBlockToPage(3, 0, 0, 320, 40, _vm->_pageBuffer1);
|
|
} else {
|
|
_screen->setScreenDim(clearDim(4));
|
|
int cp = _screen->setCurPage(2);
|
|
_screen->copyRegionToBuffer(3, 0, 0, 320, 40, _vm->_pageBuffer1);
|
|
_screen->copyBlockToPage(3, 0, 0, 320, 40, _vm->_pageBuffer2);
|
|
_screen->copyRegion(0, 0, 80, y, 240, h, 3, _screen->_curPage, Screen::CR_NO_P_CHECK);
|
|
|
|
uint32 endTime = _vm->_system->getMillis();
|
|
for (int i = 177; i > 141; i--) {
|
|
endTime += _vm->_tickLength;
|
|
_screen->copyRegion(83, i - stepH + 1, 83, i - stepH, 235, stepY, 0, 0, Screen::CR_NO_P_CHECK);
|
|
_screen->copyRegion(83, i + 1, 83, i + 1, 235, 1, 2, 0, Screen::CR_NO_P_CHECK);
|
|
_vm->updateInput();
|
|
_screen->updateScreen();
|
|
_vm->delayUntil(endTime);
|
|
}
|
|
|
|
_screen->copyBlockToPage(3, 0, 0, 320, 200, _vm->_pageBuffer1);
|
|
_screen->setCurPage(cp);
|
|
|
|
_vm->_updateFlags &= 0xFFFD;
|
|
}
|
|
} else {
|
|
if (!mode)
|
|
_screen->setScreenDim(clearDim(4));
|
|
_vm->toggleSelectedCharacterFrame(1);
|
|
}
|
|
}
|
|
|
|
void TextDisplayer_LoL::expandField() {
|
|
uint8 *tmp = _vm->_pageBuffer1 + 13000;
|
|
|
|
if (_vm->textEnabled()) {
|
|
_vm->_fadeText = false;
|
|
_vm->_textColorFlag = 0;
|
|
_vm->_timer->disable(11);
|
|
_screen->setScreenDim(clearDim(3));
|
|
_screen->copyRegionToBuffer(3, 0, 0, 320, 10, tmp);
|
|
|
|
int y = 140;
|
|
int h = 3;
|
|
int stepH = 0;
|
|
|
|
if (_vm->gameFlags().use16ColorMode) {
|
|
y = 139;
|
|
h = 4;
|
|
stepH = 1;
|
|
}
|
|
|
|
_screen->copyRegion(83, y, 0, 0, 235, h, 0, 2, Screen::CR_NO_P_CHECK);
|
|
|
|
uint32 endTime = _vm->_system->getMillis();
|
|
for (int i = 140; i < 177; i++) {
|
|
endTime += _vm->_tickLength;
|
|
_screen->copyRegion(0, 0, 83, i - stepH, 235, h, 2, 0, Screen::CR_NO_P_CHECK);
|
|
_vm->updateInput();
|
|
_screen->updateScreen();
|
|
_vm->delayUntil(endTime);
|
|
}
|
|
|
|
_screen->copyBlockToPage(3, 0, 0, 320, 10, tmp);
|
|
_vm->_updateFlags |= 2;
|
|
|
|
} else {
|
|
clearDim(3);
|
|
_vm->toggleSelectedCharacterFrame(0);
|
|
}
|
|
}
|
|
|
|
void TextDisplayer_LoL::printDialogueText2(int dim, const char *str, EMCState *script, const uint16 *paramList, int16 paramIndex) {
|
|
int oldDim = 0;
|
|
|
|
if (dim == 3) {
|
|
if (_vm->_updateFlags & 2) {
|
|
oldDim = clearDim(4);
|
|
_textDimData[4].color1= _vm->gameFlags().use16ColorMode ? 0x33 : 254;
|
|
_textDimData[4].color2 = _screen->_curDim->col2;
|
|
} else {
|
|
oldDim = clearDim(3);
|
|
_textDimData[3].color1= _vm->gameFlags().use16ColorMode ? 0x33 : 192;
|
|
_textDimData[3].color2 = _screen->_curDim->col2;
|
|
if (!_vm->gameFlags().use16ColorMode)
|
|
_screen->copyColor(192, 254);
|
|
_vm->enableTimer(11);
|
|
_vm->_textColorFlag = 0;
|
|
_vm->_fadeText = false;
|
|
}
|
|
} else {
|
|
oldDim = _screen->curDimIndex();
|
|
_screen->setScreenDim(dim);
|
|
_lineCount = 0;
|
|
_textDimData[dim].color1= _vm->gameFlags().use16ColorMode ? 0x33 : 254;
|
|
_textDimData[dim].color2 = _screen->_curDim->col2;
|
|
}
|
|
|
|
int cp = _screen->setCurPage(0);
|
|
Screen::FontId of = _screen->setFont(_vm->gameFlags().lang == Common::Language::ZH_TWN ? Screen::FID_CHINESE_FNT : _pc98TextMode ? Screen::FID_SJIS_TEXTMODE_FNT : Screen::FID_9_FNT);
|
|
|
|
preprocessString(str, script, paramList, paramIndex);
|
|
_numCharsTotal = Common::strnlen(_dialogueBuffer, 2559);
|
|
displayText(_dialogueBuffer);
|
|
|
|
_screen->setScreenDim(oldDim);
|
|
_screen->setCurPage(cp);
|
|
_screen->setFont(of);
|
|
_lineCount = 0;
|
|
_vm->_fadeText = false;
|
|
}
|
|
|
|
void TextDisplayer_LoL::printMessage(uint16 type, const char *str, ...) {
|
|
static const uint8 textColors256[] = { 0xFE, 0xA2, 0x84, 0x97, 0x9F };
|
|
static const uint8 textColors16[] = { 0x33, 0xAA, 0x88, 0x55, 0x99 };
|
|
static const uint8 soundEffect[] = { 0x0B, 0x00, 0x2B, 0x1B, 0x00 };
|
|
|
|
const uint8 *textColors = _vm->gameFlags().use16ColorMode ? textColors16 : textColors256;
|
|
|
|
if (type & 4)
|
|
type &= ~4;
|
|
else
|
|
_vm->stopPortraitSpeechAnim();
|
|
|
|
int index = type & 0x7FFF;
|
|
assert(index < 5);
|
|
|
|
uint16 col = textColors[index];
|
|
|
|
int od = _screen->curDimIndex();
|
|
|
|
if (_vm->_updateFlags & 2) {
|
|
clearDim(4);
|
|
_textDimData[4].color1= col;
|
|
} else {
|
|
clearDim(3);
|
|
if (_vm->gameFlags().use16ColorMode) {
|
|
_textDimData[3].color1= col;
|
|
} else {
|
|
_screen->copyColor(192, col);
|
|
_textDimData[3].color1= 192;
|
|
}
|
|
_vm->enableTimer(11);
|
|
}
|
|
|
|
va_list args;
|
|
va_start(args, str);
|
|
|
|
vsnprintf((char *)_buffer, 240, str, args);
|
|
|
|
va_end(args);
|
|
|
|
displayText(_buffer);
|
|
|
|
_screen->setScreenDim(od);
|
|
_lineCount = 0;
|
|
|
|
if (!(type & 0x8000)) {
|
|
if (soundEffect[index])
|
|
_vm->sound()->playSoundEffect(soundEffect[index]);
|
|
}
|
|
|
|
_vm->_textColorFlag = index;
|
|
_vm->_fadeText = false;
|
|
}
|
|
|
|
void TextDisplayer_LoL::preprocessString(const char *str, EMCState *script, const uint16 *paramList, int16 paramIndex) {
|
|
char *dst = _dialogueBuffer;
|
|
|
|
for (const char *s = str; *s;) {
|
|
if (_vm->gameFlags().lang == Common::JA_JPN) {
|
|
uint8 c = *s;
|
|
if (c >= 0xE0 || (c > 0x80 && c < 0xA0)) {
|
|
*dst++ = *s++;
|
|
*dst++ = *s++;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (*s != '%') {
|
|
*dst++ = *s++;
|
|
continue;
|
|
}
|
|
|
|
char para = *++s;
|
|
bool eos = false;
|
|
|
|
switch (para) {
|
|
case '\0':
|
|
eos = true;
|
|
break;
|
|
case '#':
|
|
para = *++s;
|
|
switch (para) {
|
|
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;
|
|
case ' ':
|
|
case '+':
|
|
case '-':
|
|
++s;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (eos)
|
|
continue;
|
|
|
|
para = *s;
|
|
|
|
switch (para) {
|
|
case '\0':
|
|
eos = true;
|
|
break;
|
|
case '0':
|
|
++s;
|
|
break;
|
|
default:
|
|
while (para && para > 47 && para < 58)
|
|
para = *++s;
|
|
break;
|
|
}
|
|
if (eos)
|
|
continue;
|
|
|
|
para = *s++;
|
|
|
|
switch (para) {
|
|
case 'a':
|
|
Common::strlcpy(dst, Common::String::format("%d", _scriptTextParameter).c_str(), 2560 - (dst - _dialogueBuffer));
|
|
dst += Common::strnlen(dst, 2559 - (dst - _dialogueBuffer));
|
|
break;
|
|
|
|
case 'n':
|
|
if (script || paramList) {
|
|
Common::strlcpy(dst, _vm->_characters[script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]].name, 2560 - (dst - _dialogueBuffer));
|
|
dst += Common::strnlen(dst, 2559 - (dst - _dialogueBuffer));
|
|
} else {
|
|
warning("TextDisplayer_LoL::preprocessString(): Missing replacement data for placeholder '%%%c'", para);
|
|
}
|
|
break;
|
|
|
|
case 's':
|
|
if (script || paramList) {
|
|
Common::strlcpy(dst, _vm->getLangString(script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]), 2560 - (dst - _dialogueBuffer));
|
|
dst += Common::strnlen(dst, 2559 - (dst - _dialogueBuffer));
|
|
} else {
|
|
warning("TextDisplayer_LoL::preprocessString(): Missing replacement data for placeholder '%%%c'", para);
|
|
}
|
|
break;
|
|
|
|
case 'X':
|
|
case 'd':
|
|
case 'u':
|
|
case 'x':
|
|
if (script || paramList) {
|
|
Common::strlcpy(dst, Common::String::format("%d", script ? script->stack[script->sp + paramIndex] : paramList[paramIndex]).c_str(), 2560 - (dst - _dialogueBuffer));
|
|
dst += Common::strnlen(dst, 2559 - (dst - _dialogueBuffer));
|
|
} else {
|
|
warning("TextDisplayer_LoL::preprocessString(): Missing replacement data for placeholder '%%%c'", para);
|
|
}
|
|
break;
|
|
|
|
case '\0':
|
|
default:
|
|
continue;
|
|
}
|
|
}
|
|
*dst = 0;
|
|
}
|
|
|
|
KyraRpgEngine *TextDisplayer_LoL::vm() {
|
|
return _vm;
|
|
}
|
|
|
|
Screen *TextDisplayer_LoL::screen() {
|
|
return _screen;
|
|
}
|
|
|
|
void TextDisplayer_LoL::textPageBreak() {
|
|
_pageBreakString = _vm->getLangString(0x4073);
|
|
TextDisplayer_rpg::textPageBreak();
|
|
}
|
|
|
|
} // End of namespace Kyra
|
|
|
|
#endif // ENABLE_LOL
|