mirror of
https://github.com/open-goal/jak-project
synced 2026-06-05 19:28:31 -04:00
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:
@@ -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",
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user