SCI: Improved multilanguage support for SCI1 and SCI1.1.
svn-id: r43217
This commit is contained in:
parent
bd71d79e73
commit
dd9e569325
7 changed files with 86 additions and 13 deletions
|
@ -497,6 +497,9 @@ int game_init(EngineState *s) {
|
||||||
if (s->sfx_init_flags & SFX_STATE_FLAG_NOSOUND)
|
if (s->sfx_init_flags & SFX_STATE_FLAG_NOSOUND)
|
||||||
game_init_sound(s, 0);
|
game_init_sound(s, 0);
|
||||||
|
|
||||||
|
// Load game language into printLang property of game object
|
||||||
|
s->getLanguage();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -320,6 +320,7 @@ SciKernelFunction kfunct_mappers[] = {
|
||||||
/*(?)*/ DEFUN("Lock", kLock, "iii*"),
|
/*(?)*/ DEFUN("Lock", kLock, "iii*"),
|
||||||
/*(?)*/ DEFUN("Palette", kPalette, "i.*"),
|
/*(?)*/ DEFUN("Palette", kPalette, "i.*"),
|
||||||
/*(?)*/ DEFUN("IsItSkip", kIsItSkip, "iiiii"),
|
/*(?)*/ DEFUN("IsItSkip", kIsItSkip, "iiiii"),
|
||||||
|
/*7b*/ DEFUN("StrSplit", kStrSplit, "rrZr"),
|
||||||
|
|
||||||
// Non-experimental Functions without a fixed ID
|
// Non-experimental Functions without a fixed ID
|
||||||
DEFUN("CosMult", kTimesCos, "ii"),
|
DEFUN("CosMult", kTimesCos, "ii"),
|
||||||
|
@ -345,7 +346,6 @@ SciKernelFunction kfunct_mappers[] = {
|
||||||
DEFUN("MemorySegment", kStub, ".*"),
|
DEFUN("MemorySegment", kStub, ".*"),
|
||||||
DEFUN("ListOps", kStub, ".*"),
|
DEFUN("ListOps", kStub, ".*"),
|
||||||
DEFUN("ATan", kStub, ".*"),
|
DEFUN("ATan", kStub, ".*"),
|
||||||
DEFUN("StrSplit", kStub, ".*"),
|
|
||||||
DEFUN("MergePoly", kStub, ".*"),
|
DEFUN("MergePoly", kStub, ".*"),
|
||||||
DEFUN("AssertPalette", kStub, ".*"),
|
DEFUN("AssertPalette", kStub, ".*"),
|
||||||
DEFUN("TextColors", kStub, ".*"),
|
DEFUN("TextColors", kStub, ".*"),
|
||||||
|
|
|
@ -540,6 +540,7 @@ reg_t kResCheck(EngineState *s, int funct_nr, int argc, reg_t *argv);
|
||||||
reg_t kSetQuitStr(EngineState *s, int funct_nr, int argc, reg_t *argv);
|
reg_t kSetQuitStr(EngineState *s, int funct_nr, int argc, reg_t *argv);
|
||||||
reg_t kShowMovie(EngineState *s, int funct_nr, int argc, reg_t *argv);
|
reg_t kShowMovie(EngineState *s, int funct_nr, int argc, reg_t *argv);
|
||||||
reg_t kSetVideoMode(EngineState *s, int funct_nr, int argc, reg_t *argv);
|
reg_t kSetVideoMode(EngineState *s, int funct_nr, int argc, reg_t *argv);
|
||||||
|
reg_t kStrSplit(EngineState *s, int funct_nr, int argc, reg_t *argv);
|
||||||
reg_t k_Unknown(EngineState *s, int funct_nr, int argc, reg_t *argv);
|
reg_t k_Unknown(EngineState *s, int funct_nr, int argc, reg_t *argv);
|
||||||
|
|
||||||
// The Unknown/Unnamed kernel function
|
// The Unknown/Unnamed kernel function
|
||||||
|
|
|
@ -812,4 +812,21 @@ reg_t kSetQuitStr(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
return s->r_acc;
|
return s->r_acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reg_t kStrSplit(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
|
const char *format = kernel_dereference_char_pointer(s, argv[1], 0);
|
||||||
|
const char *sep = !argv[2].isNull() ? kernel_dereference_char_pointer(s, argv[2], 0) : NULL;
|
||||||
|
Common::String str = s->strSplit(format, sep);
|
||||||
|
|
||||||
|
// Make sure target buffer is large enough
|
||||||
|
char *buf = kernel_dereference_char_pointer(s, argv[0], str.size() + 1);
|
||||||
|
|
||||||
|
if (buf) {
|
||||||
|
strcpy(buf, str.c_str());
|
||||||
|
return argv[0];
|
||||||
|
} else {
|
||||||
|
warning("StrSplit: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(argv[0]), str.size() + 1, str.c_str());
|
||||||
|
return NULL_REG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
|
@ -33,7 +33,7 @@ MessageTuple MessageState::getTuple() {
|
||||||
|
|
||||||
t.noun = *(_engineCursor.index_record + 0);
|
t.noun = *(_engineCursor.index_record + 0);
|
||||||
t.verb = *(_engineCursor.index_record + 1);
|
t.verb = *(_engineCursor.index_record + 1);
|
||||||
if (_version == 2101) {
|
if (_version == 2) {
|
||||||
t.cond = 0;
|
t.cond = 0;
|
||||||
t.seq = 1;
|
t.seq = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -47,7 +47,7 @@ MessageTuple MessageState::getTuple() {
|
||||||
MessageTuple MessageState::getRefTuple() {
|
MessageTuple MessageState::getRefTuple() {
|
||||||
MessageTuple t;
|
MessageTuple t;
|
||||||
|
|
||||||
if (_version == 2101) {
|
if (_version == 2) {
|
||||||
t.noun = 0;
|
t.noun = 0;
|
||||||
t.verb = 0;
|
t.verb = 0;
|
||||||
t.cond = 0;
|
t.cond = 0;
|
||||||
|
@ -68,7 +68,7 @@ void MessageState::initCursor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageState::advanceCursor(bool increaseSeq) {
|
void MessageState::advanceCursor(bool increaseSeq) {
|
||||||
_engineCursor.index_record += ((_version == 2101) ? 4 : 11);
|
_engineCursor.index_record += ((_version == 2) ? 4 : 11);
|
||||||
_engineCursor.index++;
|
_engineCursor.index++;
|
||||||
|
|
||||||
if (increaseSeq)
|
if (increaseSeq)
|
||||||
|
@ -142,7 +142,7 @@ int MessageState::getMessage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int MessageState::getTalker() {
|
int MessageState::getTalker() {
|
||||||
return (_version == 2101) ? -1 : *(_engineCursor.index_record + 4);
|
return (_version == 2) ? -1 : *(_engineCursor.index_record + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageTuple &MessageState::getLastTuple() {
|
MessageTuple &MessageState::getLastTuple() {
|
||||||
|
@ -154,7 +154,7 @@ int MessageState::getLastModule() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::String MessageState::getText() {
|
Common::String MessageState::getText() {
|
||||||
char *str = (char *)_currentResource->data + READ_LE_UINT16(_engineCursor.index_record + ((_version == 2101) ? 2 : 5));
|
char *str = (char *)_currentResource->data + READ_LE_UINT16(_engineCursor.index_record + ((_version == 2) ? 2 : 5));
|
||||||
|
|
||||||
Common::String strippedStr;
|
Common::String strippedStr;
|
||||||
Common::String skippedSubstr;
|
Common::String skippedSubstr;
|
||||||
|
@ -215,7 +215,7 @@ void MessageState::gotoNext() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int MessageState::getLength() {
|
int MessageState::getLength() {
|
||||||
int offset = READ_LE_UINT16(_engineCursor.index_record + ((_version == 2101) ? 2 : 5));
|
int offset = READ_LE_UINT16(_engineCursor.index_record + ((_version == 2) ? 2 : 5));
|
||||||
char *stringptr = (char *)_currentResource->data + offset;
|
char *stringptr = (char *)_currentResource->data + offset;
|
||||||
return strlen(stringptr);
|
return strlen(stringptr);
|
||||||
}
|
}
|
||||||
|
@ -244,8 +244,12 @@ int MessageState::loadRes(ResourceManager *resmgr, int module, bool lock) {
|
||||||
_locked = lock;
|
_locked = lock;
|
||||||
|
|
||||||
_version = READ_LE_UINT16(_currentResource->data);
|
_version = READ_LE_UINT16(_currentResource->data);
|
||||||
|
debug(5, "Message: reading resource %d.msg, version %d.%03d", _module, _version / 1000, _version % 1000);
|
||||||
|
|
||||||
int offs = (_version == 2101) ? 0 : 4;
|
// We assume for now that storing the major version is sufficient
|
||||||
|
_version /= 1000;
|
||||||
|
|
||||||
|
int offs = (_version == 2) ? 0 : 4;
|
||||||
_recordCount = READ_LE_UINT16(_currentResource->data + 4 + offs);
|
_recordCount = READ_LE_UINT16(_currentResource->data + 4 + offs);
|
||||||
_indexRecords = _currentResource->data + 6 + offs;
|
_indexRecords = _currentResource->data + 6 + offs;
|
||||||
|
|
||||||
|
|
|
@ -172,15 +172,62 @@ Common::String EngineState::getLanguageString(const char *str, kLanguage lang) c
|
||||||
return Common::String(str);
|
return Common::String(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kLanguage EngineState::getLanguage() {
|
||||||
|
kLanguage lang = K_LANG_ENGLISH;
|
||||||
|
|
||||||
|
if (((SciEngine*)g_engine)->getKernel()->_selectorMap.printLang != -1) {
|
||||||
|
EngineState *s = this;
|
||||||
|
|
||||||
|
lang = (kLanguage)GET_SEL32V(s->game_obj, printLang);
|
||||||
|
|
||||||
|
if ((_version == SCI_VERSION_1_1) || (lang == K_LANG_NONE)) {
|
||||||
|
// If language is set to none, we use the language from the game detector.
|
||||||
|
// SSCI reads this from resource.cfg (early games do not have a language
|
||||||
|
// setting in resource.cfg, but instead have the secondary language number
|
||||||
|
// hardcoded in the game script).
|
||||||
|
// SCI1.1 games always use the language setting from the config file
|
||||||
|
// (essentially disabling runtime language switching).
|
||||||
|
// Note: only a limited number of multilanguage games have been tested
|
||||||
|
// so far, so this information may not be 100% accurate.
|
||||||
|
switch (((Sci::SciEngine*)g_engine)->getLanguage()) {
|
||||||
|
case Common::FR_FRA:
|
||||||
|
lang = K_LANG_FRENCH;
|
||||||
|
break;
|
||||||
|
case Common::ES_ESP:
|
||||||
|
lang = K_LANG_SPANISH;
|
||||||
|
break;
|
||||||
|
case Common::IT_ITA:
|
||||||
|
lang = K_LANG_ITALIAN;
|
||||||
|
break;
|
||||||
|
case Common::DE_DEU:
|
||||||
|
lang = K_LANG_GERMAN;
|
||||||
|
break;
|
||||||
|
case Common::JA_JPN:
|
||||||
|
lang = K_LANG_JAPANESE;
|
||||||
|
break;
|
||||||
|
case Common::PT_BRA:
|
||||||
|
lang = K_LANG_PORTUGUESE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
lang = K_LANG_ENGLISH;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store language in printLang selector
|
||||||
|
PUT_SEL32V(s->game_obj, printLang, lang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lang;
|
||||||
|
}
|
||||||
|
|
||||||
Common::String EngineState::strSplit(const char *str, const char *sep) {
|
Common::String EngineState::strSplit(const char *str, const char *sep) {
|
||||||
EngineState *s = this;
|
EngineState *s = this;
|
||||||
|
|
||||||
kLanguage lang = (kLanguage)GET_SEL32V(s->game_obj, printLang);
|
kLanguage lang = getLanguage();
|
||||||
kLanguage subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang);
|
kLanguage subLang = K_LANG_NONE;
|
||||||
|
|
||||||
// Use English when no language settings are present in the game
|
if (((SciEngine*)g_engine)->getKernel()->_selectorMap.subtitleLang != -1)
|
||||||
if (lang == K_LANG_NONE)
|
subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang);
|
||||||
lang = K_LANG_ENGLISH;
|
|
||||||
|
|
||||||
Common::String retval = getLanguageString(str, lang);
|
Common::String retval = getLanguageString(str, lang);
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,7 @@ public:
|
||||||
virtual ~EngineState();
|
virtual ~EngineState();
|
||||||
virtual void saveLoadWithSerializer(Common::Serializer &ser);
|
virtual void saveLoadWithSerializer(Common::Serializer &ser);
|
||||||
|
|
||||||
|
kLanguage getLanguage();
|
||||||
public:
|
public:
|
||||||
int widget_serial_counter; /**< Used for savegames */
|
int widget_serial_counter; /**< Used for savegames */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue