void R_ParseTrnslate() { customTranslationMap.Clear(); translationtables[TRANSLATION_Custom].Clear(); int lump; int lastlump = 0; while (-1 != (lump = Wads.FindLump("TRNSLATE", &lastlump))) { FScanner sc(lump); while (sc.GetToken()) { sc.TokenMustBe(TK_Identifier); FName newtrans = sc.String; FRemapTable *base = nullptr; if (sc.CheckToken(':')) { sc.MustGetAnyToken(); if (sc.TokenType == TK_IntConst) { int max = 6; if (sc.Number < 0 || sc.Number > max) { sc.ScriptError("Translation must be in the range [0,%d]", max); } base = translationtables[TRANSLATION_Standard][sc.Number]; } else if (sc.TokenType == TK_Identifier) { int tnum = R_FindCustomTranslation(sc.String); if (tnum == -1) { sc.ScriptError("Base translation '%s' not found in '%s'", sc.String, newtrans.GetChars()); } base = translationtables[GetTranslationType(tnum)][GetTranslationIndex(tnum)]; } else { // error out. sc.TokenMustBe(TK_Identifier); } } sc.MustGetToken('='); FRemapTable NewTranslation; if (base != nullptr) NewTranslation = *base; else NewTranslation.MakeIdentity(); do { sc.MustGetToken(TK_StringConst); NewTranslation.AddToTranslation(sc.String); } while (sc.CheckToken(',')); int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom); customTranslationMap[newtrans] = trans; } } }
FRemapTable *TranslationToTable(int translation) { unsigned int type = GetTranslationType(translation); unsigned int index = GetTranslationIndex(translation); TAutoGrowArray<FRemapTablePtr, FRemapTable *> *slots; if (type <= 0 || type >= NUM_TRANSLATION_TABLES) { return NULL; } slots = &translationtables[type]; if (index >= slots->Size()) { return NULL; } return slots->operator[](index); }
void DIntermissionScreenCast::Init(FIntermissionAction *desc, bool first) { Super::Init(desc, first); mName = static_cast<FIntermissionActionCast*>(desc)->mName; mClass = PClass::FindClass(static_cast<FIntermissionActionCast*>(desc)->mCastClass); if (mClass != NULL) mDefaults = GetDefaultByType(mClass); else { mDefaults = NULL; caststate = NULL; return; } mCastSounds.Resize(static_cast<FIntermissionActionCast*>(desc)->mCastSounds.Size()); for (unsigned i=0; i < mCastSounds.Size(); i++) { mCastSounds[i].mSequence = static_cast<FIntermissionActionCast*>(desc)->mCastSounds[i].mSequence; mCastSounds[i].mIndex = static_cast<FIntermissionActionCast*>(desc)->mCastSounds[i].mIndex; mCastSounds[i].mSound = static_cast<FIntermissionActionCast*>(desc)->mCastSounds[i].mSound; } caststate = mDefaults->SeeState; if (mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn))) { advplayerstate = mDefaults->MissileState; casttranslation = translationtables[TRANSLATION_Players][consoleplayer]; } else { advplayerstate = NULL; casttranslation = NULL; if (mDefaults->Translation != 0) { casttranslation = translationtables[GetTranslationType(mDefaults->Translation)] [GetTranslationIndex(mDefaults->Translation)]; } } castdeath = false; castframes = 0; castonmelee = 0; castattacking = false; if (mDefaults->SeeSound) { S_Sound (CHAN_VOICE | CHAN_UI, mDefaults->SeeSound, 1, ATTN_NONE); } }
// Return a properly encoded version of a translation for 'txt'. // Memory for the string needs to be allocated and is cached in gTranslationCache // array. That way the client doesn't have to worry about the lifetime of the string. // All allocated strings can be freed with Trans::FreeData(), which should be // done at program exit so that we're guaranteed no-one is using the data const WCHAR *GetTranslation(const char *txt) { if (!gTranslationCache) { assert(dimof(gTranslations) == STRINGS_COUNT * LANGS_COUNT); gTranslationCache = AllocArray<const WCHAR *>(dimof(gTranslations)); if (!gTranslationCache) return L"Missing translation!?"; } int idx = GetTranslationIndex(txt); if (-1 == idx) return FindOrAddMissingTranslation(txt); int transIdx = (gCurrLangIdx * STRINGS_COUNT) + idx; // fall back to the English string, if a translation is missing if (!gTranslations[transIdx]) transIdx = idx; if (!gTranslationCache[transIdx]) gTranslationCache[transIdx] = str::conv::FromUtf8(gTranslations[transIdx]); return gTranslationCache[transIdx]; }
// Return a properly encoded version of a translation for 'txt'. // Memory for the string needs to be allocated and is cached in gTranslationCache // array. That way the client doesn't have to worry about the lifetime of the string. // All allocated strings can be freed with Trans::FreeData(), which should be // done at program exit so that we're guaranteed no-one is using the data const TCHAR *GetTranslation(const char *txt) { if (!gTranslationCache) { assert(dimof(gTranslations) == STRINGS_COUNT * LANGS_COUNT); gTranslationCache = SAZA(const TCHAR *, dimof(gTranslations)); if (!gTranslationCache) return _T("Missing translation!?"); _onexit(FreeData); } int idx = GetTranslationIndex(txt); assert((idx >= 0) && (idx < STRINGS_COUNT)); if (-1 == idx) return _T("Missing translation!?"); int transIdx = (gCurrLangIdx * STRINGS_COUNT) + idx; // fall back to the English string, if a translation is missing if (!gTranslations[transIdx]) transIdx = idx; if (!gTranslationCache[transIdx]) gTranslationCache[transIdx] = str::conv::FromUtf8(gTranslations[transIdx]); return gTranslationCache[transIdx]; } // returns an arbitrary index for a given language code