188 lines
5.8 KiB
C++
188 lines
5.8 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "backends/imgui/imgui_utils.h"
|
|
#include "common/formats/json.h"
|
|
#include "common/memstream.h"
|
|
#include "common/savefile.h"
|
|
#include "common/file.h"
|
|
|
|
#include "director/director.h"
|
|
#include "director/movie.h"
|
|
#include "director/score.h"
|
|
#include "director/debugger/dt-internal.h"
|
|
|
|
namespace Director {
|
|
namespace DT {
|
|
|
|
const char *savedStateFileName = "ImGuiSaveState.json";
|
|
|
|
Common::Array<WindowFlag> getWindowFlags() {
|
|
return {
|
|
{ "Archive", &_state->_w.archive },
|
|
{ "Breakpoints", &_state->_w.bpList },
|
|
{ "Cast", &_state->_w.cast },
|
|
{ "Channels", &_state->_w.channels },
|
|
{ "Control Panel", &_state->_w.controlPanel },
|
|
{ "Execution Context", &_state->_w.executionContext },
|
|
{ "Functions", &_state->_w.funcList },
|
|
{ "Log", &_state->_w.logger },
|
|
{ "Score", &_state->_w.score },
|
|
{ "Settings", &_state->_w.settings },
|
|
{ "Vars", &_state->_w.vars },
|
|
{ "Watched Vars", &_state->_w.watchedVars },
|
|
};
|
|
}
|
|
|
|
// What are the things that need saving?
|
|
// 1) Window Positions
|
|
// 2) Score frame number
|
|
// 3) Windows that are open/closed
|
|
// 4) Watched Variables
|
|
void saveCurrentState() {
|
|
Common::JSONObject json = Common::JSONObject();
|
|
|
|
// Whether windows are open or not
|
|
Common::Array<WindowFlag> windows = getWindowFlags();
|
|
|
|
uint index = 0;
|
|
int64 openFlags = 0;
|
|
for (const WindowFlag &it : windows) {
|
|
openFlags += (*it.flag) ? 1 << index : 0;
|
|
index += 1;
|
|
}
|
|
if (debugChannelSet(7, kDebugImGui)) {
|
|
debugC(7, kDebugImGui, "Window flags: ");
|
|
for (auto it : windows) {
|
|
debug("%s: %s", it.name, *it.flag ? "open" : "closed");
|
|
}
|
|
}
|
|
|
|
json["Windows"] = new Common::JSONValue((long long int)openFlags);
|
|
|
|
// Window Settings
|
|
const char *windowSettings = ImGui::SaveIniSettingsToMemory();
|
|
json["Window Settings"] = new Common::JSONValue(windowSettings);
|
|
|
|
// Current Log
|
|
ImVector<char *> currentLog = _state->_logger->getItems();
|
|
Common::JSONArray log;
|
|
for (auto iter : currentLog) {
|
|
log.push_back(new Common::JSONValue(iter));
|
|
}
|
|
json["Log"] = new Common::JSONValue(log);
|
|
|
|
// Other settings
|
|
json["ScoreWindow"] = new Common::JSONValue(_state->_scoreWindow);
|
|
json["ChannelsWindow"] = new Common::JSONValue(_state->_channelsWindow);
|
|
json["CastWindow"] = new Common::JSONValue(_state->_castWindow);
|
|
|
|
// Save the JSON
|
|
Common::JSONValue save(json);
|
|
debugC(7, kDebugImGui, "ImGui::Saved state: %s", save.stringify().c_str());
|
|
|
|
Common::OutSaveFile *stream = g_engine->getSaveFileManager()->openForSaving(savedStateFileName);
|
|
|
|
if (stream) {
|
|
stream->writeString(save.stringify());
|
|
stream->finalize();
|
|
debug("ImGui::SaveCurrentState: Saved the current ImGui State @%s", savedStateFileName);
|
|
} else {
|
|
debug("ImGui::SaveCurrentState: Failed to open the file %s for saving", savedStateFileName);
|
|
}
|
|
|
|
// Clean up everything
|
|
delete stream;
|
|
}
|
|
|
|
void loadSavedState() {
|
|
Common::InSaveFile *savedState = g_engine->getSaveFileManager()->openForLoading(savedStateFileName);
|
|
|
|
if (!savedState || savedState->size() == 0) {
|
|
debug("ImGui::loadSavedState(): Failed to open saved state file: %s", savedStateFileName);
|
|
return;
|
|
}
|
|
|
|
// ASAN throws an error if the data is exactly equal to savedState->size() in JSON::parse()
|
|
// Probably because JSON::parse() expects a NULL terminated data
|
|
char *data = (char *)malloc(savedState->size() + 1);
|
|
data[savedState->size()] = '\0';
|
|
savedState->read(data, savedState->size());
|
|
|
|
Common::JSONValue *saved = Common::JSON::parse(data);
|
|
|
|
if (!saved) {
|
|
debug("ImGui:: Bad JSON: Failed to parse the Saved state");
|
|
free(data);
|
|
return;
|
|
}
|
|
|
|
debugC(7, kDebugImGui, "ImGui::loaded state: %s", saved->stringify(true).c_str());
|
|
|
|
// Load open/closed window flags
|
|
int64 openFlags = saved->asObject()["Windows"]->asIntegerNumber();
|
|
Common::Array<WindowFlag> windows = getWindowFlags();
|
|
|
|
uint index = 0;
|
|
for (WindowFlag it : windows) {
|
|
*it.flag = (openFlags & 1 << index) ? true : false;
|
|
index += 1;
|
|
}
|
|
_state->_w.archive = (openFlags & 1) ? true : false;
|
|
if (debugChannelSet(7, kDebugImGui)) {
|
|
debugC(7, kDebugImGui, "Window flags: ");
|
|
for (auto it : windows) {
|
|
debug("%s: %s", it.name, *it.flag ? "open" : "closed");
|
|
}
|
|
}
|
|
|
|
// Load window settings
|
|
const char *windowSettings = saved->asObject()["Window Settings"]->asString().c_str();
|
|
ImGui::LoadIniSettingsFromMemory(windowSettings);
|
|
|
|
// Load the log
|
|
Common::JSONArray log = saved->asObject()["Log"]->asArray();
|
|
|
|
if (debugChannelSet(7, kDebugImGui)) {
|
|
debugC(7, kDebugImGui, "Loading log: \n");
|
|
for (auto iter : log) {
|
|
debugC(7, kDebugImGui, "%s", iter->asString().c_str());
|
|
}
|
|
}
|
|
|
|
_state->_logger->clear();
|
|
for (auto iter : log) {
|
|
_state->_logger->addLog(iter->asString().c_str());
|
|
}
|
|
|
|
// Load other settings
|
|
_state->_scoreWindow = saved->asObject()["ScoreWindow"]->asString();
|
|
_state->_channelsWindow = saved->asObject()["ChannelsWindow"]->asString();
|
|
_state->_castWindow = saved->asObject()["CastWindow"]->asString();
|
|
|
|
free(data);
|
|
delete saved;
|
|
delete savedState;
|
|
}
|
|
|
|
} // End of namespace DT
|
|
} // End of namespace Director
|