[Scummvm-git-logs] scummvm master -> b76fb0a60453961489e2c6be9e14f4561b42e05e
bluegr
noreply at scummvm.org
Sat Nov 15 12:04:09 UTC 2025
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
172a287cc2 SCI: (PQ2/PC98) - fix bug no. 16329
0b2607deb6 SCI: (PQ2/PC98) - kDisplay hi-res font drawing fix
b76fb0a604 SCI: (PQ2/PC98) - fix Japanese line breaks and lang splits
Commit: 172a287cc2835f2657954edebe6647974c34ce70
https://github.com/scummvm/scummvm/commit/172a287cc2835f2657954edebe6647974c34ce70
Author: athrxx (athrxx at scummvm.org)
Date: 2025-11-15T14:04:05+02:00
Commit Message:
SCI: (PQ2/PC98) - fix bug no. 16329
ScummVM determines the text type (SJIS or ASCII) for each
text line from the first character. PQ2 has text lines that start
with a normal (single-byte) space character, so the engine
thinks that the whole line is ASCII even if the rest consists
only of multi-byte characters.
This fix here is not based on disasm, since our code seems
to be derived from QFQ and other later PC-98 interpreters.
Original PQ2 is more rudimentary and does certain things
differently. It just would not need any handling like this.
The method for the fix has been agreed on in the bug
tracker discussion.
Changed paths:
engines/sci/graphics/text16.cpp
diff --git a/engines/sci/graphics/text16.cpp b/engines/sci/graphics/text16.cpp
index c01f54dc7d8..14830dca47d 100644
--- a/engines/sci/graphics/text16.cpp
+++ b/engines/sci/graphics/text16.cpp
@@ -593,10 +593,31 @@ void GfxText16::Box(const char *text, uint16 languageSplitter, bool show, const
maxTextWidth = 0;
while (*curTextPos) {
- // We need to check for Shift-JIS every line
- // Police Quest 2 PC-9801 often draws English + Japanese text during the same call
- if (g_sci->getLanguage() == Common::JA_JPN)
- doubleByteMode = SwitchToFont900OnSjis(curTextPos, languageSplitter);
+ // We need to check for Shift-JIS every line. Police Quest 2 PC-9801 often draws English + Japanese text into the same box.
+ if (g_sci->getLanguage() == Common::JA_JPN) {
+ doubleByteMode = SwitchToFont900OnSjis(curTextPos, languageSplitter) ||
+
+ // Ignore leading space characters for PQ2 PC-9801, so as not to break the Japanese F1 help screen. These text lines
+ // start with a normal (single-byte) space character which is followed by SJIS text.
+ //
+ // The original PQ 2 PC-9801 interpreter's SJIS text drawing method is less sophisticated than what the other PC-9801
+ // interpreters do. It doesn't even do this font change. It just keeps the English font and uses that to (wrongfully)
+ // measure the width of the Japanese text. This appears to be the main reason why the text layout looks different in
+ // the original and in ScummVM in some places (first obvious example: the copy protection dialogs; also, in the
+ // Japanese F1 help box, the headline is not centered at the exact same position as with the original interpreter).
+ //
+ // Also, the original PQ 2 PC-9801 interpreter doesn't need to prevent background graphics updates, since the SJIS
+ // text is drawn in PC-9801 text mode and the text mode layer is always displayed on top of the graphics layer, so it
+ // can never get corrupted by graphics updates (with an emulator you can see how even the mouse cursor is drawn under
+ // the Japanese text).
+ //
+ // In contrast to that, we do the font switching for PQ2 (we could eventually try to aim for a faithful text measuring
+ // and positioning, but it is more complex than just dropping the font switching) and we also need to prevent graphics
+ // updates for SJIS lines, since we don't emulate the PC-9801 text mode layer to that extent (could be done, but I
+ // don't see why we should). So, here we ignore leading space characters and determine the ASCII or SJIS text line type
+ // by the character after that...
+ (g_sci->getGameId() == GID_PQ2 && *curTextPos == ' ' && curTextPos[1] != '\0' && SwitchToFont900OnSjis(curTextPos + 1, languageSplitter));
+ }
int16 charCount = GetLongest(curTextPos, rect.width(), fontId);
if (charCount == 0)
@@ -644,9 +665,10 @@ void GfxText16::Box(const char *text, uint16 languageSplitter, bool show, const
curTextLine = textString.c_str();
}
- // This seems to be the method used by the original PC-98 interpreters. They will set the `show`
- // argument (only) for the SCI_CONTROLS_TYPE_TEXT, but then there is a separate code path for
- // the SJIS characters, which will not get the screen surface update (since they get drawn directly).
+ // This seems to be the method used by the original (non-PQ2) PC-9801 interpreters. They will set
+ // the `show` argument (only) for the SCI_CONTROLS_TYPE_TEXT, but then there is a separate code
+ // path for the SJIS characters, which will not get the screen surface update (since they get
+ // rendered directly into the video memory). We handle PQ2 the same way as the other PC-9801 targets.
if (show && !doubleByteMode) {
Show(curTextLine, 0, charCount, fontId, previousPenColor);
} else {
Commit: 0b2607deb619d13c226ef79bf74b568e115d5e88
https://github.com/scummvm/scummvm/commit/0b2607deb619d13c226ef79bf74b568e115d5e88
Author: athrxx (athrxx at scummvm.org)
Date: 2025-11-15T14:04:05+02:00
Commit Message:
SCI: (PQ2/PC98) - kDisplay hi-res font drawing fix
(extend the fix that was already there for the Korean fan
translations to PQ2/PC98)
Changed paths:
engines/sci/graphics/paint16.cpp
diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp
index b7206e9c58a..2e901e8d9ed 100644
--- a/engines/sci/graphics/paint16.cpp
+++ b/engines/sci/graphics/paint16.cpp
@@ -589,15 +589,17 @@ reg_t GfxPaint16::kernelDisplay(const char *text, uint16 languageSplitter, int a
_ports->penColor(colorPen);
}
- // To make sure that the Korean hires font does not get overdrawn we update the display area before printing
- // the text. The PC-98 versions use a lowres font here, so this fix is only for the Korean fan translation.
- if (g_sci->getLanguage() == Common::KO_KOR && !_screen->_picNotValid && bRedraw)
+ // To make sure that the hires font used by PQ2 PC-98 and by the Korean fan translations does not get overdrawn we update the
+ // display area before printing the text. The other (non-PQ2) PC-98 versions use a lowres font here, so this fix is only for
+ // PQ2 PC-98 and for the Korean fan translations.
+ bool needCJKFix = (g_sci->getLanguage() == Common::KO_KOR || (g_sci->getPlatform() == Common::kPlatformPC98 && g_sci->getGameId() == GID_PQ2));
+ if (needCJKFix && !_screen->_picNotValid && bRedraw)
bitsShow(rect);
- _text16->Box(text, languageSplitter, g_sci->getLanguage() == Common::KO_KOR, rect, alignment, -1);
+ _text16->Box(text, languageSplitter, needCJKFix, rect, alignment, -1);
// See comment above.
- if (g_sci->getLanguage() != Common::KO_KOR && _screen->_picNotValid == 0 && bRedraw)
+ if (!needCJKFix && _screen->_picNotValid == 0 && bRedraw)
bitsShow(rect);
// restoring port and cursor pos
Commit: b76fb0a60453961489e2c6be9e14f4561b42e05e
https://github.com/scummvm/scummvm/commit/b76fb0a60453961489e2c6be9e14f4561b42e05e
Author: athrxx (athrxx at scummvm.org)
Date: 2025-11-15T14:04:05+02:00
Commit Message:
SCI: (PQ2/PC98) - fix Japanese line breaks and lang splits
Unlike the other PC-98 versions, PQ2 does not convert one-byte characters
into two-byte variants. In our case, the escaped linebreaks ("\n") would be
converted to the SJIS version of that, thus corrupting these line breaks.
Also, PQ2, does not use the "\r----------\r" separator.
Changed paths:
engines/sci/engine/kgraphics.cpp
engines/sci/engine/state.cpp
engines/sci/graphics/text16.cpp
engines/sci/sci.h
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index d7b3f744f20..325ceb7771d 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -919,7 +919,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter, nullptr);
break;
case SCI_CONTROLS_TYPE_TEXT:
- splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter);
+ splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter, g_sci->getGameId() == GID_PQ2 ? "\r" : "\r----------\r");
break;
default:
break;
@@ -1276,7 +1276,7 @@ reg_t kDisplay(EngineState *s, int argc, reg_t *argv) {
}
uint16 languageSplitter = 0;
- Common::String splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter);
+ Common::String splitText = g_sci->strSplitLanguage(text.c_str(), &languageSplitter, g_sci->getGameId() == GID_PQ2 ? "\r" : "\r----------\r");
return g_sci->_gfxPaint16->kernelDisplay(splitText.c_str(), languageSplitter, argc, argv);
}
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index 6956e758844..f00de2eed46 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -252,9 +252,10 @@ Common::String SciEngine::getSciLanguageString(const Common::String &str, kLangu
}
if (foundLanguage == requestedLanguage) {
- if (curChar2 == 'J') {
+ if (curChar2 == 'J' && g_sci->getGameId() != GID_PQ2) {
// Japanese including Kanji, displayed with system font
- // Convert half-width characters to full-width equivalents
+ // Convert half-width characters to full-width equivalents.
+ // PQ2 does not do this.
Common::String fullWidth;
textPtr += 2; // skip over language splitter
diff --git a/engines/sci/graphics/text16.cpp b/engines/sci/graphics/text16.cpp
index 14830dca47d..515e4562256 100644
--- a/engines/sci/graphics/text16.cpp
+++ b/engines/sci/graphics/text16.cpp
@@ -242,7 +242,7 @@ int16 GfxText16::GetLongest(const char *&textPtr, int16 maxWidth, GuiResourceId
if ((*(const byte *)(textPtr + 1)) == 0xA) {
curCharCount++; textPtr++;
}
- // fall through
+ // fall through'J'
case 0xA:
case 0x9781: // this one is used by SQ4/japanese as line break as well (was added for SCI1/PC98)
curCharCount++; textPtr++;
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index c82a2286246..b605e539686 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -279,8 +279,8 @@ public:
* If nullptr is passed then no subtitle will be added to the returned string.
* @return The processed string.
*/
- Common::String strSplitLanguage(const char *str, uint16 *splitLanguage, const char *sep = "\r----------\r");
- Common::String strSplit(const char *str, const char *sep = "\r----------\r") {
+ Common::String strSplitLanguage(const char *str, uint16 *splitLanguage, const char *sep);
+ Common::String strSplit(const char *str, const char *sep) {
return strSplitLanguage(str, NULL, sep);
}
More information about the Scummvm-git-logs
mailing list