[Scummvm-git-logs] scummvm master -> cb3ee1411affe1fd852a66230dc3010df1e23966
phcoder
noreply at scummvm.org
Wed May 10 11:19:02 UTC 2023
This automated email contains information about 9 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
f9b6669241 COMMON: Add DBCS-oriented variant of String
e2c1cae56a GRIM: Add detection entry for Chinese monkey4
7e0d5f1c6f GRIM: Support localize file in UTF-16LE
bf4b5db9ed GRIM: Prefer unpacked files over ones in archives
87a4fe7831 GRIM: Support DBCS and Unicode word-wrapping
385d6e5115 GRIM: Mark ZH_TWN as requiring font rendering
98c337f1da GRIM: Support override font
c93486dfe2 GRIM: Support Chinese TGA font
cb3ee1411a GRIM: Use TGA font for Chinese monkey4
Commit: f9b666924149bd529f37dc94dc459f351e551761
https://github.com/scummvm/scummvm/commit/f9b666924149bd529f37dc94dc459f351e551761
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-05-10T13:18:54+02:00
Commit Message:
COMMON: Add DBCS-oriented variant of String
Changed paths:
A common/dbcs-str.cpp
A common/dbcs-str.h
common/module.mk
common/str-base.cpp
diff --git a/common/dbcs-str.cpp b/common/dbcs-str.cpp
new file mode 100644
index 00000000000..c286872947e
--- /dev/null
+++ b/common/dbcs-str.cpp
@@ -0,0 +1,230 @@
+/* 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 "common/dbcs-str.h"
+#include "common/str.h"
+#include "common/memorypool.h"
+#include "common/util.h"
+
+namespace Common {
+
+void DBCSString::decodeDBCS(const char *str, uint32 len) {
+ for (uint i = 0; i < len; ) {
+ if ((str[i] & 0x80) && i + 1 < len) {
+ operator+=((str[i] << 8) | (str[i+1] & 0xff));
+ i += 2;
+ } else if (str[i] & 0x80) {
+ operator+=(str[i] << 8);
+ i++;
+ } else {
+ operator+=(str[i]);
+ i++;
+ }
+ }
+}
+
+DBCSString::DBCSString(const char *str) : BaseString<uint16>() {
+ if (str == nullptr) {
+ _storage[0] = 0;
+ _size = 0;
+ } else {
+ decodeDBCS(str, strlen(str));
+ }
+}
+
+DBCSString::DBCSString(const char *str, uint32 len) : BaseString<uint16>() {
+ decodeDBCS(str, len);
+}
+
+DBCSString::DBCSString(const char *beginP, const char *endP) : BaseString<uint16>() {
+ assert(endP >= beginP);
+ decodeDBCS(beginP, endP - beginP);
+}
+
+DBCSString::DBCSString(const String &str) : BaseString<uint16>() {
+ decodeDBCS(str.c_str(), str.size());
+}
+
+DBCSString::DBCSString(uint16 c) : BaseString<uint16>() {
+ _storage[0] = c;
+ _storage[1] = 0;
+
+ _size = (c == 0) ? 0 : 1;
+}
+
+DBCSString &DBCSString::operator=(const DBCSString &str) {
+ assign(str);
+ return *this;
+}
+
+DBCSString &DBCSString::operator=(DBCSString &&str) {
+ assign(static_cast<DBCSString &&>(str));
+ return *this;
+}
+
+DBCSString &DBCSString::operator=(const String &str) {
+ clear();
+ decodeDBCS(str.c_str(), str.size());
+ return *this;
+}
+
+DBCSString &DBCSString::operator=(const value_type *str) {
+ return DBCSString::operator=(DBCSString(str));
+}
+
+DBCSString &DBCSString::operator=(const char *str) {
+ clear();
+ decodeDBCS(str, strlen(str));
+ return *this;
+}
+
+DBCSString &DBCSString::operator+=(const DBCSString &str) {
+ if (&str == this) {
+ return operator+=(DBCSString(str));
+ }
+
+ int len = str._size;
+ if (len > 0) {
+ ensureCapacity(_size + len, true);
+
+ memcpy(_str + _size, str._str, (len + 1) * sizeof(value_type));
+ _size += len;
+ }
+ return *this;
+}
+
+DBCSString &DBCSString::operator+=(value_type c) {
+ ensureCapacity(_size + 1, true);
+
+ _str[_size++] = c;
+ _str[_size] = 0;
+
+ return *this;
+}
+
+bool DBCSString::operator==(const String &x) const {
+ return equalsC(x.c_str());
+}
+
+bool DBCSString::operator==(const char *x) const {
+ return equalsC(x);
+}
+
+bool DBCSString::operator!=(const String &x) const {
+ return !equalsC(x.c_str());
+}
+
+bool DBCSString::operator!=(const char *x) const {
+ return !equalsC(x);
+}
+
+DBCSString operator+(const DBCSString &x, const DBCSString &y) {
+ DBCSString temp(x);
+ temp += y;
+ return temp;
+}
+
+DBCSString operator+(const DBCSString &x, const DBCSString::value_type y) {
+ DBCSString temp(x);
+ temp += y;
+ return temp;
+}
+
+DBCSString DBCSString::substr(size_t pos, size_t len) const {
+ if (pos >= _size)
+ return DBCSString();
+ else if (len == npos)
+ return DBCSString(_str + pos);
+ else
+ return DBCSString(_str + pos, MIN((size_t)_size - pos, len));
+}
+
+void DBCSString::insertString(const char *s, uint32 p) {
+ insertString(DBCSString(s), p);
+}
+
+void DBCSString::insertString(const String &s, uint32 p) {
+ insertString(DBCSString(s), p);
+}
+
+void DBCSString::replace(uint32 pos, uint32 count, const DBCSString &str) {
+ replace(pos, count, str, 0, str._size);
+}
+
+void DBCSString::replace(iterator begin_, iterator end_, const DBCSString &str) {
+ replace(begin_ - _str, end_ - begin_, str._str, 0, str._size);
+}
+
+void DBCSString::replace(uint32 posOri, uint32 countOri, const DBCSString &str,
+ uint32 posDest, uint32 countDest) {
+ replace(posOri, countOri, str._str, posDest, countDest);
+}
+
+void DBCSString::replace(uint32 posOri, uint32 countOri, const uint16 *str,
+ uint32 posDest, uint32 countDest) {
+
+ // Prepare string for the replaced text.
+ if (countOri < countDest) {
+ uint32 offset = countDest - countOri; ///< Offset to copy the characters
+ uint32 newSize = _size + offset;
+
+ ensureCapacity(newSize, true);
+
+ _size = newSize;
+
+ // Push the old characters to the end of the string
+ for (uint32 i = _size; i >= posOri + countDest; i--)
+ _str[i] = _str[i - offset];
+
+ } else if (countOri > countDest) {
+ uint32 offset = countOri - countDest; ///< Number of positions that we have to pull back
+
+ makeUnique();
+
+ // Pull the remainder string back
+ for (uint32 i = posOri + countDest; i + offset <= _size; i++)
+ _str[i] = _str[i + offset];
+
+ _size -= offset;
+ } else {
+ makeUnique();
+ }
+
+ // Copy the replaced part of the string
+ for (uint32 i = 0; i < countDest; i++)
+ _str[posOri + i] = str[posDest + i];
+
+}
+
+String DBCSString::convertToString() const {
+ Common::String r;
+ for (uint i = 0; i < size(); i++) {
+ if (_str[i] >= 0x100) {
+ r += _str[i] >> 8;
+ r += _str[i] & 0xff;
+ } else
+ r += _str[i];
+
+ }
+ return r;
+}
+
+} // End of namespace Common
diff --git a/common/dbcs-str.h b/common/dbcs-str.h
new file mode 100644
index 00000000000..dc66d555953
--- /dev/null
+++ b/common/dbcs-str.h
@@ -0,0 +1,172 @@
+/* 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 COMMON_DBCS_STR_H
+#define COMMON_DBCS_STR_H
+
+#include "common/scummsys.h"
+#include "common/util.h"
+#include "common/str-enc.h"
+#include "common/str-base.h"
+
+namespace Common {
+
+class String;
+
+/**
+ * A simple string class for DBCS strings in ScummVM.
+ *
+ * The presence of \0 characters in the string will cause undefined
+ * behavior in some operations.
+ */
+
+class DBCSString : public BaseString<uint16> {
+public:
+ typedef uint32 unsigned_type; /*!< Unsigned version of the underlying type. */
+public:
+ /** Construct a new empty string. */
+ constexpr DBCSString() : BaseString<uint16>() {}
+
+ /** Construct a new string from the given null-terminated C string. */
+ explicit DBCSString(const value_type *str) : BaseString<uint16>(str) {}
+
+ /** Construct a new string containing exactly @p len characters read from address @p str. */
+ DBCSString(const value_type *str, uint32 len) : BaseString<uint16>(str, len) {}
+
+ explicit DBCSString(const uint32 *str) : BaseString<uint16>((const value_type *) str) {}
+ DBCSString(const uint32 *str, uint32 len) : BaseString<uint16>((const value_type *) str, len) {}
+ DBCSString(const uint32 *beginP, const uint32 *endP) : BaseString<uint16>((const value_type *) beginP, (const value_type *) endP) {}
+
+ /** Construct a new string containing the characters between @p beginP (including) and @p endP (excluding). */
+ DBCSString(const value_type *beginP, const value_type *endP) : BaseString<uint16>(beginP, endP) {}
+
+ /** Construct a copy of the given string. */
+ DBCSString(const DBCSString &str) : BaseString<uint16>(str) {}
+
+ /** Construct a string by moving an existing string. */
+ DBCSString(DBCSString &&str) : BaseString<uint16>(static_cast<BaseString<uint16> &&>(str)) {}
+
+ /** Construct a new string from the given null-terminated C string that uses the given @p page encoding. */
+ explicit DBCSString(const char *str);
+
+ /** Construct a new string containing exactly @p len characters read from address @p str. */
+ DBCSString(const char *str, uint32 len);
+
+ /** Construct a new string containing the characters between @p beginP (including) and @p endP (excluding). */
+ DBCSString(const char *beginP, const char *endP);
+
+ /** Construct a copy of the given string. */
+ explicit DBCSString(const String &str);
+
+ /** Construct a string consisting of the given character. */
+ explicit DBCSString(value_type c);
+
+ /** Assign a given string to this string. */
+ DBCSString &operator=(const DBCSString &str);
+
+ /** Move a given string to this string. */
+ DBCSString &operator=(DBCSString &&str);
+
+ /** @overload */
+ DBCSString &operator=(const String &str);
+
+ /** @overload */
+ DBCSString &operator=(const value_type *str);
+
+ /** @overload */
+ DBCSString &operator=(const char *str);
+
+ /** Append the given string to this string. */
+ DBCSString &operator+=(const DBCSString &str);
+
+ /** @overload */
+ DBCSString &operator+=(value_type c);
+
+ using BaseString<value_type>::operator==;
+ using BaseString<value_type>::operator!=;
+
+ /** Check whether this string is identical to string @p x. */
+ bool operator==(const String &x) const;
+
+ /** @overload */
+ bool operator==(const char *x) const;
+
+ /** Check whether this string is different than string @p x. */
+ bool operator!=(const String &x) const;
+
+ /** @overload */
+ bool operator!=(const char *x) const;
+
+ /** Convert the string to the standard String represantation. */
+ String convertToString() const;
+
+ using BaseString<value_type>::insertString;
+ void insertString(const char *s, uint32 p); /*!< Insert string @p s into this string at position @p p. */
+ void insertString(const String &s, uint32 p); /*!< @overload */
+
+ /** Return a substring of this string */
+ DBCSString substr(size_t pos = 0, size_t len = npos) const;
+
+ /**@{
+ * Functions to replace some amount of chars with chars from some other string.
+ *
+ * @note The implementation follows that of the STL's std::string:
+ * http://www.cplusplus.com/reference/string/string/replace/
+ *
+ * @param pos Starting position for the replace in the original string.
+ * @param count Number of chars to replace from the original string.
+ * @param str Source of the new chars.
+ * @param posOri Same as pos
+ * @param countOri Same as count
+ * @param posDest Initial position to read str from.
+ * @param countDest Number of chars to read from str. npos by default.
+ */
+ // Replace 'count' bytes, starting from 'pos' with str.
+ void replace(uint32 pos, uint32 count, const DBCSString &str);
+ // Replace the characters in [begin, end) with str._str.
+ void replace(iterator begin, iterator end, const DBCSString &str);
+ // Replace _str[posOri, posOri + countOri) with
+ // str._str[posDest, posDest + countDest)
+ void replace(uint32 posOri, uint32 countOri, const DBCSString &str,
+ uint32 posDest, uint32 countDest);
+ // Replace _str[posOri, posOri + countOri) with
+ // str[posDest, posDest + countDest)
+ void replace(uint32 posOri, uint32 countOri, const uint16 *str,
+ uint32 posDest, uint32 countDest);
+ /**@}*/
+
+private:
+ void decodeDBCS(const char *str, uint32 len);
+
+ friend class String;
+};
+
+/** Concatenate strings @p x and @p y. */
+DBCSString operator+(const DBCSString &x, const DBCSString &y);
+
+/** Append the given @p y character to the given @p x string. */
+DBCSString operator+(const DBCSString &x, DBCSString::value_type y);
+
+/** @} */
+
+} // End of namespace Common
+
+#endif
diff --git a/common/module.mk b/common/module.mk
index 0f5f40f0b09..6cc1f16ade7 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
concatstream.o \
config-manager.o \
coroutines.o \
+ dbcs-str.o \
debug.o \
error.o \
events.o \
diff --git a/common/str-base.cpp b/common/str-base.cpp
index 1b8b36f7339..c38f33b5192 100644
--- a/common/str-base.cpp
+++ b/common/str-base.cpp
@@ -837,6 +837,7 @@ TEMPLATE uint BASESTRING::hash() const {
}
template class BaseString<char>;
+template class BaseString<uint16>;
template class BaseString<u32char_type_t>;
}
Commit: e2c1cae56a398507cce94059ad29658366c01ad6
https://github.com/scummvm/scummvm/commit/e2c1cae56a398507cce94059ad29658366c01ad6
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-05-10T13:18:54+02:00
Commit Message:
GRIM: Add detection entry for Chinese monkey4
Changed paths:
engines/grim/detection.cpp
diff --git a/engines/grim/detection.cpp b/engines/grim/detection.cpp
index e8296e4a4ce..2020e7cd958 100644
--- a/engines/grim/detection.cpp
+++ b/engines/grim/detection.cpp
@@ -419,6 +419,20 @@ static const GrimGameDescription gameDescriptions[] = {
},
GType_MONKEY4
},
+ {
+ // Escape from Monkey Island Chinese
+ {
+ "monkey4",
+ "",
+ AD_ENTRY2s("artAll.m4b", "61959da91d864bf5f4588daa4a5a3019", 18515664,
+ "Script.tab", "ee08a95b6820f7b876940f6cd41dbae7", 618346),
+ Common::ZH_TWN,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUI_OPTIONS_GRIME
+ },
+ GType_MONKEY4
+ },
{
// Escape from Monkey Island German
{
Commit: 7e0d5f1c6ff32dc1af6de53755a8b0b6393c0738
https://github.com/scummvm/scummvm/commit/7e0d5f1c6ff32dc1af6de53755a8b0b6393c0738
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-05-10T13:18:54+02:00
Commit Message:
GRIM: Support localize file in UTF-16LE
Changed paths:
engines/grim/grim.h
engines/grim/localize.cpp
diff --git a/engines/grim/grim.h b/engines/grim/grim.h
index c9f6f3fe9b8..c3c06fa2acc 100644
--- a/engines/grim/grim.h
+++ b/engines/grim/grim.h
@@ -288,6 +288,7 @@ protected:
public:
int _cursorX = 0;
int _cursorY = 0;
+ bool _isUtf8 = false;
};
extern GrimEngine *g_grim;
diff --git a/engines/grim/localize.cpp b/engines/grim/localize.cpp
index 5c3bf570e31..1eac0a1b751 100644
--- a/engines/grim/localize.cpp
+++ b/engines/grim/localize.cpp
@@ -102,6 +102,15 @@ Localizer::Localizer() {
case MKTAG('I', 'N', 'T', 'T'):
case MKTAG('6', '6', '6', 'I'):
break;
+ case 0xfffe4600: {
+ Common::String n = Common::U32String::decodeUTF16LE((const uint16 *) (data + 2), (filesize - 2) / 2).encode();
+ delete[] data;
+ data = new char[n.size() + 1];
+ memcpy(data, n.c_str(), n.size() + 1);
+ filesize = n.size();
+ g_grim->_isUtf8 = true;
+ break;
+ }
default:
error("Invalid magic reading %s: %08x (%s)", filename.c_str(), READ_BE_UINT32(data), tag2str(READ_BE_UINT32(data)));
}
Commit: bf4b5db9ed7483b33fedb0fa41113329e48acb22
https://github.com/scummvm/scummvm/commit/bf4b5db9ed7483b33fedb0fa41113329e48acb22
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-05-10T13:18:54+02:00
Commit Message:
GRIM: Prefer unpacked files over ones in archives
Changed paths:
engines/grim/resource.cpp
diff --git a/engines/grim/resource.cpp b/engines/grim/resource.cpp
index 2ebd8fda8cc..1920e3d80e8 100644
--- a/engines/grim/resource.cpp
+++ b/engines/grim/resource.cpp
@@ -197,7 +197,7 @@ ResourceLoader::ResourceLoader() {
error("%s", "Cannot find game data - check configuration file");
// Load labs
- int priority = files.size();
+ int priority = -1;
for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) {
Common::String filename = (*x)->getName();
filename.toLowercase();
Commit: 87a4fe7831f196f8e3bbfdef596c24ab0b409a91
https://github.com/scummvm/scummvm/commit/87a4fe7831f196f8e3bbfdef596c24ab0b409a91
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-05-10T13:18:54+02:00
Commit Message:
GRIM: Support DBCS and Unicode word-wrapping
Changed paths:
engines/grim/textobject.cpp
engines/grim/textobject.h
diff --git a/engines/grim/textobject.cpp b/engines/grim/textobject.cpp
index 99d03287410..ba6b087f7ce 100644
--- a/engines/grim/textobject.cpp
+++ b/engines/grim/textobject.cpp
@@ -21,6 +21,8 @@
#include "common/unicode-bidi.h"
+#include "common/dbcs-str.h"
+
#include "engines/grim/debug.h"
#include "engines/grim/grim.h"
#include "engines/grim/textobject.h"
@@ -161,9 +163,9 @@ void TextObject::destroy() {
}
}
-void TextObject::setupText() {
- Common::String msg = LuaBase::instance()->parseMsgText(_textID.c_str(), nullptr);
- Common::String message;
+template <typename S>
+void TextObject::setupTextReal(S msg, Common::String (*convert)(const S &s)) {
+ S message;
// remove spaces (NULL_TEXT) from the end of the string,
// while this helps make the string unique it screws up
@@ -209,7 +211,7 @@ void TextObject::setupText() {
}
// We break the message to lines not longer than maxWidth
- Common::String currLine;
+ S currLine;
_numberLines = 1;
int lineWidth = 0;
for (uint i = 0; i < msg.size(); i++) {
@@ -226,14 +228,16 @@ void TextObject::setupText() {
--i;
}
} else { // if it is a unique word
- int dashWidth = _font->getCharKernedWidth('-');
+ bool useDash = !(g_grim->getGameLanguage() == Common::Language::ZH_CHN || g_grim->getGameLanguage() == Common::Language::ZH_TWN);
+ int dashWidth = useDash ? _font->getCharKernedWidth('-') : 0;
while (lineWidth + dashWidth > maxWidth && currLine.size() > 1) {
lineWidth -= _font->getCharKernedWidth(currLine.lastChar());
message.deleteLastChar();
currLine.deleteLastChar();
--i;
}
- message += '-';
+ if (useDash)
+ message += '-';
}
message += '\n';
currLine.clear();
@@ -263,27 +267,54 @@ void TextObject::setupText() {
for (int j = 0; j < _numberLines; j++) {
int nextLinePos, cutLen;
- const char *breakPos = strchr(message.c_str(), '\n');
- if (breakPos) {
+ const typename S::value_type *breakPos = message.c_str();
+ while (*breakPos && *breakPos != '\n')
+ breakPos++;
+ if (*breakPos == '\n') {
nextLinePos = breakPos - message.c_str();
cutLen = nextLinePos + 1;
} else {
nextLinePos = message.size();
cutLen = nextLinePos;
}
- Common::String currentLine(message.c_str(), message.c_str() + nextLinePos);
+ S currentLine(message.c_str(), message.c_str() + nextLinePos);
+ Common::String currentLineConvert = convert(currentLine);
// Reverse the line for the Hebrew translation
if (g_grim->getGameLanguage() == Common::HE_ISR)
- currentLine = Common::convertBiDiString(currentLine, Common::kWindows1255);
+ currentLineConvert = Common::convertBiDiString(currentLineConvert, Common::kWindows1255);
- _lines[j] = currentLine;
- int width = _font->getKernedStringLength(currentLine);
+ _lines[j] = currentLineConvert;
+ int width = _font->getKernedStringLength(currentLineConvert);
if (width > _maxLineWidth)
_maxLineWidth = width;
for (int count = 0; count < cutLen; count++)
message.deleteChar(0);
}
+}
+
+static Common::String sConvert(const Common::String &s) {
+ return s;
+}
+
+static Common::String usConvert(const Common::U32String &us) {
+ return us.encode(Common::CodePage::kUtf8);
+}
+
+static Common::String dbcsConvert(const Common::DBCSString &ds) {
+ return ds.convertToString();
+}
+
+void TextObject::setupText() {
+ Common::String msg = LuaBase::instance()->parseMsgText(_textID.c_str(), nullptr);
+
+ if (g_grim->_isUtf8)
+ setupTextReal<Common::U32String>(msg.decode(Common::CodePage::kUtf8), usConvert);
+ else if (g_grim->getGameLanguage() == Common::Language::ZH_CHN || g_grim->getGameLanguage() == Common::Language::ZH_TWN)
+ setupTextReal<Common::DBCSString>(Common::DBCSString(msg), dbcsConvert);
+ else
+ setupTextReal<Common::String>(msg, sConvert);
+
_elapsedTime = 0;
}
diff --git a/engines/grim/textobject.h b/engines/grim/textobject.h
index 3c0adac5c93..ce37cc91054 100644
--- a/engines/grim/textobject.h
+++ b/engines/grim/textobject.h
@@ -147,6 +147,10 @@ protected:
bool _created;
int _stackLevel;
+
+private:
+ template <typename S>
+ void setupTextReal(S msg, Common::String (*convert)(const S &s));
};
} // end of namespace Grim
Commit: 385d6e51156aeb7645c6b32dfefe2084db849383
https://github.com/scummvm/scummvm/commit/385d6e51156aeb7645c6b32dfefe2084db849383
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-05-10T13:18:54+02:00
Commit Message:
GRIM: Mark ZH_TWN as requiring font rendering
Changed paths:
engines/grim/grim.cpp
diff --git a/engines/grim/grim.cpp b/engines/grim/grim.cpp
index 9267f2962e9..a87f3d1ae7e 100644
--- a/engines/grim/grim.cpp
+++ b/engines/grim/grim.cpp
@@ -282,7 +282,8 @@ GfxBase *GrimEngine::createRenderer(int screenW, int screenH) {
}
// Not supported yet.
- if (getLanguage() == Common::Language::ZH_CHN)
+ if (getLanguage() == Common::Language::ZH_CHN || getLanguage() == Common::Language::ZH_TWN
+ || getGameLanguage() == Common::Language::ZH_CHN || getGameLanguage() == Common::Language::ZH_TWN)
availableRendererTypes &= ~Graphics::kRendererTypeOpenGLShaders;
Graphics::RendererType matchingRendererType = Graphics::Renderer::getBestMatchingType(desiredRendererType, availableRendererTypes);
Commit: 98c337f1dadf00dbc6f80c8e3f4a4d556951ae2b
https://github.com/scummvm/scummvm/commit/98c337f1dadf00dbc6f80c8e3f4a4d556951ae2b
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-05-10T13:18:54+02:00
Commit Message:
GRIM: Support override font
In Chinese Monkey4 we need to use chinese font instead of normal font.
Changed paths:
engines/grim/grim.h
engines/grim/resource.cpp
diff --git a/engines/grim/grim.h b/engines/grim/grim.h
index c3c06fa2acc..701f1657f1c 100644
--- a/engines/grim/grim.h
+++ b/engines/grim/grim.h
@@ -289,6 +289,7 @@ public:
int _cursorX = 0;
int _cursorY = 0;
bool _isUtf8 = false;
+ Font *_overrideFont = nullptr;
};
extern GrimEngine *g_grim;
diff --git a/engines/grim/resource.cpp b/engines/grim/resource.cpp
index 1920e3d80e8..2300cc63adf 100644
--- a/engines/grim/resource.cpp
+++ b/engines/grim/resource.cpp
@@ -368,6 +368,9 @@ Costume *ResourceLoader::loadCostume(const Common::String &filename, Actor *owne
Font *ResourceLoader::loadFont(const Common::String &filename) {
Common::SeekableReadStream *stream;
+ if (g_grim->_overrideFont)
+ return g_grim->_overrideFont;
+
if (g_grim->getGameType() == GType_GRIM && g_grim->isRemastered()) {
Common::String name = "FontsHD/" + filename + ".txt";
stream = openNewStreamFile(name, true);
Commit: c93486dfe2d60ed726f0d900ce566190f61a5a5d
https://github.com/scummvm/scummvm/commit/c93486dfe2d60ed726f0d900ce566190f61a5a5d
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-05-10T13:18:54+02:00
Commit Message:
GRIM: Support Chinese TGA font
Changed paths:
engines/grim/font.cpp
engines/grim/font.h
diff --git a/engines/grim/font.cpp b/engines/grim/font.cpp
index 58733c680c5..e7e0802c28e 100644
--- a/engines/grim/font.cpp
+++ b/engines/grim/font.cpp
@@ -25,6 +25,8 @@
#include "graphics/font.h"
#include "graphics/surface.h"
+#include "image/tga.h"
+
#include "engines/grim/debug.h"
#include "engines/grim/grim.h"
#include "engines/grim/savegame.h"
@@ -85,14 +87,14 @@ Font *Font::getFirstFont() {
}
bool BitmapFont::is8Bit() const {
- return !_isDBCS;
+ return !_isDBCS && !_isUnicode;
}
BitmapFont::BitmapFont() :
_userData(nullptr),
_fontData(nullptr), _charHeaders(nullptr),
_numChars(0), _dataSize(0), _kernedHeight(0), _baseOffsetY(0),
- _firstChar(0), _lastChar(0) {
+ _firstChar(0), _lastChar(0), _isUnicode(false), _isDBCS(false) {
}
BitmapFont::~BitmapFont() {
@@ -164,7 +166,7 @@ void BitmapFont::load(const Common::String &filename, Common::SeekableReadStream
_charHeaders[i].startingLine = data->readSByte();
data->seek(1, SEEK_CUR);
// Character bitmap size
- _charHeaders[i].bitmapWidth = data->readUint32LE();
+ _charHeaders[i].bitmapPitch = _charHeaders[i].bitmapWidth = data->readUint32LE();
_charHeaders[i].bitmapHeight = data->readUint32LE();
}
// Read font data
@@ -175,7 +177,57 @@ void BitmapFont::load(const Common::String &filename, Common::SeekableReadStream
g_driver->createFont(this);
}
-uint16 BitmapFont::getCharIndex(uint16 c) const {
+void BitmapFont::loadTGA(const Common::String &filename, Common::SeekableReadStream *index, Common::SeekableReadStream *image) {
+ Image::TGADecoder dec;
+ bool success = dec.loadStream(*image);
+
+ if (!success)
+ return;
+
+ const Graphics::Surface *surf = dec.getSurface();
+
+ const int MAX_16BIT_CHARACTER = 0xffff;
+ const int INDEX_ENTRY_SIZE = 10;
+
+ _filename = filename;
+ _numChars = index->size() / INDEX_ENTRY_SIZE;
+ _dataSize = surf->w * surf->h;
+ _kernedHeight = 16;
+ _baseOffsetY = 0;
+ _firstChar = 0;
+ _lastChar = MAX_16BIT_CHARACTER;
+
+ _isDBCS = false;
+ _isUnicode = true;
+
+ // Read character headers
+ _charHeaders = new CharHeader[_numChars];
+
+ _fwdCharIndex.resize(MAX_16BIT_CHARACTER + 1, -1);
+ for (uint i = 0; i < _numChars; ++i) {
+ uint16 point = index->readUint16LE();
+ uint32 x = index->readUint32LE();
+ uint32 y = index->readUint32LE();
+ _fwdCharIndex[point] = i;
+ _charHeaders[i].offset = x + y * surf->w;
+ _charHeaders[i].kernedWidth = 16;
+ _charHeaders[i].startingCol = 0;
+ _charHeaders[i].startingLine = 0;
+ _charHeaders[i].bitmapWidth = 16;
+ _charHeaders[i].bitmapHeight = 16;
+ _charHeaders[i].bitmapPitch = surf->w;
+ }
+ // Read font data
+ _fontData = new byte[_dataSize];
+
+ for (int y = 0; y < surf->h; y++)
+ for (int x = 0; x < surf->w; x++)
+ _fontData[y * surf->w + x] = surf->getPixel(x, y) ? 0 : 0xff;
+
+ g_driver->createFont(this);
+}
+
+uint16 BitmapFont::getCharIndex(uint32 c) const {
int res = c < _fwdCharIndex.size() ? _fwdCharIndex[c] : -1;
if (res >= 0)
return res;
@@ -186,25 +238,70 @@ uint16 BitmapFont::getCharIndex(uint16 c) const {
return 0;
}
+uint32 BitmapFont::getNextChar(const Common::String &text, uint32 &i) const {
+ if (_isUnicode) {
+ uint32 chr = 0;
+ uint num = 1;
+
+ if ((text[i] & 0xF8) == 0xF0) {
+ num = 4;
+ } else if ((text[i] & 0xF0) == 0xE0) {
+ num = 3;
+ } else if ((text[i] & 0xE0) == 0xC0) {
+ num = 2;
+ }
+
+ if (text.size() - i < num) {
+ i = text.size();
+ return '?';
+ }
+
+ switch (num) {
+ case 4:
+ chr |= (text[i++] & 0x07) << 18;
+ chr |= (text[i++] & 0x3F) << 12;
+ chr |= (text[i++] & 0x3F) << 6;
+ chr |= (text[i++] & 0x3F);
+ break;
+
+ case 3:
+ chr |= (text[i++] & 0x0F) << 12;
+ chr |= (text[i++] & 0x3F) << 6;
+ chr |= (text[i++] & 0x3F);
+ break;
+
+ case 2:
+ chr |= (text[i++] & 0x1F) << 6;
+ chr |= (text[i++] & 0x3F);
+ break;
+
+ default:
+ chr = (text[i++] & 0x7F);
+ break;
+ }
+
+ return chr;
+ }
+ uint16 ch = uint8(text[i]);
+ if (_isDBCS && i + 1 < text.size() && (ch & 0x80)) {
+ ch = (ch << 8) | (text[++i] & 0xff);
+ }
+ i++;
+ return ch;
+}
+
int BitmapFont::getKernedStringLength(const Common::String &text) const {
int result = 0;
- for (uint32 i = 0; i < text.size(); ++i) {
- uint16 ch = uint8(text[i]);
- if (_isDBCS && i + 1 < text.size() && (ch & 0x80)) {
- ch = (ch << 8) | (text[++i] & 0xff);
- }
- result += getCharKernedWidth(ch);
+ for (uint32 i = 0; i < text.size(); ) {
+ result += getCharKernedWidth(getNextChar(text, i));
}
return result;
}
int BitmapFont::getBitmapStringLength(const Common::String &text) const {
int result = 0;
- for (uint32 i = 0; i < text.size(); ++i) {
- uint16 ch = uint8(text[i]);
- if (_isDBCS && i + 1 < text.size() && (ch & 0x80)) {
- ch = (ch << 8) | (text[++i] & 0xff);
- }
+ for (uint32 i = 0; i < text.size(); ) {
+ uint32 ch = getNextChar(text, i);
result += getCharKernedWidth(ch) + getCharStartingCol(ch);
}
return result;
@@ -212,11 +309,8 @@ int BitmapFont::getBitmapStringLength(const Common::String &text) const {
int BitmapFont::getStringHeight(const Common::String &text) const {
int result = 0;
- for (uint32 i = 0; i < text.size(); ++i) {
- uint16 ch = uint8(text[i]);
- if (_isDBCS && i + 1 < text.size() && (ch & 0x80)) {
- ch = (ch << 8) | (text[++i] & 0xff);
- }
+ for (uint32 i = 0; i < text.size(); ) {
+ uint32 ch = getNextChar(text, i);
int verticalOffset = getCharStartingLine(ch) + getBaseOffsetY();
int charHeight = verticalOffset + getCharBitmapHeight(ch);
@@ -274,12 +368,10 @@ void BitmapFont::render(Graphics::Surface &buf, const Common::String ¤tLin
buf.create(width, height, pixelFormat);
buf.fillRect(Common::Rect(0, 0, width, height), colorKey);
- for (unsigned int d = 0; d < currentLine.size(); d++) {
- uint16 ch = uint8(currentLine[d]);
- if (_isDBCS && (ch & 0x80) && d + 1 < currentLine.size()) {
- ch = (ch << 8) | (currentLine[++d] & 0xff);
- }
+ for (uint32 d = 0; d < currentLine.size(); ) {
+ uint32 ch = getNextChar(currentLine, d);
int32 charBitmapWidth = getCharBitmapWidth(ch);
+ int32 charBitmapPitch = getCharBitmapPitch(ch);
int32 charBitmapHeight = getCharBitmapHeight(ch);
int8 fontRow = getCharStartingLine(ch) + getBaseOffsetY();
int8 fontCol = getCharStartingCol(ch);
@@ -287,7 +379,7 @@ void BitmapFont::render(Graphics::Surface &buf, const Common::String ¤tLin
for (int line = 0; line < charBitmapHeight; line++) {
int lineOffset = (fontRow + line);
int columnOffset = startColumn + fontCol;
- int fontOffset = (charBitmapWidth * line);
+ int fontOffset = (charBitmapPitch * line);
for (int bitmapCol = 0; bitmapCol < charBitmapWidth; bitmapCol++, columnOffset++, fontOffset++) {
byte pixel = getCharData(ch)[fontOffset];
if (pixel == 0x80) {
diff --git a/engines/grim/font.h b/engines/grim/font.h
index f8b9cde5eb4..76c0027ba98 100644
--- a/engines/grim/font.h
+++ b/engines/grim/font.h
@@ -44,7 +44,7 @@ public:
virtual int getKernedStringLength(const Common::String &text) const = 0;
virtual int32 getBaseOffsetY() const = 0;
virtual void render(Graphics::Surface &buf, const Common::String ¤tLine, const Graphics::PixelFormat &pixelFormat, uint32 blackColor, uint32 color, uint32 colorKey) const = 0;
- virtual int32 getCharKernedWidth(uint16 c) const = 0;
+ virtual int32 getCharKernedWidth(uint32 c) const = 0;
virtual int getPoolId() const = 0;
virtual int32 getPoolTag() const = 0;
virtual bool is8Bit() const = 0;
@@ -69,20 +69,21 @@ public:
int32 getPoolTag() const override { return getStaticTag(); }
void load(const Common::String &filename, Common::SeekableReadStream *data);
-
+ void loadTGA(const Common::String &filename, Common::SeekableReadStream *index, Common::SeekableReadStream *image);
const Common::String &getFilename() const { return _filename; }
int32 getKernedHeight() const override { return _kernedHeight; }
int32 getFontWidth() const override { return getCharKernedWidth('w'); }
int32 getBaseOffsetY() const override { return _baseOffsetY; }
void render(Graphics::Surface &buf, const Common::String ¤tLine, const Graphics::PixelFormat &pixelFormat, uint32 blackColor, uint32 color, uint32 colorKey) const override;
- int32 getCharBitmapWidth(uint16 c) const { return _charHeaders[getCharIndex(c)].bitmapWidth; }
- int32 getCharBitmapHeight(uint16 c) const { return _charHeaders[getCharIndex(c)].bitmapHeight; }
- int32 getCharKernedWidth(uint16 c) const override { return _charHeaders[getCharIndex(c)].kernedWidth; }
- int32 getCharStartingCol(uint16 c) const { return _charHeaders[getCharIndex(c)].startingCol; }
- int32 getCharStartingLine(uint16 c) const { return _charHeaders[getCharIndex(c)].startingLine; }
- int32 getCharOffset(uint16 c) const { return _charHeaders[getCharIndex(c)].offset; }
- const byte *getCharData(uint16 c) const { return _fontData + (_charHeaders[getCharIndex(c)].offset); }
+ int32 getCharBitmapWidth(uint32 c) const { return _charHeaders[getCharIndex(c)].bitmapWidth; }
+ int32 getCharBitmapPitch(uint32 c) const { return _charHeaders[getCharIndex(c)].bitmapPitch; }
+ int32 getCharBitmapHeight(uint32 c) const { return _charHeaders[getCharIndex(c)].bitmapHeight; }
+ int32 getCharKernedWidth(uint32 c) const override { return _charHeaders[getCharIndex(c)].kernedWidth; }
+ int32 getCharStartingCol(uint32 c) const { return _charHeaders[getCharIndex(c)].startingCol; }
+ int32 getCharStartingLine(uint32 c) const { return _charHeaders[getCharIndex(c)].startingLine; }
+ int32 getCharOffset(uint32 c) const { return _charHeaders[getCharIndex(c)].offset; }
+ const byte *getCharData(uint32 c) const { return _fontData + (_charHeaders[getCharIndex(c)].offset); }
const byte *getFontData() const { return _fontData; }
uint32 getDataSize() const { return _dataSize; }
@@ -100,14 +101,15 @@ public:
static const uint8 emerFont[][13];
private:
-
- uint16 getCharIndex(uint16 c) const;
+ uint32 getNextChar(const Common::String &text, uint32 &i) const;
+ uint16 getCharIndex(uint32 c) const;
struct CharHeader {
int32 offset;
int8 kernedWidth;
- int8 startingCol;
- int8 startingLine;
+ int32 startingCol;
+ int32 startingLine;
int32 bitmapWidth;
+ int32 bitmapPitch;
int32 bitmapHeight;
};
@@ -119,7 +121,7 @@ private:
CharHeader *_charHeaders;
byte *_fontData;
void *_userData;
- bool _isDBCS;
+ bool _isDBCS, _isUnicode;
};
class FontTTF : public Font, public PoolObject<FontTTF> {
@@ -132,7 +134,7 @@ public:
int32 getKernedHeight() const override { return _font->getFontHeight(); }
int32 getBaseOffsetY() const override { return 0; }
- int32 getCharKernedWidth(uint16 c) const override { return _font->getCharWidth(c); }
+ int32 getCharKernedWidth(uint32 c) const override { return _font->getCharWidth(c); }
int32 getFontWidth() const override { return getCharKernedWidth('w'); }
int getKernedStringLength(const Common::String &text) const override { return _font->getStringWidth(text); }
Commit: cb3ee1411affe1fd852a66230dc3010df1e23966
https://github.com/scummvm/scummvm/commit/cb3ee1411affe1fd852a66230dc3010df1e23966
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-05-10T13:18:54+02:00
Commit Message:
GRIM: Use TGA font for Chinese monkey4
Changed paths:
engines/grim/grim.cpp
diff --git a/engines/grim/grim.cpp b/engines/grim/grim.cpp
index a87f3d1ae7e..420f5e612ff 100644
--- a/engines/grim/grim.cpp
+++ b/engines/grim/grim.cpp
@@ -396,6 +396,15 @@ Common::Error GrimEngine::run() {
g_driver = createRenderer(640, 480);
}
+ if (getGameType() == GType_MONKEY4 && getGameLanguage() == Common::Language::ZH_TWN) {
+ Common::File img, imgmap;
+ if (img.open("font.tga") && imgmap.open("map.bin")) {
+ BitmapFont *f = new BitmapFont();
+ f->loadTGA("font.tga", &imgmap, &img);
+ _overrideFont = f;
+ }
+ }
+
if (getGameType() == GType_MONKEY4 && SearchMan.hasFile("AMWI.m4b")) {
// Play EMI Mac Aspyr logo
playAspyrLogo();
More information about the Scummvm-git-logs
mailing list