subtitles-editor: Allow removing lines and fix some issues (#2573)

Allows for removing a line in the subtitle editor finally, also fixed
the following:

- The path the editor used didn't include the game name
- Loading the subtitle project is too slow to do on startup now
(4-5seconds in a debug build), do it on demand now
This commit is contained in:
Tyler Wilding
2023-04-29 10:02:18 -05:00
committed by GitHub
parent 0ce5835818
commit 8260920c2d
5 changed files with 49 additions and 32 deletions
@@ -468,7 +468,7 @@ void open_text_project(const std::string& kind,
});
}
GameSubtitleDB load_subtitle_project() {
GameSubtitleDB load_subtitle_project(GameVersion game_version) {
// Load the subtitle files
GameSubtitleDB db;
db.m_subtitle_groups = std::make_unique<GameSubtitleGroups>();
@@ -476,8 +476,9 @@ GameSubtitleDB load_subtitle_project() {
try {
goos::Reader reader;
std::vector<std::string> inputs;
std::string subtitle_project =
(file_util::get_jak_project_dir() / "game" / "assets" / "game_subtitle.gp").string();
std::string subtitle_project = (file_util::get_jak_project_dir() / "game" / "assets" /
version_to_game_name(game_version) / "game_subtitle.gp")
.string();
open_text_project("subtitle", subtitle_project, inputs);
for (auto& filename : inputs) {
auto code = reader.read_from_file({filename});
@@ -11,6 +11,7 @@
#include "common/log/log.h"
#include "common/util/Assert.h"
#include "common/util/FontUtils.h"
#include "common/versions/versions.h"
/*!
* The text bank contains all lines (accessed with an ID) for a language.
@@ -191,4 +192,4 @@ GameTextVersion parse_text_only_version(const goos::Object& data);
void open_text_project(const std::string& kind,
const std::string& filename,
std::vector<std::string>& inputs);
GameSubtitleDB load_subtitle_project();
GameSubtitleDB load_subtitle_project(GameVersion game_version);
@@ -539,7 +539,9 @@
"sagevb38",
"sagevb39"
],
"uncategorized": [],
"uncategorized": [
"evilbro-misty-end"
],
"village1": [
"ASSTLP01",
"ASSTLP02",
+38 -27
View File
@@ -7,13 +7,14 @@
#include "common/util/FileUtil.h"
#include "common/util/json_util.h"
#include "game/runtime.h"
#include "third-party/fmt/core.h"
#include "third-party/imgui/imgui.h"
#include "third-party/imgui/imgui_stdlib.h"
SubtitleEditor::SubtitleEditor() : m_repl(8181) {
update_subtitle_editor_db();
m_subtitle_db = load_subtitle_project();
m_filter = m_filter_placeholder;
m_filter_hints = m_filter_placeholder;
}
@@ -44,8 +45,6 @@ std::string SubtitleEditor::repl_get_process_string(const std::string_view& enti
void SubtitleEditor::repl_play_hint(const std::string_view& hint_name) {
repl_reset_game();
// repl_set_continue_point("village1-hut");
// TODO - move into water fountain
m_repl.eval(
fmt::format("(level-hint-spawn (text-id zero) \"{}\" (the-as entity #f) *entity-pool* "
"(game-task none))",
@@ -123,6 +122,15 @@ bool SubtitleEditor::is_scene_in_current_lang(const std::string& scene_name) {
void SubtitleEditor::draw_window() {
ImGui::Begin("Subtitle Editor");
if (!db_loaded) {
if (ImGui::Button("Load Subtitles")) {
m_subtitle_db = load_subtitle_project(g_game_version);
db_loaded = true;
}
ImGui::End();
return;
}
if (ImGui::Button("Save Changes")) {
m_files_saved_successfully = std::make_optional(write_subtitle_db_to_files(m_subtitle_db));
repl_rebuild_text();
@@ -604,51 +612,54 @@ void SubtitleEditor::draw_subtitle_options(GameSubtitleSceneInfo& scene, bool cu
}
auto font =
get_font_bank(parse_text_only_version(m_subtitle_db.m_banks[m_current_language]->file_path));
for (size_t i = 0; i < scene.m_lines.size(); i++) {
auto& subtitleLine = scene.m_lines.at(i);
auto linetext = font->convert_game_to_utf8(subtitleLine.line.c_str());
auto linespkr = font->convert_game_to_utf8(subtitleLine.speaker.c_str());
int i = 0;
for (auto subtitleLine = scene.m_lines.begin(); subtitleLine != scene.m_lines.end();) {
auto linetext = font->convert_game_to_utf8(subtitleLine->line.c_str());
auto linespkr = font->convert_game_to_utf8(subtitleLine->speaker.c_str());
std::string summary;
if (linetext.empty()) {
summary = fmt::format("[{}] Clear Screen", subtitleLine.frame);
summary = fmt::format("[{}] Clear Screen", subtitleLine->frame);
} else if (linetext.length() >= 30) {
summary =
fmt::format("[{}] {} - '{}...'", subtitleLine.frame, linespkr, linetext.substr(0, 30));
fmt::format("[{}] {} - '{}...'", subtitleLine->frame, linespkr, linetext.substr(0, 30));
} else {
summary = fmt::format("[{}] {} - '{}'", subtitleLine.frame, linespkr, linetext.substr(0, 30));
summary =
fmt::format("[{}] {} - '{}'", subtitleLine->frame, linespkr, linetext.substr(0, 30));
}
if (linetext.empty()) {
ImGui::PushStyleColor(ImGuiCol_Text, m_disabled_text_color);
} else if (subtitleLine.offscreen) {
} else if (subtitleLine->offscreen) {
ImGui::PushStyleColor(ImGuiCol_Text, m_offscreen_text_color);
}
if (ImGui::TreeNode(fmt::format("{}", i).c_str(), "%s", summary.c_str())) {
if (linetext.empty() || subtitleLine.offscreen) {
if (linetext.empty() || subtitleLine->offscreen) {
ImGui::PopStyleColor();
}
ImGui::InputInt("Starting Frame", &subtitleLine.frame,
ImGui::InputInt("Starting Frame", &subtitleLine->frame,
ImGuiInputTextFlags_::ImGuiInputTextFlags_CharsDecimal);
ImGui::InputText("Speaker", &linespkr);
ImGui::InputText("Text", &linetext);
ImGui::Checkbox("Offscreen?", &subtitleLine.offscreen);
// TODO - deleting while iterating is a bad pattern, especially with imgui's declarative
// style
// disabling this for now, it's not working in it's current state.
// if (scene.m_lines.size() > 1) { // prevent creating an empty scene
// ImGui::PushStyleColor(ImGuiCol_Button, m_warning_color);
// if (ImGui::Button("Remove Line")) {
// scene.m_lines.erase(scene.m_lines.begin() + i);
// }
// ImGui::PopStyleColor();
//}
ImGui::Checkbox("Offscreen?", &subtitleLine->offscreen);
if (scene.m_lines.size() > 1) { // prevent creating an empty scene
ImGui::PushStyleColor(ImGuiCol_Button, m_warning_color);
if (ImGui::Button("Remove")) {
subtitleLine = scene.m_lines.erase(subtitleLine);
ImGui::PopStyleColor();
ImGui::TreePop();
continue;
}
ImGui::PopStyleColor();
}
ImGui::TreePop();
} else if (linetext.empty() || subtitleLine.offscreen) {
} else if (linetext.empty() || subtitleLine->offscreen) {
ImGui::PopStyleColor();
}
auto newtext = font->convert_utf8_to_game(linetext, true);
auto newspkr = font->convert_utf8_to_game(linespkr, true);
subtitleLine.line = newtext;
subtitleLine.speaker = newspkr;
subtitleLine->line = newtext;
subtitleLine->speaker = newspkr;
i++;
subtitleLine++;
}
}
+2
View File
@@ -46,6 +46,8 @@ class SubtitleEditor {
void draw_all_hint_groups();
void draw_all_hints(std::string group_name, bool base_cutscenes);
bool db_loaded = false;
GameSubtitleDB m_subtitle_db;
std::map<std::string, SubtitleEditorDB::Entry> m_db = {};
GameSubtitleSceneInfo* m_current_scene = nullptr;