mirror of
https://github.com/open-goal/jak-project
synced 2026-07-09 06:53:45 -04:00
various subtitle editor fixes (#2941)
- fix speaker names and time frames being uneditable in Jak 1 - added toggle to auto-selected a newly created scene as current - changed the subtitle summary format slightly. - current scene's name now appears in the UI
This commit is contained in:
@@ -99,7 +99,11 @@ void SubtitleEditor::draw_window() {
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_selected_text_color);
|
||||
}
|
||||
if (ImGui::TreeNode("Currently Selected Cutscene")) {
|
||||
if (ImGui::TreeNode(
|
||||
"current_scene", "%s",
|
||||
m_current_scene
|
||||
? fmt::format("Currently Selected Scene - {}", m_current_scene->m_name).c_str()
|
||||
: "Currently Selected Scene")) {
|
||||
ImGui::PopStyleColor();
|
||||
if (m_current_scene) {
|
||||
draw_subtitle_options(*m_current_scene, true);
|
||||
@@ -207,6 +211,8 @@ void SubtitleEditor::draw_speaker_options() {
|
||||
const auto& bank = m_subtitle_db.m_banks[m_current_language];
|
||||
for (auto& [speaker_id, speaker_localized] : bank->m_speakers) {
|
||||
if (speaker_id == "none") {
|
||||
// this is a special speaker that has ID zero and does not appear in-game
|
||||
// it means there was no speaker for the line. (e.g. text-only, not vocal)
|
||||
continue;
|
||||
}
|
||||
// Insertion or deletion not needed here as it has to be wired up in .gc and C++ code
|
||||
@@ -238,9 +244,15 @@ void SubtitleEditor::draw_scene_section_header(const bool non_cutscenes) {
|
||||
new_scene.m_hint_id = 0;
|
||||
}
|
||||
m_subtitle_db.m_banks.at(m_current_language)->m_scenes.emplace(m_new_scene_name, new_scene);
|
||||
if (m_new_scene_as_current) {
|
||||
m_current_scene =
|
||||
&m_subtitle_db.m_banks.at(m_current_language)->m_scenes.at(m_new_scene_name);
|
||||
}
|
||||
|
||||
m_new_scene_name = "";
|
||||
}
|
||||
ImGui::NewLine();
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Set Scene as Current", &m_new_scene_as_current);
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@@ -343,7 +355,7 @@ std::string SubtitleEditor::subtitle_line_summary(
|
||||
std::string line_text = "";
|
||||
if (!line.text.empty()) {
|
||||
if (m_truncate_summaries && line.text.size() > 30) {
|
||||
line_text = line.text.substr(0, 30) + "...";
|
||||
line_text = line.text.substr(0, 27) + "...";
|
||||
} else {
|
||||
line_text = line.text;
|
||||
}
|
||||
@@ -351,7 +363,7 @@ std::string SubtitleEditor::subtitle_line_summary(
|
||||
if (is_v1_format()) {
|
||||
line_text = "Clear Screen";
|
||||
} else if (line_meta.merge) {
|
||||
line_text = "<Merge>";
|
||||
line_text = "<original game text>";
|
||||
}
|
||||
}
|
||||
// Append important info about the frame / speaker to the front
|
||||
@@ -359,21 +371,23 @@ std::string SubtitleEditor::subtitle_line_summary(
|
||||
// V1
|
||||
if (is_v1_format()) {
|
||||
if (line.text.empty()) {
|
||||
return fmt::format("{}] {}", info_header, line_text);
|
||||
return fmt::format("[{}] {}", line_meta.frame_start, line_text);
|
||||
} else {
|
||||
return fmt::format(
|
||||
"[{}] {}: {}", line_meta.frame_start,
|
||||
m_subtitle_db.m_banks[m_current_language]->m_speakers.at(line_meta.speaker), line_text);
|
||||
}
|
||||
return fmt::format("{}] {} - '{}'", info_header,
|
||||
m_subtitle_db.m_banks[m_current_language]->m_speakers.at(line_meta.speaker),
|
||||
line_text);
|
||||
}
|
||||
// V2
|
||||
if (line_meta.merge) {
|
||||
return fmt::format("{}-{}] {} - {}", info_header, line_meta.frame_end,
|
||||
m_subtitle_db.m_banks[m_current_language]->m_speakers.at(line_meta.speaker),
|
||||
else {
|
||||
auto speaker_text =
|
||||
line_meta.speaker == "none"
|
||||
? ""
|
||||
: fmt::format("{}: ", m_subtitle_db.m_banks[m_current_language]->m_speakers.at(
|
||||
line_meta.speaker));
|
||||
return fmt::format("[{}-{}] {}{}", line_meta.frame_start, line_meta.frame_end, speaker_text,
|
||||
line_text);
|
||||
}
|
||||
return fmt::format("{}-{}] {} - '{}'", info_header, line_meta.frame_end,
|
||||
m_subtitle_db.m_banks[m_current_language]->m_speakers.at(line_meta.speaker),
|
||||
line_text);
|
||||
}
|
||||
|
||||
void SubtitleEditor::draw_subtitle_options(GameSubtitleSceneInfo& scene, bool current_scene) {
|
||||
@@ -435,16 +449,18 @@ void SubtitleEditor::draw_subtitle_options(GameSubtitleSceneInfo& scene, bool cu
|
||||
}
|
||||
bool hide_line_options = false;
|
||||
if (is_v1_format()) {
|
||||
if (line_text.empty()) {
|
||||
hide_line_options = true;
|
||||
} else {
|
||||
ImGui::InputInt("Starting Frame", &subtitle_line->metadata.frame_start,
|
||||
ImGuiInputTextFlags_::ImGuiInputTextFlags_CharsDecimal);
|
||||
}
|
||||
ImGui::InputInt("Starting Frame", &frames[0],
|
||||
ImGuiInputTextFlags_::ImGuiInputTextFlags_CharsDecimal);
|
||||
} else {
|
||||
ImGui::InputInt2("Start and End Frame", frames,
|
||||
ImGuiInputTextFlags_::ImGuiInputTextFlags_CharsDecimal);
|
||||
}
|
||||
|
||||
// no text + text isn't going to be filled automatically by the game
|
||||
if (line_text.empty() && !line_meta.merge) {
|
||||
hide_line_options = true;
|
||||
}
|
||||
|
||||
if (!hide_line_options) {
|
||||
if (ImGui::BeginCombo(
|
||||
"Speaker",
|
||||
@@ -461,15 +477,14 @@ void SubtitleEditor::draw_subtitle_options(GameSubtitleSceneInfo& scene, bool cu
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::InputText("Text", &subtitle_line->text,
|
||||
line_meta.merge ? ImGuiInputTextFlags_ReadOnly : 0);
|
||||
ImGui::InputText("Text", &line_text, line_meta.merge ? ImGuiInputTextFlags_ReadOnly : 0);
|
||||
ImGui::Checkbox("Offscreen?", &subtitle_line->metadata.offscreen);
|
||||
if (!is_v1_format()) {
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Checkbox("Merge Text?", &subtitle_line->metadata.merge)) {
|
||||
// Clear text if they've checked it
|
||||
if (subtitle_line->metadata.merge) {
|
||||
subtitle_line->text = "";
|
||||
line_text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -533,7 +548,7 @@ void SubtitleEditor::draw_new_scene_line_form() {
|
||||
}
|
||||
}
|
||||
}
|
||||
bool rendered_text_entry_btn = false;
|
||||
|
||||
// Validation:
|
||||
// - start frame > 0
|
||||
// - end frame > start_frame
|
||||
@@ -546,7 +561,6 @@ void SubtitleEditor::draw_new_scene_line_form() {
|
||||
ImGui::Text("Can't add a new text entry with the current fields!");
|
||||
ImGui::PopStyleColor();
|
||||
} else {
|
||||
rendered_text_entry_btn = true;
|
||||
if (ImGui::Button("Add Text Entry")) {
|
||||
m_current_scene->add_line(m_current_scene_text, m_current_scene_frames[0],
|
||||
m_current_scene_frames[1], m_current_scene_offscreen,
|
||||
@@ -559,9 +573,6 @@ void SubtitleEditor::draw_new_scene_line_form() {
|
||||
ImGui::Text("Can't add a clear screen entry with the current fields!");
|
||||
ImGui::PopStyleColor();
|
||||
} else {
|
||||
if (rendered_text_entry_btn) {
|
||||
ImGui::SameLine();
|
||||
}
|
||||
if (ImGui::Button("Add Clear Screen Entry")) {
|
||||
m_current_scene->add_line("", m_current_scene_frames[0], 0, m_current_scene_offscreen, "",
|
||||
false);
|
||||
|
||||
@@ -67,6 +67,7 @@ class SubtitleEditor {
|
||||
bool m_current_scene_offscreen = false;
|
||||
bool m_current_scene_merge = false;
|
||||
|
||||
bool m_new_scene_as_current = true;
|
||||
std::string m_new_scene_name = "";
|
||||
std::string m_new_scene_id = "0";
|
||||
|
||||
|
||||
@@ -99,7 +99,17 @@ void compile_text(GameTextDB& db, const std::string& output_prefix) {
|
||||
*/
|
||||
void compile_subtitles_v1(GameSubtitleDB& db, const std::string& output_prefix) {
|
||||
for (const auto& [lang, bank] : db.m_banks) {
|
||||
// get font encoding information
|
||||
auto font = get_font_bank(bank->m_text_version);
|
||||
|
||||
// convert speakers once.
|
||||
auto speakers_converted = bank->m_speakers;
|
||||
for (auto& [id, name] : speakers_converted) {
|
||||
// convert name in-place. we copied the map earlier so this is safe.
|
||||
// the subtitle lines have the speaker "id" stored in them, which is the map key here.
|
||||
name = font->convert_utf8_to_game(name);
|
||||
}
|
||||
|
||||
DataObjectGenerator gen;
|
||||
gen.add_type_tag("subtitle-text-info"); // type
|
||||
gen.add_word(bank->m_scenes.size()); // length
|
||||
@@ -128,9 +138,18 @@ void compile_subtitles_v1(GameSubtitleDB& db, const std::string& output_prefix)
|
||||
for (auto& subtitle : scene.m_lines) {
|
||||
gen.add_word(subtitle.metadata.frame_start); // frame
|
||||
gen.add_ref_to_string_in_pool(font->convert_utf8_to_game(subtitle.text)); // line
|
||||
gen.add_ref_to_string_in_pool(
|
||||
font->convert_utf8_to_game(subtitle.metadata.speaker)); // speaker
|
||||
gen.add_word(subtitle.metadata.offscreen); // offscreen
|
||||
// speaker
|
||||
if (subtitle.metadata.speaker.empty()) {
|
||||
gen.add_ref_to_string_in_pool("");
|
||||
} else {
|
||||
auto it = speakers_converted.find(subtitle.metadata.speaker);
|
||||
if (it == speakers_converted.end()) {
|
||||
throw std::runtime_error(fmt::format("in file `{}`: could not find speaker {}",
|
||||
bank->m_file_path, subtitle.metadata.speaker));
|
||||
}
|
||||
gen.add_ref_to_string_in_pool(it->second);
|
||||
}
|
||||
gen.add_word(subtitle.metadata.offscreen); // offscreen
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user