[Scummvm-git-logs] scummvm master -> 5c91fb8d6a5733baf847e40111a86146045d3e4c
sev-
sev at scummvm.org
Mon Dec 7 22:01:42 UTC 2020
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
5c91fb8d6a SCUMM: Support Lokalizator plugin.
Commit: 5c91fb8d6a5733baf847e40111a86146045d3e4c
https://github.com/scummvm/scummvm/commit/5c91fb8d6a5733baf847e40111a86146045d3e4c
Author: Vladimir Serbinenko (phcoder at google.com)
Date: 2020-12-07T23:01:38+01:00
Commit Message:
SCUMM: Support Lokalizator plugin.
This was used by Russian translation of Pajama Sam 2 and Spy Fox 3
Changed paths:
A engines/scumm/he/localizer.cpp
A engines/scumm/he/localizer.h
engines/scumm/he/script_v72he.cpp
engines/scumm/metaengine.cpp
engines/scumm/module.mk
engines/scumm/scumm.cpp
engines/scumm/scumm.h
engines/scumm/string.cpp
diff --git a/engines/scumm/he/localizer.cpp b/engines/scumm/he/localizer.cpp
new file mode 100644
index 0000000000..f5289531ea
--- /dev/null
+++ b/engines/scumm/he/localizer.cpp
@@ -0,0 +1,122 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/endian.h"
+#include "scumm/he/localizer.h"
+#include "common/file.h"
+#include "common/debug.h"
+
+namespace Scumm {
+
+Localizer::Localizer() {
+ Common::File _file;
+
+ if (!_file.open("lokalizator.big"))
+ return;
+
+ uint _fileSize = _file.size();
+ if (_fileSize < 0x18)
+ return;
+ byte *lkBig = new byte[_fileSize];
+ _file.read(lkBig, _fileSize);
+ // Obfuscation round 1
+ for (uint i = 0; i < _fileSize; i++)
+ lkBig[i] ^= (214013 * i + 2531011) >> 16;
+
+ uint32 numFiles = READ_LE_UINT32(lkBig + 0x14);
+ uint32 localeMsgOffset = 0, localeMsgSize = 0;
+ uint32 talkieDatOffset = 0, talkieDatSize = 0;
+
+ for (uint i = 0; i < numFiles; i++) {
+ byte *fileHdr = lkBig + 0x18 + 0x4c * i;
+ if (strcmp((char *) fileHdr, "locale.msg") == 0) {
+ localeMsgOffset = READ_LE_UINT32(fileHdr + 0x48);
+ localeMsgSize = READ_LE_UINT32(fileHdr + 0x44);
+ continue;
+ }
+ if (strcmp((char *) fileHdr, "talkie.dat") == 0) {
+ talkieDatOffset = READ_LE_UINT32(fileHdr + 0x48);
+ talkieDatSize = READ_LE_UINT32(fileHdr + 0x44);
+ continue;
+ }
+ }
+
+ _isValid = true;
+
+ if (localeMsgSize > 4) {
+ uint32 msgCount = READ_LE_UINT32(lkBig + localeMsgOffset);
+ // Obfuscation round 2
+ uint32 st = 0x12345678;
+ for (uint i = 0; i < localeMsgSize - 4; i++) {
+ byte x = 0;
+ switch (i & 3) {
+ case 0:
+ x = st;
+ break;
+ case 1:
+ x = st + 35;
+ break;
+ case 2:
+ x = st + 70;
+ break;
+ case 3:
+ x = st + 105;
+ st += 45707404;
+ break;
+ }
+ lkBig[i + localeMsgOffset + 4] ^= x;
+ }
+
+ uint32 cur = localeMsgOffset + 4;
+
+ for (uint i = 0; i < msgCount && cur < localeMsgOffset + localeMsgSize; i++) {
+ cur += 4; // Domain id or something like this, always zero
+ uint32 lenOrig = READ_LE_UINT32(lkBig + cur); cur += 4;
+ Common::String orig((char *) lkBig + cur, (char *) lkBig + cur + lenOrig);
+ cur += lenOrig;
+ uint32 lenTrans = READ_LE_UINT32(lkBig + cur); cur += 4;
+ Common::String trans((char *) lkBig + cur, (char *) lkBig + cur + lenTrans);
+ cur += lenTrans;
+ _translationMap[orig] = trans;
+ }
+ }
+
+ for (uint32 cur = talkieDatOffset; cur < talkieDatOffset + talkieDatSize; cur += 16) {
+ _talkMap[READ_LE_UINT32(lkBig+cur+4)] = READ_LE_UINT32(lkBig+cur+12);
+ }
+}
+
+Common::String Localizer::translate(const Common::String &orig) {
+ if (_translationMap.contains(orig)) {
+ return _translationMap[orig];
+ }
+ return orig;
+}
+
+uint32 Localizer::mapTalk(uint32 orig) {
+ if (_talkMap.contains(orig)) {
+ return _talkMap[orig];
+ }
+ return orig;
+}
+
+}
diff --git a/engines/scumm/he/localizer.h b/engines/scumm/he/localizer.h
new file mode 100644
index 0000000000..25be5eeabf
--- /dev/null
+++ b/engines/scumm/he/localizer.h
@@ -0,0 +1,48 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SCUMM_LOCALIZER_H
+#define SCUMM_LOCALIZER_H
+
+#include "common/str.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+
+namespace Scumm {
+
+class Localizer {
+public:
+ Localizer();
+ Common::String translate(const Common::String &original);
+ uint32 mapTalk(uint32 orig);
+ bool isValid() {
+ return _isValid;
+ }
+private:
+ Common::HashMap<Common::String, Common::String> _translationMap;
+ Common::HashMap<uint32, uint32> _talkMap;
+ bool _isValid;
+};
+
+}
+
+#endif
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index 304e76faf2..2b21f3cdfa 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -31,6 +31,7 @@
#include "scumm/dialogs.h"
#include "scumm/file.h"
#include "scumm/he/intern_he.h"
+#include "scumm/he/localizer.h"
#include "scumm/object.h"
#include "scumm/resource.h"
#include "scumm/scumm.h"
@@ -317,6 +318,7 @@ void ScummEngine_v72he::decodeScriptString(byte *dst, bool scriptString) {
int args[31];
int num, len, val;
byte chr, string[1024];
+ byte *dst0 = dst;
memset(args, 0, sizeof(args));
memset(string, 0, sizeof(string));
@@ -335,6 +337,10 @@ void ScummEngine_v72he::decodeScriptString(byte *dst, bool scriptString) {
len = resStrLen(string) + 1;
}
+ if (_localizer) {
+ strncpy((char *) string, _localizer->translate((char *) string).c_str(), sizeof(string) - 1);
+ }
+
// Decode string
num = 0;
val = 0;
@@ -372,6 +378,10 @@ void ScummEngine_v72he::decodeScriptString(byte *dst, bool scriptString) {
}
}
*dst = 0;
+
+ if (_localizer) {
+ strncpy((char *) dst0, _localizer->translate((char *) dst0).c_str(), sizeof(string) - 1);
+ }
}
int ScummEngine_v72he::findObject(int x, int y, int num, int *args) {
diff --git a/engines/scumm/metaengine.cpp b/engines/scumm/metaengine.cpp
index 58bcf9201c..aaeb667715 100644
--- a/engines/scumm/metaengine.cpp
+++ b/engines/scumm/metaengine.cpp
@@ -333,13 +333,6 @@ Common::Error ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) co
return Common::kUnsupportedGameidError;
}
- // We don't support yet the
- // the full game.
- if (!strcmp(res.game.gameid, "pajama2") && !strcmp(res.extra, "Russobit")) {
- GUIErrorMessage(_("The Russian version of Pajama Sam 2 is not supported yet due to incomplete code."));
- return Common::kUnsupportedGameidError;
- }
-
// If the GUI options were updated, we catch this here and update them in the users config
// file transparently.
Common::updateGameGUIOptions(res.game.guioptions, getGameGUIOptionsDescriptionLanguage(res.language));
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index b12597be23..36d7871da8 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -137,6 +137,7 @@ MODULE_OBJS += \
he/script_v100he.o \
he/sprite_he.o \
he/wiz_he.o \
+ he/localizer.o \
he/logic/baseball2001.o \
he/logic/basketball.o \
he/logic/football.o \
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 5afa175515..6b60875b2b 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -72,6 +72,7 @@
#include "scumm/scumm_v8.h"
#include "scumm/sound.h"
#include "scumm/imuse/sysex.h"
+#include "scumm/he/localizer.h"
#include "scumm/he/sprite_he.h"
#include "scumm/he/cup_player_he.h"
#include "scumm/util.h"
@@ -124,6 +125,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_rnd("scumm")
{
+ _localizer = nullptr;
+
#ifdef USE_RGB_COLOR
if (_game.features & GF_16BIT_COLOR) {
if (_game.platform == Common::kPlatformPCEngine)
@@ -1337,6 +1340,14 @@ Common::Error ScummEngine::init() {
}
}
+#ifdef ENABLE_HE
+ Localizer *loc = new Localizer();
+ if (!loc->isValid())
+ delete loc;
+ else
+ _localizer = loc;
+#endif
+
_outputPixelFormat = _system->getScreenFormat();
setupScumm();
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index eb8aa5d151..d8f4351d59 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -90,6 +90,7 @@ class Player_Towns;
class ScummEngine;
class ScummDebugger;
class Sound;
+class Localizer;
struct Box;
struct BoxCoords;
@@ -1108,6 +1109,8 @@ protected:
int _nextLeft, _nextTop;
+ Localizer *_localizer;
+
void restoreCharsetBg();
void clearCharsetMask();
void clearTextSurface();
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index 755396c271..26c19cd6d6 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -32,6 +32,7 @@
#include "scumm/imuse_digi/dimuse.h"
#ifdef ENABLE_HE
#include "scumm/he/intern_he.h"
+#include "scumm/he/localizer.h"
#endif
#include "scumm/resource.h"
#include "scumm/scumm.h"
@@ -336,7 +337,11 @@ bool ScummEngine::handleNextCharsetCode(Actor *a, int *code) {
talk_sound_b = buffer[8] | (buffer[9] << 8) | (buffer[12] << 16) | (buffer[13] << 24);
buffer += 14;
if (_game.heversion >= 60) {
+#ifdef ENABLE_HE
+ ((SoundHE *)_sound)->startHETalkSound(_localizer ? _localizer->mapTalk(talk_sound_a) : talk_sound_a);
+#else
((SoundHE *)_sound)->startHETalkSound(talk_sound_a);
+#endif
} else {
_sound->talkSound(talk_sound_a, talk_sound_b, 2);
}
@@ -406,7 +411,7 @@ bool ScummEngine_v72he::handleNextCharsetCode(Actor *a, int *code) {
}
value[i] = 0;
//talk_sound_b = atoi(value);
- ((SoundHE *)_sound)->startHETalkSound(talk_sound_a);
+ ((SoundHE *)_sound)->startHETalkSound(_localizer ? _localizer->mapTalk(talk_sound_a) : talk_sound_a);
break;
case 104:
_haveMsg = 0;
@@ -429,7 +434,7 @@ bool ScummEngine_v72he::handleNextCharsetCode(Actor *a, int *code) {
value[i] = 0;
talk_sound_a = atoi(value);
//talk_sound_b = 0;
- ((SoundHE *)_sound)->startHETalkSound(talk_sound_a);
+ ((SoundHE *)_sound)->startHETalkSound(_localizer ? _localizer->mapTalk(talk_sound_a) : talk_sound_a);
break;
case 119:
_haveMsg = 0xFF;
More information about the Scummvm-git-logs
mailing list