From d039207b03fc20716592b112b6f0e74c89892ec8 Mon Sep 17 00:00:00 2001 From: milek7 Date: Tue, 2 Jul 2019 01:00:42 +0200 Subject: [PATCH] snapshot --- CMakeLists.txt | 10 +- DynObj.cpp | 2 +- Globals.h | 2 +- Texture.cpp | 30 ++++- Texture.h | 1 + application.cpp | 16 ++- application.h | 4 +- applicationmode.h | 7 +- driverkeyboardinput.cpp | 3 +- editorkeyboardinput.cpp | 3 +- keyboardinput.cpp | 160 ++++++++++++++++++----- keyboardinput.h | 48 ++++--- stb/stb_image.h | 1 - translation.cpp | 273 +++++++++++++++++++++++++++++++++++++--- translation.h | 34 ++--- uilayer.cpp | 35 +++--- uilayer.h | 9 +- widgets/perfgraphs.h | 2 +- 18 files changed, 529 insertions(+), 111 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 411e34ca..d7b463a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,8 @@ file(GLOB HEADERS "*.h" "gl/*.h" "network/*.h" "network/backend/*.h" -"widgets/*.h") +"widgets/*.h" +"launcher/*.h") if (APPLE) set (CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000") @@ -162,6 +163,13 @@ set(SOURCES "stb/stb_image.c" "extras/VS_Dev.cpp" + +"launcher/launchermode.cpp" +"launcher/scenery_list.cpp" +"launcher/launcheruilayer.cpp" +"launcher/vehicle_picker.cpp" +"launcher/keymapper.cpp" +"launcher/mainmenu.cpp" ) if (USE_IMGUI_GL3) diff --git a/DynObj.cpp b/DynObj.cpp index 23ce7c37..ac55b48e 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -62,7 +62,7 @@ TextureTest( std::string const &Name ) { auto const lookup { FileExists( { Global.asCurrentTexturePath + Name, Name, szTexturePath + Name }, - { ".mat", ".dds", ".tga", ".png", ".bmp" } ) }; + { ".mat", ".dds", ".tga", ".png", ".bmp", ".jpg", ".tex" } ) }; return ( lookup.first + lookup.second ); } diff --git a/Globals.h b/Globals.h index 958081db..38b32768 100644 --- a/Globals.h +++ b/Globals.h @@ -62,7 +62,7 @@ struct global_settings { std::string szTexturesTGA{ ".tga" }; // lista tekstur od TGA std::string szTexturesDDS{ ".dds" }; // lista tekstur od DDS std::string szDefaultExt{ szTexturesDDS }; - std::string SceneryFile{ "td.scn" }; + std::string SceneryFile; std::string local_start_vehicle{ "EU07-424" }; int iConvertModels{ 0 }; // tworzenie plików binarnych // logs diff --git a/Texture.cpp b/Texture.cpp index 254eb2c4..a3f8cdb8 100644 --- a/Texture.cpp +++ b/Texture.cpp @@ -24,9 +24,9 @@ http://mozilla.org/MPL/2.0/. #include "sn_utils.h" #include "utilities.h" #include "flip-s3tc.h" +#include "stb/stb_image.h" #include - #define EU07_DEFERRED_TEXTURE_UPLOAD texture_manager::texture_manager() { @@ -161,6 +161,8 @@ void opengl_texture::gles_match_internalformat(GLuint internalformat) // TODO: wrap it in a workitem class, for the job system deferred loading void opengl_texture::load() { + if (data_state == resource_state::good) + return; if( type == "make:" ) { // for generated texture we delay data creation until texture is bound @@ -179,6 +181,7 @@ opengl_texture::load() { else if( type == ".tga" ) { load_TGA(); } else if( type == ".png" ) { load_PNG(); } else if( type == ".bmp" ) { load_BMP(); } + else if( type == ".jpg" ) { load_STBI(); } else if( type == ".tex" ) { load_TEX(); } else { goto fail; } } @@ -251,6 +254,29 @@ void opengl_texture::load_PNG() data_state = resource_state::good; } +void opengl_texture::load_STBI() +{ + int x, y, n; + uint8_t *image = stbi_load((name + type).c_str(), &x, &y, &n, 4); + + if (!image) { + data_state = resource_state::failed; + ErrorLog(std::string(stbi_failure_reason())); + return; + } + + data.resize(x * y * 4); + memcpy(&data[0], image, data.size()); + delete image; + + data_format = GL_RGBA; + data_components = (n == 4 ? GL_RGBA : GL_RGB); + data_width = x; + data_height = y; + data_mapcount = 1; + data_state = resource_state::good; +} + void opengl_texture::make_stub() { @@ -1343,7 +1369,7 @@ texture_manager::find_on_disk( std::string const &Texturename ) const { return ( FileExists( filenames, - { ".dds", ".tga", ".png", ".bmp", ".ext" } ) ); + { ".dds", ".tga", ".png", ".bmp", ".jpg", ".tex" } ) ); } //--------------------------------------------------------------------------- diff --git a/Texture.h b/Texture.h index af7c0726..220967ec 100644 --- a/Texture.h +++ b/Texture.h @@ -68,6 +68,7 @@ private: void load_PNG(); void load_DDS(); void load_TEX(); + void load_STBI(); void load_TGA(); void set_filtering() const; void downsize( GLuint const Format ); diff --git a/application.cpp b/application.cpp index 052dd663..41f6d63f 100644 --- a/application.cpp +++ b/application.cpp @@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/. #include "drivermode.h" #include "editormode.h" #include "scenarioloadermode.h" +#include "launcher/launchermode.h" #include "Globals.h" #include "simulation.h" @@ -164,6 +165,8 @@ eu07_application::run() { Timer::subsystem.mainloop_total.start(); glfwPollEvents(); + begin_ui_frame(); + // ------------------------------------------------------------------- // multiplayer command relaying logic can seem a bit complex // @@ -367,6 +370,13 @@ eu07_application::render_ui() { m_modes[ m_modestack.top() ]->render_ui(); } +void eu07_application::begin_ui_frame() { + + if( m_modestack.empty() ) { return; } + + m_modes[ m_modestack.top() ]->begin_ui_frame(); +} + bool eu07_application::pop_mode() { if( m_modestack.empty() ) { return false; } @@ -761,6 +771,7 @@ eu07_application::init_modes() { // but doing it in one go at the start saves us some error checking headache down the road // create all application behaviour modes + m_modes[ mode::launcher ] = std::make_shared(); m_modes[ mode::scenarioloader ] = std::make_shared(); m_modes[ mode::driver ] = std::make_shared(); m_modes[ mode::editor ] = std::make_shared(); @@ -771,7 +782,10 @@ eu07_application::init_modes() { } } // activate the default mode - push_mode( mode::scenarioloader ); + if (Global.SceneryFile.empty()) + push_mode( mode::launcher ); + else + push_mode( mode::scenarioloader ); return 0; } diff --git a/application.h b/application.h index db212384..9dbc0039 100644 --- a/application.h +++ b/application.h @@ -19,7 +19,7 @@ class eu07_application { public: // types enum mode { -// launcher = 0, + launcher = 0, scenarioloader, driver, editor, @@ -45,6 +45,8 @@ public: exit(); void render_ui(); + void + begin_ui_frame(); // switches application to specified mode bool pop_mode(); diff --git a/applicationmode.h b/applicationmode.h index 28241cb1..381d9dbb 100644 --- a/applicationmode.h +++ b/applicationmode.h @@ -28,12 +28,17 @@ public: virtual bool update() = 0; - // draws node-specific user interface + // draws mode-specific user interface inline void render_ui() { if( m_userinterface != nullptr ) { m_userinterface->render(); } } + inline + void + begin_ui_frame() { + if( m_userinterface != nullptr ) { + m_userinterface->begin_ui_frame(); } } inline void set_progress( float const Progress = 0.f, float const Subtaskprogress = 0.f ) { diff --git a/driverkeyboardinput.cpp b/driverkeyboardinput.cpp index 471e11d9..83b7e689 100644 --- a/driverkeyboardinput.cpp +++ b/driverkeyboardinput.cpp @@ -15,8 +15,7 @@ driverkeyboard_input::init() { default_bindings(); recall_bindings(); - bind(); - m_bindingsetups.clear(); + bind(); return true; } diff --git a/editorkeyboardinput.cpp b/editorkeyboardinput.cpp index 0e88137a..139e2f53 100644 --- a/editorkeyboardinput.cpp +++ b/editorkeyboardinput.cpp @@ -16,8 +16,7 @@ editorkeyboard_input::init() { default_bindings(); // TODO: re-enable after mode-specific binding import is in place // return recall_bindings(); - bind(); - m_bindingsetups.clear(); + bind(); return true; } diff --git a/keyboardinput.cpp b/keyboardinput.cpp index 82ea9088..5c9e84c5 100644 --- a/keyboardinput.cpp +++ b/keyboardinput.cpp @@ -22,6 +22,102 @@ bool key_shift; } +std::unordered_map keyboard_input::keytonamemap = +{ + { GLFW_KEY_0, "0" }, + { GLFW_KEY_1, "1" }, + { GLFW_KEY_2, "2" }, + { GLFW_KEY_3, "3" }, + { GLFW_KEY_4, "4" }, + { GLFW_KEY_5, "5" }, + { GLFW_KEY_6, "6" }, + { GLFW_KEY_7, "7" }, + { GLFW_KEY_8, "8" }, + { GLFW_KEY_9, "9" }, + { GLFW_KEY_MINUS, "-" }, + { GLFW_KEY_EQUAL, "=" }, + { GLFW_KEY_A, "a" }, + { GLFW_KEY_B, "b" }, + { GLFW_KEY_C, "c" }, + { GLFW_KEY_D, "d" }, + { GLFW_KEY_E, "e" }, + { GLFW_KEY_F, "f" }, + { GLFW_KEY_G, "g" }, + { GLFW_KEY_H, "h" }, + { GLFW_KEY_I, "i" }, + { GLFW_KEY_J, "j" }, + { GLFW_KEY_K, "k" }, + { GLFW_KEY_L, "l" }, + { GLFW_KEY_M, "m" }, + { GLFW_KEY_N, "n" }, + { GLFW_KEY_O, "o" }, + { GLFW_KEY_P, "p" }, + { GLFW_KEY_Q, "q" }, + { GLFW_KEY_R, "r" }, + { GLFW_KEY_S, "s" }, + { GLFW_KEY_T, "t" }, + { GLFW_KEY_U, "u" }, + { GLFW_KEY_V, "v" }, + { GLFW_KEY_W, "w" }, + { GLFW_KEY_X, "x" }, + { GLFW_KEY_Y, "y" }, + { GLFW_KEY_Z, "z" }, + { GLFW_KEY_MINUS, "-" }, + { GLFW_KEY_EQUAL, "=" }, + { GLFW_KEY_BACKSPACE, "backspace" }, + { GLFW_KEY_LEFT_BRACKET, "[" }, + { GLFW_KEY_RIGHT_BRACKET, "]" }, + { GLFW_KEY_BACKSLASH, "\\" }, + { GLFW_KEY_SEMICOLON, ";" }, + { GLFW_KEY_APOSTROPHE, "'" }, + { GLFW_KEY_ENTER, "enter" }, + { GLFW_KEY_COMMA, "," }, + { GLFW_KEY_PERIOD, "." }, + { GLFW_KEY_SLASH, "/" }, + { GLFW_KEY_SPACE, "space" }, + { GLFW_KEY_PAUSE, "pause" }, + { GLFW_KEY_INSERT, "insert" }, + { GLFW_KEY_DELETE, "delete" }, + { GLFW_KEY_HOME, "home" }, + { GLFW_KEY_END, "end" }, + { GLFW_KEY_KP_DIVIDE, "num_/" }, + { GLFW_KEY_KP_MULTIPLY, "num_*" }, + { GLFW_KEY_KP_SUBTRACT, "num_-" }, + { GLFW_KEY_KP_7, "num_7" }, + { GLFW_KEY_KP_8, "num_8" }, + { GLFW_KEY_KP_9, "num_9" }, + { GLFW_KEY_KP_ADD, "num_+" }, + { GLFW_KEY_KP_4, "num_4" }, + { GLFW_KEY_KP_5, "num_5" }, + { GLFW_KEY_KP_6, "num_6" }, + { GLFW_KEY_KP_1, "num_1" }, + { GLFW_KEY_KP_2, "num_2" }, + { GLFW_KEY_KP_3, "num_3" }, + { GLFW_KEY_KP_ENTER, "num_enter" }, + { GLFW_KEY_KP_0, "num_0" }, + { GLFW_KEY_KP_DECIMAL, "num_." }, + { GLFW_KEY_F1, "f1" }, + { GLFW_KEY_F2, "f2" }, + { GLFW_KEY_F3, "f3" }, + { GLFW_KEY_F4, "f4" }, + { GLFW_KEY_F5, "f5" }, + { GLFW_KEY_F6, "f6" }, + { GLFW_KEY_F7, "f7" }, + { GLFW_KEY_F8, "f8" }, + { GLFW_KEY_F9, "f9" }, + { GLFW_KEY_F10, "f10" }, + { GLFW_KEY_F11, "f11" }, + { GLFW_KEY_F12, "f12" }, + { GLFW_KEY_TAB, "tab" }, + { GLFW_KEY_ESCAPE, "esc" }, + { GLFW_KEY_LEFT, "left" }, + { GLFW_KEY_RIGHT, "right" }, + { GLFW_KEY_UP, "up" }, + { GLFW_KEY_DOWN, "down" }, + { GLFW_KEY_PAGE_UP, "page_up" }, + { GLFW_KEY_PAGE_DOWN, "page_down" }, +}; + bool keyboard_input::recall_bindings() { @@ -39,32 +135,11 @@ keyboard_input::recall_bindings() { static_cast( commandid ) ); ++commandid; } - std::unordered_map nametokeymap = { - { "0", GLFW_KEY_0 }, { "1", GLFW_KEY_1 }, { "2", GLFW_KEY_2 }, { "3", GLFW_KEY_3 }, { "4", GLFW_KEY_4 }, - { "5", GLFW_KEY_5 }, { "6", GLFW_KEY_6 }, { "7", GLFW_KEY_7 }, { "8", GLFW_KEY_8 }, { "9", GLFW_KEY_9 }, - { "-", GLFW_KEY_MINUS }, { "=", GLFW_KEY_EQUAL }, - { "a", GLFW_KEY_A }, { "b", GLFW_KEY_B }, { "c", GLFW_KEY_C }, { "d", GLFW_KEY_D }, { "e", GLFW_KEY_E }, - { "f", GLFW_KEY_F }, { "g", GLFW_KEY_G }, { "h", GLFW_KEY_H }, { "i", GLFW_KEY_I }, { "j", GLFW_KEY_J }, - { "k", GLFW_KEY_K }, { "l", GLFW_KEY_L }, { "m", GLFW_KEY_M }, { "n", GLFW_KEY_N }, { "o", GLFW_KEY_O }, - { "p", GLFW_KEY_P }, { "q", GLFW_KEY_Q }, { "r", GLFW_KEY_R }, { "s", GLFW_KEY_S }, { "t", GLFW_KEY_T }, - { "u", GLFW_KEY_U }, { "v", GLFW_KEY_V }, { "w", GLFW_KEY_W }, { "x", GLFW_KEY_X }, { "y", GLFW_KEY_Y }, { "z", GLFW_KEY_Z }, - { "-", GLFW_KEY_MINUS }, { "=", GLFW_KEY_EQUAL }, { "backspace", GLFW_KEY_BACKSPACE }, - { "[", GLFW_KEY_LEFT_BRACKET }, { "]", GLFW_KEY_RIGHT_BRACKET }, { "\\", GLFW_KEY_BACKSLASH }, - { ";", GLFW_KEY_SEMICOLON }, { "'", GLFW_KEY_APOSTROPHE }, { "enter", GLFW_KEY_ENTER }, - { ",", GLFW_KEY_COMMA }, { ".", GLFW_KEY_PERIOD }, { "/", GLFW_KEY_SLASH }, - { "space", GLFW_KEY_SPACE }, - { "pause", GLFW_KEY_PAUSE }, { "insert", GLFW_KEY_INSERT }, { "delete", GLFW_KEY_DELETE }, { "home", GLFW_KEY_HOME }, { "end", GLFW_KEY_END }, - // numpad block - { "num_/", GLFW_KEY_KP_DIVIDE }, { "num_*", GLFW_KEY_KP_MULTIPLY }, { "num_-", GLFW_KEY_KP_SUBTRACT }, - { "num_7", GLFW_KEY_KP_7 }, { "num_8", GLFW_KEY_KP_8 }, { "num_9", GLFW_KEY_KP_9 }, { "num_+", GLFW_KEY_KP_ADD }, - { "num_4", GLFW_KEY_KP_4 }, { "num_5", GLFW_KEY_KP_5 }, { "num_6", GLFW_KEY_KP_6 }, - { "num_1", GLFW_KEY_KP_1 }, { "num_2", GLFW_KEY_KP_2 }, { "num_3", GLFW_KEY_KP_3 }, { "num_enter", GLFW_KEY_KP_ENTER }, - { "num_0", GLFW_KEY_KP_0 }, { "num_.", GLFW_KEY_KP_DECIMAL }, - // misc - { "f1", GLFW_KEY_F1 }, { "f2", GLFW_KEY_F2 }, { "f3", GLFW_KEY_F3 }, { "f4", GLFW_KEY_F4 }, { "f5", GLFW_KEY_F5 }, - { "f6", GLFW_KEY_F6 }, { "f7", GLFW_KEY_F7 }, { "f8", GLFW_KEY_F8 }, { "f9", GLFW_KEY_F9 }, { "f10", GLFW_KEY_F10 }, - { "f11", GLFW_KEY_F11 }, { "f12", GLFW_KEY_F12 }, { "tab", GLFW_KEY_TAB }, { "esc", GLFW_KEY_ESCAPE } - }; + std::unordered_map nametokeymap; + + for (const std::pair &key : keytonamemap) { + nametokeymap.emplace(key.second, key.first); + } // NOTE: to simplify things we expect one entry per line, and whole entry in one line while( true == bindingparser.getTokens( 1, true, "\n" ) ) { @@ -107,7 +182,7 @@ keyboard_input::recall_bindings() { } if( ( binding & 0xffff ) != 0 ) { - m_bindingsetups.emplace_back( binding_setup{ lookup->second, binding } ); + m_bindingsetups.insert_or_assign(lookup->second, binding); } } } @@ -117,6 +192,33 @@ keyboard_input::recall_bindings() { return true; } +void keyboard_input::dump_bindings() +{ + std::fstream stream("eu07_input-keyboard.ini", + std::ios_base::binary | std::ios_base::trunc | std::ios_base::out); + + if (!stream.is_open()) { + ErrorLog("failed to save keyboard config"); + return; + } + + for (const std::pair &binding : m_bindingsetups) { + stream << simulation::Commands_descriptions[static_cast(binding.first)].name << ' '; + + auto it = keytonamemap.find(binding.second & 0xFFFF); + if (it != keytonamemap.end()) { + if (binding.second & keymodifier::control) + stream << "ctrl "; + if (binding.second & keymodifier::shift) + stream << "shift "; + + stream << it->second << "\r\n"; + } else { + stream << "none\r\n"; + } + } +} + bool keyboard_input::key( int const Key, int const Action ) { @@ -188,11 +290,13 @@ keyboard_input::key( int const Key ) const { void keyboard_input::bind() { + m_bindings.clear(); for( auto const &bindingsetup : m_bindingsetups ) { - m_bindings[ bindingsetup.binding ] = bindingsetup.command; + m_bindings[ bindingsetup.second ] = bindingsetup.first; } + // cache movement key bindings m_bindingscache.forward = binding( user_command::moveforward ); m_bindingscache.back = binding( user_command::moveback ); diff --git a/keyboardinput.h b/keyboardinput.h index aa64ed9e..ec6ab9ff 100644 --- a/keyboardinput.h +++ b/keyboardinput.h @@ -23,8 +23,23 @@ extern bool key_shift; } class keyboard_input { - public: +// types + /* + struct binding_setup { + + user_command command; + int binding; + };*/ + + using bindingsetup_sequence = std::map; + + enum keymodifier : int { + + shift = 0x10000, + control = 0x20000 + }; + // constructors keyboard_input() = default; @@ -45,38 +60,31 @@ public: user_command const command() const { return m_command; } + bindingsetup_sequence& + bindings() { + return m_bindingsetups; } + void + bind(); + void + dump_bindings(); + +// members + static std::unordered_map keytonamemap; protected: -// types - enum keymodifier : int { - - shift = 0x10000, - control = 0x20000 - }; - - struct binding_setup { - - user_command command; - int binding; - }; - - using bindingsetup_sequence = std::vector; - // methods virtual void default_bindings() = 0; bool recall_bindings(); - void - bind(); // members - bindingsetup_sequence m_bindingsetups; + bindingsetup_sequence m_bindingsetups; private: // types - using usercommand_map = std::unordered_map; + using usercommand_map = std::unordered_map; struct bindings_cache { diff --git a/stb/stb_image.h b/stb/stb_image.h index 106e1927..ab2e3ce3 100644 --- a/stb/stb_image.h +++ b/stb/stb_image.h @@ -111,7 +111,6 @@ RECENT REVISION HISTORY: #define STBI_INCLUDE_STB_IMAGE_H #define STBI_ONLY_JPEG -#define STBI_NO_STDIO // DOCUMENTATION // diff --git a/translation.cpp b/translation.cpp index 6d5bf5c4..366a1330 100644 --- a/translation.cpp +++ b/translation.cpp @@ -13,13 +13,10 @@ http://mozilla.org/MPL/2.0/. #include "stdafx.h" #include "translation.h" - +#include "Logs.h" #include "Globals.h" -namespace locale { - -void -init() { + /* // TODO: import localized strings from localization files std::unordered_map> stringmap; @@ -568,24 +565,264 @@ init() { m_cabcontrols.insert( { cabcontrol, strings[ stringidx++ ] } ); } } + */ + +void locale::init() +{ + std::fstream stream("lang/" + Global.asLang + ".po", std::ios_base::in | std::ios_base::binary); + + if (!stream.is_open()) { + WriteLog("translation: cannot open lang file: " + Global.asLang); + return; + } + + while (stream.eof()) + parse_translation(stream); + + WriteLog("translation: " + std::to_string(lang_mapping.size()) + " strings loaded"); } -std::string -label_cab_control( std::string const &Label ) { +const std::string& locale::lookup_s(const std::string &msg, bool constant) +{ + if (constant) { + auto it = pointer_cache.find(&msg); + if (it != pointer_cache.end()) + return *(it->second); + } + auto it = lang_mapping.find(msg); + if (it != lang_mapping.end()) { + if (constant) + pointer_cache.emplace(&msg, &(it->second)); + return it->second; + } + + if (constant) + pointer_cache.emplace(&msg, &msg); + return msg; +} + +const char* locale::lookup(const char *msg, bool constant) +{ + if (constant) { + auto it = pointer_cache.find(&msg); + if (it != pointer_cache.end()) + return it->second->c_str(); + } + + auto it = lang_mapping.find(std::string(msg)); + if (it != lang_mapping.end()) { + if (constant) + pointer_cache.emplace(&msg, &(it->second)); + return it->second.c_str(); + } + + return msg; +} + +void locale::parse_translation(std::istream &stream) +{ + std::string line; + + std::string msgid; + std::string msgstr; + std::string msgctxt; + char last = 'x'; + + while (std::getline(stream, line)) { + if (line.size() > 0 && line[0] == '#') + continue; + + if (string_starts_with(line, "msgid")) + last = 'i'; + else if (string_starts_with(line, "msgstr")) + last = 's'; + else if (string_starts_with(line, "msgctxt")) + last = 'c'; + + if (line.size() > 1 && last != 'x') { + if (last == 'i') + msgid += parse_c_literal(line); + else if (last == 's') + msgstr += parse_c_literal(line); + else if (last == 'c') + msgctxt += parse_c_literal(line); + } + else { + if (!msgid.empty() && !msgstr.empty()) + lang_mapping.emplace(msgctxt + "\x1d" + msgid, msgstr); + return; + } + } +} + +std::string locale::parse_c_literal(const std::string &str) +{ + std::istringstream stream(str); + std::string out; + + bool active = false; + bool escape = false; + + char c; + while ((c = stream.get()) != stream.eof()) { + if (!escape && c == '"') + active = !active; + else if (active && !escape && c == '\\') + escape = true; + else if (active && escape) { + if (c == 'r') + out += '\r'; + else if (c == 'n') + out += '\n'; + else if (c == 't') + out += '\t'; + else if (c == '\\') + out += '\\'; + else if (c == '?') + out += '?'; + else if (c == '\'') + out += '\''; + else if (c == '"') + out += '"'; + else if (c == 'x') { + char n1 = stream.get() - 48; + char n2 = stream.get() - 48; + if (n1 > 9) + n1 -= 7; + if (n1 > 16) + n1 -= 32; + if (n2 > 9) + n2 -= 7; + if (n2 > 16) + n2 -= 32; + out += ((n1 << 4) | n2); + } + escape = false; + } + else if (active) + out += c; + } + + return out; +} + +std::string locale::label_cab_control(std::string const &Label) +{ if( Label.empty() ) { return ""; } - auto const lookup = m_cabcontrols.find( Label ); + static std::unordered_map cabcontrols_labels = { + { "mainctrl:", "master controller" }, + { "jointctrl:", "master controller" }, + { "scndctrl:", "second controller" }, + { "shuntmodepower:", "shunt mode power" }, + { "tempomat_sw:", "tempomat" }, + { "dirkey:", "reverser" }, + { "brakectrl:", "train brake" }, + { "localbrake:", "independent brake" }, + { "manualbrake:", "manual brake" }, + { "alarmchain:", "emergency brake" }, + { "brakeprofile_sw:", "brake acting speed" }, + { "brakeprofileg_sw:", "brake acting speed: cargo" }, + { "brakeprofiler_sw:", "brake acting speed: rapid" }, + { "brakeopmode_sw", "brake operation mode" }, + { "maxcurrent_sw:", "motor overload relay threshold" }, + { "waterpump_sw:", "water pump" }, + { "waterpumpbreaker_sw:", "water pump breaker" }, + { "waterheater_sw:", "water heater" }, + { "waterheaterbreaker_sw:", "water heater breaker" }, + { "watercircuitslink_sw:", "water circuits link" }, + { "fuelpump_sw:", "fuel pump" }, + { "oilpump_sw:", "oil pump" }, + { "motorblowersfront_sw:", "motor blowers A" }, + { "motorblowersrear_sw:", "motor blowers B" }, + { "motorblowersalloff_sw:", "all motor blowers" }, + { "coolingfans_sw:", "cooling fans" }, + { "main_off_bt:", "line breaker" }, + { "main_on_bt:", "line breaker" }, + { "security_reset_bt:", "alerter" }, + { "releaser_bt:", "independent brake releaser" }, + { "sand_bt:", "sandbox" }, + { "antislip_bt:", "wheelspin brake" }, + { "horn_bt:", "horn" }, + { "hornlow_bt:", "low tone horn" }, + { "hornhigh_bt:", "high tone horn" }, + { "whistle_bt:", "whistle" }, + { "fuse_bt:", "motor overload relay reset" }, + { "converterfuse_bt:", "converter overload relay reset" }, + { "stlinoff_bt:", "motor connectors" }, + { "doorleftpermit_sw:", "left door (permit)" }, + { "doorrightpermit_sw:", "right door (permit)" }, + { "doorpermitpreset_sw:", "door (permit)" }, + { "door_left_sw:", "left door" }, + { "door_right_sw:", "right door" }, + { "doorlefton_sw:", "left door (open)" }, + { "doorrighton_sw:", "right door (open)" }, + { "doorleftoff_sw:", "left door (close)" }, + { "doorrightoff_sw:", "right door (close)" }, + { "doorallon_sw:", "all doors (open)" }, + { "dooralloff_sw:", "all doors (close)" }, + { "doorstep_sw:", "doorstep" }, + { "doormode_sw", "door control mode" }, + { "departure_signal_bt:", "departure signal" }, + { "upperlight_sw:", "upper headlight" }, + { "leftlight_sw:", "left headlight" }, + { "rightlight_sw:", "right headlight" }, + { "dimheadlights_sw:", "headlights dimmer" }, + { "leftend_sw:", "left marker light" }, + { "rightend_sw:", "right marker light" }, + { "lights_sw:", "light pattern" }, + { "rearupperlight_sw:", "rear upper headlight" }, + { "rearleftlight_sw:", "rear left headlight" }, + { "rearrightlight_sw:", "rear right headlight" }, + { "rearleftend_sw:", "rear left marker light" }, + { "rearrightend_sw:", "rear right marker light" }, + { "compressor_sw:", "compressor" }, + { "compressorlocal_sw:", "local compressor" }, + { "converter_sw:", "converter" }, + { "converterlocal_sw:", "local converter" }, + { "converteroff_sw:", "converter" }, + { "main_sw:", "line breaker" }, + { "radio_sw:", "radio" }, + { "radiochannel_sw:", "radio channel" }, + { "radiochannelprev_sw:", "radio channel" }, + { "radiochannelnext_sw:", "radio channel" }, + { "radiotest_sw:", "radiostop test" }, + { "radiostop_sw:", "radiostop" }, + { "pantfront_sw:", "pantograph A" }, + { "pantrear_sw:", "pantograph B" }, + { "pantfrontoff_sw:", "pantograph A" }, + { "pantrearoff_sw:", "pantograph B" }, + { "pantalloff_sw:", "all pantographs" }, + { "pantselected_sw:", "selected pantograph" }, + { "pantselectedoff_sw:", "selected pantograph" }, + { "pantcompressor_sw:", "pantograph compressor" }, + { "pantcompressorvalve_sw:", "pantograph 3 way valve" }, + { "trainheating_sw:", "heating" }, + { "signalling_sw:", "braking indicator" }, + { "door_signalling_sw:", "door locking" }, + { "nextcurrent_sw:", "current indicator source" }, + { "instrumentlight_sw:", "instrument light" }, + { "dashboardlight_sw:", "dashboard light" }, + { "timetablelight_sw:", "timetable light" }, + { "cablight_sw:", "interior light" }, + { "cablightdim_sw:", "interior light dimmer" }, + { "battery_sw:", "battery" }, + { "universal0:", "interactive part" }, + { "universal1:", "interactive part" }, + { "universal2:", "interactive part" }, + { "universal3:", "interactive part" }, + { "universal4:", "interactive part" }, + { "universal5:", "interactive part" }, + { "universal6:", "interactive part" }, + { "universal7:", "interactive part" }, + { "universal8:", "interactive part" }, + { "universal9:", "interactive part" } + }; + + auto const it = cabcontrols_labels.find( Label ); return ( - lookup != m_cabcontrols.end() ? - lookup->second : + it != cabcontrols_labels.end() ? + lookup_s(it->second) : "" ); } - -std::vector strings; - -std::unordered_map m_cabcontrols; - -} // namespace locale - -//--------------------------------------------------------------------------- diff --git a/translation.h b/translation.h index 705b8273..b6d70793 100644 --- a/translation.h +++ b/translation.h @@ -12,9 +12,8 @@ http://mozilla.org/MPL/2.0/. #include #include -namespace locale { +/* -enum string { driver_aid_header, driver_aid_throttle, driver_aid_speedlimit, @@ -222,18 +221,25 @@ enum string { cab_universal9, string_count + +*/ + +class locale { +public: + static void init(); + static std::string label_cab_control(const std::string &Label); + + static const char* lookup(const char *msg, bool constant = true); + static const std::string& lookup_s(const std::string &msg, bool constant = true); + +private: + static void parse_translation(std::istream &stream); + static std::string parse_c_literal(const std::string &str); + + static std::unordered_map lang_mapping; + static std::unordered_map pointer_cache; }; -void - init(); -std::string - label_cab_control( std::string const &Label ); - -extern std::vector strings; - -extern std::unordered_map m_cabcontrols; - -} - -//--------------------------------------------------------------------------- +#define LOC_STR(x) locale::lookup_s(#x) +#define LOC_STR_C(x) locale::lookup(#x) diff --git a/uilayer.cpp b/uilayer.cpp index ebdc098d..327ff2bd 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -130,6 +130,7 @@ bool ui_layer::init(GLFWwindow *Window) ImGui::CreateContext(); m_imguiio = &ImGui::GetIO(); + m_imguiio->ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange; // m_imguiio->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // m_imguiio->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; @@ -147,19 +148,14 @@ bool ui_layer::init(GLFWwindow *Window) ImGui::StyleColorsDark(); ImGui_ImplGlfw_InitForOpenGL(m_window); #ifdef EU07_USEIMGUIIMPLOPENGL2 - ImGui_ImplOpenGL2_Init(); - ImGui_ImplOpenGL2_NewFrame(); + ImGui_ImplOpenGL2_Init(); #else if (Global.gfx_usegles) ImGui_ImplOpenGL3_Init("#version 300 es\nprecision highp float;"); else - ImGui_ImplOpenGL3_Init("#version 330 core"); - ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplOpenGL3_Init("#version 330 core"); #endif - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - return true; } @@ -250,15 +246,21 @@ void ui_layer::render() ImGui::Render(); #ifdef EU07_USEIMGUIIMPLOPENGL2 - ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); - ImGui_ImplOpenGL2_NewFrame(); + ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); #else - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); #endif +} - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); +void ui_layer::begin_ui_frame() +{ +#ifdef EU07_USEIMGUIIMPLOPENGL2 + ImGui_ImplOpenGL2_NewFrame(); +#else + ImGui_ImplOpenGL3_NewFrame(); +#endif + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); } void ui_layer::render_quit_widget() @@ -347,6 +349,9 @@ void ui_layer::render_panels() panel->render(); for (auto &panel : m_ownedpanels) panel->render(); + + if (m_imgui_demo) + ImGui::ShowDemoWindow(&m_imgui_demo); } void ui_layer::render_tooltip() @@ -384,8 +389,10 @@ void ui_layer::render_menu_contents() if (ImGui::BeginMenu(LOC_STR(ui_windows))) { ImGui::MenuItem(LOC_STR(ui_log), "F9", &m_logpanel.is_open); - if (DebugModeFlag) + if (DebugModeFlag) { + ImGui::MenuItem("ImGui Demo", nullptr, &m_imgui_demo); ImGui::MenuItem("Headlight config", nullptr, &GfxRenderer.debug_ui_active); + } ImGui::EndMenu(); } } diff --git a/uilayer.h b/uilayer.h index c2d45b03..1c00513b 100644 --- a/uilayer.h +++ b/uilayer.h @@ -16,8 +16,6 @@ http://mozilla.org/MPL/2.0/. // GuiLayer -- basic user interface class. draws requested information on top of openGL screen -#define LOC_STR(x) locale::strings[locale::string::x].c_str() - class ui_panel { public: @@ -111,6 +109,10 @@ public: // draws requested UI elements void render(); + // begins new UI frame + // (this is separate from render() to allow for debug GUI outside of proper UI framework) + void + begin_ui_frame(); // static void @@ -147,7 +149,7 @@ protected: static bool m_cursorvisible; virtual void render_menu_contents(); - ui_log_panel m_logpanel { "Log", true }; + ui_log_panel m_logpanel { "Log", true }; private: // methods @@ -185,4 +187,5 @@ private: std::vector> m_ownedpanels; std::string m_tooltip; bool m_quit_active = false; + bool m_imgui_demo = false; }; diff --git a/widgets/perfgraphs.h b/widgets/perfgraphs.h index 56a10a3c..f00c554a 100644 --- a/widgets/perfgraphs.h +++ b/widgets/perfgraphs.h @@ -2,7 +2,7 @@ class perfgraph_panel : public ui_panel { - std::array history; + std::array history = { 0 }; size_t pos = 0; enum timers_e {