From cb220fd8c101b531a32b7c1d57a3c4953f5cd2c8 Mon Sep 17 00:00:00 2001 From: FlayaN Date: Sun, 20 Oct 2024 21:56:41 +0200 Subject: [PATCH] feat: add core feature support --- CMakeLists.txt | 19 ++++-- README.md | 3 +- features/Dynamic Cubemaps/CORE | 0 features/Extended Materials/CORE | 0 features/Frame Generation/CORE | 0 src/Feature.h | 8 +++ src/Features/DynamicCubemaps.h | 1 + src/Features/ExtendedMaterials.h | 1 + src/Menu.cpp | 99 ++++++++++++++++++++------------ 9 files changed, 88 insertions(+), 43 deletions(-) create mode 100644 features/Dynamic Cubemaps/CORE create mode 100644 features/Extended Materials/CORE create mode 100644 features/Frame Generation/CORE diff --git a/CMakeLists.txt b/CMakeLists.txt index da1fe64f5..4ef92b328 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,6 +162,7 @@ if(AUTO_PLUGIN_DEPLOYMENT OR AIO_ZIP_TO_DIST) COMMAND ${CMAKE_COMMAND} -E copy_directory ${FEATURE_PATHS} "${AIO_DIR}" COMMAND ${CMAKE_COMMAND} -E copy $ "${AIO_DIR}/SKSE/Plugins/" COMMAND ${CMAKE_COMMAND} -E copy $ "${AIO_DIR}/SKSE/Plugins/" + COMMAND ${CMAKE_COMMAND} -E remove "${AIO_DIR}/CORE" ) add_custom_command( @@ -209,17 +210,24 @@ endif() # Zip base CommunityShaders and all addons as their own 7z in dist folder if(ZIP_TO_DIST) set(ZIP_DIR "${CMAKE_CURRENT_BINARY_DIR}/zip") + message("Copying base CommunityShader into ${ZIP_DIR}.") add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E remove_directory "${ZIP_DIR}" ${CMAKE_SOURCE_DIR}/dist COMMAND ${CMAKE_COMMAND} -E make_directory "${ZIP_DIR}/SKSE/Plugins" ${CMAKE_SOURCE_DIR}/dist - ) - - message("Copying base CommunityShader into ${ZIP_DIR}.") - add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/package "${ZIP_DIR}" COMMAND ${CMAKE_COMMAND} -E copy $ "${ZIP_DIR}/SKSE/Plugins/" COMMAND ${CMAKE_COMMAND} -E copy $ "${ZIP_DIR}/SKSE/Plugins/" ) + foreach(FEATURE_PATH ${FEATURE_PATHS}) + if (EXISTS "${FEATURE_PATH}/CORE") + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${FEATURE_PATH} "${ZIP_DIR}" + ) + endif() + endforeach() + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E remove "${ZIP_DIR}/CORE" + ) set(TARGET_ZIP "${PROJECT_NAME}-${UTC_NOW}.7z") message("Zipping ${ZIP_DIR} to ${CMAKE_SOURCE_DIR}/dist/${TARGET_ZIP}") @@ -229,6 +237,9 @@ if(ZIP_TO_DIST) ) foreach(FEATURE_PATH ${FEATURE_PATHS}) + if (EXISTS "${FEATURE_PATH}/CORE") + continue() + endif() get_filename_component(FEATURE ${FEATURE_PATH} NAME) message("Zipping ${FEATURE_PATH} to ${CMAKE_SOURCE_DIR}/dist/${FEATURE}-${UTC_NOW}.7z") add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD diff --git a/README.md b/README.md index 4358e10c0..215df8d2b 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,8 @@ If you want an example CMakeUserPreset to start off with you can copy the `CMake #### ZIP_TO_DIST * This option is default `"ON"` * Make sure `"ZIP_TO_DIST"` is set to `"ON"` in `CMakeUserPresets.json` -* This will create a zip for each feature and one for the base Community shaders in /dist containing +* This will create a zip for each feature and one for the base Community shaders in /dist +* If having a file with name `CORE` in the root of the features folder it will instead be merged into the core zip #### TRACY_SUPPORT * This option is default `"OFF"` * This will enable tracy support, might need to delete build folder when this option is changed diff --git a/features/Dynamic Cubemaps/CORE b/features/Dynamic Cubemaps/CORE new file mode 100644 index 000000000..e69de29bb diff --git a/features/Extended Materials/CORE b/features/Extended Materials/CORE new file mode 100644 index 000000000..e69de29bb diff --git a/features/Frame Generation/CORE b/features/Frame Generation/CORE new file mode 100644 index 000000000..e69de29bb diff --git a/src/Feature.h b/src/Feature.h index a69ec1513..1b90e3db7 100644 --- a/src/Feature.h +++ b/src/Feature.h @@ -19,6 +19,14 @@ struct Feature */ virtual bool SupportsVR() { return false; } + /** + * Whether the feature is a CORE feature + * This will place it under "Core Features" in UI + * Also need to create a file named "CORE" in the root of the feature folder + * if it should be merged into main cs zip file + */ + virtual bool IsCore() const { return false; } + virtual void SetupResources() {} virtual void Reset() {} diff --git a/src/Features/DynamicCubemaps.h b/src/Features/DynamicCubemaps.h index 8860722f6..810f75fe4 100644 --- a/src/Features/DynamicCubemaps.h +++ b/src/Features/DynamicCubemaps.h @@ -144,4 +144,5 @@ struct DynamicCubemaps : Feature void Irradiance(bool a_reflections); virtual bool SupportsVR() override { return true; }; + virtual bool IsCore() const override { return true; }; }; diff --git a/src/Features/ExtendedMaterials.h b/src/Features/ExtendedMaterials.h index f89b33bcd..ffc7f4898 100644 --- a/src/Features/ExtendedMaterials.h +++ b/src/Features/ExtendedMaterials.h @@ -42,4 +42,5 @@ struct ExtendedMaterials : Feature virtual void RestoreDefaultSettings() override; virtual bool SupportsVR() override { return true; }; + virtual bool IsCore() const override { return true; }; }; diff --git a/src/Menu.cpp b/src/Menu.cpp index 2e174a12a..bafc080b8 100644 --- a/src/Menu.cpp +++ b/src/Menu.cpp @@ -148,7 +148,7 @@ void Menu::SetupImGuiStyle() const colors[ImGuiCol_TextDisabled] = textDisabled; colors[ImGuiCol_FrameBg] = themeSettings.Palette.Background; - colors[ImGuiCol_FrameBgHovered] = colors[ImGuiCol_FrameBg]; + colors[ImGuiCol_FrameBgHovered] = headerHovered; colors[ImGuiCol_FrameBgActive] = colors[ImGuiCol_FrameBg]; colors[ImGuiCol_DockingEmptyBg] = themeSettings.Palette.Border; @@ -424,49 +424,60 @@ void Menu::DrawSettings() bool hasFailedMessage = !feat->failedLoadedMessage.empty(); auto& themeSettings = Menu::GetSingleton()->settings.Theme; - ImVec4 textColor; + if (ImGui::BeginTable("##FeatureButtons", 2, ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableNextColumn(); - // Determine the text color based on the state - if (isDisabled) { - textColor = themeSettings.StatusPalette.Disable; - } else if (hasFailedMessage) { - textColor = themeSettings.StatusPalette.Error; - } else { - textColor = ImGui::GetStyleColorVec4(ImGuiCol_Text); - } - ImGui::PushStyleColor(ImGuiCol_Text, textColor); + ImVec4 textColor; - if (ImGui::Button(isDisabled ? "Enable at Boot" : "Disable at Boot", { -1, 0 })) { - bool newState = feat->ToggleAtBootSetting(); - logger::info("{}: {} at boot.", featureName, newState ? "Enabled" : "Disabled"); - } + // Determine the text color based on the state + if (isDisabled) { + textColor = themeSettings.StatusPalette.Disable; + } else if (hasFailedMessage) { + textColor = themeSettings.StatusPalette.Error; + } else { + textColor = ImGui::GetStyleColorVec4(ImGuiCol_Text); + } + ImGui::PushStyleColor(ImGuiCol_Text, textColor); - if (auto _tt = Util::HoverTooltipWrapper()) { - ImGui::Text( - "Current State: %s\n" - "%s the feature settings at boot. " - "Restart will be required to reenable. " - "This is the same as deleting the ini file. " - "This should remove any performance impact for the feature.", - isDisabled ? "Disabled" : "Enabled", - isDisabled ? "Enable" : "Disable"); - } + if (ImGui::Button(isDisabled ? "Enable at Boot" : "Disable at Boot", { -1, 0 })) { + bool newState = feat->ToggleAtBootSetting(); + logger::info("{}: {} at boot.", featureName, newState ? "Enabled" : "Disabled"); + } - ImGui::PopStyleColor(); + if (auto _tt = Util::HoverTooltipWrapper()) { + ImGui::Text( + "Current State: %s\n" + "%s the feature settings at boot. " + "Restart will be required to reenable. " + "This is the same as deleting the ini file. " + "This should remove any performance impact for the feature.", + isDisabled ? "Disabled" : "Enabled", + isDisabled ? "Enable" : "Disable"); + } + + ImGui::PopStyleColor(); + + ImGui::TableNextColumn(); + + if (!isDisabled && isLoaded) { + if (ImGui::Button("Restore Defaults", { -1, 0 })) { + feat->RestoreDefaultSettings(); + } + if (auto _tt = Util::HoverTooltipWrapper()) { + ImGui::Text( + "Restores the feature's settings back to their default values. " + "You will still need to Save Settings to make these changes permanent."); + } + } + + ImGui::EndTable(); + } if (hasFailedMessage) { ImGui::TextColored(themeSettings.StatusPalette.Error, feat->failedLoadedMessage.c_str()); } if (!isDisabled && isLoaded) { - if (ImGui::Button("Restore Defaults", { -1, 0 })) { - feat->RestoreDefaultSettings(); - } - if (auto _tt = Util::HoverTooltipWrapper()) { - ImGui::Text( - "Restores the feature's settings back to their default values. " - "You will still need to Save Settings to make these changes permanent."); - } if (ImGui::BeginChild("##FeatureConfigFrame", { 0, 0 }, true)) { feat->DrawSettings(); } @@ -477,17 +488,29 @@ void Menu::DrawSettings() auto& featureList = Feature::GetFeatureList(); auto sortedFeatureList{ featureList }; // need a copy so the load order is not lost - std::sort(sortedFeatureList.begin(), sortedFeatureList.end(), [](Feature* a, Feature* b) { + std::ranges::sort(sortedFeatureList, [](Feature* a, Feature* b) { return a->GetName() < b->GetName(); }); auto menuList = std::vector{ BuiltInMenu{ "General", [&]() { DrawGeneralSettings(); } }, BuiltInMenu{ "Advanced", [&]() { DrawAdvancedSettings(); } }, - BuiltInMenu{ "Display", [&]() { DrawDisplaySettings(); } }, - "Features"s + BuiltInMenu{ "Display", [&]() { DrawDisplaySettings(); } } }; - std::ranges::copy(sortedFeatureList, std::back_inserter(menuList)); + + menuList.push_back("Core Features"s); + std::ranges::copy( + sortedFeatureList | std::ranges::views::filter([](Feature* feat) { + return feat->IsCore(); + }), + std::back_inserter(menuList)); + + menuList.push_back("Features"s); + std::ranges::copy( + sortedFeatureList | std::ranges::views::filter([](Feature* feat) { + return !feat->IsCore(); + }), + std::back_inserter(menuList)); ImGui::TableNextColumn(); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);