diff --git a/source/main/gui/panels/GUI_GameChatBox.cpp b/source/main/gui/panels/GUI_GameChatBox.cpp index 1530744499..da226ec6db 100644 --- a/source/main/gui/panels/GUI_GameChatBox.cpp +++ b/source/main/gui/panels/GUI_GameChatBox.cpp @@ -26,6 +26,7 @@ #include "Console.h" #include "GUIManager.h" #include "Language.h" +#include "InputEngine.h" #include // strtok, strncmp #include @@ -73,9 +74,11 @@ void GameChatBox::Draw() ImGui::Begin("ChatMessages", nullptr, msg_flags | ImGuiWindowFlags_NoInputs); } - if (initialized == true) + if (initialized) { - App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _LC("ChatBox", "Welcome to Rigs of Rods!")); + App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, + fmt::format(_LC("ChatBox", "Press {} to spawn a vehicle"), + App::GetInputEngine()->getEventCommandTrimmed(EV_COMMON_GET_NEW_VEHICLE)), "lightbulb.png"); initialized = false; } diff --git a/source/main/gui/panels/GUI_SimActorStats.cpp b/source/main/gui/panels/GUI_SimActorStats.cpp index d038cbc6f6..d660a6e0fe 100644 --- a/source/main/gui/panels/GUI_SimActorStats.cpp +++ b/source/main/gui/panels/GUI_SimActorStats.cpp @@ -40,6 +40,7 @@ void SimActorStats::Draw(RoR::GfxActor* actorx) ImGuiWindowFlags flags = ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar; ImGui::SetNextWindowPos(ImVec2(theme.screen_edge_padding.x, (theme.screen_edge_padding.y + 150))); + ImGui::PushStyleColor(ImGuiCol_WindowBg, theme.semitransparent_window_bg); ImGui::Begin("SimActorStats", nullptr, flags); RoR::ImTextWrappedColorMarked(actorx->GetActor()->getTruckName()); @@ -221,6 +222,7 @@ void SimActorStats::Draw(RoR::GfxActor* actorx) ImGui::NewLine(); ImGui::End(); + ImGui::PopStyleColor(1); // WindowBg } void SimActorStats::UpdateStats(float dt, Actor* actor) diff --git a/source/main/gui/panels/GUI_SimPerfStats.cpp b/source/main/gui/panels/GUI_SimPerfStats.cpp index e857984c77..a1290f1b74 100644 --- a/source/main/gui/panels/GUI_SimPerfStats.cpp +++ b/source/main/gui/panels/GUI_SimPerfStats.cpp @@ -24,6 +24,7 @@ #include "AppContext.h" #include "GUIManager.h" #include "Language.h" +#include #include #include @@ -39,13 +40,42 @@ void SimPerfStats::Draw() ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar; ImGui::SetNextWindowPos(theme.screen_edge_padding); ImGui::PushStyleColor(ImGuiCol_WindowBg, theme.semitransparent_window_bg); + ImVec2 histogram_size = ImVec2(60.f, 35.f); ImGui::Begin("FPS", &m_is_visible, flags); const Ogre::RenderTarget::FrameStats& stats = App::GetAppContext()->GetRenderWindow()->getStatistics(); - ImGui::Text("%s%.2f", _LC("SimPerfStats", "Current FPS: "), stats.lastFPS); - ImGui::Text("%s%.2f", _LC("SimPerfStats", "Average FPS: "), stats.avgFPS); - ImGui::Text("%s%.2f", _LC("SimPerfStats", "Worst FPS: "), stats.worstFPS); - ImGui::Text("%s%.2f", _LC("SimPerfStats", "Best FPS: "), stats.bestFPS); + + std::string title = "FPS"; + ImGui::SetCursorPosX((ImGui::GetWindowSize().x - ImGui::CalcTextSize(title.c_str()).x) * 0.5f); + ImGui::Text(title.c_str()); + + std::string a = "Current"; + ImGui::SetCursorPosX((histogram_size.x + (3 * ImGui::GetStyle().ItemSpacing.x) + ImGui::GetStyle().FramePadding.x - ImGui::CalcTextSize(a.c_str()).x) * 0.5f); + ImGui::Text("%s", _LC("SimPerfStats", a.c_str())); + ImGui::SameLine(); + + std::string b = "Average"; + ImGui::SetCursorPosX((histogram_size.x * 3 + (5 * ImGui::GetStyle().ItemSpacing.x) + ImGui::GetStyle().FramePadding.x - ImGui::CalcTextSize(b.c_str()).x) * 0.5f); + ImGui::Text("%s", _LC("SimPerfStats", b.c_str())); + ImGui::SameLine(); + + std::string c = "Worst"; + ImGui::SetCursorPosX((histogram_size.x * 5 + (7 * ImGui::GetStyle().ItemSpacing.x) + ImGui::GetStyle().FramePadding.x - ImGui::CalcTextSize(c.c_str()).x) * 0.5f); + ImGui::Text("%s", _LC("SimPerfStats", c.c_str())); + ImGui::SameLine(); + + std::string d = "Best"; + ImGui::SetCursorPosX((histogram_size.x * 7 + (9 * ImGui::GetStyle().ItemSpacing.x) + ImGui::GetStyle().FramePadding.x - ImGui::CalcTextSize(d.c_str()).x) * 0.5f); + ImGui::Text("%s", _LC("SimPerfStats", d.c_str())); + + ImGui::PlotHistogram("", &stats.lastFPS, 1, 0, this->Convert(stats.lastFPS).c_str(), 0.f, stats.bestFPS, histogram_size); + ImGui::SameLine(); + ImGui::PlotHistogram("", &stats.avgFPS, 1, 0, this->Convert(stats.avgFPS).c_str(), 0.f, stats.bestFPS, histogram_size); + ImGui::SameLine(); + ImGui::PlotHistogram("", &stats.worstFPS, 1, 0, this->Convert(stats.worstFPS).c_str(), 0.f, stats.bestFPS, histogram_size); + ImGui::SameLine(); + ImGui::PlotHistogram("", &stats.bestFPS, 1, 0, this->Convert(stats.bestFPS).c_str(), 0.f, stats.bestFPS, histogram_size); + ImGui::Separator(); ImGui::Text("%s%zu", _LC("SimPerfStats", "Triangle count: "), stats.triangleCount); ImGui::Text("%s%zu", _LC("SimPerfStats", "Batch count: "), stats.batchCount); @@ -53,3 +83,10 @@ void SimPerfStats::Draw() ImGui::End(); ImGui::PopStyleColor(1); // WindowBg } + +std::string SimPerfStats::Convert(const float f) +{ + std::stringstream s; + s << std::fixed << std::setprecision(2) << f; + return s.str(); +} \ No newline at end of file diff --git a/source/main/gui/panels/GUI_SimPerfStats.h b/source/main/gui/panels/GUI_SimPerfStats.h index 70c98a5fd2..b64ba4e48c 100644 --- a/source/main/gui/panels/GUI_SimPerfStats.h +++ b/source/main/gui/panels/GUI_SimPerfStats.h @@ -34,6 +34,7 @@ class SimPerfStats private: bool m_is_visible = false; + std::string Convert(const float f); // converts const float to std::string with precision }; } // namespace GUI diff --git a/source/main/gui/panels/GUI_TopMenubar.cpp b/source/main/gui/panels/GUI_TopMenubar.cpp index df74e53dc9..5f3b4fb83f 100644 --- a/source/main/gui/panels/GUI_TopMenubar.cpp +++ b/source/main/gui/panels/GUI_TopMenubar.cpp @@ -352,7 +352,7 @@ void TopMenubar::Update() m_open_menu = TopMenu::TOPMENU_NONE; } ImGui::SameLine(); - ImGui::TextColored(GRAY_HINT_TEXT, "('NUMPAD: /')"); + ImGui::TextColored(GRAY_HINT_TEXT, "(NUMPAD: /)"); if (m_quickload) { @@ -362,12 +362,12 @@ void TopMenubar::Update() m_open_menu = TopMenu::TOPMENU_NONE; } ImGui::SameLine(); - ImGui::TextColored(GRAY_HINT_TEXT, "('NUMPAD: *')"); + ImGui::TextColored(GRAY_HINT_TEXT, "(NUMPAD: *)"); } ImGui::Separator(); - ImGui::TextColored(GRAY_HINT_TEXT, _LC("TopMenubar", "(Save with 'CTRL+ALT+1..5')")); + ImGui::TextColored(GRAY_HINT_TEXT, _LC("TopMenubar", "(Save with CTRL+ALT+1..5)")); for (int i = 1; i <= 5; i++) { Ogre::String name = _LC("TopMenubar", "Empty Slot"); @@ -384,7 +384,7 @@ void TopMenubar::Update() } } - ImGui::TextColored(GRAY_HINT_TEXT, _LC("TopMenubar", "(Load with 'ALT+1..5')")); + ImGui::TextColored(GRAY_HINT_TEXT, _LC("TopMenubar", "(Load with ALT+1..5)")); for (int i = 1; i <= 5; i++) { if (!m_savegame_names[i].empty()) @@ -624,8 +624,8 @@ void TopMenubar::Update() ImGui::Separator(); ImGui::TextColored(GRAY_HINT_TEXT, _LC("TopMenubar", "Live diagnostic views:")); - ImGui::TextColored(GRAY_HINT_TEXT, _LC("TopMenubar", "(Toggle with '%s')"), App::GetInputEngine()->getEventCommand(EV_COMMON_TOGGLE_DEBUG_VIEW).c_str()); - ImGui::TextColored(GRAY_HINT_TEXT, _LC("TopMenubar", "(Cycle with '%s')"), App::GetInputEngine()->getEventCommand(EV_COMMON_CYCLE_DEBUG_VIEWS).c_str()); + ImGui::TextColored(GRAY_HINT_TEXT, _LC("TopMenubar", "(Toggle with %s)"), App::GetInputEngine()->getEventCommandTrimmed(EV_COMMON_TOGGLE_DEBUG_VIEW).c_str()); + ImGui::TextColored(GRAY_HINT_TEXT, _LC("TopMenubar", "(Cycle with %s)"), App::GetInputEngine()->getEventCommandTrimmed(EV_COMMON_CYCLE_DEBUG_VIEWS).c_str()); int debug_view_type = static_cast(GfxActor::DebugViewType::DEBUGVIEW_NONE); if (current_actor != nullptr) @@ -857,8 +857,8 @@ void TopMenubar::DrawSpecialStateBox(float top_offset) if (App::GetGameContext()->GetActorManager()->IsSimulationPaused() && !App::GetGuiManager()->IsGuiHidden()) { special_color = ORANGE_TEXT; - special_text = fmt::format(_LC("TopMenubar", "All physics paused, press '{}' to resume"), - App::GetInputEngine()->getEventCommand(EV_COMMON_TOGGLE_PHYSICS)); + special_text = fmt::format(_LC("TopMenubar", "All physics paused, press {} to resume"), + App::GetInputEngine()->getEventCommandTrimmed(EV_COMMON_TOGGLE_PHYSICS)); content_width = ImGui::CalcTextSize(special_text.c_str()).x; } else if (App::GetGameContext()->GetPlayerActor() && @@ -866,8 +866,8 @@ void TopMenubar::DrawSpecialStateBox(float top_offset) !App::GetGuiManager()->IsGuiHidden()) { special_color = GREEN_TEXT; - special_text = fmt::format(_LC("TopMenubar", "Vehicle physics paused, press '{}' to resume"), - App::GetInputEngine()->getEventCommand(EV_TRUCK_TOGGLE_PHYSICS)); + special_text = fmt::format(_LC("TopMenubar", "Vehicle physics paused, press {} to resume"), + App::GetInputEngine()->getEventCommandTrimmed(EV_TRUCK_TOGGLE_PHYSICS)); content_width = ImGui::CalcTextSize(special_text.c_str()).x; } else if (App::GetGameContext()->GetPlayerActor() && @@ -914,6 +914,13 @@ void TopMenubar::DrawSpecialStateBox(float top_offset) special_text_d = fmt::format("{:02d}.{:02d}.{:02d}", (int)(best_time) / 60, (int)(best_time) % 60, (int)(best_time * 100.0) % 100); } } + else if (App::sim_state->getEnum() == SimState::EDITOR_MODE) + { + special_color = GREEN_TEXT; + special_text = fmt::format(_LC("TopMenubar", "Terrain editing mode, press {} to save and exit"), + App::GetInputEngine()->getEventCommandTrimmed(EV_COMMON_TOGGLE_TERRAIN_EDITOR)); + content_width = ImGui::CalcTextSize(special_text.c_str()).x; + } // Draw box if needed if (!special_text.empty()) diff --git a/source/main/main.cpp b/source/main/main.cpp index ccb7e4e368..0c44402362 100644 --- a/source/main/main.cpp +++ b/source/main/main.cpp @@ -502,11 +502,9 @@ int main(int argc, char *argv[]) #ifdef USE_SOCKETW if (App::mp_state->getEnum() == MpState::CONNECTED) { - char text[300]; - std::snprintf(text, 300, _L("Press %s to start chatting"), - RoR::App::GetInputEngine()->getKeyForCommand(EV_COMMON_ENTER_CHATMODE).c_str()); - App::GetConsole()->putMessage( - Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, text); + App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, + fmt::format(_LC("ChatBox", "Press {} to start chatting"), + App::GetInputEngine()->getEventCommandTrimmed(EV_COMMON_ENTER_CHATMODE)), "lightbulb.png"); } #endif // USE_SOCKETW if (App::io_outgauge_mode->getInt() > 0) @@ -705,6 +703,9 @@ int main(int argc, char *argv[]) App::sim_state->setVal((int)SimState::EDITOR_MODE); App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Entered terrain editing mode")); + App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, + fmt::format(_L("Press {} or middle mouse click to select an object"), + App::GetInputEngine()->getEventCommandTrimmed(EV_COMMON_ENTER_OR_EXIT_TRUCK)), "lightbulb.png"); } break; @@ -812,17 +813,19 @@ int main(int argc, char *argv[]) if (App::app_state->getEnum() == AppState::SIMULATION) { - App::GetGameContext()->GetCharacterFactory()->Update(dt); // Character MUST be updated before CameraManager, otherwise camera position is always 1 frame behind the character position, causing stuttering. - App::GetCameraManager()->UpdateInputEvents(dt); - App::GetOverlayWrapper()->update(dt); if (App::sim_state->getEnum() == SimState::EDITOR_MODE) { App::GetGameContext()->UpdateSkyInputEvents(dt); App::GetSimTerrain()->GetTerrainEditor()->UpdateInputEvents(dt); } - else if (App::sim_state->getEnum() == SimState::RUNNING) + else + { + App::GetGameContext()->GetCharacterFactory()->Update(dt); // Character MUST be updated before CameraManager, otherwise camera position is always 1 frame behind the character position, causing stuttering. + } + App::GetCameraManager()->UpdateInputEvents(dt); + App::GetOverlayWrapper()->update(dt); + if (App::sim_state->getEnum() == SimState::RUNNING) { - if (App::GetCameraManager()->GetCurrentBehavior() != CameraManager::CAMERA_BEHAVIOR_FREE) { App::GetGameContext()->UpdateSimInputEvents(dt); diff --git a/source/main/terrain/TerrainEditor.cpp b/source/main/terrain/TerrainEditor.cpp index 52a12f2d69..82e16a7445 100644 --- a/source/main/terrain/TerrainEditor.cpp +++ b/source/main/terrain/TerrainEditor.cpp @@ -135,18 +135,18 @@ void TerrainEditor::UpdateInputEvents(float dt) m_rotation_axis = 0; } UTFString ssmsg = _L("Rotating: ") + axis; - App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, ssmsg, "infromation.png"); + App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, ssmsg, "information.png"); } if (App::GetInputEngine()->isKeyDownValueBounce(OIS::KC_SPACE)) { m_object_tracking = !m_object_tracking; UTFString ssmsg = m_object_tracking ? _L("Enabled object tracking") : _L("Disabled object tracking"); - App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, ssmsg, "infromation.png"); + App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, ssmsg, "information.png"); } if (m_object_index != -1 && update) { String ssmsg = _L("Selected object: [") + TOSTRING(m_object_index) + "/" + TOSTRING(object_list.size()) + "] (" + object_list[m_object_index].name + ")"; - App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, ssmsg, "infromation.png"); + App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, ssmsg, "information.png"); if (m_object_tracking) { App::GetGameContext()->GetPlayerCharacter()->setPosition(object_list[m_object_index].node->getPosition()); diff --git a/source/main/utils/InputEngine.cpp b/source/main/utils/InputEngine.cpp index 236f287b18..ff89c12df5 100644 --- a/source/main/utils/InputEngine.cpp +++ b/source/main/utils/InputEngine.cpp @@ -27,6 +27,8 @@ #include "GUIManager.h" #include "Language.h" +#include + using namespace RoR; const char* mOISDeviceType[6] = {"Unknown Device", "Keyboard", "Mouse", "JoyStick", "Tablet", "Other Device"}; @@ -81,7 +83,7 @@ InputEvent eventInfo[] = { // Common: UI {"COMMON_CONSOLE_TOGGLE", EV_COMMON_CONSOLE_TOGGLE, "Keyboard EXPL+GRAVE", _LC("InputEvent", "show / hide the console")}, - {"COMMON_ENTER_CHATMODE", EV_COMMON_ENTER_CHATMODE, "Keyboard Y", _LC("InputEvent", "enter the chat")}, + {"COMMON_ENTER_CHATMODE", EV_COMMON_ENTER_CHATMODE, "Keyboard EXPL+Y", _LC("InputEvent", "enter the chat")}, {"COMMON_SEND_CHAT", EV_COMMON_SEND_CHAT, "Keyboard RETURN", _LC("InputEvent", "sends the entered text")}, {"COMMON_HIDE_GUI", EV_COMMON_HIDE_GUI, "Keyboard EXPL+U", _LC("InputEvent", "hide all GUI elements")}, {"COMMON_TOGGLE_DASHBOARD", EV_COMMON_TOGGLE_DASHBOARD, "Keyboard EXPL+CTRL+U", _LC("InputEvent", "display or hide the dashboard overlay")}, @@ -758,6 +760,12 @@ String InputEngine::getEventCommand(int eventID) return ""; } +std::string InputEngine::getEventCommandTrimmed(int eventID) +{ + std::string result = regex_replace(App::GetInputEngine()->getEventCommand(eventID).c_str(), std::regex("EXPL\\+"), ""); + return result; +} + String InputEngine::getTriggerCommand(event_trigger_t const& evt) { return this->composeEventCommandString(evt); diff --git a/source/main/utils/InputEngine.h b/source/main/utils/InputEngine.h index 8473ffa743..9d65a083db 100644 --- a/source/main/utils/InputEngine.h +++ b/source/main/utils/InputEngine.h @@ -539,6 +539,7 @@ class InputEngine : public ZeroedMemoryAllocator void windowResized(Ogre::RenderWindow* rw); OIS::ForceFeedback* getForceFeedbackDevice() { return mForceFeedback; }; + std::string getEventCommandTrimmed(int eventID); // Removes EXPL protected: