aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
authorMartin Kiewitz2014-11-04 22:01:21 +0100
committerMartin Kiewitz2014-11-04 22:01:21 +0100
commiteff78c442474185ecb1bde59bfc54c276178c480 (patch)
tree583021de254265f55a71e057cb5441973a3a4d48 /engines/sci/engine
parentad8dbd364203a463fbae935b751cf96f76c38cf5 (diff)
downloadscummvm-rg350-eff78c442474185ecb1bde59bfc54c276178c480.tar.gz
scummvm-rg350-eff78c442474185ecb1bde59bfc54c276178c480.tar.bz2
scummvm-rg350-eff78c442474185ecb1bde59bfc54c276178c480.zip
SCI: fix Japanese Space Quest 4 (intro + buttons)
At least SQ4 uses #j text prefix as signal for the interpreter to not use the PC9801 hires font, but to use the internal low res font instead
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/kgraphics.cpp33
-rw-r--r--engines/sci/engine/state.cpp84
2 files changed, 72 insertions, 45 deletions
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index c2089bcd4d..ee2249bd9d 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -354,13 +354,16 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
}
textWidth = dest[3].toUint16(); textHeight = dest[2].toUint16();
+
+ uint16 languageSplitter = 0;
+ Common::String splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter, sep);
#ifdef ENABLE_SCI32
if (g_sci->_gfxText32)
- g_sci->_gfxText32->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight);
+ g_sci->_gfxText32->kernelTextSize(splitText.c_str(), font_nr, maxwidth, &textWidth, &textHeight);
else
#endif
- g_sci->_gfxText16->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight);
+ g_sci->_gfxText16->kernelTextSize(splitText.c_str(), languageSplitter, font_nr, maxwidth, &textWidth, &textHeight);
// One of the game texts in LB2 German contains loads of spaces in
// its end. We trim the text here, otherwise the graphics code will
@@ -376,7 +379,7 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
// Copy over the trimmed string...
s->_segMan->strcpy(argv[1], text.c_str());
// ...and recalculate bounding box dimensions
- g_sci->_gfxText16->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight);
+ g_sci->_gfxText16->kernelTextSize(splitText.c_str(), languageSplitter, font_nr, maxwidth, &textWidth, &textHeight);
}
}
@@ -818,16 +821,29 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
if (!textReference.isNull())
text = s->_segMan->getString(textReference);
+ uint16 languageSplitter = 0;
+ Common::String splitText;
+
+ switch (type) {
+ case SCI_CONTROLS_TYPE_BUTTON:
+ case SCI_CONTROLS_TYPE_TEXTEDIT:
+ splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter, NULL);
+ break;
+ case SCI_CONTROLS_TYPE_TEXT:
+ splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter);
+ break;
+ }
+
switch (type) {
case SCI_CONTROLS_TYPE_BUTTON:
debugC(kDebugLevelGraphics, "drawing button %04x:%04x to %d,%d", PRINT_REG(controlObject), x, y);
- g_sci->_gfxControls16->kernelDrawButton(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, style, hilite);
+ g_sci->_gfxControls16->kernelDrawButton(rect, controlObject, splitText.c_str(), languageSplitter, fontId, style, hilite);
return;
case SCI_CONTROLS_TYPE_TEXT:
alignment = readSelectorValue(s->_segMan, controlObject, SELECTOR(mode));
debugC(kDebugLevelGraphics, "drawing text %04x:%04x ('%s') to %d,%d, mode=%d", PRINT_REG(controlObject), text.c_str(), x, y, alignment);
- g_sci->_gfxControls16->kernelDrawText(rect, controlObject, g_sci->strSplit(text.c_str()).c_str(), fontId, alignment, style, hilite);
+ g_sci->_gfxControls16->kernelDrawText(rect, controlObject, splitText.c_str(), languageSplitter, fontId, alignment, style, hilite);
s->r_acc = g_sci->_gfxText16->allocAndFillReferenceRectArray();
return;
@@ -841,7 +857,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
writeSelectorValue(s->_segMan, controlObject, SELECTOR(cursor), cursorPos);
}
debugC(kDebugLevelGraphics, "drawing edit control %04x:%04x (text %04x:%04x, '%s') to %d,%d", PRINT_REG(controlObject), PRINT_REG(textReference), text.c_str(), x, y);
- g_sci->_gfxControls16->kernelDrawTextEdit(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, mode, style, cursorPos, maxChars, hilite);
+ g_sci->_gfxControls16->kernelDrawTextEdit(rect, controlObject, splitText.c_str(), languageSplitter, fontId, mode, style, cursorPos, maxChars, hilite);
return;
case SCI_CONTROLS_TYPE_ICON:
@@ -1165,8 +1181,11 @@ reg_t kDisplay(EngineState *s, int argc, reg_t *argv) {
argc--; argc--; argv++; argv++;
text = g_sci->getKernel()->lookupText(textp, index);
}
+
+ uint16 languageSplitter = 0;
+ Common::String splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter);
- return g_sci->_gfxPaint16->kernelDisplay(g_sci->strSplit(text.c_str()).c_str(), argc, argv);
+ return g_sci->_gfxPaint16->kernelDisplay(splitText.c_str(), languageSplitter, argc, argv);
}
reg_t kSetVideoMode(EngineState *s, int argc, reg_t *argv) {
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index 1b7fa7699e..c07dc925e0 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -203,37 +203,45 @@ static kLanguage charToLanguage(const char c) {
}
}
-Common::String SciEngine::getSciLanguageString(const Common::String &str, kLanguage lang, kLanguage *lang2) const {
- kLanguage secondLang = K_LANG_NONE;
-
- const char *seeker = str.c_str();
- while (*seeker) {
- if ((*seeker == '%') || (*seeker == '#')) {
- secondLang = charToLanguage(*(seeker + 1));
-
- if (secondLang != K_LANG_NONE)
+Common::String SciEngine::getSciLanguageString(const Common::String &str, kLanguage requestedLanguage, kLanguage *secondaryLanguage, uint16 *languageSplitter) const {
+ kLanguage foundLanguage = K_LANG_NONE;
+ const byte *textPtr = (byte *)str.c_str();
+ byte curChar = 0;
+ byte curChar2 = 0;
+
+ while (1) {
+ curChar = *textPtr;
+ if (!curChar)
+ break;
+
+ if ((curChar == '%') || (curChar == '#')) {
+ curChar2 = *(textPtr + 1);
+ foundLanguage = charToLanguage(curChar2);
+
+ if (foundLanguage != K_LANG_NONE) {
+ // Return language splitter
+ if (languageSplitter)
+ *languageSplitter = curChar | ( curChar2 << 8 );
+ // Return the secondary language found in the string
+ if (secondaryLanguage)
+ *secondaryLanguage = foundLanguage;
break;
+ }
}
-
- ++seeker;
+ textPtr++;
}
- // Return the secondary language found in the string
- if (lang2)
- *lang2 = secondLang;
-
- if (secondLang == lang) {
- if (*(++seeker) == 'J') {
+ if (foundLanguage == requestedLanguage) {
+ if (curChar2 == 'J') {
// Japanese including Kanji, displayed with system font
// Convert half-width characters to full-width equivalents
Common::String fullWidth;
- byte curChar, curChar2;
uint16 mappedChar;
- seeker++;
+ textPtr += 2; // skip over language splitter
while (1) {
- curChar = *(seeker);
+ curChar = *textPtr;
switch (curChar) {
case 0: // Terminator NUL
@@ -243,7 +251,7 @@ Common::String SciEngine::getSciLanguageString(const Common::String &str, kLangu
// inside GetLongest() (text16). We do it here, because it's much cleaner and
// we have to process the text here anyway.
// Occurs for example in Police Quest 2 intro
- curChar2 = *(seeker + 1);
+ curChar2 = *(textPtr + 1);
switch (curChar2) {
case 'n':
case 'N':
@@ -251,12 +259,12 @@ Common::String SciEngine::getSciLanguageString(const Common::String &str, kLangu
case 'R':
fullWidth += ' ';
fullWidth += 0x0D; // CR
- seeker += 2;
+ textPtr += 2;
continue;
}
}
- seeker++;
+ textPtr++;
mappedChar = s_halfWidthSJISMap[curChar];
if (mappedChar) {
@@ -264,7 +272,7 @@ Common::String SciEngine::getSciLanguageString(const Common::String &str, kLangu
fullWidth += mappedChar & 0xFF;
} else {
// Copy double-byte character
- curChar2 = *(seeker++);
+ curChar2 = *(textPtr++);
if (!curChar) {
error("SJIS character %02X is missing second byte", curChar);
break;
@@ -275,14 +283,14 @@ Common::String SciEngine::getSciLanguageString(const Common::String &str, kLangu
}
} else {
- return Common::String(seeker + 1);
+ return Common::String((const char *)(textPtr + 2));
}
}
- if (*seeker)
- return Common::String(str.c_str(), seeker - str.c_str());
- else
- return str;
+ if (curChar)
+ return Common::String(str.c_str(), (const char *)textPtr - str.c_str());
+
+ return str;
}
kLanguage SciEngine::getSciLanguage() {
@@ -341,25 +349,25 @@ void SciEngine::setSciLanguage() {
setSciLanguage(getSciLanguage());
}
-Common::String SciEngine::strSplit(const char *str, const char *sep) {
- kLanguage lang = getSciLanguage();
- kLanguage subLang = K_LANG_NONE;
+Common::String SciEngine::strSplitLanguage(const char *str, uint16 *languageSplitter, const char *sep) {
+ kLanguage activeLanguage = getSciLanguage();
+ kLanguage subtitleLanguage = K_LANG_NONE;
if (SELECTOR(subtitleLang) != -1)
- subLang = (kLanguage)readSelectorValue(_gamestate->_segMan, _gameObjectAddress, SELECTOR(subtitleLang));
+ subtitleLanguage = (kLanguage)readSelectorValue(_gamestate->_segMan, _gameObjectAddress, SELECTOR(subtitleLang));
- kLanguage secondLang;
- Common::String retval = getSciLanguageString(str, lang, &secondLang);
+ kLanguage foundLanguage;
+ Common::String retval = getSciLanguageString(str, activeLanguage, &foundLanguage, languageSplitter);
// Don't add subtitle when separator is not set, subtitle language is not set, or
// string contains only one language
- if ((sep == NULL) || (subLang == K_LANG_NONE) || (secondLang == K_LANG_NONE))
+ if ((sep == NULL) || (subtitleLanguage == K_LANG_NONE) || (foundLanguage == K_LANG_NONE))
return retval;
// Add subtitle, unless the subtitle language doesn't match the languages in the string
- if ((subLang == K_LANG_ENGLISH) || (subLang == secondLang)) {
+ if ((subtitleLanguage == K_LANG_ENGLISH) || (subtitleLanguage == foundLanguage)) {
retval += sep;
- retval += getSciLanguageString(str, subLang);
+ retval += getSciLanguageString(str, subtitleLanguage);
}
return retval;