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