1.5: Fuckin' UE5... #38
9 changed files with 398 additions and 249 deletions
|
@ -139,6 +139,8 @@ add_executable(MassBuilderSaveTool WIN32
|
|||
SaveTool/SaveTool_MassViewer_Weapons.cpp
|
||||
SaveTool/SaveTool_ProfileManager.cpp
|
||||
SaveTool/SaveTool_UpdateChecker.cpp
|
||||
Configuration/Configuration.h
|
||||
Configuration/Configuration.cpp
|
||||
ProfileManager/ProfileManager.h
|
||||
ProfileManager/ProfileManager.cpp
|
||||
Profile/Profile.h
|
||||
|
|
152
src/Configuration/Configuration.cpp
Normal file
152
src/Configuration/Configuration.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
#include <Corrade/Containers/Optional.h>
|
||||
#include <Corrade/Containers/Pair.h>
|
||||
#include <Corrade/Utility/Path.h>
|
||||
|
||||
#include "Configuration.h"
|
||||
|
||||
Configuration::Configuration() {
|
||||
Containers::String exe_path = Utility::Path::split(*Utility::Path::executableLocation()).first();
|
||||
_conf = Utility::Configuration{Utility::Path::join(exe_path, "MassBuilderSaveTool.ini")};
|
||||
|
||||
if(_conf.hasValue("swap_interval")) {
|
||||
_swapInterval = _conf.value<int>("swap_interval");
|
||||
}
|
||||
else {
|
||||
_conf.setValue("swap_interval", 1);
|
||||
}
|
||||
|
||||
if(_conf.hasValue("frame_limit")) {
|
||||
std::string frame_limit = _conf.value("frame_limit");
|
||||
if(frame_limit == "half_vsync") {
|
||||
_swapInterval = 2;
|
||||
}
|
||||
_conf.removeValue("frame_limit");
|
||||
}
|
||||
|
||||
if(_conf.hasValue("fps_cap")) {
|
||||
_fpsCap = _conf.value<float>("fps_cap");
|
||||
}
|
||||
else {
|
||||
_conf.setValue("fps_cap", 60.0f);
|
||||
}
|
||||
|
||||
if(_conf.hasValue("cheat_mode")) {
|
||||
_cheatMode = _conf.value<bool>("cheat_mode");
|
||||
}
|
||||
else {
|
||||
_conf.setValue("cheat_mode", _cheatMode);
|
||||
}
|
||||
|
||||
if(_conf.hasValue("advanced_mode")) {
|
||||
_advancedMode = _conf.value<bool>("advanced_mode");
|
||||
}
|
||||
else {
|
||||
_conf.setValue("advanced_mode", _advancedMode);
|
||||
}
|
||||
|
||||
if(_conf.hasValue("startup_update_check")) {
|
||||
_checkUpdatesOnStartup = _conf.value<bool>("startup_update_check");
|
||||
}
|
||||
else {
|
||||
_conf.setValue("startup_update_check", _checkUpdatesOnStartup);
|
||||
}
|
||||
|
||||
if(_conf.hasValue("skip_disclaimer")) {
|
||||
_skipDisclaimer = _conf.value<bool>("skip_disclaimer");
|
||||
}
|
||||
else {
|
||||
_conf.setValue("skip_disclaimer", _skipDisclaimer);
|
||||
}
|
||||
}
|
||||
|
||||
Configuration::~Configuration() {
|
||||
save();
|
||||
}
|
||||
|
||||
void
|
||||
Configuration::save() {
|
||||
_conf.save();
|
||||
}
|
||||
|
||||
int
|
||||
Configuration::swapInterval() const {
|
||||
return _swapInterval;
|
||||
}
|
||||
|
||||
void
|
||||
Configuration::setSwapInterval(int interval) {
|
||||
_swapInterval = interval;
|
||||
_conf.setValue("swap_interval", _swapInterval);
|
||||
_conf.save();
|
||||
}
|
||||
|
||||
float
|
||||
Configuration::fpsCap() const {
|
||||
return _fpsCap;
|
||||
}
|
||||
|
||||
void
|
||||
Configuration::setFpsCap(float cap) {
|
||||
_fpsCap = cap;
|
||||
_conf.setValue("fps_cap", _fpsCap);
|
||||
_conf.save();
|
||||
}
|
||||
|
||||
bool
|
||||
Configuration::cheatMode() const {
|
||||
return _cheatMode;
|
||||
}
|
||||
|
||||
void
|
||||
Configuration::setCheatMode(bool enabled) {
|
||||
_cheatMode = enabled;
|
||||
_conf.setValue("cheat_mode", _cheatMode);
|
||||
_conf.save();
|
||||
}
|
||||
|
||||
bool
|
||||
Configuration::advancedMode() const {
|
||||
return _advancedMode;
|
||||
}
|
||||
|
||||
void
|
||||
Configuration::setAdvancedMode(bool enabled) {
|
||||
_advancedMode = enabled;
|
||||
_conf.setValue("advanced_mode", _advancedMode);
|
||||
_conf.save();
|
||||
}
|
||||
|
||||
bool
|
||||
Configuration::checkUpdatesOnStartup() const {
|
||||
return _checkUpdatesOnStartup;
|
||||
}
|
||||
|
||||
void
|
||||
Configuration::setCheckUpdatesOnStartup(bool mode) {
|
||||
_checkUpdatesOnStartup = mode;
|
||||
_conf.setValue("startup_update_check", _checkUpdatesOnStartup);
|
||||
_conf.save();
|
||||
}
|
||||
|
||||
bool
|
||||
Configuration::skipDisclaimer() const {
|
||||
return _skipDisclaimer;
|
||||
}
|
||||
|
||||
void
|
||||
Configuration::setSkipDisclaimer(bool mode) {
|
||||
_skipDisclaimer = mode;
|
||||
_conf.setValue("skip_disclaimer", _skipDisclaimer);
|
||||
_conf.save();
|
||||
}
|
||||
|
||||
Configuration&
|
||||
Configuration::instance() {
|
||||
static Configuration conf{};
|
||||
return conf;
|
||||
}
|
||||
|
||||
Configuration&
|
||||
conf() {
|
||||
return Configuration::instance();
|
||||
}
|
46
src/Configuration/Configuration.h
Normal file
46
src/Configuration/Configuration.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
|
||||
#include <Corrade/Utility/Configuration.h>
|
||||
|
||||
using namespace Corrade;
|
||||
|
||||
class Configuration {
|
||||
public:
|
||||
static Configuration& instance();
|
||||
|
||||
~Configuration();
|
||||
|
||||
void save();
|
||||
|
||||
int swapInterval() const;
|
||||
void setSwapInterval(int interval);
|
||||
|
||||
float fpsCap() const;
|
||||
void setFpsCap(float cap);
|
||||
|
||||
bool cheatMode() const;
|
||||
void setCheatMode(bool enabled);
|
||||
|
||||
bool advancedMode() const;
|
||||
void setAdvancedMode(bool enabled);
|
||||
|
||||
bool checkUpdatesOnStartup() const;
|
||||
void setCheckUpdatesOnStartup(bool mode);
|
||||
|
||||
bool skipDisclaimer() const;
|
||||
void setSkipDisclaimer(bool mode);
|
||||
|
||||
private:
|
||||
explicit Configuration();
|
||||
|
||||
Utility::Configuration _conf;
|
||||
|
||||
int _swapInterval = 1;
|
||||
float _fpsCap = 60.0f;
|
||||
bool _cheatMode = false;
|
||||
bool _advancedMode = false;
|
||||
bool _checkUpdatesOnStartup = true;
|
||||
bool _skipDisclaimer = false;
|
||||
};
|
||||
|
||||
Configuration& conf();
|
|
@ -35,6 +35,7 @@
|
|||
#include <wtsapi32.h>
|
||||
|
||||
#include "../FontAwesome/IconsFontAwesome5.h"
|
||||
#include "../Configuration/Configuration.h"
|
||||
#include "../Logger/Logger.h"
|
||||
|
||||
using namespace Containers::Literals;
|
||||
|
@ -130,7 +131,7 @@ SaveTool::SaveTool(const Arguments& arguments):
|
|||
|
||||
LOG_INFO("Initialising update checker.");
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
if(_checkUpdatesOnStartup) {
|
||||
if(conf().checkUpdatesOnStartup()) {
|
||||
_queue.addToast(Toast::Type::Default, "Checking for updates..."_s);
|
||||
_updateThread = std::thread{[this]{ checkForUpdates(); }};
|
||||
}
|
||||
|
@ -141,7 +142,7 @@ SaveTool::SaveTool(const Arguments& arguments):
|
|||
GL::DebugOutput::setEnabled(GL::DebugOutput::Source::Api, GL::DebugOutput::Type::Other, {131185}, false);
|
||||
}
|
||||
|
||||
if(_skipDisclaimer) {
|
||||
if(conf().skipDisclaimer()) {
|
||||
_uiState = UiState::Initialising;
|
||||
_initThread = std::thread{[this]{ initialiseManager(); }};
|
||||
}
|
||||
|
@ -159,14 +160,7 @@ SaveTool::~SaveTool() {
|
|||
|
||||
LOG_INFO("Saving the configuration.");
|
||||
|
||||
_conf.setValue("cheat_mode"_s, _cheatMode);
|
||||
_conf.setValue("advanced_mode"_s, _advancedMode);
|
||||
_conf.setValue("startup_update_check"_s, _checkUpdatesOnStartup);
|
||||
_conf.setValue("skip_disclaimer"_s, _skipDisclaimer);
|
||||
_conf.setValue("swap_interval"_s, _swapInterval);
|
||||
_conf.setValue("fps_cap"_s, _fpsCap);
|
||||
|
||||
_conf.save();
|
||||
conf().save();
|
||||
|
||||
LOG_INFO("Exiting.");
|
||||
}
|
||||
|
@ -182,8 +176,8 @@ void SaveTool::drawEvent() {
|
|||
|
||||
swapBuffers();
|
||||
|
||||
if(_swapInterval == 0 && _fpsCap < 301.0f) {
|
||||
while(_timeline.currentFrameDuration() < (1.0f / _fpsCap));
|
||||
if(conf().swapInterval() == 0 && conf().fpsCap() < 301.0f) {
|
||||
while(_timeline.currentFrameDuration() < (1.0f / conf().fpsCap()));
|
||||
}
|
||||
|
||||
redraw();
|
||||
|
@ -344,7 +338,9 @@ void SaveTool::drawDisclaimer() {
|
|||
ImGui::Dummy({0.0f, 5.0f});
|
||||
ImGui::Dummy({4.0f, 0.0f});
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Don't show next time", &_skipDisclaimer);
|
||||
if(drawCheckbox("Don't show next time", conf().skipDisclaimer())) {
|
||||
conf().setSkipDisclaimer(!conf().skipDisclaimer());
|
||||
}
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {24.0f, 12.0f});
|
||||
if(ImGui::Button("I understand the risks")) {
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include <Corrade/Containers/Pointer.h>
|
||||
#include <Corrade/Containers/String.h>
|
||||
#include <Corrade/Utility/Configuration.h>
|
||||
#include <Corrade/Utility/Resource.h>
|
||||
#ifdef SAVETOOL_DEBUG_BUILD
|
||||
#include <Corrade/Utility/Tweakable.h>
|
||||
|
@ -198,7 +197,6 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
|
|||
|
||||
void checkForUpdates();
|
||||
|
||||
Utility::Configuration _conf{"MassBuilderSaveTool.ini"_s};
|
||||
Utility::Resource _rs{"assets"_s};
|
||||
|
||||
// GUI-related members
|
||||
|
@ -263,12 +261,6 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
|
|||
};
|
||||
Containers::StaticArray<2, efsw::WatchID> _watchIDs;
|
||||
|
||||
int _swapInterval = 1;
|
||||
float _fpsCap = 60.0f;
|
||||
|
||||
bool _skipDisclaimer{false};
|
||||
bool _checkUpdatesOnStartup{true};
|
||||
|
||||
bool _updateAvailable{false};
|
||||
Containers::String _latestVersion;
|
||||
Containers::String _releaseLink;
|
||||
|
@ -291,8 +283,5 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
|
|||
bool _bLaunchersDirty{false};
|
||||
bool _eLaunchersDirty{false};
|
||||
|
||||
bool _cheatMode{false};
|
||||
bool _advancedMode{false};
|
||||
|
||||
Timeline _timeline;
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <shlobj.h>
|
||||
|
||||
#include "../Configuration/Configuration.h"
|
||||
#include "../FontAwesome/IconsFontAwesome5.h"
|
||||
#include "../FontAwesome/IconsFontAwesome5Brands.h"
|
||||
#include "../Logger/Logger.h"
|
||||
|
@ -51,62 +52,8 @@ void SaveTool::initEvent(SDL_Event& event) {
|
|||
void SaveTool::initialiseConfiguration() {
|
||||
LOG_INFO("Reading configuration file.");
|
||||
|
||||
if(_conf.hasValue("cheat_mode"_s)) {
|
||||
_cheatMode = _conf.value<bool>("cheat_mode"_s);
|
||||
}
|
||||
else {
|
||||
_conf.setValue("cheat_mode"_s, _cheatMode);
|
||||
}
|
||||
|
||||
if(_conf.hasValue("advanced_mode"_s)) {
|
||||
_advancedMode = _conf.value<bool>("advanced_mode"_s);
|
||||
}
|
||||
else {
|
||||
_conf.setValue("advanced_mode"_s, _advancedMode);
|
||||
}
|
||||
|
||||
if(_conf.hasValue("startup_update_check"_s)) {
|
||||
_checkUpdatesOnStartup = _conf.value<bool>("startup_update_check"_s);
|
||||
}
|
||||
else {
|
||||
_conf.setValue("startup_update_check"_s, _checkUpdatesOnStartup);
|
||||
}
|
||||
|
||||
if(_conf.hasValue("skip_disclaimer"_s)) {
|
||||
_skipDisclaimer = _conf.value<bool>("skip_disclaimer"_s);
|
||||
}
|
||||
else {
|
||||
_conf.setValue("skip_disclaimer"_s, _skipDisclaimer);
|
||||
}
|
||||
|
||||
if(_conf.hasValue("swap_interval"_s)) {
|
||||
_swapInterval = _conf.value<int>("swap_interval"_s);
|
||||
}
|
||||
else {
|
||||
_conf.setValue("swap_interval"_s, 1);
|
||||
}
|
||||
|
||||
if(_conf.hasValue("fps_cap"_s)) {
|
||||
_fpsCap = _conf.value<float>("fps_cap");
|
||||
}
|
||||
else {
|
||||
_conf.setValue("fps_cap", 60.0f);
|
||||
}
|
||||
|
||||
if(_conf.hasValue("frame_limit"_s)) {
|
||||
std::string frame_limit = _conf.value("frame_limit"_s);
|
||||
if(frame_limit == "half_vsync"_s) {
|
||||
_swapInterval = 2;
|
||||
}
|
||||
_conf.removeValue("frame_limit"_s);
|
||||
}
|
||||
|
||||
setSwapInterval(_swapInterval);
|
||||
if(_swapInterval == 0) {
|
||||
setMinimalLoopPeriod(0);
|
||||
}
|
||||
|
||||
_conf.save();
|
||||
setSwapInterval(conf().swapInterval());
|
||||
setMinimalLoopPeriod(0);
|
||||
}
|
||||
|
||||
void SaveTool::initialiseGui() {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <SDL_messagebox.h>
|
||||
|
||||
#include "../Configuration/Configuration.h"
|
||||
#include "../FontAwesome/IconsFontAwesome5.h"
|
||||
#include "../Maps/LastMissionId.h"
|
||||
#include "../Maps/StoryProgress.h"
|
||||
|
@ -224,7 +225,7 @@ void SaveTool::drawGeneralInfo() {
|
|||
}
|
||||
}
|
||||
|
||||
if(!_cheatMode) {
|
||||
if(!conf().cheatMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -403,7 +404,7 @@ void SaveTool::drawMaterialRow(Containers::StringView name, Int tier, Getter get
|
|||
ImGui::TableSetColumnIndex(2);
|
||||
if(getter() != -1) {
|
||||
ImGui::Text("%i", getter());
|
||||
if(_cheatMode) {
|
||||
if(conf().cheatMode()) {
|
||||
ImGui::TableSetColumnIndex(3);
|
||||
ImGui::PushID(name.data());
|
||||
static Int var = 0;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <Magnum/ImGuiIntegration/Integration.h>
|
||||
|
||||
#include "../Configuration/Configuration.h"
|
||||
#include "../FontAwesome/IconsFontAwesome5.h"
|
||||
#include "../Maps/Accessories.h"
|
||||
#define STYLENAMES_DEFINITION
|
||||
|
@ -393,10 +394,10 @@ auto SaveTool::drawCustomStyle(CustomStyle& style) -> DCSResult {
|
|||
void SaveTool::drawDecalEditor(Decal& decal) {
|
||||
ImGui::Text("ID: %i", decal.id);
|
||||
|
||||
if(ImGui::BeginTable("##DecalTable", _advancedMode ? 2 : 1, ImGuiTableFlags_BordersInnerV)) {
|
||||
if(ImGui::BeginTable("##DecalTable", conf().advancedMode() ? 2 : 1, ImGuiTableFlags_BordersInnerV)) {
|
||||
ImGui::TableSetupColumn("##Normal", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
if(_advancedMode) {
|
||||
if(conf().advancedMode()) {
|
||||
ImGui::TableSetupColumn("##Advanced", ImGuiTableColumnFlags_WidthStretch);
|
||||
}
|
||||
|
||||
|
@ -442,7 +443,7 @@ void SaveTool::drawDecalEditor(Decal& decal) {
|
|||
ImGui::Checkbox("##Wrap", &decal.wrap);
|
||||
ImGui::EndGroup();
|
||||
|
||||
if(_advancedMode) {
|
||||
if(conf().advancedMode()) {
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::TextColored(ImColor(255, 255, 0), ICON_FA_EXCLAMATION_TRIANGLE);
|
||||
|
@ -635,11 +636,11 @@ void SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<C
|
|||
|
||||
ImGui::BeginGroup();
|
||||
drawAlignedText("Styles:");
|
||||
if(_advancedMode) {
|
||||
if(conf().advancedMode()) {
|
||||
drawAlignedText("Base position:");
|
||||
}
|
||||
drawAlignedText("Position offset:");
|
||||
if(_advancedMode) {
|
||||
if(conf().advancedMode()) {
|
||||
drawAlignedText("Base rotation:");
|
||||
}
|
||||
drawAlignedText("Rotation offset:");
|
||||
|
@ -672,7 +673,7 @@ void SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<C
|
|||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if(_advancedMode) {
|
||||
if(conf().advancedMode()) {
|
||||
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
||||
ImGui::DragFloat("##PosX", &accessory.relativePosition.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f");
|
||||
ImGui::PopItemWidth();
|
||||
|
@ -696,7 +697,7 @@ void SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<C
|
|||
ImGui::SameLine();
|
||||
drawHelpMarker("+/-500.0 = +/-250 in-game");
|
||||
|
||||
if(_advancedMode) {
|
||||
if(conf().advancedMode()) {
|
||||
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
||||
ImGui::DragFloat("##RotX", &accessory.relativeRotation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "Roll: %.3f");
|
||||
ImGui::PopItemWidth();
|
||||
|
|
|
@ -16,202 +16,217 @@
|
|||
|
||||
#include <Corrade/Utility/Path.h>
|
||||
|
||||
#include "../Configuration/Configuration.h"
|
||||
#include "../FontAwesome/IconsFontAwesome5.h"
|
||||
#include "../FontAwesome/IconsFontAwesome5Brands.h"
|
||||
|
||||
#include "SaveTool.h"
|
||||
|
||||
void SaveTool::drawMainMenu() {
|
||||
if(ImGui::BeginMainMenuBar()) {
|
||||
if(ImGui::BeginMenu("Save Tool##SaveToolMenu")) {
|
||||
if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open game data directory", Utility::Path::exists(_gameDataDir))) {
|
||||
if(ImGui::MenuItem(ICON_FA_COG " Configuration", nullptr, false, Utility::Path::exists(_configDir))) {
|
||||
openUri(Utility::Path::toNativeSeparators(_configDir));
|
||||
}
|
||||
if(!ImGui::BeginMainMenuBar()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(ImGui::MenuItem(ICON_FA_SAVE " Saves", nullptr, false, Utility::Path::exists(_saveDir))) {
|
||||
openUri(Utility::Path::toNativeSeparators(_saveDir));
|
||||
}
|
||||
|
||||
if(ImGui::MenuItem(ICON_FA_IMAGE " Screenshots", nullptr, false, Utility::Path::exists(_screenshotsDir))) {
|
||||
openUri(Utility::Path::toNativeSeparators(_screenshotsDir));
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
if(ImGui::BeginMenu("Save Tool##SaveToolMenu")) {
|
||||
if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open game data directory", Utility::Path::exists(_gameDataDir))) {
|
||||
if(ImGui::MenuItem(ICON_FA_COG " Configuration", nullptr, false, Utility::Path::exists(_configDir))) {
|
||||
openUri(Utility::Path::toNativeSeparators(_configDir));
|
||||
}
|
||||
|
||||
if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open manager directory")) {
|
||||
if(ImGui::MenuItem(ICON_FA_FILE_ARCHIVE " Profile backups", nullptr, false, Utility::Path::exists(_backupsDir))) {
|
||||
openUri(Utility::Path::toNativeSeparators(_backupsDir));
|
||||
}
|
||||
|
||||
if(ImGui::MenuItem(ICON_FA_EXCHANGE_ALT " Staging area", nullptr, false, Utility::Path::exists(_stagingDir))) {
|
||||
openUri(Utility::Path::toNativeSeparators(_stagingDir));
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
if(ImGui::MenuItem(ICON_FA_SAVE " Saves", nullptr, false, Utility::Path::exists(_saveDir))) {
|
||||
openUri(Utility::Path::toNativeSeparators(_saveDir));
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
if(ImGui::MenuItem(ICON_FA_IMAGE " Screenshots", nullptr, false, Utility::Path::exists(_screenshotsDir))) {
|
||||
openUri(Utility::Path::toNativeSeparators(_screenshotsDir));
|
||||
}
|
||||
|
||||
if(ImGui::BeginMenu(ICON_FA_COG " Settings")) {
|
||||
ImGui::BeginGroup();
|
||||
drawAlignedText("Vertical sync:");
|
||||
if(_swapInterval == 0) {
|
||||
drawAlignedText("FPS cap:");
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open manager directory")) {
|
||||
if(ImGui::MenuItem(ICON_FA_FILE_ARCHIVE " Profile backups", nullptr, false, Utility::Path::exists(_backupsDir))) {
|
||||
openUri(Utility::Path::toNativeSeparators(_backupsDir));
|
||||
}
|
||||
|
||||
ImGui::BeginGroup();
|
||||
if(ImGui::MenuItem(ICON_FA_EXCHANGE_ALT " Staging area", nullptr, false, Utility::Path::exists(_stagingDir))) {
|
||||
openUri(Utility::Path::toNativeSeparators(_stagingDir));
|
||||
}
|
||||
|
||||
static const char* framelimit_labels[] = {
|
||||
"Off",
|
||||
"Every VBLANK",
|
||||
"Every second VBLANK",
|
||||
"Every third VBLANK",
|
||||
};
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::PushItemWidth(300.0f);
|
||||
ImGui::Separator();
|
||||
|
||||
if(ImGui::BeginCombo("##FrameLimit", framelimit_labels[_swapInterval])) {
|
||||
for(int i = 0; i <= 3; i++) {
|
||||
if(ImGui::Selectable(framelimit_labels[i], _swapInterval == i)) {
|
||||
_swapInterval = i;
|
||||
setSwapInterval(i);
|
||||
if(i == 0) {
|
||||
setMinimalLoopPeriod(0);
|
||||
}
|
||||
if(ImGui::BeginMenu(ICON_FA_COG " Settings")) {
|
||||
ImGui::BeginGroup();
|
||||
drawAlignedText("Vertical sync:");
|
||||
if(conf().swapInterval() == 0) {
|
||||
drawAlignedText("FPS cap:");
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
static const char* framelimit_labels[] = {
|
||||
"Off",
|
||||
"Every VBLANK",
|
||||
"Every second VBLANK",
|
||||
"Every third VBLANK",
|
||||
};
|
||||
|
||||
ImGui::PushItemWidth(300.0f);
|
||||
|
||||
if(ImGui::BeginCombo("##FrameLimit", framelimit_labels[conf().swapInterval()])) {
|
||||
for(int i = 0; i <= 3; i++) {
|
||||
if(ImGui::Selectable(framelimit_labels[i], conf().swapInterval() == i)) {
|
||||
conf().setSwapInterval(i);
|
||||
setSwapInterval(i);
|
||||
if(i == 0) {
|
||||
setMinimalLoopPeriod(0);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if(_swapInterval == 0) {
|
||||
ImGui::SliderFloat("##FpsCapSlider", &_fpsCap, 15.0f, 301.0f,
|
||||
_fpsCap != 301.0f ? "%.0f" : "Uncapped", ImGuiSliderFlags_AlwaysClamp);
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if(conf().swapInterval() == 0) {
|
||||
static float fps_cap = conf().fpsCap();
|
||||
if(ImGui::SliderFloat("##FpsCapSlider", &fps_cap, 15.0f, 301.0f,
|
||||
conf().fpsCap() != 301.0f ? "%.0f" : "Uncapped", ImGuiSliderFlags_AlwaysClamp))
|
||||
{
|
||||
conf().setFpsCap(fps_cap);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::EndGroup();
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::Checkbox("Cheat mode", &_cheatMode);
|
||||
if(drawCheckbox("Cheat mode", conf().cheatMode())) {
|
||||
conf().setCheatMode(!conf().cheatMode());
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
drawHelpMarker("This gives access to save edition features that can be considered cheats.",
|
||||
Float(windowSize().x()) * 0.4f);
|
||||
|
||||
if(drawCheckbox("Advanced mode", conf().advancedMode())) {
|
||||
conf().setAdvancedMode(!conf().advancedMode());
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
drawHelpMarker("This gives access to editing values that have unknown purposes or are undocumented.",
|
||||
Float(windowSize().x()) * 0.4f);
|
||||
|
||||
if(drawCheckbox("Check for updates on startup", conf().checkUpdatesOnStartup())) {
|
||||
conf().setCheckUpdatesOnStartup(!conf().checkUpdatesOnStartup());
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button(ICON_FA_SYNC_ALT " Check now")) {
|
||||
_queue.addToast(Toast::Type::Default, "Checking for updates...");
|
||||
_updateThread = std::thread{[this]{ checkForUpdates(); }};
|
||||
}
|
||||
|
||||
if(_updateAvailable) {
|
||||
drawAlignedText("Version %s is available.", _latestVersion.data());
|
||||
if(ImGui::Button(ICON_FA_FILE_SIGNATURE " Release notes")) {
|
||||
openUri(_releaseLink);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
drawHelpMarker("This gives access to save edition features that can be considered cheats.",
|
||||
Float(windowSize().x()) * 0.4f);
|
||||
|
||||
ImGui::Checkbox("Advanced mode", &_advancedMode);
|
||||
ImGui::SameLine();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
drawHelpMarker("This gives access to editing values that have unknown purposes or are undocumented.",
|
||||
Float(windowSize().x()) * 0.4f);
|
||||
|
||||
ImGui::Checkbox("Check for updates on startup", &_checkUpdatesOnStartup);
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button(ICON_FA_SYNC_ALT " Check now")) {
|
||||
_queue.addToast(Toast::Type::Default, "Checking for updates...");
|
||||
_updateThread = std::thread{[this]{ checkForUpdates(); }};
|
||||
if(ImGui::Button(ICON_FA_DOWNLOAD " Download now")) {
|
||||
openUri(_downloadLink);
|
||||
}
|
||||
|
||||
if(_updateAvailable) {
|
||||
drawAlignedText("Version %s is available.", _latestVersion.data());
|
||||
if(ImGui::Button(ICON_FA_FILE_SIGNATURE " Release notes")) {
|
||||
openUri(_releaseLink);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button(ICON_FA_DOWNLOAD " Download now")) {
|
||||
openUri(_downloadLink);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Skip disclaimer", &_skipDisclaimer);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(ImGui::MenuItem(ICON_FA_SIGN_OUT_ALT " Quit##QuitMenuItem")) {
|
||||
exit(EXIT_SUCCESS);
|
||||
if(drawCheckbox("Skip disclaimer", conf().skipDisclaimer())) {
|
||||
conf().setSkipDisclaimer(!conf().skipDisclaimer());
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if(ImGui::BeginMenu("Game##GameMenu")) {
|
||||
if(ImGui::MenuItem(ICON_FA_PLAY " Run demo##RunDemoMenuItem")) {
|
||||
openUri("steam://run/1048390");
|
||||
}
|
||||
drawTooltip("Will not work if you have the full game.");
|
||||
ImGui::Separator();
|
||||
|
||||
if(ImGui::MenuItem(ICON_FA_PLAY " Run full game##RunFullGameMenuItem")) {
|
||||
openUri("steam://run/956680");
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(ImGui::BeginMenu(ICON_FA_DISCORD " Discord communities")) {
|
||||
if(ImGui::MenuItem("Official server")) {
|
||||
openUri("https://discord.gg/sekai-project");
|
||||
}
|
||||
|
||||
if(ImGui::MenuItem("Community server")) {
|
||||
openUri("https://discord.gg/massbuildercommunity");
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
if(ImGui::MenuItem(ICON_FA_SIGN_OUT_ALT " Quit##QuitMenuItem")) {
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
#ifdef SAVETOOL_DEBUG_BUILD
|
||||
if(ImGui::BeginMenu("Debug tools")) {
|
||||
ImGui::MenuItem("ImGui demo window", nullptr, &_demoWindow);
|
||||
ImGui::MenuItem("ImGui style editor", nullptr, &_styleEditor);
|
||||
ImGui::MenuItem("ImGui metrics window", nullptr, &_metricsWindow);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
#endif
|
||||
|
||||
if(ImGui::BeginMenu("Help")) {
|
||||
if(ImGui::BeginMenu(ICON_FA_KEYBOARD " Keyboard shortcuts")) {
|
||||
ImGui::BulletText("CTRL+Click on a slider or drag box to input value as text.");
|
||||
ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields.");
|
||||
ImGui::BulletText("While inputing text:\n");
|
||||
ImGui::Indent();
|
||||
ImGui::BulletText("CTRL+Left/Right to word jump.");
|
||||
ImGui::BulletText("CTRL+A or double-click to select all.");
|
||||
ImGui::BulletText("CTRL+X/C/V to use clipboard cut/copy/paste.");
|
||||
ImGui::BulletText("CTRL+Z,CTRL+Y to undo/redo.");
|
||||
ImGui::BulletText("ESCAPE to revert.");
|
||||
ImGui::BulletText("You can apply arithmetic operators +,*,/ on numerical values.\nUse +- to subtract.");
|
||||
ImGui::Unindent();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::MenuItem(ICON_FA_INFO_CIRCLE " About", nullptr, &_aboutPopup);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if(_gameCheckTimerId != 0) {
|
||||
if(ImGui::BeginTable("##MainMenuLayout", 2)) {
|
||||
ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("##GameState", ImGuiTableColumnFlags_WidthFixed);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
drawGameState();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndMainMenuBar();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if(ImGui::BeginMenu("Game##GameMenu")) {
|
||||
if(ImGui::MenuItem(ICON_FA_PLAY " Run demo##RunDemoMenuItem")) {
|
||||
openUri("steam://run/1048390");
|
||||
}
|
||||
drawTooltip("Will not work if you have the full game.");
|
||||
|
||||
if(ImGui::MenuItem(ICON_FA_PLAY " Run full game##RunFullGameMenuItem")) {
|
||||
openUri("steam://run/956680");
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(ImGui::BeginMenu(ICON_FA_DISCORD " Discord communities")) {
|
||||
if(ImGui::MenuItem("Official server")) {
|
||||
openUri("https://discord.gg/sekai-project");
|
||||
}
|
||||
|
||||
if(ImGui::MenuItem("Community server")) {
|
||||
openUri("https://discord.gg/massbuildercommunity");
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
#ifdef SAVETOOL_DEBUG_BUILD
|
||||
if(ImGui::BeginMenu("Debug tools")) {
|
||||
ImGui::MenuItem("ImGui demo window", nullptr, &_demoWindow);
|
||||
ImGui::MenuItem("ImGui style editor", nullptr, &_styleEditor);
|
||||
ImGui::MenuItem("ImGui metrics window", nullptr, &_metricsWindow);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
#endif
|
||||
|
||||
if(ImGui::BeginMenu("Help")) {
|
||||
if(ImGui::BeginMenu(ICON_FA_KEYBOARD " Keyboard shortcuts")) {
|
||||
ImGui::BulletText("CTRL+Click on a slider or drag box to input value as text.");
|
||||
ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields.");
|
||||
ImGui::BulletText("While inputing text:\n");
|
||||
ImGui::Indent();
|
||||
ImGui::BulletText("CTRL+Left/Right to word jump.");
|
||||
ImGui::BulletText("CTRL+A or double-click to select all.");
|
||||
ImGui::BulletText("CTRL+X/C/V to use clipboard cut/copy/paste.");
|
||||
ImGui::BulletText("CTRL+Z,CTRL+Y to undo/redo.");
|
||||
ImGui::BulletText("ESCAPE to revert.");
|
||||
ImGui::BulletText("You can apply arithmetic operators +,*,/ on numerical values.\nUse +- to subtract.");
|
||||
ImGui::Unindent();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::MenuItem(ICON_FA_INFO_CIRCLE " About", nullptr, &_aboutPopup);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if(_gameCheckTimerId != 0) {
|
||||
if(ImGui::BeginTable("##MainMenuLayout", 2)) {
|
||||
ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("##GameState", ImGuiTableColumnFlags_WidthFixed);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
drawGameState();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue