aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2007-02-12 18:01:51 +0000
committerJohannes Schickel2007-02-12 18:01:51 +0000
commit7af17382b5e85f48412b2b44733ac3d5431b31a9 (patch)
treef63cdc6932d49d25ff3ff3e6457240d2db0204f2
parent7107fcc2c693a077689a0969011e0e164f75b382 (diff)
downloadscummvm-rg350-7af17382b5e85f48412b2b44733ac3d5431b31a9.tar.gz
scummvm-rg350-7af17382b5e85f48412b2b44733ac3d5431b31a9.tar.bz2
scummvm-rg350-7af17382b5e85f48412b2b44733ac3d5431b31a9.zip
Support for Japanese FM-Towns version. (code contributed by Florian Kagerer, modified a bit)
svn-id: r25530
-rw-r--r--engines/kyra/gui.cpp8
-rw-r--r--engines/kyra/kyra.cpp63
-rw-r--r--engines/kyra/kyra.h1
-rw-r--r--engines/kyra/plugin.cpp19
-rw-r--r--engines/kyra/screen.cpp518
-rw-r--r--engines/kyra/screen.h41
-rw-r--r--engines/kyra/script_v1.cpp5
-rw-r--r--engines/kyra/seqplayer.cpp6
-rw-r--r--engines/kyra/sequences_v1.cpp16
-rw-r--r--engines/kyra/staticres.cpp6
-rw-r--r--engines/kyra/text.cpp10
-rw-r--r--engines/kyra/text.h4
12 files changed, 629 insertions, 68 deletions
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index 99969731c6..8654cb2c51 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -819,6 +819,10 @@ void KyraEngine::gui_getInput() {
case OSystem::EVENT_MOUSEMOVE:
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
+ if (_flags.useHiResOverlay) {
+ _mouseX >>= 1;
+ _mouseY >>= 1;
+ }
_system->updateScreen();
lastScreenUpdate = now;
break;
@@ -1485,6 +1489,10 @@ bool KyraEngine::gui_mainMenuGetInput() {
case OSystem::EVENT_MOUSEMOVE:
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
+ if (_flags.useHiResOverlay) {
+ _mouseX >>= 1;
+ _mouseY >>= 1;
+ }
break;
case OSystem::EVENT_LBUTTONUP:
return true;
diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp
index 84e4a32c7e..ab6dad32cb 100644
--- a/engines/kyra/kyra.cpp
+++ b/engines/kyra/kyra.cpp
@@ -195,7 +195,7 @@ int KyraEngine::init() {
assert(_animator);
_animator->init(5, 11, 12);
assert(*_animator);
- _text = new TextDisplayer(_screen);
+ _text = new TextDisplayer(this, _screen);
assert(_text);
_staticres = new StaticResource(this);
@@ -337,25 +337,27 @@ int KyraEngine::init() {
_lang = 0;
Common::Language lang = Common::parseLanguage(ConfMan.get("language"));
- switch (lang) {
- case Common::EN_ANY:
- case Common::EN_USA:
- case Common::EN_GRB:
- _lang = 0;
- break;
-
- case Common::FR_FRA:
- _lang = 1;
- break;
-
- case Common::DE_DEU:
- _lang = 2;
- break;
-
- default:
- warning("unsupported language, switching back to English");
- _lang = 0;
- break;
+ if (_flags.gameID == GI_KYRA2 || _flags.gameID == GI_KYRA3) {
+ switch (lang) {
+ case Common::EN_ANY:
+ case Common::EN_USA:
+ case Common::EN_GRB:
+ _lang = 0;
+ break;
+
+ case Common::FR_FRA:
+ _lang = 1;
+ break;
+
+ case Common::DE_DEU:
+ _lang = 2;
+ break;
+
+ default:
+ warning("unsupported language, switching back to English");
+ _lang = 0;
+ break;
+ }
}
return 0;
@@ -634,6 +636,10 @@ void KyraEngine::delay(uint32 amount, bool update, bool isMainLoop) {
case OSystem::EVENT_MOUSEMOVE:
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
+ if (_flags.useHiResOverlay) {
+ _mouseX >>= 1;
+ _mouseY >>= 1;
+ }
_animator->_updateScreen = true;
break;
case OSystem::EVENT_QUIT:
@@ -644,19 +650,24 @@ void KyraEngine::delay(uint32 amount, bool update, bool isMainLoop) {
break;
case OSystem::EVENT_LBUTTONUP:
_mousePressFlag = false;
- if (_abortWalkFlag2) {
- _abortWalkFlag = true;
- _mouseX = event.mouse.x;
- _mouseY = event.mouse.y;
+
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ if (_flags.useHiResOverlay) {
+ _mouseX >>= 1;
+ _mouseY >>= 1;
}
+
+ if (_abortWalkFlag2)
+ _abortWalkFlag = true;
+
if (_handleInput) {
- _mouseX = event.mouse.x;
- _mouseY = event.mouse.y;
_handleInput = false;
processInput(_mouseX, _mouseY);
_handleInput = true;
} else
_skipFlag = true;
+
break;
default:
break;
diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h
index 905b6fc212..ad42dd3c0a 100644
--- a/engines/kyra/kyra.h
+++ b/engines/kyra/kyra.h
@@ -52,6 +52,7 @@ struct GameFlags {
bool isDemo;
bool useAltShapeHeader; // alternative shape header (uses 2 bytes more, those are unused though)
bool isTalkie;
+ bool useHiResOverlay;
byte gameID;
};
diff --git a/engines/kyra/plugin.cpp b/engines/kyra/plugin.cpp
index 31f87afaa8..43fa207cff 100644
--- a/engines/kyra/plugin.cpp
+++ b/engines/kyra/plugin.cpp
@@ -36,16 +36,17 @@ struct KYRAGameDescription {
namespace {
-#define FLAGS(x, y, z, id) { Common::UNK_LANG, Common::kPlatformUnknown, x, y, z, id }
+#define FLAGS(x, y, z, a, id) { Common::UNK_LANG, Common::kPlatformUnknown, x, y, z, a, id }
-#define KYRA1_FLOPPY_FLAGS FLAGS(false, false, false, Kyra::GI_KYRA1)
-#define KYRA1_TOWNS_FLAGS FLAGS(false, true, false, Kyra::GI_KYRA1)
-#define KYRA1_CD_FLAGS FLAGS(false, true, true, Kyra::GI_KYRA1)
-#define KYRA1_DEMO_FLAGS FLAGS(true, false, false, Kyra::GI_KYRA1)
+#define KYRA1_FLOPPY_FLAGS FLAGS(false, false, false, false, Kyra::GI_KYRA1)
+#define KYRA1_TOWNS_FLAGS FLAGS(false, true, false, false, Kyra::GI_KYRA1)
+#define KYRA1_TOWNS_SJIS_FLAGS FLAGS(false, true, false, true, Kyra::GI_KYRA1)
+#define KYRA1_CD_FLAGS FLAGS(false, true, true, false, Kyra::GI_KYRA1)
+#define KYRA1_DEMO_FLAGS FLAGS(true, false, false, false, Kyra::GI_KYRA1)
-#define KYRA2_UNK_FLAGS FLAGS(false, false, false, Kyra::GI_KYRA2)
+#define KYRA2_UNK_FLAGS FLAGS(false, false, false, false, Kyra::GI_KYRA2)
-#define KYRA3_CD_FLAGS FLAGS(false, false, true, Kyra::GI_KYRA3)
+#define KYRA3_CD_FLAGS FLAGS(false, false, true, false, Kyra::GI_KYRA3)
const KYRAGameDescription adGameDescs[] = {
{ { "kyra1", 0, AD_ENTRY1("GEMCUT.EMC", "3c244298395520bb62b5edfe41688879"), Common::EN_ANY, Common::kPlatformPC }, KYRA1_FLOPPY_FLAGS },
@@ -58,7 +59,7 @@ const KYRAGameDescription adGameDescs[] = {
{ { "kyra1", 0, AD_ENTRY1("GEMCUT.EMC", "ef08c8c237ee1473fd52578303fc36df"), Common::IT_ITA, Common::kPlatformPC }, KYRA1_FLOPPY_FLAGS }, // from gourry
{ { "kyra1", 0, AD_ENTRY1("TWMUSIC.PAK", "e53bca3a3e3fb49107d59463ec387a59"), Common::EN_ANY, Common::kPlatformFMTowns }, KYRA1_TOWNS_FLAGS },
- //{ { "kyra1", 0, AD_ENTRY1("TWMUSIC.PAK", "e53bca3a3e3fb49107d59463ec387a59"), Common::JA_JPN, Common::kPlatformFMTowns }, KYRA1_TOWNS_FLAGS },
+ { { "kyra1", 0, AD_ENTRY1("TWMUSIC.PAK", "e53bca3a3e3fb49107d59463ec387a59"), Common::JA_JPN, Common::kPlatformFMTowns }, KYRA1_TOWNS_SJIS_FLAGS },
{ { "kyra1", "CD", AD_ENTRY1("GEMCUT.PAK", "fac399fe62f98671e56a005c5e94e39f"), Common::EN_ANY, Common::kPlatformPC }, KYRA1_CD_FLAGS },
{ { "kyra1", "CD", AD_ENTRY1("GEMCUT.PAK", "230f54e6afc007ab4117159181a1c722"), Common::DE_DEU, Common::kPlatformPC }, KYRA1_CD_FLAGS },
@@ -71,7 +72,7 @@ const KYRAGameDescription adGameDescs[] = {
{ { "kyra3", 0, AD_ENTRY1("ONETIME.PAK", "3833ff312757b8e6147f464cca0a6587"), Common::EN_ANY, Common::kPlatformPC }, KYRA3_CD_FLAGS },
{ { "kyra3", 0, AD_ENTRY1("ONETIME.PAK", "3833ff312757b8e6147f464cca0a6587"), Common::DE_DEU, Common::kPlatformPC }, KYRA3_CD_FLAGS },
{ { "kyra3", 0, AD_ENTRY1("ONETIME.PAK", "3833ff312757b8e6147f464cca0a6587"), Common::FR_FRA, Common::kPlatformPC }, KYRA3_CD_FLAGS },
- { { NULL, NULL, { {NULL, 0, NULL, 0} }, Common::UNK_LANG, Common::kPlatformUnknown }, FLAGS(0, 0, 0, 0) }
+ { { NULL, NULL, { {NULL, 0, NULL, 0} }, Common::UNK_LANG, Common::kPlatformUnknown }, FLAGS(0, 0, 0, 0, 0) }
};
const PlainGameDescriptor gameList[] = {
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 0aa834588c..1f14e84d35 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -37,6 +37,9 @@ Screen::Screen(KyraEngine *vm, OSystem *system)
}
Screen::~Screen() {
+ for (int i = 0; i < SCREEN_OVLS_NUM; ++i) {
+ delete [] _sjisOverlayPtrs[i];
+ }
for (int pageNum = 0; pageNum < SCREEN_PAGE_NUM; pageNum += 2) {
delete [] _pagePtrs[pageNum];
_pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = 0;
@@ -45,6 +48,8 @@ Screen::~Screen() {
delete[] _fonts[f].fontData;
_fonts[f].fontData = NULL;
}
+ delete [] _sjisFontData;
+ delete [] _sjisTempPage;
delete [] _currentPalette;
delete [] _screenPalette;
delete [] _decodeShapeBuffer;
@@ -70,20 +75,48 @@ bool Screen::init() {
_system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, false);
- _system->beginGFXTransaction();
- _vm->initCommonGFX(false);
- //for debug reasons (see Screen::updateScreen)
- //_system->initSize(640, 200);
- _system->initSize(320, 200);
- _system->endGFXTransaction();
+ memset(_sjisOverlayPtrs, 0, sizeof(_sjisOverlayPtrs));
+ _useOverlays = false;
+ _useSJIS = false;
+
+ if (_vm->gameFlags().useHiResOverlay) {
+ _system->beginGFXTransaction();
+ _vm->initCommonGFX(true);
+ _system->initSize(640, 400);
+ _system->endGFXTransaction();
+
+ for (int i = 0; i < SCREEN_OVLS_NUM; ++i) {
+ _sjisOverlayPtrs[i] = new uint8[SCREEN_OVL_SJIS_SIZE];
+ assert(_sjisOverlayPtrs[i]);
+ memset(_sjisOverlayPtrs[i], 0x80, SCREEN_OVL_SJIS_SIZE);
+ }
+ _useOverlays = true;
+ _useSJIS = (_vm->gameFlags().lang == Common::JA_JPN);
+
+ if (_useSJIS) {
+ _sjisFontData = _vm->resource()->fileData("FMT_FNT.ROM", 0);
+ if (!_sjisFontData)
+ error("missing font rom ('FMT_FNT.ROM') required for this version");
+ _sjisTempPage = new uint8[420];
+ assert(_sjisTempPage);
+ _sjisTempPage2 = _sjisTempPage + 60;
+ _sjisSourceChar = _sjisTempPage + 384;
+ }
+ } else {
+ _system->beginGFXTransaction();
+ _vm->initCommonGFX(false);
+ //for debug reasons (see Screen::updateScreen)
+ //_system->initSize(640, 200);
+ _system->initSize(320, 200);
+ _system->endGFXTransaction();
+ }
_curPage = 0;
for (int pageNum = 0; pageNum < SCREEN_PAGE_NUM; pageNum += 2) {
uint8 *pagePtr = new uint8[SCREEN_PAGE_SIZE];
- if (pagePtr) {
- memset(pagePtr, 0, SCREEN_PAGE_SIZE);
- _pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = pagePtr;
- }
+ assert(pagePtr);
+ memset(pagePtr, 0, SCREEN_PAGE_SIZE);
+ _pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = pagePtr;
}
memset(_shapePages, 0, sizeof(_shapePages));
_currentPalette = new uint8[768];
@@ -138,7 +171,10 @@ void Screen::updateScreen() {
if (_disableScreen)
return;
- updateDirtyRects();
+ if (_useOverlays)
+ updateDirtyRectsOvl();
+ else
+ updateDirtyRects();
//for debug reasons (needs 640x200 screen)
//_system->copyRectToScreen(getPagePtr(2), SCREEN_W, 320, 0, SCREEN_W, SCREEN_H);
@@ -159,6 +195,68 @@ void Screen::updateDirtyRects() {
_numDirtyRects = 0;
}
+void Screen::updateDirtyRectsOvl() {
+ if (_forceFullUpdate) {
+ const byte *src = getCPagePtr(0);
+ byte *dst = _sjisOverlayPtrs[0];
+
+ scale2x(dst, 640, src, SCREEN_W, SCREEN_W, SCREEN_H);
+ mergeOverlay(0, 0, 640, 400);
+ _system->copyRectToScreen(dst, 640, 0, 0, 640, 400);
+ } else {
+ const byte *page0 = getCPagePtr(0);
+ byte *ovl0 = _sjisOverlayPtrs[0];
+
+ for (int i = 0; i < _numDirtyRects; ++i) {
+ Rect &cur = _dirtyRects[i];
+ byte *dst = ovl0 + cur.y * 1280 + (cur.x<<1);
+ const byte *src = page0 + cur.y * SCREEN_W + cur.x;
+
+ scale2x(dst, 640, src, SCREEN_W, cur.x2, cur.y2);
+ mergeOverlay(cur.x<<1, cur.y<<1, cur.x2<<1, cur.y2<<1);
+ _system->copyRectToScreen(dst, 640, cur.x<<1, cur.y<<1, cur.x2<<1, cur.y2<<1);
+ }
+ }
+ _forceFullUpdate = false;
+ _numDirtyRects = 0;
+}
+
+void Screen::scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) {
+ byte *dstL1 = dst;
+ byte *dstL2 = dst + dstPitch;
+
+ int dstAdd = dstPitch * 2 - w * 2;
+ int srcAdd = srcPitch - w;
+
+ while (h--) {
+ for (int x = 0; x < w; ++x, dstL1 += 2, dstL2 += 2) {
+ uint16 col = *src++;
+ col |= col << 8;
+ *(uint16*)(dstL1) = col;
+ *(uint16*)(dstL2) = col;
+ }
+ dstL1 += dstAdd; dstL2 += dstAdd;
+ src += srcAdd;
+ }
+}
+
+void Screen::mergeOverlay(int x, int y, int w, int h) {
+ byte *dst = _sjisOverlayPtrs[0] + y * 640 + x;
+ const byte *src = _sjisOverlayPtrs[1] + y * 640 + x;
+
+ int add = 640 - w;
+
+ while (h--) {
+ for (x = 0; x < w; ++x, ++dst) {
+ byte col = *src++;
+ if (col != 0x80)
+ *dst = col;
+ }
+ dst += add;
+ src += add;
+ }
+}
+
uint8 *Screen::getPagePtr(int pageNum) {
debugC(9, kDebugLevelScreen, "Screen::getPagePtr(%d)", pageNum);
assert(pageNum < SCREEN_PAGE_NUM);
@@ -183,6 +281,7 @@ void Screen::clearPage(int pageNum) {
assert(pageNum < SCREEN_PAGE_NUM);
if (pageNum == 0 || pageNum == 1) _forceFullUpdate = true;
memset(getPagePtr(pageNum), 0, SCREEN_PAGE_SIZE);
+ clearOverlayPage(pageNum);
}
int Screen::setCurPage(int pageNum) {
@@ -197,6 +296,7 @@ void Screen::clearCurPage() {
debugC(9, kDebugLevelScreen, "Screen::clearCurPage()");
if (_curPage == 0 || _curPage == 1) _forceFullUpdate = true;
memset(getPagePtr(_curPage), 0, SCREEN_PAGE_SIZE);
+ clearOverlayPage(_curPage);
}
uint8 Screen::getPagePixel(int pageNum, int x, int y) {
@@ -344,6 +444,7 @@ void Screen::copyToPage0(int y, int h, uint8 page, uint8 *seqBuf) {
dstPage += SCREEN_W;
}
addDirtyRect(0, y, SCREEN_W, h);
+ clearOverlayRect(0, 0, y, SCREEN_W, h);
}
void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage, int flags) {
@@ -383,6 +484,8 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag
if (dstPage == 0 || dstPage == 1)
addDirtyRect(x2, y2, w, h);
+ copyOverlayRegion(x1, y1, x2, y2, w, h, srcPage, dstPage);
+
if (flags & CR_X_FLIPPED) {
while (h--) {
for (int i = 0; i < w; ++i) {
@@ -421,6 +524,7 @@ void Screen::copyPage(uint8 srcPage, uint8 dstPage) {
uint8 *src = getPagePtr(srcPage);
uint8 *dst = getPagePtr(dstPage);
memcpy(dst, src, SCREEN_W * SCREEN_H);
+ copyOverlayRegion(0, 0, 0, 0, SCREEN_W, SCREEN_H, srcPage, dstPage);
if (dstPage == 0 || dstPage == 1) _forceFullUpdate = true;
}
@@ -433,6 +537,8 @@ void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint
if (pageNum == 0 || pageNum == 1)
addDirtyRect(x, y, w, h);
+ clearOverlayRect(pageNum, x, y, w, h);
+
while (h--) {
memcpy(dst, src, w);
dst += SCREEN_W;
@@ -463,6 +569,8 @@ void Screen::copyFromCurPageBlock(int x, int y, int w, int h, const uint8 *src)
if (_curPage == 0 || _curPage == 1)
addDirtyRect(x*8, y, w*8, h);
+ clearOverlayRect(_curPage, x*8, y, w*8, h);
+
while (h--) {
memcpy(dst, src, w*8);
dst += SCREEN_W;
@@ -547,6 +655,9 @@ void Screen::shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPag
_vm->delay(wait);
}
}
+
+ copyOverlayRegion(sx, sy, sx, sy, w, h, srcPage, dstPage);
+
if (_vm->quit()) {
copyRegion(sx, sy, sx, sy, w, h, srcPage, dstPage);
_system->updateScreen();
@@ -563,6 +674,8 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum)
if (pageNum == 0 || pageNum == 1)
addDirtyRect(x1, y1, x2-x1+1, y2-y1+1);
+
+ clearOverlayRect(pageNum, x1, y1, x2-x1+1, y2-y1+1);
for (; y1 <= y2; ++y1) {
memset(dst, color, x2 - x1 + 1);
@@ -650,6 +763,8 @@ void Screen::drawLine(bool vertical, int x, int y, int length, int color) {
if (_curPage == 0 || _curPage == 1)
addDirtyRect(x, y, (vertical) ? 1 : length, (vertical) ? length : 1);
+
+ clearOverlayRect(_curPage, x, y, (vertical) ? 1 : length, (vertical) ? length : 1);
}
void Screen::setAnimBlockPtr(int size) {
@@ -718,17 +833,21 @@ int Screen::getFontWidth() const {
return *(_fonts[_currentFont].fontData + _fonts[_currentFont].charSizeOffset + 5);
}
-int Screen::getCharWidth(uint8 c) const {
- debugC(9, kDebugLevelScreen, "Screen::getCharWidth('%c')", c);
+int Screen::getCharWidth(uint16 c) const {
+ debugC(9, kDebugLevelScreen, "Screen::getCharWidth('%c'|%d)", c & 0xFF, c);
+ if (c & 0xFF00)
+ return SJIS_CHARSIZE >> 1;
return (int)_fonts[_currentFont].charWidthTable[c] + _charWidth;
}
int Screen::getTextWidth(const char *str) const {
debugC(9, kDebugLevelScreen, "Screen::getTextWidth('%s')", str);
+
int curLineLen = 0;
int maxLineLen = 0;
while (1) {
- char c = *str++;
+ uint c = *str++;
+ c &= 0xFF;
if (c == 0) {
break;
} else if (c == '\r') {
@@ -738,9 +857,16 @@ int Screen::getTextWidth(const char *str) const {
curLineLen = 0;
}
} else {
- curLineLen += getCharWidth(c);
+ if (c <= 0x7F || !_useSJIS)
+ curLineLen += getCharWidth(c);
+ else {
+ c = READ_LE_UINT16(str - 1);
+ ++str;
+ curLineLen += getCharWidth(c);
+ }
}
}
+
return MAX(curLineLen, maxLineLen);
}
@@ -752,7 +878,8 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
setTextColor(cmap, 0, 1);
Font *fnt = &_fonts[_currentFont];
- uint8 charHeight = *(fnt->fontData + fnt->charSizeOffset + 4);
+ const uint8 charHeightFnt = *(fnt->fontData + fnt->charSizeOffset + 4);
+ uint8 charHeight = 0;
if (x < 0) {
x = 0;
@@ -767,7 +894,8 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
}
while (1) {
- char c = *str++;
+ uint c = *str++;
+ c &= 0xFF;
if (c == 0) {
break;
} else if (c == '\r') {
@@ -782,13 +910,22 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
break;
}
}
- drawChar(c, x, y);
+ if (c <= 0x7F || !_useSJIS) {
+ drawCharANSI(c, x, y);
+ charHeight = charHeightFnt;
+ } else {
+ c = READ_LE_UINT16(str - 1);
+ ++str;
+ charWidth = getCharWidth(c);
+ charHeight = SJIS_CHARSIZE >> 1;
+ drawCharSJIS(c, x, y);
+ }
x += charWidth;
}
}
}
-void Screen::drawChar(uint8 c, int x, int y) {
+void Screen::drawCharANSI(uint8 c, int x, int y) {
debugC(9, kDebugLevelScreen, "Screen::drawChar('%c', %d, %d)", c, x, y);
Font *fnt = &_fonts[_currentFont];
uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x;
@@ -856,7 +993,7 @@ void Screen::drawChar(uint8 c, int x, int y) {
}
void Screen::setScreenDim(int dim) {
- debugC(9, kDebugLevelScreen, "setScreenDim(%d)", dim);
+ debugC(9, kDebugLevelScreen, "Screen::setScreenDim(%d)", dim);
if (_vm->game() == GI_KYRA1) {
assert(dim < _screenDimTableCount);
_curDim = &_screenDimTable[dim];
@@ -1053,6 +1190,7 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
uint8 *dstStart = getPagePtr(pageNum);
if (pageNum == 0 || pageNum == 1)
addDirtyRect(x, y, x2-x1, y2-y1);
+ clearOverlayRect(pageNum, x, y, x2-x1, y2-y1);
int scaleYTable[SCREEN_H];
assert(y1 >= 0 && y2 < SCREEN_H);
@@ -1984,12 +2122,26 @@ void Screen::setMouseCursor(int x, int y, byte *shape) {
if (_vm->gameFlags().useAltShapeHeader)
shape -= 2;
+ if (_vm->gameFlags().useHiResOverlay) {
+ mouseWidth <<= 1;
+ mouseHeight <<= 1;
+ fillRect(mouseWidth, 0, mouseWidth, mouseHeight, 0, 8);
+ }
+
+
uint8 *cursor = new uint8[mouseHeight * mouseWidth];
fillRect(0, 0, mouseWidth, mouseHeight, 0, 8);
drawShape(8, shape, 0, 0, 0, 0);
+ int xOffset = 0;
+
+ if (_vm->gameFlags().useHiResOverlay) {
+ xOffset = mouseWidth;
+ scale2x(getPagePtr(8) + mouseWidth, SCREEN_W, getPagePtr(8), SCREEN_W, mouseWidth, mouseHeight);
+ }
+
CursorMan.showMouse(false);
- copyRegionToBuffer(8, 0, 0, mouseWidth, mouseHeight, cursor);
+ copyRegionToBuffer(8, xOffset, 0, mouseWidth, mouseHeight, cursor);
CursorMan.replaceCursor(cursor, mouseWidth, mouseHeight, x, y, 0);
CursorMan.showMouse(true);
delete [] cursor;
@@ -2013,6 +2165,7 @@ void Screen::copyScreenFromRect(int x, int y, int w, int h, const uint8 *ptr) {
}
addDirtyRect(x, y, w, h);
+ clearOverlayRect(0, x, y, w, h);
}
void Screen::copyScreenToRect(int x, int y, int w, int h, uint8 *ptr) {
@@ -2109,6 +2262,7 @@ void Screen::savePageToDisk(const char *file, int page) {
void Screen::loadPageFromDisk(const char *file, int page) {
debugC(9, kDebugLevelScreen, "Screen::loadPageFromDisk('%s', %d)", file, page);
copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page/2]);
+ clearOverlayRect(page, 0, 0, SCREEN_W, SCREEN_H);
delete [] _saveLoadPage[page/2];
_saveLoadPage[page/2] = 0;
}
@@ -2383,4 +2537,326 @@ void Screen::addDirtyRect(int x, int y, int w, int h) {
cur.y2 = h;
}
+// overlay functions
+
+byte *Screen::getOverlayPtr(int page) {
+ if (page == 0 || page == 1)
+ return _sjisOverlayPtrs[1];
+ else if (page == 2 || page == 3)
+ return _sjisOverlayPtrs[2];
+ else
+ return 0;
+}
+
+void Screen::clearOverlayPage(int page) {
+ byte *dst = getOverlayPtr(page);
+ if (!dst)
+ return;
+ memset(dst, 0x80, SCREEN_OVL_SJIS_SIZE);
+}
+
+void Screen::clearOverlayRect(int page, int x, int y, int w, int h) {
+ byte *dst = getOverlayPtr(page);
+
+ if (!dst || w < 0 || h < 0)
+ return;
+
+ x <<= 1; y <<= 1;
+ w <<= 1; h <<= 1;
+
+ dst += y * 640 + x;
+
+ if (w == 640 && h == 400) {
+ memset(dst, 0x80, SCREEN_OVL_SJIS_SIZE);
+ } else {
+ while (h--) {
+ memset(dst, 0x80, w);
+ dst += 640;
+ }
+ }
+}
+
+void Screen::copyOverlayRegion(int x, int y, int x2, int y2, int w, int h, int srcPage, int dstPage) {
+ byte *dst = getOverlayPtr(dstPage);
+ const byte *src = getOverlayPtr(srcPage);
+
+ if (!dst || !src)
+ return;
+
+ x <<= 1; x2 <<= 1;
+ y <<= 1; y2 <<= 1;
+ w <<= 1; h <<= 1;
+
+ dst += y2 * 640 + x2;
+ src += y * 640 + x;
+
+ while (h--) {
+ for (x = 0; x < w; ++x)
+ memcpy(dst, src, w);
+ dst += 640;
+ src += 640;
+ }
+}
+
+// SJIS rendering
+
+namespace {
+int SJIStoFMTChunk(int f, int s) { // copied from scumm\charset.cpp
+ enum {
+ KANA = 0,
+ KANJI = 1,
+ EKANJI = 2
+ };
+ int base = s - ((s + 1) % 32);
+ int c = 0, p = 0, chunk_f = 0, chunk = 0, cr = 0, kanjiType = KANA;
+
+ if (f >= 0x81 && f <= 0x84) kanjiType = KANA;
+ if (f >= 0x88 && f <= 0x9f) kanjiType = KANJI;
+ if (f >= 0xe0 && f <= 0xea) kanjiType = EKANJI;
+
+ if ((f > 0xe8 || (f == 0xe8 && base >= 0x9f)) || (f > 0x90 || (f == 0x90 && base >= 0x9f))) {
+ c = 48; //correction
+ p = -8; //correction
+ }
+
+ if (kanjiType == KANA) {//Kana
+ chunk_f = (f - 0x81) * 2;
+ } else if (kanjiType == KANJI) {//Standard Kanji
+ p += f - 0x88;
+ chunk_f = c + 2 * p;
+ } else if (kanjiType == EKANJI) {//Enhanced Kanji
+ p += f - 0xe0;
+ chunk_f = c + 2 * p;
+ }
+
+ // Base corrections
+ if (base == 0x7f && s == 0x7f)
+ base -= 0x20;
+ if (base == 0x9f && s == 0xbe)
+ base += 0x20;
+ if (base == 0xbf && s == 0xde)
+ base += 0x20;
+ //if (base == 0x7f && s == 0x9e)
+ // base += 0x20;
+
+ switch (base) {
+ case 0x3f:
+ cr = 0; //3f
+ if (kanjiType == KANA) chunk = 1;
+ else if (kanjiType == KANJI) chunk = 31;
+ else if (kanjiType == EKANJI) chunk = 111;
+ break;
+ case 0x5f:
+ cr = 0; //5f
+ if (kanjiType == KANA) chunk = 17;
+ else if (kanjiType == KANJI) chunk = 47;
+ else if (kanjiType == EKANJI) chunk = 127;
+ break;
+ case 0x7f:
+ cr = -1; //80
+ if (kanjiType == KANA) chunk = 9;
+ else if (kanjiType == KANJI) chunk = 63;
+ else if (kanjiType == EKANJI) chunk = 143;
+ break;
+ case 0x9f:
+ cr = 1; //9e
+ if (kanjiType == KANA) chunk = 2;
+ else if (kanjiType == KANJI) chunk = 32;
+ else if (kanjiType == EKANJI) chunk = 112;
+ break;
+ case 0xbf:
+ cr = 1; //be
+ if (kanjiType == KANA) chunk = 18;
+ else if (kanjiType == KANJI) chunk = 48;
+ else if (kanjiType == EKANJI) chunk = 128;
+ break;
+ case 0xdf:
+ cr = 1; //de
+ if (kanjiType == KANA) chunk = 10;
+ else if (kanjiType == KANJI) chunk = 64;
+ else if (kanjiType == EKANJI) chunk = 144;
+ break;
+ default:
+ debug(4, "Invalid Char! f %x s %x base %x c %d p %d", f, s, base, c, p);
+ return 0;
+ }
+
+ debug(6, "Kanji: %c%c f 0x%x s 0x%x base 0x%x c %d p %d chunk %d cr %d index %d", f, s, f, s, base, c, p, chunk, cr, ((chunk_f + chunk) * 32 + (s - base)) + cr);
+ return ((chunk_f + chunk) * 32 + (s - base)) + cr;
+}
+} // end of anonymous namespace
+
+void Screen::drawCharSJIS(uint16 c, int x, int y) {
+ debugC(9, kDebugLevelScreen, "Screen::drawCharSJIS('%c', %d, %d)", c, x, y);
+
+ int color1 = _textColorsMap[1];
+ int color2 = _textColorsMap[0];
+
+ memset(_sjisTempPage2, 0x80, 324);
+ memset(_sjisSourceChar, 0, 36);
+ memcpy(_sjisSourceChar, _sjisFontData + 0x20 * SJIStoFMTChunk(c & 0xff, c >> 8), 0x20);
+
+ if (_curPage == 0 || _curPage == 1)
+ addDirtyRect(x, y, SJIS_CHARSIZE >> 1, SJIS_CHARSIZE >> 1);
+
+ x <<= 1;
+ y <<= 1;
+
+ uint8 *destPage = getOverlayPtr(_curPage);
+ if (!destPage) {
+ warning("trying to draw SJIS char on unsupported page %d", _curPage);
+ return;
+ }
+
+ destPage += y * 640 + x;
+ uint8 *src = 0, *dst = 0;
+
+ if (color2 != 0x80) {
+ // draw color2 shadow
+ src = _sjisSourceChar;
+ dst = _sjisTempPage2;
+
+ for (int i = 0; i < SJIS_CHARSIZE; i++) {
+ *((uint16*)dst) = READ_LE_UINT16(src);
+ dst += 2; src += 2;
+ *dst++ = 0;
+ }
+
+ src = _sjisTempPage2;
+ dst = _sjisTempPage;
+ memset(dst, 0, 60);
+ for (int i = 0; i < 48; i++)
+ *dst++ |= *src++;
+
+ src = _sjisTempPage2;
+ dst = _sjisTempPage + 3;
+ for (int i = 0; i < 48; i++)
+ *dst++ |= *src++;
+
+ src = _sjisTempPage2;
+ dst = _sjisTempPage + 6;
+ for (int i = 0; i < 48; i++)
+ *dst++ |= *src++;
+
+ for (int i = 0; i < 2; i++) {
+ src = _sjisTempPage;
+ for (int ii = 0; ii < SJIS_CHARSIZE; ii++) {
+ uint8 cy2 = 0;
+ uint8 cy1 = 0;
+ for (int iii = 0; iii < 3; iii++) {
+ cy1 = *src & 1;
+ *src |= ((*src >> 1) | (cy2 << 7));
+ cy2 = cy1;
+ src++;
+ }
+ }
+ }
+
+ src = _sjisTempPage2;
+ for (int i = 0; i < SJIS_CHARSIZE; i++) {
+ uint8 cy2 = 0;
+ uint8 cy1 = 0;
+ for (int ii = 0; ii < 3; ii++) {
+ cy1 = *src & 1;
+ *src = ((*src >> 1) | (cy2 << 7));
+ cy2 = cy1;
+ src++;
+ }
+ }
+
+ src = _sjisTempPage2;
+ dst = _sjisTempPage + 3;
+ for (int i = 0; i < 48; i++)
+ *dst++ ^= *src++;
+
+ memset(_sjisTempPage2, 0x80, 324);
+ src = _sjisTempPage;
+ dst = _sjisTempPage2;
+
+ uint8 height = SJIS_CHARSIZE * 3;
+ uint8 width = SJIS_CHARSIZE;
+ if (color2 & 0xff00) {
+ height -= 3;
+ width--;
+ dst += 0x13;
+ }
+
+ for (int i = 0; i < height; i++) {
+ uint8 rs = *src++;
+ for (int ii = 0; ii < 8; ii++) {
+ if (rs & 0x80)
+ *dst = (color2 & 0xff);
+ rs <<= 1;
+ dst++;
+
+ if (!--width) {
+ width = SJIS_CHARSIZE;
+ if (color2 & 0xff00) {
+ width--;
+ dst++;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ // draw color1 char
+ src = _sjisSourceChar;
+ dst = _sjisTempPage;
+
+ for (int i = 0; i < SJIS_CHARSIZE; i++) {
+ *(uint16*)dst = READ_LE_UINT16(src);
+ dst += 2; src += 2;
+ *dst++ = 0;
+ }
+
+ src = _sjisTempPage;
+ dst = _sjisTempPage2;
+ if (color2 != 0x80)
+ color1 = (color1 & 0xff) | 0x100;
+
+ uint8 height = SJIS_CHARSIZE * 3;
+ uint8 width = SJIS_CHARSIZE;
+ if (color1 & 0xff00) {
+ height -= 3;
+ width--;
+ dst += 0x13;
+ }
+
+ for (int i = 0; i < height; i++) {
+ uint8 rs = *src++;
+ for (int ii = 0; ii < 8; ii++) {
+ if (rs & 0x80)
+ *dst = (color1 & 0xff);
+ rs <<= 1;
+ dst++;
+
+ if (!--width) {
+ width = SJIS_CHARSIZE;
+ if (color1 & 0xff00) {
+ width--;
+ dst++;
+ }
+ break;
+ }
+ }
+ }
+
+ // copy char to surface
+ src = _sjisTempPage2;
+ dst = destPage;
+ int pitch = 640 - SJIS_CHARSIZE;
+
+ for (int i = 0; i < SJIS_CHARSIZE; i++) {
+ for (int ii = 0; ii < SJIS_CHARSIZE; ii++) {
+ if (*src != 0x80)
+ *dst = *src;
+ src++;
+ dst++;
+ }
+ dst += pitch;
+ }
+}
+
} // End of namespace Kyra
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index f9e0a7264f..e8823bb8f2 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -61,7 +61,9 @@ public:
SCREEN_W = 320,
SCREEN_H = 200,
SCREEN_PAGE_SIZE = 320 * 200 + 1024,
- SCREEN_PAGE_NUM = 16
+ SCREEN_OVL_SJIS_SIZE = 640 * 400,
+ SCREEN_PAGE_NUM = 16,
+ SCREEN_OVLS_NUM = 3
};
enum CopyRegionFlags {
@@ -149,11 +151,10 @@ public:
int getFontHeight() const;
int getFontWidth() const;
- int getCharWidth(uint8 c) const;
+ int getCharWidth(uint16 c) const;
int getTextWidth(const char *str) const;
void printText(const char *str, int x, int y, uint8 color1, uint8 color2);
- void drawChar(uint8 c, int x, int y);
void setTextColorMap(const uint8 *cmap);
void setTextColor(const uint8 *cmap, int a, int b);
@@ -240,6 +241,25 @@ public:
private:
uint8 *getPagePtr(int pageNum);
void updateDirtyRects();
+ void updateDirtyRectsOvl();
+
+ void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h);
+ void mergeOverlay(int x, int y, int w, int h);
+
+ // overlay specific
+ byte *getOverlayPtr(int pageNum);
+ void clearOverlayPage(int pageNum);
+ void clearOverlayRect(int pageNum, int x, int y, int w, int h);
+ void copyOverlayRegion(int x, int y, int x2, int y2, int w, int h, int srcPage, int dstPage);
+
+ // font/text specific
+ void drawCharANSI(uint8 c, int x, int y);
+ void drawCharSJIS(uint16 c, int x, int y);
+
+ enum {
+ SJIS_CHARSIZE = 18,
+ SJIS_CHARS = 8192
+ };
int16 encodeShapeAndCalculateSize(uint8 *from, uint8 *to, int size);
void restoreMouseRect();
@@ -250,15 +270,30 @@ private:
template<bool noXor> static void wrapped_decodeFrameDeltaPage(uint8 *dst, const uint8 *src, const int pitch);
uint8 *_pagePtrs[16];
+ uint8 *_sjisOverlayPtrs[SCREEN_OVLS_NUM];
+
+ bool _useOverlays;
+ bool _useSJIS;
+
+ uint8 *_sjisFontData;
+ uint8 *_sjisTempPage;
+ uint8 *_sjisTempPage2;
+ uint8 *_sjisSourceChar;
+
uint8 *_saveLoadPage[8];
+
uint8 *_screenPalette;
uint8 *_palettes[3];
+
Font _fonts[FID_NUM];
uint8 _textColorsMap[16];
+
uint8 *_decodeShapeBuffer;
int _decodeShapeBufferSize;
+
uint8 *_animBlockPtr;
int _animBlockSize;
+
int _mouseLockCount;
Rect *_bitBlitRects;
diff --git a/engines/kyra/script_v1.cpp b/engines/kyra/script_v1.cpp
index 0551d2aab2..a3b6997384 100644
--- a/engines/kyra/script_v1.cpp
+++ b/engines/kyra/script_v1.cpp
@@ -717,7 +717,10 @@ int KyraEngine::o1_copyWSARegion(ScriptState *script) {
int KyraEngine::o1_printText(ScriptState *script) {
debugC(3, kDebugLevelScriptFuncs, "o1_printText(%p) ('%s', %d, %d, 0x%X, 0x%X)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
- _screen->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
+ if (_flags.lang == Common::JA_JPN && stackPos(3) == 7)
+ _screen->printText(stackPosString(0), stackPos(1), stackPos(2), 0, 0x80);
+ else
+ _screen->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
_screen->updateScreen();
return 0;
}
diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp
index af173cad44..1614d9e76b 100644
--- a/engines/kyra/seqplayer.cpp
+++ b/engines/kyra/seqplayer.cpp
@@ -598,9 +598,11 @@ bool SeqPlayer::playSequence(const uint8 *seqData, bool skipSeq) {
// used in Kallak writing intro
if (_seqDisplayTextFlag && _seqDisplayedTextTimer != 0xFFFFFFFF) {
if (_seqDisplayedTextTimer < _system->getMillis()) {
- char charStr[2];
+ char charStr[3];
charStr[0] = _vm->seqTextsTable()[_seqDisplayedText][_seqDisplayedChar];
- charStr[1] = '\0';
+ charStr[1] = charStr[2] = '\0';
+ if (_vm->gameFlags().lang == Common::JA_JPN)
+ charStr[1] = _vm->seqTextsTable()[_seqDisplayedText][++_seqDisplayedChar];
_screen->printText(charStr, _seqDisplayedTextX, 180, 0xF, 0xC);
_seqDisplayedTextX += _screen->getCharWidth(charStr[0]);
++_seqDisplayedChar;
diff --git a/engines/kyra/sequences_v1.cpp b/engines/kyra/sequences_v1.cpp
index 64a8d94b99..07c44b4fe7 100644
--- a/engines/kyra/sequences_v1.cpp
+++ b/engines/kyra/sequences_v1.cpp
@@ -211,7 +211,7 @@ void KyraEngine::seq_introStory() {
return;
} else if (_flags.lang == Common::EN_ANY && _flags.platform == Common::kPlatformPC) {
_screen->loadBitmap("TEXT.CPS", 3, 3, 0);
- } else if (_flags.lang == Common::EN_ANY) {
+ } else if (_flags.lang == Common::EN_ANY || _flags.lang == Common::JA_JPN) {
_screen->loadBitmap("TEXT_ENG.CPS", 3, 3, 0);
} else if (_flags.lang == Common::DE_DEU) {
_screen->loadBitmap("TEXT_GER.CPS", 3, 3, 0);
@@ -225,6 +225,20 @@ void KyraEngine::seq_introStory() {
warning("no story graphics file found");
}
_screen->copyRegion(0, 0, 0, 0, 320, 200, 3, 0);
+
+ if (_flags.lang == Common::JA_JPN) {
+ const int x1 = (Screen::SCREEN_W - _screen->getTextWidth(_seq_textsTable[18])) / 2;
+ const int x2 = (Screen::SCREEN_W - _screen->getTextWidth(_seq_textsTable[19])) / 2;
+ const int y1 = 175;
+ const int y2 = 184;
+
+ uint8 colorMap[] = { 0, 15, 12, 12 };
+ _screen->setTextColor(colorMap, 0, 3);
+
+ _screen->printText(_seq_textsTable[18], x1, y1, 5, 8);
+ _screen->printText(_seq_textsTable[19], x2, y2, 5, 8);
+ }
+
_screen->updateScreen();
//debugC(0, kDebugLevelMain, "skipFlag %i, %i", _skipFlag, _tickLength);
delay(360 * _tickLength);
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 4d4e8811f6..32226d330e 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -31,7 +31,7 @@
namespace Kyra {
-#define RESFILE_VERSION 15
+#define RESFILE_VERSION 16
bool StaticResource::checkKyraDat() {
Common::File kyraDat;
@@ -235,7 +235,7 @@ bool StaticResource::init() {
delete [] temp;
temp = 0;
- if (version < RESFILE_VERSION) {
+ if (version != RESFILE_VERSION) {
error("invalid KYRA.DAT file version (%d, required %d)", version, RESFILE_VERSION);
}
if (gameID != _engine->game()) {
@@ -840,7 +840,7 @@ void KyraEngine::loadMainScreen(int page) {
if (_flags.lang == Common::EN_ANY && !_flags.isTalkie && _flags.platform == Common::kPlatformPC)
_screen->loadBitmap("MAIN15.CPS", page, page, 0);
- else if (_flags.lang == Common::EN_ANY)
+ else if (_flags.lang == Common::EN_ANY || _flags.lang == Common::JA_JPN)
_screen->loadBitmap("MAIN_ENG.CPS", page, page, 0);
else if (_flags.lang == Common::FR_FRA)
_screen->loadBitmap("MAIN_FRE.CPS", page, page, 0);
diff --git a/engines/kyra/text.cpp b/engines/kyra/text.cpp
index 4f6ad3674a..4433330c1a 100644
--- a/engines/kyra/text.cpp
+++ b/engines/kyra/text.cpp
@@ -29,6 +29,7 @@
#include "kyra/sprites.h"
#include "common/system.h"
+#include "common/endian.h"
namespace Kyra {
@@ -395,8 +396,9 @@ void KyraEngine::updateTextFade() {
}
}
-TextDisplayer::TextDisplayer(Screen *screen) {
+TextDisplayer::TextDisplayer(KyraEngine *vm, Screen *screen) {
_screen = screen;
+ _vm = vm;
_talkCoords.y = 0x88;
_talkCoords.x = 0;
@@ -430,6 +432,12 @@ int TextDisplayer::getCharLength(const char *str, int len) {
Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
int i = 0;
while (i <= len && *str) {
+ uint c = *str++;
+ c &= 0xFF;
+ if (c >= 0x7F && _vm->gameFlags().lang == Common::JA_JPN) {
+ c = READ_LE_UINT16(str - 1);
+ ++str;
+ }
i += _screen->getCharWidth(*str++);
++charsCount;
}
diff --git a/engines/kyra/text.h b/engines/kyra/text.h
index 725e4c3a1a..977e2290c4 100644
--- a/engines/kyra/text.h
+++ b/engines/kyra/text.h
@@ -25,6 +25,7 @@
namespace Kyra {
class Screen;
+class KyraEngine;
class FontId;
class TextDisplayer {
@@ -37,7 +38,7 @@ class TextDisplayer {
TALK_SUBSTRING_NUM = 3
};
public:
- TextDisplayer(Screen *screen);
+ TextDisplayer(KyraEngine *vm, Screen *screen);
~TextDisplayer() {}
void setTalkCoords(uint16 y);
@@ -60,6 +61,7 @@ public:
bool printed() const { return _talkMessagePrinted; }
private:
Screen *_screen;
+ KyraEngine *_vm;
char _talkBuffer[300];
char _talkSubstrings[TALK_SUBSTRING_LEN * TALK_SUBSTRING_NUM];