mirror of
https://github.com/libretro/scummvm.git
synced 2026-11-07 04:26:05 -10:00
MACS2: support for adding multiple translation dat files to the game dir
even the demo supports those translations now - except the one demo-only chapter at the end
This commit is contained in:
1 parent
cdbe4b55eb
commit
f04ff1a7ab
14 files changed
+258
-44
No files matched your search
@@ -81,9 +81,6 @@ scripts, from.
|
||||
lure.dat:
|
||||
This file contains essential game data used by Lure of the Temptress game.
|
||||
|
||||
macs2_translation.dat:
|
||||
This file contains game translations for the MACS2 engine.
|
||||
|
||||
macgui.dat:
|
||||
The file contains set of offsets for recreation of Classic Mac OS GUI, used
|
||||
by Director, MacVenture and WAGE engines.
|
||||
|
||||
@@ -50,9 +50,6 @@ endif
|
||||
ifdef ENABLE_PRINCE
|
||||
DIST_FILES_LIST += dists/engine-data/prince_translation.dat
|
||||
endif
|
||||
ifdef ENABLE_MACS2
|
||||
DIST_FILES_LIST += dists/engine-data/macs2_translation.dat
|
||||
endif
|
||||
ifdef ENABLE_QUEEN
|
||||
DIST_FILES_LIST += dists/engine-data/queen.tbl
|
||||
endif
|
||||
|
||||
Binary file not shown.
@@ -41,7 +41,6 @@ f 0644 root sys usr/ScummVM/share/scummvm/kyra.dat kyra.dat scummvm.sw.eoe
|
||||
f 0644 root sys usr/ScummVM/share/scummvm/lure.dat lure.dat scummvm.sw.eoe
|
||||
f 0644 root sys usr/ScummVM/share/scummvm/macgui.dat macgui.dat scummvm.sw.eoe
|
||||
f 0644 root sys usr/ScummVM/share/scummvm/macventure.dat macventure.dat scummvm.sw.eoe
|
||||
f 0644 root sys usr/ScummVM/share/scummvm/macs2_translation.dat macs2_translation.dat scummvm.sw.eoe
|
||||
f 0644 root sys usr/ScummVM/share/scummvm/monkey4-patch.m4b monkey4-patch.m4b scummvm.sw.eoe
|
||||
f 0644 root sys usr/ScummVM/share/scummvm/mort.dat mort.dat scummvm.sw.eoe
|
||||
f 0644 root sys usr/ScummVM/share/scummvm/myst3.dat myst3.dat scummvm.sw.eoe
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Macs2 {
|
||||
|
||||
namespace {
|
||||
|
||||
// German source keys for macs2_translation.dat msgctxt "uilabel".
|
||||
// German source keys for sis-translation-<lang>.dat msgctxt "uilabel".
|
||||
Common::String uiText(const char *source) {
|
||||
if (g_engine)
|
||||
return g_engine->translateUiLabel(source);
|
||||
|
||||
@@ -53,10 +53,7 @@ extern const ADGameDescription gameDescriptions[];
|
||||
#define GAMEOPTION_ORIGINAL_SAVELOAD GUIO_GAMEOPTIONS1
|
||||
#define GAMEOPTION_TTS GUIO_GAMEOPTIONS2
|
||||
#define GAMEOPTION_ENHANCEMENTS GUIO_GAMEOPTIONS3
|
||||
|
||||
enum {
|
||||
GF_TRANSLATED = 1 << 0,
|
||||
};
|
||||
#define GAMEOPTION_TRANSLATION GUIO_GAMEOPTIONS4
|
||||
|
||||
} // End of namespace Macs2
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ const ADGameDescription gameDescriptions[] = {
|
||||
Common::DE_DEU,
|
||||
Common::kPlatformDOS,
|
||||
ADGF_TESTING,
|
||||
GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_TTS, GAMEOPTION_ENHANCEMENTS)},
|
||||
GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_TTS, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_TRANSLATION)},
|
||||
|
||||
// GMACS II Interpreter V1.00 - Written & Copyright (C) 1993 by Arndt Hasch - Copyright by LINEL
|
||||
{"sis",
|
||||
@@ -45,17 +45,7 @@ const ADGameDescription gameDescriptions[] = {
|
||||
Common::DE_DEU,
|
||||
Common::kPlatformDOS,
|
||||
ADGF_DEMO | ADGF_TESTING,
|
||||
GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_TTS, GAMEOPTION_ENHANCEMENTS)},
|
||||
|
||||
// English fan translation (original + macs2_translation.dat)
|
||||
{"sis",
|
||||
"w/translation",
|
||||
AD_ENTRY2s("RESOURCE.MCS", "b8646d5cc2e45442a414220b1a65ba73", 8621636,
|
||||
"macs2_translation.dat", nullptr, AD_NO_SIZE),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformDOS,
|
||||
GF_TRANSLATED | ADGF_TESTING,
|
||||
GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_TTS, GAMEOPTION_ENHANCEMENTS)},
|
||||
GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_TTS, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_TRANSLATION)},
|
||||
|
||||
// Amiga demo - DataA (MXMF) + Mdir (MXDR). GMACS II / LINEL.
|
||||
{"sis",
|
||||
|
||||
@@ -21,15 +21,27 @@
|
||||
|
||||
#include "macs2/dialogs.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/gui_options.h"
|
||||
#include "common/translation.h"
|
||||
#include "engines/enhancements.h"
|
||||
#include "gui/widget.h"
|
||||
#include "macs2/detection.h"
|
||||
|
||||
namespace Macs2 {
|
||||
|
||||
Macs2OptionsWidget::Macs2OptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain) :
|
||||
OptionsContainerWidget(boss, name, "Macs2GameOptionsDialog", domain) {
|
||||
|
||||
if (Common::checkGameGUIOption(GAMEOPTION_TRANSLATION, ConfMan.get("guioptions", domain))) {
|
||||
GUI::StaticTextWidget *label = new GUI::StaticTextWidget(widgetsBoss(), _dialogLayout + ".translationLabel", _("Translation:"));
|
||||
label->setAlign(Graphics::kTextAlignRight);
|
||||
_translationPopUp = new GUI::PopUpWidget(widgetsBoss(), _dialogLayout + ".translation");
|
||||
_translationPopUp->appendEntry(_("Original"), 0);
|
||||
_translationPackages = listTranslationPackages(Common::FSNode(ConfMan.getPath("path", domain)), ConfMan.get("gameid", domain));
|
||||
for (uint i = 0; i < _translationPackages.size(); ++i)
|
||||
_translationPopUp->appendEntry(_translationPackages[i].displayName, i + 1);
|
||||
}
|
||||
|
||||
_originalMenusCheckbox = new GUI::CheckboxWidget(widgetsBoss(), _dialogLayout + ".originalMenus",
|
||||
_("Use original save/load screens"),
|
||||
_("Use the original save/load screens instead of the ScummVM ones"));
|
||||
@@ -77,6 +89,17 @@ Macs2OptionsWidget::Macs2OptionsWidget(GuiObject *boss, const Common::String &na
|
||||
}
|
||||
|
||||
void Macs2OptionsWidget::load() {
|
||||
if (_translationPopUp) {
|
||||
_translationPopUp->setSelectedTag(0);
|
||||
const Common::String code = ConfMan.get(kTranslationConfigKey, _domain);
|
||||
for (uint i = 0; i < _translationPackages.size(); ++i) {
|
||||
if (_translationPackages[i].code.equalsIgnoreCase(code)) {
|
||||
_translationPopUp->setSelectedTag(i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_originalMenusCheckbox->setState(ConfMan.getBool("original_menus", _domain));
|
||||
|
||||
#ifdef USE_TTS
|
||||
@@ -112,6 +135,14 @@ void Macs2OptionsWidget::load() {
|
||||
}
|
||||
|
||||
bool Macs2OptionsWidget::save() {
|
||||
if (_translationPopUp) {
|
||||
const uint32 selected = _translationPopUp->getSelectedTag();
|
||||
if (selected > 0 && selected <= _translationPackages.size())
|
||||
ConfMan.set(kTranslationConfigKey, _translationPackages[selected - 1].code, _domain);
|
||||
else
|
||||
ConfMan.removeKey(kTranslationConfigKey, _domain);
|
||||
}
|
||||
|
||||
ConfMan.setBool("original_menus", _originalMenusCheckbox->getState(), _domain);
|
||||
|
||||
#ifdef USE_TTS
|
||||
@@ -153,7 +184,14 @@ bool Macs2OptionsWidget::save() {
|
||||
void Macs2OptionsWidget::defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const {
|
||||
layouts.addDialog(layoutName, overlayedLayout)
|
||||
.addLayout(GUI::ThemeLayout::kLayoutVertical, 5)
|
||||
.addPadding(0, 0, 0, 0)
|
||||
.addPadding(0, 0, 0, 0);
|
||||
if (_translationPopUp) {
|
||||
layouts.addLayout(GUI::ThemeLayout::kLayoutHorizontal)
|
||||
.addWidget("translationLabel", "OptionsLabel")
|
||||
.addWidget("translation", "PopUp")
|
||||
.closeLayout();
|
||||
}
|
||||
layouts
|
||||
.addWidget("originalMenus", "Checkbox")
|
||||
#ifdef USE_TTS
|
||||
.addWidget("ttsEnabled", "Checkbox")
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include "gui/ThemeEval.h"
|
||||
#include "gui/widget.h"
|
||||
#include "gui/widgets/popup.h"
|
||||
#include "macs2/translation.h"
|
||||
|
||||
namespace Macs2 {
|
||||
|
||||
@@ -46,6 +48,8 @@ private:
|
||||
void defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const override;
|
||||
|
||||
GUI::CheckboxWidget *_originalMenusCheckbox = nullptr;
|
||||
GUI::PopUpWidget *_translationPopUp = nullptr;
|
||||
Common::Array<TranslationPackage> _translationPackages;
|
||||
#ifdef USE_TTS
|
||||
GUI::CheckboxWidget *_ttsCheckbox = nullptr;
|
||||
#endif
|
||||
|
||||
+36
-19
@@ -48,6 +48,7 @@
|
||||
#include "macs2/detection.h"
|
||||
#include "macs2/hotspot_names.h"
|
||||
#include "macs2/music.h"
|
||||
#include "macs2/translation.h"
|
||||
#include "macs2/view1.h"
|
||||
|
||||
namespace Macs2 {
|
||||
@@ -2455,9 +2456,23 @@ int Macs2Engine::computeStringIndex(Common::MemoryReadStream *stream, int target
|
||||
}
|
||||
|
||||
void Macs2Engine::loadTranslation() {
|
||||
Common::SeekableReadStream *f = SearchMan.createReadStreamForMember("macs2_translation.dat");
|
||||
const Common::String code = ConfMan.get(kTranslationConfigKey);
|
||||
if (code.empty() || isAmiga())
|
||||
return;
|
||||
|
||||
const Common::FSNode gameDataDir(ConfMan.getPath("path"));
|
||||
const Common::Array<TranslationPackage> packages = listTranslationPackages(gameDataDir, getGameId());
|
||||
Common::String fileName;
|
||||
for (const TranslationPackage &package : packages) {
|
||||
if (package.code.equalsIgnoreCase(code)) {
|
||||
fileName = package.fileName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *f = fileName.empty() ? nullptr : gameDataDir.getChild(fileName).createReadStream();
|
||||
if (!f) {
|
||||
warning("Cannot open macs2_translation.dat");
|
||||
warning("Cannot open %s translation package for '%s'", getGameId().c_str(), code.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2465,14 +2480,14 @@ void Macs2Engine::loadTranslation() {
|
||||
char magic[4];
|
||||
f->read(magic, 4);
|
||||
if (memcmp(magic, "MCS2", 4) != 0) {
|
||||
warning("Invalid macs2_translation.dat magic");
|
||||
warning("Invalid %s magic", fileName.c_str());
|
||||
delete f;
|
||||
return;
|
||||
}
|
||||
|
||||
const uint16 version = f->readUint16LE();
|
||||
if (version != 1) {
|
||||
warning("Unsupported macs2_translation.dat version %u", version);
|
||||
warning("Unsupported %s version %u", fileName.c_str(), version);
|
||||
delete f;
|
||||
return;
|
||||
}
|
||||
@@ -2515,7 +2530,7 @@ void Macs2Engine::loadTranslation() {
|
||||
for (uint16 k = 0; k < len; k++) {
|
||||
s += (char)f->readByte();
|
||||
}
|
||||
entry.strings.push_back(s);
|
||||
entry.strings.push_back(normalizeTranslationString(s));
|
||||
}
|
||||
stringDataEnd = MAX(stringDataEnd, (uint32)f->pos());
|
||||
_sceneTranslations[sceneIndex[i].id] = entry;
|
||||
@@ -2531,7 +2546,7 @@ void Macs2Engine::loadTranslation() {
|
||||
for (uint16 k = 0; k < len; k++) {
|
||||
s += (char)f->readByte();
|
||||
}
|
||||
entry.strings.push_back(s);
|
||||
entry.strings.push_back(normalizeTranslationString(s));
|
||||
}
|
||||
stringDataEnd = MAX(stringDataEnd, (uint32)f->pos());
|
||||
_objectTranslations[objectIndex[i].id] = entry;
|
||||
@@ -2550,7 +2565,7 @@ void Macs2Engine::loadTranslation() {
|
||||
val += (char)f->readByte();
|
||||
}
|
||||
if (!key.empty() && !val.empty()) {
|
||||
out[key] = val;
|
||||
out[key] = normalizeTranslationString(val);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -2564,12 +2579,12 @@ void Macs2Engine::loadTranslation() {
|
||||
readLabelMap(numUiLabels, _uiLabelTranslations);
|
||||
|
||||
delete f;
|
||||
debug("Loaded macs2_translation.dat: %u scenes, %u objects, %u overlay labels, %u UI labels",
|
||||
numScenes, numObjects, (uint)_hotspotLabelTranslations.size(), (uint)_uiLabelTranslations.size());
|
||||
debug("Loaded %s: %u scenes, %u objects, %u overlay labels, %u UI labels",
|
||||
fileName.c_str(), numScenes, numObjects, (uint)_hotspotLabelTranslations.size(), (uint)_uiLabelTranslations.size());
|
||||
}
|
||||
|
||||
Common::String Macs2Engine::translateHotspotLabel(const Common::String &cp850Name) const {
|
||||
if (cp850Name.empty() || !(getFeatures() & GF_TRANSLATED)) {
|
||||
if (cp850Name.empty()) {
|
||||
return cp850Name;
|
||||
}
|
||||
auto it = _hotspotLabelTranslations.find(cp850Name);
|
||||
@@ -2580,7 +2595,7 @@ Common::String Macs2Engine::translateHotspotLabel(const Common::String &cp850Nam
|
||||
}
|
||||
|
||||
Common::String Macs2Engine::translateUiLabel(const Common::String &source) const {
|
||||
if (source.empty() || !(getFeatures() & GF_TRANSLATED)) {
|
||||
if (source.empty()) {
|
||||
return source;
|
||||
}
|
||||
auto it = _uiLabelTranslations.find(source);
|
||||
@@ -2620,17 +2635,22 @@ Common::StringArray Macs2Engine::decodeStrings(Common::MemoryReadStream *stream,
|
||||
}
|
||||
|
||||
// Apply translation if available
|
||||
if (getFeatures() & GF_TRANSLATED) {
|
||||
if (!_sceneTranslations.empty() || !_objectTranslations.empty()) {
|
||||
const int baseIndex = computeStringIndex(stream, offset);
|
||||
const TranslationEntry *entry = nullptr;
|
||||
if (objectId != 0 && _objectTranslations.contains(objectId)) {
|
||||
entry = &_objectTranslations[objectId];
|
||||
const int translationObjectId = isDemo() ? remapDemoTranslationObjectId(objectId) : objectId;
|
||||
bool sceneTranslation = false;
|
||||
if (translationObjectId != 0 && _objectTranslations.contains(translationObjectId)) {
|
||||
entry = &_objectTranslations[translationObjectId];
|
||||
} else if (sceneId != 0 && _sceneTranslations.contains(sceneId)) {
|
||||
entry = &_sceneTranslations[sceneId];
|
||||
sceneTranslation = true;
|
||||
}
|
||||
if (entry) {
|
||||
for (int i = 0; i < numStrings; i++) {
|
||||
const int idx = baseIndex + i;
|
||||
int idx = baseIndex + i;
|
||||
if (isDemo() && sceneTranslation)
|
||||
idx = remapDemoTranslationSceneStringIndex(sceneId, idx);
|
||||
if (idx >= 0 && idx < (int)entry->strings.size() && !entry->strings[idx].empty()) {
|
||||
result[i] = entry->strings[idx];
|
||||
}
|
||||
@@ -3026,10 +3046,7 @@ Common::Error Macs2Engine::run() {
|
||||
loadBootstrapResources();
|
||||
initInventoryIconIndices();
|
||||
|
||||
// Load translation data if available
|
||||
if (getFeatures() & GF_TRANSLATED) {
|
||||
loadTranslation();
|
||||
}
|
||||
loadTranslation();
|
||||
|
||||
// Initialize graphics mode (taller framebuffer when action bar verb UI is enabled)
|
||||
int gfxH = screenHeight();
|
||||
|
||||
@@ -18,6 +18,7 @@ MODULE_OBJS = \
|
||||
saveload.o \
|
||||
scriptexecutor.o \
|
||||
text.o \
|
||||
translation.o \
|
||||
actionbar.o \
|
||||
view1.o
|
||||
|
||||
|
||||
@@ -52,6 +52,21 @@ bool Text::findGlyph(char c, GlyphData &out, const GlyphData *glyphs, uint16 num
|
||||
}
|
||||
|
||||
void Text::addDialogueFontFallbacks() {
|
||||
GlyphData existingPunctuation, colon, comma;
|
||||
if (_numGlyphs < kMaxGlyphs && !findGlyph(';', existingPunctuation) &&
|
||||
findGlyph(':', colon) && findGlyph(',', comma) &&
|
||||
colon._width == comma._width && colon._height > comma._height / 2) {
|
||||
// Combine the colon's upper dot with the comma's tail.
|
||||
GlyphData &semicolon = _glyphs[_numGlyphs++];
|
||||
semicolon = comma;
|
||||
semicolon._ascii = ';';
|
||||
const uint rows = comma._height / 2 + 1;
|
||||
for (uint y = 0; y < rows; ++y) {
|
||||
for (uint x = 0; x < comma._width; ++x)
|
||||
semicolon._data[y * comma._width + x] = colon._data[y * colon._width + x];
|
||||
}
|
||||
}
|
||||
|
||||
// Swedish CP850 characters missing from the original DOS dialogue font.
|
||||
// Match its transparent/outline/foreground palette entries and cell
|
||||
// dimensions to preserve text alignment and line spacing.
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/* 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 "macs2/translation.h"
|
||||
#include "common/algorithm.h"
|
||||
#include "common/language.h"
|
||||
#include "common/ptr.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
namespace Macs2 {
|
||||
|
||||
Common::String normalizeTranslationString(const Common::String &text) {
|
||||
Common::String result;
|
||||
for (char c : text) {
|
||||
if ((byte)c != 0xf0) // CP850 soft hyphen; also used to pad unused dialogue lines.
|
||||
result += c;
|
||||
}
|
||||
// An empty DAT entry falls back to German; keep an intentional blank nonempty.
|
||||
if (!text.empty() && result.empty())
|
||||
result = " ";
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16 remapDemoTranslationObjectId(uint16 objectId) {
|
||||
// The DOS demo renumbers inventory objects, retaining the NPC IDs.
|
||||
static const uint16 fullGameIds[] = {
|
||||
0, 1, 85, 87, 96, 97, 6, 98, 99, 101, 102, 103, 12, 107, 108, 15,
|
||||
109, 113, 114, 19, 115, 117, 118, 119, 120, 126, 130, 134, 138, 139, 141
|
||||
};
|
||||
return objectId < ARRAYSIZE(fullGameIds) ? fullGameIds[objectId] : objectId;
|
||||
}
|
||||
|
||||
int remapDemoTranslationSceneStringIndex(int sceneId, int stringIndex) {
|
||||
// The DOS demo omits some full-game dialogue and inserts a chapter-end message.
|
||||
if (sceneId == 30 && stringIndex == 249)
|
||||
return -1;
|
||||
|
||||
static const struct {
|
||||
int sceneId;
|
||||
int firstString;
|
||||
int offset;
|
||||
} ranges[] = {
|
||||
{30, 250, -1}, {30, 297, 1}, {30, 299, 3}, {30, 304, 5},
|
||||
{30, 308, 23}, {30, 313, 26}, {30, 318, 32},
|
||||
{31, 77, 17}, {31, 80, 25},
|
||||
{32, 3, 2}, {32, 4, 5}, {32, 66, 10}, {32, 70, 17},
|
||||
{32, 73, 21}, {32, 75, 25},
|
||||
{33, 6, 3}, {33, 82, 11}
|
||||
};
|
||||
int offset = 0;
|
||||
for (const auto &range : ranges) {
|
||||
if (range.sceneId == sceneId && stringIndex >= range.firstString)
|
||||
offset = range.offset;
|
||||
}
|
||||
return stringIndex + offset;
|
||||
}
|
||||
|
||||
Common::Array<TranslationPackage> listTranslationPackages(const Common::FSNode &gameDataDir, const Common::String &gameId) {
|
||||
Common::Array<TranslationPackage> packages;
|
||||
Common::FSList files;
|
||||
if (!gameDataDir.getChildren(files, Common::FSNode::kListFilesOnly))
|
||||
return packages;
|
||||
|
||||
Common::String prefix = gameId + "-translation-";
|
||||
prefix.toLowercase();
|
||||
const Common::String suffix = ".dat";
|
||||
for (const Common::FSNode &file : files) {
|
||||
Common::String name = file.getName();
|
||||
name.toLowercase();
|
||||
if (!name.hasPrefix(prefix) || !name.hasSuffix(suffix))
|
||||
continue;
|
||||
|
||||
const Common::String code = name.substr(prefix.size(), name.size() - prefix.size() - suffix.size());
|
||||
if (code.empty())
|
||||
continue;
|
||||
|
||||
Common::ScopedPtr<Common::SeekableReadStream> stream(file.createReadStream());
|
||||
if (!stream || stream->size() < 14 || stream->readUint32BE() != MKTAG('M', 'C', 'S', '2') || stream->readUint16LE() != 1)
|
||||
continue;
|
||||
|
||||
TranslationPackage package;
|
||||
package.code = code;
|
||||
const char *description = Common::getLanguageDescription(Common::parseLanguage(code));
|
||||
package.displayName = description ? description : code;
|
||||
package.fileName = file.getName();
|
||||
packages.push_back(package);
|
||||
}
|
||||
|
||||
Common::sort(packages.begin(), packages.end(), [](const TranslationPackage &a, const TranslationPackage &b) {
|
||||
return a.code < b.code;
|
||||
});
|
||||
return packages;
|
||||
}
|
||||
|
||||
} // End of namespace Macs2
|
||||
@@ -0,0 +1,46 @@
|
||||
/* 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 MACS2_TRANSLATION_H
|
||||
#define MACS2_TRANSLATION_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/fs.h"
|
||||
#include "common/str.h"
|
||||
|
||||
namespace Macs2 {
|
||||
|
||||
static const char *const kTranslationConfigKey = "macs2_translation";
|
||||
|
||||
struct TranslationPackage {
|
||||
Common::String code;
|
||||
Common::String displayName;
|
||||
Common::String fileName;
|
||||
};
|
||||
|
||||
Common::Array<TranslationPackage> listTranslationPackages(const Common::FSNode &gameDataDir, const Common::String &gameId);
|
||||
Common::String normalizeTranslationString(const Common::String &text);
|
||||
uint16 remapDemoTranslationObjectId(uint16 objectId);
|
||||
int remapDemoTranslationSceneStringIndex(int sceneId, int stringIndex);
|
||||
|
||||
} // End of namespace Macs2
|
||||
|
||||
#endif // MACS2_TRANSLATION_H
|
||||
Reference in new issue
Block a user