[Scummvm-git-logs] scummvm master -> 1f0d0fdb1eff31108c7e7c61459185ee3e10d1bf

athrxx noreply at scummvm.org
Sat Aug 12 13:24:05 UTC 2023


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
96d9a32876 KYRA: (EOB II/ZH) - fix voc file warning
1f0d0fdb1e KYRA: (EOB II/ZH) - some party generator improvements and fixes


Commit: 96d9a3287697a9333c4efc89b6dc1e3eb6d0d405
    https://github.com/scummvm/scummvm/commit/96d9a3287697a9333c4efc89b6dc1e3eb6d0d405
Author: athrxx (athrxx at scummvm.org)
Date: 2023-08-12T15:19:13+02:00

Commit Message:
KYRA: (EOB II/ZH) - fix voc file warning

Changed paths:
    engines/kyra/sequence/sequences_darkmoon.cpp


diff --git a/engines/kyra/sequence/sequences_darkmoon.cpp b/engines/kyra/sequence/sequences_darkmoon.cpp
index 7bc7af3324a..f904372784d 100644
--- a/engines/kyra/sequence/sequences_darkmoon.cpp
+++ b/engines/kyra/sequence/sequences_darkmoon.cpp
@@ -1500,7 +1500,9 @@ void DarkmoonSequenceHelper::printText(int index, int color) {
 	Common::String str = _config->strings[index];
 
 	if (_config->voicePattern) {
-		_vm->_sound->voicePlay(Common::String::format(_config->voicePattern, index + 1).c_str(), &_vm->_speechHandle);
+		Common::String file(Common::String::format(_config->voicePattern, index + 1));
+		if (_vm->_sound->isVoicePresent(file.c_str()))
+			_vm->_sound->voicePlay(file.c_str(), &_vm->_speechHandle);
 	}
 
 	const ScreenDim *dm = _screen->_curDim;


Commit: 1f0d0fdb1eff31108c7e7c61459185ee3e10d1bf
    https://github.com/scummvm/scummvm/commit/1f0d0fdb1eff31108c7e7c61459185ee3e10d1bf
Author: athrxx (athrxx at scummvm.org)
Date: 2023-08-12T15:20:47+02:00

Commit Message:
KYRA: (EOB II/ZH) - some party generator improvements and fixes

Changed paths:
    devtools/create_kyradat/resources/eob2_dos_chinese.h
    dists/engine-data/kyra.dat
    engines/kyra/engine/chargen.cpp
    engines/kyra/graphics/screen.cpp
    engines/kyra/graphics/screen.h
    engines/kyra/graphics/screen_eob.cpp
    engines/kyra/graphics/screen_eob.h
    engines/kyra/gui/gui_eob.cpp
    engines/kyra/gui/gui_eob.h


diff --git a/devtools/create_kyradat/resources/eob2_dos_chinese.h b/devtools/create_kyradat/resources/eob2_dos_chinese.h
index ab9838f72f7..c2e6274a8fa 100644
--- a/devtools/create_kyradat/resources/eob2_dos_chinese.h
+++ b/devtools/create_kyradat/resources/eob2_dos_chinese.h
@@ -1,5 +1,5 @@
 static const char *const kEoB2ChargenStrings1DOSChinese[9] = {
-	"\xaa\xba\xab\x5f\xc0\x49\xb6\xa4\xa5\xee\xa4\x77\xab\xd8\xa5\xdf\xa7\xb9\xb2\xa6\x2c\xbd\xd0\xb1\x4e\xab\xfc\xbc\xd0\xb2\xbe\xa8\xec\x5b\x50\x4c\x41\x59\x5d\xab\xf6\xa4\x55\xa5\xaa\xc1\xe4\x2c\xa9\xce\xab\xf6\x5b\x50\x5d\xc1\xe4\x2c\xb6\x7d\xa9\x6c\xb1\x7a\xaa\xba\xab\x5f\xc0\x49\xae\xc8\xb5\x7b", /* "的冒險隊伍已建立完畢,請將指標移到[PLAY]按下左鍵,或按[P]鍵,開始您的冒險旅程"; */
+	"\xb1""z""\xaa\xba\xab""_""\xc0""I""\xb6\xa4\xa5\xee\xa4""w""\xab\xd8\xa5\xdf\xa7\xb9\xb2\xa6"",""\xbd\xd0\xb1""N""\xab\xfc\xbc\xd0\xb2\xbe\xa8\xec""[PLAY]""\xab\xf6\xa4""U""\xa5\xaa\xc1\xe4"",""\xa9\xce\xab\xf6""[P]""\xc1\xe4"",""\xb6""}""\xa9""l""\xb1""z""\xaa\xba\xab""_""\xc0""I""\xae\xc8\xb5""{", /* "您的冒險隊伍已建立完畢,請將指標移到[PLAY]按下左鍵,或按[P]鍵,開始您的冒險旅程"; */
 	"          ",
 	"\xa8\xbe\x3a\r\xa9\x52\x3a\r\xaf\xc5\x3a", /* "防:\r命:\r級:"; */
 	"%s\r%d\r%d\r%d\r%d\r%d",
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 8eb17844670..7f6afea95fb 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/engine/chargen.cpp b/engines/kyra/engine/chargen.cpp
index 7698fd7bb48..6cee167f6e9 100644
--- a/engines/kyra/engine/chargen.cpp
+++ b/engines/kyra/engine/chargen.cpp
@@ -77,6 +77,7 @@ private:
 
 	uint8 **_chargenMagicShapes;
 	uint8 *_chargenButtonLabels[17];
+	uint8 *_nameLabelsZH[4];
 	int _activeBox;
 	int _magicShapesBox;
 	int _updateBoxShapesIndex;
@@ -115,6 +116,15 @@ private:
 	static const CreatePartyModButton _chargenModButtons[];
 	static const EoBRect8 _chargenButtonBodyCoords[];
 	static const uint8 _chargenSegaButtonCoords[60];
+
+	struct ButtonExtraDataChinese {
+		const char *string;
+		int mapping;
+		int type;
+	};
+
+	static const ButtonExtraDataChinese _chineseButtonExtraData[17];
+
 	static const int16 _chargenBoxX[];
 	static const int16 _chargenBoxY[];
 	static const int16 _chargenNameFieldX[];
@@ -125,9 +135,6 @@ private:
 
 	static const int16 _raceModifiers[];
 
-	static const char *_chineseStrings[17];
-	static const int _chineseButtonMapping[17];
-
 	EoBCharacter *_characters;
 	const uint8 **_faceShapes;
 
@@ -156,7 +163,8 @@ CharacterGenerator::CharacterGenerator(EoBCoreEngine *vm, Screen_EoB *screen) :
 	memset(_chargenMinStats, 0, sizeof(_chargenMinStats));
 	memset(_chargenMaxStats, 0, sizeof(_chargenMaxStats));
 	memset(_chargenButtonLabels, 0, sizeof(_chargenButtonLabels));
-
+	memset(_nameLabelsZH, 0, sizeof(_nameLabelsZH));
+	
 	int temp;
 	_chargenStrings1 = _vm->staticres()->loadStrings(kEoBBaseChargenStrings1, temp);
 	_chargenStrings2 = _vm->staticres()->loadStrings(kEoBBaseChargenStrings2, temp);
@@ -204,6 +212,9 @@ CharacterGenerator::~CharacterGenerator() {
 	for (int i = 0; i < 17; i++)
 		delete[] _chargenButtonLabels[i];
 
+	for (int i = 0; i < 4; i++)
+		delete[] _nameLabelsZH[i];
+
 	delete[] _chargenButtonDefs;
 	delete[] _wndBackgrnd;
 	_vm->_wndBackgrnd = 0;
@@ -348,6 +359,17 @@ void CharacterGenerator::init(bool defaultParty) {
 	_screen->convertToHiColor(2);
 	_screen->shadeRect(142, 63, 306, 193, 4);
 	_screen->copyRegion(144, 64, 0, 0, 180, 128, 0, 2, Screen::CR_NO_P_CHECK);
+
+	if (_vm->_flags.lang == Common::ZH_TWN) {
+		for (int i = 0; i < 4; ++i) {
+			_vm->gui_drawHorizontalBarGraph(_chargenNameFieldX[i], _chargenNameFieldY[i] - 5, 60, 15, 2, 1, _vm->guiSettings()->colors.fill, _vm->guiSettings()->colors.guiColorDarkBlue);
+			// We backup a slightly larger rect so that we can restore the complete background even from the
+			// font shadow overdrawing. The original doesn't care about that, the overdrawing artifacts (which
+			// happen for e. g. characters like 'g' or ',') will just remain visible on screen).
+			_nameLabelsZH[i] = _screen->encodeShape(_chargenNameFieldX[i] >> 3, _chargenNameFieldY[i] - 5, 8, 17);
+		}
+	}
+
 	_screen->updateScreen();
 }
 
@@ -487,9 +509,28 @@ void CharacterGenerator::initButton(int index, const EoBChargenButtonDef *e) {
 void CharacterGenerator::checkForCompleteParty() {
 	_screen->copyRegion(0, 0, 160, 0, 160, 128, 2, 2, Screen::CR_NO_P_CHECK);
 	int cp = _screen->setCurPage(2);
-	int x = (_vm->gameFlags().platform == Common::kPlatformFMTowns) ? 184 : 168;
-	int y1 = (_vm->game() == GI_EOB2 && _vm->gameFlags().platform == Common::kPlatformPC98) ? 40 : 16;
-	int y2 = (_vm->game() == GI_EOB2 && _vm->gameFlags().platform == Common::kPlatformPC98) ? 56 : 61;
+	int x1 = 168;
+	int x2 = 304;
+	int y1 = 16;
+	int y2 = 61;
+	int h2 = 40;
+	int shadowColor2 = _vm->guiSettings()->colors.guiColorBlack;
+
+	if (_vm->game() == GI_EOB2) {
+		if (_vm->gameFlags().lang == Common::Language::ZH_TWN) {
+			x2 = 298;
+			y2 = 46;
+			h2 = 80;
+			shadowColor2 = _vm->guiSettings()->colors.guiColorDarkBlue;
+		} else if (_vm->gameFlags().platform == Common::kPlatformFMTowns) {
+			x1 = 184;
+		} else if (_vm->gameFlags().platform == Common::kPlatformPC98) {
+			x1 = 184;
+			y1 = 20;
+			y2 = 44;
+		}
+	}
+
 	int cs = 0;
 
 	if (_vm->gameFlags().platform == Common::kPlatformSegaCD) {
@@ -498,7 +539,7 @@ void CharacterGenerator::checkForCompleteParty() {
 		cs = _screen->setFontStyles(_screen->_currentFont, _vm->gameFlags().lang == Common::JA_JPN ? Font::kStyleNone : Font::kStyleFullWidth);
 		_vm->_txt->printShadedText(_chargenStrings1[8], 0, 0, -1, 0x99);
 	} else {
-		_screen->printShadedText(_chargenStrings1[8], x, y1, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(_chargenStrings1[8], x1, y1, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
 		_screen->copyRegion(160, 0, 144, 64, 160, 128, 2, 0, Screen::CR_NO_P_CHECK);
 	}
 	_screen->setCurPage(cp);
@@ -514,9 +555,11 @@ void CharacterGenerator::checkForCompleteParty() {
 			_vm->_txt->printShadedText(_chargenStrings1[0], 0, 60, -1, 0x99);
 		} else {
 			_screen->setCurPage(2);
-			_screen->printShadedText(_chargenStrings1[0], x, y2, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+			_screen->setTextMarginRight(x2);
+			_screen->printShadedText(_chargenStrings1[0], x1, y2, _vm->guiSettings()->colors.guiColorWhite, 0, shadowColor2);
 			_screen->setCurPage(0);
-			_screen->copyRegion(168, 61, 152, 125, 136, 40, 2, 0, Screen::CR_NO_P_CHECK);
+			_screen->setTextMarginRight(Screen::SCREEN_W);
+			_screen->copyRegion(168, y2, 152, y2 + 64, 152, h2, 2, 0, Screen::CR_NO_P_CHECK);
 		}
 		drawButton(15, 0);
 	} else {
@@ -556,8 +599,8 @@ void CharacterGenerator::drawButton(int index, int buttonState) {
 		return;
 	}
 
-	if (_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::Language::ZH_TWN && _chineseStrings[index]) {
-		int mappedIdx = _chineseButtonMapping[index];
+	if (_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::Language::ZH_TWN && _chineseButtonExtraData[index].type != -1) {
+		int mappedIdx = _chineseButtonExtraData[index].mapping;
 		int destX = _chargenButtonDefs[mappedIdx].x;
 		int destY = _chargenButtonDefs[mappedIdx].y;
 		int w = _chargenButtonDefs[mappedIdx].w;
@@ -565,16 +608,23 @@ void CharacterGenerator::drawButton(int index, int buttonState) {
 
 		int x2 = destX;
 		int y2 = destY;
+		int page = _screen->setCurPage(0);
+		uint8 labelTextColor = buttonState ? _vm->guiSettings()->colors.guiColorLightRed : _vm->guiSettings()->colors.guiColorWhite;
 
-		int page = _screen->_curPage;
+		if (_chineseButtonExtraData[index].type == 0) {
+			_vm->gui_drawBox(x2, y2, w, h, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, -1);
+			_vm->gui_drawBox(x2 + 1, y2 + 1, w - 2, h - 2, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, _vm->guiSettings()->colors.fill);
+		} else {
+			// This is quite a terrible abuse of the bar graph function, but we do it just like the original...
+			_vm->gui_drawHorizontalBarGraph(x2 + 1, y2 + 1, w - 3, h, 2, 1, _vm->guiSettings()->colors.fill, _vm->guiSettings()->colors.guiColorDarkBlue);
+			uint8 col1 = buttonState ? _vm->guiSettings()->colors.fill : _vm->guiSettings()->colors.frame1;
+			uint8 col2 = buttonState ? _vm->guiSettings()->colors.fill : _vm->guiSettings()->colors.frame2;
+			_vm->gui_drawBox(x2 + 2, y2 + 2, w, h, col1, col2, -1);
+			_vm->gui_drawBox(x2 + 3, y2 + 3, w - 2, h - 2, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, _vm->guiSettings()->colors.fill);
+			labelTextColor = buttonState ? _vm->guiSettings()->colors.guiColorWhite : _vm->guiSettings()->colors.guiColorYellow;
+		}
 
-		_screen->_curPage = 0;
-		_screen->set16bitShadingLevel(4);
-		_vm->gui_drawBox(x2, y2, w, h, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, -1);
-		_vm->gui_drawBox(x2 + 1, y2 + 1, w - 2, h - 2, _vm->guiSettings()->colors.frame1, _vm->guiSettings()->colors.frame2, _vm->guiSettings()->colors.fill);
-		_screen->set16bitShadingLevel(0);
-		_screen->printShadedText(_chineseStrings[index], x2 + 2, y2 + 2, buttonState ? _vm->guiSettings()->colors.guiColorLightRed : _vm->guiSettings()->colors.guiColorWhite,
-					 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(_chineseButtonExtraData[index].string, x2 + 2, y2 + 2, labelTextColor, 0, _vm->guiSettings()->colors.guiColorBlack);
 		_screen->_curPage = page;
 		_screen->updateScreen();
 		return;
@@ -713,14 +763,13 @@ void CharacterGenerator::createPartyMember() {
 				if (!_vm->shouldQuit())
 					_vm->_gui->getTextInput(_characters[_activeBox].name, (_chargenBoxX[_activeBox] >> 3) - 1, _chargenBoxY[_activeBox] + 41, 7, 0xFF, 0x00, 0xFF);
 			} else {
-				if (_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::Language::ZH_TWN)
-					_screen->copyRegion(5, 33, 149, 97, 64, 21, 2, 0, Screen::CR_NO_P_CHECK);
-				_screen->printShadedText(_chargenStrings2[11], 149, 100, _vm->guiSettings()->colors.guiColorLightBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
 				if (!_vm->shouldQuit()) {
 					if (_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::Language::ZH_TWN) {
-						_vm->_gui->getTextInput(_characters[_activeBox].name, 28, 100, 8,
+						_screen->printShadedText(_chargenStrings2[11], 149, 66, _vm->guiSettings()->colors.guiColorLightBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
+						_vm->_gui->getTextInput(_characters[_activeBox].name, 19, 81, 8,
 									_vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorDarkRed);
 					} else {
+						_screen->printShadedText(_chargenStrings2[11], 149, 100, _vm->guiSettings()->colors.guiColorLightBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
 						Screen::FontId of = _screen->setFont(_vm->_invFont3);
 						_vm->_gui->getTextInput(_characters[_activeBox].name, 24, 100, 10,
 									_vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorDarkRed);
@@ -783,10 +832,10 @@ int CharacterGenerator::classMenu(int raceSex) {
 		_vm->_txt->printShadedText(_chargenStrings2[9], 0, 0, -1, 0x99);
 	} else if (_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::Language::ZH_TWN) {
 		_screen->printShadedText(_chargenStrings2[9], 145, 65,
-					 _vm->guiSettings()->colors.guiColorLightBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
+			_vm->guiSettings()->colors.guiColorLightBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
 	} else {
 		_screen->printShadedText(_chargenStrings2[9], 147, 67,
-					 _vm->guiSettings()->colors.guiColorLightBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
+			_vm->guiSettings()->colors.guiColorLightBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
 	}
 	drawButton(5, 0);
 
@@ -798,6 +847,7 @@ int CharacterGenerator::classMenu(int raceSex) {
 
 	_vm->_mouseX = _vm->_mouseY = 0;
 	int16 res = -1;
+	bool backBtnHiLite = false;
 
 	while (res == -1 && !_vm->shouldQuit()) {
 		updateMagicShapes();
@@ -808,14 +858,24 @@ int CharacterGenerator::classMenu(int raceSex) {
 			res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
 		} else if (_vm->posWithinRect(mp.x, mp.y, _chargenButtonDefs[41].x, _chargenButtonDefs[41].y,
 					      _chargenButtonDefs[41].x + _chargenButtonDefs[41].w, _chargenButtonDefs[41].y + _chargenButtonDefs[41].h)) {
-			if (in == 199 || in == 201)
+			if (in == 199 || in == 201) {
 				res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
-			else
+			} else { 
+				if (_vm->_flags.lang == Common::ZH_TWN && !backBtnHiLite) {
+					drawButton(5, 1);
+					_vm->_gui->simpleMenu_unselect(2, _chargenClassStrings, 0, itemsMask, 0);
+					backBtnHiLite = true;
+				}
 				_vm->removeInputTop();
+			}
 		} else {
 			res = _vm->_gui->simpleMenu_process(2, _chargenClassStrings, 0, itemsMask, 0);
-			if (_vm->_flags.platform == Common::kPlatformSegaCD)
+			if (_vm->_flags.platform == Common::kPlatformSegaCD) {
 				_screen->sega_getRenderer()->render(0, 18, 8, 20, 16);
+			} else if (backBtnHiLite) {
+				drawButton(5, 0);
+				backBtnHiLite = false;
+			}
 			_screen->updateScreen();
 		}
 	}
@@ -847,8 +907,8 @@ int CharacterGenerator::alignmentMenu(int cClass) {
 		_vm->_txt->printShadedText(_chargenStrings2[10], 0, 0, -1, 0x99);
 	} else {
 		_screen->printShadedText(_chargenStrings2[10], 147,
-					 (_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::Language::ZH_TWN) ? 65 : 67,
-					 _vm->guiSettings()->colors.guiColorLightBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
+			(_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::Language::ZH_TWN) ? 65 : 67,
+			_vm->guiSettings()->colors.guiColorLightBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
 	}
 
 	drawButton(5, 0);
@@ -861,6 +921,7 @@ int CharacterGenerator::alignmentMenu(int cClass) {
 
 	_vm->_mouseX = _vm->_mouseY = 0;
 	int16 res = -1;
+	bool backBtnHiLite = false;
 
 	while (res == -1 && !_vm->shouldQuit()) {
 		updateMagicShapes();
@@ -870,15 +931,25 @@ int CharacterGenerator::alignmentMenu(int cClass) {
 		if (in == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_ESCAPE] || _vm->_gui->_menuLastInFlags == _vm->_keyMap[Common::KEYCODE_b]) {
 			res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
 		} else if (_vm->posWithinRect(mp.x, mp.y, _chargenButtonDefs[41].x, _chargenButtonDefs[41].y,
-					      _chargenButtonDefs[41].x + _chargenButtonDefs[41].w, _chargenButtonDefs[41].y + _chargenButtonDefs[41].h)) {
-			if (in == 199 || in == 201)
+			_chargenButtonDefs[41].x + _chargenButtonDefs[41].w, _chargenButtonDefs[41].y + _chargenButtonDefs[41].h)) {
+			if (in == 199 || in == 201) {
 				res = _vm->_keyMap[Common::KEYCODE_ESCAPE];
-			else
+			} else {
+				if (_vm->_flags.lang == Common::ZH_TWN && !backBtnHiLite) {
+					drawButton(5, 1);
+					_vm->_gui->simpleMenu_unselect(2, _chargenAlignmentStrings, 0, itemsMask, 0);
+					backBtnHiLite = true;
+				}
 				_vm->removeInputTop();
+			}
 		} else {
 			res = _vm->_gui->simpleMenu_process(3, _chargenAlignmentStrings, 0, itemsMask, 0);
-			if (_vm->_flags.platform == Common::kPlatformSegaCD)
+			if (_vm->_flags.platform == Common::kPlatformSegaCD) {
 				_screen->sega_getRenderer()->render(0, 18, 9, 20, 16);
+			} else if (backBtnHiLite) {
+				drawButton(5, 0);
+				backBtnHiLite = false;
+			}
 			_screen->updateScreen();
 		}
 	}
@@ -1202,53 +1273,50 @@ void CharacterGenerator::printStats(int index, int mode) {
 		_vm->_txt->printShadedText(str1.c_str(), 32, 72);
 		_vm->_txt->printShadedText(str2.c_str(), 112, 72);
 		_vm->_txt->printShadedText(str3.c_str(), 120, 88);
+	} else if (_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::Language::ZH_TWN) {
+		_screen->printShadedText(c->name, 245, 34, _vm->guiSettings()->colors.guiColorBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(_chargenRaceSexStrings[c->raceSex], 165, 34, _vm->guiSettings()->colors.guiColorDarkBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(_chargenClassStrings[c->cClass], 165, 49, _vm->guiSettings()->colors.guiColorLightRed, 0, _vm->guiSettings()->colors.guiColorBlack);
+
+		for (int i = 0; i < 6; i++)
+			_screen->printShadedText(_chargenStatStrings[i], 165 + (i / 3) * 75, 64 + 16 * (i % 3), _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText("\xa8\xbe:" /* "防:"; */, 165, 64 + 16 * 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText("\xa9\x52:" /* "命:"; */, 165 + 45, 64 + 16 * 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText("\xaf\xc5:" /* "ç´š:"; */, 165 + 91, 64 + 16 * 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+
+		Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
+		_screen->printShadedText(_vm->getCharStrength(c->strengthCur, c->strengthExtCur, _vm->gameFlags().platform == Common::kPlatformSegaCD).c_str(),
+					 192, 64 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(Common::String::format("%d", c->intelligenceCur).c_str(),
+					 192, 64 + 16 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(Common::String::format("%d", c->wisdomCur).c_str(),
+					 192, 64 + 16 * 2 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(Common::String::format("%d", c->dexterityCur).c_str(),
+					 264, 64 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(Common::String::format("%d", c->constitutionCur).c_str(),
+					 264, 64 + 16 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(Common::String::format("%d", c->charismaCur).c_str(),
+					 264, 64 + 16 * 2 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+
+		_screen->printShadedText(Common::String::format("%d", c->armorClass).c_str(),
+					 192, 64 + 16 * 3 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(Common::String::format("%d", c->hitPointsMax).c_str(),
+					 232, 64 + 16 * 3 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(str3.c_str(),
+					 280, 64 + 16 * 3 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->setFont(of);
 	} else {
-		_screen->printShadedText(c->name,
-					 160 + ((160 - _screen->getTextWidth(c->name)) / 2),
-					 35, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-		if (_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::Language::ZH_TWN) {
-			_screen->printShadedText(_chargenRaceSexStrings[c->raceSex], 165, 34, _vm->guiSettings()->colors.guiColorLightBlue, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(_chargenClassStrings[c->cClass], 165, 49, _vm->guiSettings()->colors.guiColorLightRed, 0, _vm->guiSettings()->colors.guiColorBlack);
-
-			for (int i = 0; i < 6; i++)
-				_screen->printShadedText(_chargenStatStrings[i], 165 + (i / 3) * 75, 64 + 16 * (i % 3), _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText("\xa8\xbe:" /* "防:"; */, 165, 64 + 16 * 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText("\xa9\x52:" /* "命:"; */, 165 + 45, 64 + 16 * 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText("\xaf\xc5:" /* "ç´š:"; */, 165 + 91, 64 + 16 * 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-
-			Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
-			_screen->printShadedText(_vm->getCharStrength(c->strengthCur, c->strengthExtCur, _vm->gameFlags().platform == Common::kPlatformSegaCD).c_str(),
-						 165 + 25, 64 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(Common::String::format("%d", c->intelligenceCur).c_str(),
-						 165 + 25, 64 + 16 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(Common::String::format("%d", c->wisdomCur).c_str(),
-						 165 + 25, 64 + 16 * 2 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(Common::String::format("%d", c->dexterityCur).c_str(),
-						 165 + 75 + 25, 64 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(Common::String::format("%d", c->constitutionCur).c_str(),
-						 165 + 75 + 25, 64 + 16 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(Common::String::format("%d", c->charismaCur).c_str(),
-						 165 + 75 + 25, 64 + 16 * 2 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-
-			_screen->printShadedText(str3.c_str(),
-						 165 + 25, 64 + 16 * 3 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(Common::String::format("%d", c->hitPointsMax).c_str(),
-						 165 + 45 + 25, 64 + 16 * 3 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(Common::String::format("%d", c->armorClass).c_str(),
-						 165 + 91 + 25, 64 + 16 * 3 + 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->setFont(of);
-		} else {
-			_screen->printShadedText(_chargenRaceSexStrings[c->raceSex], 160 + ((160 - _screen->getTextWidth(_chargenRaceSexStrings[c->raceSex])) / 2), 45, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(_chargenClassStrings[c->cClass], 160 + ((160 - _screen->getTextWidth(_chargenClassStrings[c->cClass])) / 2), 54, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(c->name, 160 + ((160 - _screen->getTextWidth(c->name)) / 2), 35, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(_chargenRaceSexStrings[c->raceSex], 160 + ((160 - _screen->getTextWidth(_chargenRaceSexStrings[c->raceSex])) / 2), 45, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(_chargenClassStrings[c->cClass], 160 + ((160 - _screen->getTextWidth(_chargenClassStrings[c->cClass])) / 2), 54, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
 
-			for (int i = 0; i < 6; i++)
-				_screen->printShadedText(_chargenStatStrings[i], 163, (i + 8) << 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(_chargenStrings1[2], 248, 64, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		for (int i = 0; i < 6; i++)
+			_screen->printShadedText(_chargenStatStrings[i], 163, (i + 8) << 3, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(_chargenStrings1[2], 248, 64, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
 
-			_screen->printShadedText(str1.c_str(), 192, 64, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(str2.c_str(), 280, 64, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-			_screen->printShadedText(str3.c_str(), 280, 80, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
-		}
+		_screen->printShadedText(str1.c_str(), 192, 64, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(str2.c_str(), 280, 64, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printShadedText(str3.c_str(), 280, 80, _vm->guiSettings()->colors.guiColorWhite, 0, _vm->guiSettings()->colors.guiColorBlack);
 	}
 
 	if (_vm->_flags.platform == Common::kPlatformSegaCD) {
@@ -1288,11 +1356,15 @@ void CharacterGenerator::printStats(int index, int mode) {
 }
 
 void CharacterGenerator::processNameInput(int index, int textColor) {
-	Screen::FontId of = _screen->setFont(_vm->_conFont);
-	_screen->fillRect(_chargenNameFieldX[index], _chargenNameFieldY[index], _chargenNameFieldX[index] + 59, _chargenNameFieldY[index] + 5, _vm->guiSettings()->colors.guiColorBlack);
-	_screen->setFont(_vm->_invFont1);
-	int xOffs = (60 - _screen->getTextWidth(_characters[index].name)) >> 1;
-	_screen->printText(_characters[index].name, _chargenNameFieldX[index] + xOffs, _chargenNameFieldY[index], textColor, 0);
+	Screen::FontId of = _screen->setFont(_vm->_invFont1);
+	if (_vm->_flags.lang == Common::ZH_TWN) {
+		_screen->drawShape(0, _nameLabelsZH[index], _chargenNameFieldX[index] & ~7, _chargenNameFieldY[index] - 5);
+		_screen->printShadedText(_characters[index].name, _chargenNameFieldX[index] + ((62 - (strlen(_characters[index].name) << 3)) >> 1), _chargenNameFieldY[index] - 4, textColor, 0, _vm->guiSettings()->colors.guiColorBlack);
+	} else {
+		int xOffs = ((60 - _screen->getTextWidth(_characters[index].name)) >> 1);
+		_screen->fillRect(_chargenNameFieldX[index], _chargenNameFieldY[index], _chargenNameFieldX[index] + 59, _chargenNameFieldY[index] + 5, _vm->guiSettings()->colors.guiColorBlack);
+		_screen->printText(_characters[index].name, _chargenNameFieldX[index] + ((60 - _screen->getTextWidth(_characters[index].name)) >> 1), _chargenNameFieldY[index], textColor, 0);
+	}	
 	_screen->updateScreen();
 	_screen->setFont(of);
 }
@@ -1740,44 +1812,24 @@ void CharacterGenerator::finish() {
 }
 
 // TODO: Move to kyra.dat
-const char *CharacterGenerator::_chineseStrings[17] = {
-	nullptr, /* Unused */
-	nullptr, /* Unused */
-	nullptr, /* Unused */
-	nullptr, /* Unused */
-	"\xbb\xeb\xa4\x6c", /* "骰子"; */
-	"\xb0\x68\xa6\x5e", /* "退回" */
-	"\xb1\xb5\xa8\xfc", /* "接受"; */
-	"\xad\xd7\xa7\xef", /* "修改"; */
-	"\xb3\x79\xab\xac", /* "造型"; */
-	"\xa7\xb9\xb2\xa6", /* "完畢"; */
-	"\xa4\x51", /* "十"; */
-	"\xa4\x40", /* "一"; */
-	nullptr, /* Arrow */
-	nullptr, /* Arrow */
-	nullptr, /* Inactive play */
-	nullptr, /* Active play */
-	"\xa7\x52\xb0\xa3", /* "刪除"; */
-};
-
-const int CharacterGenerator::_chineseButtonMapping[17] = {
-	-1,
-	-1,
-	-1,
-	-1,
-	27,
-	41,
-	30,
-	28,
-	29,
-	40,
-	38,
-	39,
-	-1,
-	-1,
-	-1,
-	-1,
-	6,
+const CharacterGenerator::ButtonExtraDataChinese CharacterGenerator::_chineseButtonExtraData[17] = {
+	{ nullptr, /* Unused */				-1, -1 },
+	{ nullptr, /* Unused */				-1, -1 },
+	{ nullptr, /* Unused */				-1, -1 },
+	{ nullptr, /* Unused */				-1, -1 },
+	{ "\xbb\xeb\xa4\x6c", /* "骰子"; */	27,  1 },
+	{ "\xb0\x68\xa6\x5e", /* "退回" */	41,  0 },
+	{ "\xb1\xb5\xa8\xfc", /* "接受"; */	30,  1 },
+	{ "\xad\xd7\xa7\xef", /* "修改"; */	28,  1 },
+	{ "\xb3\x79\xab\xac", /* "造型"; */	29,  1 },
+	{ "\xa7\xb9\xb2\xa6", /* "完畢"; */	40,  1 },
+	{ "\xa4\x51", /* "十"; */			38,  1 },
+	{ "\xa4\x40", /* "一"; */			39,  1 },
+	{ nullptr, /* Arrow */				-1, -1 },
+	{ nullptr, /* Arrow */				-1, -1 },
+	{ nullptr, /* Inactive play */		-1, -1 },
+	{ nullptr, /* Active play */		-1, -1 },
+	{ "\xa7\x52\xb0\xa3", /* "刪除"; */	 6,  1 }
 };
 
 const EoBChargenButtonDef CharacterGenerator::_chargenButtonDefsDOSChinese[] = {
@@ -1786,8 +1838,8 @@ const EoBChargenButtonDef CharacterGenerator::_chargenButtonDefsDOSChinese[] = {
 	{ 0x01 << 3, 0x77, 0x31, 0x32, 0x72 },
 	{ 0x09 << 3, 0x77, 0x31, 0x32, 0x73 },
 	{ 0x03 << 3, 0xB5, 0x53, 0x10, 0x1A },
-	{ 190, 64, 35, 18, 0x19 },
-	{ 144, 64, 35, 18, 0x21 },
+	{ 190, 64, 35, 15, 0x19 },
+	{ 144, 64, 35, 15, 0x21 },
 	{ 0x21 << 3, 0xAC, 0x26, 0x10, 0x32 },
 	{ 0x13 << 3, 0x50, 0x9A, 0x08, 0x00 },
 	{ 0x13 << 3, 0x58, 0x9A, 0x08, 0x00 },
@@ -1808,10 +1860,10 @@ const EoBChargenButtonDef CharacterGenerator::_chargenButtonDefsDOSChinese[] = {
 	{ 0x1A << 3, 0x42, 0x20, 0x20, 0x00 },
 	{ 0x1E << 3, 0x42, 0x20, 0x20, 0x00 },
 	{ 0x22 << 3, 0x42, 0x20, 0x20, 0x00 },
-	{ 144,  64, 35, 18, 0x14 },
-	{ 183,  64, 35, 18, 0x34 },
-	{ 144,  80, 35, 18, 0x22 },
-	{ 183,  80, 35, 18, 0x26 },
+	{ 144,  64, 35, 15, 0x14 },
+	{ 183,  64, 35, 15, 0x34 },
+	{ 144,  80, 35, 15, 0x22 },
+	{ 183,  80, 35, 15, 0x26 },
 	{ 145, 130, 43, 16, 0x00 },
 	{ 145, 146, 43, 16, 0x00 },
 	{ 145, 162, 43, 16, 0x00 },
@@ -1819,9 +1871,9 @@ const EoBChargenButtonDef CharacterGenerator::_chargenButtonDefsDOSChinese[] = {
 	{ 220, 146, 43, 16, 0x00 },
 	{ 220, 162, 43, 16, 0x00 },
 	{ 190, 178, 43, 16, 0x00 },
-	{ 144,  64, 19, 18, 0x0D },
-	{ 167,  64, 19, 18, 0x0C },
-	{ 190,  64, 35, 18, 0x19 },
+	{ 144,  64, 17, 15, 0x0D },
+	{ 167,  64, 17, 15, 0x0C },
+	{ 190,  64, 35, 15, 0x19 },
 	{ 267, 171, 35, 18, 0x00 },
 };
 
diff --git a/engines/kyra/graphics/screen.cpp b/engines/kyra/graphics/screen.cpp
index 3e86b55f7e9..209fe903ac1 100644
--- a/engines/kyra/graphics/screen.cpp
+++ b/engines/kyra/graphics/screen.cpp
@@ -87,6 +87,7 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system, const ScreenDim *dimTable, co
 	_fontStyles = 0;
 	_paletteChanged = true;
 	_textMarginRight = SCREEN_W;
+	_overdrawMargin = false;
 	_customDimTable = nullptr;
 	_curDim = nullptr;
 	_curDimIndex = 0;
@@ -262,6 +263,7 @@ bool Screen::init() {
 	_curDim = nullptr;
 	_charSpacing = 0;
 	_lineSpacing = 0;
+	_overdrawMargin = (_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::ZH_TWN);
 	for (int i = 0; i < ARRAYSIZE(_textColorsMap); ++i)
 		_textColorsMap[i] = i;
 	_textColorsMap16bit[0] = _textColorsMap16bit[1] = 0;
@@ -1543,9 +1545,17 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
 			x = x_start;
 			y += (charHeight + _lineSpacing);
 		} else {
+			bool needDrawing = true;
 			int charWidth = getCharWidth(c);
 			int needSpace = enableWordWrap ? getTextWidth(str, true) + charWidth : charWidth;
 			if (x + needSpace > _textMarginRight) {
+				if (_overdrawMargin && (x + needSpace <= Screen::SCREEN_W)) {
+					// The Chinese version of EOB II has a weird way of handling the right margin.
+					// It will squeeze in the final character even if it goes over the margin
+					// (see e. g. the chargen screen "Your party is complete. Select the PLAY button...").
+					drawChar(c, x, y, pitch);
+					needDrawing = false;
+				}
 				x = x_start;
 				y += (charHeight + _lineSpacing);
 				if (enableWordWrap) {
@@ -1558,9 +1568,10 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
 				if (y >= _screenHeight)
 					break;
 			}
-
-			drawChar(c, x, y, pitch);
-			x += charWidth;
+			if (needDrawing) {
+				drawChar(c, x, y, pitch);
+				x += charWidth;
+			}
 		}
 	}
 }
diff --git a/engines/kyra/graphics/screen.h b/engines/kyra/graphics/screen.h
index 4377d785ca9..fac6c4dffbf 100644
--- a/engines/kyra/graphics/screen.h
+++ b/engines/kyra/graphics/screen.h
@@ -721,6 +721,7 @@ public:
 
 	void setTextMarginRight(int x) { _textMarginRight = x; }
 	uint16 _textMarginRight;
+	bool _overdrawMargin;
 
 	const ScreenDim *_curDim;
 
diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp
index fdbee787ed6..9195018e325 100644
--- a/engines/kyra/graphics/screen_eob.cpp
+++ b/engines/kyra/graphics/screen_eob.cpp
@@ -1737,7 +1737,7 @@ bool Screen_EoB::loadFont(FontId fontId, const char *filename) {
 			_vm->staticres()->loadRawData(kEoB1CharWidthTable1, temp), _vm->staticres()->loadRawData(kEoB1CharWidthTable2, temp), _vm->staticres()->loadRawData(kEoB1CharWidthTable3, temp));
 	} else if (fontId == FID_CHINESE_FNT && _vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::ZH_TWN) {
 		// We wrap all fonts in Big5 support but FID_CHINESE additionally attempts to match height
-		OldDOSFont *ofnt = new OldDOSFont(_useHiResEGADithering ? Common::kRenderVGA : _renderMode, 12);
+		OldDOSFont *ofnt = new OldDOSFont(_useHiResEGADithering ? Common::kRenderVGA : _renderMode, 12, false);
 		ofnt->loadPCBIOSTall();
 		fnt = new ChineseTwoByteFontEoB(_big5, ofnt);
 		fnt->setColorMap(_textColorsMap);
@@ -1993,7 +1993,7 @@ const uint8 Screen_EoB::_egaMatchTable[] = {
 uint16 *OldDOSFont::_cgaDitheringTable = 0;
 int OldDOSFont::_numRef = 0;
 
-OldDOSFont::OldDOSFont(Common::RenderMode mode, uint8 shadowColor) : _renderMode(mode), _shadowColor(shadowColor), _numGlyphsMax(128), _useOverlay(false), _scaleV(1), _colorMap8bit(0), _colorMap16bit(0) {
+OldDOSFont::OldDOSFont(Common::RenderMode mode, uint8 shadowColor, bool remapCharacters) : _renderMode(mode), _shadowColor(shadowColor), _remapCharacters(remapCharacters), _numGlyphsMax(128), _useOverlay(false), _scaleV(1), _colorMap8bit(0), _colorMap16bit(0) {
 	_data = 0;
 	_width = _height = _numGlyphs = 0;
 	_bitmapOffsets = 0;
@@ -2115,7 +2115,8 @@ void OldDOSFont::drawCharIntern(uint16 c, byte *dst, int pitch, int bpp, int col
 		0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff
 	};
 
-	c = convert(c);
+	if (_remapCharacters)
+		c = convert(c);
 
 	if (c >= _numGlyphs)
 		return;
diff --git a/engines/kyra/graphics/screen_eob.h b/engines/kyra/graphics/screen_eob.h
index 13886ab6762..4a69d41e0b0 100644
--- a/engines/kyra/graphics/screen_eob.h
+++ b/engines/kyra/graphics/screen_eob.h
@@ -262,7 +262,7 @@ private:
 */
 class OldDOSFont : public Font {
 public:
-	OldDOSFont(Common::RenderMode mode, uint8 shadowColor);
+	OldDOSFont(Common::RenderMode mode, uint8 shadowColor, bool remapCharacters = true);
 	~OldDOSFont() override;
 
 	bool load(Common::SeekableReadStream &file) override;
@@ -297,6 +297,7 @@ private:
 	virtual uint16 convert(uint16 c) const;
 	Common::RenderMode _renderMode;
 	const uint16 *_colorMap16bit;
+	bool _remapCharacters;
 
 	static uint16 *_cgaDitheringTable;
 	static int _numRef;
diff --git a/engines/kyra/gui/gui_eob.cpp b/engines/kyra/gui/gui_eob.cpp
index 2ad453e5395..4679f3d98d7 100644
--- a/engines/kyra/gui/gui_eob.cpp
+++ b/engines/kyra/gui/gui_eob.cpp
@@ -1567,9 +1567,14 @@ void EoBCoreEngine::gui_processInventorySlotClick(int slot) {
 	}
 }
 
-GUI_EoB::GUI_EoB(EoBCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen), _numSlotsVisible(vm->gameFlags().platform == Common::kPlatformSegaCD ? 5 : 6),
-	_menuFont(_vm->gameFlags().platform == Common::kPlatformPC98 ? Screen::FID_SJIS_FNT : (_vm->_flags.lang == Common::Language::ZH_TWN ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT)),
-	_menuFont2(_vm->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : (_vm->_flags.lang == Common::Language::ZH_TWN ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT)) {
+GUI_EoB::GUI_EoB(EoBCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm ? vm->_screen : nullptr), _numSlotsVisible(vm && vm->gameFlags().platform == Common::kPlatformSegaCD ? 5 : 6),
+	_menuFont(vm ? (vm->gameFlags().platform == Common::kPlatformPC98 ? Screen::FID_SJIS_FNT : (vm->_flags.lang == Common::Language::ZH_TWN ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT)) : Screen::FID_8_FNT),
+	_menuFont2(vm ? (vm->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : (vm->_flags.lang == Common::Language::ZH_TWN ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT)) : Screen::FID_8_FNT),
+	// The PC-98 versions of EOB I + II, the English Sega-CD version of EOB I and the Chinese version of EOB II allow small characters.
+	// For all other versions we convert to capital characters.
+	_textInputForceUppercase(vm && vm->_flags.platform != Common::kPlatformPC98 && vm->_flags.lang != Common::ZH_TWN && !(vm->_flags.platform == Common::kPlatformSegaCD && vm->_flags.lang != Common::EN_ANY)),
+	_textInputHeight(vm && vm->game() == GI_EOB2 && vm->gameFlags().lang == Common::Language::ZH_TWN ? 16 : 9),
+	_textInputShadowOffset(vm && vm->game() == GI_EOB2 && vm->gameFlags().lang == Common::Language::ZH_TWN ? 1 : 0) {
 
 	_menuStringsPrefsTemp = new char*[4]();
 	_saveSlotStringsTemp = new char*[6];
@@ -1593,6 +1598,7 @@ GUI_EoB::GUI_EoB(EoBCoreEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen), _n
 	_menuTextColor = _menuHighlightColor = _menuShadowColor = 0;
 	_menuCur = 0;
 	_menuNumItems = 0;
+	assert(_vm);
 
 	_numPages = (_vm->game() == GI_EOB2) ? 8 : 5;
 	_numVisPages = (_vm->game() == GI_EOB2) ? 6 : 5;
@@ -2153,23 +2159,23 @@ Common::Point GUI_EoB::simpleMenu_getTextPoint(int num, int *col) {
 void GUI_EoB::simpleMenu_printButton(int sd, int num, const char *title, bool isHighlight, bool isInitial) {
 	int column;
 	Common::Point tPoint = simpleMenu_getTextPoint(num, &column);
-        if (_vm->gameFlags().platform == Common::kPlatformSegaCD) {
-                _vm->_txt->printShadedText(title, 4 + tPoint.x, (sd == 8 ? 2 : 20) + tPoint.y, isHighlight ? _menuHighlightColor : _menuTextColor, _menuShadowColor);
-        } else {
+    if (_vm->gameFlags().platform == Common::kPlatformSegaCD) {
+		_vm->_txt->printShadedText(title, 4 + tPoint.x, (sd == 8 ? 2 : 20) + tPoint.y, isHighlight ? _menuHighlightColor : _menuTextColor, _menuShadowColor);
+    } else {
 		Common::Point p = tPoint + _menuPoint;
-                _screen->printShadedText(title, p.x, p.y, _menuTextColor, 0, _menuShadowColor);
-                if (isHighlight)
-                        _screen->printText(title, p.x, p.y, _menuHighlightColor, 0);
+        _screen->printShadedText(title, p.x, p.y, _menuTextColor, 0, _menuShadowColor);
+		if (isHighlight)
+			_screen->printText(title, p.x, p.y, _menuHighlightColor, 0);
 		if (num < ARRAYSIZE(_menuOverflow) && isInitial)
 			_menuOverflow[num] = _screen->getTextWidth(title) > _menuColumnWidth[column];
-        }
+	}
 }
 
 void GUI_EoB::simpleMenu_setup(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int itemOffset, int lineSpacing, int textColor, int highlightColor, int shadowColor) {
 	simpleMenu_initMenuItemsMask(sd, maxItem, menuItemsMask, itemOffset);
 
 	const ScreenDim *dm = _screen->getScreenDim(19 + sd);
-        _menuPoint = Common::Point((_screen->_curDim->sx + dm->sx) << 3, _screen->_curDim->sy + dm->sy);
+	_menuPoint = Common::Point((_screen->_curDim->sx + dm->sx) << 3, _screen->_curDim->sy + dm->sy);
 
 	int v = simpleMenu_getMenuItem(_menuCur, menuItemsMask, itemOffset);
 	_menuColumns = 1;
@@ -2216,7 +2222,7 @@ void GUI_EoB::simpleMenu_setup(int sd, int maxItem, const char *const *strings,
 
 	for (int i = 0; i < _menuNumItems; i++) {
 		int item = simpleMenu_getMenuItem(i, menuItemsMask, itemOffset);
-                simpleMenu_printButton(sd, i, strings[item], item == v, true);
+		simpleMenu_printButton(sd, i, strings[item], item == v, true);
 	}
 
 	_vm->removeInputTop();
@@ -2307,8 +2313,8 @@ int GUI_EoB::simpleMenu_process(int sd, const char *const *strings, void *b, int
 	}
 
 	if (newItem != currentItem) {
-                simpleMenu_printButton(sd, currentItem, strings[simpleMenu_getMenuItem(currentItem, menuItemsMask, itemOffset)], false, false);
-                simpleMenu_printButton(sd, newItem, strings[simpleMenu_getMenuItem(newItem, menuItemsMask, itemOffset)], true, false);
+		simpleMenu_printButton(sd, currentItem, strings[simpleMenu_getMenuItem(currentItem, menuItemsMask, itemOffset)], false, false);
+		simpleMenu_printButton(sd, newItem, strings[simpleMenu_getMenuItem(newItem, menuItemsMask, itemOffset)], true, false);
 		if (_vm->gameFlags().platform == Common::kPlatformSegaCD) {
 			_screen->sega_getRenderer()->render(0, 6, 20, 26, 5);
 		}
@@ -2327,6 +2333,14 @@ int GUI_EoB::simpleMenu_process(int sd, const char *const *strings, void *b, int
 	return result;
 }
 
+void GUI_EoB::simpleMenu_unselect(int sd, const char *const *strings, void *b, int32 menuItemsMask, int itemOffset) {
+	// This function is basically just a hack for EOB II Chinese. It isn't used or needed anywhere else.
+	int currentItem = _menuCur % _menuNumItems;
+	simpleMenu_printButton(sd, currentItem, strings[simpleMenu_getMenuItem(currentItem, menuItemsMask, itemOffset)], false, false);
+	_menuCur = 0;
+	_screen->updateScreen();
+}
+
 int GUI_EoB::simpleMenu_getMenuItem(int index, int32 menuItemsMask, int itemOffset) {
 	if (menuItemsMask == -1)
 		return index;
@@ -2904,7 +2918,6 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 	uint8 *segaCharBuf = new uint8[destMaxLen << 5]();
 
 	int len = strlen(dest);
-	int height = (_vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::Language::ZH_TWN) ? 15 : 9;
 	if (len > destMaxLen) {
 		len = destMaxLen;
 		dest[destMaxLen] = 0;
@@ -2914,7 +2927,7 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 	if (len >= destMaxLen)
 		pos--;
 
-	_screen->copyRegion((x - 1) << 3, y, 0, 200 - height, (destMaxLen + 2) << 3, height, 0, 2, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion((x - 1) << 3, y, 0, 200 - _textInputHeight, (destMaxLen + 2) << 3, _textInputHeight, 0, 2, Screen::CR_NO_P_CHECK);
 	if (_vm->gameFlags().platform == Common::kPlatformFMTowns)
 		_screen->copyRegion(0, 0, 160, 0, 160, 128, 2, 2, Screen::CR_NO_P_CHECK);
 	_screen->printShadedText(dest, x << 3, y, textColor1, textColor2, _vm->guiSettings()->colors.guiColorBlack);
@@ -2943,10 +2956,10 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 					_screen->sega_getRenderer()->render(0, x + pos, y >> 3, 1, 1);
 					_screen->sega_setTextBuffer(0, 0);
 				} else if (cursorState) {
-					_screen->copyRegion((pos + 1) << 3, 200 - height, (x + pos) << 3, y, 8, height, 2, 0, Screen::CR_NO_P_CHECK);
+					_screen->copyRegion((pos + 1) << 3, 200 - _textInputHeight, (x + pos) << 3, y, 8, _textInputHeight, 2, 0, Screen::CR_NO_P_CHECK);
 					_screen->printShadedText(sufx, (x + pos) << 3, y, textColor1, textColor2, _vm->guiSettings()->colors.guiColorBlack);
 				} else {
-					_screen->fillRect((x + pos) << 3, y, ((x + pos) << 3) + 7, y + height - 2, cursorColor);
+					_screen->fillRect((x + pos) << 3, y, ((x + pos) << 3) + 7, y + _textInputHeight - 2 + _textInputShadowOffset, cursorColor);
 					_screen->printText(sufx, (x + pos) << 3, y, textColor1, cursorColor);
 				}
 
@@ -3011,9 +3024,7 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 
 		} else if ((in > 31 && in < 126) || (in == 0x89)) {
 			if (!(in == 32 && pos == 0)) {
-				// The PC-98 versions of EOB I + II and the English Sega-CD version of EOB I are the only versions that allow small characters.
-				// For all other versions we convert to capital characters.
-				if (in >= 97 && in <= 122 && _vm->_flags.platform != Common::kPlatformPC98 && !(_vm->_flags.platform == Common::kPlatformSegaCD && _vm->_flags.lang != Common::EN_ANY))
+				if (in >= 97 && in <= 122 && _textInputForceUppercase)
 					in -= 32;
 
 				if (pos < len) {
@@ -3070,7 +3081,7 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo
 			_screen->sega_getRenderer()->render(0, x, y >> 3, destMaxLen, 1);
 			_screen->sega_setTextBuffer(0, 0);
 		} else {
-			_screen->copyRegion(0, 200 - height, (x - 1) << 3, y, (destMaxLen + 2) << 3, height, 2, 0, Screen::CR_NO_P_CHECK);
+			_screen->copyRegion(0, 200 - _textInputHeight, (x - 1) << 3, y, (destMaxLen + 2) << 3, _textInputHeight, 2, 0, Screen::CR_NO_P_CHECK);
 			_screen->printShadedText(dest, x << 3, y, textColor1, textColor2, _vm->guiSettings()->colors.guiColorBlack);
 		}
 
diff --git a/engines/kyra/gui/gui_eob.h b/engines/kyra/gui/gui_eob.h
index acf6d4de614..5d734513c7e 100644
--- a/engines/kyra/gui/gui_eob.h
+++ b/engines/kyra/gui/gui_eob.h
@@ -56,6 +56,7 @@ public:
 	// Non button based menu handling (main menu, character generation)
 	void simpleMenu_setup(int sd, int maxItem, const char *const *strings, int32 menuItemsMask, int itemOffset, int lineSpacing, int textColor, int highlightColor, int shadowColor);
 	int simpleMenu_process(int sd, const char *const *strings, void *b, int32 menuItemsMask, int itemOffset);
+	void simpleMenu_unselect(int sd, const char *const *strings, void *b, int32 menuItemsMask, int itemOffset);
 
 	// Button based menus (camp menu, load menu)
 	virtual void runCampMenu();
@@ -174,6 +175,10 @@ private:
 	const uint8 *_highLightColorTable;
 	uint32 _highLightBoxTimer;
 
+	const bool _textInputForceUppercase;
+	const int _textInputHeight;
+	const int _textInputShadowOffset;
+
 	const Screen::FontId _menuFont;
 	const Screen::FontId _menuFont2;
 




More information about the Scummvm-git-logs mailing list