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)
|
||||
game_init_sound(s, 0);
|
||||
|
||||
// Load game language into printLang property of game object
|
||||
s->getLanguage();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -320,6 +320,7 @@ SciKernelFunction kfunct_mappers[] = {
|
|||
/*(?)*/ DEFUN("Lock", kLock, "iii*"),
|
||||
/*(?)*/ DEFUN("Palette", kPalette, "i.*"),
|
||||
/*(?)*/ DEFUN("IsItSkip", kIsItSkip, "iiiii"),
|
||||
/*7b*/ DEFUN("StrSplit", kStrSplit, "rrZr"),
|
||||
|
||||
// Non-experimental Functions without a fixed ID
|
||||
DEFUN("CosMult", kTimesCos, "ii"),
|
||||
|
@ -345,7 +346,6 @@ SciKernelFunction kfunct_mappers[] = {
|
|||
DEFUN("MemorySegment", kStub, ".*"),
|
||||
DEFUN("ListOps", kStub, ".*"),
|
||||
DEFUN("ATan", kStub, ".*"),
|
||||
DEFUN("StrSplit", kStub, ".*"),
|
||||
DEFUN("MergePoly", kStub, ".*"),
|
||||
DEFUN("AssertPalette", 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 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 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);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -33,7 +33,7 @@ MessageTuple MessageState::getTuple() {
|
|||
|
||||
t.noun = *(_engineCursor.index_record + 0);
|
||||
t.verb = *(_engineCursor.index_record + 1);
|
||||
if (_version == 2101) {
|
||||
if (_version == 2) {
|
||||
t.cond = 0;
|
||||
t.seq = 1;
|
||||
} else {
|
||||
|
@ -47,7 +47,7 @@ MessageTuple MessageState::getTuple() {
|
|||
MessageTuple MessageState::getRefTuple() {
|
||||
MessageTuple t;
|
||||
|
||||
if (_version == 2101) {
|
||||
if (_version == 2) {
|
||||
t.noun = 0;
|
||||
t.verb = 0;
|
||||
t.cond = 0;
|
||||
|
@ -68,7 +68,7 @@ void MessageState::initCursor() {
|
|||
}
|
||||
|
||||
void MessageState::advanceCursor(bool increaseSeq) {
|
||||
_engineCursor.index_record += ((_version == 2101) ? 4 : 11);
|
||||
_engineCursor.index_record += ((_version == 2) ? 4 : 11);
|
||||
_engineCursor.index++;
|
||||
|
||||
if (increaseSeq)
|
||||
|
@ -142,7 +142,7 @@ int MessageState::getMessage() {
|
|||
}
|
||||
|
||||
int MessageState::getTalker() {
|
||||
return (_version == 2101) ? -1 : *(_engineCursor.index_record + 4);
|
||||
return (_version == 2) ? -1 : *(_engineCursor.index_record + 4);
|
||||
}
|
||||
|
||||
MessageTuple &MessageState::getLastTuple() {
|
||||
|
@ -154,7 +154,7 @@ int MessageState::getLastModule() {
|
|||
}
|
||||
|
||||
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 skippedSubstr;
|
||||
|
@ -215,7 +215,7 @@ void MessageState::gotoNext() {
|
|||
}
|
||||
|
||||
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;
|
||||
return strlen(stringptr);
|
||||
}
|
||||
|
@ -244,8 +244,12 @@ int MessageState::loadRes(ResourceManager *resmgr, int module, bool lock) {
|
|||
_locked = lock;
|
||||
|
||||
_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);
|
||||
_indexRecords = _currentResource->data + 6 + offs;
|
||||
|
||||
|
|
|
@ -172,15 +172,62 @@ Common::String EngineState::getLanguageString(const char *str, kLanguage lang) c
|
|||
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) {
|
||||
EngineState *s = this;
|
||||
|
||||
kLanguage lang = (kLanguage)GET_SEL32V(s->game_obj, printLang);
|
||||
kLanguage subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang);
|
||||
kLanguage lang = getLanguage();
|
||||
kLanguage subLang = K_LANG_NONE;
|
||||
|
||||
// Use English when no language settings are present in the game
|
||||
if (lang == K_LANG_NONE)
|
||||
lang = K_LANG_ENGLISH;
|
||||
if (((SciEngine*)g_engine)->getKernel()->_selectorMap.subtitleLang != -1)
|
||||
subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang);
|
||||
|
||||
Common::String retval = getLanguageString(str, lang);
|
||||
|
||||
|
|
|
@ -125,6 +125,7 @@ public:
|
|||
virtual ~EngineState();
|
||||
virtual void saveLoadWithSerializer(Common::Serializer &ser);
|
||||
|
||||
kLanguage getLanguage();
|
||||
public:
|
||||
int widget_serial_counter; /**< Used for savegames */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue