diff --git a/package/SKSE/Plugins/CommunityShaders.json b/package/SKSE/Plugins/CommunityShaders.json index 0991720ad..4f351b544 100644 --- a/package/SKSE/Plugins/CommunityShaders.json +++ b/package/SKSE/Plugins/CommunityShaders.json @@ -1,4 +1,7 @@ { + "Menu": { + "Toggle Key": 35 + }, "General": { "Enable Async": true, "Enable Disk Cache": true, diff --git a/src/Menu.cpp b/src/Menu.cpp index 6e7ea4b81..5437e139a 100644 --- a/src/Menu.cpp +++ b/src/Menu.cpp @@ -10,6 +10,7 @@ #include "Features/DistantTreeLighting.h" #include "Features/GrassCollision.h" +#define SETTING_MENU_TOGGLEKEY "Toggle Key" void SetupImGuiStyle() { @@ -18,6 +19,21 @@ void SetupImGuiStyle() } bool IsEnabled = false; +void Menu::Load(json& o_json) +{ + if (o_json[SETTING_MENU_TOGGLEKEY].is_number_unsigned()) { + toggleKey = o_json[SETTING_MENU_TOGGLEKEY]; + } +} + +void Menu::Save(json& o_json) +{ + json menu; + menu[SETTING_MENU_TOGGLEKEY] = toggleKey; + + o_json["Menu"] = menu; +} + RE::BSEventNotifyControl Menu::ProcessEvent(RE::InputEvent* const* a_event, RE::BSTEventSource* a_eventSource) { if (!a_event || !a_eventSource) @@ -32,6 +48,7 @@ RE::BSEventNotifyControl Menu::ProcessEvent(RE::InputEvent* const* a_event, RE:: auto scan_code = button->GetIDCode(); uint32_t key = MapVirtualKeyEx(scan_code, MAPVK_VSC_TO_VK_EX, GetKeyboardLayout(0)); + switch (scan_code) { case DIK_LEFTARROW: key = VK_LEFT; @@ -117,7 +134,14 @@ RE::BSEventNotifyControl Menu::ProcessEvent(RE::InputEvent* const* a_event, RE:: switch (button->device.get()) { case RE::INPUT_DEVICE::kKeyboard: - if (key == VK_END && !button->IsPressed()) { + if (key == toggleKey && !button->IsPressed()) { + + // Avoid closing menu when setting the toggle key + if (settingToggleKey) { + settingToggleKey = false; + break; + } + IsEnabled = !IsEnabled; if (const auto controlMap = RE::ControlMap::GetSingleton()) { controlMap->ignoreKeyboardMouse = IsEnabled; @@ -186,6 +210,36 @@ void Menu::DrawSettings() ImGui::Spacing(); + if (ImGui::CollapsingHeader("Menu")) { + + // Check if we're waiting for input + if (settingToggleKey) { + // Loop over all the keys and check if any of them are pressed + for (int i = 0; i < IM_ARRAYSIZE(ImGui::GetIO().KeysDown); i++) { + if (ImGui::IsKeyPressed(i)) { + // If a key is pressed, set the selected key code and break out of the loop + toggleKey = i; + break; + } + } + } + if (settingToggleKey) + { + ImGui::Text("Press any key to set as toggle key..."); + } + else + { + ImGui::Text("Toggle Key:"); + ImGui::SameLine(); + ImGui::TextColored(ImVec4(1, 1, 0, 1), "%s", KeyIdToString(toggleKey)); + + ImGui::SameLine(); + if (ImGui::Button("Change")) { + settingToggleKey = true; + } + } + } + if (ImGui::CollapsingHeader("General", ImGuiTreeNodeFlags_DefaultOpen)) { bool useCustomShaders = shaderCache.IsEnabled(); if (ImGui::Checkbox("Enable Shaders", &useCustomShaders)) { @@ -273,4 +327,31 @@ void Menu::DrawOverlay() ImGui::GetIO().MouseDrawCursor = true; DrawSettings(); } -} \ No newline at end of file +} + +const char* Menu::KeyIdToString(uint32_t key) +{ + if (key >= 256) + return std::string().c_str(); + + static const char* keyboard_keys_international[256] = { + "", "Left Mouse", "Right Mouse", "Cancel", "Middle Mouse", "X1 Mouse", "X2 Mouse", "", "Backspace", "Tab", "", "", "Clear", "Enter", "", "", + "Shift", "Control", "Alt", "Pause", "Caps Lock", "", "", "", "", "", "", "Escape", "", "", "", "", + "Space", "Page Up", "Page Down", "End", "Home", "Left Arrow", "Up Arrow", "Right Arrow", "Down Arrow", "Select", "", "", "Print Screen", "Insert", "Delete", "Help", + "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", "Left Windows", "Right Windows", "Apps", "", "Sleep", + "Numpad 0", "Numpad 1", "Numpad 2", "Numpad 3", "Numpad 4", "Numpad 5", "Numpad 6", "Numpad 7", "Numpad 8", "Numpad 9", "Numpad *", "Numpad +", "", "Numpad -", "Numpad Decimal", "Numpad /", + "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", + "F17", "F18", "F19", "F20", "F21", "F22", "F23", "F24", "", "", "", "", "", "", "", "", + "Num Lock", "Scroll Lock", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "Left Shift", "Right Shift", "Left Control", "Right Control", "Left Menu", "Right Menu", "Browser Back", "Browser Forward", "Browser Refresh", "Browser Stop", "Browser Search", "Browser Favorites", "Browser Home", "Volume Mute", "Volume Down", "Volume Up", + "Next Track", "Previous Track", "Media Stop", "Media Play/Pause", "Mail", "Media Select", "Launch App 1", "Launch App 2", "", "", "OEM ;", "OEM +", "OEM ,", "OEM -", "OEM .", "OEM /", + "OEM ~", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "OEM [", "OEM \\", "OEM ]", "OEM '", "OEM 8", + "", "", "OEM <", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "Attn", "CrSel", "ExSel", "Erase EOF", "Play", "Zoom", "", "PA1", "OEM Clear", "" + }; + + return keyboard_keys_international[key]; +} diff --git a/src/Menu.h b/src/Menu.h index 5e3993364..66332cd53 100644 --- a/src/Menu.h +++ b/src/Menu.h @@ -13,6 +13,9 @@ class Menu : public RE::BSTEventSink return &menu; } + void Load(json& o_json); + void Save(json& o_json); + RE::BSEventNotifyControl ProcessEvent(RE::InputEvent* const* a_event, RE::BSTEventSource* a_eventSource) override; @@ -20,7 +23,10 @@ class Menu : public RE::BSTEventSink void DrawOverlay(); private: - Menu() - { - } + + uint32_t toggleKey = VK_END; + bool settingToggleKey = false; + + Menu() { } + const char* KeyIdToString(uint32_t key); }; diff --git a/src/State.cpp b/src/State.cpp index 24f125010..d0b1bd5f1 100644 --- a/src/State.cpp +++ b/src/State.cpp @@ -3,6 +3,7 @@ #include #include "ShaderCache.h" +#include "Menu.h" #include "Features/Clustered.h" #include "Features/GrassLighting.h" @@ -57,9 +58,29 @@ void State::Setup() void State::Load() { auto& shaderCache = SIE::ShaderCache::Instance(); - std::ifstream i(L"Data\\SKSE\\Plugins\\CommunityShaders.json"); + + std::string configPath = "Data\\SKSE\\Plugins\\CommunityShaders.json"; + + std::ifstream i(configPath); + if (!i.is_open()) { + logger::error("Error opening config file ({})\n", configPath); + return; + } + json settings; - i >> settings; + try + { + i >> settings; + } + catch (const nlohmann::json::parse_error& e) + { + logger::error("Error parsing json config file ({}) : {}\n", configPath, e.what()); + return; + } + + if (settings["Menu"].is_object()) { + Menu::GetSingleton()->Load(settings["Menu"]); + } if (settings["General"].is_object()) { json& general = settings["General"]; @@ -68,10 +89,10 @@ void State::Load() shaderCache.SetEnabled(general["Enable Shaders"]); if (general["Enable Disk Cache"].is_boolean()) - shaderCache.SetEnabled(general["Enable Disk Cache"]); + shaderCache.SetDiskCache(general["Enable Disk Cache"]); if (general["Enable Async"].is_boolean()) - shaderCache.SetEnabled(general["Enable Async"]); + shaderCache.SetAsync(general["Enable Async"]); } if (settings["Replace Original Shaders"].is_object()) { @@ -95,6 +116,8 @@ void State::Save() std::ofstream o(L"Data\\SKSE\\Plugins\\CommunityShaders.json"); json settings; + Menu::GetSingleton()->Save(settings); + json general; general["Enable Shaders"] = shaderCache.IsEnabled(); general["Enable Disk Cache"] = shaderCache.IsDiskCache();