diff --git a/src/core.h b/src/core.h index 20def8a..35d6aeb 100644 --- a/src/core.h +++ b/src/core.h @@ -202,7 +202,7 @@ namespace Core { #endif } support; -#define SETTINGS_VERSION 4 +#define SETTINGS_VERSION 5 #define SETTINGS_READING 0xFF struct Settings { @@ -222,7 +222,6 @@ namespace Core { uint8 quality[4]; }; uint8 simple; - uint8 subtitles; uint8 vsync; uint8 stereo; void setFilter(Quality value) { @@ -262,6 +261,8 @@ namespace Core { uint8 music; uint8 sound; uint8 reverb; + uint8 subtitles; + uint8 language; } audio; struct Controls { @@ -607,6 +608,7 @@ namespace Core { namespace Core { static const char *version = __DATE__; + static int defLang = 0; void readPerlinAsync(Stream *stream, void *userData) { int size = PERLIN_TEX_SIZE * PERLIN_TEX_SIZE * PERLIN_TEX_SIZE; @@ -729,12 +731,13 @@ namespace Core { settings.detail.setShadows (Core::Settings::HIGH); settings.detail.setWater (Core::Settings::HIGH); settings.detail.simple = false; - settings.detail.subtitles = true; settings.detail.vsync = true; settings.detail.stereo = Settings::STEREO_OFF; settings.audio.music = 14; settings.audio.sound = 14; settings.audio.reverb = true; + settings.audio.subtitles = true; + settings.audio.language = defLang; // player 1 { diff --git a/src/gameflow.h b/src/gameflow.h index dd03432..138fa56 100644 --- a/src/gameflow.h +++ b/src/gameflow.h @@ -2,6 +2,7 @@ #define H_GAMEFLOW #include "utils.h" +#include "lang.h" #define CHECK_FILE(name) if (Stream::existsContent(name)) return name @@ -190,97 +191,100 @@ namespace TR { TRACK_TR3_CUT_12 = 66, }; +// #define LEVEL (version,name,track) { #name, STR_##version##_##name, TRACK_##version##track }, +// #define CUT (version,id) { #CUT_#id, STR_##version##_##name, TRACK_##version##track }, + struct LevelInfo { const char *name; - const char *title; + StringID title; int track; } LEVEL_INFO[LVL_MAX] = { + { "" , STR_EMPTY , TRACK_TR1_CAVES }, // TR1 - { "" , "Custom Level", TRACK_TR1_CAVES }, - { "TITLE" , "", TRACK_TR1_TITLE }, - { "GYM" , "Lara's Home", NO_TRACK }, - { "LEVEL1" , "Caves", TRACK_TR1_CAVES }, - { "LEVEL2" , "City of Vilcabamba", TRACK_TR1_CAVES }, - { "LEVEL3A" , "Lost Valley", TRACK_TR1_CAVES }, - { "LEVEL3B" , "Tomb of Qualopec", TRACK_TR1_CAVES }, - { "CUT1" , "", TRACK_TR1_CUT_1 }, - { "LEVEL4" , "St. Francis' Folly", TRACK_TR1_CAVES }, - { "LEVEL5" , "Colosseum", TRACK_TR1_CAVES }, - { "LEVEL6" , "Palace Midas", TRACK_TR1_CAVES }, - { "LEVEL7A" , "The Cistern", TRACK_TR1_CISTERN }, - { "LEVEL7B" , "Tomb of Tihocan", TRACK_TR1_CISTERN }, - { "CUT2" , "", TRACK_TR1_CUT_2 }, - { "LEVEL8A" , "City of Khamoon", TRACK_TR1_EGYPT }, - { "LEVEL8B" , "Obelisk of Khamoon", TRACK_TR1_EGYPT }, - { "LEVEL8C" , "Sanctuary of the Scion", TRACK_TR1_EGYPT }, - { "LEVEL10A" , "Natla's Mines", TRACK_TR1_MINE }, - { "CUT3" , "", TRACK_TR1_CUT_3 }, - { "LEVEL10B" , "Atlantis", TRACK_TR1_MINE }, - { "CUT4" , "", TRACK_TR1_CUT_4 }, - { "LEVEL10C" , "The Great Pyramid", TRACK_TR1_MINE }, - { "EGYPT" , "Return to Egypt", TRACK_TR1_EGYPT }, - { "CAT" , "Temple of the Cat", TRACK_TR1_EGYPT }, - { "END" , "Atlantean Stronghold", TRACK_TR1_EGYPT }, - { "END2" , "The Hive", TRACK_TR1_EGYPT }, + { "TITLE" , STR_EMPTY , TRACK_TR1_TITLE }, + { "GYM" , STR_TR1_GYM , NO_TRACK }, + { "LEVEL1" , STR_TR1_LEVEL1 , TRACK_TR1_CAVES }, + { "LEVEL2" , STR_TR1_LEVEL2 , TRACK_TR1_CAVES }, + { "LEVEL3A" , STR_TR1_LEVEL3A , TRACK_TR1_CAVES }, + { "LEVEL3B" , STR_TR1_LEVEL3B , TRACK_TR1_CAVES }, + { "CUT1" , STR_EMPTY , TRACK_TR1_CUT_1 }, + { "LEVEL4" , STR_TR1_LEVEL4 , TRACK_TR1_CAVES }, + { "LEVEL5" , STR_TR1_LEVEL5 , TRACK_TR1_CAVES }, + { "LEVEL6" , STR_TR1_LEVEL6 , TRACK_TR1_CAVES }, + { "LEVEL7A" , STR_TR1_LEVEL7A , TRACK_TR1_CISTERN }, + { "LEVEL7B" , STR_TR1_LEVEL7B , TRACK_TR1_CISTERN }, + { "CUT2" , STR_EMPTY , TRACK_TR1_CUT_2 }, + { "LEVEL8A" , STR_TR1_LEVEL8A , TRACK_TR1_EGYPT }, + { "LEVEL8B" , STR_TR1_LEVEL8B , TRACK_TR1_EGYPT }, + { "LEVEL8C" , STR_TR1_LEVEL8C , TRACK_TR1_EGYPT }, + { "LEVEL10A" , STR_TR1_LEVEL10A , TRACK_TR1_MINE }, + { "CUT3" , STR_EMPTY , TRACK_TR1_CUT_3 }, + { "LEVEL10B" , STR_TR1_LEVEL10B , TRACK_TR1_MINE }, + { "CUT4" , STR_EMPTY , TRACK_TR1_CUT_4 }, + { "LEVEL10C" , STR_TR1_LEVEL10C , TRACK_TR1_MINE }, + { "EGYPT" , STR_TR1_EGYPT , TRACK_TR1_EGYPT }, + { "CAT" , STR_TR1_CAT , TRACK_TR1_EGYPT }, + { "END" , STR_TR1_END , TRACK_TR1_EGYPT }, + { "END2" , STR_TR1_END2 , TRACK_TR1_EGYPT }, // TR2 - { "TITLE" , "", TRACK_TR2_TITLE }, - { "ASSAULT" , "Lara's Home", NO_TRACK }, - { "WALL" , "The Great Wall", TRACK_TR2_CHINA_1 }, - { "CUT1" , "", TRACK_TR2_CUT_1 }, - { "BOAT" , "Venice", NO_TRACK }, - { "VENICE" , "Bartoli's Hideout", NO_TRACK }, - { "OPERA" , "Opera House", TRACK_TR2_ITALY }, - { "CUT2" , "", TRACK_TR2_CUT_2 }, - { "RIG" , "Offshore Rig", TRACK_TR2_RIG }, - { "PLATFORM" , "Diving Area", TRACK_TR2_RIG }, - { "CUT3" , "", TRACK_TR2_CUT_3 }, - { "UNWATER" , "40 Fathoms", TRACK_TR2_UNWATER_1 }, - { "KEEL" , "Wreck of the Maria Doria", TRACK_TR2_UNWATER_2 }, - { "LIVING" , "Living Quarters", TRACK_TR2_UNWATER_1 }, - { "DECK" , "The Deck", TRACK_TR2_UNWATER_2 }, - { "SKIDOO" , "Tibetan Foothills", TRACK_TR2_TIBET_1 }, - { "MONASTRY" , "Barkhang Monastery", NO_TRACK }, - { "CATACOMB" , "Catacombs of the Talion", TRACK_TR2_TIBET_2 }, - { "ICECAVE" , "Ice Palace", TRACK_TR2_TIBET_2 }, - { "EMPRTOMB" , "Temple of Xian", TRACK_TR2_CHINA_2 }, - { "CUT4" , "", TRACK_TR2_CUT_4 }, - { "FLOATING" , "Floating Islands", TRACK_TR2_CHINA_2 }, - { "XIAN" , "The Dragon's Lair", TRACK_TR2_CHINA_2 }, - { "HOUSE" , "Home Sweet Home", NO_TRACK }, + { "TITLE" , STR_EMPTY , TRACK_TR2_TITLE }, + { "ASSAULT" , STR_TR2_ASSAULT , NO_TRACK }, + { "WALL" , STR_TR2_WALL , TRACK_TR2_CHINA_1 }, + { "CUT1" , STR_EMPTY , TRACK_TR2_CUT_1 }, + { "BOAT" , STR_TR2_BOAT , NO_TRACK }, + { "VENICE" , STR_TR2_VENICE , NO_TRACK }, + { "OPERA" , STR_TR2_OPERA , TRACK_TR2_ITALY }, + { "CUT2" , STR_EMPTY , TRACK_TR2_CUT_2 }, + { "RIG" , STR_TR2_RIG , TRACK_TR2_RIG }, + { "PLATFORM" , STR_TR2_PLATFORM , TRACK_TR2_RIG }, + { "CUT3" , STR_EMPTY , TRACK_TR2_CUT_3 }, + { "UNWATER" , STR_TR2_UNWATER , TRACK_TR2_UNWATER_1 }, + { "KEEL" , STR_TR2_KEEL , TRACK_TR2_UNWATER_2 }, + { "LIVING" , STR_TR2_LIVING , TRACK_TR2_UNWATER_1 }, + { "DECK" , STR_TR2_DECK , TRACK_TR2_UNWATER_2 }, + { "SKIDOO" , STR_TR2_SKIDOO , TRACK_TR2_TIBET_1 }, + { "MONASTRY" , STR_TR2_MONASTRY , NO_TRACK }, + { "CATACOMB" , STR_TR2_CATACOMB , TRACK_TR2_TIBET_2 }, + { "ICECAVE" , STR_TR2_ICECAVE , TRACK_TR2_TIBET_2 }, + { "EMPRTOMB" , STR_TR2_EMPRTOMB , TRACK_TR2_CHINA_2 }, + { "CUT4" , STR_EMPTY , TRACK_TR2_CUT_4 }, + { "FLOATING" , STR_TR2_FLOATING , TRACK_TR2_CHINA_2 }, + { "XIAN" , STR_TR2_XIAN , TRACK_TR2_CHINA_2 }, + { "HOUSE" , STR_TR2_HOUSE , NO_TRACK }, // TR3 - { "TITLE", "", TRACK_TR3_TITLE }, - { "HOUSE", "Lara's House", NO_TRACK }, - { "JUNGLE", "Jungle", TRACK_TR3_INDIA_1 }, - { "CUT6", "", TRACK_TR3_CUT_6 }, - { "TEMPLE", "Temple Ruins", TRACK_TR3_INDIA_1 }, - { "CUT9", "", TRACK_TR3_CUT_9 }, - { "QUADCHAS", "The River Ganges", TRACK_TR3_INDIA_1 }, - { "TONYBOSS", "Caves Of Kaliya", TRACK_TR3_INDIA_2 }, - { "SHORE", "Coastal Village", TRACK_TR3_SOUTH_1 }, - { "CUT1", "", TRACK_TR3_CUT_1 }, - { "CRASH", "Crash Site", TRACK_TR3_SOUTH_2 }, - { "CUT4", "", TRACK_TR3_CUT_4 }, - { "RAPIDS", "Madubu Gorge", TRACK_TR3_SOUTH_3 }, - { "TRIBOSS", "Temple Of Puna", TRACK_TR3_CAVES }, - { "ROOFS", "Thames Wharf", TRACK_TR3_LONDON_1 }, - { "CUT2", "", TRACK_TR3_CUT_2 }, - { "SEWER", "Aldwych", TRACK_TR3_LONDON_2 }, - { "CUT5", "", TRACK_TR3_CUT_5 }, - { "TOWER", "Lud's Gate", TRACK_TR3_LONDON_3 }, - { "CUT11", "", TRACK_TR3_CUT_11 }, - { "OFFICE", "City", TRACK_TR3_LONDON_4 }, - { "NEVADA", "Nevada Desert", TRACK_TR3_NEVADA_1 }, - { "CUT7", "", TRACK_TR3_CUT_7 }, - { "COMPOUND", "High Security Compound", TRACK_TR3_NEVADA_2 }, - { "CUT8", "", TRACK_TR3_CUT_8 }, - { "AREA51", "Area 51", TRACK_TR3_NEVADA_2 }, - { "ANTARC", "Antarctica", TRACK_TR3_ANTARC_1 }, - { "CUT3", "", TRACK_TR3_CUT_3 }, - { "MINES", "RX-Tech Mines", TRACK_TR3_ANTARC_2 }, - { "CITY", "Lost City Of Tinnos", TRACK_TR3_ANTARC_3 }, - { "CUT12", "", TRACK_TR3_CUT_12 }, - { "CHAMBER", "Meteorite Cavern", TRACK_TR3_ANTARC_3 }, - { "STPAUL", "All Hallows", TRACK_TR3_CAVES }, + { "TITLE" , STR_EMPTY , TRACK_TR3_TITLE }, + { "HOUSE" , STR_TR3_HOUSE , NO_TRACK }, + { "JUNGLE" , STR_TR3_JUNGLE , TRACK_TR3_INDIA_1 }, + { "CUT6" , STR_EMPTY , TRACK_TR3_CUT_6 }, + { "TEMPLE" , STR_TR3_TEMPLE , TRACK_TR3_INDIA_1 }, + { "CUT9" , STR_EMPTY , TRACK_TR3_CUT_9 }, + { "QUADCHAS" , STR_TR3_QUADCHAS , TRACK_TR3_INDIA_1 }, + { "TONYBOSS" , STR_TR3_TONYBOSS , TRACK_TR3_INDIA_2 }, + { "SHORE" , STR_TR3_SHORE , TRACK_TR3_SOUTH_1 }, + { "CUT1" , STR_EMPTY , TRACK_TR3_CUT_1 }, + { "CRASH" , STR_TR3_CRASH , TRACK_TR3_SOUTH_2 }, + { "CUT4" , STR_EMPTY , TRACK_TR3_CUT_4 }, + { "RAPIDS" , STR_TR3_RAPIDS , TRACK_TR3_SOUTH_3 }, + { "TRIBOSS" , STR_TR3_TRIBOSS , TRACK_TR3_CAVES }, + { "ROOFS" , STR_TR3_ROOFS , TRACK_TR3_LONDON_1 }, + { "CUT2" , STR_EMPTY , TRACK_TR3_CUT_2 }, + { "SEWER" , STR_TR3_SEWER , TRACK_TR3_LONDON_2 }, + { "CUT5" , STR_EMPTY , TRACK_TR3_CUT_5 }, + { "TOWER" , STR_TR3_TOWER , TRACK_TR3_LONDON_3 }, + { "CUT11" , STR_EMPTY , TRACK_TR3_CUT_11 }, + { "OFFICE" , STR_TR3_OFFICE , TRACK_TR3_LONDON_4 }, + { "NEVADA" , STR_TR3_NEVADA , TRACK_TR3_NEVADA_1 }, + { "CUT7" , STR_EMPTY , TRACK_TR3_CUT_7 }, + { "COMPOUND" , STR_TR3_COMPOUND , TRACK_TR3_NEVADA_2 }, + { "CUT8" , STR_EMPTY , TRACK_TR3_CUT_8 }, + { "AREA51" , STR_TR3_AREA51 , TRACK_TR3_NEVADA_2 }, + { "ANTARC" , STR_TR3_ANTARC , TRACK_TR3_ANTARC_1 }, + { "CUT3" , STR_EMPTY , TRACK_TR3_CUT_3 }, + { "MINES" , STR_TR3_MINES , TRACK_TR3_ANTARC_2 }, + { "CITY" , STR_TR3_CITY , TRACK_TR3_ANTARC_3 }, + { "CUT12" , STR_EMPTY , TRACK_TR3_CUT_12 }, + { "CHAMBER" , STR_TR3_CHAMBER , TRACK_TR3_ANTARC_3 }, + { "STPAUL" , STR_TR3_STPAUL , TRACK_TR3_CAVES }, }; LevelID getLevelID(int size, const char *name, Version &version, bool &isDemoLevel) { @@ -918,11 +922,17 @@ namespace TR { bool checkTrack(const char *pre, char *name) { static const char *fmt[] = { ".ogg", ".mp3", ".wav" }; - static const char *lng[] = { "", "_EN", "_DE", "_FR", "_IT", "_JA", "_RU" }; + const char *lng[] = { "", "", "_EN", "_FR", "_DE", "_ES", "_IT", "_RU", "_JA" }; + + int start = 1; + if (Core::settings.audio.language != 0) { + start = 0; + lng[start] = lng[Core::settings.audio.language + 2]; + } char buf[32]; for (int f = 0; f < COUNT(fmt); f++) - for (int l = 0; l < COUNT(lng); l++) { + for (int l = start; l < COUNT(lng); l++) { strcpy(buf, pre); strcat(buf, name); strcat(buf, lng[l]); @@ -978,7 +988,12 @@ namespace TR { case VER_TR1_SAT : case VER_TR1_PC : case VER_TR1_PSX : - sprintf(title, "audio/1/track_%02d.ogg", track); + if (track != 24 && track >= 22 && track <= 56 && Core::settings.audio.language != LANG_ES && Core::settings.audio.language != LANG_IT) { // es, it isn't implemented yet + const char *lng[] = { "_EN", "_FR", "_DE", "_ES", "_IT", "_RU", "_JA" }; + sprintf(title, "audio/1/track_%02d%s.ogg", track, lng[Core::settings.audio.language]); + } else { + sprintf(title, "audio/1/track_%02d.ogg", track); + } #ifndef _OS_WEB if (Stream::existsContent(title)) break; diff --git a/src/inventory.h b/src/inventory.h index e92918d..44c253a 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -35,7 +35,7 @@ struct OptionItem { uint8 maxValue; bool bar; - OptionItem(Type type = TYPE_EMPTY, int title = STR_NOT_IMPLEMENTED, intptr_t offset = 0, uint32 color = 0xFFFFFFFF, int icon = 0, uint8 maxValue = 0, bool bar = false) : type(type), title(StringID(title)), offset(offset), color(color), icon(icon), maxValue(maxValue), bar(bar) {} + OptionItem(Type type = TYPE_EMPTY, int title = STR_EMPTY, intptr_t offset = 0, uint32 color = 0xFFFFFFFF, int icon = 0, uint8 maxValue = 0, bool bar = false) : type(type), title(StringID(title)), offset(offset), color(color), icon(icon), maxValue(maxValue), bar(bar) {} void setValue(uint8 value, Core::Settings *settings) const { *(uint8*)(intptr_t(settings) + offset) = value; @@ -54,7 +54,7 @@ struct OptionItem { } float drawParam(float x, float y, float w, StringID oStr, bool active, uint8 value) const { - if (oStr != STR_NOT_IMPLEMENTED) { + if (oStr != STR_EMPTY) { UI::textOut(vec2(x + 32.0f, y), oStr); x = x + w * 0.5f; w = w * 0.5f - 32.0f; @@ -104,7 +104,7 @@ struct OptionItem { UI::textOut(vec2(x, y), title, UI::aCenter, w, 255, UI::SHADE_GRAY); case TYPE_EMPTY : break; case TYPE_BUTTON : { - const char *caption = offset ? (char*)offset : STR[title]; + const char *caption = STR[offset ? StringID(offset) : title]; UI::textOut(vec2(x, y), caption, UI::aCenter, w); break; } @@ -127,7 +127,6 @@ static const OptionItem optDetail[] = { OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_SHADOWS, SETTINGS( detail.shadows ), STR_QUALITY_LOW, 0, 2 ), OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_WATER, SETTINGS( detail.water ), STR_QUALITY_LOW, 0, 2 ), OptionItem( OptionItem::TYPE_PARAM, STR_OPT_SIMPLE_ITEMS, SETTINGS( detail.simple ), STR_OFF, 0, 1 ), - OptionItem( OptionItem::TYPE_PARAM, STR_OPT_SUBTITLES, SETTINGS( detail.subtitles ), STR_OFF, 0, 1 ), #if defined(_OS_WIN) || defined(_OS_LINUX) || defined(_OS_PSP) || defined(_OS_RPI) || defined(_OS_PSV) OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_VSYNC, SETTINGS( detail.vsync ), STR_OFF, 0, 1 ), #endif @@ -147,24 +146,26 @@ static const OptionItem optDetail[] = { static const OptionItem optSound[] = { OptionItem( OptionItem::TYPE_TITLE, STR_SET_VOLUMES ), OptionItem( ), - OptionItem( OptionItem::TYPE_PARAM, STR_NOT_IMPLEMENTED, SETTINGS( audio.music ), 0xFF0080FF, 101, SND_MAX_VOLUME, true ), - OptionItem( OptionItem::TYPE_PARAM, STR_NOT_IMPLEMENTED, SETTINGS( audio.sound ), 0xFFFF8000, 102, SND_MAX_VOLUME, true ), - OptionItem( OptionItem::TYPE_PARAM, STR_REVERBERATION, SETTINGS( audio.reverb ), STR_OFF, 0, 1 ), + OptionItem( OptionItem::TYPE_PARAM, STR_EMPTY, SETTINGS( audio.music ), 0xFF0080FF, 101, SND_MAX_VOLUME, true ), + OptionItem( OptionItem::TYPE_PARAM, STR_EMPTY, SETTINGS( audio.sound ), 0xFFFF8000, 102, SND_MAX_VOLUME, true ), + OptionItem( OptionItem::TYPE_PARAM, STR_REVERBERATION, SETTINGS( audio.reverb ), STR_OFF, 0, 1 ), + OptionItem( OptionItem::TYPE_PARAM, STR_OPT_SUBTITLES, SETTINGS( audio.subtitles ), STR_OFF, 0, 1 ), + OptionItem( OptionItem::TYPE_PARAM, STR_OPT_LANGUAGE, SETTINGS( audio.language ), STR_LANG_EN, 0, 6 ), }; static const OptionItem optControls[] = { OptionItem( OptionItem::TYPE_TITLE, STR_SET_CONTROLS ), OptionItem( ), - OptionItem( OptionItem::TYPE_PARAM, STR_NOT_IMPLEMENTED , SETTINGS( playerIndex ), STR_PLAYER_1, 0, 1 ), + OptionItem( OptionItem::TYPE_PARAM, STR_EMPTY, SETTINGS( playerIndex ), STR_PLAYER_1, 0, 1 ), #ifndef _OS_CLOVER - OptionItem( OptionItem::TYPE_PARAM, STR_OPT_CONTROLS_GAMEPAD , SETTINGS( controls[0].joyIndex ), STR_GAMEPAD_1, 0, 3 ), + OptionItem( OptionItem::TYPE_PARAM, STR_OPT_CONTROLS_GAMEPAD, SETTINGS( controls[0].joyIndex ), STR_GAMEPAD_1, 0, 3 ), #endif #if defined(_OS_WIN) || defined(_OS_LINUX) || defined(_OS_RPI) OptionItem( OptionItem::TYPE_PARAM, STR_OPT_CONTROLS_VIBRATION , SETTINGS( controls[0].vibration ), STR_OFF, 0, 1 ), #endif OptionItem( OptionItem::TYPE_PARAM, STR_OPT_CONTROLS_RETARGET , SETTINGS( controls[0].retarget ), STR_OFF, 0, 1 ), OptionItem( OptionItem::TYPE_PARAM, STR_OPT_CONTROLS_MULTIAIM , SETTINGS( controls[0].multiaim ), STR_OFF, 0, 1 ), - OptionItem( OptionItem::TYPE_PARAM, STR_NOT_IMPLEMENTED , SETTINGS( ctrlIndex ), STR_OPT_CONTROLS_KEYBOARD, 0, 1 ), + OptionItem( OptionItem::TYPE_PARAM, STR_EMPTY , SETTINGS( ctrlIndex ), STR_OPT_CONTROLS_KEYBOARD, 0, 1 ), OptionItem( OptionItem::TYPE_KEY, STR_CTRL_FIRST + cUp , SETTINGS( controls[0].keys[ cUp ] ), STR_KEY_FIRST ), OptionItem( OptionItem::TYPE_KEY, STR_CTRL_FIRST + cDown , SETTINGS( controls[0].keys[ cDown ] ), STR_KEY_FIRST ), OptionItem( OptionItem::TYPE_KEY, STR_CTRL_FIRST + cRight , SETTINGS( controls[0].keys[ cRight ] ), STR_KEY_FIRST ), @@ -322,7 +323,7 @@ struct Inventory { OptionItem item; item.type = OptionItem::TYPE_BUTTON; - item.offset = slot.isCheckpoint() ? intptr_t(STR[STR_CURRENT_POSITION]) : intptr_t(TR::LEVEL_INFO[id].title); // offset as int pointer to level title string + item.offset = slot.isCheckpoint() ? STR_CURRENT_POSITION : TR::LEVEL_INFO[id].title; item.color = i; // color as slot index optLoadSlots.push(item); } @@ -1572,7 +1573,7 @@ struct Inventory { case TR::Entity::INV_GAMMA : case TR::Entity::INV_STOPWATCH : case TR::Entity::INV_MAP : - UI::textOut(vec2(-eye, 240), STR_NOT_IMPLEMENTED, UI::aCenter, UI::width); + UI::textOut(vec2(-eye, 240), STR_EMPTY, UI::aCenter, UI::width); break; default : ; } @@ -1915,7 +1916,7 @@ struct Inventory { sprintf(time, "%d:%02d", m, s); sprintf(buf, STR[STR_LEVEL_STATS], - TR::LEVEL_INFO[saveStats.level].title, + STR[TR::LEVEL_INFO[saveStats.level].title], saveStats.kills, saveStats.pickups, secrets, secretsMax, time); diff --git a/src/lang.h b/src/lang.h new file mode 100644 index 0000000..b9dce40 --- /dev/null +++ b/src/lang.h @@ -0,0 +1,962 @@ +#ifndef H_LANG +#define H_LANG + +enum StringID { + STR_EMPTY +// common + , STR_LOADING + , STR_HELP_PRESS + , STR_HELP_TEXT + , STR_LEVEL_STATS + , STR_HINT_SAVING + , STR_HINT_SAVING_DONE + , STR_HINT_SAVING_ERROR + , STR_YES + , STR_NO + , STR_OFF + , STR_ON + , STR_SPLIT + , STR_VR + , STR_QUALITY_LOW + , STR_QUALITY_MEDIUM + , STR_QUALITY_HIGH + , STR_LANG_EN + , STR_LANG_FR + , STR_LANG_DE + , STR_LANG_ES + , STR_LANG_IT + , STR_LANG_RU + , STR_LANG_JA + , STR_APPLY + , STR_GAMEPAD_1 + , STR_GAMEPAD_2 + , STR_GAMEPAD_3 + , STR_GAMEPAD_4 + , STR_NOT_READY + , STR_PLAYER_1 + , STR_PLAYER_2 + , STR_PRESS_ANY_KEY + , STR_HELP_SELECT + , STR_HELP_BACK +// inventory pages + , STR_OPTION + , STR_INVENTORY + , STR_ITEMS +// save game page + , STR_SAVEGAME + , STR_CURRENT_POSITION +// inventory option + , STR_GAME + , STR_MAP + , STR_COMPASS + , STR_STOPWATCH + , STR_HOME + , STR_DETAIL + , STR_SOUND + , STR_CONTROLS + , STR_GAMMA +// passport menu + , STR_LOAD_GAME + , STR_START_GAME + , STR_RESTART_LEVEL + , STR_EXIT_TO_TITLE + , STR_EXIT_GAME + , STR_SELECT_LEVEL +// detail options + , STR_SELECT_DETAIL + , STR_OPT_DETAIL_FILTER + , STR_OPT_DETAIL_LIGHTING + , STR_OPT_DETAIL_SHADOWS + , STR_OPT_DETAIL_WATER + , STR_OPT_DETAIL_VSYNC + , STR_OPT_DETAIL_STEREO + , STR_OPT_SIMPLE_ITEMS +// sound options + , STR_SET_VOLUMES + , STR_REVERBERATION + , STR_OPT_SUBTITLES + , STR_OPT_LANGUAGE +// controls options + , STR_SET_CONTROLS + , STR_OPT_CONTROLS_KEYBOARD + , STR_OPT_CONTROLS_GAMEPAD + , STR_OPT_CONTROLS_VIBRATION + , STR_OPT_CONTROLS_RETARGET + , STR_OPT_CONTROLS_MULTIAIM + // controls + , STR_CTRL_FIRST + , STR_CTRL_LAST = STR_CTRL_FIRST + cMAX - 1 + // keys + , STR_KEY_FIRST + , STR_KEY_LAST = STR_KEY_FIRST + ikZ + // gamepad + , STR_JOY_FIRST + , STR_JOY_LAST = STR_JOY_FIRST + jkMAX - 1 +// inventory items + , STR_UNKNOWN + , STR_EXPLOSIVE + , STR_PISTOLS + , STR_SHOTGUN + , STR_MAGNUMS + , STR_UZIS + , STR_AMMO_PISTOLS + , STR_AMMO_SHOTGUN + , STR_AMMO_MAGNUMS + , STR_AMMO_UZIS + , STR_MEDI_SMALL + , STR_MEDI_BIG + , STR_LEAD_BAR + , STR_SCION +// keys + , STR_KEY + , STR_KEY_SILVER + , STR_KEY_RUSTY + , STR_KEY_GOLD + , STR_KEY_SAPPHIRE + , STR_KEY_NEPTUNE + , STR_KEY_ATLAS + , STR_KEY_DAMOCLES + , STR_KEY_THOR + , STR_KEY_ORNATE +// puzzles + , STR_PUZZLE + , STR_PUZZLE_GOLD_IDOL + , STR_PUZZLE_GOLD_BAR + , STR_PUZZLE_COG + , STR_PUZZLE_FUSE + , STR_PUZZLE_ANKH + , STR_PUZZLE_HORUS + , STR_PUZZLE_ANUBIS + , STR_PUZZLE_SCARAB + , STR_PUZZLE_PYRAMID +// TR1 subtitles + , STR_TR1_SUB_26 + , STR_TR1_SUB_27 + , STR_TR1_SUB_28 + , STR_TR1_SUB_29 + , STR_TR1_SUB_30 + , STR_TR1_SUB_31 + , STR_TR1_SUB_32 + , STR_TR1_SUB_33 + , STR_TR1_SUB_34 + , STR_TR1_SUB_35 + , STR_TR1_SUB_36 + , STR_TR1_SUB_37 + , STR_TR1_SUB_38 + , STR_TR1_SUB_39 + , STR_TR1_SUB_40 + , STR_TR1_SUB_41 + , STR_TR1_SUB_42 + , STR_TR1_SUB_43 + , STR_TR1_SUB_44 + , STR_TR1_SUB_45 + , STR_TR1_SUB_46 + , STR_TR1_SUB_47 + , STR_TR1_SUB_48 + , STR_TR1_SUB_49 + , STR_TR1_SUB_50 + , STR_TR1_SUB_51 + , STR_TR1_SUB_52 + , STR_TR1_SUB_53 + , STR_TR1_SUB_54 + , STR_TR1_SUB_55 + , STR_TR1_SUB_56 +// TR1 levels + , STR_TR1_GYM + , STR_TR1_LEVEL1 + , STR_TR1_LEVEL2 + , STR_TR1_LEVEL3A + , STR_TR1_LEVEL3B + , STR_TR1_LEVEL4 + , STR_TR1_LEVEL5 + , STR_TR1_LEVEL6 + , STR_TR1_LEVEL7A + , STR_TR1_LEVEL7B + , STR_TR1_LEVEL8A + , STR_TR1_LEVEL8B + , STR_TR1_LEVEL8C + , STR_TR1_LEVEL10A + , STR_TR1_LEVEL10B + , STR_TR1_LEVEL10C + , STR_TR1_EGYPT + , STR_TR1_CAT + , STR_TR1_END + , STR_TR1_END2 +// TR2 levels + , STR_TR2_ASSAULT + , STR_TR2_WALL + , STR_TR2_BOAT + , STR_TR2_VENICE + , STR_TR2_OPERA + , STR_TR2_RIG + , STR_TR2_PLATFORM + , STR_TR2_UNWATER + , STR_TR2_KEEL + , STR_TR2_LIVING + , STR_TR2_DECK + , STR_TR2_SKIDOO + , STR_TR2_MONASTRY + , STR_TR2_CATACOMB + , STR_TR2_ICECAVE + , STR_TR2_EMPRTOMB + , STR_TR2_FLOATING + , STR_TR2_XIAN + , STR_TR2_HOUSE +// TR3 levels + , STR_TR3_HOUSE + , STR_TR3_JUNGLE + , STR_TR3_TEMPLE + , STR_TR3_QUADCHAS + , STR_TR3_TONYBOSS + , STR_TR3_SHORE + , STR_TR3_CRASH + , STR_TR3_RAPIDS + , STR_TR3_TRIBOSS + , STR_TR3_ROOFS + , STR_TR3_SEWER + , STR_TR3_TOWER + , STR_TR3_OFFICE + , STR_TR3_NEVADA + , STR_TR3_COMPOUND + , STR_TR3_AREA51 + , STR_TR3_ANTARC + , STR_TR3_MINES + , STR_TR3_CITY + , STR_TR3_CHAMBER + , STR_TR3_STPAUL + + , STR_MAX +}; + +const char *helpText = + "Start - add second player or restore Lara@" + "H - Show or hide this help@" + "ALT + ENTER - Fullscreen@" + "5 - Save Game@" + "9 - Load Game@" + "C - Look@" + "R - Slow motion@" + "T - Fast motion@" + "Roll - Up + Down@" + "Step Left - Walk + Left@" + "Step Right - Walk + Right@" + "Out of water - Up + Action@" + "Handstand - Up + Walk@" + "Swan dive - Up + Walk + Jump@" + "First Person View - Look + Action@" + "DOZY on - Look + Duck + Action + Jump@" + "DOZY off - Walk"; + +const char *STR_EN[] = { "" +// help + , "Loading..." + , "Press H for help" + , helpText + , "%s@@@" + "KILLS %d@@" + "PICKUPS %d@@" + "SECRETS %d of %d@@" + "TIME TAKEN %s" + , "Saving game..." + , "Saving done!" + , "SAVING ERROR!" + , "YES" + , "NO" + , "Off" + , "On" + , "Split Screen" + , "VR" + , "Low" + , "Medium" + , "High" + , "English" + , "French" + , "German" + , "Spanish" + , "Italian" + , "Russian" + , "Japanese" + , "Apply" + , "Gamepad 1" + , "Gamepad 2" + , "Gamepad 3" + , "Gamepad 4" + , "Not Ready" + , "Player 1" + , "Player 2" + , "Press Any Key" + , "%s - Select" + , "%s - Go Back" +// inventory pages + , "OPTIONS" + , "INVENTORY" + , "ITEMS" +// save game page + , "Save Game?" + , "Current Position" +// inventory option + , "Game" + , "Map" + , "Compass" + , "Statistics" + , "Lara's Home" + , "Detail Levels" + , "Sound" + , "Controls" + , "Gamma" +// passport menu + , "Load Game" + , "Start Game" + , "Restart Level" + , "Exit to Title" + , "Exit Game" + , "Select Level" +// detail options + , "Select Detail" + , "Filtering" + , "Lighting" + , "Shadows" + , "Water" + , "VSync" + , "Stereo" + , "Simple Items" +// sound options + , "Set Volumes" + , "Reverberation" + , "Subtitles" + , "Language" +// controls options + , "Set Controls" + , "Keyboard" + , "Gamepad" + , "Vibration" + , "Retargeting" + , "Multi-aiming" + // controls + , "Left", "Right", "Run", "Back", "Jump", "Walk", "Action", "Draw Weapon", "Look", "Duck", "Dash", "Roll", "Inventory", "Start" + // keys + , "NONE", "LEFT", "RIGHT", "UP", "DOWN", "SPACE", "TAB", "ENTER", "ESCAPE", "SHIFT", "CTRL", "ALT" + , "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" + , "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M" + , "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" + // gamepad + , "NONE", "A", "B", "X", "Y", "L BUMPER", "R BUMPER", "SELECT", "START", "L STICK", "R STICK", "L TRIGGER", "R TRIGGER", "D-LEFT", "D-RIGHT", "D-UP", "D-DOWN" +// inventory items + , "Unknown" + , "Explosive" + , "Pistols" + , "Shotgun" + , "Magnums" + , "Uzis" + , "Pistol Clips" + , "Shotgun Shells" + , "Magnum Clips" + , "Uzi Clips" + , "Small Medi Pack" + , "Large Medi Pack" + , "Lead Bar" + , "Scion" +// keys + , "Key" + , "Silver Key" + , "Rusty Key" + , "Gold Key" + , "Sapphire Key" + , "Neptune Key" + , "Atlas Key" + , "Damocles Key" + , "Thor Key" + , "Ornate Key" +// puzzles + , "Puzzle" + , "Gold Idol" + , "Gold Bar" + , "Machine Cog" + , "Fuse" + , "Ankh" + , "Eye of Horus" + , "Seal of Anubis" + , "Scarab" + , "Pyramid Key" +// TR1 subtitles +/* 26 */ , "Welcome to my home!@I'll take you on a guided tour." +/* 27 */ , "Use the directional buttons to go into the music room." +/* 28 */ , "OK. Let's do some tumbling.@Press the jump button." +/* 29 */ , "Now press it again and press one of@the directions and I'll jump that way." +/* 30 */ , "Ah, the main hall.@Sorry about the crates, I'm having some things put@ into storage and the delivery people haven't been yet." +/* 31 */ , "Run up to a crate, and while still pressing forwards@press action, and I'll vault up onto it." +/* 32 */ , "This used to be the ballroom, but I've converted it into my own personal gym.@What do you think?@Well, let's do some exercises." +/* 33 */ , "I don't actually run everywhere.@When I want to be careful, I walk.@Hold down the walk button, and walk to the white line." +/* 34 */ , "With the walk button down, I won't fall off even if you try to make me.@Go on, try it." +/* 35 */ , "If you want look around, press and hold the look button.@Then press in the direction you want to look." +/* 36 */ , "If a jump is too far for me, I can grab the ledge and save myself from a nasty fall.@Walk to the edge with the white line until I won't go any further.@Then press jump immediately followed by forwards then while @I'm in the air press and hold the action button." +/* 37 */ , "Press forward and I'll climb up." +/* 38 */ , "If I do a running jump, I can make a jump like that, no problem." +/* 39 */ , "Walk to the edge with the white line until I stop.@Then let go of walk and tap backwards to give me a run up.@Press forward, and almost immediately press and hold the jump button.@I won't actually jump until the last minute." +/* 40 */ , "Right. This is a really big one.@So do a running jump exactly as before except while I'm in the air@press and hold the action button to make me grab the ledge." +/* 41 */ , "Nice." +/* 42 */ , "Try to vault up here.@Press forwards and hold action." +/* 43 */ , "I can't climb up because the gap is too small.@But press right and I'll shimmy sideways@until there is room, then press forward." +/* 44 */ , "Great!@If there is a long drop and I don't want to@hurt myself jumping off I can let myself down carefully." +/* 45 */ , "Tap backwards, and I'll jump off backwards.@Immediately press and hold the action button,@and I'll grab the ledge on the way down." +/* 46 */ , "Then let go." +/* 47 */ , "Let's go for a swim." +/* 48 */ , "The jump button and the directions@move me around underwater." +/* 49 */ , "Ah! Air!@Just use forward and left and right@to manoeuvre around on the surface.@Press jump to dive down for another swim about.@Or go to the edge and press action to climb out." +/* 50 */ , "Right. Now I'd better take off these wet clothes." +/* 51 */ , "Say cheese!" +/* 52 */ , "Ain't nothin' personal." +/* 53 */ , "I still git a pain in my brain from ye.@An' it's tellin' me funny ideas now.@Like to shoot you to hell!" +/* 54 */ , "You can't bump off me and my brood so easy, Lara." +/* 55 */ , "A leetle late for the prize giving - non?@Still, it is the taking-part wheech counts." +/* 56 */ , "You firin' at me?@You firin' at me, huh?@Ain't nobody else, so you must be firin' at me!" +// TR1 levels + , "Lara's Home" + , "Caves" + , "City of Vilcabamba" + , "Lost Valley" + , "Tomb of Qualopec" + , "St. Francis' Folly" + , "Colosseum" + , "Palace Midas" + , "The Cistern" + , "Tomb of Tihocan" + , "City of Khamoon" + , "Obelisk of Khamoon" + , "Sanctuary of the Scion" + , "Natla's Mines" + , "Atlantis" + , "The Great Pyramid" + , "Return to Egypt" + , "Temple of the Cat" + , "Atlantean Stronghold" + , "The Hive" +// TR2 levels + , "Lara's Home" + , "The Great Wall" + , "Venice" + , "Bartoli's Hideout" + , "Opera House" + , "Offshore Rig" + , "Diving Area" + , "40 Fathoms" + , "Wreck of the Maria Doria" + , "Living Quarters" + , "The Deck" + , "Tibetan Foothills" + , "Barkhang Monastery" + , "Catacombs of the Talion" + , "Ice Palace" + , "Temple of Xian" + , "Floating Islands" + , "The Dragon's Lair" + , "Home Sweet Home" +// TR3 levels + , "Lara's House" + , "Jungle" + , "Temple Ruins" + , "The River Ganges" + , "Caves Of Kaliya" + , "Coastal Village" + , "Crash Site" + , "Madubu Gorge" + , "Temple Of Puna" + , "Thames Wharf" + , "Aldwych" + , "Lud's Gate" + , "City" + , "Nevada Desert" + , "High Security Compound" + , "Area 51" + , "Antarctica" + , "RX-Tech Mines" + , "Lost City Of Tinnos" + , "Meteorite Cavern" + , "All Hallows" +}; + +const char *STR_FR[] = { "" +// help + , "Chargement..." + , "Press H for help" + , helpText + , "%s@@@" + "ENNEMIS TU)ES %d@@" + "OBJETS TROUVES %d@@" + "SECRETS %d / %d@@" + "TEMPS %s" + , "Sauvegarde..." + , "Sauvegarde achev)ee !" + , "SAUVER ERREUR !" + , "OUI" + , "NON" + , "Arret" + , "Marche" + , ")Ecran Divis)e" + , "VR" + , "Bas" + , "Moyen" + , "Haut" + , "English" + , "French" + , "German" + , "Spanish" + , "Italian" + , "Russian" + , "Japanese" + , "Appliquer" + , "Gamepad 1" + , "Gamepad 2" + , "Gamepad 3" + , "Gamepad 4" + , "Not Ready" + , "Joueur 1" + , "Joueur 2" + , "Press Any Key" + , "%s - Choisir" + , "%s - Arri$ere" +// inventory pages + , "OPTIONS" + , "INVENTAIRE" + , "OBJETS" +// save game page + , "Sauver le jeu ?" + , "Charger Partie" +// inventory option + , "Jeu" + , "Carte" + , "Boussole" + , "Statistiques" + , "Manoir de Lara" + , "Niveau des D)etails" + , "Sons" + , "Controles" + , "Gamma" +// passport menu + , "Charger" + , "Commencer" + , "Rejouer Niveau" + , "Sortie vers titre" + , "Quitter" + , "Choisir Niveau" +// detail options + , "Niveau de D)etail" + , "Filtration" + , ")Eclairage" + , "Ombres" + , "Eau" + , "VSync" + , "St)er)eo" + , "Objets Simples" +// sound options + , "R)egler Volume" + , "R)everb)eration" + , "Sous-titres" + , "Langue" +// controls options + , "R)egler Controles" + , "Clavier" + , "Gamepad" + , "Vibration" + , "Reciblage" + , "Multi-vis)ee" + // controls + , "Gauche", "Droite", "Courir", "Arri$ere", "Sauter", "Marcher", "Action", "D)egainer", "Regarder", "Duck", "Dash", "Roulade", "Inventaire", "Start" + // keys + , "NONE", "LEFT", "RIGHT", "UP", "DOWN", "SPACE", "TAB", "ENTER", "ESCAPE", "SHIFT", "CTRL", "ALT" + , "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" + , "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M" + , "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" + // gamepad + , "NONE", "A", "B", "X", "Y", "L BUMPER", "R BUMPER", "SELECT", "START", "L STICK", "R STICK", "L TRIGGER", "R TRIGGER", "D-LEFT", "D-RIGHT", "D-UP", "D-DOWN" +// inventory items + , "Inconnu" + , "Explosif" + , "Pistolets" + , "Fusil $a pompe" + , "Magnums" + , "Uzis" + , "Balles de pistolet" + , "Cartouches de fusil" + , "Balles de magnum" + , "Balles d'uzi" + , "Mini m)edikit" + , "Grand m)edikit" + , "Barre en plomb" + , "Scion" +// keys + , "Cl)e" + , "Cl)e d'argent" + , "Cl)e rouill)ee" + , "Cl)e en or" + , "Cl)e de saphir" + , "Cl)e Neptune" + , "Cl)e d'Atlas" + , "Cl)e Damocl$es" + , "Cl)e de Thor" + , "Cl)e Ornement)ee" +// puzzles + , "Puzzle" + , "Idole d'or" + , "Lingot d'or" + , "Engrenage" + , "Fusible" + , "Ankh" + , "Oeil d'Horus" + , "Sceau d'Anubis" + , "Scarab)ee" + , "Cl)e pyramide" +// TR1 subtitles +/* 26 */ , "Bienvenue chez moi !" +/* 27 */ , "Utilisez le bouton multidirectionnel pour@aller dans le salon de musique." +/* 28 */ , "OK. On va bouger un peu.@Appuyez sur la touche de saut." +/* 29 */ , "Recommencez en appuyant sur le bouton multidirectionnel@et je sauterai dans cette direction." +/* 30 */ , "Voici le grand hall.@Excusez le d)esordre, je dois tout envoyer au garde-meuble@et les d)em)enageurs ne sont pas encore arriv)es." +/* 31 */ , "Approchez-vous d'une caisse, puis appuyez@en m(eme temps sur la touche d'action et vers@le haut pour que je grimpe dessus." +/* 32 */ , "C')etait autrefois la salle de bal, mais je l'ai transform)ee en salle de gym personnelle.@C'est chouette, non ?@Allez, un peu d'exercice." +/* 33 */ , "Je ne cours pas sans arr(et, en fait.@S'il faut (etre prudente, je peux aussi marcher.@Appuyez sur la touche de marche et avancez@jusqu'$a la ligne blanche." +/* 34 */ , "Tant que vous garderez la touche de marche enfonc)ee,@je ne tomberai pas, m(eme si vous insistez.@Allez-y, essayez !" +/* 35 */ , "Si vous voulez examiner les environs, gardez la touche Observer enfonc)ee.@Puis utilisez le bouton multidirectionnel." +/* 36 */ , "Si je ne peux pas sauter assez loin, je peux me rattraper@de justesse pour ne pas tomber. Approchez-vous du bord au maximum,@en marchant pour que je ne tombe pas. Appuyez sur la touche de saut@puis vers le haut, et maintenez la touche@d'action enfonc)ee pendant que je saute." +/* 37 */ , "Appuyez vers le haut pour me faire grimper." +/* 38 */ , "Avec de l')elan, je peux m'en sortir sans probl$eme." +/* 39 */ , "Avancez en marchant jusqu'$a la ligne blanche, bien au bord.@L(achez la touche de marche et reculez@d'un cran pour que je prenne de l')elan.@Appuyez vers le haut et enfoncez tout de suite la touche de saut.@En fait, je ne sauterai qu'au dernier moment." +/* 40 */ , "L$a, c'est plus difficile.@Nous allons faire exactement le m(eme saut, mais@vous maintiendrez la touche d'action enfonc)ee pour que je me rattrape." +/* 41 */ , "Tr$es bien." +/* 42 */ , "Nous allons grimper ici.@Avancez en appuyant sur la touche d'action." +/* 43 */ , "Je n'ai pas assez de place pour monter, mais je peux longer la corniche.@Appuyez vers la droite jusqu'$a ce qu'il y ait assez d'espace,@puis appuyez vers le haut." +/* 44 */ , "Bien !@Pour )eviter de me blesser en sautant de si haut,@je peux redescendre tout en douceur." +/* 45 */ , "Appuyez vers le bas pour que je me laisse tomber et maintenez@la touche d'action enfonc)ee pour que@je me rattrape dans ma chute." +/* 46 */ , "Vous pouvez ensuite l(acher la touche d'action." +/* 47 */ , "Allons nager un peu." +/* 48 */ , "La touche de saut et le bouton multidirectionnel@me permettent d')evoluer sous l'eau." +/* 49 */ , "Ah ! De l'air !@Utilisez le bouton multidirectionnel pour me faire nager en surface.@Appuyez sur la touche de saut pour me faire nager sous l'eau.@Pour sortir, allez vers le bord et@appuyez sur la touche d'action." +/* 50 */ , "Bon. Je ferais mieux d'aller mettre des v(etements secs." +/* 51 */ , "Souris un peu !" +/* 52 */ , "J'fais que mon boulot." +/* 53 */ , "J'ai encore mal au cr(ane suite $a notre derni$ere rencontre.@Ca me donne des envies )etranges@Cette fois-ci, pas de cadeaux !" +/* 54 */ , "Vous ne pourrez pas vous d)ebarrasser@aussi facilement de moi, Lara." +/* 55 */ , "Vous arrivez un peu tard pour la remise des prix.@Mais l'important, c'est de participer, non ?" +/* 56 */ , "ON ME TIRE DESSUS !@ON ME TIRE DESSUS, LA !@IL N'Y A PAS DE DOUTE, ON ME TIRE DESSUS !" +// TR1 levels + , "Manoir de Lara" + , "Cavernes" + , "Cit)ee de Vilcabamba" + , "Vall)ee Perdue" + , "Tombe de Qualopec" + , "Monument St. Francis" + , "Colosseum" + , "Palais de Midas" + , "La Citerne" + , "Tombe de Tihocan" + , "Cit)ee de Khamoon" + , "Ob)elisque de Khamoon" + , "Sanctuaire du Scion" + , "Mines de Natla" + , "Atlantide" + , "La Grande Pyramide" + , "Retour en Egypte" + , "Temple du Chat" + , "La Forteresse Atlantique" + , "La Ruche" +// TR2 levels + , "Lara's Home" + , "The Great Wall" + , "Venice" + , "Bartoli's Hideout" + , "Opera House" + , "Offshore Rig" + , "Diving Area" + , "40 Fathoms" + , "Wreck of the Maria Doria" + , "Living Quarters" + , "The Deck" + , "Tibetan Foothills" + , "Barkhang Monastery" + , "Catacombs of the Talion" + , "Ice Palace" + , "Temple of Xian" + , "Floating Islands" + , "The Dragon's Lair" + , "Home Sweet Home" +// TR3 levels + , "Lara's House" + , "Jungle" + , "Temple Ruins" + , "The River Ganges" + , "Caves Of Kaliya" + , "Coastal Village" + , "Crash Site" + , "Madubu Gorge" + , "Temple Of Puna" + , "Thames Wharf" + , "Aldwych" + , "Lud's Gate" + , "City" + , "Nevada Desert" + , "High Security Compound" + , "Area 51" + , "Antarctica" + , "RX-Tech Mines" + , "Lost City Of Tinnos" + , "Meteorite Cavern" + , "All Hallows" +}; + +const char *STR_DE[] = { "" +// help + , "Wird geladen..." + , "Press H for help" + , helpText + , "%s@@@" + "Besiegte Gegner %d@@" + "Gegenst~ande %d@@" + "Geheimnisse %d von %d@@" + "Ben~otigte Zeit %s" + , "Spiel sicherung..." + , "Spielstand gesichert!" + , "Sicherung FEHLER!" + , "JA" + , "NEIN" + , "Aus" + , "An" + , "Geteilter Bildschirm" + , "VR" + , "Niedrig" + , "Mittel" + , "Hoch" + , "English" + , "French" + , "German" + , "Spanish" + , "Italian" + , "Russian" + , "Japanese" + , "Anwenden" + , "Gamepad 1" + , "Gamepad 2" + , "Gamepad 3" + , "Gamepad 4" + , "Not Ready" + , "Spieler 1" + , "Spieler 2" + , "Press Any Key" + , "%s - W~ahlen" + , "%s - Zur~uck" +// inventory pages + , "OPTIONEN" + , "INVENTAR" + , "GEGENST~ANDE" +// save game page + , "Spiel sichern?" + , "Aktuelle Position" +// inventory option + , "Spiel" + , "Karte" + , "Kompa=" + , "Statistiken" + , "Laras Haus" + , "Detail-Stufe" + , "Ton" + , "Kontrollen" + , "Gamma" +// passport menu + , "Spiel Laden" + , "Spiel Starten" + , "Level neu starten" + , "Zur~uck zum Hauptmen~u" + , "Spiel Beenden" + , "Level W~ahlen" +// detail options + , "Detailstufe W~ahlen" + , "Filterung" + , "Beleuchtung" + , "Schatten" + , "Wasser" + , "VSync" + , "Stereo" + , "Einfache Gegenst~ande" +// sound options + , "Lautst~arke Einstellen" + , "Nachhall" + , "Untertitel" + , "Sprache" +// controls options + , "Kontrollen Einstellen" + , "Tastatur" + , "Gamepad" + , "Vibration" + , "Retargeting" + , "Multi-Zielen" + // controls + , "Links", "Rechts", "Laufen", "R~uckw~arts", "Springen", "Gehen", "Handlung", "Waffe ziehen", "Umsehen", "Duck", "Dash", "Rolle", "Inventory", "Start" + // keys + , "NONE", "LEFT", "RIGHT", "UP", "DOWN", "SPACE", "TAB", "ENTER", "ESCAPE", "SHIFT", "CTRL", "ALT" + , "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" + , "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M" + , "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" + // gamepad + , "NONE", "A", "B", "X", "Y", "L BUMPER", "R BUMPER", "SELECT", "START", "L STICK", "R STICK", "L TRIGGER", "R TRIGGER", "D-LEFT", "D-RIGHT", "D-UP", "D-DOWN" +// inventory items + , "Unbekannte" + , "Explosiv" + , "Pistolen" + , "Schrotflinte" + , "Magnums" + , "Uzis" + , "Pistolen-Munition" + , "Schrot-Munition" + , "Magnum-Munition" + , "Uzi-Ladestreifen" + , "Kleines Medi-Pack" + , "Gro=es Medi-Pack" + , "Bleibarren" + , "Scion" +// keys + , "Schl~ussel" + , "Silberner Schl~ussel" + , "Rostiger Schl~ussel" + , "Goldener Schl~ussel" + , "Saphir-Schl~ussel" + , "Schl~ussel des Neptun" + , "Schl~ussel des Atlas" + , "Schl~ussel des Damokles" + , "Schl~ussel des Thor" + , "Der antike Schl~ussel" +// puzzles + , "R~atsel" + , "Goldener G~otze" + , "Goldbarren" + , "Zahnrad" + , "Sicherung" + , "Ankh-Kreuz" + , "Auge des Horus" + , "Siegel des Anubis" + , "Skarab~aus" + , "Schl~ussel der Pyramide" +// TR1 subtitles +/* 26 */ , "Willkommen in meinem Haus." +/* 27 */ , "Mit dem Steuerkreuz kommen Sie ins Musikzimmer." +/* 28 */ , "OK, ~uben wir ein paar Spr~unge.@Dr~ucken Sie die Sprungtaste." +/* 29 */ , "Nochmal Sprungtaste, dann das Steuerkreuz dr~ucken,@und ich springe in diese Richtung." +/* 30 */ , "Ah, die Haupthalle.@Sorry wegen der Kisten: Ich will einige Sachen einlagern@und sie sind noch nicht abgeholt worden." +/* 31 */ , "So springe ich auf eine Kiste: Vorw~artstaste gedr~uckt halten,@w~ahrend ich darauf zurenne und Handlungstaste dr~ucken." +/* 32 */ , "Fr~uher war das der Ballsaal.@Jetzt nutze ich ihn als Turnhalle.@Nicht ~ubel, was?@Dann wollen wir mal." +/* 33 */ , "~Ubrigens renne ich nicht immer:@Wenn Vorsicht geboten ist, gehe ich langsam.@Halten Sie die Gehen-Taste gedr~uckt@und gehen Sie bis zur weissen Linie." +/* 34 */ , "Ist die Gehen-Taste gedr~uckt,@kann ich nicht hinunterfallen - auch nicht, wenn Sie das m~ochten.@Los, versuchen Sie's mal." +/* 35 */ , "Dr~ucken und halten Sie die Umsehen-Taste, um sich umzusehen.@Dr~ucken Sie dann die Richtung, in die Sie blicken m~ochten." +/* 36 */ , "Ist ein Sprung zu weit f~ur mich, kann ich nach einem@Vorsprung greifen, um nicht abzust~urzen.@Gehen Sie zum Rand mit der weissen Linie, bis ich stehen bleibe.@Dr~ucken Sie dann Springen und gleich danach Vorw~arts.@Dr~ucken und halten Sie die Handlungstaste,@w~ahrend ich in der Luft bin." +/* 37 */ , "Dr~ucken Sie Vorw~arts, klettere ich nach oben." +/* 38 */ , "Wenn ich mit Anlauf springe, kann ich das problemlos schaffen." +/* 39 */ , "Gehen Sie zur weissen Linie am Rand, bis ich stehen bleibe.@Lassen Sie dann die Gehen-Taste los und dr~ucken@Sie kurz R~uckw~arts, damit ich Anlauf nehmen kann.@Dr~ucken Sie Vorw~arts. Dr~ucken und halten Sie dann fast gleichzeitig die Sprungtaste.@Ich springe erst im letzten Moment." +/* 40 */ , "OK. Jetzt geht's richtig zur Sache.@Machen Sie also wie vorhin einen Sprung mit Anlauf.@Aber wenn ich in der Luft bin dr~ucken und halten@Sie die Handlungstaste, damit ich den Vorsprung greifen kann." +/* 41 */ , "Sehr sch~on." +/* 42 */ , "Versuchen Sie mal, hier drauf zu springen:@Dr~ucken Sie Vorw~arts und halten Sie die Handlungstaste." +/* 43 */ , "Ich kann nicht hinaufklettern: Nicht genug Platz.@Dr~ucken Sie also Rechts, und ich bewege mich seitw~arts,@bis genug Platz ist. Dr~ucken Sie dann Vorw~arts." +/* 44 */ , "Prima!@Bei einem Sprung aus grosser H~ohe k~onnte ich mich verletzen:@Hier ist es besser, sich vorsichtig hinunter zu lassen." +/* 45 */ , "Dr~ucken Sie kurz R~uckw~arts,@damit ich r~uckw~arts abspringe.@Dr~ucken und halten Sie dann sofort die Handlungstaste,@halte ich mich an der Kante fest." +/* 46 */ , "Lassen Sie dann los." +/* 47 */ , "Gehen wir schwimmen." +/* 48 */ , "Mit der Sprungtaste und dem Steuerkreuz steuern@Sie mich unter Wasser." +/* 49 */ , "Ah! Luft!@Benutzen Sie einfach Vorw~arts, Links und Rechts,@um an der Oberfl~ache herumzuschwimmen.@Dr~ucken Sie die Sprungtaste, um noch mal abzutauchen und weiter zu schwimmen.@Oder schwimmen Sie zum Rand und dr~ucken Sie@die Handlungstaste, um heraus zu klettern." +/* 50 */ , "So. Die nassen Sachen sollte ich wohl besser ausziehen." +/* 51 */ , "Sag 'Cheese'!" +/* 52 */ , "Nimm's nicht pers~onlich." +/* 53 */ , "Es ist gef~ahrlich, Leuten auf den Kopf zu hauen.@Davon kriegt man ganz komische Ideen@wie zum Beispiel, Sie wegzupusten!" +/* 54 */ , "Mich und meine Brut werden Sie nicht so leicht los, Lara." +/* 55 */ , "Zu sp~at f~ur die Preisverleihung - non?@Aber dabei sein ist alles, nicht wahr?" +/* 56 */ , "Schiessen Sie auf mich?@He, ob Sie auf mich schiessen?@Ist ja sonst keiner da, Sie m~ussen wohl mich meinen!" +// TR1 levels + , "Laras Haus" + , "Die Kavernen" + , "Die Stadt Vilcabamba" + , "Das Verlorene Tal" + , "Das Grab von Qualopec" + , "St. Francis' Folly" + , "Das Kolosseum" + , "Der Palast des Midas" + , "Die Zisterne" + , "Das Grab des Tihocan" + , "Die Stadt Khamoon" + , "Der Obelisk von Khamoon" + , "Das Heiligtum des Scion" + , "Natlas Katakomben" + , "Atlantis" + , "Die Gro=e Pyramide" + , "Zuruck nach Agypten" + , "Tempel der Katze" + , "Atlantischen Stronghold" + , "Der Bienenstock" +// TR2 levels + , "Lara's Home" + , "The Great Wall" + , "Venice" + , "Bartoli's Hideout" + , "Opera House" + , "Offshore Rig" + , "Diving Area" + , "40 Fathoms" + , "Wreck of the Maria Doria" + , "Living Quarters" + , "The Deck" + , "Tibetan Foothills" + , "Barkhang Monastery" + , "Catacombs of the Talion" + , "Ice Palace" + , "Temple of Xian" + , "Floating Islands" + , "The Dragon's Lair" + , "Home Sweet Home" +// TR3 levels + , "Lara's House" + , "Jungle" + , "Temple Ruins" + , "The River Ganges" + , "Caves Of Kaliya" + , "Coastal Village" + , "Crash Site" + , "Madubu Gorge" + , "Temple Of Puna" + , "Thames Wharf" + , "Aldwych" + , "Lud's Gate" + , "City" + , "Nevada Desert" + , "High Security Compound" + , "Area 51" + , "Antarctica" + , "RX-Tech Mines" + , "Lost City Of Tinnos" + , "Meteorite Cavern" + , "All Hallows" +}; + +char **STR = NULL; + +enum LangID { + LANG_EN , + LANG_FR , + LANG_DE , + LANG_ES , + LANG_IT , + LANG_RU , + LANG_JA , +}; + +void ensureLanguage(LangID lang) { + ASSERT(COUNT(STR_EN) == STR_MAX); + ASSERT(COUNT(STR_FR) == STR_MAX); + ASSERT(COUNT(STR_DE) == STR_MAX); + + switch (lang) { + case LANG_FR : STR = (char**)STR_FR; break; + case LANG_DE : STR = (char**)STR_DE; break; + case LANG_ES : STR = (char**)STR_EN; break; + case LANG_IT : STR = (char**)STR_EN; break; + case LANG_RU : STR = (char**)STR_EN; break; + case LANG_JA : STR = (char**)STR_EN; break; + default : STR = (char**)STR_EN; break; + } +} + +#endif diff --git a/src/platform/web/index.html b/src/platform/web/index.php similarity index 89% rename from src/platform/web/index.html rename to src/platform/web/index.php index c43e6e8..6886b8e 100644 --- a/src/platform/web/index.html +++ b/src/platform/web/index.php @@ -8,11 +8,11 @@ } body { margin: 0px; - font-size: 1.0em; - overflow: hidden; + font-size: 1.0em; + overflow: hidden; } .game_fs { - position: fixed; + position: fixed; top: 0px; left: 0px; margin: 0px; @@ -111,7 +111,26 @@ } proc.connect(audioContext.destination); } - + + function getLanguage() { + var lang = navigator.languages && navigator.languages[0] || navigator.language || navigator.userLanguage; + var id = 0; + if (lang.startsWith("fr")) { + id = 1; + } else if (lang.startsWith("de")) { + id = 2; + } else if (lang.startsWith("es")) { + id = 3; + } else if (lang.startsWith("it")) { + id = 4; + } else if (lang.startsWith("ru") || lang.startsWith("be") || lang.startsWith("uk")) { + id = 5; + } else if (lang.startsWith("it")) { + id = 6; + } + Module.ccall('set_def_lang', 'null', ['number'], [id]); + } + // unlock audio context after user interaction var userAction = function() { if (audioContext && audioContext.state == "suspended") { @@ -147,7 +166,9 @@ OpenLara on github & facebook
-
last update: 14.02.2019
+
last update:

diff --git a/src/platform/web/main.cpp b/src/platform/web/main.cpp index c5f0f63..e2faea1 100644 --- a/src/platform/web/main.cpp +++ b/src/platform/web/main.cpp @@ -236,6 +236,10 @@ bool isFullScreen() { } extern "C" { + void EMSCRIPTEN_KEEPALIVE set_def_lang(int id) { + Core::defLang = id; + } + void EMSCRIPTEN_KEEPALIVE snd_fill(Sound::Frame *frames, int count) { Sound::fill(frames, count); } @@ -338,6 +342,7 @@ int main() { emscripten_set_mouseup_callback(0, 0, 1, mouseCallback); emscripten_set_mousemove_callback(0, 0, 1, mouseCallback); + emscripten_run_script("getLanguage()"); Game::init(); emscripten_run_script("snd_init()"); resize(); diff --git a/src/platform/win/OpenLara.vcxproj b/src/platform/win/OpenLara.vcxproj index 619a929..9f25992 100644 --- a/src/platform/win/OpenLara.vcxproj +++ b/src/platform/win/OpenLara.vcxproj @@ -211,6 +211,7 @@ + diff --git a/src/platform/win/OpenLara.vcxproj.filters b/src/platform/win/OpenLara.vcxproj.filters index ed6a0a3..d0ed235 100644 --- a/src/platform/win/OpenLara.vcxproj.filters +++ b/src/platform/win/OpenLara.vcxproj.filters @@ -58,6 +58,7 @@ + diff --git a/src/platform/win/main.cpp b/src/platform/win/main.cpp index ebe529b..0d9f934 100644 --- a/src/platform/win/main.cpp +++ b/src/platform/win/main.cpp @@ -489,6 +489,22 @@ void parseCommand(char *cmd) { } #endif +LangID checkLanguage() { + LANGID id = GetUserDefaultUILanguage() & 0xFF; + switch (id) { + case LANG_ENGLISH : return LANG_EN; + case LANG_FRENCH : return LANG_FR; + case LANG_GERMAN : return LANG_DE; + case LANG_SPANISH : return LANG_ES; + case LANG_ITALIAN : return LANG_IT; + case LANG_RUSSIAN : + case LANG_UKRAINIAN : + case LANG_BELARUSIAN : return LANG_RU; + case LANG_JAPANESE : return LANG_JA; + } + return LANG_EN; +} + static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { // window @@ -848,6 +864,8 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi joyInit(); sndInit(hWnd); + Core::defLang = checkLanguage(); + Game::init(argc > 1 ? argv[1] : NULL); #ifdef VR_SUPPORT diff --git a/src/ui.h b/src/ui.h index 9b2c6a8..2f07a76 100644 --- a/src/ui.h +++ b/src/ui.h @@ -12,343 +12,7 @@ #define UI_SHOW_FPS #endif -enum StringID { - STR_NOT_IMPLEMENTED -// common - , STR_LOADING - , STR_HELP_PRESS - , STR_HELP_TEXT - , STR_LEVEL_STATS - , STR_HINT_SAVING - , STR_HINT_SAVING_DONE - , STR_HINT_SAVING_ERROR - , STR_YES - , STR_NO - , STR_OFF - , STR_ON - , STR_SPLIT - , STR_VR - , STR_QUALITY_LOW - , STR_QUALITY_MEDIUM - , STR_QUALITY_HIGH - , STR_APPLY - , STR_GAMEPAD_1 - , STR_GAMEPAD_2 - , STR_GAMEPAD_3 - , STR_GAMEPAD_4 - , STR_NOT_READY - , STR_PLAYER_1 - , STR_PLAYER_2 - , STR_PRESS_ANY_KEY - , STR_HELP_SELECT - , STR_HELP_BACK -// inventory pages - , STR_OPTION - , STR_INVENTORY - , STR_ITEMS -// save game page - , STR_SAVEGAME - , STR_CURRENT_POSITION -// inventory option - , STR_GAME - , STR_MAP - , STR_COMPASS - , STR_STOPWATCH - , STR_HOME - , STR_DETAIL - , STR_SOUND - , STR_CONTROLS - , STR_GAMMA -// passport menu - , STR_AUTOSAVE - , STR_LOAD_GAME - , STR_START_GAME - , STR_RESTART_LEVEL - , STR_EXIT_TO_TITLE - , STR_EXIT_GAME - , STR_SELECT_LEVEL -// detail options - , STR_SELECT_DETAIL - , STR_OPT_DETAIL_FILTER - , STR_OPT_DETAIL_LIGHTING - , STR_OPT_DETAIL_SHADOWS - , STR_OPT_DETAIL_WATER - , STR_OPT_DETAIL_VSYNC - , STR_OPT_DETAIL_STEREO - , STR_OPT_SIMPLE_ITEMS - , STR_OPT_SUBTITLES -// sound options - , STR_SET_VOLUMES - , STR_REVERBERATION -// controls options - , STR_SET_CONTROLS - , STR_OPT_CONTROLS_KEYBOARD - , STR_OPT_CONTROLS_GAMEPAD - , STR_OPT_CONTROLS_VIBRATION - , STR_OPT_CONTROLS_RETARGET - , STR_OPT_CONTROLS_MULTIAIM - // controls - , STR_CTRL_FIRST - , STR_CTRL_LAST = STR_CTRL_FIRST + cMAX - 1 - // keys - , STR_KEY_FIRST - , STR_KEY_LAST = STR_KEY_FIRST + ikZ - // gamepad - , STR_JOY_FIRST - , STR_JOY_LAST = STR_JOY_FIRST + jkMAX - 1 -// inventory items - , STR_UNKNOWN - , STR_EXPLOSIVE - , STR_PISTOLS - , STR_SHOTGUN - , STR_MAGNUMS - , STR_UZIS - , STR_AMMO_PISTOLS - , STR_AMMO_SHOTGUN - , STR_AMMO_MAGNUMS - , STR_AMMO_UZIS - , STR_MEDI_SMALL - , STR_MEDI_BIG - , STR_LEAD_BAR - , STR_SCION -// keys - , STR_KEY - , STR_KEY_SILVER - , STR_KEY_RUSTY - , STR_KEY_GOLD - , STR_KEY_SAPPHIRE - , STR_KEY_NEPTUNE - , STR_KEY_ATLAS - , STR_KEY_DAMOCLES - , STR_KEY_THOR - , STR_KEY_ORNATE -// puzzles - , STR_PUZZLE - , STR_PUZZLE_GOLD_IDOL - , STR_PUZZLE_GOLD_BAR - , STR_PUZZLE_COG - , STR_PUZZLE_FUSE - , STR_PUZZLE_ANKH - , STR_PUZZLE_HORUS - , STR_PUZZLE_ANUBIS - , STR_PUZZLE_SCARAB - , STR_PUZZLE_PYRAMID -// TR1 subtitles - , STR_TR1_SUB_26 - , STR_TR1_SUB_27 - , STR_TR1_SUB_28 - , STR_TR1_SUB_29 - , STR_TR1_SUB_30 - , STR_TR1_SUB_31 - , STR_TR1_SUB_32 - , STR_TR1_SUB_33 - , STR_TR1_SUB_34 - , STR_TR1_SUB_35 - , STR_TR1_SUB_36 - , STR_TR1_SUB_37 - , STR_TR1_SUB_38 - , STR_TR1_SUB_39 - , STR_TR1_SUB_40 - , STR_TR1_SUB_41 - , STR_TR1_SUB_42 - , STR_TR1_SUB_43 - , STR_TR1_SUB_44 - , STR_TR1_SUB_45 - , STR_TR1_SUB_46 - , STR_TR1_SUB_47 - , STR_TR1_SUB_48 - , STR_TR1_SUB_49 - , STR_TR1_SUB_50 - , STR_TR1_SUB_51 - , STR_TR1_SUB_52 - , STR_TR1_SUB_53 - , STR_TR1_SUB_54 - , STR_TR1_SUB_55 - , STR_TR1_SUB_56 - - , STR_MAX -}; - -const char *helpText = - "Start - add second player or restore Lara@" - "H - Show or hide this help@" - "ALT + ENTER - Fullscreen@" - "5 - Save Game@" - "9 - Load Game@" - "C - Look@" - "R - Slow motion@" - "T - Fast motion@" - "Roll - Up + Down@" - "Step Left - Walk + Left@" - "Step Right - Walk + Right@" - "Out of water - Up + Action@" - "Handstand - Up + Walk@" - "Swan dive - Up + Walk + Jump@" - "First Person View - Look + Action@" - "DOZY on - Look + Duck + Action + Jump@" - "DOZY off - Walk"; - -const char *levelStats = - "%s@@@" - "KILLS %d@@" - "PICKUPS %d@@" - "SECRETS %d of %d@@" - "TIME TAKEN %s"; - -const char *STR[STR_MAX] = { - "Not implemented yet!" -// help - , "Loading..." - , "Press H for help" - , helpText - , levelStats - , "Saving game..." - , "Saving done!" - , "SAVING ERROR!" - , "YES" - , "NO" - , "Off" - , "On" - , "Split Screen" - , "VR" - , "Low" - , "Medium" - , "High" - , "Apply" - , "Gamepad 1" - , "Gamepad 2" - , "Gamepad 3" - , "Gamepad 4" - , "Not Ready" - , "Player 1" - , "Player 2" - , "Press Any Key" - , "%s - Select" - , "%s - Go Back" -// inventory pages - , "OPTION" - , "INVENTORY" - , "ITEMS" -// save game page - , "Save Game?" - , "Current Position" -// inventory option - , "Game" - , "Map" - , "Compass" - , "Statistics" - , "Lara's Home" - , "Detail Levels" - , "Sound" - , "Controls" - , "Gamma" -// passport menu - , "Autosave" - , "Load Game" - , "Start Game" - , "Restart Level" - , "Exit to Title" - , "Exit Game" - , "Load Game" -// detail options - , "Select Detail" - , "Filtering" - , "Lighting" - , "Shadows" - , "Water" - , "VSync" - , "Stereo" - , "Simple Items" - , "Subtitles" -// sound options - , "Set Volumes" - , "Reverberation" -// controls options - , "Set Controls" - , "Keyboard" - , "Gamepad" - , "Vibration" - , "Retargeting" - , "Multi-aiming" - // controls - , "Left", "Right", "Up", "Down", "Jump", "Walk", "Action", "Draw Weapon", "Look", "Duck", "Dash", "Roll", "Inventory", "Start" - // keys - , "NONE", "LEFT", "RIGHT", "UP", "DOWN", "SPACE", "TAB", "ENTER", "ESCAPE", "SHIFT", "CTRL", "ALT" - , "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" - , "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M" - , "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" - // gamepad - , "NONE", "A", "B", "X", "Y", "L BUMPER", "R BUMPER", "SELECT", "START", "L STICK", "R STICK", "L TRIGGER", "R TRIGGER", "D-LEFT", "D-RIGHT", "D-UP", "D-DOWN" -// inventory items - , "Unknown" - , "Explosive" - , "Pistols" - , "Shotgun" - , "Magnums" - , "Uzis" - , "Pistol Clips" - , "Shotgun Shells" - , "Magnum Clips" - , "Uzi Clips" - , "Small Medi Pack" - , "Large Medi Pack" - , "Lead Bar" - , "Scion" -// keys - , "Key" - , "Silver Key" - , "Rusty Key" - , "Gold Key" - , "Sapphire Key" - , "Neptune Key" - , "Atlas Key" - , "Damocles Key" - , "Thor Key" - , "Ornate Key" -// puzzles - , "Puzzle" - , "Gold Idol" - , "Gold Bar" - , "Machine Cog" - , "Fuse" - , "Ankh" - , "Eye of Horus" - , "Seal of Anubis" - , "Scarab" - , "Pyramid Key" -// TR1 subtitles -/* 26 */ , "Welcome to my home.@I'll take you on a guided tour." -/* 27 */ , "Use the directional buttons to go into the music room." -/* 28 */ , "OK. Let's do some tumbling.@Press the jump button." -/* 29 */ , "Now press it again and press one of@the directions and I'll jump that way." -/* 30 */ , "Ah, the main hall.@Sorry about the crates, I'm having some things put@ into storage and the delivery people haven't been yet." -/* 31 */ , "Run up to a crate, and while still pressing forwards@press action, and I'll vault up onto it." -/* 32 */ , "This used to be the ballroom, but I've converted it into my own personal gym.@What do you think?@Well, let's do some exercises." -/* 33 */ , "I don't actually run everywhere.@When I want to be careful, I walk.@Hold down the walk button, and walk to the white line." -/* 34 */ , "With the walk button down, I won't fall off even if you try to make me.@Go on, try it." -/* 35 */ , "If you want look around, press and hold the look button.@Then press in the direction you want to look." -/* 36 */ , "If a jump is too far for me, I can grab the ledge and save myself from a nasty fall.@Walk to the edge with the white line until I won't go any further.@Then press jump immediately followed by forwards then while @I'm in the air press and hold the action button." -/* 37 */ , "Press forward and I'll climb up." -/* 38 */ , "If I do a running jump, I can make a jump like that, no problem." -/* 39 */ , "Walk to the edge with the white line until I stop.@Then let go of walk and tap backwards to give me a run up.@Press forward, and almost immediately press and hold the jump button.@I won't actually jump until the last minute." -/* 40 */ , "Right. This is a really big one.@So do a running jump exactly as before except while I'm in the air@press and hold the action button to make me grab the ledge." -/* 41 */ , "Nice." -/* 42 */ , "Try to vault up here.@Press forwards and hold action." -/* 43 */ , "I can't climb up because the gap is too small.@But press right and I'll shimmy sideways@until there is room, then press forward." -/* 44 */ , "Great!@If there is a long drop and I don't want to@hurt myself jumping off I can let myself down carefully." -/* 45 */ , "Tap backwards, and I'll jump off backwards.@Immediately press and hold the action button,@and I'll grab the ledge on the way down." -/* 46 */ , "Then let go." -/* 47 */ , "Let's go for a swim." -/* 48 */ , "The jump button and the directions@move me around underwater." -/* 49 */ , "Ah! Air!@Just use forward and left and right@to manoeuvre around on the surface.@Press jump to dive down for another swim about.@Or go to the edge and press action to climb out." -/* 50 */ , "Right. Now I'd better take off these wet clothes." -/* 51 */ , "Say cheese!" -/* 52 */ , "Ain't nothin' personal." -/* 53 */ , "I still git a pain in my brain from ye.@An' it's tellin' me funny ideas now.@Like to shoot you to hell!" -/* 54 */ , "You can't bump off me and my brood so easy, Lara." -/* 55 */ , "A leetle late for the prize giving - non?@Still, it is the taking-part wheech counts." -/* 56 */ , "You firin' at me?@You firin' at me, huh?@Ain't nobody else, so you must be firin' at me!" -}; +#include "lang.h" #ifdef _NAPI_SOCKET extern char command[256]; @@ -380,7 +44,7 @@ namespace UI { 14, 11, 11, 11, 11, 11, 11, 13, 8, 11, 12, 11, 13, 13, 12, 11, 12, 12, 11, 12, 13, 13, 13, 12, 12, 11, // A-Z 9, 9, 9, 9, 9, 9, 9, 9, 5, 9, 9, 5, 12, 10, 9, 9, 9, 8, 9, 8, 9, 9, 11, 9, 9, 9, // a-z 12, 8, 10, 10, 10, 10, 10, 9, 10, 10, // 0-9 - 5, 5, 5, 11, 9, 10, 8, 6, 6, 7, 7, 3, 11, 8, 13, 16, 9, 4, 12, 12, + 5, 5, 5, 11, 9, 10, 8, 6, 6, 7, 7, 3, 8, 8, 13, 16, 9, 4, 12, 12, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 16, 14, 14, 14, 16, 16, 16, 16, 16, 12, 14, 8, 8, 8, 8, 8, 8, 8 }; static const uint8 char_map[102] = { @@ -405,12 +69,18 @@ namespace UI { int x = 0; while (char c = *text++) { - if (c == ' ' || c == '_') { + //if (c == '¿') c = '?'; + //if (c == '¡') c = '!'; + + if (c == '~' || c == '$' || c == ')') { // umlauts + // + } else if (c == ' ' || c == '_') { x += 6; } else if (c == '@') { break; - } else + } else { x += char_width[charRemap(c)] + 1; + } } return short2(x, 16); } @@ -419,13 +89,18 @@ namespace UI { int x = 0, w = 0, h = 16; while (char c = *text++) { - if (c == ' ' || c == '_') { + //if (c == '¿') c = '?'; + //if (c == '¡') c = '!'; + + if (c == '~' || c == '$' || c == ')') { // umlauts + // + } else if (c == ' ' || c == '_') { x += 6; } else if (c == '@') { w = max(w, x); h += 16; x = 0; - } else + } else x += char_width[charRemap(c)] + 1; } w = max(w, x); @@ -455,6 +130,8 @@ namespace UI { } void begin() { + ensureLanguage(LangID(Core::settings.audio.language)); + Core::setDepthTest(false); Core::setBlendMode(bmPremult); Core::setCullMode(cmNone); @@ -517,6 +194,8 @@ namespace UI { } while (char c = *text++) { + //if (c == '¿') c = '?'; + //if (c == '¡') c = '!'; if (c == '@') { x = int(pos.x) + getLeftOffset(text, align, int(width)); @@ -554,7 +233,9 @@ namespace UI { mesh->addDynSprite(level->spriteSequences[seq].sStart + frame, short3(x, y, 0), tColor, bColor, true); - x += char_width[frame] + 1; + if (c != '~' && c != '$' && c != ')') { // umlauts + x += char_width[frame] + 1; + } } } @@ -577,6 +258,7 @@ namespace UI { #undef MAX_CHARS void init(IGame *game) { + ensureLanguage(LangID(Core::settings.audio.language)); UI::game = game; showHelp = false; helpTipTime = 5.0f; @@ -688,7 +370,7 @@ namespace UI { } void showSubs(StringID str) { - if (str == STR_NOT_IMPLEMENTED || !Core::settings.detail.subtitles) + if (str == STR_EMPTY || !Core::settings.audio.subtitles) return; subsStr = str; subsTime = strlen(STR[str]) * SUBTITLES_SPEED; @@ -697,7 +379,7 @@ namespace UI { StringID getSubs(int track) { if (game && (game->getLevel()->version & TR::VER_TR1) && track >= 26 && track <= 56) return StringID(STR_TR1_SUB_26 + (track - 26)); - return STR_NOT_IMPLEMENTED; + return STR_EMPTY; } void renderHelp() { @@ -838,4 +520,4 @@ namespace UI { } }; -#endif \ No newline at end of file +#endif