[Scummvm-git-logs] scummvm master -> a728a5aee1893ea7f55308a74cc1305b4ef36300
sev-
noreply at scummvm.org
Mon Feb 27 23:40:41 UTC 2023
This automated email contains information about 23 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
e53cc43272 SHERLOCK: Enable Chinese serrated scalpel
c4da7fffdf SHERLOCK: Skip images with negative sizes
47cbf56d94 GRAPHICS: Extract big5 renderer from sky into common graphics code
7daa2b5d85 SHERLOCK: Add rendering of Serrated scalpel chinese texts
518b96f24f SHERLOCK: Add function for width of multibyte character
5068c3253e SHERLOCK: Add skipping comments in big5
96d4f93d40 SHERLOCK: Extract word-wrapping algorithm into common file
d2b37c9dde SHERLOCK: Use common word-wrapping algorithm in journal
d5480c37c3 SHERLOCK: Handle scalpel big5 wrapping
0b9e85f93a SHERLOCK: Support Chinese object description wrapping for serrated scalpel
3396f84269 SHERLOCK: Increase line height in Chinese serrated scalpel
9329f7410a SHERLOCK: Fix button positions in Chinese serrated scalpel
b6efa850aa SHERLOCK: Increase line height for Chinese object description for serrated scalpel
4c782a176c SHERLOCK: Minor infoline fix for Chinese serrated scalpel
24baae1ae0 SHERLOCK: Add Chinese strings for Serrated Scalpel
8486739c00 SHERLOCK: Rearrange buttons in Chinese serrated scalpel
38a6cb8e8b SHERLOCK: Always use font 2 for Chinese serrated scalpel
c58c5cb86a SHERLOCK: Fix handling of big5 in journal
187b28f0e5 SHERLOCK: Fix offsets in Chinese journal for serrated scalpel
cf651ca336 SHERLOCK: Fix isPrintable for big5
f407e19890 SHERLOCK: Adjust journal buttons for Chinese serrated scalpel
12ed6c83fe SHERLOCK: Change coordinates for search bar in Chinese serrated scalpel
a728a5aee1 SHERLOCK: Don't print bogus hotkey
Commit: e53cc43272fb851be4dec2c3f00b7b73f087e255
https://github.com/scummvm/scummvm/commit/e53cc43272fb851be4dec2c3f00b7b73f087e255
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Enable Chinese serrated scalpel
Changed paths:
engines/sherlock/detection_tables.h
diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h
index 25aa978151d..9135985f8da 100644
--- a/engines/sherlock/detection_tables.h
+++ b/engines/sherlock/detection_tables.h
@@ -220,11 +220,11 @@ static const SherlockGameDescription gameDescriptions[] = {
// Provided by AquariumTroop
{
"scalpel",
- _s("Missing game code"), // Reason for being unsupported
+ nullptr,
AD_ENTRY1s("talk.lib", "334c7d468860f20eafbcd002891f0c6b", 173935),
Common::ZH_TWN,
Common::kPlatformDOS,
- ADGF_UNSUPPORTED,
+ ADGF_NO_FLAGS,
GUIO1(GUIO_NOSPEECH)
},
GType_SerratedScalpel,
Commit: c4da7fffdf42261c50b5b0a804e0db923f2296e3
https://github.com/scummvm/scummvm/commit/c4da7fffdf42261c50b5b0a804e0db923f2296e3
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Skip images with negative sizes
Changed paths:
engines/sherlock/image_file.cpp
diff --git a/engines/sherlock/image_file.cpp b/engines/sherlock/image_file.cpp
index d839f01b7b5..53d74eca710 100644
--- a/engines/sherlock/image_file.cpp
+++ b/engines/sherlock/image_file.cpp
@@ -97,10 +97,25 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool
int streamSize = stream.size();
while (stream.pos() < streamSize) {
ImageFrame frame;
+ bool invalid = false;
+
frame._width = stream.readUint16LE() + 1;
frame._height = stream.readUint16LE() + 1;
frame._paletteBase = stream.readByte();
+ // Exact purpose of the image with size (-320)x(-200) in
+ // the titles is unclear but skipping it seems to have no ill effect.
+ // Just skip it.
+ if (frame._width > 32768) {
+ frame._width = -(int16_t)frame._width;
+ invalid = true;
+ }
+
+ if (frame._height > 32768) {
+ frame._height = -(int16_t)frame._height;
+ invalid = true;
+ }
+
if (animImages) {
// Animation cutscene image files use a 16-bit x offset
frame._offset.x = stream.readUint16LE();
@@ -129,7 +144,12 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool
frame._pos = stream.pos();
- if (_name.empty()) {
+ if (invalid) {
+ frame._decoded = true;
+ frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8());
+ frame._frame.fillRect(Common::Rect(0, 0, frame._width, frame._height), 0xff);
+ stream.seek(MIN(stream.pos() + frame._size, stream.size()));
+ } else if (_name.empty()) {
// Load data for frame and decompress it
frame._decoded = true;
byte *data1 = new byte[frame._size + 4];
Commit: 47cbf56d944bdf2394ba47faaa22fa415929a061
https://github.com/scummvm/scummvm/commit/47cbf56d944bdf2394ba47faaa22fa415929a061
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
GRAPHICS: Extract big5 renderer from sky into common graphics code
Changed paths:
A graphics/big5.cpp
A graphics/big5.h
engines/sky/sky.cpp
engines/sky/sky.h
engines/sky/text.cpp
graphics/module.mk
diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp
index 88819b7801b..d78953d6be5 100644
--- a/engines/sky/sky.cpp
+++ b/engines/sky/sky.cpp
@@ -122,8 +122,8 @@ SkyEngine::~SkyEngine() {
delete [] _chineseTraditionalBlock;
_chineseTraditionalBlock = nullptr;
- _chineseTraditionalFont.clear();
- _chineseTraditionalIndex.clear();
+ delete _big5Font;
+ _big5Font = nullptr;
}
void SkyEngine::syncSoundSettings() {
@@ -283,39 +283,6 @@ Common::Error SkyEngine::go() {
return Common::kNoError;
}
-void SkyEngine::ChineseTraditionalGlyph::makeOutline() {
- outline[0][0] = 0;
- outline[0][1] = 0;
- // OR into outline the original bitmap moved by 1 pixel
- // 1 pixel down
- for (int y = 0; y < SkyEngine::kChineseTraditionalHeight - 1; y++) {
- outline[y+1][0] = bitmap[y][0];
- outline[y+1][1] = bitmap[y][1];
- }
- // 1 pixel up
- for (int y = 0; y < SkyEngine::kChineseTraditionalHeight - 1; y++) {
- outline[y][0] |= bitmap[y+1][0];
- outline[y][1] |= bitmap[y+1][1];
- }
- for (int y = 0; y < SkyEngine::kChineseTraditionalHeight; y++) {
- // 1 pixel right
- outline[y][0] |= bitmap[y][0] >> 1;
- outline[y][1] |= bitmap[y][0] << 7;
- outline[y][1] |= bitmap[y][1] >> 1;
-
- // 1 pixel left
- outline[y][0] |= bitmap[y][0] << 1;
- outline[y][0] |= bitmap[y][1] >> 7;
- outline[y][1] |= bitmap[y][1] << 1;
- }
-
- // Then AND-out the original bitmap
- for (int y = 0; y < SkyEngine::kChineseTraditionalHeight; y++) {
- outline[y][0] &= ~bitmap[y][0];
- outline[y][1] &= ~bitmap[y][1];
- }
-}
-
static const struct {
// Identification
const char *md5; // File MD5
@@ -367,21 +334,8 @@ bool SkyEngine::loadChineseTraditional() {
skyExe.read(_chineseTraditionalBlock, stringBlockLen);
skyExe.seek(chineseExes[i].fontOffset);
- _chineseTraditionalIndex = Common::move(Common::Array<int>(0x8000, -1));
- // So far the only version had 1981 glyphs. Optimize a little bit for this number
- // but don't rely on it in any way
- _chineseTraditionalFont.reserve(1981);
- while(1) {
- // Big-endian because it's not really a u16 but a big5 sequence.
- uint16 ch = skyExe.readUint16BE();
- ChineseTraditionalGlyph glyph;
- if (ch == 0xffff)
- break;
- skyExe.read(&glyph.bitmap, sizeof(glyph.bitmap));
- glyph.makeOutline();
- _chineseTraditionalIndex[ch & 0x7fff] = _chineseTraditionalFont.size();
- _chineseTraditionalFont.push_back(glyph);
- }
+ _big5Font = new Graphics::Big5Font();
+ _big5Font->loadPrefixedRaw(skyExe, 15);
return true;
}
}
diff --git a/engines/sky/sky.h b/engines/sky/sky.h
index ec6054deb22..a0332d1d34c 100644
--- a/engines/sky/sky.h
+++ b/engines/sky/sky.h
@@ -27,6 +27,7 @@
#include "common/error.h"
#include "common/keyboard.h"
#include "engines/engine.h"
+#include "graphics/big5.h"
/**
* This is the namespace of the Sky engine.
@@ -110,19 +111,9 @@ public:
static void *_itemList[300];
static SystemVars *_systemVars;
static const char *shortcutsKeymapId;
- static const int kChineseTraditionalWidth = 16;
- static const int kChineseTraditionalHeight = 15;
- struct ChineseTraditionalGlyph {
- byte bitmap[kChineseTraditionalHeight][kChineseTraditionalWidth / 8];
- byte outline[kChineseTraditionalHeight][kChineseTraditionalWidth / 8];
-
- void makeOutline();
- };
-
- uint32 _chineseTraditionalOffsets[8];
+ uint32 _chineseTraditionalOffsets[8];
char *_chineseTraditionalBlock;
- Common::Array<ChineseTraditionalGlyph> _chineseTraditionalFont;
- Common::Array<int> _chineseTraditionalIndex;
+ Graphics::Big5Font *_big5Font;
protected:
// Engine APIs
diff --git a/engines/sky/text.cpp b/engines/sky/text.cpp
index de3fa48926c..6f4455dd93f 100644
--- a/engines/sky/text.cpp
+++ b/engines/sky/text.cpp
@@ -284,7 +284,7 @@ DisplayedText Text::displayText(char *textPtr, uint32 bufLen, uint8 *dest, bool
if (isBig5 && (textChar & 0x80)) {
isDoubleChar = true;
curPos++;
- lineWidth += SkyEngine::kChineseTraditionalWidth;
+ lineWidth += Graphics::Big5Font::kChineseTraditionalWidth;
} else {
if ((_curCharSet == 1) && (textChar >= 0x80))
textChar = 0x20;
@@ -332,7 +332,7 @@ DisplayedText Text::displayText(char *textPtr, uint32 bufLen, uint8 *dest, bool
if (numLines > MAX_NO_LINES)
error("Maximum no. of lines exceeded");
- int charHeight = isBig5 ? MAX<int>(_charHeight, SkyEngine::kChineseTraditionalHeight) : _charHeight;
+ int charHeight = isBig5 && _vm->_big5Font ? MAX<int>(_charHeight, _vm->_big5Font->getFontHeight()) : _charHeight;
uint32 dtLineSize = pixelWidth * charHeight;
uint32 numBytes = (dtLineSize * numLines) + sizeof(DataFileHeader) + 4;
@@ -357,6 +357,7 @@ DisplayedText Text::displayText(char *textPtr, uint32 bufLen, uint8 *dest, bool
uint32 *centerTblPtr = centerTable;
do {
+ byte *lineEnd = curDest + pixelWidth;
if (center) {
uint32 width = (pixelWidth - *centerTblPtr) >> 1;
centerTblPtr++;
@@ -368,9 +369,17 @@ DisplayedText Text::displayText(char *textPtr, uint32 bufLen, uint8 *dest, bool
if (isBig5 && (textChar & 0x80)) {
uint8 trail = *curPos++;
uint16 fullCh = (textChar << 8) | trail;
- makeChineseGameCharacter(fullCh, _characterSet, curDest, color, pixelWidth);
- } else
- makeGameCharacter(textChar - 0x20, _characterSet, curDest, color, pixelWidth);
+ if (_vm->_big5Font->drawBig5Char(curDest, fullCh, lineEnd - curDest, charHeight, pixelWidth, color, 240)) {
+ //update position
+ curDest += Graphics::Big5Font::kChineseTraditionalWidth;
+ textChar = *curPos++;
+ continue;
+ }
+
+ textChar = '?';
+ }
+
+ makeGameCharacter(textChar - 0x20, _characterSet, curDest, color, pixelWidth);
textChar = *curPos++;
}
@@ -385,29 +394,6 @@ DisplayedText Text::displayText(char *textPtr, uint32 bufLen, uint8 *dest, bool
return ret;
}
-void Text::makeChineseGameCharacter(uint16 textChar, uint8 *charSetPtr, uint8 *&dest, uint8 color, uint16 bufPitch) {
- int glyphIdx = _vm->_chineseTraditionalIndex[textChar & 0x7fff];
- if (glyphIdx < 0) {
- makeGameCharacter('?' - 0x20, charSetPtr, dest, color, bufPitch);
- return;
- }
-
- const SkyEngine::ChineseTraditionalGlyph& glyph = _vm->_chineseTraditionalFont[glyphIdx];
-
- for (int y = 0; y < SkyEngine::kChineseTraditionalHeight; y++) {
- uint8 *cur = dest + y * bufPitch;
-
- for (int byte = 0; byte < 2; byte++)
- for (int bit = 0; bit < 8; bit++, cur++)
- if ((glyph.bitmap[y][byte] << bit) & 0x80)
- *cur = color;
- else if ((glyph.outline[y][byte] << bit) & 0x80)
- *cur = 240;
- }
- //update position
- dest += SkyEngine::kChineseTraditionalWidth;
-}
-
void Text::makeGameCharacter(uint8 textChar, uint8 *charSetPtr, uint8 *&dest, uint8 color, uint16 bufPitch) {
bool maskBit, dataBit;
uint8 charWidth = (uint8)((*(charSetPtr + textChar)) + 1 - _dtCharSpacing);
diff --git a/graphics/big5.cpp b/graphics/big5.cpp
new file mode 100644
index 00000000000..87a283e8b1b
--- /dev/null
+++ b/graphics/big5.cpp
@@ -0,0 +1,130 @@
+/* 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/>.
+ *
+ */
+
+#include "graphics/big5.h"
+
+namespace Graphics {
+
+Big5Font::Big5Font() : _chineseTraditionalHeight(0) {
+}
+
+Big5Font::~Big5Font() {
+ _chineseTraditionalFont.clear();
+ _chineseTraditionalIndex.clear();
+}
+
+void Big5Font::ChineseTraditionalGlyph::makeOutline(int height) {
+ outline[0][0] = 0;
+ outline[0][1] = 0;
+ // OR into outline the original bitmap moved by 1 pixel
+ // 1 pixel down
+ for (int y = 0; y < height - 1; y++) {
+ outline[y+1][0] = bitmap[y][0];
+ outline[y+1][1] = bitmap[y][1];
+ }
+ // 1 pixel up
+ for (int y = 0; y < height - 1; y++) {
+ outline[y][0] |= bitmap[y+1][0];
+ outline[y][1] |= bitmap[y+1][1];
+ }
+ for (int y = 0; y < height; y++) {
+ // 1 pixel right
+ outline[y][0] |= bitmap[y][0] >> 1;
+ outline[y][1] |= bitmap[y][0] << 7;
+ outline[y][1] |= bitmap[y][1] >> 1;
+
+ // 1 pixel left
+ outline[y][0] |= bitmap[y][0] << 1;
+ outline[y][0] |= bitmap[y][1] >> 7;
+ outline[y][1] |= bitmap[y][1] << 1;
+ }
+
+ // Then AND-out the original bitmap
+ for (int y = 0; y < height; y++) {
+ outline[y][0] &= ~bitmap[y][0];
+ outline[y][1] &= ~bitmap[y][1];
+ }
+}
+
+void Big5Font::loadPrefixedRaw(Common::ReadStream &input, int height) {
+ _chineseTraditionalHeight = height;
+ _chineseTraditionalFont.clear();
+
+ _chineseTraditionalIndex = Common::move(Common::Array<int>(0x8000, -1));
+ // So far the smallest version had 1981 glyphs. Optimize a little bit for this number
+ // but don't rely on it in any way
+ _chineseTraditionalFont.reserve(1981);
+ while(!input.eos()) {
+ // Big-endian because it's not really a u16 but a big5 sequence.
+ uint16 ch = input.readUint16BE();
+ ChineseTraditionalGlyph glyph;
+ if (ch == 0xffff)
+ break;
+ memset(&glyph.bitmap, 0, sizeof(glyph.bitmap));
+ memset(&glyph.outline, 0, sizeof(glyph.outline));
+ input.read(&glyph.bitmap, (kChineseTraditionalWidth / 8) * _chineseTraditionalHeight);
+ glyph.makeOutline(height);
+ _chineseTraditionalIndex[ch & 0x7fff] = _chineseTraditionalFont.size();
+ _chineseTraditionalFont.push_back(glyph);
+ }
+}
+
+template <class T> bool Big5Font::drawReal(byte *dest, uint16 textChar, int maxX, int maxY, uint32 destPitch, byte color, byte outlineColor, bool outline) const {
+ int glyphIdx = _chineseTraditionalIndex[textChar & 0x7fff];
+ if (glyphIdx < 0) {
+ return false;
+ }
+
+ const ChineseTraditionalGlyph& glyph = _chineseTraditionalFont[glyphIdx];
+
+ for (int y = 0; y < _chineseTraditionalHeight && y < maxY; y++) {
+ T *cur = (T*) (dest + y * destPitch);
+ T *curMax = cur + maxX;
+
+ for (int byte = 0; byte < 2; byte++)
+ for (int bit = 0; bit < 8 && cur < curMax; bit++, cur++)
+ if ((glyph.bitmap[y][byte] << bit) & 0x80)
+ *cur = color;
+ else if (outline && (((glyph.outline[y][byte] << bit) & 0x80)))
+ *cur = outlineColor;
+ }
+ return true;
+}
+
+bool Big5Font::drawBig5Char(byte *dest, uint16 ch, int maxX, int maxY, uint32 destPitch, byte color, byte outlineColor) const {
+ return drawReal<uint8>(dest, maxX, maxY, destPitch, ch, color, outlineColor, true);
+}
+
+bool Big5Font::drawBig5Char(Graphics::Surface *surf, uint16 ch, const Common::Point &pt, uint32 color) const {
+ switch(surf->format.bytesPerPixel) {
+ case 4:
+ return drawReal<uint32>((byte*)surf->getBasePtr(pt.x, pt.y), surf->w - pt.x, surf->h - pt.y, surf->pitch, ch, color, 0, false);
+ case 2:
+ return drawReal<uint16>((byte*)surf->getBasePtr(pt.x, pt.y), surf->w - pt.x, surf->h - pt.y, surf->pitch, ch, color, 0, false);
+ case 1:
+ return drawReal<uint8>((byte*)surf->getBasePtr(pt.x, pt.y), surf->w - pt.x, surf->h - pt.y, surf->pitch, ch, color, 0, false);
+ default:
+ error("Big5 font for bpp=%d is not supported", surf->format.bytesPerPixel);
+ }
+
+}
+
+}
diff --git a/graphics/big5.h b/graphics/big5.h
new file mode 100644
index 00000000000..1aa73876dc6
--- /dev/null
+++ b/graphics/big5.h
@@ -0,0 +1,60 @@
+/* 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/>.
+ *
+ */
+
+#ifndef GRAPHICS_BIG5_H
+#define GRAPHICS_BIG5_H
+
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/stream.h"
+#include "graphics/surface.h"
+
+namespace Graphics {
+
+class Big5Font {
+public:
+ Big5Font();
+ ~Big5Font();
+ void loadPrefixedRaw(Common::ReadStream &input, int height);
+ bool drawBig5Char(byte *dest, uint16 ch, int maxX, int maxY, uint32 destPitch, byte color, byte outlineColor) const;
+ bool drawBig5Char(Graphics::Surface *surf, uint16 ch, const Common::Point &pt, uint32 color) const;
+
+ int getFontHeight() const { return _chineseTraditionalHeight; }
+
+ static const int kChineseTraditionalWidth = 16;
+private:
+ static const int kChineseTraditionalMaxHeight = 16;
+ struct ChineseTraditionalGlyph {
+ byte bitmap[kChineseTraditionalMaxHeight][kChineseTraditionalWidth / 8];
+ byte outline[kChineseTraditionalMaxHeight][kChineseTraditionalWidth / 8];
+
+ void makeOutline(int height);
+ };
+
+ template <class T> bool drawReal(byte *dest, uint16 textChar, int maxX, int maxY, uint32 destPitch, byte color, byte outlineColor, bool outline) const;
+
+ Common::Array<ChineseTraditionalGlyph> _chineseTraditionalFont;
+ Common::Array<int> _chineseTraditionalIndex;
+ int _chineseTraditionalHeight;
+};
+
+}
+#endif
diff --git a/graphics/module.mk b/graphics/module.mk
index 6c8b021c81b..1e63b227526 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -1,6 +1,7 @@
MODULE := graphics
MODULE_OBJS := \
+ big5.o \
blit.o \
blit-scale.o \
cursorman.o \
Commit: 7daa2b5d85e644cefac039eb412e78d44a1637e4
https://github.com/scummvm/scummvm/commit/7daa2b5d85e644cefac039eb412e78d44a1637e4
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Add rendering of Serrated scalpel chinese texts
Changed paths:
engines/sherlock/fonts.cpp
engines/sherlock/fonts.h
diff --git a/engines/sherlock/fonts.cpp b/engines/sherlock/fonts.cpp
index dfb75f7e281..a85927d8028 100644
--- a/engines/sherlock/fonts.cpp
+++ b/engines/sherlock/fonts.cpp
@@ -36,13 +36,16 @@ int Fonts::_widestChar;
uint16 Fonts::_charCount;
byte Fonts::_yOffsets[255];
bool Fonts::_isModifiedEucCn;
+bool Fonts::_isBig5;
byte *Fonts::_chineseFont;
+Graphics::Big5Font *Fonts::_big5Font;
void Fonts::setVm(SherlockEngine *vm) {
_vm = vm;
_font = nullptr;
_charCount = 0;
_isModifiedEucCn = (_vm->getLanguage() == Common::Language::ZH_ANY && _vm->getGameID() == GameType::GType_RoseTattoo);
+ _isBig5 = (_vm->getLanguage() == Common::Language::ZH_TWN && _vm->getGameID() == GameType::GType_SerratedScalpel);
}
void Fonts::freeFont() {
@@ -78,6 +81,16 @@ void Fonts::setFont(int fontNum) {
}
}
+ if (_isBig5 && _chineseFont == nullptr) {
+ Common::File pat;
+ if (!pat.open("TEXTPAT.FNT")) {
+ _isBig5 = false;
+ } else {
+ _big5Font = new Graphics::Big5Font();
+ _big5Font->loadPrefixedRaw(pat, 14);
+ }
+ }
+
if (_vm->getPlatform() != Common::kPlatform3DO) {
// PC
// use FONT[number].VGS, which is a regular sherlock graphic file
@@ -290,6 +303,17 @@ void Fonts::writeString(BaseSurface *surface, const Common::String &str,
charPos.x += 5; // hardcoded space
continue;
}
+
+ if (_isBig5 && (curChar & 0x80) && nextChar) {
+ curCharPtr++;
+ uint16 point = (curChar << 8) | nextChar;
+ if (_big5Font->drawBig5Char(surface->surfacePtr(), point, charPos, overrideColor)) {
+ charPos.x += Graphics::Big5Font::kChineseTraditionalWidth;
+ continue;
+ }
+ curChar = '?';
+ }
+
curChar = translateChar(curChar);
if (curChar < _charCount) {
@@ -334,6 +358,12 @@ int Fonts::stringWidth(const Common::String &str) {
continue;
}
+ if (_isBig5 && (curChar & 0x80) && nextChar) {
+ width += Graphics::Big5Font::kChineseTraditionalWidth;
+ c++;
+ continue;
+ }
+
width += charWidth(*c);
}
@@ -372,6 +402,12 @@ int Fonts::stringHeight(const Common::String &str) {
continue;
}
+ if (_isBig5 && _big5Font && (curChar & 0x80) && nextChar) {
+ height = MAX(height, _big5Font->getFontHeight());
+ c++;
+ continue;
+ }
+
height = MAX(height, charHeight(*c));
}
diff --git a/engines/sherlock/fonts.h b/engines/sherlock/fonts.h
index d5e52196788..d59ee3e8e9c 100644
--- a/engines/sherlock/fonts.h
+++ b/engines/sherlock/fonts.h
@@ -24,6 +24,7 @@
#include "common/rect.h"
#include "common/platform.h"
+#include "graphics/big5.h"
#include "graphics/surface.h"
namespace Sherlock {
@@ -34,14 +35,21 @@ class BaseSurface;
class Fonts {
private:
+ struct ChinaFontCodElement {
+ uint16 a;
+ uint16 b;
+ uint8 c;
+ };
static ImageFile *_font;
static byte *_chineseFont;
+ static Graphics::Big5Font *_big5Font;
static byte _yOffsets[255];
static int _fontNumber;
static int _fontHeight;
static int _widestChar;
static uint16 _charCount;
static bool _isModifiedEucCn;
+ static bool _isBig5;
static inline byte translateChar(byte c);
protected:
@@ -65,6 +73,7 @@ public:
static void freeFont();
static bool isModifiedEucCn() { return _isModifiedEucCn; }
+ static bool isBig5() { return _isBig5; }
/**
* Set the font to use for writing text on the screen
@@ -96,7 +105,7 @@ public:
/**
* Return the font height
*/
- int fontHeight() const { return _chineseFont ? MAX(_fontHeight, 16) : _fontHeight; }
+ int fontHeight() const { return _chineseFont || _isBig5 ? MAX(_fontHeight, 16) : _fontHeight; }
/**
* Return the width of the widest character in the font
Commit: 518b96f24fec29bd24fe5bd8ff52c8ff79c79ab0
https://github.com/scummvm/scummvm/commit/518b96f24fec29bd24fe5bd8ff52c8ff79c79ab0
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Add function for width of multibyte character
Changed paths:
engines/sherlock/fonts.cpp
engines/sherlock/fonts.h
diff --git a/engines/sherlock/fonts.cpp b/engines/sherlock/fonts.cpp
index a85927d8028..49fe0c24a68 100644
--- a/engines/sherlock/fonts.cpp
+++ b/engines/sherlock/fonts.cpp
@@ -334,37 +334,31 @@ int Fonts::stringWidth(const Common::String &str) {
bool isInEucEscape = false;
- for (const char *c = str.c_str(); *c; ++c) {
- byte curChar = *c;
- byte nextChar = c[1];
+ for (int idx = 0; idx < (int) str.size(); ) {
+ byte curChar = str.c_str()[idx];
+ byte nextChar = str.c_str()[idx+1];
if (_isModifiedEucCn && !isInEucEscape && curChar == '@' && nextChar == '$') {
width += charWidth(' ');
- c++;
+ idx += 2;
isInEucEscape = true;
continue;
}
if (_isModifiedEucCn && isInEucEscape && curChar == '$' && nextChar == '@') {
width += charWidth(' ');
- c++;
+ idx += 2;
isInEucEscape = false;
continue;
}
if (_isModifiedEucCn && curChar >= 0x41 && nextChar >= 0x41 && (isInEucEscape || ((curChar >= 0xa1) && (nextChar >= 0xa1)))) {
width += kChineseWidth;
- c++;
+ idx += 2;
continue;
}
- if (_isBig5 && (curChar & 0x80) && nextChar) {
- width += Graphics::Big5Font::kChineseTraditionalWidth;
- c++;
- continue;
- }
-
- width += charWidth(*c);
+ width += charWidth(str.c_str(), idx);
}
return width;
@@ -414,22 +408,37 @@ int Fonts::stringHeight(const Common::String &str) {
return height;
}
-int Fonts::charWidth(unsigned char c) {
- byte curChar;
+
+int Fonts::charWidth(const char *p, int &idx) {
+ byte curChar = p[idx];
+ byte nextChar = p[idx + 1];
+ if (_isBig5 && (curChar & 0x80) && nextChar) {
+ idx += 2;
+ return Graphics::Big5Font::kChineseTraditionalWidth;
+ }
+
+ idx++;
if (!_font)
return 0;
- if (c == ' ') {
+ if (curChar == ' ') {
return 5; // hardcoded space
}
- curChar = translateChar(c);
- if (curChar < _charCount)
- return (*_font)[curChar]._frame.w + 1;
+ byte translatedChar = translateChar(curChar);
+
+ if (translatedChar < _charCount)
+ return (*_font)[translatedChar]._frame.w + 1;
return 0;
}
+int Fonts::charWidth(char c) {
+ char s[2] = { c, '\0' };
+ int idx = 0;
+ return charWidth(s, idx);
+}
+
int Fonts::charHeight(unsigned char c) {
byte curChar;
diff --git a/engines/sherlock/fonts.h b/engines/sherlock/fonts.h
index d59ee3e8e9c..50ede979998 100644
--- a/engines/sherlock/fonts.h
+++ b/engines/sherlock/fonts.h
@@ -95,7 +95,12 @@ public:
/**
* Returns the width of a character in pixels
*/
- int charWidth(unsigned char c);
+ int charWidth(const char *str, int &idx);
+
+ /**
+ * Returns the width of a character in pixels
+ */
+ int charWidth(char ch);
/**
* Returns the width of a character in pixels
Commit: 5068c3253e3a6cd388ad4a628a4ef71cad61d09e
https://github.com/scummvm/scummvm/commit/5068c3253e3a6cd388ad4a628a4ef71cad61d09e
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Add skipping comments in big5
Changed paths:
engines/sherlock/talk.cpp
diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp
index 1e945ac9583..0bfdf669ede 100644
--- a/engines/sherlock/talk.cpp
+++ b/engines/sherlock/talk.cpp
@@ -773,8 +773,19 @@ void Talk::doScript(const Common::String &script) {
_endStr = true;
} else if (c == '{') {
// Start of comment, so skip over it
- while (*str++ != '}')
- ;
+ if (Fonts::isBig5()) {
+ while (*str && *str != '}') {
+ if ((*str & 0x80) && str[1])
+ str += 2;
+ else
+ str++;
+ }
+ if (*str)
+ str++;
+ } else {
+ while (*str++ != '}')
+ ;
+ }
} else if (isOpcode(c)) {
// the original interpreter checked for c being >= 0x80
// and if that is the case, it tried to process it as opcode, BUT ALSO ALWAYS skipped over it
Commit: 96d4f93d40cbf030d28d77c70b2446fa1458fc15
https://github.com/scummvm/scummvm/commit/96d4f93d40cbf030d28d77c70b2446fa1458fc15
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Extract word-wrapping algorithm into common file
Changed paths:
engines/sherlock/fonts.cpp
engines/sherlock/fonts.h
engines/sherlock/tattoo/widget_base.cpp
diff --git a/engines/sherlock/fonts.cpp b/engines/sherlock/fonts.cpp
index 49fe0c24a68..5a5b3a7fbc0 100644
--- a/engines/sherlock/fonts.cpp
+++ b/engines/sherlock/fonts.cpp
@@ -433,6 +433,122 @@ int Fonts::charWidth(const char *p, int &idx) {
return 0;
}
+Common::Array<Common::String> Fonts::wordWrap(const Common::String &str, uint maxWidth, Common::String &rem, uint maxChars, uint maxLines, bool skipHeadAt) {
+ Common::Array<Common::String> lines;
+ int strIdx = 0;
+
+ bool isInEucEscape = false;
+ do {
+ uint width = 0;
+ uint numChars = 0;
+ int spaceIdx = 0;
+ bool spacePNeedsEndEscape = false;
+ bool spacePNeedsBeginEscape = false;
+ int lineStartIdx = strIdx;
+ // Invariant: lastCharIdx is either -1
+ // or is exactly one character behind strP
+ // and in the same escape state.
+ int lastCharIdx = -1;
+ bool isLineStartPInEucEscape = isInEucEscape;
+
+ if (skipHeadAt) {
+ // If the first character is a '@' flagging a title line, then move
+ // past it, so the @ won't be included in the line width calculation
+ if (strIdx + 1 < (int)str.size() && str[strIdx] == '@' && str[strIdx + 1] != '$')
+ ++strIdx;
+ }
+
+ // Find how many characters will fit on the next line
+ while (width < maxWidth && numChars < maxChars && strIdx < (int)str.size() && str[strIdx] != '\n') {
+ if (_isModifiedEucCn) {
+ byte curChar = str[strIdx];
+ byte nextChar = strIdx + 1 < (int)str.size() ? str[strIdx + 1] : 0;
+ if (!isInEucEscape && curChar == '@' && nextChar == '$') {
+ width += charWidth(' ');
+ numChars++;
+ if (lineStartIdx != strIdx) {
+ spaceIdx = strIdx;
+ spacePNeedsEndEscape = isInEucEscape;
+ spacePNeedsBeginEscape = true;
+ }
+ lastCharIdx = -1;
+ strIdx += 2;
+ isInEucEscape = true;
+ continue;
+ }
+
+ if (isInEucEscape && curChar == '$' && nextChar == '@') {
+ width += charWidth(' ');
+ numChars++;
+ spaceIdx = strIdx;
+ lastCharIdx = -1;
+ strIdx += 2;
+ spacePNeedsEndEscape = isInEucEscape;
+ spacePNeedsBeginEscape = false;
+ isInEucEscape = false;
+ continue;
+ }
+
+ if (curChar >= 0x41 && nextChar >= 0x41 && (isInEucEscape || ((curChar >= 0xa1) && (nextChar >= 0xa1)))) {
+ width += kChineseWidth;
+ lastCharIdx = strIdx;
+ strIdx += 2;
+ numChars++;
+ continue;
+ }
+ }
+
+ // Keep track of the last space
+ if (str[strIdx] == ' ') {
+ spacePNeedsEndEscape = isInEucEscape;
+ spacePNeedsBeginEscape = isInEucEscape;
+ spaceIdx = strIdx;
+ }
+ lastCharIdx = strIdx;
+ width += charWidth(str.c_str(), strIdx);
+ numChars++;
+ }
+
+ bool previousEucEscape = isInEucEscape;
+
+ // If the line was too wide to fit on a single line, go back to the last space
+ // if there was one, or otherwise simply break the line at this point
+ if (width >= maxWidth || numChars >= maxChars) {
+ if (spaceIdx > 0) {
+ previousEucEscape = spacePNeedsEndEscape;
+ isInEucEscape = spacePNeedsBeginEscape;
+ strIdx = spaceIdx;
+ } else if (lastCharIdx > 0 && lastCharIdx != lineStartIdx) {
+ strIdx = lastCharIdx;
+ }
+ }
+
+ Common::String line = str.substr(lineStartIdx, strIdx - lineStartIdx);
+ assert(!line.contains('\n'));
+ if (!line.hasPrefix("@$") && isLineStartPInEucEscape)
+ line = "@$" + line;
+
+ if (!line.hasSuffix("$@") && previousEucEscape)
+ line = line + "$@";
+
+ // Add the line to the output array
+ lines.push_back(line);
+
+ // Move the string ahead to the next line
+ while (strIdx < (int)str.size() && (str[strIdx] == '\n' || str[strIdx] == ' ' || str[strIdx] == '\r'))
+ ++strIdx;
+ } while (strIdx < (int)str.size() && lines.size() < maxLines);
+
+ rem = str.substr(strIdx);
+
+ return lines;
+}
+
+Common::Array<Common::String> Fonts::wordWrap(const Common::String &str, uint maxWidth, uint maxChars, uint maxLines, bool skipHeadAt) {
+ Common::String rem;
+ return wordWrap(str, maxWidth, rem, maxChars, maxLines, skipHeadAt);
+}
+
int Fonts::charWidth(char c) {
char s[2] = { c, '\0' };
int idx = 0;
diff --git a/engines/sherlock/fonts.h b/engines/sherlock/fonts.h
index 50ede979998..cf9c3aa4321 100644
--- a/engines/sherlock/fonts.h
+++ b/engines/sherlock/fonts.h
@@ -121,6 +121,11 @@ public:
* Return the currently active font number
*/
int fontNumber() const { return _fontNumber; }
+
+ Common::Array<Common::String> wordWrap(const Common::String &str, uint maxWidth, Common::String &rem,
+ uint maxChars = Common::String::npos, uint maxLines = Common::String::npos, bool skipHeadAt = false);
+ Common::Array<Common::String> wordWrap(const Common::String &str, uint maxWidth,
+ uint maxChars = Common::String::npos, uint maxLines = Common::String::npos, bool skipHeadAt = false);
};
} // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/widget_base.cpp b/engines/sherlock/tattoo/widget_base.cpp
index d002c638e33..7587b722e22 100644
--- a/engines/sherlock/tattoo/widget_base.cpp
+++ b/engines/sherlock/tattoo/widget_base.cpp
@@ -135,104 +135,18 @@ void WidgetBase::drawBackground() {
Common::String WidgetBase::splitLines(const Common::String &str, Common::StringArray &lines, int maxWidth, uint maxLines) {
Talk &talk = *_vm->_talk;
- const char *strP = str.c_str();
- bool isModifiedEucCn = Fonts::isModifiedEucCn();
- bool isInEucEscape = false;
-
- // Loop counting up lines
lines.clear();
- do {
- int width = 0;
- const char *spaceP = nullptr;
- bool spacePNeedsEndEscape = false;
- bool spacePNeedsBeginEscape = false;
- const char *lineStartP = strP;
- // Invariant: lastCharP is either nullptr
- // or is exactly one character behind strP
- // and in the same escape state.
- const char *lastCharP = nullptr;
- bool isLineStartPInEucEscape = isInEucEscape;
-
- // Find how many characters will fit on the next line
- while (width < maxWidth && *strP && ((byte)*strP < talk._opcodes[OP_SWITCH_SPEAKER] ||
- (byte)*strP == talk._opcodes[OP_NULL])) {
- if (isModifiedEucCn) {
- byte curChar = *strP;
- byte nextChar = strP[1];
- if (!isInEucEscape && curChar == '@' && nextChar == '$') {
- width += _surface.charWidth(' ');
- if (lineStartP != strP) {
- spaceP = strP;
- spacePNeedsEndEscape = isInEucEscape;
- spacePNeedsBeginEscape = true;
- }
- lastCharP = nullptr;
- strP += 2;
- isInEucEscape = true;
- continue;
- }
-
- if (isInEucEscape && curChar == '$' && nextChar == '@') {
- width += _surface.charWidth(' ');
- spaceP = strP;
- lastCharP = nullptr;
- strP += 2;
- spacePNeedsEndEscape = isInEucEscape;
- spacePNeedsBeginEscape = false;
- isInEucEscape = false;
- continue;
- }
-
- if (curChar >= 0x41 && nextChar >= 0x41 && (isInEucEscape || ((curChar >= 0xa1) && (nextChar >= 0xa1)))) {
- width += Fonts::kChineseWidth;
- lastCharP = strP;
- strP += 2;
- continue;
- }
- }
- width += _surface.charWidth(*strP);
-
- // Keep track of the last space
- if (*strP == ' ') {
- spacePNeedsEndEscape = isInEucEscape;
- spacePNeedsBeginEscape = isInEucEscape;
- spaceP = strP;
- }
- lastCharP = strP;
- ++strP;
- }
-
- bool previousEucEscape = isInEucEscape;
-
- // If the line was too wide to fit on a single line, go back to the last space
- // if there was one, or otherwise simply break the line at this point
- if (width >= maxWidth && spaceP != nullptr) {
- previousEucEscape = spacePNeedsEndEscape;
- isInEucEscape = spacePNeedsBeginEscape;
- strP = spaceP;
- } else if (width >= maxWidth && lastCharP != nullptr && lastCharP != lineStartP) {
- strP = lastCharP;
- }
-
- Common::String line(lineStartP, strP);
- if (!line.hasPrefix("@$") && isLineStartPInEucEscape)
- line = "@$" + line;
-
- if (!line.hasSuffix("$@") && previousEucEscape)
- line = line + "$@";
-
- // Add the line to the output array
- lines.push_back(line);
-
- // Move the string ahead to the next line
- if (*strP == ' ' || *strP == 13)
- ++strP;
- } while (*strP && (lines.size() < maxLines) && ((byte)*strP < talk._opcodes[OP_SWITCH_SPEAKER]
- || (byte)*strP == talk._opcodes[OP_NULL]));
+ uint idx;
+ for (idx = 0; idx < str.size(); idx++)
+ if (str[idx] >= talk._opcodes[OP_SWITCH_SPEAKER] && str[idx] != talk._opcodes[OP_NULL])
+ break;
+ Common::String rest;
+ Common::Array<Common::String> arr = _surface.wordWrap(str.substr(0, idx), maxWidth, rest, Common::String::npos, maxLines);
+ lines.swap(arr);
// Return any remaining text left over
- return *strP ? Common::String(strP) : Common::String();
+ return rest + str.substr(idx);
}
void WidgetBase::restrictToScreen() {
Commit: d2b37c9dde58e8207b6dc430d8a0a005bf5ebdc7
https://github.com/scummvm/scummvm/commit/d2b37c9dde58e8207b6dc430d8a0a005bf5ebdc7
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Use common word-wrapping algorithm in journal
Changed paths:
engines/sherlock/journal.cpp
diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp
index 15c8290e504..6ecdee9ca83 100644
--- a/engines/sherlock/journal.cpp
+++ b/engines/sherlock/journal.cpp
@@ -757,38 +757,11 @@ void Journal::loadJournalFile(bool alreadyLoaded) {
// _lines array
_lines.clear();
- while (!journalString.empty()) {
- const char *startP = journalString.c_str();
-
- // If the first character is a '@' flagging a title line, then move
- // past it, so the @ won't be included in the line width calculation
- if (*startP == '@')
- ++startP;
-
- // Build up chacters until a full line is found
- int width = 0;
- const char *endP = startP;
- while (width < JOURNAL_MAX_WIDTH && *endP && *endP != '\n' && (endP - startP) < (JOURNAL_MAX_CHARS - 1))
- width += screen.charWidth(*endP++);
-
- // If word wrapping, move back to end of prior word
- if (width >= JOURNAL_MAX_WIDTH || (endP - startP) >= (JOURNAL_MAX_CHARS - 1)) {
- while (*--endP != ' ')
- ;
- }
-
- // Add in the line
- _lines.push_back(Common::String(journalString.c_str(), endP));
-
- // Strip line off from string being processed
- journalString = *endP ? Common::String(endP + 1) : "";
- }
+ _lines = screen.wordWrap(journalString, JOURNAL_MAX_WIDTH, JOURNAL_MAX_CHARS, Common::String::npos, true);
// Add a blank line at the end of the text as long as text was present
if (!startOfReply) {
_lines.push_back("");
- } else {
- _lines.clear();
}
}
Commit: d5480c37c3c379184d0f1a7f4bd88586d3d269d8
https://github.com/scummvm/scummvm/commit/d5480c37c3c379184d0f1a7f4bd88586d3d269d8
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Handle scalpel big5 wrapping
Changed paths:
engines/sherlock/scalpel/scalpel_talk.cpp
diff --git a/engines/sherlock/scalpel/scalpel_talk.cpp b/engines/sherlock/scalpel/scalpel_talk.cpp
index 3faaabc0f75..a63b0eb6bce 100644
--- a/engines/sherlock/scalpel/scalpel_talk.cpp
+++ b/engines/sherlock/scalpel/scalpel_talk.cpp
@@ -232,11 +232,14 @@ void ScalpelTalk::talkInterface(const byte *&str) {
}
// Find amount of text that will fit on the line
- int width = 0, idx = 0;
+ int width = 0, idx = 0, last_space = 0, last_valid = 0;
do {
- width += screen.charWidth(str[idx]);
- ++idx;
- ++_charCount;
+ int old_idx = idx;
+ if (str[idx] == ' ')
+ last_space = idx;
+ last_valid = idx;
+ width += screen.charWidth((const char *) str, idx);
+ _charCount += idx - old_idx;
} while (width < 298 && str[idx] && str[idx] != '{' && (!isOpcode(str[idx])));
if (str[idx] || width >= 298) {
@@ -250,9 +253,12 @@ void ScalpelTalk::talkInterface(const byte *&str) {
// If word wrap is needed, find the start of the current word
if (width >= 298) {
- while (str[idx] != ' ') {
- --idx;
- --_charCount;
+ if (last_space > 0) {
+ _charCount -= idx - last_space;
+ idx = last_space;
+ } else {
+ _charCount -= idx - last_valid;
+ idx = last_valid;
}
}
@@ -279,8 +285,8 @@ void ScalpelTalk::talkInterface(const byte *&str) {
// Move to end of displayed line
str += idx;
- // If line wrap occurred, then move to after the separating space between the words
- if (str[0] && (!isOpcode(str[0])) && str[0] != '{')
+ // If line wrap with space occurred, then move to after the separating space between the words
+ if (str[0] == ' ')
++str;
_yp += 9;
@@ -823,19 +829,27 @@ int ScalpelTalk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool
for (;;) {
// Get as much of the statement as possible will fit on the
Common::String sLine;
- const char *lineEndP = lineStartP;
int width = 0;
+ int lastSpace = 0;
+ int lastValid = 0;
+ int linePtr = 0;
+ int nextLine = -1;
do {
- width += screen.charWidth(*lineEndP);
- } while (*++lineEndP && width < maxWidth);
+ lastValid = linePtr;
+ if (lineStartP[linePtr] == ' ')
+ lastSpace = linePtr;
+ width += screen.charWidth(lineStartP, linePtr);
+ } while (lineStartP[linePtr] && width < maxWidth);
// Check if we need to wrap the line
if (width >= maxWidth) {
- // Work backwards to the prior word's end
- while (*--lineEndP != ' ')
- ;
-
- sLine = Common::String(lineStartP, lineEndP++);
+ if (lastSpace > 0) {
+ sLine = Common::String(lineStartP, lastSpace);
+ nextLine = lastSpace + 1;
+ } else {
+ sLine = Common::String(lineStartP, lastValid);
+ nextLine = lastValid;
+ }
} else {
// Can display remainder of the statement on the current line
sLine = Common::String(lineStartP);
@@ -872,10 +886,9 @@ int ScalpelTalk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool
// Move to next line, if any
lineY += 9;
- lineStartP = lineEndP;
-
- if (!*lineEndP)
+ if (nextLine < 0)
break;
+ lineStartP += nextLine;
} else {
// We're close to the bottom of the screen, so stop display
lineY = -1;
Commit: 0b9e85f93ac617161ea8bf68d98e298620dd951e
https://github.com/scummvm/scummvm/commit/0b9e85f93ac617161ea8bf68d98e298620dd951e
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Support Chinese object description wrapping for serrated scalpel
Changed paths:
engines/sherlock/scalpel/scalpel_user_interface.cpp
diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp
index 9e590b7808e..77be5dc1f60 100644
--- a/engines/sherlock/scalpel/scalpel_user_interface.cpp
+++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp
@@ -1996,47 +1996,20 @@ void ScalpelUserInterface::printObjectDesc(const Common::String &str, bool first
events.clearEvents();
// Loop through displaying up to five lines
- bool endOfStr = false;
- const char *msgP = str.c_str();
- for (int lineNum = 0; lineNum < ONSCREEN_FILES_COUNT && !endOfStr; ++lineNum) {
- int width = 0;
- const char *lineStartP = msgP;
-
- // Determine how much can be displayed on the line
- do {
- width += screen.charWidth(*msgP++);
- } while (width < 300 && *msgP);
-
- if (*msgP)
- --msgP;
- else
- endOfStr = true;
-
- // If the line needs to be wrapped, scan backwards to find
- // the end of the previous word as a splitting point
- if (width >= 300) {
- while (*msgP != ' ')
- --msgP;
- endOfStr = false;
- }
-
- // Print out the line
- Common::String line(lineStartP, msgP);
+ Common::String remainder;
+ Common::Array<Common::String> lines = screen.wordWrap(str, 300, remainder, Common::String::npos, ONSCREEN_FILES_COUNT);
+ for (uint lineNum = 0; lineNum < lines.size(); ++lineNum) {
screen.gPrint(Common::Point(16, CONTROLS_Y + 12 + lineNum * 9),
- INV_FOREGROUND, "%s", line.c_str());
-
- if (!endOfStr)
- // Start next line at start of the nxet word after space
- ++msgP;
+ INV_FOREGROUND, "%s", lines[lineNum].c_str());
}
// Handle display depending on whether all the message was shown
- if (!endOfStr) {
+ if (!remainder.empty()) {
Common::String fixedText_PressKeyForMore = FIXED(PressKey_ForMore);
screen.makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10),
SHERLOCK_SCREEN_WIDTH / 2, fixedText_PressKeyForMore);
- _descStr = msgP;
+ _descStr = remainder;
} else {
Common::String fixedText_PressKeyToContinue = FIXED(PressKey_ToContinue);
Commit: 3396f8426934ab4e0c566cbf8af7a30cddb63436
https://github.com/scummvm/scummvm/commit/3396f8426934ab4e0c566cbf8af7a30cddb63436
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Increase line height in Chinese serrated scalpel
Changed paths:
engines/sherlock/scalpel/scalpel_talk.cpp
diff --git a/engines/sherlock/scalpel/scalpel_talk.cpp b/engines/sherlock/scalpel/scalpel_talk.cpp
index a63b0eb6bce..58e407de9d0 100644
--- a/engines/sherlock/scalpel/scalpel_talk.cpp
+++ b/engines/sherlock/scalpel/scalpel_talk.cpp
@@ -289,7 +289,7 @@ void ScalpelTalk::talkInterface(const byte *&str) {
if (str[0] == ' ')
++str;
- _yp += 9;
+ _yp += _vm->getLanguage() == Common::Language::ZH_TWN ? 16 : 9;
++_line;
// Certain different conditions require a wait
@@ -885,7 +885,7 @@ int ScalpelTalk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool
}
// Move to next line, if any
- lineY += 9;
+ lineY += _vm->getLanguage() == Common::Language::ZH_TWN ? 16 : 9;
if (nextLine < 0)
break;
lineStartP += nextLine;
Commit: 9329f7410a008d803e47ffedb8a3f340e20c0c72
https://github.com/scummvm/scummvm/commit/9329f7410a008d803e47ffedb8a3f340e20c0c72
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Fix button positions in Chinese serrated scalpel
Changed paths:
engines/sherlock/scalpel/scalpel_user_interface.cpp
engines/sherlock/scalpel/scalpel_user_interface.h
diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp
index 77be5dc1f60..454bd59dd0e 100644
--- a/engines/sherlock/scalpel/scalpel_user_interface.cpp
+++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp
@@ -38,7 +38,7 @@ namespace Sherlock {
namespace Scalpel {
// Main user interface menu control locations
-const int MENU_POINTS[12][4] = {
+const int MENU_POINTS_INTL[12][4] = {
{ 13, 153, 72, 165 },
{ 13, 169, 72, 181 },
{ 13, 185, 72, 197 },
@@ -53,6 +53,21 @@ const int MENU_POINTS[12][4] = {
{ 249, 185, 305, 197 }
};
+const int MENU_POINTS_ZH[12][4] = {
+ { 5, 158, 47, 172 },
+ { 5, 181, 47, 196 },
+ { 57, 158, 99, 172 },
+ { 57, 181, 99, 196 },
+ { 109, 158, 151, 172 },
+ { 109, 181, 151, 196 },
+ { 160, 158, 202, 172 },
+ { 160, 181, 202, 196 },
+ { 212, 158, 254, 172 },
+ { 212, 181, 254, 196 },
+ { 265, 158, 307, 172 },
+ { 265, 181, 307, 196 }
+};
+
// Inventory control locations */
const int INVENTORY_POINTS[8][3] = {
{ 4, 50, 29 },
@@ -69,6 +84,42 @@ const int UI_OFFSET_3DO = 16; // (320 - 288) / 2
/*----------------------------------------------------------------*/
+Common::Point ScalpelUserInterface::getTopLeftButtonPoint(int num) const {
+ Common::Point pt;
+ if (_vm->getLanguage() == Common::Language::ZH_TWN) {
+ pt = Common::Point(MENU_POINTS_ZH[num][0], MENU_POINTS_ZH[num][1]);
+ } else {
+ pt = Common::Point(MENU_POINTS_INTL[num][0], MENU_POINTS_INTL[num][1]);
+ }
+
+ if (IS_3DO) {
+ if (num >= 0 && num <= 2)
+ pt.x += 15;
+ else if (num >= 6 && num <= 8)
+ pt.x -= 4;
+ else if (num >= 9 && num <= 11)
+ pt.x -= 8;
+ }
+
+ return pt;
+}
+
+Common::Rect ScalpelUserInterface::getButtonRect(int buttonNr) const {
+ Common::Rect r;
+
+ if (_vm->getLanguage() == Common::Language::ZH_TWN) {
+ r = Common::Rect(MENU_POINTS_ZH[buttonNr][0], MENU_POINTS_ZH[buttonNr][1],
+ MENU_POINTS_ZH[buttonNr][2], MENU_POINTS_ZH[buttonNr][3]);
+ } else {
+ r = Common::Rect(MENU_POINTS_INTL[buttonNr][0], MENU_POINTS_INTL[buttonNr][1],
+ MENU_POINTS_INTL[buttonNr][2], MENU_POINTS_INTL[buttonNr][3]);
+ }
+ if (IS_3DO && buttonNr <= 2) {
+ r.left += UI_OFFSET_3DO - 1;
+ r.right += UI_OFFSET_3DO - 1;
+ }
+ return r;
+}
ScalpelUserInterface::ScalpelUserInterface(SherlockEngine *vm): UserInterface(vm) {
if (_vm->_interactiveFl) {
@@ -424,8 +475,7 @@ void ScalpelUserInterface::handleInput() {
void ScalpelUserInterface::depressButton(int num) {
Screen &screen = *_vm->_screen;
- Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]);
- offsetButton3DO(pt, num);
+ Common::Point pt = getTopLeftButtonPoint(num);
ImageFrame &frame = (*_controls)[num];
screen._backBuffer1.SHtransBlitFrom(frame, pt);
@@ -435,8 +485,7 @@ void ScalpelUserInterface::depressButton(int num) {
void ScalpelUserInterface::restoreButton(int num) {
Events &events = *_vm->_events;
Screen &screen = *_vm->_screen;
- Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]);
- offsetButton3DO(pt, num);
+ Common::Point pt = getTopLeftButtonPoint(num);
Graphics::Surface &frame = (*_controls)[num]._frame;
@@ -489,8 +538,7 @@ void ScalpelUserInterface::toggleButton(uint16 num) {
_keyboardInput = false;
ImageFrame &frame = (*_controls)[num];
- Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]);
- offsetButton3DO(pt, num);
+ Common::Point pt = getTopLeftButtonPoint(num);
screen._backBuffer1.SHtransBlitFrom(frame, pt);
screen.slamArea(pt.x, pt.y, pt.x + frame._width, pt.y + frame._height);
}
@@ -1273,8 +1321,7 @@ void ScalpelUserInterface::doLookControl() {
else if (!_invLookFlag) {
if (!_lookHelp) {
// Need to close the window and depress the Look button
- Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]);
- offsetButton3DO(pt, 0);
+ Common::Point pt = getTopLeftButtonPoint(0);
screen._backBuffer2.SHblitFrom((*_controls)[0], pt);
banishWindow();
@@ -1334,12 +1381,7 @@ void ScalpelUserInterface::doMainControl() {
// Check whether the mouse is in any of the command areas
for (uint16 buttonNr = 0; buttonNr < 12; buttonNr++) {
- Common::Rect r(MENU_POINTS[buttonNr][0], MENU_POINTS[buttonNr][1],
- MENU_POINTS[buttonNr][2], MENU_POINTS[buttonNr][3]);
- if (IS_3DO && buttonNr <= 2) {
- r.left += UI_OFFSET_3DO - 1;
- r.right += UI_OFFSET_3DO - 1;
- }
+ Common::Rect r = getButtonRect(buttonNr);
if (r.contains(pt)) {
_temp = buttonNr;
pressedButtonId = buttonNr;
@@ -1923,8 +1965,7 @@ void ScalpelUserInterface::printObjectDesc(const Common::String &str, bool first
// the look button before we close the window. So save a copy of the
// menu area, and draw the controls onto it
Surface tempSurface((*_controls)[0]._frame.w, (*_controls)[0]._frame.h);
- Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]);
- offsetButton3DO(pt, 0);
+ Common::Point pt = getTopLeftButtonPoint(0);
tempSurface.SHblitFrom(screen._backBuffer2, Common::Point(0, 0),
Common::Rect(pt.x, pt.y, pt.x + tempSurface.width(), pt.y + tempSurface.height()));
@@ -2267,17 +2308,6 @@ void ScalpelUserInterface::checkUseAction(const UseType *use, const Common::Stri
events.setCursor(ARROW);
}
-void ScalpelUserInterface::offsetButton3DO(Common::Point &pt, int num) {
- if (IS_3DO) {
- if (num >= 0 && num <= 2)
- pt.x += 15;
- else if (num >= 6 && num <= 8)
- pt.x -= 4;
- else if (num >= 9 && num <= 11)
- pt.x -= 8;
- }
-}
-
} // End of namespace Scalpel
} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_user_interface.h b/engines/sherlock/scalpel/scalpel_user_interface.h
index d8d34d3fb25..f898fa8a9ce 100644
--- a/engines/sherlock/scalpel/scalpel_user_interface.h
+++ b/engines/sherlock/scalpel/scalpel_user_interface.h
@@ -197,7 +197,9 @@ public:
*/
void examine();
- void offsetButton3DO(Common::Point &pt, int num);
+ Common::Point getTopLeftButtonPoint(int num) const;
+ Common::Rect getButtonRect(int buttonNr) const;
+
public:
/**
* Resets the user interface
Commit: b6efa850aa458bcc333cf352ee049e7c447daad0
https://github.com/scummvm/scummvm/commit/b6efa850aa458bcc333cf352ee049e7c447daad0
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Increase line height for Chinese object description for serrated scalpel
Changed paths:
engines/sherlock/scalpel/scalpel_user_interface.cpp
diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp
index 454bd59dd0e..d70eff5fd84 100644
--- a/engines/sherlock/scalpel/scalpel_user_interface.cpp
+++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp
@@ -2040,7 +2040,7 @@ void ScalpelUserInterface::printObjectDesc(const Common::String &str, bool first
Common::String remainder;
Common::Array<Common::String> lines = screen.wordWrap(str, 300, remainder, Common::String::npos, ONSCREEN_FILES_COUNT);
for (uint lineNum = 0; lineNum < lines.size(); ++lineNum) {
- screen.gPrint(Common::Point(16, CONTROLS_Y + 12 + lineNum * 9),
+ screen.gPrint(Common::Point(16, CONTROLS_Y + 12 + lineNum * (_vm->getLanguage() == Common::Language::ZH_TWN ? 16 : 9)),
INV_FOREGROUND, "%s", lines[lineNum].c_str());
}
Commit: 4c782a176cc53c057c1b859a67f7c4aa4f85ca8f
https://github.com/scummvm/scummvm/commit/4c782a176cc53c057c1b859a67f7c4aa4f85ca8f
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Minor infoline fix for Chinese serrated scalpel
Changed paths:
engines/sherlock/scalpel/scalpel_user_interface.cpp
engines/sherlock/scalpel/scalpel_user_interface.h
diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp
index d70eff5fd84..60a0b4c231b 100644
--- a/engines/sherlock/scalpel/scalpel_user_interface.cpp
+++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp
@@ -197,6 +197,14 @@ void ScalpelUserInterface::reset() {
_help = _oldHelp = -1;
}
+int ScalpelUserInterface::infoLineHeight() const {
+ return _vm->getLanguage() == Common::Language::ZH_TWN ? 14 : 10;
+}
+
+int ScalpelUserInterface::infoLineYOffset() const {
+ return _vm->getLanguage() == Common::Language::ZH_TWN ? 0 : 1;
+}
+
void ScalpelUserInterface::drawInterface(int bufferNum) {
Screen &screen = *_vm->_screen;
@@ -217,7 +225,7 @@ void ScalpelUserInterface::drawInterface(int bufferNum) {
}
if (bufferNum == 3)
screen._backBuffer2.SHfillRect(Common::Rect(0, INFO_LINE,
- SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10), INFO_BLACK);
+ SHERLOCK_SCREEN_WIDTH, INFO_LINE + infoLineHeight()), INFO_BLACK);
}
void ScalpelUserInterface::handleInput() {
@@ -310,7 +318,7 @@ void ScalpelUserInterface::handleInput() {
if (_help != -1 && !scene._bgShapes[_bgFound]._description.empty()
&& scene._bgShapes[_bgFound]._description[0] != ' ')
- screen.print(Common::Point(0, INFO_LINE + 1),
+ screen.print(Common::Point(0, INFO_LINE + infoLineYOffset()),
INFO_FOREGROUND, "%s", scene._bgShapes[_bgFound]._description.c_str());
_oldBgFound = _bgFound;
@@ -551,8 +559,8 @@ void ScalpelUserInterface::toggleButton(uint16 num) {
void ScalpelUserInterface::clearInfo() {
if (_infoFlag) {
- _vm->_screen->vgaBar(Common::Rect(IS_3DO ? 33 : 16, INFO_LINE,
- SHERLOCK_SCREEN_WIDTH - (IS_3DO ? 33 : 19), INFO_LINE + 10), INFO_BLACK);
+ _vm->_screen->vgaBar(Common::Rect(IS_3DO ? 33 : 16, INFO_LINE + infoLineYOffset() - 1,
+ SHERLOCK_SCREEN_WIDTH - (IS_3DO ? 33 : 19), INFO_LINE + infoLineHeight()), INFO_BLACK);
_infoFlag = false;
_oldLook = -1;
}
@@ -703,16 +711,16 @@ void ScalpelUserInterface::lookScreen(const Common::Point &pt) {
}
int xStart = (SHERLOCK_SCREEN_WIDTH - x) / 2;
- screen.print(Common::Point(xStart, INFO_LINE + 1),
+ screen.print(Common::Point(xStart, INFO_LINE + infoLineYOffset()),
INFO_FOREGROUND, "%s", useText1.c_str());
if (_selector != -1) {
- screen.print(Common::Point(xStart + width1, INFO_LINE + 1),
+ screen.print(Common::Point(xStart + width1, INFO_LINE + infoLineYOffset()),
TALK_FOREGROUND, "%s", useText2.c_str());
- screen.print(Common::Point(xStart + width1 + width2, INFO_LINE + 1),
+ screen.print(Common::Point(xStart + width1 + width2, INFO_LINE + infoLineYOffset()),
INFO_FOREGROUND, "%s", useText3.c_str());
} else {
- screen.print(Common::Point(xStart + width1, INFO_LINE + 1),
+ screen.print(Common::Point(xStart + width1, INFO_LINE + infoLineYOffset()),
INFO_FOREGROUND, "%s", useText3.c_str());
}
} else if (temp >= 0 && temp < 1000 && _selector != -1 &&
@@ -735,15 +743,15 @@ void ScalpelUserInterface::lookScreen(const Common::Point &pt) {
}
int xStart = (SHERLOCK_SCREEN_WIDTH - x) / 2;
- screen.print(Common::Point(xStart, INFO_LINE + 1),
+ screen.print(Common::Point(xStart, INFO_LINE + infoLineYOffset()),
INFO_FOREGROUND, "%s", giveText1.c_str());
- screen.print(Common::Point(xStart + width1, INFO_LINE + 1),
+ screen.print(Common::Point(xStart + width1, INFO_LINE + infoLineYOffset()),
TALK_FOREGROUND, "%s", giveText2.c_str());
- screen.print(Common::Point(xStart + width1 + width2, INFO_LINE + 1),
+ screen.print(Common::Point(xStart + width1 + width2, INFO_LINE + infoLineYOffset()),
INFO_FOREGROUND, "%s", giveText3.c_str());
}
} else {
- screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", tempStr.c_str());
+ screen.print(Common::Point(0, INFO_LINE + infoLineYOffset()), INFO_FOREGROUND, "%s", tempStr.c_str());
}
_infoFlag = true;
@@ -767,7 +775,7 @@ void ScalpelUserInterface::lookInv() {
if (temp < inv._holdings) {
if (temp < inv._holdings) {
clearInfo();
- screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND,
+ screen.print(Common::Point(0, INFO_LINE + infoLineYOffset()), INFO_FOREGROUND,
"%s", inv[temp]._description.c_str());
_infoFlag = true;
_oldLook = temp;
@@ -2231,7 +2239,7 @@ void ScalpelUserInterface::checkUseAction(const UseType *use, const Common::Stri
// Display error message
_menuCounter = 30;
- screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "You can't do that to yourself.");
+ screen.print(Common::Point(0, INFO_LINE + infoLineYOffset()), INFO_FOREGROUND, "You can't do that to yourself.");
return;
}
@@ -2283,7 +2291,7 @@ void ScalpelUserInterface::checkUseAction(const UseType *use, const Common::Stri
if (scene._goToScene != 1 && !printed && !talk._talkToAbort) {
_infoFlag = true;
clearInfo();
- screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", FIXED(UserInterface_Done));
+ screen.print(Common::Point(0, INFO_LINE + infoLineYOffset()), INFO_FOREGROUND, "%s", FIXED(UserInterface_Done));
_menuCounter = 25;
}
}
@@ -2293,12 +2301,12 @@ void ScalpelUserInterface::checkUseAction(const UseType *use, const Common::Stri
clearInfo();
if (giveMode) {
- screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", FIXED(UserInterface_NoThankYou));
+ screen.print(Common::Point(0, INFO_LINE + infoLineYOffset()), INFO_FOREGROUND, "%s", FIXED(UserInterface_NoThankYou));
} else if (fixedTextActionId == kFixedTextAction_Invalid) {
- screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", FIXED(UserInterface_YouCantDoThat));
+ screen.print(Common::Point(0, INFO_LINE + infoLineYOffset()), INFO_FOREGROUND, "%s", FIXED(UserInterface_YouCantDoThat));
} else {
Common::String errorMessage = fixedText.getActionMessage(fixedTextActionId, 0);
- screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", errorMessage.c_str());
+ screen.print(Common::Point(0, INFO_LINE + infoLineYOffset()), INFO_FOREGROUND, "%s", errorMessage.c_str());
}
_infoFlag = true;
diff --git a/engines/sherlock/scalpel/scalpel_user_interface.h b/engines/sherlock/scalpel/scalpel_user_interface.h
index f898fa8a9ce..5b00f4bf9b3 100644
--- a/engines/sherlock/scalpel/scalpel_user_interface.h
+++ b/engines/sherlock/scalpel/scalpel_user_interface.h
@@ -199,6 +199,8 @@ public:
Common::Point getTopLeftButtonPoint(int num) const;
Common::Rect getButtonRect(int buttonNr) const;
+ int infoLineHeight() const;
+ int infoLineYOffset() const;
public:
/**
Commit: 24baae1ae0dfcc1cba3f82ee156819553049a5fc
https://github.com/scummvm/scummvm/commit/24baae1ae0dfcc1cba3f82ee156819553049a5fc
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Add Chinese strings for Serrated Scalpel
Changed paths:
engines/sherlock/fixed_text.cpp
engines/sherlock/scalpel/scalpel_fixed_text.cpp
diff --git a/engines/sherlock/fixed_text.cpp b/engines/sherlock/fixed_text.cpp
index 53dbfdb58c8..c184ebfa588 100644
--- a/engines/sherlock/fixed_text.cpp
+++ b/engines/sherlock/fixed_text.cpp
@@ -168,6 +168,37 @@ static const char *const fixedJournalTextES[] = {
"Despu\202s %s dijo, "
};
+static const char *const fixedJournalTextZHBig5[] = {
+ // Holmes asked/said...
+ "\xba\xd6\xba\xb8\xbc\xaf\xb4\xb5\xb0\xdd\xa7\xda\x3a\x22", /* "ç¦ç¾æ©æ¯åæ:"; "Holmes asked me, " */
+ "\xba\xd6\xba\xb8\xbc\xaf\xb4\xb5\xb0\xdd\xb1\xb4\xaa\xf8\x3a\x22", /* "ç¦ç¾æ©æ¯åæ¢é·:"; "Holmes asked the Inspector, " */
+ "\xba\xd6\xba\xb8\xbc\xaf\xb4\xb5\xb0\xdd%s\x3a\x22", /* "ç¦ç¾æ©æ¯å%s:"; "Holmes asked %s, " */
+ "\xba\xd6\xba\xb8\xbc\xaf\xb4\xb5\xbb\xa1\xa7\xda\x3a\x22", /* "ç¦ç¾æ©æ¯èªªæ:"; "Holmes said to me, " */
+ "\xba\xd6\xba\xb8\xbc\xaf\xb4\xb5\xbb\xa1\xb1\xb4\xaa\xf8\x3a\x22", /* "ç¦ç¾æ©æ¯èªªæ¢é·:"; "Holmes said to the Inspector, " */
+ "\xba\xd6\xba\xb8\xbc\xaf\xb4\xb5\xbb\xa1%s\x3a\x22", /* "ç¦ç¾æ©æ¯èªª%s:"; "Holmes said to %s, " */
+ // I asked/said...
+ "\xa7\xda\xa6\x5e\xb5\xaa\x3a\x22", /* "æåç:""; "I replied, " */
+ "\xa6\x5e\xb5\xaa\xbb\xa1\x3a\x22", /* "åç說:""; "The reply was, " */
+ // Holmes/I/The Inspector/Person asked/said (without "Then" prefix)
+ "Holmes asked, ", // TODO
+ "\xba\xd6\xba\xb8\xbc\xaf\xb4\xb5\xbb\xa1\x3a", /* "ç¦ç¾æ©æ¯èªª:"; "Holmes said, " */
+ "I asked, ", // TODO
+ "I said, ", // TODO
+ "The Inspector asked, ", // TODO
+ "The Inspector said, ", // TODO
+ "%s asked, ", // TODO
+ "\x25\x73\xbb\xa1\x3a", /* "%s說:"; "%s said, " */
+ // Then Holmes/I/The Inspector/Person asked/said
+ "Then Holmes asked, ", // TODO
+ "Then Holmes said, ", // TODO
+ "Then I asked, ", // TODO
+ "Then I said, ", // TODO
+ "Then the Inspector asked, ", // TODO
+ "Then the Inspector said, ", // TODO
+ "Then %s asked, ", // TODO
+ "Then %s said, " // TODO
+};
+
FixedText::FixedText(SherlockEngine *vm) {
_vm = vm;
@@ -195,6 +226,11 @@ FixedText::FixedText(SherlockEngine *vm) {
_fixedJournalTextArray = fixedJournalTextES;
_fixedObjectPickedUpText = "Cogido/a %s";
break;
+ case Common::ZH_TWN:
+ // Used by Sherlock Holmes 1+2
+ _fixedJournalTextArray = fixedJournalTextZHBig5;
+ _fixedObjectPickedUpText = "Picked up %s"; // TODO
+ break;
default:
// Default to English
_fixedJournalTextArray = fixedJournalTextEN;
diff --git a/engines/sherlock/scalpel/scalpel_fixed_text.cpp b/engines/sherlock/scalpel/scalpel_fixed_text.cpp
index 398962bf3cc..9eb7be78eaf 100644
--- a/engines/sherlock/scalpel/scalpel_fixed_text.cpp
+++ b/engines/sherlock/scalpel/scalpel_fixed_text.cpp
@@ -481,6 +481,160 @@ static const char *const fixedTextES[] = {
"El agente Dugan"
};
+static const char *const fixedTextZH[] = {
+ // Game hotkeys
+ "LMTPOCIUGJFS",
+ // SH1: Window buttons
+ "E\xc2\xf7\xb6\x7d(E)", /* "Eé¢é"; "EExit" */
+ "U\xa4\x57(U)", /* "Uä¸"; "UUp" */
+ "D\xa4\x55(D)", /* "Dä¸"; "DDown" */
+ // SH1: Inventory buttons
+ "E\xc2\xf7\xb6\x7d(E)", /* "Eé¢é"; "EExit" */
+ "L\xac\x64\xac\xdd(L)", /* "Læ¥ç"; "LLook" */
+ "U\xa8\xcf\xa5\xce(U)", /* "U使ç¨"; "UUse" */
+ "G\xb5\xb9\xbb\x50(G)", /* "G給è"; "GGive" */
+ // TODO: Inventorty next/prev buttons:
+ //"\xa5\xaa\xad\xb6", /* "å·¦é "; */
+ //"\xa5\xaa\xa4\x40", /* "å·¦ä¸"; */
+ //"\xa5\x6b\xa4\x40", /* "å³ä¸"; */
+ //"\xa5\x6b\xad\xb6", /* "å³é "; */
+ // SH1: Journal text
+ "\xb5\xd8\xa5\xcd\xaa\xba\xb5\xa7\xb0\x4f", /* "è¯çççè¨"; "Watson's Journal" */
+ "\xb2\xc4\x25\x64\xad\xb6", /* "第%dé "; "Page %d" */
+ // SH1: Journal buttons
+ "E\xc2\xf7\xb6\x7d(E)", /* "Eé¢é"; "EExit" */
+ "B\xab\x65\xa4\x51\xad\xb6(B)", /* "Bååé "; "BBack 10" */
+ "U\xa4\x57(U)", /* "Uä¸"; "UUp" */
+ "D\xa4\x55(D)", /* "Dä¸"; "DDown" */
+ "A\xab\xe1\xa4\x51\xad\xb6(A)", /* "Aå¾åé "; "AAhead 10" */
+ "S\xb4\x4d\xa7\xe4(S)", /* "Så°æ¾"; "SSearch" */
+ "F\xad\xba\xad\xb6(F)", /* "Fé¦é "; "FFirst Page" */
+ "L\xa9\xb3\xad\xb6(L)", /* "Låºé "; "LLast Page" */
+ "P\xa6\x43\xa6\x4c(P)", /* "åå°"; "PPrint Text" */
+ // SH1: Journal search
+ "\xc2\xf7\xb6\x7d", /* "Eé¢é"; "Exit" */
+ "\xab\x65\xb4\x4d", /* "åå°"; "Backward" */
+ "\xab\xe1\xb4\x4d", /* "å¾å°"; "Forward" */
+ "\xa8\x53\xa6\xb3\xa7\xe4\xa8\xec\x21", /* "æ²ææ¾å°!"; "Text Not Found !" */
+ // SH1: Settings
+ "E\xc2\xf7\xb6\x7d(E)", /* "é¢é"; "EExit" */
+ "M\xad\xb5\xbc\xd6\xb6\x7d(M)", /* "M鳿¨é"; "MMusic on" */
+ "M\xad\xb5\xbc\xd6\xc3\xf6(M)", /* "M鳿¨é"; "MMusic off" */
+ "P\xa8\x76\xb9\xb3\xb6\x7d(P)", /* "Pèåé"; "PPortrait on" */
+ "P\xa8\x76\xb9\xb3\xc3\xf6(P)", /* "Pèåé"; "PPortrait off" */
+ "JJoystick off", // Not used in Chinese as this button is skipped
+ "NNew Font Style", // Not used in Chinese as only one font is available
+ "S\xad\xb5\xae\xc4\xb6\x7d(S)", /* "S鳿é"; "SSound Effects on" */
+ "S\xad\xb5\xae\xc4\xc3\xf6(S)", /* "S鳿é"; "SSound Effects off" */
+ "W\xb5\xf8\xb5\xa1\xb7\xc6\xb1\xb2(W)", /* "Wè¦çªæ»æ²"; "WWindow Slide Scroll" */
+ "W\xb5\xf8\xb5\xa1\xa8\x71\xa5\x58(W)", /* "Wè¦çªç§åº"; "WWindow Show" */
+ "C\xbd\xd5\xbe\xe3\xb7\x6e\xb1\xec(C)", /* "èª¿æ´ææ¡¿"; "CCalibrate Joystick" */
+ "A\xbb\xb2\xa7\x55\xa5\xaa(A)", /* "Aè¼å©å·¦"; "AAuto Help left" */
+ "A\xbb\xb2\xa7\x55\xa5\x6b(A)", /* "Aè¼å©å³"; "AAuto Help right" */
+ "VVoices on", // Not used in Chinese as no voices are available
+ "VVoices off", // Not used in Chinese as no voices are available
+ "F\xb2\x48\xa5\x58\xc2\x49\xaa\xac(F)", /* "Fæ·¡åºé»ç"; "FFade by Pixel" */
+ "F\xb2\x48\xa5\x58\xaa\xbd\xb1\xb5(F)", /* "Fæ·¡åºç´æ¥"; "FFade Directly" */
+ "K\xc1\xe4\xaa\xa9\xba\x43(K)", /* "Kéµçæ
¢"; "KKey Pad Slow" */
+ "K\xc1\xe4\xaa\xa9\xa7\xd6(K)", /* "Kéµçå¿«"; "KKey Pad Fast" */
+ // Load/Save
+ "EExit", // TODO
+ "L\xb8\xfc\xa4\x4a(L)", /* "Lè¼å
¥"; "LLoad" */
+ "S\xc0\x78\xa6\x73(S)", /* "Så²å"; "SSave" */
+ "U\xa4\x57(U)", /* "Uä¸"; "UUp" */
+ "D\xa4\x55(D)", /* "Dä¸"; "DDown" */
+ "Q\xb5\xb2\xa7\xf4(Q)", /* "Qçµæ"; "QQuit" */
+ // Quit Game
+ "\xb1\x7a\xbd\x54\xa9\x77\xad\x6e\xb5\xb2\xa7\xf4\xb9\x43\xc0\xb8\xb6\xdc\x3f", /* "æ¨ç¢ºå®è¦çµæéæ²å?"; "Are you sure you wish to Quit ?" */
+ "Y\xac\x4f(Y)", /* "Yæ¯"; "YYes" */
+ "N\xa4\xa3(N)", /* "Nä¸"; "NNo" */
+ // SH1: Press key text
+ "P\xbd\xd0\xab\xf6\xa5\xf4\xb7\x4e\xc1\xe4\xc4\x7e\xc4\xf2\xa4\x55\xad\xb6\xa4\xba\xae\x65.(P)", /* "Pè«æä»»æéµç¹¼çºä¸é å
§å®¹."; "PPress any Key for More." */
+ "P\xbd\xd0\xab\xf6\xa5\xf4\xb7\x4e\xc1\xe4\xc4\x7e\xc4\xf2.(P)", /* "Pè«æä»»æéµç¹¼çº."; "PPress any Key to Continue." */
+ // SH1: Initial Inventory
+ "\xab\x4b\xb1\xf8\xaf\xc8", /* "便æ¢ç´"; "A message requesting help" */
+ "\xba\xd6\xba\xb8\xbc\xaf\xb4\xb5\xaa\xba\xa6\x57\xa4\xf9", /* "ç¦ç¾æ©æ¯çåç"; "A number of business cards" */
+ "\xba\x71\xbc\x40\xb0\x7c\xc1\x70\xb2\xbc", /* "æåé¢è¯ç¥¨"; "Opera Tickets" */
+ "\xb3\x53\xb3\xa7", /* "è¢é¦"; "Cuff Link" */
+ "\xc5\x4b\xb5\xb7\xa4\xc4", /* "éµçµ²å¾"; "Wire Hook" */
+ "\xa9\xf1\xa6\xe6\xb1\xf8", /* "æ¾è¡æ¢"; "Note" */
+ "\xa5\xb4\xb6\x7d\xaa\xba\xc3\x68\xbf\xf6", /* "æéçæ·é¶"; "An open pocket watch" */
+ "\xaf\xc8", /* "ç´"; "A piece of paper with numbers on it" */
+ "\xab\x48", /* "ä¿¡"; "A letter folded many times" */
+ "\xaf\xc8\xb5\x50", /* "ç´ç"; "Tarot Cards" */
+ "\xb5\xd8\xc4\x52\xaa\xba\xc6\x5f\xb0\xcd", /* "è¯éºçé°å"; "An ornate key" */
+ "\xb7\xed\xb2\xbc", /* "ç¶ç¥¨"; "A pawn ticket" */
+ // SH1: User Interface
+ "\xa4\xa3\x2c\xc1\xc2\xc1\xc2\xb1\x7a\x2e", /* "ä¸,è¬è¬æ¨."; "No, thank you." */
+ "You can't do that.", // TODO
+ "\xa7\xb9\xb2\xa6\x2e\x2e\x2e", /* "å®ç¢..."; "Done..." */
+ "Use ", // TODO
+ " on %s", // TODO
+ "Give ", // TODO
+ " to %s", // TODO
+ // SH1: People names
+ "\xba\xd6\xba\xb8\xbc\xaf\xb4\xb5", /* "ç¦ç¾æ©æ¯"; "Sherlock Holmes" */
+ "\xb5\xd8\xa5\xcd\xc2\xe5\xa5\xcd", /* "è¯çé«ç"; "Dr. Watson" */
+ "\xb5\xdc\xb4\xb5\xb1\x5a\xbc\x77\xb1\xb4\xaa\xf8", /* "èæ¯å´å¾·æ¢é·"; "Inspector Lestrade" */
+ "\xb6\xf8\xa5\xac\xb5\xdc\xa6\x77\xa8\xb5\xa6\xf5", /* "奧å¸èå®å·¡ä½"; "Constable O'Brien" */
+ "\xb9\x70\xba\xfb\xb4\xb5\xa8\xb5\xa6\xf5", /* "é·ç¶æ¯å·¡ä½"; "Constable Lewis" */
+ "\xdf\xc4\xdb\x69\x2e\xa9\xac\xa7\x4a", /* "è¸è.å¸å
"; "Sheila Parker" */
+ "\xa6\xeb\xa7\x51\x2e\xa5\x64\xcd\xba\xb7\xe6", /* "亨å©.å¡è®ç"; "Henry Carruthers" */
+ "\xb5\xdc\xb5\xb7\xb2\xfa", /* "èçµ²è"; "Lesley" */
+ "\xa4\xde\xae\x79\xad\xfb", /* "å¼åº§å¡"; "An Usher" */
+ "\xa5\xb1\xb7\xe7\xbc\x77\x2e\xa6\xe3\xa7\x42\xb4\xb5\xa5\xc5", /* "å¼çå¾·.è¾ä¼¯æ¯æ±"; "Fredrick Epstein" */
+ "\xb4\xec\xa8\xaf\xb9\x79\xa4\xd3\xa4\xd3", /* "渥è¾é 太太"; "Mrs. Worthington" */
+ "\xb1\xd0\xbd\x6d", /* "æç·´"; "The Coach" */
+ "\xa4\x40\xa6\x57\xb6\xa4\xad\xfb", /* "ä¸åéå¡"; "A Player" */
+ "\xb4\xa3\xa9\x69", /* "æå§"; "Tim", */
+ "\xa9\x69\xa4\x68\x2e\xae\xe1\xbc\x77\xb4\xb5", /* "å§å£«.æ¡å¾·æ¯"; "James Sanders" */
+ "\xa8\xa9\xb2\xfa", /* "è²è"; "Belle" */
+ "\xb2\x4d\xbc\xe4\xa4\x6b\xa4\x75", /* "æ¸
æ½å¥³å·¥"; "Cleaning Girl" */
+ "\xc3\x51\xaa\xf7\xb4\xb5", /* "é鿝"; "Wiggins" */
+ "\xab\x4f\xc3\xb9", /* "ä¿ç¾
"; "Paul" */
+ "\xb0\x73\xab\x4f", /* "é
ä¿"; "The Bartender" */
+ "\xa4\x40\xad\xd3\xbb\xea\xc5\xbc\xaa\xba\xb0\x73\xb0\xad", /* "ä¸å骯é«çé
鬼"; "A Dirty Drunk" */
+ "\xa4\x40\xad\xd3\xa4\x6a\xc1\x6e\xbb\xa1\xb8\xdc\xaa\xba\xb0\x73\xb0\xad", /* "ä¸å大è²èªªè©±çé
鬼"; "A Shouting Drunk" */
+ "\xa4\x40\xad\xd3\xa8\xab\xb8\xf4\xb7\x6e\xb7\x45\xaa\xba\xb0\x73\xb0\xad", /* "ä¸åèµ°è·¯æå¹çé
鬼"; "A Staggering Drunk" */
+ "\xab\x4f\xc3\xf0", /* "ä¿é¢"; "The Bouncer" */
+ "\xc5\xe7\xab\xcd\xa9\x78", /* "é©å±å®"; "The Coroner" */
+ "\xc3\x4d\xa4\x68\xaa\x41\xa9\xb1\xaa\xba\xb9\xd9\xad\x70", /* "é¨å£«æåºç夥è¨"; "Reginald Snipes" lit. "The clerk of the knight clothing store" */
+ "\xb3\xec\xaa\x76\x2e\xa5\xac\xb5\xdc\xa7\x4a\xa5\xee", /* "嬿²».å¸èå
ä¼"; "George Blackwood" */
+ "\xbf\xe0\xa6\xd5\xb4\xb5", /* "è³´è³æ¯"; "Lars" */
+ "\xc3\xc4\xa9\xd0\xa6\xd1\xaa\x4f", /* "è¥æ¿èæ¿"; "The Chemist" lit "Pharmacy owner" */
+ "\xb8\xaf\xb7\xe7\xb4\xcb\xb1\xb4\xaa\xf8", /* "èçæ£®æ¢é·"; "Inspector Gregson" */
+ "\xb8\xeb\xa5\x69\xa7\x42\x2e\xaa\x6b\xa8\xaf\xb9\x79", /* "è³å¯ä¼¯.æ³è¾é "; "Jacob Farthington" */
+ "\xb3\xc1\xa6\xd2\xa4\xd2", /* "麥è夫"; "Mycroft" */
+ "\xa6\xd1\xb3\xb7\xb0\xd2", /* "èéªæ¼"; "Old Sherman" */
+ "\xb2\x7a\xac\x64", /* "çæ¥"; "Richard" */
+ "\xbd\xd5\xb0\x73\xae\x76", /* "調é
師"; "The Barman" */
+ "\xa4\x40\xad\xd3\xa4\x40\xac\x79\xaa\xba\xaa\xb1\xaa\xcc", /* "ä¸å䏿µçç©è
"; "A Dandy Player" */
+ "\xa4\x40\xad\xd3\xa4\x54\xac\x79\xaa\xba\xaa\xb1\xaa\xcc", /* "ä¸å䏿µçç©è
"; "A Rough-looking Player" lit "A third-rate player" */
+ "\xae\xc7\xc6\x5b\xaa\xcc", /* "æè§è
"; "A Spectator" */
+ "\xc3\xb9\xa7\x42\x2e\xba\x7e\xaf\x53", /* "ç¾
伯.æ¼¢ç¹"; "Robert Hunt" */
+ "Violet", // TODO, Maybe "\xcb\xa2\xb5\xdc\xaf\x53", /* "èèç¹" */
+ "\xa8\xa9\xab\xd2\xae\xe6\xbe\x7c", /* "è²å¸æ ¼é¯"; "Pettigrew" */
+ "\xb6\xf8\xa6\x4e", /* "奧å"; "Augie" */
+ "\xa6\x77\xae\x52\x2e\xa5\x64\xac\xa5\xc1\xa8", /* "å®å¨.塿´è"; "Anna Carroway" */
+ "\xc4\xb5\xbd\xc3", /* "è¦è¡"; "A Guard" */
+ "\xa6\x77\xaa\x46\xa5\xa7\xb6\xf8\x2e\xa5\x64", /* "宿±å°¼å¥§.å¡"; "Antonio Caruso" */
+ "\xa6\xab\xa4\xf1", /* "ææ¯"; "Toby the Dog" lit "Toby" */
+ "\xa6\xe8\xbb\x58\x2e\xaa\xf7\xb4\xb5\xb5\xdc", /* "西è.鿝è"; "Simon Kingsley" */
+ "\xa8\xc8\xa6\xf2\xa6\x43\xbc\x77", /* "äºä½åå¾·"; "Alfred" */
+ "\xa5\xac\xaa\xf9\xab\xc2\xba\xb8\xa4\xd2\xa4\x48", /* "å¸éå¨ç¾å¤«äºº"; "Lady Brumwell" */
+ "\xc3\xb9\xb2\xef\xa4\xd2\xa4\x48", /* "ç¾
è夫人"; "Madame Rosa" */
+ "\xac\xf9\xb7\xe6\x2e\xbc\xaf\xba\xb8\xae\xfc\xbc\x77", /* "ç´ç.æ©ç¾æµ·å¾·"; "Joseph Moorehead" */
+ "\xb2\xa6\xba\xb8\xa4\xd3\xa4\xd3", /* "ç¢ç¾å¤ªå¤ª"; "Mrs. Beale" */
+ "\xb5\xe1\xa7\x51\xa7\x4a\xb4\xb5", /* "è²å©å
æ¯"; "Felix" */
+ "\xb2\xfc\xc6\x46\xb9\x79", /* "è·éé "; "Hollingston" */
+ "\xa5\x64\xb5\xdc\xba\x7e\xa8\xb5\xa6\xf5", /* "å¡è漢巡ä½"; "Constable Callaghan" */
+ "\xbe\x48\xaa\xd6\xa8\xb5\xa6\xf5", /* "é§è¯å·¡ä½"; "Sergeant Duncan" */
+ "\xa5\xac\xaa\xf9\xab\xc2\xba\xb8\xc0\xef\xa4\x68", /* "å¸éå¨ç¾çµå£«"; "Lord Brumwell" */
+ "\xa5\xa7\xae\xe6\x2e\xb3\xc7\xa9\x69\xb4\xcb", /* "å°¼æ ¼.åå§æ£®"; "Nigel Jaimeson" */
+ "\xc1\xe9\xaf\xc7\xb4\xb5\x2e\xb7\xe7\xa7\x4a", /* "é¾ç´æ¯.çå
"; "Jonas" */
+ "\xbe\x48\xae\xda\xa8\xb5\xa6\xf5" /* "é§æ ¹å·¡ä½"; "Constable Dugan" */
+};
+
// =========================================
// === Sherlock Holmes 1: Serrated Scalpel ===
@@ -511,6 +665,15 @@ static const char *const fixedTextES_ActionOpen[] = {
"."
};
+static const char *const fixedTextZH_ActionOpen[] = {
+ "\xb3\x6f\xb5\x4c\xaa\x6b\xa5\xb4\xb6\x7d\xaa\xba", /* "éç¡æ³æéç"; "This cannot be opened" */
+ "\xa5\xa6\xa4\x77\xb8\x67\xa5\xb4\xb6\x7d\xa4\x46", /* "å®å·²ç¶æéäº"; "It is already open" */
+ "\xa5\xa6\xb3\x51\xc2\xea\xa6\xed\xa4\x46", /* "å®è¢«éä½äº"; "It is locked" */
+ "\xb5\xa5\xab\xdd\xb5\xd8\xa5\xcd", /* "çå¾
è¯ç"; "Wait for Watson" */
+ " ",
+ "."
+};
+
static const char *const fixedTextEN_ActionClose[] = {
"This cannot be closed",
"It is already closed",
@@ -529,6 +692,12 @@ static const char *const fixedTextES_ActionClose[] = {
"La puerta de seguridad esta entre medias"
};
+static const char *const fixedTextZH_ActionClose[] = {
+ "\xb3\x6f\xb5\x4c\xaa\x6b\xc3\xf6\xa6\xed\xaa\xba", /* "éç¡æ³éä½ç"; "This cannot be closed" */
+ "\xa5\xa6\xa4\x77\xb8\x67\xc3\xf6\xb0\x5f\xa8\xd3\xa4\x46", /* "å®å·²ç¶éèµ·ä¾äº"; "It is already closed" */
+ "The safe door is in the way", // TODO
+};
+
static const char *const fixedTextEN_ActionMove[] = {
"This cannot be moved",
"It is bolted to the floor",
@@ -551,6 +720,13 @@ static const char *const fixedTextES_ActionMove[] = {
"El otro cajon esta en mitad"
};
+static const char *const fixedTextZH_ActionMove[] = {
+ "\xb3\x6f\xb5\x4c\xaa\x6b\xb2\xbe\xb0\xca\xaa\xba", /* "éç¡æ³ç§»åç"; "This cannot be moved" */
+ "It is bolted to the floor", // TODO
+ "\xb3\x6f\xaa\x46\xa6\xe8\xa4\xd3\xad\xab\xa4\x46", /* "éæ±è¥¿å¤ªéäº"; "It is too heavy" */
+ "\xb3\x51\xa8\xe4\xa5\xa6\xaa\xba\xa4\xec\xbd\x63\xbe\xd7\xa6\xed\xb8\xf4\xa4\x46", /* "被å
¶å®çæ¨ç®±æä½è·¯äº"; "The other crate is in the way" */
+};
+
static const char *const fixedTextEN_ActionPick[] = {
"Nothing of interest here",
"It is bolted down",
@@ -587,6 +763,18 @@ static const char *const fixedTextES_ActionPick[] = {
"Propiedad del gobierno para uso oficial"
};
+static const char *const fixedTextZH_ActionPick[] = {
+ "\xa8\x53\xa6\xb3\xa4\xb0\xbb\xf2\xa5\x69\xad\xc8\xb1\x6f\xae\xb3", /* "æ²æä»éº¼å¯å¼å¾æ¿"; "Nothing of interest here" */
+ "It is bolted down", // TODO
+ "It is too big to carry", // TODO
+ "\xa8\xba\xa4\xd3\xad\xab\xa4\x46", /* "é£å¤ªéäº"; "It is too heavy" */
+ "I think a girl would be more your type", // TODO
+ "Those flowers belong to Penny", // TODO
+ "She's far too young for you!", // TODO
+ "I think a girl would be more your type!", // TODO
+ "\xac\x46\xa9\xb2\xa9\xd2\xa6\xb3\x2c\xb6\xc8\xaf\xe0\xa8\xd1\xa9\x78\xa4\xe8\xa8\xcf\xa5\xce" /* "æ¿åºææ,å
è½ä¾å®æ¹ä½¿ç¨"; "Government property for official use only" */
+};
+
static const char *const fixedTextEN_ActionUse[] = {
"You can't do that",
"It had no effect",
@@ -611,6 +799,15 @@ static const char *const fixedTextES_ActionUse[] = {
"Las puertas no fuman"
};
+
+static const char *const fixedTextZH_ActionUse[] = {
+ "\xb1\x7a\xb5\x4c\xaa\x6b\xa8\xba\xbc\xcb\xa8\xcf\xa5\xce", /* "æ¨ç¡æ³é£æ¨£ä½¿ç¨"; "You can't do that" */
+ "\xa5\xa6\xac\x4f\xa8\x53\xa6\xb3\xae\xc4\xaa\x47\xaa\xba", /* "宿¯æ²æææç"; "It had no effect" */
+ "\xb1\x7a\xb5\x4c\xaa\x6b\xa8\xec\xb9\x46\xa8\xba\xc3\xe4", /* "æ¨ç¡æ³å°éé£é"; "You can't reach it" */
+ "\xa6\x6e\xa4\x46\x21\xaa\xf9\xa4\x77\xb8\x67\xb6\x7d\xa4\x46\x2c\xb0\xaa\xbf\xb3\xb6\xdc\x3f", /* "好äº!éå·²ç¶éäº,é«èå?"; "OK, the door looks bigger! Happy?" */
+ "\xaa\xf9\xb5\x4c\xaa\x6b\xa9\xe2\xb7\xcf" /* "éç¡æ³æ½ç
"; "Doors don't smoke" */
+};
+
#define FIXEDTEXT_GETCOUNT(_name_) sizeof(_name_) / sizeof(byte *)
#define FIXEDTEXT_ENTRY(_name_) _name_, FIXEDTEXT_GETCOUNT(_name_)
@@ -638,12 +835,21 @@ static const FixedTextActionEntry fixedTextES_Actions[] = {
{ FIXEDTEXT_ENTRY(fixedTextES_ActionUse) }
};
+static const FixedTextActionEntry fixedTextZH_Actions[] = {
+ { FIXEDTEXT_ENTRY(fixedTextZH_ActionOpen) },
+ { FIXEDTEXT_ENTRY(fixedTextZH_ActionClose) },
+ { FIXEDTEXT_ENTRY(fixedTextZH_ActionMove) },
+ { FIXEDTEXT_ENTRY(fixedTextZH_ActionPick) },
+ { FIXEDTEXT_ENTRY(fixedTextZH_ActionUse) }
+};
+
// =========================================
static const FixedTextLanguageEntry fixedTextLanguages[] = {
{ Common::DE_DEU, fixedTextDE, fixedTextDE_Actions },
{ Common::ES_ESP, fixedTextES, fixedTextES_Actions },
{ Common::EN_ANY, fixedTextEN, fixedTextEN_Actions },
+ { Common::ZH_TWN, fixedTextZH, fixedTextZH_Actions },
{ Common::UNK_LANG, fixedTextEN, fixedTextEN_Actions }
};
Commit: 8486739c00750d8bb3346a5135692ed560b1d9bf
https://github.com/scummvm/scummvm/commit/8486739c00750d8bb3346a5135692ed560b1d9bf
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Rearrange buttons in Chinese serrated scalpel
Changed paths:
engines/sherlock/scalpel/scalpel_screen.cpp
engines/sherlock/scalpel/scalpel_screen.h
engines/sherlock/scalpel/settings.cpp
engines/sherlock/scalpel/settings.h
diff --git a/engines/sherlock/scalpel/scalpel_screen.cpp b/engines/sherlock/scalpel/scalpel_screen.cpp
index ecdfd8338c1..c05deade992 100644
--- a/engines/sherlock/scalpel/scalpel_screen.cpp
+++ b/engines/sherlock/scalpel/scalpel_screen.cpp
@@ -32,7 +32,7 @@ ScalpelScreen::ScalpelScreen(SherlockEngine *vm) : Screen(vm) {
activateBackBuffer1();
}
-void ScalpelScreen::makeButton(const Common::Rect &bounds, int textX,
+void ScalpelScreen::makeButton(const Common::Rect &bounds, const Common::Point &textPoint,
const Common::String &buttonText, bool textContainsHotkey) {
Surface &bb = _backBuffer;
@@ -42,7 +42,12 @@ void ScalpelScreen::makeButton(const Common::Rect &bounds, int textX,
bb.fillRect(Common::Rect(bounds.left + 1, bounds.bottom - 1, bounds.right, bounds.bottom), BUTTON_BOTTOM);
bb.fillRect(Common::Rect(bounds.left + 1, bounds.top + 1, bounds.right - 1, bounds.bottom - 1), BUTTON_MIDDLE);
- buttonPrint(Common::Point(textX, bounds.top), COMMAND_FOREGROUND, false, buttonText, textContainsHotkey);
+ buttonPrint(textPoint, COMMAND_FOREGROUND, false, buttonText, textContainsHotkey);
+}
+
+void ScalpelScreen::makeButton(const Common::Rect &bounds, int textX,
+ const Common::String &buttonText, bool textContainsHotkey) {
+ makeButton(bounds, Common::Point(textX, bounds.top), buttonText, textContainsHotkey);
}
// ButtonText is supposed to have its hotkey as a prefix. The hotkey will get highlighted.
diff --git a/engines/sherlock/scalpel/scalpel_screen.h b/engines/sherlock/scalpel/scalpel_screen.h
index 32db55361a8..3a05656f9dc 100644
--- a/engines/sherlock/scalpel/scalpel_screen.h
+++ b/engines/sherlock/scalpel/scalpel_screen.h
@@ -39,6 +39,7 @@ public:
* Draws a button for use in the inventory, talk, and examine dialogs.
* ButtonText is supposed to have its hotkey as a prefix. The hotkey will get highlighted.
*/
+ void makeButton(const Common::Rect &bounds, const Common::Point &textPoint, const Common::String &buttonText, bool textContainsHotkey = true);
void makeButton(const Common::Rect &bounds, int textX, const Common::String &buttonText, bool textContainsHotkey = true);
/**
diff --git a/engines/sherlock/scalpel/settings.cpp b/engines/sherlock/scalpel/settings.cpp
index a721cf9ec61..21ef5c14142 100644
--- a/engines/sherlock/scalpel/settings.cpp
+++ b/engines/sherlock/scalpel/settings.cpp
@@ -30,7 +30,7 @@ namespace Sherlock {
namespace Scalpel {
-static const int SETUP_POINTS[12][4] = {
+static const int SETUP_POINTS_INTL[12][4] = {
{ 4, 154, 101, 53 }, // Exit
{ 4, 165, 101, 53 }, // Music Toggle
{ 219, 165, 316, 268 }, // Voice Toggle
@@ -45,8 +45,65 @@ static const int SETUP_POINTS[12][4] = {
{ 219, 187, 316, 268 } // _key Pad Accel. Toggle
};
+// Different from original to accomodate hotkeys
+static const int SETUP_POINTS_ZH[12][4] = {
+ { 3, 159, 73, 38 }, // Exit // OK
+ { 3, 178, 73, 38 }, // Music Toggle // OK
+ { 0, 0, 0, 0 }, // Voice Toggle
+ { 74, 178, 145, 109 }, // Sound Effects Toggle // OK
+ { 146, 178, 233, 191 }, // Help Button Left/Right // OK
+ { 0, 0, 0, 0 }, // New Font Style // OK
+ { 0, 0, 0, 0 }, // Joystick Toggle // OK
+ { 0, 0, 0, 0 }, // Calibrate Joystick // OK
+ { 234, 159, 317, 276 }, // Fade Style // OK
+ { 146, 159, 233, 191 }, // Window Open Style // OK
+ { 74, 159, 145, 109 }, // Portraits Toggle // OK
+ { 234, 178, 317, 276 } // _key Pad Accel. Toggle
+};
+
/*----------------------------------------------------------------*/
+bool Settings::doesButtonExist(int num) const {
+ if (_vm->getLanguage() == Common::Language::ZH_TWN)
+ return num != 2 && num != 5 && num != 6 && num != 7;
+ return true;
+}
+
+void Settings::makeButtonNumDisabled(int num, const Common::String &s) {
+ if (!doesButtonExist(num))
+ return;
+
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ makeButtonNum(num, s);
+ screen.buttonPrint(getButtonTextPoint(num), COMMAND_NULL, false, s);
+}
+
+Common::Rect Settings::getButtonRect(int num) const {
+ if (_vm->getLanguage() == Common::Language::ZH_TWN) {
+ return Common::Rect(SETUP_POINTS_ZH[num][0], SETUP_POINTS_ZH[num][1],
+ SETUP_POINTS_ZH[num][2], SETUP_POINTS_ZH[num][1] + 19);
+ } else {
+ return Common::Rect(SETUP_POINTS_INTL[num][0], SETUP_POINTS_INTL[num][1],
+ SETUP_POINTS_INTL[num][2], SETUP_POINTS_INTL[num][1] + 10);
+ }
+}
+
+void Settings::makeButtonNum(int num, const Common::String &s) {
+ if (!doesButtonExist(num))
+ return;
+
+ ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+ screen.makeButton(getButtonRect(num), getButtonTextPoint(num), s);
+}
+
+Common::Point Settings::getButtonTextPoint(int num) const {
+ if (_vm->getLanguage() == Common::Language::ZH_TWN) {
+ return Common::Point(SETUP_POINTS_ZH[num][3], SETUP_POINTS_ZH[num][1] + 2);
+ } else {
+ return Common::Point(SETUP_POINTS_INTL[num][3], SETUP_POINTS_INTL[num][1]);
+ }
+}
+
void Settings::drawInterface(bool flag) {
People &people = *_vm->_people;
ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
@@ -67,8 +124,7 @@ void Settings::drawInterface(bool flag) {
tempStr = FIXED(Settings_Exit);
_hotkeyExit = toupper(tempStr.firstChar());
- screen.makeButton(Common::Rect(SETUP_POINTS[0][0], SETUP_POINTS[0][1], SETUP_POINTS[0][2], SETUP_POINTS[0][1] + 10),
- SETUP_POINTS[0][3], tempStr);
+ makeButtonNum(0, tempStr);
if (music._musicOn) {
tempStr = FIXED(Settings_MusicOn);
@@ -76,8 +132,7 @@ void Settings::drawInterface(bool flag) {
tempStr = FIXED(Settings_MusicOff);
}
_hotkeyMusic = toupper(tempStr.firstChar());
- screen.makeButton(Common::Rect(SETUP_POINTS[1][0], SETUP_POINTS[1][1], SETUP_POINTS[1][2], SETUP_POINTS[1][1] + 10),
- SETUP_POINTS[1][3], tempStr);
+ makeButtonNum(1, tempStr);
if (people._portraitsOn) {
tempStr = FIXED(Settings_PortraitsOn);
@@ -85,19 +140,15 @@ void Settings::drawInterface(bool flag) {
tempStr = FIXED(Settings_PortraitsOff);
}
_hotkeyPortraits = toupper(tempStr.firstChar());
- screen.makeButton(Common::Rect(SETUP_POINTS[10][0], SETUP_POINTS[10][1], SETUP_POINTS[10][2], SETUP_POINTS[10][1] + 10),
- SETUP_POINTS[10][3], tempStr);
+ makeButtonNum(10, tempStr);
// WORKAROUND: We don't support the joystick in ScummVM, so draw the next two buttons as disabled
tempStr = FIXED(Settings_JoystickOff);
- screen.makeButton(Common::Rect(SETUP_POINTS[6][0], SETUP_POINTS[6][1], SETUP_POINTS[6][2], SETUP_POINTS[6][1] + 10),
- SETUP_POINTS[6][3], tempStr);
- screen.buttonPrint(Common::Point(SETUP_POINTS[6][3], SETUP_POINTS[6][1]), COMMAND_NULL, false, tempStr);
+ makeButtonNumDisabled(6, tempStr);
tempStr = FIXED(Settings_NewFontStyle);
_hotkeyNewFontStyle = toupper(tempStr.firstChar());
- screen.makeButton(Common::Rect(SETUP_POINTS[5][0], SETUP_POINTS[5][1], SETUP_POINTS[5][2], SETUP_POINTS[5][1] + 10),
- SETUP_POINTS[5][3], tempStr);
+ makeButtonNum(5, tempStr);
if (sound._digitized) {
tempStr = FIXED(Settings_SoundEffectsOn);
@@ -105,8 +156,7 @@ void Settings::drawInterface(bool flag) {
tempStr = FIXED(Settings_SoundEffectsOff);
}
_hotkeySoundEffects = toupper(tempStr.firstChar());
- screen.makeButton(Common::Rect(SETUP_POINTS[3][0], SETUP_POINTS[3][1], SETUP_POINTS[3][2], SETUP_POINTS[3][1] + 10),
- SETUP_POINTS[3][3], tempStr);
+ makeButtonNum(3, tempStr);
if (ui._slideWindows) {
tempStr = FIXED(Settings_WindowsSlide);
@@ -114,13 +164,10 @@ void Settings::drawInterface(bool flag) {
tempStr = FIXED(Settings_WindowsAppear);
}
_hotkeyWindows = toupper(tempStr.firstChar());
- screen.makeButton(Common::Rect(SETUP_POINTS[9][0], SETUP_POINTS[9][1], SETUP_POINTS[9][2], SETUP_POINTS[9][1] + 10),
- SETUP_POINTS[9][3], tempStr);
+ makeButtonNum(9, tempStr);
tempStr = FIXED(Settings_CalibrateJoystick);
- screen.makeButton(Common::Rect(SETUP_POINTS[7][0], SETUP_POINTS[7][1], SETUP_POINTS[7][2], SETUP_POINTS[7][1] + 10),
- SETUP_POINTS[7][3], tempStr);
- screen.buttonPrint(Common::Point(SETUP_POINTS[7][3], SETUP_POINTS[7][1]), COMMAND_NULL, false, tempStr);
+ makeButtonNumDisabled(7, tempStr);
if (ui._helpStyle) {
tempStr = FIXED(Settings_AutoHelpRight);
@@ -128,8 +175,7 @@ void Settings::drawInterface(bool flag) {
tempStr = FIXED(Settings_AutoHelpLeft);
}
_hotkeyAutoHelp = toupper(tempStr.firstChar());
- screen.makeButton(Common::Rect(SETUP_POINTS[4][0], SETUP_POINTS[4][1], SETUP_POINTS[4][2], SETUP_POINTS[4][1] + 10),
- SETUP_POINTS[4][3], tempStr);
+ makeButtonNum(4, tempStr);
if (sound._voices) {
tempStr = FIXED(Settings_VoicesOn);
@@ -137,8 +183,7 @@ void Settings::drawInterface(bool flag) {
tempStr = FIXED(Settings_VoicesOff);
}
_hotkeyVoices = toupper(tempStr.firstChar());
- screen.makeButton(Common::Rect(SETUP_POINTS[2][0], SETUP_POINTS[2][1], SETUP_POINTS[2][2], SETUP_POINTS[2][1] + 10),
- SETUP_POINTS[2][3], tempStr);
+ makeButtonNum(2, tempStr);
if (screen._fadeStyle) {
tempStr = FIXED(Settings_FadeByPixel);
@@ -146,13 +191,10 @@ void Settings::drawInterface(bool flag) {
tempStr = FIXED(Settings_FadeDirectly);
}
_hotkeyFade = toupper(tempStr.firstChar());
- screen.makeButton(Common::Rect(SETUP_POINTS[8][0], SETUP_POINTS[8][1], SETUP_POINTS[8][2], SETUP_POINTS[8][1] + 10),
- SETUP_POINTS[8][3], tempStr);
+ makeButtonNum(8, tempStr);
tempStr = FIXED(Settings_KeyPadSlow);
- screen.makeButton(Common::Rect(SETUP_POINTS[11][0], SETUP_POINTS[11][1], SETUP_POINTS[11][2], SETUP_POINTS[11][1] + 10),
- SETUP_POINTS[11][3], tempStr);
- screen.buttonPrint(Common::Point(SETUP_POINTS[11][3], SETUP_POINTS[11][1]), COMMAND_NULL, false, tempStr);
+ makeButtonNumDisabled(11, tempStr);
_hotkeysIndexed[0] = _hotkeyExit;
_hotkeysIndexed[1] = _hotkeyMusic;
@@ -190,8 +232,9 @@ int Settings::drawButtons(const Common::Point &pt, int _key) {
Common::String tempStr;
for (int idx = 0; idx < 12; ++idx) {
- if ((pt.x > SETUP_POINTS[idx][0] && pt.x < SETUP_POINTS[idx][2] && pt.y > SETUP_POINTS[idx][1]
- && pt.y < (SETUP_POINTS[idx][1] + 10) && (events._pressed || events._released))
+ if (!doesButtonExist(idx))
+ continue;
+ if ((getButtonRect(idx).contains(pt) && (events._pressed || events._released))
|| (_key == toupper(_hotkeysIndexed[idx]))) {
found = idx;
color = COMMAND_HIGHLIGHTED;
@@ -268,7 +311,7 @@ int Settings::drawButtons(const Common::Point &pt, int _key) {
default:
continue;
}
- screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr);
+ screen.buttonPrint(getButtonTextPoint(idx), color, true, tempStr);
}
return found;
diff --git a/engines/sherlock/scalpel/settings.h b/engines/sherlock/scalpel/settings.h
index b0feaebba28..925f0c258f2 100644
--- a/engines/sherlock/scalpel/settings.h
+++ b/engines/sherlock/scalpel/settings.h
@@ -69,6 +69,13 @@ private:
* Draws the buttons for the settings dialog
*/
int drawButtons(const Common::Point &pt, int key);
+
+ Common::Rect getButtonRect(int num) const;
+ Common::Point getButtonTextPoint(int num) const;
+ void makeButtonNum(int num, const Common::String &s);
+ void makeButtonNumDisabled(int num, const Common::String &s);
+ bool doesButtonExist(int num) const;
+
public:
/**
* Handles input when the settings window is being shown
Commit: 38a6cb8e8b666234f2d9f6fc4dc7425b09965d0f
https://github.com/scummvm/scummvm/commit/38a6cb8e8b666234f2d9f6fc4dc7425b09965d0f
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Always use font 2 for Chinese serrated scalpel
Changed paths:
engines/sherlock/fonts.cpp
diff --git a/engines/sherlock/fonts.cpp b/engines/sherlock/fonts.cpp
index 5a5b3a7fbc0..60f575b48af 100644
--- a/engines/sherlock/fonts.cpp
+++ b/engines/sherlock/fonts.cpp
@@ -67,6 +67,8 @@ void Fonts::setFont(int fontNum) {
// The non-interactive demo does not contain any font at all
return;
}
+ if (_vm->getLanguage() == Common::Language::ZH_TWN)
+ fontNum = 2;
}
Common::String fontFilename;
Commit: c58c5cb86a22b5f290b79e7282434110fd37115f
https://github.com/scummvm/scummvm/commit/c58c5cb86a22b5f290b79e7282434110fd37115f
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Fix handling of big5 in journal
Changed paths:
engines/sherlock/journal.cpp
diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp
index 6ecdee9ca83..f7c00dfb162 100644
--- a/engines/sherlock/journal.cpp
+++ b/engines/sherlock/journal.cpp
@@ -304,6 +304,7 @@ void Journal::loadJournalFile(bool alreadyLoaded) {
Talk &talk = *_vm->_talk;
JournalEntry &journalEntry = _journal[_index];
const byte *opcodes = talk._opcodes;
+ bool isBig5 = Fonts::isBig5();
Common::String dirFilename = _directory[journalEntry._converseNum];
bool replyOnly = journalEntry._replyOnly;
@@ -520,7 +521,13 @@ void Journal::loadJournalFile(bool alreadyLoaded) {
// {} block is started, or a control character is encountered
journalString += c;
while (*replyP && isPrintable(*replyP) && *replyP != '{' && *replyP != '}') {
- journalString += *replyP++;
+ journalString += *replyP;
+
+ if (isBig5 && (*replyP & 0x80)) {
+ journalString += *++replyP;
+ }
+
+ replyP++;
}
commentJustPrinted = false;
Commit: 187b28f0e52b5606e90d2e4f60a9fe223383732f
https://github.com/scummvm/scummvm/commit/187b28f0e52b5606e90d2e4f60a9fe223383732f
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Fix offsets in Chinese journal for serrated scalpel
Changed paths:
engines/sherlock/journal.cpp
engines/sherlock/journal.h
engines/sherlock/scalpel/scalpel_journal.cpp
diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp
index f7c00dfb162..f27c25fcd25 100644
--- a/engines/sherlock/journal.cpp
+++ b/engines/sherlock/journal.cpp
@@ -56,8 +56,8 @@ bool Journal::drawJournal(int direction, int howFar) {
FixedText &fixedText = *_vm->_fixedText;
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
- int topLineY = IS_SERRATED_SCALPEL ? 37 : 103 - screen.charHeight('A');
- int yp = topLineY;
+ int topLineY;
+ int yp;
int startPage = _page;
bool endJournal = false;
bool firstOccurance = true;
@@ -68,6 +68,22 @@ bool Journal::drawJournal(int direction, int howFar) {
int temp;
const char *matchP;
int width;
+ int leftX;
+
+ if (IS_SERRATED_SCALPEL) {
+ if (_vm->getLanguage() == Common::ZH_TWN) {
+ topLineY = 31;
+ leftX = 36;
+ } else {
+ topLineY = 37;
+ leftX = 53;
+ }
+ } else {
+ topLineY = 103 - screen.charHeight('A');
+ leftX = 156;
+ }
+
+ yp = topLineY;
talk._converseNum = -1;
_down = true;
@@ -242,30 +258,30 @@ bool Journal::drawJournal(int direction, int howFar) {
Common::String lineStart(_lines[temp].c_str(), matchP);
if (lineStart.hasPrefix("@")) {
width = screen.stringWidth(lineStart.c_str() + 1);
- screen.gPrint(Common::Point(JOURNAL_LEFT_X, yp), COL_PEN_HIGHLIGHT, "%s", lineStart.c_str() + 1);
+ screen.gPrint(Common::Point(leftX, yp), COL_PEN_HIGHLIGHT, "%s", lineStart.c_str() + 1);
} else {
width = screen.stringWidth(lineStart.c_str());
- screen.gPrint(Common::Point(JOURNAL_LEFT_X, yp), COL_PEN_COLOR, "%s", lineStart.c_str());
+ screen.gPrint(Common::Point(leftX, yp), COL_PEN_COLOR, "%s", lineStart.c_str());
}
// Print out the found keyword
Common::String lineMatch(matchP, matchP + _find.size());
byte fgColor = IS_SERRATED_SCALPEL ? (byte)Scalpel::INV_FOREGROUND : (byte)Tattoo::PEN_HIGHLIGHT_COLOR;
- screen.gPrint(Common::Point(JOURNAL_LEFT_X + width, yp), fgColor, "%s", lineMatch.c_str());
+ screen.gPrint(Common::Point(leftX + width, yp), fgColor, "%s", lineMatch.c_str());
width += screen.stringWidth(lineMatch.c_str());
// Print remainder of line
- screen.gPrint(Common::Point(JOURNAL_LEFT_X + width, yp), COL_PEN_COLOR, "%s", matchP + _find.size());
+ screen.gPrint(Common::Point(leftX + width, yp), COL_PEN_COLOR, "%s", matchP + _find.size());
} else if (_lines[temp].hasPrefix("@")) {
- screen.gPrint(Common::Point(JOURNAL_LEFT_X, yp), COL_PEN_HIGHLIGHT, "%s", _lines[temp].c_str() + 1);
+ screen.gPrint(Common::Point(leftX, yp), COL_PEN_HIGHLIGHT, "%s", _lines[temp].c_str() + 1);
} else {
- screen.gPrint(Common::Point(JOURNAL_LEFT_X, yp), COL_PEN_COLOR, "%s", _lines[temp].c_str());
+ screen.gPrint(Common::Point(leftX, yp), COL_PEN_COLOR, "%s", _lines[temp].c_str());
}
} else {
if (_lines[temp].hasPrefix("@")) {
- screen.gPrint(Common::Point(JOURNAL_LEFT_X, yp), COL_PEN_HIGHLIGHT, "%s", _lines[temp].c_str() + 1);
+ screen.gPrint(Common::Point(leftX, yp), COL_PEN_HIGHLIGHT, "%s", _lines[temp].c_str() + 1);
} else {
- screen.gPrint(Common::Point(JOURNAL_LEFT_X, yp), COL_PEN_COLOR, "%s", _lines[temp].c_str());
+ screen.gPrint(Common::Point(leftX, yp), COL_PEN_COLOR, "%s", _lines[temp].c_str());
}
}
@@ -286,7 +302,10 @@ bool Journal::drawJournal(int direction, int howFar) {
if (inc) {
// Move to next line
- yp += IS_SERRATED_SCALPEL ? 13 : TATTOO_LINE_SPACING[lineNum];
+ if (IS_SERRATED_SCALPEL)
+ yp += _vm->getLanguage() == Common::ZH_TWN ? 16 : 13;
+ else
+ yp += TATTOO_LINE_SPACING[lineNum];
++lineNum;
}
} while (lineNum < LINES_PER_PAGE && !endFlag);
diff --git a/engines/sherlock/journal.h b/engines/sherlock/journal.h
index 9aa326fa052..0262dd3eaf1 100644
--- a/engines/sherlock/journal.h
+++ b/engines/sherlock/journal.h
@@ -34,7 +34,6 @@ namespace Sherlock {
#define LINES_PER_PAGE (IS_SERRATED_SCALPEL ? 11 : 17)
#define JOURNAL_MAX_WIDTH (IS_SERRATED_SCALPEL ? 230 : 422)
#define JOURNAL_MAX_CHARS 80
-#define JOURNAL_LEFT_X (IS_SERRATED_SCALPEL ? 53 : 156)
class SherlockEngine;
diff --git a/engines/sherlock/scalpel/scalpel_journal.cpp b/engines/sherlock/scalpel/scalpel_journal.cpp
index f1859437520..a5bcf5fe9cb 100644
--- a/engines/sherlock/scalpel/scalpel_journal.cpp
+++ b/engines/sherlock/scalpel/scalpel_journal.cpp
@@ -175,8 +175,13 @@ void ScalpelJournal::drawFrame() {
// Set the palette and print the title
screen.setPalette(palette);
- screen.gPrint(Common::Point(111, 18), BUTTON_BOTTOM, "%s", _fixedTextWatsonsJournal.c_str());
- screen.gPrint(Common::Point(110, 17), INV_FOREGROUND, "%s", _fixedTextWatsonsJournal.c_str());
+ if (_vm->getLanguage() == Common::ZH_TWN) {
+ screen.gPrint(Common::Point(111, 13), BUTTON_BOTTOM, "%s", _fixedTextWatsonsJournal.c_str());
+ screen.gPrint(Common::Point(110, 12), INV_FOREGROUND, "%s", _fixedTextWatsonsJournal.c_str());
+ } else {
+ screen.gPrint(Common::Point(111, 18), BUTTON_BOTTOM, "%s", _fixedTextWatsonsJournal.c_str());
+ screen.gPrint(Common::Point(110, 17), INV_FOREGROUND, "%s", _fixedTextWatsonsJournal.c_str());
+ }
// Draw the buttons
screen.makeButton(Common::Rect(JOURNAL_POINTS[0][0], JOURNAL_BUTTONS_Y,
Commit: cf651ca336c0edbbf6479d5e49dfc60ad3e41242
https://github.com/scummvm/scummvm/commit/cf651ca336c0edbbf6479d5e49dfc60ad3e41242
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Fix isPrintable for big5
Changed paths:
engines/sherlock/journal.cpp
diff --git a/engines/sherlock/journal.cpp b/engines/sherlock/journal.cpp
index f27c25fcd25..0553587f695 100644
--- a/engines/sherlock/journal.cpp
+++ b/engines/sherlock/journal.cpp
@@ -806,6 +806,9 @@ bool Journal::isPrintable(byte ch) const {
if (_vm->getLanguage() == Common::DE_DEU && ch == 0xe1) // accept German Sharp-S character
return true;
+ if (_vm->getLanguage() == Common::ZH_TWN && IS_SERRATED_SCALPEL && ch > 161)
+ return true;
+
return false;
}
Commit: f407e19890667e31664cb9ca78bc08cde42cc835
https://github.com/scummvm/scummvm/commit/f407e19890667e31664cb9ca78bc08cde42cc835
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Adjust journal buttons for Chinese serrated scalpel
Changed paths:
engines/sherlock/scalpel/scalpel_journal.cpp
engines/sherlock/scalpel/scalpel_journal.h
diff --git a/engines/sherlock/scalpel/scalpel_journal.cpp b/engines/sherlock/scalpel/scalpel_journal.cpp
index a5bcf5fe9cb..605611719bf 100644
--- a/engines/sherlock/scalpel/scalpel_journal.cpp
+++ b/engines/sherlock/scalpel/scalpel_journal.cpp
@@ -31,14 +31,15 @@ namespace Sherlock {
namespace Scalpel {
-#define JOURNAL_BUTTONS_Y 178
+#define JOURNAL_BUTTONS_Y_INTL 178
+#define JOURNAL_BUTTONS_Y_ZH 181
#define JOURNAL_SEARCH_LEFT 15
#define JOURNAL_SEARCH_TOP 186
#define JOURNAL_SEARCH_RIGHT 296
#define JOURNAL_SEACRH_MAX_CHARS 50
// Positioning of buttons in the journal view
-static const int JOURNAL_POINTS[9][3] = {
+static const int JOURNAL_POINTS_INTL[9][3] = {
{ 6, 68, 37 },
{ 69, 131, 100 },
{ 132, 192, 162 },
@@ -50,6 +51,18 @@ static const int JOURNAL_POINTS[9][3] = {
{ 237, 313, 275 }
};
+static const int JOURNAL_POINTS_ZH[9][3] = {
+ { 0, 52, 26 },
+ { 53, 121, 87 },
+ { 122, 157, 140 },
+ { 158, 194, 176 },
+ { 195, 265, 230 },
+ { 266, 320, 293 },
+ { 270, 320, 295 },
+ { 270, 320, 295 },
+ { 0, 0, 0 }
+};
+
static const int SEARCH_POINTS[3][3] = {
{ 51, 123, 86 },
{ 124, 196, 159 },
@@ -95,6 +108,40 @@ ScalpelJournal::ScalpelJournal(SherlockEngine *vm) : Journal(vm) {
_hotkeySearchForward = toupper(_fixedTextSearchForward[0]);
}
+Common::Rect ScalpelJournal::getButtonRect(JournalButton btn) {
+ int idx = btn - 1;
+ if (_vm->getLanguage() == Common::ZH_TWN) {
+ if (btn >= BTN_FIRST_PAGE) {
+ return Common::Rect(JOURNAL_POINTS_ZH[idx][0], JOURNAL_BUTTONS_Y_ZH - (btn - BTN_FIRST_PAGE + 1) * 19,
+ JOURNAL_POINTS_ZH[idx][1], JOURNAL_BUTTONS_Y_ZH + 19 - (btn - BTN_FIRST_PAGE + 1) * 19);
+ } else
+ return Common::Rect(JOURNAL_POINTS_ZH[idx][0], JOURNAL_BUTTONS_Y_ZH,
+ JOURNAL_POINTS_ZH[idx][1], JOURNAL_BUTTONS_Y_ZH + 19);
+ } else {
+ if (btn >= BTN_SEARCH)
+ return Common::Rect(JOURNAL_POINTS_INTL[idx][0], JOURNAL_BUTTONS_Y_INTL + 11,
+ JOURNAL_POINTS_INTL[idx][1], JOURNAL_BUTTONS_Y_INTL + 21);
+ else
+ return Common::Rect(JOURNAL_POINTS_INTL[idx][0], JOURNAL_BUTTONS_Y_INTL,
+ JOURNAL_POINTS_INTL[idx][1], JOURNAL_BUTTONS_Y_INTL + 10);
+ }
+}
+
+Common::Point ScalpelJournal::getButtonTextPoint(JournalButton btn) {
+ int idx = btn - 1;
+ if (_vm->getLanguage() == Common::ZH_TWN) {
+ if (btn >= BTN_FIRST_PAGE)
+ return Common::Point(JOURNAL_POINTS_ZH[idx][2], JOURNAL_BUTTONS_Y_ZH + 2 - (btn - BTN_FIRST_PAGE + 1) * 19);
+ else
+ return Common::Point(JOURNAL_POINTS_ZH[idx][2], JOURNAL_BUTTONS_Y_ZH + 2);
+ } else {
+ if (btn >= BTN_SEARCH)
+ return Common::Point(JOURNAL_POINTS_INTL[idx][2], JOURNAL_BUTTONS_Y_INTL + 11);
+ else
+ return Common::Point(JOURNAL_POINTS_INTL[idx][2], JOURNAL_BUTTONS_Y_INTL);
+ }
+}
+
void ScalpelJournal::loadLocations() {
Resources &res = *_vm->_res;
@@ -184,37 +231,21 @@ void ScalpelJournal::drawFrame() {
}
// Draw the buttons
- screen.makeButton(Common::Rect(JOURNAL_POINTS[0][0], JOURNAL_BUTTONS_Y,
- JOURNAL_POINTS[0][1], JOURNAL_BUTTONS_Y + 10),
- JOURNAL_POINTS[0][2], _fixedTextExit);
- screen.makeButton(Common::Rect(JOURNAL_POINTS[1][0], JOURNAL_BUTTONS_Y,
- JOURNAL_POINTS[1][1], JOURNAL_BUTTONS_Y + 10),
- JOURNAL_POINTS[1][2], _fixedTextBack10);
- screen.makeButton(Common::Rect(JOURNAL_POINTS[2][0], JOURNAL_BUTTONS_Y,
- JOURNAL_POINTS[2][1], JOURNAL_BUTTONS_Y + 10),
- JOURNAL_POINTS[2][2], _fixedTextUp);
- screen.makeButton(Common::Rect(JOURNAL_POINTS[3][0], JOURNAL_BUTTONS_Y,
- JOURNAL_POINTS[3][1], JOURNAL_BUTTONS_Y + 10),
- JOURNAL_POINTS[3][2], _fixedTextDown);
- screen.makeButton(Common::Rect(JOURNAL_POINTS[4][0], JOURNAL_BUTTONS_Y,
- JOURNAL_POINTS[4][1], JOURNAL_BUTTONS_Y + 10),
- JOURNAL_POINTS[4][2], _fixedTextAhead10);
- screen.makeButton(Common::Rect(JOURNAL_POINTS[5][0], JOURNAL_BUTTONS_Y + 11,
- JOURNAL_POINTS[5][1], JOURNAL_BUTTONS_Y + 21),
- JOURNAL_POINTS[5][2], _fixedTextSearch);
- screen.makeButton(Common::Rect(JOURNAL_POINTS[6][0], JOURNAL_BUTTONS_Y + 11,
- JOURNAL_POINTS[6][1], JOURNAL_BUTTONS_Y + 21),
- JOURNAL_POINTS[6][2], _fixedTextFirstPage);
- screen.makeButton(Common::Rect(JOURNAL_POINTS[7][0], JOURNAL_BUTTONS_Y + 11,
- JOURNAL_POINTS[7][1], JOURNAL_BUTTONS_Y + 21),
- JOURNAL_POINTS[7][2], _fixedTextLastPage);
+ screen.makeButton(getButtonRect(BTN_EXIT), getButtonTextPoint(BTN_EXIT), _fixedTextExit);
+ screen.makeButton(getButtonRect(BTN_BACK10), getButtonTextPoint(BTN_BACK10), _fixedTextBack10);
+ screen.makeButton(getButtonRect(BTN_UP), getButtonTextPoint(BTN_UP), _fixedTextUp);
+ screen.makeButton(getButtonRect(BTN_DOWN), getButtonTextPoint(BTN_DOWN), _fixedTextDown);
+ screen.makeButton(getButtonRect(BTN_AHEAD110), getButtonTextPoint(BTN_AHEAD110), _fixedTextAhead10);
+ screen.makeButton(getButtonRect(BTN_SEARCH), getButtonTextPoint(BTN_SEARCH), _fixedTextSearch);
+ screen.makeButton(getButtonRect(BTN_FIRST_PAGE), getButtonTextPoint(BTN_FIRST_PAGE), _fixedTextFirstPage);
+ screen.makeButton(getButtonRect(BTN_LAST_PAGE), getButtonTextPoint(BTN_LAST_PAGE), _fixedTextLastPage);
// WORKAROUND: Draw Print Text button as disabled, since we don't support it in ScummVM
- screen.makeButton(Common::Rect(JOURNAL_POINTS[8][0], JOURNAL_BUTTONS_Y + 11,
- JOURNAL_POINTS[8][1], JOURNAL_BUTTONS_Y + 21),
- JOURNAL_POINTS[8][2], _fixedTextPrintText);
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11),
- COMMAND_NULL, false, _fixedTextPrintText);
+ // In Chinese version skip it altogether to make space for hotkeys
+ if (_vm->getLanguage() != Common::ZH_TWN) {
+ screen.makeButton(getButtonRect(BTN_PRINT_TEXT), getButtonTextPoint(BTN_PRINT_TEXT), _fixedTextPrintText);
+ screen.buttonPrint(getButtonTextPoint(BTN_PRINT_TEXT), COMMAND_NULL, false, _fixedTextPrintText);
+ }
}
void ScalpelJournal::drawInterface() {
@@ -239,57 +270,50 @@ void ScalpelJournal::doArrows() {
byte color;
color = (_page > 1) ? COMMAND_FOREGROUND : COMMAND_NULL;
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), color, false, _fixedTextBack10);
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), color, false, _fixedTextUp);
+ screen.buttonPrint(getButtonTextPoint(BTN_BACK10), color, false, _fixedTextBack10);
+ screen.buttonPrint(getButtonTextPoint(BTN_UP), color, false, _fixedTextUp);
color = _down ? COMMAND_FOREGROUND : COMMAND_NULL;
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), color, false, _fixedTextDown);
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), color, false, _fixedTextAhead10);
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, false, _fixedTextLastPage);
+ screen.buttonPrint(getButtonTextPoint(BTN_DOWN), color, false, _fixedTextDown);
+ screen.buttonPrint(getButtonTextPoint(BTN_AHEAD110), color, false, _fixedTextAhead10);
+ screen.buttonPrint(getButtonTextPoint(BTN_LAST_PAGE), color, false, _fixedTextLastPage);
color = _journal.size() > 0 ? COMMAND_FOREGROUND : COMMAND_NULL;
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, false, _fixedTextSearch);
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, false, _fixedTextPrintText);
+ screen.buttonPrint(getButtonTextPoint(BTN_SEARCH), color, false, _fixedTextSearch);
+ if (_vm->getLanguage() != Common::ZH_TWN) {
+ screen.buttonPrint(getButtonTextPoint(BTN_PRINT_TEXT), COMMAND_NULL, false, _fixedTextPrintText);
+ }
color = _page > 1 ? COMMAND_FOREGROUND : COMMAND_NULL;
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, false, _fixedTextFirstPage);
+ screen.buttonPrint(getButtonTextPoint(BTN_FIRST_PAGE), color, false, _fixedTextFirstPage);
}
JournalButton ScalpelJournal::getHighlightedButton(const Common::Point &pt) {
- if (pt.x > JOURNAL_POINTS[0][0] && pt.x < JOURNAL_POINTS[0][1] && pt.y >= JOURNAL_BUTTONS_Y &&
- pt.y < (JOURNAL_BUTTONS_Y + 10))
+ if (getButtonRect(BTN_EXIT).contains(pt))
return BTN_EXIT;
- if (pt.x > JOURNAL_POINTS[1][0] && pt.x < JOURNAL_POINTS[1][1] && pt.y >= JOURNAL_BUTTONS_Y &&
- pt.y < (JOURNAL_BUTTONS_Y + 10) && _page > 1)
+ if (getButtonRect(BTN_BACK10).contains(pt) && _page > 1)
return BTN_BACK10;
- if (pt.x > JOURNAL_POINTS[2][0] && pt.x < JOURNAL_POINTS[2][1] && pt.y >= JOURNAL_BUTTONS_Y &&
- pt.y < (JOURNAL_BUTTONS_Y + 10) && _up)
+ if (getButtonRect(BTN_UP).contains(pt) && _up)
return BTN_UP;
- if (pt.x > JOURNAL_POINTS[3][0] && pt.x < JOURNAL_POINTS[3][1] && pt.y >= JOURNAL_BUTTONS_Y &&
- pt.y < (JOURNAL_BUTTONS_Y + 10) && _down)
+ if (getButtonRect(BTN_DOWN).contains(pt) && _down)
return BTN_DOWN;
- if (pt.x > JOURNAL_POINTS[4][0] && pt.x < JOURNAL_POINTS[4][1] && pt.y >= JOURNAL_BUTTONS_Y &&
- pt.y < (JOURNAL_BUTTONS_Y + 10) && _down)
+ if (getButtonRect(BTN_AHEAD110).contains(pt) && _down)
return BTN_AHEAD110;
- if (pt.x > JOURNAL_POINTS[5][0] && pt.x < JOURNAL_POINTS[5][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
- pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty())
+ if (getButtonRect(BTN_SEARCH).contains(pt) && !_journal.empty())
return BTN_SEARCH;
- if (pt.x > JOURNAL_POINTS[6][0] && pt.x < JOURNAL_POINTS[6][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
- pt.y < (JOURNAL_BUTTONS_Y + 20) && _up)
+ if (getButtonRect(BTN_FIRST_PAGE).contains(pt) && _up)
return BTN_FIRST_PAGE;
- if (pt.x > JOURNAL_POINTS[7][0] && pt.x < JOURNAL_POINTS[7][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
- pt.y < (JOURNAL_BUTTONS_Y + 20) && _down)
+ if (getButtonRect(BTN_LAST_PAGE).contains(pt) && _down)
return BTN_LAST_PAGE;
- if (pt.x > JOURNAL_POINTS[8][0] && pt.x < JOURNAL_POINTS[8][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
- pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty())
+ if (_vm->getLanguage() != Common::ZH_TWN && getButtonRect(BTN_PRINT_TEXT).contains(pt) && !_journal.empty())
return BTN_PRINT_TEXT;
return BTN_NONE;
@@ -307,34 +331,34 @@ bool ScalpelJournal::handleEvents(int key) {
if (events._pressed || events._released) {
// Exit button
color = (btn == BTN_EXIT) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND;
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[0][2], JOURNAL_BUTTONS_Y), color, true, _fixedTextExit);
+ screen.buttonPrint(getButtonTextPoint(BTN_EXIT), color, true, _fixedTextExit);
// Back 10 button
if (btn == BTN_BACK10) {
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, _fixedTextBack10);
+ screen.buttonPrint(getButtonTextPoint(BTN_BACK10), COMMAND_HIGHLIGHTED, true, _fixedTextBack10);
} else if (_page > 1) {
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, _fixedTextBack10);
+ screen.buttonPrint(getButtonTextPoint(BTN_BACK10), COMMAND_FOREGROUND, true, _fixedTextBack10);
}
// Up button
if (btn == BTN_UP) {
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, _fixedTextUp);
+ screen.buttonPrint(getButtonTextPoint(BTN_UP), COMMAND_HIGHLIGHTED, true, _fixedTextUp);
} else if (_up) {
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, _fixedTextUp);
+ screen.buttonPrint(getButtonTextPoint(BTN_UP), COMMAND_FOREGROUND, true, _fixedTextUp);
}
// Down button
if (btn == BTN_DOWN) {
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, _fixedTextDown);
+ screen.buttonPrint(getButtonTextPoint(BTN_DOWN), COMMAND_HIGHLIGHTED, true, _fixedTextDown);
} else if (_down) {
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, _fixedTextDown);
+ screen.buttonPrint(getButtonTextPoint(BTN_DOWN), COMMAND_FOREGROUND, true, _fixedTextDown);
}
// Ahead 10 button
if (btn == BTN_AHEAD110) {
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, _fixedTextAhead10);
+ screen.buttonPrint(getButtonTextPoint(BTN_AHEAD110), COMMAND_HIGHLIGHTED, true, _fixedTextAhead10);
} else if (_down) {
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, _fixedTextAhead10);
+ screen.buttonPrint(getButtonTextPoint(BTN_AHEAD110), COMMAND_FOREGROUND, true, _fixedTextAhead10);
}
// Search button
@@ -345,7 +369,7 @@ bool ScalpelJournal::handleEvents(int key) {
} else {
color = COMMAND_FOREGROUND;
}
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, true, _fixedTextSearch);
+ screen.buttonPrint(getButtonTextPoint(BTN_SEARCH), color, true, _fixedTextSearch);
// First Page button
if (btn == BTN_FIRST_PAGE) {
@@ -355,7 +379,7 @@ bool ScalpelJournal::handleEvents(int key) {
} else {
color = COMMAND_NULL;
}
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, true, _fixedTextFirstPage);
+ screen.buttonPrint(getButtonTextPoint(BTN_FIRST_PAGE), color, true, _fixedTextFirstPage);
// Last Page button
if (btn == BTN_LAST_PAGE) {
@@ -365,10 +389,12 @@ bool ScalpelJournal::handleEvents(int key) {
} else {
color = COMMAND_NULL;
}
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, true, _fixedTextLastPage);
+ screen.buttonPrint(getButtonTextPoint(BTN_LAST_PAGE), color, true, _fixedTextLastPage);
- // Print Text button
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, true, _fixedTextPrintText);
+ if (_vm->getLanguage() != Common::ZH_TWN) {
+ // Print Text button
+ screen.buttonPrint(getButtonTextPoint(BTN_PRINT_TEXT), COMMAND_NULL, true, _fixedTextPrintText);
+ }
}
if (btn == BTN_EXIT && events._released) {
@@ -408,7 +434,7 @@ bool ScalpelJournal::handleEvents(int key) {
screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
} else if (((btn == BTN_SEARCH && events._released) || key == _hotkeySearch) && !_journal.empty()) {
- screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), COMMAND_FOREGROUND, true, _fixedTextSearch);
+ screen.buttonPrint(getButtonTextPoint(BTN_SEARCH), COMMAND_FOREGROUND, true, _fixedTextSearch);
bool notFound = false;
do {
diff --git a/engines/sherlock/scalpel/scalpel_journal.h b/engines/sherlock/scalpel/scalpel_journal.h
index 39f373da3a3..c32377d3034 100644
--- a/engines/sherlock/scalpel/scalpel_journal.h
+++ b/engines/sherlock/scalpel/scalpel_journal.h
@@ -120,6 +120,9 @@ public:
* can then read the journal to review them
*/
void record(int converseNum, int statementNum, bool replyOnly = false) override;
+
+ Common::Rect getButtonRect(JournalButton btn);
+ Common::Point getButtonTextPoint(JournalButton btn);
};
} // End of namespace Scalpel
Commit: 12ed6c83fe51ea37a6e34891a8ca79cb222386ac
https://github.com/scummvm/scummvm/commit/12ed6c83fe51ea37a6e34891a8ca79cb222386ac
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Change coordinates for search bar in Chinese serrated scalpel
Changed paths:
engines/sherlock/scalpel/scalpel_journal.cpp
engines/sherlock/scalpel/scalpel_journal.h
diff --git a/engines/sherlock/scalpel/scalpel_journal.cpp b/engines/sherlock/scalpel/scalpel_journal.cpp
index 605611719bf..1719380ed49 100644
--- a/engines/sherlock/scalpel/scalpel_journal.cpp
+++ b/engines/sherlock/scalpel/scalpel_journal.cpp
@@ -34,7 +34,8 @@ namespace Scalpel {
#define JOURNAL_BUTTONS_Y_INTL 178
#define JOURNAL_BUTTONS_Y_ZH 181
#define JOURNAL_SEARCH_LEFT 15
-#define JOURNAL_SEARCH_TOP 186
+#define JOURNAL_SEARCH_TOP_INTL 186
+#define JOURNAL_SEARCH_TOP_ZH 184
#define JOURNAL_SEARCH_RIGHT 296
#define JOURNAL_SEACRH_MAX_CHARS 50
@@ -53,22 +54,28 @@ static const int JOURNAL_POINTS_INTL[9][3] = {
static const int JOURNAL_POINTS_ZH[9][3] = {
{ 0, 52, 26 },
- { 53, 121, 87 },
+ { 52, 121, 87 },
{ 122, 157, 140 },
- { 158, 194, 176 },
- { 195, 265, 230 },
- { 266, 320, 293 },
+ { 157, 194, 176 },
+ { 194, 265, 230 },
+ { 265, 320, 293 },
{ 270, 320, 295 },
{ 270, 320, 295 },
{ 0, 0, 0 }
};
-static const int SEARCH_POINTS[3][3] = {
+static const int SEARCH_POINTS_INTL[3][3] = {
{ 51, 123, 86 },
{ 124, 196, 159 },
{ 197, 269, 232 }
};
+static const int SEARCH_POINTS_ZH[3][3] = {
+ { 206, 243, 225 },
+ { 243, 279, 261 },
+ { 279, 315, 297 }
+};
+
/*----------------------------------------------------------------*/
ScalpelJournal::ScalpelJournal(SherlockEngine *vm) : Journal(vm) {
@@ -142,6 +149,22 @@ Common::Point ScalpelJournal::getButtonTextPoint(JournalButton btn) {
}
}
+Common::Rect ScalpelJournal::getSearchButtonRect(int idx) {
+ if (_vm->getLanguage() == Common::ZH_TWN) {
+ return Common::Rect(SEARCH_POINTS_ZH[idx][0], 175, SEARCH_POINTS_ZH[idx][1], 194);
+ } else {
+ return Common::Rect(SEARCH_POINTS_INTL[idx][0], 174, SEARCH_POINTS_INTL[idx][1], 184);
+ }
+}
+
+Common::Point ScalpelJournal::getSearchButtonTextPoint(int idx) {
+ if (_vm->getLanguage() == Common::ZH_TWN) {
+ return Common::Point(SEARCH_POINTS_ZH[idx][2], 177);
+ } else {
+ return Common::Point(SEARCH_POINTS_INTL[idx][2], 174);
+ }
+}
+
void ScalpelJournal::loadLocations() {
Resources &res = *_vm->_res;
@@ -496,22 +519,27 @@ int ScalpelJournal::getSearchString(bool printError) {
ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
Talk &talk = *_vm->_talk;
int xp;
- int yp = 174;
+ int yp;
bool flag = false;
Common::String name;
int done = 0;
byte color;
+ bool isChinese = _vm->getLanguage() == Common::ZH_TWN;
// Draw search panel
- screen.makePanel(Common::Rect(6, 171, 313, 199));
- screen.makeButton(Common::Rect(SEARCH_POINTS[0][0], yp, SEARCH_POINTS[0][1], yp + 10),
- SEARCH_POINTS[0][2], _fixedTextSearchExit);
- screen.makeButton(Common::Rect(SEARCH_POINTS[1][0], yp, SEARCH_POINTS[1][1], yp + 10),
- SEARCH_POINTS[1][2], _fixedTextSearchBackward);
- screen.makeButton(Common::Rect(SEARCH_POINTS[2][0], yp, SEARCH_POINTS[2][1], yp + 10),
- SEARCH_POINTS[2][2], _fixedTextSearchForward);
+ if (isChinese)
+ screen.makePanel(Common::Rect(6, 171, 318, 199));
+ else
+ screen.makePanel(Common::Rect(6, 171, 313, 199));
+
+ screen.makeButton(getSearchButtonRect(0), getSearchButtonTextPoint(0), _fixedTextSearchExit, !isChinese);
+ screen.makeButton(getSearchButtonRect(1), getSearchButtonTextPoint(1), _fixedTextSearchBackward, !isChinese);
+ screen.makeButton(getSearchButtonRect(2), getSearchButtonTextPoint(2), _fixedTextSearchForward, !isChinese);
- screen.makeField(Common::Rect(12, 185, 307, 196));
+ if (isChinese)
+ screen.makeField(Common::Rect(12, 175, 205, 194));
+ else
+ screen.makeField(Common::Rect(12, 185, 307, 196));
if (printError) {
screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - screen.stringWidth(_fixedTextSearchNotFound)) / 2, 185),
@@ -522,7 +550,10 @@ int ScalpelJournal::getSearchString(bool printError) {
name = _find;
}
- screen.slamArea(6, 171, 307, 28);
+ if (_vm->getLanguage() == Common::ZH_TWN)
+ screen.slamArea(6, 171, 312, 28);
+ else
+ screen.slamArea(6, 171, 307, 28);
if (printError) {
// Give time for user to see the message
@@ -545,7 +576,7 @@ int ScalpelJournal::getSearchString(bool printError) {
}
xp = JOURNAL_SEARCH_LEFT + screen.stringWidth(name);
- yp = JOURNAL_SEARCH_TOP;
+ yp = isChinese ? JOURNAL_SEARCH_TOP_ZH : JOURNAL_SEARCH_TOP_INTL;
do {
events._released = false;
@@ -564,29 +595,29 @@ int ScalpelJournal::getSearchString(bool printError) {
screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), flag ? INV_FOREGROUND : BUTTON_MIDDLE);
if (events._pressed || events._released) {
- if (pt.x > SEARCH_POINTS[0][0] && pt.x < SEARCH_POINTS[0][1] && pt.y > 174 && pt.y < 183) {
+ if (getSearchButtonRect(0).contains(pt)) {
found = BTN_EXIT;
color = COMMAND_HIGHLIGHTED;
} else {
color = COMMAND_FOREGROUND;
}
- screen.buttonPrint(Common::Point(SEARCH_POINTS[0][0], SEARCH_POINTS[0][2]), color, false, _fixedTextSearchExit);
+ screen.buttonPrint(getSearchButtonTextPoint(0), color, false, _fixedTextSearchExit, !isChinese);
- if (pt.x > SEARCH_POINTS[1][0] && pt.x < SEARCH_POINTS[1][1] && pt.y > 174 && pt.y < 183) {
+ if (getSearchButtonRect(1).contains(pt)) {
found = BTN_BACKWARD;
color = COMMAND_HIGHLIGHTED;
} else {
color = COMMAND_FOREGROUND;
}
- screen.buttonPrint(Common::Point(SEARCH_POINTS[1][0], SEARCH_POINTS[1][2]), color, false, _fixedTextSearchBackward);
+ screen.buttonPrint(getSearchButtonTextPoint(1), color, false, _fixedTextSearchBackward, !isChinese);
- if (pt.x > SEARCH_POINTS[2][0] && pt.x < SEARCH_POINTS[2][1] && pt.y > 174 && pt.y < 183) {
+ if (getSearchButtonRect(2).contains(pt)) {
found = BTN_FORWARD;
color = COMMAND_HIGHLIGHTED;
} else {
color = COMMAND_FOREGROUND;
}
- screen.buttonPrint(Common::Point(SEARCH_POINTS[2][0], SEARCH_POINTS[2][2]), color, false, _fixedTextSearchForward);
+ screen.buttonPrint(getSearchButtonTextPoint(2), color, false, _fixedTextSearchForward, !isChinese);
}
events.wait(2);
diff --git a/engines/sherlock/scalpel/scalpel_journal.h b/engines/sherlock/scalpel/scalpel_journal.h
index c32377d3034..294fda8e0e9 100644
--- a/engines/sherlock/scalpel/scalpel_journal.h
+++ b/engines/sherlock/scalpel/scalpel_journal.h
@@ -91,6 +91,9 @@ private:
* Returns the button, if any, that is under the specified position
*/
JournalButton getHighlightedButton(const Common::Point &pt);
+
+ Common::Rect getSearchButtonRect(int idx);
+ Common::Point getSearchButtonTextPoint(int idx);
public:
ScalpelJournal(SherlockEngine *vm);
~ScalpelJournal() override {}
Commit: a728a5aee1893ea7f55308a74cc1305b4ef36300
https://github.com/scummvm/scummvm/commit/a728a5aee1893ea7f55308a74cc1305b4ef36300
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-02-28T00:40:25+01:00
Commit Message:
SHERLOCK: Don't print bogus hotkey
Changed paths:
engines/sherlock/scalpel/scalpel_screen.cpp
diff --git a/engines/sherlock/scalpel/scalpel_screen.cpp b/engines/sherlock/scalpel/scalpel_screen.cpp
index c05deade992..a5f51941a4f 100644
--- a/engines/sherlock/scalpel/scalpel_screen.cpp
+++ b/engines/sherlock/scalpel/scalpel_screen.cpp
@@ -96,11 +96,13 @@ void ScalpelScreen::buttonPrint(const Common::Point &pt, uint color, bool slamIt
if (slamIt) {
print(Common::Point(xStart, pt.y + 1),
COMMAND_FOREGROUND, "%s", buttonText.c_str() + skipTextOffset);
- print(Common::Point(xStart + prefixOffsetX, pt.y + 1), COMMAND_HIGHLIGHTED, "%c", hotkey);
+ if (textContainsHotkey)
+ print(Common::Point(xStart + prefixOffsetX, pt.y + 1), COMMAND_HIGHLIGHTED, "%c", hotkey);
} else {
gPrint(Common::Point(xStart, pt.y),
COMMAND_FOREGROUND, "%s", buttonText.c_str() + skipTextOffset);
- gPrint(Common::Point(xStart + prefixOffsetX, pt.y), COMMAND_HIGHLIGHTED, "%c", hotkey);
+ if (textContainsHotkey)
+ gPrint(Common::Point(xStart + prefixOffsetX, pt.y), COMMAND_HIGHLIGHTED, "%c", hotkey);
}
} else if (slamIt) {
print(Common::Point(xStart, pt.y + 1), color, "%s", buttonText.c_str() + skipTextOffset);
More information about the Scummvm-git-logs
mailing list