From af5cb9b1cb9b39568f91a8d439f081cb4defe9ce Mon Sep 17 00:00:00 2001 From: Hat Kid <6624576+Hat-Kid@users.noreply.github.com> Date: Tue, 12 Nov 2024 02:45:16 +0100 Subject: [PATCH] jak3: `subtitle3`, `vag-player` (#3758) --- common/serialization/subtitles/subtitles.cpp | 8 +- .../serialization/subtitles/subtitles_v2.cpp | 81 +- decompiler/config/jak3/all-types.gc | 2 +- decompiler/config/jak3/jak3_config.jsonc | 2 +- decompiler/config/jak3/ntsc_v1/inputs.jsonc | 235 +- .../config/jak3/ntsc_v1/var_names.jsonc | 3 + decompiler/data/StrFileReader.cpp | 2 +- decompiler/data/game_text.cpp | 12 +- game/assets/jak3/game_subtitle.gp | 103 +- .../jak3/subtitle/subtitle_lines_cm-CM.json | 50 + .../jak3/subtitle/subtitle_lines_de-DE.json | 47 +- .../jak3/subtitle/subtitle_lines_en-GB.json | 47 +- .../jak3/subtitle/subtitle_lines_en-US.json | 49 +- .../jak3/subtitle/subtitle_lines_es-ES.json | 47 +- .../jak3/subtitle/subtitle_lines_fr-FR.json | 47 +- .../jak3/subtitle/subtitle_lines_it-IT.json | 47 +- .../jak3/subtitle/subtitle_lines_jp-JP.json | 47 +- .../jak3/subtitle/subtitle_lines_ko-KR.json | 47 +- .../jak3/subtitle/subtitle_lines_nl-NL.json | 50 + .../jak3/subtitle/subtitle_lines_pt-PT.json | 50 + .../jak3/subtitle/subtitle_lines_ru-RU.json | 50 + .../jak3/subtitle/subtitle_meta_cm-CM.json | 4 + .../jak3/subtitle/subtitle_meta_en-US.json | 9448 ++++++++++++++++- .../jak3/subtitle/subtitle_meta_nl-NL.json | 4 + .../jak3/subtitle/subtitle_meta_pt-PT.json | 4 + .../jak3/subtitle/subtitle_meta_ru-RU.json | 4 + game/kernel/jak3/kmachine.cpp | 2 +- game/kernel/jak3/kmachine_extras.cpp | 42 + game/kernel/jak3/kscheme.h | 1 + .../tools/subtitle_editor/subtitle_editor.cpp | 4 + goal_src/jak2/engine/load/loader.gc | 2 +- goal_src/jak3/dgos/game.gd | 3 + goal_src/jak3/engine/debug/default-menu.gc | 2 + goal_src/jak3/engine/gfx/font-h.gc | 10 +- goal_src/jak3/engine/load/loader.gc | 10 +- goal_src/jak3/engine/scene/scene.gc | 13 +- .../jak3/engine/ui/progress/progress-draw.gc | 4 +- goal_src/jak3/game.gp | 4 +- goal_src/jak3/kernel/gkernel.gc | 5 + goal_src/jak3/kernel/gstate.gc | 3 +- goal_src/jak3/pc/debug/default-menu-pc.gc | 68 +- goal_src/jak3/pc/debug/vag-player.gc | 456 + goal_src/jak3/pc/subtitle3-h.gc | 381 + goal_src/jak3/pc/subtitle3.gc | 885 ++ goalc/data_compiler/game_text_common.cpp | 9 +- .../reference/jak3/decompiler-macros.gc | 2 +- .../reference/jak3/engine/gfx/font-h_REF.gc | 14 +- .../engine/ui/progress/progress-draw_REF.gc | 8 +- 48 files changed, 12292 insertions(+), 126 deletions(-) create mode 100644 game/assets/jak3/subtitle/subtitle_lines_cm-CM.json create mode 100644 game/assets/jak3/subtitle/subtitle_lines_nl-NL.json create mode 100644 game/assets/jak3/subtitle/subtitle_lines_pt-PT.json create mode 100644 game/assets/jak3/subtitle/subtitle_lines_ru-RU.json create mode 100644 game/assets/jak3/subtitle/subtitle_meta_cm-CM.json create mode 100644 game/assets/jak3/subtitle/subtitle_meta_nl-NL.json create mode 100644 game/assets/jak3/subtitle/subtitle_meta_pt-PT.json create mode 100644 game/assets/jak3/subtitle/subtitle_meta_ru-RU.json create mode 100644 goal_src/jak3/pc/debug/vag-player.gc create mode 100644 goal_src/jak3/pc/subtitle3-h.gc create mode 100644 goal_src/jak3/pc/subtitle3.gc diff --git a/common/serialization/subtitles/subtitles.cpp b/common/serialization/subtitles/subtitles.cpp index e189de48ac6..4ad154b83e6 100644 --- a/common/serialization/subtitles/subtitles.cpp +++ b/common/serialization/subtitles/subtitles.cpp @@ -61,7 +61,10 @@ const std::unordered_map> locale_lookup = {GameVersion::Jak1, {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "en-GB", "pt-PT", "fi-FI", "sv-SE", "da-DK", "no-NO", "nl-NL", "pt-BR", "hu-HU", "ca-ES", "is-IS"}}, - {GameVersion::Jak2, {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "ko-KR", "en-GB"}}}; + {GameVersion::Jak2, {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "ko-KR", "en-GB"}}, + {GameVersion::Jak3, + {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "cm-CM", "jp-JP", "ko-KR", "ru-RU", "pt-PT", + "nl-NL", "en-GB"}}}; std::string lookup_locale_code(const GameVersion game_version, const int language_id) { if (locale_lookup.find(game_version) == locale_lookup.end() || @@ -73,7 +76,8 @@ std::string lookup_locale_code(const GameVersion game_version, const int languag const std::unordered_map> language_ids_with_audio = { {GameVersion::Jak1, {0, 1, 2, 3, 4, 5, 6}}, - {GameVersion::Jak2, {0, 1, 2, 3, 4, 5, 6, 7}}}; + {GameVersion::Jak2, {0, 1, 2, 3, 4, 5, 6, 7}}, + {GameVersion::Jak3, {0, 1, 2, 3, 4, 5, 11}}}; bool dump_language_with_duplicates_from_base(const GameVersion game_version, const int language_id) { diff --git a/common/serialization/subtitles/subtitles_v2.cpp b/common/serialization/subtitles/subtitles_v2.cpp index afc920c30a4..49d8917cbbd 100644 --- a/common/serialization/subtitles/subtitles_v2.cpp +++ b/common/serialization/subtitles/subtitles_v2.cpp @@ -93,6 +93,55 @@ const std::unordered_map jak2_speaker_name_to_enum_val = { {"metalkor-before-consite", 35}, {"metalkor-intro", 36}}; +// matches enum in `subtitle3-h.gc` with "none" (first) and "max" (last and removed) +const std::unordered_map jak3_speaker_name_to_enum_val = { + {"none", 0}, + {"jak", 1}, + {"darkjak", 2}, + {"daxter", 3}, + {"pecker", 4}, + {"ashelin", 5}, + {"veger", 6}, + {"samos", 7}, + {"damas", 8}, + {"kleiver", 9}, + {"seem", 10}, + {"errol", 11}, + {"errol-hologram", 12}, + {"sig", 13}, + {"torn", 14}, + {"tess", 15}, + {"guard", 16}, + {"guard-a", 17}, + {"guard-b", 18}, + {"keira", 19}, + {"vin", 20}, + {"onin", 21}, + {"jinx", 22}, + {"wastelander-male", 23}, + {"wastelander-female", 24}, + {"citizen-male", 25}, + {"citizen-female", 26}, + {"marauder", 27}, + {"oracle", 28}, + {"precursor", 29}, + {"ottsel-leader", 30}, + {"ottsel-surfer", 31}, + {"ottsel-dummy", 32}, + {"ottsel-veger", 33}, + {"ottsel-tess", 34}, + {"computer", 35}, + {"krew", 36}, + {"baron", 37}, + {"scherr", 38}, + {"arey", 39}, + {"baldwin", 40}, + {"schimpf", 41}, + {"martinsen", 42}, + {"phillips", 43}, + {"yates", 44}, +}; + GameSubtitlePackage read_json_files_v2(const GameSubtitleDefinitionFile& file_info) { GameSubtitlePackage package; SubtitleFile lang_lines; @@ -256,11 +305,21 @@ void GameSubtitleBank::add_scenes_from_files(const GameSubtitlePackage& package) } } -// TODO - for jak 3+, this needs some game version context info (could infer from text version) std::vector GameSubtitleBank::speaker_names_ordered_by_enum_value() { // Create a temporary vector of pairs (key, value) - std::vector> temp_vec(jak2_speaker_name_to_enum_val.begin(), - jak2_speaker_name_to_enum_val.end()); + std::vector> temp_vec; + switch (m_text_version) { + case GameTextVersion::JAK2: + temp_vec = {jak2_speaker_name_to_enum_val.begin(), jak2_speaker_name_to_enum_val.end()}; + break; + case GameTextVersion::JAK3: + temp_vec = {jak3_speaker_name_to_enum_val.begin(), jak3_speaker_name_to_enum_val.end()}; + break; + default: + throw std::runtime_error(fmt::format("GameSubtitleBank: invalid game text version {} ({})", + (int)m_text_version, + get_text_version_name(m_text_version))); + } // Sort the temporary vector based on the enum value in ascending order std::sort(temp_vec.begin(), temp_vec.end(), [](const auto& a, const auto& b) { return a.second < b.second; }); @@ -279,13 +338,25 @@ std::vector GameSubtitleBank::speaker_names_ordered_by_enum_value() } u16 GameSubtitleBank::speaker_enum_value_from_name(const std::string& speaker_id) { - if (jak2_speaker_name_to_enum_val.find(speaker_id) == jak2_speaker_name_to_enum_val.end()) { + std::unordered_map enum_map; + switch (m_text_version) { + case GameTextVersion::JAK2: + enum_map = jak2_speaker_name_to_enum_val; + break; + case GameTextVersion::JAK3: + enum_map = jak3_speaker_name_to_enum_val; + break; + default: + throw std::runtime_error(fmt::format("GameSubtitleBank: invalid game text version {}", + get_text_version_name(m_text_version))); + } + if (enum_map.find(speaker_id) == enum_map.end()) { throw std::runtime_error( fmt::format("'{}' speaker could not be found in the enum value mapping, update it or fix " "the invalid speaker!", speaker_id)); } - return u16(jak2_speaker_name_to_enum_val.at(speaker_id)); + return u16(enum_map.at(speaker_id)); } SubtitleMetadataFile dump_bank_meta_v2(const GameVersion game_version, diff --git a/decompiler/config/jak3/all-types.gc b/decompiler/config/jak3/all-types.gc index 6664c5d8cd0..6aaa4598942 100644 --- a/decompiler/config/jak3/all-types.gc +++ b/decompiler/config/jak3/all-types.gc @@ -8306,7 +8306,7 @@ (define-extern *font-default-matrix* matrix) (define-extern *font-work* font-work) (define-extern font-set-tex0 (function (pointer gs-tex0) texture int int int none)) -(define-extern set-font-color (function font-color int rgba rgba rgba int)) +(define-extern set-font-color (function font-color rgba rgba rgba rgba int)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; decomp-h ;; diff --git a/decompiler/config/jak3/jak3_config.jsonc b/decompiler/config/jak3/jak3_config.jsonc index 710820c0c4a..7551fcfddc5 100644 --- a/decompiler/config/jak3/jak3_config.jsonc +++ b/decompiler/config/jak3/jak3_config.jsonc @@ -73,7 +73,7 @@ "write_hex_near_instructions": false, // to write out "scripts", which are currently just all the linked lists found. mostly a jak 2/3 thing - "write_scripts": true, + "write_scripts": false, // hex dump of code/data files. "hexdump_code": false, diff --git a/decompiler/config/jak3/ntsc_v1/inputs.jsonc b/decompiler/config/jak3/ntsc_v1/inputs.jsonc index ffd7135048f..2f819b6d422 100644 --- a/decompiler/config/jak3/ntsc_v1/inputs.jsonc +++ b/decompiler/config/jak3/ntsc_v1/inputs.jsonc @@ -316,7 +316,240 @@ "str_texture_file_names": ["STR/PRMINIMA.STR"], // some objects are part of STR files (streaming data). - "str_file_names": [], + "str_file_names": [ + "STR/ARF1INTR.STR", + "STR/ARF1RES.STR", + "STR/ARF2INTR.STR", + "STR/ARF2RES.STR", + "STR/ARF3INTR.STR", + "STR/ARF3RES.STR", + "STR/AROUTRO.STR", + "STR/ART1INTR.STR", + "STR/CAGSHIEL.STR", + "STR/CATRES.STR", + "STR/CAWRRES.STR", + "STR/CIATIDES.STR", + "STR/CIATOUT.STR", + "STR/CIBBINTR.STR", + "STR/CIBBRES.STR", + "STR/CIBTINTR.STR", + "STR/CIDGRES.STR", + "STR/CIFCEINT.STR", + "STR/CIGC1RES.STR", + "STR/CIGC2INT.STR", + "STR/CIGC2RES.STR", + "STR/CIGCINTR.STR", + "STR/CIGDPUNC.STR", + "STR/CIGTCINT.STR", + "STR/CIHVRES.STR", + "STR/CIPAIB.STR", + "STR/CIPAINTR.STR", + "STR/CIPARES.STR", + "STR/CIPFINTR.STR", + "STR/CIPGINTR.STR", + "STR/CIPGRES.STR", + "STR/CIPHINTR.STR", + "STR/CIPHRES.STR", + "STR/CISFINTR.STR", + "STR/COETEMPL.STR", + "STR/COEXIT.STR", + "STR/DAD06.STR", + "STR/DAD07.STR", + "STR/DAD10.STR", + "STR/DAD12.STR", + "STR/DAD13.STR", + "STR/DAD14.STR", + "STR/DAD16.STR", + "STR/DAD17.STR", + "STR/DAD18.STR", + "STR/DAD20.STR", + "STR/DAD21.STR", + "STR/DAD24.STR", + "STR/DAD31.STR", + "STR/DAD35.STR", + "STR/DAD38.STR", + "STR/DAD57.STR", + "STR/DAD58.STR", + "STR/DAD61.STR", + "STR/DAMOLE.STR", + "STR/DEAR1INT.STR", + "STR/DEAR1RES.STR", + "STR/DEAR2INT.STR", + "STR/DEATIN.STR", + "STR/DEATOUT.STR", + "STR/DEBBINTR.STR", + "STR/DECLINTR.STR", + "STR/DECRINTR.STR", + "STR/DECWIN.STR", + "STR/DEFBIA.STR", + "STR/DEFBINTR.STR", + "STR/DEFBRB.STR", + "STR/DEFBRES.STR", + "STR/DEGRES.STR", + "STR/DEHINTRO.STR", + "STR/DEHRES.STR", + "STR/DEJGOTA.STR", + "STR/DEJGOTB.STR", + "STR/DEJGOTC.STR", + "STR/DEJMINTR.STR", + "STR/DELC2.STR", + "STR/DELC3.STR", + "STR/DELCATCH.STR", + "STR/DEODRB.STR", + "STR/DEODRES.STR", + "STR/DERINTRO.STR", + "STR/DERRA.STR", + // "STR/DESCREEN.STR", + "STR/DPBTURRE.STR", + "STR/FABINTRO.STR", + "STR/FABRES.STR", + "STR/FAI1INTR.STR", + "STR/FAI2INTR.STR", + "STR/FAI3INTR.STR", + "STR/FAI4INTR.STR", + "STR/FASBIB.STR", + "STR/FASBINTR.STR", + "STR/FASBRES.STR", + "STR/FORB.STR", + "STR/FORCRES.STR", + "STR/FOTOMRES.STR", + "STR/FOTOWER.STR", + "STR/GRMANIMS.STR", + "STR/INDROP.STR", + "STR/INFFHQ.STR", + "STR/INLOST.STR", + "STR/INPALACE.STR", + "STR/INRESCUE.STR", + "STR/INTIRED.STR", + "STR/INTRAINI.STR", + "STR/JAA1.STR", + "STR/JAA2.STR", + "STR/JAA3.STR", + "STR/JAA4.STR", + "STR/JAA5.STR", + "STR/JAA6.STR", + "STR/JAA7.STR", + "STR/JABOARD.STR", + "STR/JACARRY.STR", + "STR/JAD1.STR", + "STR/JAD2.STR", + "STR/JAD3.STR", + "STR/JAD4.STR", + "STR/JAD5.STR", + "STR/JADARK.STR", + "STR/JADON.STR", + "STR/JADUMMY.STR", + "STR/JAEBOARD.STR", + "STR/JAEDARK.STR", + "STR/JAEGC.STR", + "STR/JAEGNORM.STR", + "STR/JAEGOLD.STR", + "STR/JAELIGHT.STR", + "STR/JAENORMA.STR", + // "STR/JAEXTERN.STR", + "STR/JAFLDAX.STR", + "STR/JAFLUT.STR", + "STR/JAGUN.STR", + "STR/JAICE.STR", + "STR/JAINDAX.STR", + "STR/JAKANGA.STR", + "STR/JALADDER.STR", + "STR/JALIGHT.STR", + "STR/JAMECH.STR", + "STR/JAPEGASU.STR", + "STR/JAPGLIDE.STR", + "STR/JAPGUN.STR", + "STR/JAPHCAR.STR", + "STR/JAPIDAX.STR", + "STR/JAPILOT.STR", + "STR/JAPOLE.STR", + "STR/JAPWCAR.STR", + "STR/JARACER.STR", + "STR/JASWIM.STR", + "STR/JATENTAC.STR", + "STR/JATUBE.STR", + "STR/JATURRET.STR", + "STR/KRWB1.STR", + "STR/KRWB2.STR", + "STR/KRWB3.STR", + "STR/MIBINTRO.STR", + "STR/MIBRES.STR", + "STR/MIERES.STR", + "STR/MIGEXIT.STR", + "STR/MITINTRO.STR", + "STR/MITRES.STR", + "STR/MU2ANIMS.STR", + "STR/MU3ANIMS.STR", + "STR/MU4ANIMS.STR", + "STR/MUANIMS.STR", + "STR/NEDBARRI.STR", + "STR/NEEINTRO.STR", + "STR/NEHINTRO.STR", + "STR/NEHRES.STR", + "STR/NSB1BREA.STR", + "STR/NSB2BREA.STR", + "STR/PARAINTR.STR", + "STR/PARARA.STR", + "STR/PARARES.STR", + "STR/PARPINTR.STR", + "STR/PEFLY.STR", + "STR/POAINTRO.STR", + "STR/PRDSERES.STR", + "STR/PRDSLOSE.STR", + "STR/PRDSRES.STR", + "STR/PRHA.STR", + "STR/PRHB.STR", + "STR/PRHC.STR", + "STR/PRHFINAL.STR", + // "STR/PRMINIMA.STR", + "STR/PRTRES.STR", + "STR/RATA1INT.STR", + "STR/RATA2INT.STR", + // "STR/SCBOOK.STR", + "STR/SEEINTRO.STR", + "STR/SEGENTRA.STR", + "STR/SEHKENTR.STR", + "STR/SEHKRES.STR", + "STR/SEKENTRA.STR", + "STR/SEKEXIT.STR", + "STR/SEKMINTR.STR", + "STR/SEMEXIT.STR", + "STR/SEMHINTR.STR", + "STR/SEPEXIT.STR", + "STR/SESGRUNT.STR", + "STR/SEWATERS.STR", + "STR/TECINTRO.STR", + "STR/TECRES.STR", + "STR/TEDINTRO.STR", + "STR/TEDRES.STR", + "STR/TEEANIMS.STR", + "STR/TEELAANI.STR", + "STR/TEELODS.STR", + "STR/TEJGLGLI.STR", + "STR/TEOINTRO.STR", + "STR/TEORES.STR", + "STR/TETINTRO.STR", + "STR/TETRA.STR", + "STR/TETRB.STR", + "STR/TEWDESER.STR", + "STR/TODINTRO.STR", + "STR/TODRB.STR", + "STR/TODRES.STR", + "STR/VODRES.STR", + "STR/VOI1INTR.STR", + "STR/VOI1RES.STR", + "STR/VOI2INTR.STR", + "STR/VOI2RES.STR", + "STR/WACINTRO.STR", + "STR/WADRES.STR", + "STR/WAGINTRO.STR", + "STR/WAGRES.STR", + "STR/WALRINTR.STR", + "STR/WALRRES.STR", + "STR/WAPGINTR.STR", + "STR/WAPGRES.STR" + // "STR/WOMAP.STR" + ], // streaming "art" that should be added to GAME.FR3. "str_art_file_names": ["STR/JAEXTERN.STR"], diff --git a/decompiler/config/jak3/ntsc_v1/var_names.jsonc b/decompiler/config/jak3/ntsc_v1/var_names.jsonc index 5793eec3724..39f24b388dc 100644 --- a/decompiler/config/jak3/ntsc_v1/var_names.jsonc +++ b/decompiler/config/jak3/ntsc_v1/var_names.jsonc @@ -2141,5 +2141,8 @@ "a2-1": ["a2-1", "uint"], "a3-0": ["a3-0", "uint"] } + }, + "set-font-color": { + "args": ["idx", "clr0", "clr1", "clr2", "clr3"] } } diff --git a/decompiler/data/StrFileReader.cpp b/decompiler/data/StrFileReader.cpp index f50e5049bac..526f92bda35 100644 --- a/decompiler/data/StrFileReader.cpp +++ b/decompiler/data/StrFileReader.cpp @@ -166,7 +166,7 @@ FullName extract_name(const std::string& file_info_name) { name.name = name.name.substr(0, name.name.length() - 6); int chunk_id = 0; int place = 0; - for (int i = 2; i-- > 0;) { + for (int i = 3; i-- > 0;) { char c = name.name.back(); if (c >= '0' && c <= '9') { int val = (c - '0'); diff --git a/decompiler/data/game_text.cpp b/decompiler/data/game_text.cpp index bf1f0ec7d4c..294b335a78d 100644 --- a/decompiler/data/game_text.cpp +++ b/decompiler/data/game_text.cpp @@ -454,7 +454,7 @@ std::string write_spool_subtitles( bool has_spools = false; for (auto& [spool_name, subs] : data) { result += " \"" + spool_name + "\": {\n"; - result += " \"scene\": true,\n"; + // result += " \"scene\": true,\n"; result += " \"lines\": [\n"; bool has_subs = false; for (auto& sub : subs) { @@ -463,20 +463,20 @@ std::string write_spool_subtitles( continue; } result += " {\n"; - result += " \"end\": " + float_to_string(sub.end_frame) + ",\n"; + result += " \"frame_end\": " + float_to_string(sub.end_frame) + ",\n"; + result += " \"frame_start\": " + float_to_string(sub.start_frame) + ",\n"; if (dump_text) { result += " \"merge\": false,\n"; } else { result += " \"merge\": true,\n"; } result += " \"offscreen\": false,\n"; - result += " \"speaker\": \"none\",\n"; - result += " \"start\": " + float_to_string(sub.start_frame) + ",\n"; if (dump_text) { - result += " \"text\": \"" + msg.text + "\"\n"; + result += " \"text\": \"" + msg.text + "\",\n"; } else { - result += " \"text\": \"\"\n"; + // result += " \"text\": \"\",\n"; } + result += " \"speaker\": \"none\"\n"; result += " },\n"; has_subs = true; } diff --git a/game/assets/jak3/game_subtitle.gp b/game/assets/jak3/game_subtitle.gp index 89f54566f0d..f81fcd83f4c 100644 --- a/game/assets/jak3/game_subtitle.gp +++ b/game/assets/jak3/game_subtitle.gp @@ -3,55 +3,82 @@ (subtitle-v2 (file-json :language-id 0 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json :language-id 1 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_fr-FR.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_fr-FR.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_fr-FR.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_fr-FR.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json :language-id 2 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_de-DE.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_de-DE.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_de-DE.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_de-DE.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json :language-id 3 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_es-ES.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_es-ES.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_es-ES.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_es-ES.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json :language-id 4 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_it-IT.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_it-IT.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_it-IT.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_it-IT.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json + ;; commentary :language-id 5 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_jp-JP.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_jp-JP.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_cm-CM.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_cm-CM.json") (file-json :language-id 6 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_ko-KR.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_ko-KR.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_jp-JP.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_jp-JP.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json :language-id 7 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_en-GB.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_en-GB.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json")) + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_ko-KR.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_ko-KR.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") + (file-json + :language-id 8 + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_ru-RU.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_ru-RU.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") + (file-json + :language-id 9 + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_pt-PT.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_pt-PT.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") + (file-json + :language-id 10 + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_nl-NL.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_nl-NL.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") + (file-json + :language-id 11 + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_en-GB.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_en-GB.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json")) diff --git a/game/assets/jak3/subtitle/subtitle_lines_cm-CM.json b/game/assets/jak3/subtitle/subtitle_lines_cm-CM.json new file mode 100644 index 00000000000..adafe6184eb --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_lines_cm-CM.json @@ -0,0 +1,50 @@ +{ + "cutscenes": {}, + "other": {}, + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } +} diff --git a/game/assets/jak3/subtitle/subtitle_lines_de-DE.json b/game/assets/jak3/subtitle/subtitle_lines_de-DE.json index 7942f008bc7..adafe6184eb 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_de-DE.json +++ b/game/assets/jak3/subtitle/subtitle_lines_de-DE.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_en-GB.json b/game/assets/jak3/subtitle/subtitle_lines_en-GB.json index 7942f008bc7..adafe6184eb 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_en-GB.json +++ b/game/assets/jak3/subtitle/subtitle_lines_en-GB.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_en-US.json b/game/assets/jak3/subtitle/subtitle_lines_en-US.json index 7942f008bc7..f0188637186 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_en-US.json +++ b/game/assets/jak3/subtitle/subtitle_lines_en-US.json @@ -1,5 +1,50 @@ { "cutscenes": {}, - "other": {}, - "speakers": {} + "other": { "dax128": ["Head for the city, Jak."] }, + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_es-ES.json b/game/assets/jak3/subtitle/subtitle_lines_es-ES.json index 7942f008bc7..adafe6184eb 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_es-ES.json +++ b/game/assets/jak3/subtitle/subtitle_lines_es-ES.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_fr-FR.json b/game/assets/jak3/subtitle/subtitle_lines_fr-FR.json index 7942f008bc7..adafe6184eb 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_fr-FR.json +++ b/game/assets/jak3/subtitle/subtitle_lines_fr-FR.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_it-IT.json b/game/assets/jak3/subtitle/subtitle_lines_it-IT.json index 7942f008bc7..adafe6184eb 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_it-IT.json +++ b/game/assets/jak3/subtitle/subtitle_lines_it-IT.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_jp-JP.json b/game/assets/jak3/subtitle/subtitle_lines_jp-JP.json index 7942f008bc7..adafe6184eb 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_jp-JP.json +++ b/game/assets/jak3/subtitle/subtitle_lines_jp-JP.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_ko-KR.json b/game/assets/jak3/subtitle/subtitle_lines_ko-KR.json index 7942f008bc7..adafe6184eb 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_ko-KR.json +++ b/game/assets/jak3/subtitle/subtitle_lines_ko-KR.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_nl-NL.json b/game/assets/jak3/subtitle/subtitle_lines_nl-NL.json new file mode 100644 index 00000000000..adafe6184eb --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_lines_nl-NL.json @@ -0,0 +1,50 @@ +{ + "cutscenes": {}, + "other": {}, + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } +} diff --git a/game/assets/jak3/subtitle/subtitle_lines_pt-PT.json b/game/assets/jak3/subtitle/subtitle_lines_pt-PT.json new file mode 100644 index 00000000000..adafe6184eb --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_lines_pt-PT.json @@ -0,0 +1,50 @@ +{ + "cutscenes": {}, + "other": {}, + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } +} diff --git a/game/assets/jak3/subtitle/subtitle_lines_ru-RU.json b/game/assets/jak3/subtitle/subtitle_lines_ru-RU.json new file mode 100644 index 00000000000..adafe6184eb --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_lines_ru-RU.json @@ -0,0 +1,50 @@ +{ + "cutscenes": {}, + "other": {}, + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } +} diff --git a/game/assets/jak3/subtitle/subtitle_meta_cm-CM.json b/game/assets/jak3/subtitle/subtitle_meta_cm-CM.json new file mode 100644 index 00000000000..495996ba8e7 --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_meta_cm-CM.json @@ -0,0 +1,4 @@ +{ + "cutscenes": {}, + "other": {} +} diff --git a/game/assets/jak3/subtitle/subtitle_meta_en-US.json b/game/assets/jak3/subtitle/subtitle_meta_en-US.json index 495996ba8e7..811141e4da9 100644 --- a/game/assets/jak3/subtitle/subtitle_meta_en-US.json +++ b/game/assets/jak3/subtitle/subtitle_meta_en-US.json @@ -1,4 +1,9448 @@ { - "cutscenes": {}, - "other": {} + "cutscenes": { + "wascity-leaper-race-intro": { + "lines": [ + { + "frame_end": 91.0, + "frame_start": 46.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 170.0, + "frame_start": 95.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 227.0, + "frame_start": 175.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 320.0, + "frame_start": 281.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 444.0, + "frame_start": 321.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 535.0, + "frame_start": 445.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 609.0, + "frame_start": 541.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 695.0, + "frame_start": 610.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 747.0, + "frame_start": 696.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 851.0, + "frame_start": 788.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 926.0, + "frame_start": 852.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1007.0, + "frame_start": 927.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1134.0, + "frame_start": 1008.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1188.0, + "frame_start": 1147.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1264.0, + "frame_start": 1214.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1336.0, + "frame_start": 1271.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-gun-res": { + "lines": [ + { + "frame_end": 184.0, + "frame_start": 75.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 258.0, + "frame_start": 185.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 400.0, + "frame_start": 259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 544.0, + "frame_start": 401.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-defend-res": { + "lines": [ + { + "frame_end": 56.0, + "frame_start": 25.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 147.0, + "frame_start": 57.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 187.0, + "frame_start": 148.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 306.0, + "frame_start": 188.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 440.0, + "frame_start": 307.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 524.0, + "frame_start": 448.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 631.0, + "frame_start": 535.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 764.0, + "frame_start": 632.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 816.0, + "frame_start": 765.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 948.0, + "frame_start": 830.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1060.0, + "frame_start": 949.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1185.0, + "frame_start": 1061.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1281.0, + "frame_start": 1196.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1427.0, + "frame_start": 1282.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1493.0, + "frame_start": 1428.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1608.0, + "frame_start": 1502.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1690.0, + "frame_start": 1623.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1806.0, + "frame_start": 1703.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1865.0, + "frame_start": 1817.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "volcano-indax-1-intro": { + "lines": [ + { + "frame_end": 151.0, + "frame_start": 102.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "tower-destroy-intro": { + "lines": [ + { + "frame_end": 344.0, + "frame_start": 298.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 394.0, + "frame_start": 345.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 455.0, + "frame_start": 405.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 502.0, + "frame_start": 460.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 554.0, + "frame_start": 511.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 660.0, + "frame_start": 555.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-tests-res-b": { + "lines": [ + { + "frame_end": 241.0, + "frame_start": 166.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 280.0, + "frame_start": 242.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 325.0, + "frame_start": 296.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 418.0, + "frame_start": 338.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 546.0, + "frame_start": 422.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 619.0, + "frame_start": 547.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 735.0, + "frame_start": 620.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 853.0, + "frame_start": 806.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-tests-res-a": { + "lines": [ + { + "frame_end": 226.0, + "frame_start": 51.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 339.0, + "frame_start": 227.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 514.0, + "frame_start": 340.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 632.0, + "frame_start": 515.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 771.0, + "frame_start": 633.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-tests-intro": { + "lines": [ + { + "frame_end": 232.0, + "frame_start": 191.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 273.0, + "frame_start": 233.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-oracle-res": { + "lines": [ + { + "frame_end": 154.0, + "frame_start": 57.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 258.0, + "frame_start": 173.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 353.0, + "frame_start": 259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 464.0, + "frame_start": 354.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 573.0, + "frame_start": 465.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 752.0, + "frame_start": 574.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 850.0, + "frame_start": 762.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 962.0, + "frame_start": 851.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1067.0, + "frame_start": 965.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1185.0, + "frame_start": 1068.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1223.0, + "frame_start": 1189.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1346.0, + "frame_start": 1226.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1371.0, + "frame_start": 1351.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1518.0, + "frame_start": 1381.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1651.0, + "frame_start": 1582.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1840.0, + "frame_start": 1673.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-oracle-intro": { + "lines": [ + { + "frame_end": 182.0, + "frame_start": 136.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 271.0, + "frame_start": 183.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 324.0, + "frame_start": 275.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 416.0, + "frame_start": 325.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 571.0, + "frame_start": 419.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 694.0, + "frame_start": 572.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 784.0, + "frame_start": 695.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 845.0, + "frame_start": 796.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-defend-res": { + "lines": [ + { + "frame_end": 147.0, + "frame_start": 33.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 223.0, + "frame_start": 148.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 329.0, + "frame_start": 224.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 506.0, + "frame_start": 353.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 694.0, + "frame_start": 544.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 809.0, + "frame_start": 716.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 919.0, + "frame_start": 810.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1030.0, + "frame_start": 928.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1223.0, + "frame_start": 1031.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1275.0, + "frame_start": 1230.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-gun-intro": { + "lines": [ + { + "frame_end": 121.0, + "frame_start": 20.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 156.0, + "frame_start": 122.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 226.0, + "frame_start": 158.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 309.0, + "frame_start": 227.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 382.0, + "frame_start": 310.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 437.0, + "frame_start": 383.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 585.0, + "frame_start": 440.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-defend-intro": { + "lines": [ + { + "frame_end": 153.0, + "frame_start": 37.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 254.0, + "frame_start": 162.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 366.0, + "frame_start": 264.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 527.0, + "frame_start": 367.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 628.0, + "frame_start": 547.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 707.0, + "frame_start": 629.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 817.0, + "frame_start": 708.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 927.0, + "frame_start": 823.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 999.0, + "frame_start": 928.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1067.0, + "frame_start": 1000.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1108.0, + "frame_start": 1068.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-climb-res": { + "lines": [ + { + "frame_end": 99.0, + "frame_start": 57.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 192.0, + "frame_start": 104.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 267.0, + "frame_start": 193.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 342.0, + "frame_start": 269.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 455.0, + "frame_start": 343.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 496.0, + "frame_start": 457.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 591.0, + "frame_start": 497.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 701.0, + "frame_start": 592.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 780.0, + "frame_start": 702.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 907.0, + "frame_start": 781.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 972.0, + "frame_start": 908.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 993.0, + "frame_start": 976.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1015.0, + "frame_start": 994.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1047.0, + "frame_start": 1016.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1088.0, + "frame_start": 1048.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1105.0, + "frame_start": 1089.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1123.0, + "frame_start": 1106.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1142.0, + "frame_start": 1124.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1235.0, + "frame_start": 1181.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "sewer-kg-met-intro": { + "lines": [ + { + "frame_end": 100.0, + "frame_start": 37.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 149.0, + "frame_start": 101.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 214.0, + "frame_start": 150.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 290.0, + "frame_start": 215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 394.0, + "frame_start": 291.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 471.0, + "frame_start": 395.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 544.0, + "frame_start": 478.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 672.0, + "frame_start": 556.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 692.0, + "frame_start": 679.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 795.0, + "frame_start": 706.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 869.0, + "frame_start": 806.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 928.0, + "frame_start": 870.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "volcano-darkeco-res": { + "lines": [ + { + "frame_end": 207.0, + "frame_start": 171.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 245.0, + "frame_start": 213.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 316.0, + "frame_start": 246.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 361.0, + "frame_start": 331.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 482.0, + "frame_start": 362.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 518.0, + "frame_start": 483.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 592.0, + "frame_start": 536.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 754.0, + "frame_start": 614.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 790.0, + "frame_start": 755.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 874.0, + "frame_start": 791.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 910.0, + "frame_start": 879.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1011.0, + "frame_start": 994.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1041.0, + "frame_start": 1026.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1087.0, + "frame_start": 1057.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1124.0, + "frame_start": 1109.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1276.0, + "frame_start": 1138.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1322.0, + "frame_start": 1287.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1392.0, + "frame_start": 1323.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1452.0, + "frame_start": 1393.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1529.0, + "frame_start": 1481.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1593.0, + "frame_start": 1530.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1709.0, + "frame_start": 1594.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1820.0, + "frame_start": 1785.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1852.0, + "frame_start": 1821.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "sewer-explore-intro": { + "lines": [ + { + "frame_end": 100.0, + "frame_start": 37.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 149.0, + "frame_start": 101.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 214.0, + "frame_start": 150.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 290.0, + "frame_start": 215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 394.0, + "frame_start": 291.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 471.0, + "frame_start": 395.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 544.0, + "frame_start": 478.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 672.0, + "frame_start": 556.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 692.0, + "frame_start": 679.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 795.0, + "frame_start": 706.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 869.0, + "frame_start": 806.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 928.0, + "frame_start": 870.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "precursor-tour-res": { + "lines": [ + { + "frame_end": 94.0, + "frame_start": 52.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 120.0, + "frame_start": 99.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 147.0, + "frame_start": 126.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 196.0, + "frame_start": 151.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 240.0, + "frame_start": 197.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 316.0, + "frame_start": 241.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 358.0, + "frame_start": 317.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 404.0, + "frame_start": 359.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 488.0, + "frame_start": 407.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 539.0, + "frame_start": 502.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "precursor-destroy-ship-res": { + "lines": [ + { + "frame_end": 492.0, + "frame_start": 401.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 590.0, + "frame_start": 512.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 641.0, + "frame_start": 591.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 681.0, + "frame_start": 650.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 730.0, + "frame_start": 682.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 759.0, + "frame_start": 731.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 774.0, + "frame_start": 760.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 880.0, + "frame_start": 865.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 919.0, + "frame_start": 898.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1632.0, + "frame_start": 1590.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-jak-gets-light-glide": { + "lines": [ + { + "frame_end": 196.0, + "frame_start": 62.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 345.0, + "frame_start": 197.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 561.0, + "frame_start": 352.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6801.0, + "frame_start": 567.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "port-assault-intro": { + "lines": [ + { + "frame_end": 114.0, + "frame_start": 30.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 171.0, + "frame_start": 115.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 214.0, + "frame_start": 172.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 319.0, + "frame_start": 215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 362.0, + "frame_start": 320.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 438.0, + "frame_start": 363.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 526.0, + "frame_start": 439.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 568.0, + "frame_start": 527.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 668.0, + "frame_start": 569.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 740.0, + "frame_start": 669.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "palace-ruins-attack-res": { + "lines": [ + { + "frame_end": 320.0, + "frame_start": 299.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 416.0, + "frame_start": 337.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 582.0, + "frame_start": 451.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 751.0, + "frame_start": 598.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 879.0, + "frame_start": 802.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 967.0, + "frame_start": 893.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1175.0, + "frame_start": 968.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1266.0, + "frame_start": 1176.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1403.0, + "frame_start": 1283.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1566.0, + "frame_start": 1404.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1744.0, + "frame_start": 1620.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1964.0, + "frame_start": 1947.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2069.0, + "frame_start": 1986.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2221.0, + "frame_start": 2070.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2291.0, + "frame_start": 2222.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2430.0, + "frame_start": 2292.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2565.0, + "frame_start": 2431.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2716.0, + "frame_start": 2566.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2782.0, + "frame_start": 2730.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2880.0, + "frame_start": 2801.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3018.0, + "frame_start": 2881.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3142.0, + "frame_start": 3111.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3241.0, + "frame_start": 3148.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3293.0, + "frame_start": 3246.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3416.0, + "frame_start": 3294.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3447.0, + "frame_start": 3417.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "nest-hunt-intro": { + "lines": [ + { + "frame_end": 37.0, + "frame_start": 15.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 95.0, + "frame_start": 38.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 193.0, + "frame_start": 96.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 304.0, + "frame_start": 194.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 411.0, + "frame_start": 305.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 467.0, + "frame_start": 412.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 563.0, + "frame_start": 468.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "nest-eggs-intro": { + "lines": [ + { + "frame_end": 128.0, + "frame_start": 38.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 231.0, + "frame_start": 129.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 349.0, + "frame_start": 232.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 435.0, + "frame_start": 350.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 567.0, + "frame_start": 436.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 644.0, + "frame_start": 568.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 694.0, + "frame_start": 645.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 727.0, + "frame_start": 701.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 786.0, + "frame_start": 729.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 879.0, + "frame_start": 787.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 978.0, + "frame_start": 880.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1046.0, + "frame_start": 979.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1132.0, + "frame_start": 1047.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1226.0, + "frame_start": 1133.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "mine-boss-res": { + "lines": [ + { + "frame_end": 339.0, + "frame_start": 311.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 404.0, + "frame_start": 341.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 492.0, + "frame_start": 412.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-protect-hq-intro": { + "lines": [ + { + "frame_end": 92.0, + "frame_start": 31.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 201.0, + "frame_start": 93.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 265.0, + "frame_start": 205.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 340.0, + "frame_start": 272.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 382.0, + "frame_start": 343.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 473.0, + "frame_start": 388.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 511.0, + "frame_start": 474.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 596.0, + "frame_start": 512.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 680.0, + "frame_start": 603.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 815.0, + "frame_start": 688.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 864.0, + "frame_start": 816.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 941.0, + "frame_start": 865.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1063.0, + "frame_start": 942.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1165.0, + "frame_start": 1064.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1244.0, + "frame_start": 1166.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1343.0, + "frame_start": 1254.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1390.0, + "frame_start": 1344.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1504.0, + "frame_start": 1391.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1621.0, + "frame_start": 1515.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1728.0, + "frame_start": 1633.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1897.0, + "frame_start": 1729.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1931.0, + "frame_start": 1905.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2039.0, + "frame_start": 1936.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2087.0, + "frame_start": 2040.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2178.0, + "frame_start": 2091.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-power-game-res": { + "lines": [ + { + "frame_end": 100.0, + "frame_start": 71.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 205.0, + "frame_start": 110.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 297.0, + "frame_start": 206.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 361.0, + "frame_start": 298.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 453.0, + "frame_start": 371.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 480.0, + "frame_start": 454.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "catacombs-wild-ride-res": { + "lines": [ + { + "frame_end": 751.0, + "frame_start": 478.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 938.0, + "frame_start": 799.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1081.0, + "frame_start": 939.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1233.0, + "frame_start": 1117.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1523.0, + "frame_start": 1234.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1579.0, + "frame_start": 1547.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1689.0, + "frame_start": 1580.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1796.0, + "frame_start": 1694.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2002.0, + "frame_start": 1919.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2162.0, + "frame_start": 2003.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2267.0, + "frame_start": 2168.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2429.0, + "frame_start": 2268.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2649.0, + "frame_start": 2449.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2782.0, + "frame_start": 2652.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2862.0, + "frame_start": 2783.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2921.0, + "frame_start": 2863.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3118.0, + "frame_start": 3010.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3291.0, + "frame_start": 3119.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3491.0, + "frame_start": 3439.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3683.0, + "frame_start": 3496.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3936.0, + "frame_start": 3684.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3974.0, + "frame_start": 3950.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4029.0, + "frame_start": 3988.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4090.0, + "frame_start": 4038.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4153.0, + "frame_start": 4095.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4198.0, + "frame_start": 4159.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4345.0, + "frame_start": 4199.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4395.0, + "frame_start": 4346.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4441.0, + "frame_start": 4400.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4545.0, + "frame_start": 4445.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4611.0, + "frame_start": 4546.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4648.0, + "frame_start": 4614.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4745.0, + "frame_start": 4649.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4866.0, + "frame_start": 4798.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4954.0, + "frame_start": 4867.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4981.0, + "frame_start": 4960.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5008.0, + "frame_start": 4982.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5057.0, + "frame_start": 5013.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5079.0, + "frame_start": 5058.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5221.0, + "frame_start": 5080.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5291.0, + "frame_start": 5222.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5375.0, + "frame_start": 5292.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5440.0, + "frame_start": 5379.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5548.0, + "frame_start": 5441.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5636.0, + "frame_start": 5549.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5724.0, + "frame_start": 5654.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5787.0, + "frame_start": 5725.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5907.0, + "frame_start": 5798.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6030.0, + "frame_start": 5965.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6162.0, + "frame_start": 6042.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6243.0, + "frame_start": 6163.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6311.0, + "frame_start": 6248.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6345.0, + "frame_start": 6321.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6382.0, + "frame_start": 6352.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6509.0, + "frame_start": 6383.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6543.0, + "frame_start": 6510.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6603.0, + "frame_start": 6545.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6640.0, + "frame_start": 6616.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6823.0, + "frame_start": 6777.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-power-game-intro": { + "lines": [ + { + "frame_end": 129.0, + "frame_start": 79.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 186.0, + "frame_start": 130.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 277.0, + "frame_start": 195.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 333.0, + "frame_start": 281.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 399.0, + "frame_start": 334.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 463.0, + "frame_start": 401.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 555.0, + "frame_start": 472.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 658.0, + "frame_start": 556.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 744.0, + "frame_start": 659.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 804.0, + "frame_start": 757.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 899.0, + "frame_start": 807.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1031.0, + "frame_start": 900.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1082.0, + "frame_start": 1032.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1221.0, + "frame_start": 1083.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1321.0, + "frame_start": 1222.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1434.0, + "frame_start": 1322.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1523.0, + "frame_start": 1435.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1550.0, + "frame_start": 1532.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1573.0, + "frame_start": 1558.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1601.0, + "frame_start": 1577.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1630.0, + "frame_start": 1602.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1653.0, + "frame_start": 1634.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1682.0, + "frame_start": 1658.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1748.0, + "frame_start": 1683.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1871.0, + "frame_start": 1749.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1959.0, + "frame_start": 1872.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2090.0, + "frame_start": 1960.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2132.0, + "frame_start": 2095.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2212.0, + "frame_start": 2138.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2322.0, + "frame_start": 2213.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2369.0, + "frame_start": 2323.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2480.0, + "frame_start": 2377.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2607.0, + "frame_start": 2485.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2741.0, + "frame_start": 2608.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2773.0, + "frame_start": 2742.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2871.0, + "frame_start": 2789.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2935.0, + "frame_start": 2872.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2982.0, + "frame_start": 2940.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-gun-course-2-res": { + "lines": [ + { + "frame_end": 75.0, + "frame_start": 17.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 172.0, + "frame_start": 76.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 227.0, + "frame_start": 173.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 351.0, + "frame_start": 228.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-leaper-race-res": { + "lines": [ + { + "frame_end": 69.0, + "frame_start": 46.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 151.0, + "frame_start": 70.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 207.0, + "frame_start": 161.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 296.0, + "frame_start": 215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 409.0, + "frame_start": 297.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 448.0, + "frame_start": 410.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 550.0, + "frame_start": 449.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 588.0, + "frame_start": 558.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 641.0, + "frame_start": 591.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 679.0, + "frame_start": 642.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 791.0, + "frame_start": 680.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 875.0, + "frame_start": 792.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "palace-ruins-attack-intro": { + "lines": [ + { + "frame_end": 173.0, + "frame_start": 40.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 312.0, + "frame_start": 174.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 501.0, + "frame_start": 386.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 655.0, + "frame_start": 502.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 756.0, + "frame_start": 656.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 915.0, + "frame_start": 873.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 979.0, + "frame_start": 917.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1063.0, + "frame_start": 980.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1148.0, + "frame_start": 1074.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1246.0, + "frame_start": 1149.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1291.0, + "frame_start": 1258.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-port-attack-intro": { + "lines": [ + { + "frame_end": 133.0, + "frame_start": 31.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 219.0, + "frame_start": 146.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 294.0, + "frame_start": 223.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 391.0, + "frame_start": 295.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 418.0, + "frame_start": 400.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 496.0, + "frame_start": 425.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 575.0, + "frame_start": 497.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 678.0, + "frame_start": 576.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 766.0, + "frame_start": 679.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 838.0, + "frame_start": 767.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 919.0, + "frame_start": 839.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1022.0, + "frame_start": 948.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1072.0, + "frame_start": 1023.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1164.0, + "frame_start": 1080.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1223.0, + "frame_start": 1165.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1334.0, + "frame_start": 1224.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1398.0, + "frame_start": 1343.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1462.0, + "frame_start": 1399.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1540.0, + "frame_start": 1463.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1606.0, + "frame_start": 1541.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1682.0, + "frame_start": 1611.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1726.0, + "frame_start": 1686.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1786.0, + "frame_start": 1727.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "forest-ring-chase-res": { + "lines": [ + { + "frame_end": 199.0, + "frame_start": 85.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 325.0, + "frame_start": 200.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 421.0, + "frame_start": 335.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 569.0, + "frame_start": 431.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 720.0, + "frame_start": 570.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 819.0, + "frame_start": 721.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 942.0, + "frame_start": 820.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1130.0, + "frame_start": 943.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1345.0, + "frame_start": 1131.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1397.0, + "frame_start": 1353.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1464.0, + "frame_start": 1406.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1549.0, + "frame_start": 1473.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1715.0, + "frame_start": 1550.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1810.0, + "frame_start": 1716.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1925.0, + "frame_start": 1811.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2019.0, + "frame_start": 1926.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-gun-course-2-intro": { + "lines": [ + { + "frame_end": 61.0, + "frame_start": 41.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 99.0, + "frame_start": 62.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 178.0, + "frame_start": 100.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 244.0, + "frame_start": 179.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 383.0, + "frame_start": 246.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 462.0, + "frame_start": 384.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 562.0, + "frame_start": 463.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 679.0, + "frame_start": 568.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 764.0, + "frame_start": 680.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 852.0, + "frame_start": 769.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 897.0, + "frame_start": 861.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 939.0, + "frame_start": 899.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1074.0, + "frame_start": 945.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1181.0, + "frame_start": 1075.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1213.0, + "frame_start": 1182.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-rescue": { + "lines": [ + { + "frame_end": 285.0, + "frame_start": 155.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 377.0, + "frame_start": 309.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 415.0, + "frame_start": 378.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 468.0, + "frame_start": 435.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 566.0, + "frame_start": 469.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-port-attack-intro-b": { + "lines": [ + { + "frame_end": 82.0, + "frame_start": 51.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-gun-course-1-res": { + "lines": [ + { + "frame_end": 129.0, + "frame_start": 46.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 216.0, + "frame_start": 131.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 335.0, + "frame_start": 218.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 366.0, + "frame_start": 336.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 452.0, + "frame_start": 367.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-protect-hq-res": { + "lines": [ + { + "frame_end": 59.0, + "frame_start": 19.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 200.0, + "frame_start": 60.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 309.0, + "frame_start": 201.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 404.0, + "frame_start": 310.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 525.0, + "frame_start": 405.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 609.0, + "frame_start": 526.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 671.0, + "frame_start": 616.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 740.0, + "frame_start": 678.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 819.0, + "frame_start": 741.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 916.0, + "frame_start": 820.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 991.0, + "frame_start": 917.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1096.0, + "frame_start": 1034.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1141.0, + "frame_start": 1097.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1157.0, + "frame_start": 1142.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1213.0, + "frame_start": 1174.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1268.0, + "frame_start": 1214.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1295.0, + "frame_start": 1269.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1385.0, + "frame_start": 1299.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1491.0, + "frame_start": 1386.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1551.0, + "frame_start": 1492.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1618.0, + "frame_start": 1554.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1804.0, + "frame_start": 1635.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1856.0, + "frame_start": 1805.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1949.0, + "frame_start": 1901.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2030.0, + "frame_start": 1956.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2114.0, + "frame_start": 2031.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2254.0, + "frame_start": 2115.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2390.0, + "frame_start": 2266.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2436.0, + "frame_start": 2391.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2533.0, + "frame_start": 2437.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2626.0, + "frame_start": 2540.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2751.0, + "frame_start": 2627.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2830.0, + "frame_start": 2752.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2903.0, + "frame_start": 2831.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-find-catacomb-ent-intro": { + "lines": [ + { + "frame_end": 76.0, + "frame_start": 15.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 168.0, + "frame_start": 85.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 259.0, + "frame_start": 169.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 346.0, + "frame_start": 260.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 503.0, + "frame_start": 347.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 638.0, + "frame_start": 509.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 752.0, + "frame_start": 644.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 840.0, + "frame_start": 765.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 964.0, + "frame_start": 850.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1056.0, + "frame_start": 965.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1171.0, + "frame_start": 1057.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1217.0, + "frame_start": 1172.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1370.0, + "frame_start": 1223.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1457.0, + "frame_start": 1380.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1529.0, + "frame_start": 1458.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1630.0, + "frame_start": 1530.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1727.0, + "frame_start": 1631.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-pre-game-res": { + "lines": [ + { + "frame_end": 83.0, + "frame_start": 59.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 157.0, + "frame_start": 96.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 261.0, + "frame_start": 190.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 307.0, + "frame_start": 262.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 380.0, + "frame_start": 317.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 524.0, + "frame_start": 381.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 568.0, + "frame_start": 526.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 636.0, + "frame_start": 569.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 708.0, + "frame_start": 637.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 794.0, + "frame_start": 709.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 863.0, + "frame_start": 796.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 937.0, + "frame_start": 865.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1024.0, + "frame_start": 946.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1312.0, + "frame_start": 1229.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1378.0, + "frame_start": 1319.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1481.0, + "frame_start": 1379.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1569.0, + "frame_start": 1487.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1644.0, + "frame_start": 1570.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1700.0, + "frame_start": 1651.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1796.0, + "frame_start": 1701.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "factory-boss-res": { + "lines": [ + { + "frame_end": 305.0, + "frame_start": 265.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 390.0, + "frame_start": 315.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 486.0, + "frame_start": 426.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-blow-tower-intro": { + "lines": [ + { + "frame_end": 99.0, + "frame_start": 15.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 136.0, + "frame_start": 100.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 206.0, + "frame_start": 143.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 264.0, + "frame_start": 211.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 343.0, + "frame_start": 272.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 386.0, + "frame_start": 344.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 471.0, + "frame_start": 387.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 525.0, + "frame_start": 477.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 576.0, + "frame_start": 526.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 599.0, + "frame_start": 579.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 666.0, + "frame_start": 600.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 713.0, + "frame_start": 667.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 735.0, + "frame_start": 714.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 831.0, + "frame_start": 736.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 960.0, + "frame_start": 832.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1018.0, + "frame_start": 961.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1038.0, + "frame_start": 1019.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1116.0, + "frame_start": 1039.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1199.0, + "frame_start": 1117.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1329.0, + "frame_start": 1200.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1367.0, + "frame_start": 1332.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1479.0, + "frame_start": 1368.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1594.0, + "frame_start": 1480.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1711.0, + "frame_start": 1603.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-fight-1-intro": { + "lines": [ + { + "frame_end": 111.0, + "frame_start": 40.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 226.0, + "frame_start": 114.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 295.0, + "frame_start": 230.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 360.0, + "frame_start": 299.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 513.0, + "frame_start": 392.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 577.0, + "frame_start": 515.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 610.0, + "frame_start": 578.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 745.0, + "frame_start": 614.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 784.0, + "frame_start": 746.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 888.0, + "frame_start": 787.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 933.0, + "frame_start": 898.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 995.0, + "frame_start": 945.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1049.0, + "frame_start": 999.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1131.0, + "frame_start": 1051.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-destroy-grid-res": { + "lines": [ + { + "frame_end": 172.0, + "frame_start": 119.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 247.0, + "frame_start": 173.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 312.0, + "frame_start": 259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 371.0, + "frame_start": 313.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 413.0, + "frame_start": 372.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-fight-3-res": { + "lines": [ + { + "frame_end": 104.0, + "frame_start": 85.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 157.0, + "frame_start": 114.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 182.0, + "frame_start": 159.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 251.0, + "frame_start": 187.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 282.0, + "frame_start": 252.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 363.0, + "frame_start": 284.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 454.0, + "frame_start": 372.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 499.0, + "frame_start": 455.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 604.0, + "frame_start": 500.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 636.0, + "frame_start": 607.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 879.0, + "frame_start": 795.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 982.0, + "frame_start": 880.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1068.0, + "frame_start": 1001.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1112.0, + "frame_start": 1079.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-port-fight-intro": { + "lines": [ + { + "frame_end": 65.0, + "frame_start": 15.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 111.0, + "frame_start": 66.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 195.0, + "frame_start": 113.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 291.0, + "frame_start": 196.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 363.0, + "frame_start": 296.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 475.0, + "frame_start": 364.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 521.0, + "frame_start": 477.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 588.0, + "frame_start": 523.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 606.0, + "frame_start": 589.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 732.0, + "frame_start": 609.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 766.0, + "frame_start": 733.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 852.0, + "frame_start": 767.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 879.0, + "frame_start": 856.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 956.0, + "frame_start": 880.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1009.0, + "frame_start": 957.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1121.0, + "frame_start": 1010.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1183.0, + "frame_start": 1122.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1334.0, + "frame_start": 1184.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1421.0, + "frame_start": 1336.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1465.0, + "frame_start": 1422.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1546.0, + "frame_start": 1466.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1576.0, + "frame_start": 1547.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1611.0, + "frame_start": 1577.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1677.0, + "frame_start": 1615.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1725.0, + "frame_start": 1678.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "catacomb-get-shield": { + "lines": [ + { + "frame_end": 172.0, + "frame_start": 60.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 284.0, + "frame_start": 173.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 397.0, + "frame_start": 285.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 499.0, + "frame_start": 398.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-fight-2-intro": { + "lines": [ + { + "frame_end": 130.0, + "frame_start": 25.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 237.0, + "frame_start": 131.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 325.0, + "frame_start": 238.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 415.0, + "frame_start": 326.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 491.0, + "frame_start": 418.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 578.0, + "frame_start": 492.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 625.0, + "frame_start": 579.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 717.0, + "frame_start": 626.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 788.0, + "frame_start": 718.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 868.0, + "frame_start": 790.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "factory-boss-intro": { + "lines": [ + { + "frame_end": 347.0, + "frame_start": 226.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 407.0, + "frame_start": 354.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 566.0, + "frame_start": 415.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 690.0, + "frame_start": 567.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 849.0, + "frame_start": 691.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 986.0, + "frame_start": 850.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1064.0, + "frame_start": 987.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1117.0, + "frame_start": 1066.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1188.0, + "frame_start": 1118.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1236.0, + "frame_start": 1189.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1381.0, + "frame_start": 1247.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1506.0, + "frame_start": 1382.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1641.0, + "frame_start": 1507.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1744.0, + "frame_start": 1642.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1799.0, + "frame_start": 1753.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "volcano-indax-2-intro": { + "lines": [ + { + "frame_end": 178.0, + "frame_start": 129.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-fight-1-res": { + "lines": [ + { + "frame_end": 273.0, + "frame_start": 204.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 384.0, + "frame_start": 276.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 495.0, + "frame_start": 386.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 537.0, + "frame_start": 500.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 564.0, + "frame_start": 539.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 635.0, + "frame_start": 571.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 673.0, + "frame_start": 636.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 771.0, + "frame_start": 684.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 878.0, + "frame_start": 772.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 961.0, + "frame_start": 879.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1077.0, + "frame_start": 962.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1201.0, + "frame_start": 1078.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1265.0, + "frame_start": 1202.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1371.0, + "frame_start": 1266.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1432.0, + "frame_start": 1372.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1498.0, + "frame_start": 1433.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1567.0, + "frame_start": 1499.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "catacombs-travel-res": { + "lines": [ + { + "frame_end": 108.0, + "frame_start": 40.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 170.0, + "frame_start": 110.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 260.0, + "frame_start": 171.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 362.0, + "frame_start": 268.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 431.0, + "frame_start": 373.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 556.0, + "frame_start": 432.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-fight-2-res": { + "lines": [ + { + "frame_end": 83.0, + "frame_start": 10.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 131.0, + "frame_start": 86.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 217.0, + "frame_start": 135.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 290.0, + "frame_start": 219.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 415.0, + "frame_start": 293.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 529.0, + "frame_start": 416.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 637.0, + "frame_start": 530.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 712.0, + "frame_start": 638.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 791.0, + "frame_start": 714.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 855.0, + "frame_start": 792.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 928.0, + "frame_start": 856.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1022.0, + "frame_start": 930.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1098.0, + "frame_start": 1040.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1149.0, + "frame_start": 1101.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1171.0, + "frame_start": 1150.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1254.0, + "frame_start": 1172.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1338.0, + "frame_start": 1255.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1478.0, + "frame_start": 1339.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1597.0, + "frame_start": 1479.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1711.0, + "frame_start": 1598.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-training-1-intro": { + "lines": [ + { + "frame_end": 112.0, + "frame_start": 27.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 204.0, + "frame_start": 113.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 307.0, + "frame_start": 205.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 408.0, + "frame_start": 308.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 519.0, + "frame_start": 409.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 665.0, + "frame_start": 520.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 796.0, + "frame_start": 732.0, + "merge": true, + "offscreen": false, + "speaker": "jak" + }, + { + "frame_end": 888.0, + "frame_start": 798.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 961.0, + "frame_start": 889.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 986.0, + "frame_start": 962.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1101.0, + "frame_start": 987.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1162.0, + "frame_start": 1102.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1235.0, + "frame_start": 1163.0, + "merge": true, + "offscreen": false, + "speaker": "daxter" + }, + { + "frame_end": 1317.0, + "frame_start": 1241.0, + "merge": true, + "offscreen": false, + "speaker": "damas" + }, + { + "frame_end": 1388.0, + "frame_start": 1318.0, + "merge": true, + "offscreen": false, + "speaker": "damas" + }, + { + "frame_end": 1494.0, + "frame_start": 1398.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1542.0, + "frame_start": 1498.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1657.0, + "frame_start": 1543.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1684.0, + "frame_start": 1658.0, + "merge": true, + "offscreen": false, + "speaker": "daxter" + }, + { + "frame_end": 1745.0, + "frame_start": 1685.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + } + ] + }, + "arena-fight-3-intro": { + "lines": [ + { + "frame_end": 211.0, + "frame_start": 142.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 439.0, + "frame_start": 212.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 488.0, + "frame_start": 440.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 555.0, + "frame_start": 493.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 630.0, + "frame_start": 556.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 646.0, + "frame_start": 631.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 661.0, + "frame_start": 647.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 751.0, + "frame_start": 662.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 802.0, + "frame_start": 752.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 935.0, + "frame_start": 803.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "tower-destroy-res": { + "lines": [ + { + "frame_end": 127.0, + "frame_start": 32.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 222.0, + "frame_start": 128.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 292.0, + "frame_start": 223.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 344.0, + "frame_start": 297.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 444.0, + "frame_start": 345.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 473.0, + "frame_start": 450.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 553.0, + "frame_start": 474.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 682.0, + "frame_start": 554.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 760.0, + "frame_start": 683.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 797.0, + "frame_start": 787.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 947.0, + "frame_start": 798.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 974.0, + "frame_start": 948.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1088.0, + "frame_start": 1054.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-outro": { + "lines": [ + { + "frame_end": 254.0, + "frame_start": 178.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 376.0, + "frame_start": 255.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 489.0, + "frame_start": 377.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 660.0, + "frame_start": 499.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 777.0, + "frame_start": 671.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 879.0, + "frame_start": 788.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 980.0, + "frame_start": 880.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1064.0, + "frame_start": 981.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1172.0, + "frame_start": 1069.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1245.0, + "frame_start": 1173.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1299.0, + "frame_start": 1246.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1386.0, + "frame_start": 1303.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1528.0, + "frame_start": 1391.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1588.0, + "frame_start": 1533.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1673.0, + "frame_start": 1589.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1785.0, + "frame_start": 1684.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1881.0, + "frame_start": 1805.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1923.0, + "frame_start": 1893.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2023.0, + "frame_start": 1934.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2117.0, + "frame_start": 2024.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2179.0, + "frame_start": 2118.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2271.0, + "frame_start": 2180.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2382.0, + "frame_start": 2281.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2475.0, + "frame_start": 2387.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2547.0, + "frame_start": 2476.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2719.0, + "frame_start": 2594.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2916.0, + "frame_start": 2785.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2977.0, + "frame_start": 2919.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3137.0, + "frame_start": 3081.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3245.0, + "frame_start": 3138.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3364.0, + "frame_start": 3277.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3454.0, + "frame_start": 3388.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3598.0, + "frame_start": 3461.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3674.0, + "frame_start": 3631.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3819.0, + "frame_start": 3696.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3888.0, + "frame_start": 3827.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4019.0, + "frame_start": 3889.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4158.0, + "frame_start": 4020.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4283.0, + "frame_start": 4194.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4310.0, + "frame_start": 4293.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4367.0, + "frame_start": 4319.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4906.0, + "frame_start": 4860.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5015.0, + "frame_start": 4907.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5100.0, + "frame_start": 5017.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5192.0, + "frame_start": 5106.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5297.0, + "frame_start": 5193.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5367.0, + "frame_start": 5298.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-blow-barricade-intro": { + "lines": [ + { + "frame_end": 147.0, + "frame_start": 36.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 248.0, + "frame_start": 154.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 312.0, + "frame_start": 249.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 392.0, + "frame_start": 313.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 436.0, + "frame_start": 393.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 517.0, + "frame_start": 438.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 593.0, + "frame_start": 518.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 673.0, + "frame_start": 594.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 816.0, + "frame_start": 678.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 930.0, + "frame_start": 817.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1004.0, + "frame_start": 931.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1068.0, + "frame_start": 1005.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-chase-intro": { + "lines": [ + { + "frame_end": 97.0, + "frame_start": 21.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 189.0, + "frame_start": 98.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 231.0, + "frame_start": 199.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 299.0, + "frame_start": 233.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 404.0, + "frame_start": 302.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 465.0, + "frame_start": 405.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 535.0, + "frame_start": 466.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 568.0, + "frame_start": 540.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 648.0, + "frame_start": 570.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 782.0, + "frame_start": 649.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 877.0, + "frame_start": 783.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 956.0, + "frame_start": 878.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1036.0, + "frame_start": 957.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1097.0, + "frame_start": 1037.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1177.0, + "frame_start": 1098.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1281.0, + "frame_start": 1178.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1320.0, + "frame_start": 1284.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1361.0, + "frame_start": 1327.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1448.0, + "frame_start": 1362.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "mine-boss-intro": { + "lines": [ + { + "frame_end": 362.0, + "frame_start": 259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 409.0, + "frame_start": 363.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 547.0, + "frame_start": 410.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 626.0, + "frame_start": 548.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 798.0, + "frame_start": 627.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 927.0, + "frame_start": 799.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 993.0, + "frame_start": 936.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1051.0, + "frame_start": 994.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1157.0, + "frame_start": 1059.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1217.0, + "frame_start": 1158.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1279.0, + "frame_start": 1218.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1370.0, + "frame_start": 1280.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1542.0, + "frame_start": 1380.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1608.0, + "frame_start": 1543.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1657.0, + "frame_start": 1613.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1707.0, + "frame_start": 1660.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1785.0, + "frame_start": 1708.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1882.0, + "frame_start": 1786.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1964.0, + "frame_start": 1883.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2048.0, + "frame_start": 1965.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2166.0, + "frame_start": 2049.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2233.0, + "frame_start": 2169.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2256.0, + "frame_start": 2234.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2294.0, + "frame_start": 2259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2397.0, + "frame_start": 2295.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2423.0, + "frame_start": 2398.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2530.0, + "frame_start": 2424.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2594.0, + "frame_start": 2531.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2693.0, + "frame_start": 2595.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2716.0, + "frame_start": 2694.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2810.0, + "frame_start": 2717.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2971.0, + "frame_start": 2811.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3175.0, + "frame_start": 3060.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-blow-barricade-res": { + "lines": [ + { + "frame_end": 86.0, + "frame_start": 56.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 157.0, + "frame_start": 87.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 241.0, + "frame_start": 158.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 287.0, + "frame_start": 242.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 344.0, + "frame_start": 288.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-get-to-catacombs-intro": { + "lines": [ + { + "frame_end": 76.0, + "frame_start": 15.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 168.0, + "frame_start": 85.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 259.0, + "frame_start": 169.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 346.0, + "frame_start": 260.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 503.0, + "frame_start": 347.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 638.0, + "frame_start": 509.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 752.0, + "frame_start": 644.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 840.0, + "frame_start": 765.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 964.0, + "frame_start": 850.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1056.0, + "frame_start": 965.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1171.0, + "frame_start": 1057.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1217.0, + "frame_start": 1172.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1370.0, + "frame_start": 1223.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1457.0, + "frame_start": 1380.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1529.0, + "frame_start": 1458.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1630.0, + "frame_start": 1530.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1727.0, + "frame_start": 1631.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-glide-res": { + "lines": [ + { + "frame_end": 301.0, + "frame_start": 231.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 336.0, + "frame_start": 308.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 382.0, + "frame_start": 339.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 440.0, + "frame_start": 413.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-palace": { + "lines": [ + { + "frame_end": 101.0, + "frame_start": 79.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 118.0, + "frame_start": 107.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 188.0, + "frame_start": 119.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 271.0, + "frame_start": 189.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 373.0, + "frame_start": 272.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 425.0, + "frame_start": 374.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 496.0, + "frame_start": 434.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 578.0, + "frame_start": 497.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 665.0, + "frame_start": 579.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 709.0, + "frame_start": 673.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 767.0, + "frame_start": 716.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 851.0, + "frame_start": 768.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 940.0, + "frame_start": 852.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1308.0, + "frame_start": 1255.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1473.0, + "frame_start": 1444.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1499.0, + "frame_start": 1481.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1945.0, + "frame_start": 1890.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-sniper-fight-intro": { + "lines": [ + { + "frame_end": 115.0, + "frame_start": 37.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 216.0, + "frame_start": 116.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 321.0, + "frame_start": 217.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 447.0, + "frame_start": 322.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 496.0, + "frame_start": 448.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 592.0, + "frame_start": 502.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-port-attack-res": { + "lines": [ + { + "frame_end": 79.0, + "frame_start": 9.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-drop": { + "lines": [ + { + "frame_end": 997.0, + "frame_start": 908.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1098.0, + "frame_start": 998.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1240.0, + "frame_start": 1099.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1336.0, + "frame_start": 1245.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1402.0, + "frame_start": 1337.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1480.0, + "frame_start": 1403.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1519.0, + "frame_start": 1481.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1569.0, + "frame_start": 1523.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1629.0, + "frame_start": 1570.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1677.0, + "frame_start": 1630.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1809.0, + "frame_start": 1678.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1858.0, + "frame_start": 1811.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1930.0, + "frame_start": 1865.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1994.0, + "frame_start": 1936.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2035.0, + "frame_start": 1995.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2133.0, + "frame_start": 2036.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2156.0, + "frame_start": 2134.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2203.0, + "frame_start": 2158.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2308.0, + "frame_start": 2204.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2323.0, + "frame_start": 2309.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2385.0, + "frame_start": 2326.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2480.0, + "frame_start": 2386.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2588.0, + "frame_start": 2500.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2800.0, + "frame_start": 2774.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2836.0, + "frame_start": 2801.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2933.0, + "frame_start": 2836.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3054.0, + "frame_start": 2934.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3123.0, + "frame_start": 3056.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3224.0, + "frame_start": 3124.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3253.0, + "frame_start": 3225.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3350.0, + "frame_start": 3254.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3399.0, + "frame_start": 3351.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3454.0, + "frame_start": 3401.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "palace-ruins-patrol-intro": { + "lines": [ + { + "frame_end": 80.0, + "frame_start": 22.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 157.0, + "frame_start": 81.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 230.0, + "frame_start": 199.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 384.0, + "frame_start": 323.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 465.0, + "frame_start": 385.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-artifact-race-1-intro": { + "lines": [ + { + "frame_end": 94.0, + "frame_start": 62.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 179.0, + "frame_start": 95.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 212.0, + "frame_start": 183.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 278.0, + "frame_start": 217.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 334.0, + "frame_start": 279.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 365.0, + "frame_start": 337.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 459.0, + "frame_start": 368.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 604.0, + "frame_start": 460.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 752.0, + "frame_start": 609.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 802.0, + "frame_start": 753.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 861.0, + "frame_start": 803.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 952.0, + "frame_start": 862.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1021.0, + "frame_start": 955.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-lizard-catch-2": { + "lines": [ + { + "frame_end": 121.0, + "frame_start": 79.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "sewer-met-hum-intro": { + "lines": [ + { + "frame_end": 124.0, + "frame_start": 44.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 191.0, + "frame_start": 137.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 218.0, + "frame_start": 195.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 236.0, + "frame_start": 219.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 390.0, + "frame_start": 246.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 506.0, + "frame_start": 394.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 605.0, + "frame_start": 513.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 748.0, + "frame_start": 606.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 861.0, + "frame_start": 749.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 917.0, + "frame_start": 862.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1022.0, + "frame_start": 930.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1097.0, + "frame_start": 1028.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1155.0, + "frame_start": 1105.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1274.0, + "frame_start": 1156.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1383.0, + "frame_start": 1281.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1504.0, + "frame_start": 1384.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1639.0, + "frame_start": 1505.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1791.0, + "frame_start": 1640.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1853.0, + "frame_start": 1792.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1909.0, + "frame_start": 1869.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-hijack-vehicle-res": { + "lines": [ + { + "frame_end": 29.0, + "frame_start": 6.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 96.0, + "frame_start": 37.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 132.0, + "frame_start": 110.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 166.0, + "frame_start": 135.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 331.0, + "frame_start": 307.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 372.0, + "frame_start": 332.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-lizard-catch-3": { + "lines": [ + { + "frame_end": 128.0, + "frame_start": 75.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 379.0, + "frame_start": 295.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 466.0, + "frame_start": 380.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 502.0, + "frame_start": 474.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 580.0, + "frame_start": 503.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 620.0, + "frame_start": 584.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 661.0, + "frame_start": 627.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-training": { + "lines": [ + { + "frame_end": 333.0, + "frame_start": 162.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 408.0, + "frame_start": 334.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 483.0, + "frame_start": 409.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 581.0, + "frame_start": 484.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 728.0, + "frame_start": 584.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 821.0, + "frame_start": 735.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 963.0, + "frame_start": 822.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1021.0, + "frame_start": 964.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1092.0, + "frame_start": 1022.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1204.0, + "frame_start": 1093.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1279.0, + "frame_start": 1207.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1363.0, + "frame_start": 1280.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1477.0, + "frame_start": 1364.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1614.0, + "frame_start": 1478.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1697.0, + "frame_start": 1616.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1902.0, + "frame_start": 1699.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1981.0, + "frame_start": 1903.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2070.0, + "frame_start": 1982.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2201.0, + "frame_start": 2071.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2256.0, + "frame_start": 2202.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2360.0, + "frame_start": 2258.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2438.0, + "frame_start": 2362.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2492.0, + "frame_start": 2450.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-ffhq": { + "lines": [ + { + "frame_end": 74.0, + "frame_start": 27.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 146.0, + "frame_start": 75.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 218.0, + "frame_start": 147.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 273.0, + "frame_start": 219.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 333.0, + "frame_start": 274.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 400.0, + "frame_start": 334.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 468.0, + "frame_start": 403.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 541.0, + "frame_start": 469.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 629.0, + "frame_start": 542.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 673.0, + "frame_start": 630.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 768.0, + "frame_start": 675.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 858.0, + "frame_start": 769.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 917.0, + "frame_start": 862.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-artifact-race-1-res": { + "lines": [ + { + "frame_end": 133.0, + "frame_start": 56.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 223.0, + "frame_start": 138.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 305.0, + "frame_start": 225.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 418.0, + "frame_start": 306.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 525.0, + "frame_start": 419.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 592.0, + "frame_start": 526.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 696.0, + "frame_start": 593.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 802.0, + "frame_start": 697.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-artifact-race-2-intro": { + "lines": [ + { + "frame_end": 133.0, + "frame_start": 69.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 198.0, + "frame_start": 134.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 247.0, + "frame_start": 199.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 317.0, + "frame_start": 254.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 337.0, + "frame_start": 325.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 412.0, + "frame_start": 338.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 441.0, + "frame_start": 413.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 554.0, + "frame_start": 442.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 583.0, + "frame_start": 555.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-oasis-defense-res": { + "lines": [ + { + "frame_end": 140.0, + "frame_start": 73.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 237.0, + "frame_start": 141.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 318.0, + "frame_start": 238.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 385.0, + "frame_start": 331.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 449.0, + "frame_start": 391.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 528.0, + "frame_start": 454.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 617.0, + "frame_start": 529.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 652.0, + "frame_start": 618.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 747.0, + "frame_start": 666.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 804.0, + "frame_start": 756.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 859.0, + "frame_start": 805.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 896.0, + "frame_start": 870.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 957.0, + "frame_start": 917.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1031.0, + "frame_start": 958.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1072.0, + "frame_start": 1032.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1151.0, + "frame_start": 1073.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1214.0, + "frame_start": 1152.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1240.0, + "frame_start": 1215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1282.0, + "frame_start": 1264.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-beast-battle-intro": { + "lines": [ + { + "frame_end": 158.0, + "frame_start": 44.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 195.0, + "frame_start": 159.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 234.0, + "frame_start": 201.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 399.0, + "frame_start": 239.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 521.0, + "frame_start": 400.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 594.0, + "frame_start": 522.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 646.0, + "frame_start": 595.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 766.0, + "frame_start": 647.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 825.0, + "frame_start": 767.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 898.0, + "frame_start": 826.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 969.0, + "frame_start": 912.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1060.0, + "frame_start": 975.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-catch-lizards-intro": { + "lines": [ + { + "frame_end": 212.0, + "frame_start": 60.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 302.0, + "frame_start": 220.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 423.0, + "frame_start": 310.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 466.0, + "frame_start": 426.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 506.0, + "frame_start": 468.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 638.0, + "frame_start": 507.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 749.0, + "frame_start": 670.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 850.0, + "frame_start": 750.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 892.0, + "frame_start": 860.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1065.0, + "frame_start": 929.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1152.0, + "frame_start": 1067.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1235.0, + "frame_start": 1153.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1274.0, + "frame_start": 1236.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1391.0, + "frame_start": 1302.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1477.0, + "frame_start": 1392.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1553.0, + "frame_start": 1478.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1627.0, + "frame_start": 1554.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1697.0, + "frame_start": 1637.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1873.0, + "frame_start": 1763.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-tired": { + "lines": [ + { + "frame_end": 239.0, + "frame_start": 215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 284.0, + "frame_start": 252.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 369.0, + "frame_start": 337.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 435.0, + "frame_start": 388.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 558.0, + "frame_start": 453.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 660.0, + "frame_start": 621.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-pre-game-intro": { + "lines": [ + { + "frame_end": 146.0, + "frame_start": 49.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 209.0, + "frame_start": 147.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 256.0, + "frame_start": 210.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 329.0, + "frame_start": 259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 427.0, + "frame_start": 331.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 492.0, + "frame_start": 429.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 556.0, + "frame_start": 493.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 604.0, + "frame_start": 560.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 747.0, + "frame_start": 610.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 825.0, + "frame_start": 751.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 893.0, + "frame_start": 830.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 951.0, + "frame_start": 894.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1071.0, + "frame_start": 952.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1135.0, + "frame_start": 1072.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1222.0, + "frame_start": 1136.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1306.0, + "frame_start": 1230.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1336.0, + "frame_start": 1307.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1395.0, + "frame_start": 1338.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1519.0, + "frame_start": 1396.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1635.0, + "frame_start": 1520.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1693.0, + "frame_start": 1638.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1727.0, + "frame_start": 1694.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1830.0, + "frame_start": 1807.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-final-boss-intro": { + "lines": [ + { + "frame_end": 143.0, + "frame_start": 90.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 221.0, + "frame_start": 196.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 329.0, + "frame_start": 262.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 766.0, + "frame_start": 723.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 799.0, + "frame_start": 770.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 867.0, + "frame_start": 800.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 960.0, + "frame_start": 879.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1014.0, + "frame_start": 961.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1054.0, + "frame_start": 1028.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-hover-intro": { + "lines": [ + { + "frame_end": 114.0, + "frame_start": 56.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 244.0, + "frame_start": 115.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 374.0, + "frame_start": 245.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 433.0, + "frame_start": 375.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 514.0, + "frame_start": 434.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 626.0, + "frame_start": 515.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 729.0, + "frame_start": 629.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 826.0, + "frame_start": 730.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 884.0, + "frame_start": 827.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 953.0, + "frame_start": 887.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1042.0, + "frame_start": 958.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1102.0, + "frame_start": 1043.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1251.0, + "frame_start": 1108.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-hover-res": { + "lines": [ + { + "frame_end": 295.0, + "frame_start": 262.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 325.0, + "frame_start": 296.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 399.0, + "frame_start": 326.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 464.0, + "frame_start": 401.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 574.0, + "frame_start": 465.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 618.0, + "frame_start": 575.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 656.0, + "frame_start": 620.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 744.0, + "frame_start": 658.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 786.0, + "frame_start": 745.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 867.0, + "frame_start": 799.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 916.0, + "frame_start": 868.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 966.0, + "frame_start": 917.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1031.0, + "frame_start": 973.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1086.0, + "frame_start": 1032.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1136.0, + "frame_start": 1087.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-jump-mission-intro": { + "lines": [ + { + "frame_end": 243.0, + "frame_start": 89.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 308.0, + "frame_start": 260.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 383.0, + "frame_start": 318.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 474.0, + "frame_start": 384.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 586.0, + "frame_start": 475.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 686.0, + "frame_start": 587.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 793.0, + "frame_start": 687.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 830.0, + "frame_start": 808.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 901.0, + "frame_start": 837.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1023.0, + "frame_start": 902.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1125.0, + "frame_start": 1024.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1160.0, + "frame_start": 1126.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1251.0, + "frame_start": 1161.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1315.0, + "frame_start": 1252.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1421.0, + "frame_start": 1316.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1457.0, + "frame_start": 1430.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1622.0, + "frame_start": 1465.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1680.0, + "frame_start": 1623.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1772.0, + "frame_start": 1681.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1906.0, + "frame_start": 1773.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1994.0, + "frame_start": 1907.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-oasis-defense-res-b": { + "lines": [ + { + "frame_end": 75.0, + "frame_start": 30.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 214.0, + "frame_start": 95.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 332.0, + "frame_start": 223.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 362.0, + "frame_start": 336.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 465.0, + "frame_start": 363.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 598.0, + "frame_start": 477.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 672.0, + "frame_start": 623.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 797.0, + "frame_start": 743.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "nest-hunt-res": { + "lines": [ + { + "frame_end": 142.0, + "frame_start": 31.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 274.0, + "frame_start": 143.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 347.0, + "frame_start": 285.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 387.0, + "frame_start": 354.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 467.0, + "frame_start": 396.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 551.0, + "frame_start": 479.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 590.0, + "frame_start": 552.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 628.0, + "frame_start": 591.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 703.0, + "frame_start": 629.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 765.0, + "frame_start": 704.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 857.0, + "frame_start": 766.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 912.0, + "frame_start": 862.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 977.0, + "frame_start": 917.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1042.0, + "frame_start": 978.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1148.0, + "frame_start": 1043.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1181.0, + "frame_start": 1149.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1296.0, + "frame_start": 1194.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1412.0, + "frame_start": 1345.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1454.0, + "frame_start": 1424.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1526.0, + "frame_start": 1459.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1568.0, + "frame_start": 1527.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-rescue-intro": { + "lines": [ + { + "frame_end": 83.0, + "frame_start": 17.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 194.0, + "frame_start": 84.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 288.0, + "frame_start": 207.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 337.0, + "frame_start": 289.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 404.0, + "frame_start": 338.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 478.0, + "frame_start": 405.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "factory-sky-battle-intro": { + "lines": [ + { + "frame_end": 81.0, + "frame_start": 30.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 146.0, + "frame_start": 82.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 229.0, + "frame_start": 147.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 329.0, + "frame_start": 230.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 405.0, + "frame_start": 330.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 530.0, + "frame_start": 410.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 588.0, + "frame_start": 538.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 650.0, + "frame_start": 589.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 708.0, + "frame_start": 651.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 776.0, + "frame_start": 709.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 878.0, + "frame_start": 778.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 942.0, + "frame_start": 881.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-gun-course-intro": { + "lines": [ + { + "frame_end": 107.0, + "frame_start": 73.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 136.0, + "frame_start": 109.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 272.0, + "frame_start": 137.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 323.0, + "frame_start": 273.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 379.0, + "frame_start": 326.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 408.0, + "frame_start": 381.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 489.0, + "frame_start": 409.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 518.0, + "frame_start": 490.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 586.0, + "frame_start": 521.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 694.0, + "frame_start": 587.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 830.0, + "frame_start": 695.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 977.0, + "frame_start": 831.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1036.0, + "frame_start": 997.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1096.0, + "frame_start": 1057.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1269.0, + "frame_start": 1097.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "forest-turn-on-machine-res": { + "lines": [ + { + "frame_end": 297.0, + "frame_start": 187.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 434.0, + "frame_start": 366.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 521.0, + "frame_start": 436.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 612.0, + "frame_start": 527.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 653.0, + "frame_start": 613.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 681.0, + "frame_start": 663.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 719.0, + "frame_start": 702.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-course-race-intro": { + "lines": [ + { + "frame_end": 83.0, + "frame_start": 12.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 157.0, + "frame_start": 84.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 243.0, + "frame_start": 158.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 338.0, + "frame_start": 244.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 394.0, + "frame_start": 339.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 432.0, + "frame_start": 406.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 471.0, + "frame_start": 438.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 615.0, + "frame_start": 472.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 674.0, + "frame_start": 616.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 718.0, + "frame_start": 680.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 816.0, + "frame_start": 724.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 867.0, + "frame_start": 817.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 922.0, + "frame_start": 868.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 971.0, + "frame_start": 923.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1015.0, + "frame_start": 978.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1071.0, + "frame_start": 1025.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1155.0, + "frame_start": 1078.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1281.0, + "frame_start": 1160.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1320.0, + "frame_start": 1282.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1359.0, + "frame_start": 1327.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1457.0, + "frame_start": 1366.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1547.0, + "frame_start": 1458.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1599.0, + "frame_start": 1548.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1659.0, + "frame_start": 1604.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1674.0, + "frame_start": 1660.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1748.0, + "frame_start": 1707.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1818.0, + "frame_start": 1749.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-lost": { + "lines": [ + { + "frame_end": 207.0, + "frame_start": 107.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 271.0, + "frame_start": 208.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 357.0, + "frame_start": 272.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 478.0, + "frame_start": 358.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 611.0, + "frame_start": 479.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + } + }, + "other": { + "dax128": { + "lines": [ + { + "frame_start": 0, + "frame_end": 41, + "merge": false, + "offscreen": true, + "speaker": "daxter" + } + ] + } + } } diff --git a/game/assets/jak3/subtitle/subtitle_meta_nl-NL.json b/game/assets/jak3/subtitle/subtitle_meta_nl-NL.json new file mode 100644 index 00000000000..495996ba8e7 --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_meta_nl-NL.json @@ -0,0 +1,4 @@ +{ + "cutscenes": {}, + "other": {} +} diff --git a/game/assets/jak3/subtitle/subtitle_meta_pt-PT.json b/game/assets/jak3/subtitle/subtitle_meta_pt-PT.json new file mode 100644 index 00000000000..495996ba8e7 --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_meta_pt-PT.json @@ -0,0 +1,4 @@ +{ + "cutscenes": {}, + "other": {} +} diff --git a/game/assets/jak3/subtitle/subtitle_meta_ru-RU.json b/game/assets/jak3/subtitle/subtitle_meta_ru-RU.json new file mode 100644 index 00000000000..495996ba8e7 --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_meta_ru-RU.json @@ -0,0 +1,4 @@ +{ + "cutscenes": {}, + "other": {} +} diff --git a/game/kernel/jak3/kmachine.cpp b/game/kernel/jak3/kmachine.cpp index 836168c6b36..c48000a6369 100644 --- a/game/kernel/jak3/kmachine.cpp +++ b/game/kernel/jak3/kmachine.cpp @@ -375,7 +375,7 @@ void InitMachine_PCPort() { make_function_symbol_from_c("pc-discord-rpc-update", (void*)kmachine_extras::update_discord_rpc); // debugging tools - // make_function_symbol_from_c("alloc-vagdir-names", (void*)alloc_vagdir_names); + make_function_symbol_from_c("alloc-vagdir-names", (void*)kmachine_extras::alloc_vagdir_names); // external RPCs /* diff --git a/game/kernel/jak3/kmachine_extras.cpp b/game/kernel/jak3/kmachine_extras.cpp index 626be6a067e..4ac0f6bb3e0 100644 --- a/game/kernel/jak3/kmachine_extras.cpp +++ b/game/kernel/jak3/kmachine_extras.cpp @@ -12,9 +12,11 @@ #include "game/kernel/common/Symbol4.h" #include "game/kernel/common/kmachine.h" #include "game/kernel/common/kscheme.h" +#include "game/overlord/jak3/iso_cd.h" namespace jak3 { namespace kmachine_extras { +using namespace jak3; void update_discord_rpc(u32 discord_info) { if (gDiscordRpcEnabled) { @@ -175,6 +177,46 @@ void pc_set_active_levels(u32 lev_list) { Gfx::GetCurrentRenderer()->set_active_levels(levels); } +static std::string unpack_vag_name_jak3(u64 compressed) { + const char* char_map = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-"; + u32 chars = compressed & 0x1fffff; + std::array buf{}; + buf.fill(0); + for (int i = 0; i < 8; i++) { + if (i == 4) { + chars = (compressed >> 21) & 0x1fffff; + } + buf[7 - i] = char_map[chars % 38]; + chars /= 38; + } + + return {buf.data()}; +} + +u32 alloc_vagdir_names(u32 heap_sym) { + auto alloced_heap = (Ptr)alloc_heap_memory(heap_sym, g_VagDir.num_entries * 8 + 8); + if (alloced_heap.offset) { + *alloced_heap = g_VagDir.num_entries; + // use entry -1 to get the amount + alloced_heap = alloced_heap + 8; + for (size_t i = 0; i < g_VagDir.num_entries; ++i) { + char vagname_temp[9]; + u64 packed = *(u64*)g_VagDir.entries[i].words; + auto name = unpack_vag_name_jak3(packed).data(); + memcpy(vagname_temp, name, 8); + for (int j = 0; j < 8; ++j) { + vagname_temp[j] = tolower(vagname_temp[j]); + } + vagname_temp[8] = 0; + u64 vagname_val; + memcpy(&vagname_val, vagname_temp, 8); + *(alloced_heap + i * 8) = vagname_val; + } + return alloced_heap.offset; + } + return s7.offset; +} + inline u64 bool_to_symbol(const bool val) { return val ? static_cast(s7.offset) + true_symbol_offset(g_game_version) : s7.offset; } diff --git a/game/kernel/jak3/kscheme.h b/game/kernel/jak3/kscheme.h index ef76389c4da..776a5985555 100644 --- a/game/kernel/jak3/kscheme.h +++ b/game/kernel/jak3/kscheme.h @@ -60,6 +60,7 @@ Ptr intern_type_from_c(int a, int b, const char* name, u64 methods); u64 alloc_heap_object(u32 heap, u32 type, u32 size, u32 pp); int InitHeapAndSymbol(); u64 call_method_of_type_arg2(u32 arg, Ptr type, u32 method_id, u32 a1, u32 a2); +u64 alloc_heap_memory(u32 heap, u32 size); template Ptr> sym_to_string_ptr(Ptr> in) { return Ptr>(SymbolString.offset + in.offset - s7.offset); diff --git a/game/tools/subtitle_editor/subtitle_editor.cpp b/game/tools/subtitle_editor/subtitle_editor.cpp index 687bebdb4b4..dfa27c108af 100644 --- a/game/tools/subtitle_editor/subtitle_editor.cpp +++ b/game/tools/subtitle_editor/subtitle_editor.cpp @@ -402,6 +402,10 @@ void SubtitleEditor::draw_subtitle_options(GameSubtitleSceneInfo& scene, bool cu } else { bool play = false; bool save_and_reload_text = false; + if (ImGui::Button("Save")) { + save_and_reload_text = true; + } + ImGui::SameLine(); if (ImGui::Button("Play")) { play = true; } diff --git a/goal_src/jak2/engine/load/loader.gc b/goal_src/jak2/engine/load/loader.gc index e28b79a03ce..c1d7ed8fcc8 100644 --- a/goal_src/jak2/engine/load/loader.gc +++ b/goal_src/jak2/engine/load/loader.gc @@ -2299,7 +2299,7 @@ ) (set! (-> gp-0 cmd 69) '((65 . wait) (71 . wait) (67 . wait) (66 . wait))) (set! (-> gp-0 cmd 70) '((65 . wait) (90 . hide) (91 . hide) (81 . hide) (80 . hide))) - ;; added this one + ;; og:preserve-this added this one (set! (-> gp-0 cmd (gui-channel subtitle-pc)) '(((the binteger (gui-channel blackout)) . wait) )) (set! (-> gp-0 cmd 80) '((64 . wait) (65 . wait) (80 . wait) (70 . wait))) diff --git a/goal_src/jak3/dgos/game.gd b/goal_src/jak3/dgos/game.gd index 5807ef53de6..8bf4ebf8667 100644 --- a/goal_src/jak3/dgos/game.gd +++ b/goal_src/jak3/dgos/game.gd @@ -352,6 +352,8 @@ "capture-pc.o" ;; added "pckernel-common.o" ;; added "pckernel.o" ;; added + "subtitle3-h.o" ;; added + "subtitle3.o" ;; added "main.o" "collide-cache.o" "collide-debug.o" @@ -410,6 +412,7 @@ "visvol-edit.o" "collision-editor.o" "speech-manager.o" + "vag-player.o" ;; added "default-menu-pc.o" ;; added "dir-tpages.go" "tpage-1.go" diff --git a/goal_src/jak3/engine/debug/default-menu.gc b/goal_src/jak3/engine/debug/default-menu.gc index d06e68024a4..cfc95a87e0a 100644 --- a/goal_src/jak3/engine/debug/default-menu.gc +++ b/goal_src/jak3/engine/debug/default-menu.gc @@ -3679,6 +3679,8 @@ (flag "german" 2 dm-setting-subtitle-language) (flag "spanish" 3 dm-setting-subtitle-language) (flag "italian" 4 dm-setting-subtitle-language) + ;; og:preserve-this added + (flag "commentary" 5 dm-setting-subtitle-language) (flag "korean" 7 dm-setting-subtitle-language) (flag "russian" 8 dm-setting-subtitle-language) (flag "portuguese" 9 dm-setting-subtitle-language) diff --git a/goal_src/jak3/engine/gfx/font-h.gc b/goal_src/jak3/engine/gfx/font-h.gc index b014473dfeb..ce1ceb12d07 100644 --- a/goal_src/jak3/engine/gfx/font-h.gc +++ b/goal_src/jak3/engine/gfx/font-h.gc @@ -725,10 +725,10 @@ (none) ) -(defun set-font-color ((arg0 font-color) (arg1 int) (arg2 rgba) (arg3 rgba) (arg4 rgba)) - (set! (-> *font-work* color-table arg0 color 0) (the-as rgba arg1)) - (set! (-> *font-work* color-table arg0 color 1) arg2) - (set! (-> *font-work* color-table arg0 color 2) arg3) - (set! (-> *font-work* color-table arg0 color 3) arg4) +(defun set-font-color ((idx font-color) (clr0 rgba) (clr1 rgba) (clr2 rgba) (clr3 rgba)) + (set! (-> *font-work* color-table idx color 0) clr0) + (set! (-> *font-work* color-table idx color 1) clr1) + (set! (-> *font-work* color-table idx color 2) clr2) + (set! (-> *font-work* color-table idx color 3) clr3) 0 ) diff --git a/goal_src/jak3/engine/load/loader.gc b/goal_src/jak3/engine/load/loader.gc index 99d645d5e60..b9cdb672c70 100644 --- a/goal_src/jak3/engine/load/loader.gc +++ b/goal_src/jak3/engine/load/loader.gc @@ -2212,6 +2212,10 @@ ) ) +;; og:preserve-this added for debugging +(#when PC_PORT +(define *gui-kick-str* #f)) + (defmethod update-connection ((this gui-control) (arg0 gui-connection) (arg1 process) (arg2 symbol)) (local-vars (v1-75 symbol)) (when (and (>= (the-as uint (-> arg0 channel)) (the-as uint 16)) @@ -2253,7 +2257,9 @@ ((= s3-0 (gui-status ready)) (case (shr (the-as int (-> arg0 channel)) 4) ((1 2) - (if (not (paused?)) + ;; og:preserve-this added condition + (if (#if PC_PORT (or *gui-kick-str* (not (paused?))) + (not (paused?))) (str-play-async (-> arg0 name) (-> arg0 id) @@ -2723,6 +2729,8 @@ (set! (-> gp-0 cmd 35) '((64 . wait) (21 . wait) (22 . wait) (23 . wait) (25 . wait) (19 . wait) (28 . wait) (35 . wait)) ) + ;; og:preserve-this added + (set! (-> gp-0 cmd (gui-channel subtitle-pc)) '(((the binteger (gui-channel blackout)) . wait))) (set! (-> gp-0 group 18) (sound-group)) (set! (-> gp-0 group 27) (sound-group)) (set! (-> gp-0 group 31) (sound-group)) diff --git a/goal_src/jak3/engine/scene/scene.gc b/goal_src/jak3/engine/scene/scene.gc index cb4a0540a37..76ea9453e75 100644 --- a/goal_src/jak3/engine/scene/scene.gc +++ b/goal_src/jak3/engine/scene/scene.gc @@ -817,6 +817,10 @@ ) (let ((v1-9 (-> self skel root-channel 0 frame-group))) (when v1-9 + ;; og:preserve-this send a movie-no-subtitle message so the pc subtitle system at least knows there's a movie playing + (#when PC_PORT + (if (= (-> self type) scene-player) + (send-event (ppointer->process *subtitle3*) 'movie-no-subtitle (-> (the scene-player self) anim name) #f (ja-aframe-num 0)))) (let ((gp-0 (res-lump-struct (-> v1-9 extra) 'subtitle-range (array subtitle-range)))) (when gp-0 (let ((f30-0 (ja-aframe-num 0)) @@ -865,7 +869,14 @@ (+! (-> s2-0 origin y) 1.0) (set! (-> s2-0 color) (font-color default)) (set! (-> s2-0 flags) (font-flags shadow kerning middle middle-vert large)) - (print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id hud-draw-pris2)) + ;; og:preserve-this subtitle3 + (#if PC_PORT + (if (or (!= (-> self type) scene-player) + (not (send-event (ppointer->process *subtitle3*) 'movie (-> (the scene-player self) anim name) s3-0 f30-0))) + (print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id hud-draw-pris2))) + + (print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id hud-draw-pris2))) + ; (print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id hud-draw-pris2)) (gui-control-method-12 *gui-control* self diff --git a/goal_src/jak3/engine/ui/progress/progress-draw.gc b/goal_src/jak3/engine/ui/progress/progress-draw.gc index 79ad73f0c30..f8bd50930e8 100644 --- a/goal_src/jak3/engine/ui/progress/progress-draw.gc +++ b/goal_src/jak3/engine/ui/progress/progress-draw.gc @@ -154,14 +154,14 @@ (if (< (seconds 0.027) (logand (-> pp clock integral-frame-counter) 15)) (set-font-color (the-as font-color gp-0) - (the-as int (the-as uint #x80ffffff)) + (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) ) (set-font-color (the-as font-color gp-0) - (the-as int (the-as uint #x80606060)) + (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) diff --git a/goal_src/jak3/game.gp b/goal_src/jak3/game.gp index a5bf480cbf3..23407ab7cf4 100644 --- a/goal_src/jak3/game.gp +++ b/goal_src/jak3/game.gp @@ -513,7 +513,7 @@ (defstep :in "game/assets/jak3/game_subtitle.gp" :tool 'subtitle-v2 - :out '("$OUT/iso/0SUBTI2.TXT") + :out '("$OUT/iso/0SUBTI3.TXT") ) ;;;;;;;;;;;;;;;;;;;;; @@ -530,7 +530,7 @@ "$OUT/iso/5COMMON.TXT" "$OUT/iso/6COMMON.TXT" "$OUT/iso/7COMMON.TXT" - "$OUT/iso/0SUBTI2.TXT" + "$OUT/iso/0SUBTI3.TXT" "$OUT/iso/VAGDIR.AYB" "$OUT/iso/TWEAKVAL.MUS" ,@(reverse *all-vis*) diff --git a/goal_src/jak3/kernel/gkernel.gc b/goal_src/jak3/kernel/gkernel.gc index 9b0b23985d0..54ddcbf62ca 100644 --- a/goal_src/jak3/kernel/gkernel.gc +++ b/goal_src/jak3/kernel/gkernel.gc @@ -2370,6 +2370,11 @@ (change-parent (define *display-pool* (new 'global 'process-tree "display-pool")) *active-pool*) +;; og:preserve-this added pc pool +(#when PC_PORT +(change-parent (define *pc-pool* (new 'global 'process-tree "pc-pool")) *active-pool*) +(set! (-> *pc-pool* mask) (process-mask freeze pause menu progress process-tree))) + (change-parent (define *camera-pool* (new 'global 'process-tree "camera-pool")) *active-pool*) (set! (-> *camera-pool* mask) (process-mask freeze pause menu progress process-tree camera)) diff --git a/goal_src/jak3/kernel/gstate.gc b/goal_src/jak3/kernel/gstate.gc index ae8fbf9b057..50d5ec6e552 100644 --- a/goal_src/jak3/kernel/gstate.gc +++ b/goal_src/jak3/kernel/gstate.gc @@ -41,11 +41,10 @@ &rest args) "Start a new process and run an init function on it. Returns a pointer to the new process, or #f (or is it 0?) if something goes wrong." - (with-gensyms (new-proc) `(let ((,new-proc (the-as ,(if runtime 'process proc-type) (get-process ,from ,proc-type ,stack-size ,unk)))) (when ,new-proc - ((method-of-type ,(if runtime 'process proc-type) activate) ,new-proc ,to ,(if name name `(symbol->string ,proc-type)) ,stack) + ((method-of-type ,(if runtime 'process proc-type) activate) ,new-proc ,to ,(if name name `(symbol->string ',proc-type)) ,stack) (run-now-in-process ,new-proc ,(if init init (string->symbol (fmt #f "{}-init-by-other" proc-type))) ,@args) (the (pointer ,(if runtime 'process proc-type)) (-> ,new-proc ppointer)) ) diff --git a/goal_src/jak3/pc/debug/default-menu-pc.gc b/goal_src/jak3/pc/debug/default-menu-pc.gc index 14b045f63ed..4c1705287a4 100644 --- a/goal_src/jak3/pc/debug/default-menu-pc.gc +++ b/goal_src/jak3/pc/debug/default-menu-pc.gc @@ -733,44 +733,42 @@ ) -;; (define *made-vag-list* #f) -;; (defun build-vag-list ((menu debug-menu)) -;; "Fill the vag play menu" +(define *made-vag-list* #f) +(defun build-vag-list ((menu debug-menu)) + "Fill the vag play menu" + (if *made-vag-list* + (return #f)) + (true! *made-vag-list*) -;; (if *made-vag-list* -;; (return #f)) -;; (true! *made-vag-list*) - -;; ;; clear old list -;; (debug-menu-remove-all-items menu) + ;; clear old list + (debug-menu-remove-all-items menu) -;; ;; make button for each vag, we use an index -;; (dotimes (i (-> *vag-list* allocated-length)) -;; (debug-menu-append-item menu (new-dm-func (-> *vag-list* i) i vag-player-play-from-index)) -;; ) + ;; make button for each vag, we use an index + (dotimes (i (-> *vag-list* allocated-length)) + (debug-menu-append-item menu (new-dm-func (-> *vag-list* i) i vag-player-play-from-index)) + ) -;; ;; sort by vag name - note: already sorted from before -;; ;(set! (-> menu items) (sort (-> menu items) debug-menu-node menu items) (sort (-> menu items) debug-menu-node *setting-control* user-default subtitle))) -;; (-> *setting-control* user-default subtitle)))) -;; ;; pick channel - -;; (new-dm-submenu "Vag" vag-menu) -;; ) -;; ) +(define *vag-play-menu* (the debug-menu #f)) +(defun debug-menu-make-vag-menu ((ctx debug-menu-context)) + (let ((vag-menu (new 'debug 'debug-menu ctx "Vag menu"))) + (let ((play-menu (new 'debug 'debug-menu ctx "Play Vag menu"))) + (set! *vag-play-menu* play-menu) + (debug-menu-append-item vag-menu (new-dm-submenu "Play" play-menu)) + ) + (debug-menu-append-item vag-menu (new-dm-func "Make List" *vag-play-menu* build-vag-list)) + (debug-menu-append-item vag-menu (new-dm-bool "subtitle" #f + (lambda (arg (msg debug-menu-msg)) + (if (= msg (debug-menu-msg press)) + (not! (-> *setting-control* user-default subtitle))) + (-> *setting-control* user-default subtitle)))) + ;; pick channel + (new-dm-submenu "Vag" vag-menu) + ) + ) (defun dm-frame-rate-pick-func ((bfps int) (msg debug-menu-msg)) (let ((fps (/ bfps 8))) @@ -815,7 +813,7 @@ (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-part-menu *debug-menu-context*)) (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-entity-menu *debug-menu-context*)) (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-regions-menu *debug-menu-context*)) - ;; (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-vag-menu *debug-menu-context*)) + (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-vag-menu *debug-menu-context*)) (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-from-template *debug-menu-context* diff --git a/goal_src/jak3/pc/debug/vag-player.gc b/goal_src/jak3/pc/debug/vag-player.gc new file mode 100644 index 00000000000..d1cbc6c7c35 --- /dev/null +++ b/goal_src/jak3/pc/debug/vag-player.gc @@ -0,0 +1,456 @@ +;;-*-Lisp-*- +(in-package goal) + +#| + + vag player process for debugging vag streams and for easier subtitling. + + |# + +(declare-file (debug)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; constants +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; types and enums +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;---------------------------------- +;; process type +;;;---------------------------------- + + +;; the vag-player process. it lives on the PC actor pool +(deftype vag-player (process) + ( + (vag-index int32) + (id sound-id) + (speed float) + (old-speed float) + + ;; temp settings + (master-mode symbol) + (display-art-control symbol) + (debug-menu-hidden symbol) + (gui-kick-str symbol) + ) + + (:methods + (vag-stop (_type_) int) + (vag-play (_type_) sound-id) + (vag-playing? (_type_) symbol) + (vag-set-speed (_type_ float) sound-id) + ) + (:states + (vag-player-playing int) + ) + ) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; vag list +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;; an array of 64-bit values which can be turned into a string +;; each representing the name of a vag stream. convert using alloc-vag-list +(define *vagdir-names-list* (alloc-vagdir-names 'debug)) + +(defun strcmp ((a string) (b string)) + "C-style strcmp. Unlike GOAL's string comparison functions, these actually work: + (strcmp 'ab' 'a') and (strcmp 'a' 'ab') give the opposite result." + (let ((a-ptr (-> a data)) + (b-ptr (-> b data))) + (while (and (nonzero? (-> a-ptr)) + (= (-> a-ptr) (-> b-ptr))) + (&+! a-ptr 1) + (&+! b-ptr 1) + ) + (- (the int (-> a-ptr)) (the int (-> b-ptr))) + ) + ) + +(defun string-quicksort-partition ((arr (array string)) (lo int) (hi int)) + (let ((pivot (-> arr hi)) + (i (- lo 1)) + (j lo) + ) + (while (< j hi) + (when (< (strcmp (-> arr j) pivot) 0) + (+! i 1) + (swap! (-> arr i) (-> arr j)) + ) + (+! j 1) + ) + (+! i 1) + (swap! (-> arr i) (-> arr hi)) + i + ) + ) + +(defun-recursive string-quicksort-run (array string) ((arr (array string)) (lo int) (hi int)) + (when (or (>= lo hi) (< lo 0)) + (return arr) + ) + (let ((p (string-quicksort-partition arr lo hi))) + (string-quicksort-run arr lo (- p 1)) + (string-quicksort-run arr (+ p 1) hi) + ) + arr + ) + +(defun string-quicksort ((arr (array string))) + "Sort an array of strings alphabetically using quicksort. + This is about 100x faster than the normal GOAL sort." + (string-quicksort-run arr 0 (- (-> arr length) 1)) + ) + + +(defun alloc-vag-list () + "allocates and returns a boxed array with all of the vag names as strings, sorted" + (let ((list (new 'debug 'boxed-array string (the int (-> *vagdir-names-list* -1))))) + + ;; for each vag... + (dotimes (i (-> list allocated-length)) + ;; write the vag name (64 bits) into the string directly and add a null character + (set! (-> (the (pointer uint64) (-> *temp-string* data))) (-> *vagdir-names-list* i)) + (set! (-> *temp-string* data 8) 0) + (countdown (ii 8) + (if (!= #x20 (-> *temp-string* data ii)) + (set! ii 0) + (set! (-> *temp-string* data ii) 0)) + ) + + ;; copy into a new string + (set! (-> list i) (new 'debug 'string 0 *temp-string*))) + + ;; return the allocated, filled and sorted array + (string-quicksort list)) + ) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; globals +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;; the process pointer. +(define *vag-player* (the (pointer vag-player) #f)) + +;; list of vag names (as a string) +(define *vag-list* (alloc-vag-list)) +;; the highest recorded position for each vag +(define *vag-max-pos-list* (the (pointer int32) (malloc 'debug (* 4 (-> *vag-list* allocated-length))))) + +(defun get-vag-index-from-name ((name string)) + "return the index of the vag with that name in the *vag-list* or -1 if not found" + + ;; uppercase the string so we have a consistent name format + (string-upcase name *vag-temp-string* #f) + (dotimes (i (-> *vag-list* allocated-length)) + (string-upcase (-> *vag-list* i) *vag-temp-string-2* #f) + (when (string= *vag-temp-string* *vag-temp-string-2*) + (return i)) + ) + -1) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; states +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defmethod deactivate vag-player ((obj vag-player)) + (set! *vag-player* (the (pointer vag-player) #f)) + ((method-of-type process deactivate) obj) + (none) + ) + +(defstate vag-player-idle (vag-player) + :event (behavior ((from process) (argc int) (msg symbol) (block event-message-block)) + (case msg + (('play) + (let ((vag-idx (get-vag-index-from-name (the string (-> block param 0))))) + (when (!= vag-idx -1) + (go vag-player-playing vag-idx) + (return #t))) + #f) + (('play-index) + (go vag-player-playing (the int (-> block param 0)))) + ) + ) + + :code sleep-code + ) + + +(defstate vag-player-playing (vag-player) + + :event (behavior ((from process) (argc int) (msg symbol) (block event-message-block)) + (case msg + (('play) + (let ((vag-idx (get-vag-index-from-name (the string (-> block param 0))))) + (when (!= vag-idx -1) + (set! (-> self vag-index) vag-idx) + (vag-play self) + (return #t))) + #f) + (('play-index) + (set! (-> self vag-index) (the int (-> block param 0))) + (vag-play self) + #t) + ) + ) + + :enter (behavior ((index int)) + (set! (-> self master-mode) *master-mode*) + (set! (-> self debug-menu-hidden) (-> *debug-menu-context* is-hidden)) + (set! (-> self display-art-control) *display-art-control*) + (set! (-> self gui-kick-str) *gui-kick-str*) + + (set-master-mode 'menu) ;; put us in menu mode first + (true! *display-art-control*) ;; force this on + (true! (-> *debug-menu-context* is-hidden)) ;; hide debug menu + (true! *gui-kick-str*) ;; force gui control to play streams + (sound-group-continue (sound-group dialog dialog2)) ;; unpause dialog + (set-setting! 'music-volume 'abs 0.0 0) ;; mute music + (set-setting! 'sfx-volume 'abs 0.0 0) ;; mute sfx + (set-setting! 'ambient-volume 'abs 0.0 0) ;; mute ambient + (set-setting! 'dialog-volume 'abs 1.0 0) ;; max dialog + (apply-settings *setting-control*) ;; apply settings now + + (set! (-> self speed) 0.0) + (set! (-> self old-speed) 0.0) + ) + + :exit (behavior () + (vag-stop self) + + (remove-setting! 'music-volume) + (remove-setting! 'sfx-volume) + (remove-setting! 'ambient-volume) + (remove-setting! 'dialog-volume) + (apply-settings *setting-control*) + (sound-group-pause (sound-group dialog dialog2)) + (set! *display-art-control* (-> self display-art-control)) + (set! (-> *debug-menu-context* is-hidden) (-> self debug-menu-hidden)) + (set! *gui-kick-str* (-> self gui-kick-str)) + (if (!= (-> self master-mode) 'menu) + (set-master-mode (-> self master-mode))) + ) + + :code (behavior ((index int)) + (set! (-> self vag-index) index) + + (let ((exit? #f)) + (vag-play self) + (while (= (gui-status pending) (get-status *gui-control* (-> self id))) + (suspend)) + + (until (or exit? (!= *master-mode* 'menu)) + (format *stdcon* "Vag Player -- Press Triangle To Exit~%") + (cond + ((zero? (-> self id)) + (format *stdcon* "No vag queued~%")) + ((not (vag-playing? self)) + (format *stdcon* "Vag not playing~%")) + (else + (format *stdcon* "Vag playing: ~3L~D~0L~%" (the int (/ (the float (current-str-pos (-> self id))) (/ 1024.0 30))))) + ) + (format *stdcon* "Vag: ~S <- ~S(max:~3L~D~0L) -> ~S~%" (if (> (-> self vag-index) 0) (-> *vag-list* (1- (-> self vag-index)))) + (-> *vag-list* (-> self vag-index)) (-> *vag-max-pos-list* (-> self vag-index)) + (if (< (1+ (-> self vag-index)) (-> *vag-list* allocated-length)) (-> *vag-list* (1+ (-> self vag-index))))) + (format *stdcon* "X to Pause and Play~%R1 and L1 for Speed, Circle Resets~%Left and Right for Prev / Next~%Square for Subtitles (~A)~%" (-> *setting-control* user-default subtitle)) + (format *stdcon* "Speed: ~f~%" (-> self speed)) + (cond + ((cpad-pressed? 0 triangle) + (cpad-clear! 0 triangle) + (true! exit?)) + ((cpad-pressed? 0 x) + (cpad-clear! 0 x) + (cond + ((not (vag-playing? self)) + (vag-play self)) + ((= (-> self speed) -1000.0) + (set! (-> self speed) 0.0) + (sound-continue (-> self id)) + (when *sound-player-enable* + (let ((cmd (the-as sound-rpc-set-param (get-sound-buffer-entry)))) + (set! (-> cmd command) (sound-command set-param)) + (set! (-> cmd id) (-> self id)) + (set! (-> cmd params pitch-mod) 0) + (set! (-> cmd params mask) (the-as uint 2)) + (-> cmd id) + ) + ) + ) + (else + (set! (-> self speed) -1000.0) + (sound-pause (-> self id)) + ) + ) + ) + ((and (cpad-pressed? 0 left) (> (-> self vag-index) 0)) + (cpad-clear! 0 left) + (1-! (-> self vag-index)) + (vag-play self)) + ((and (cpad-pressed? 0 right) (< (1+ (-> self vag-index)) (-> *vag-list* allocated-length))) + (cpad-clear! 0 right) + (1+! (-> self vag-index)) + (vag-play self)) + ((and (cpad-hold? 0 r1 l1) (!= (-> self speed) -1000.0)) + (seek! (-> self speed) (if (cpad-hold? 0 l1) -4.0 4.0) (* 0.5 (-> self clock seconds-per-frame))) + ) + ((cpad-pressed? 0 circle) + (cpad-clear! 0 circle) + (set! (-> self speed) 0.0)) + ((cpad-pressed? 0 square) + (cpad-clear! 0 square) + (not! (-> *setting-control* user-default subtitle))) + ) + (when (vag-playing? self) + (max! (-> *vag-max-pos-list* (-> self vag-index)) (the int (/ (the float (current-str-pos (-> self id))) (/ 1024.0 30)))) + (when (and (!= (-> self speed) (-> self old-speed)) (!= (-> self speed) -1000.0)) + (vag-set-speed self (-> self speed)) + (set! (-> self old-speed) (-> self speed)))) + (suspend)) + ) + + (go vag-player-idle) + ) + ) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; methods +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defmethod vag-play vag-player ((self vag-player)) + "play the current vag stream" + (set! (-> self speed) 0.0) + (set! (-> self old-speed) 0.0) + (vag-stop self) + (set! (-> self id) (add-process *gui-control* self (gui-channel alert) (gui-action play) (-> *vag-list* (-> self vag-index)) -10.0 0))) + +(defmethod vag-stop vag-player ((self vag-player)) + "stop the current vag stream" + (set-action! *gui-control* (gui-action stop) (-> self id) (gui-channel none) (gui-action none) (the string #f) (the-as (function gui-connection symbol) #f) (the-as process #f))) + +(defmethod vag-playing? vag-player ((self vag-player)) + "is the current vag stream playing?" + (let ((status (get-status *gui-control* (-> self id)))) (or (= status (gui-status ready)) (= status (gui-status active))))) + +(defmethod vag-set-speed vag-player ((self vag-player) (speed float)) + "set the speed of the current vag stream" + (when *sound-player-enable* + (let ((cmd (the-as sound-rpc-set-param (get-sound-buffer-entry)))) + (set! (-> cmd command) (sound-command set-param)) + (set! (-> cmd id) (-> self id)) + (set! (-> cmd params pitch-mod) (the int (* 1524.0 speed))) + (set! (-> cmd params mask) (the-as uint 2)) + (-> cmd id) + ) + )) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; helper functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +(defbehavior vag-player-init-by-other vag-player () + "external initializer for vag-player process" + (set! (-> self id) (new 'static 'sound-id)) + (process-mask-clear! (-> self mask) menu pause) + (go vag-player-idle) + ) + + +(defun vag-player-stop () + "kill the vag-player process" + (kill-by-type vag-player *pc-pool*)) + +(defun vag-player-start () + "start the vag-player process" + + (when *vag-player* + (vag-player-stop) + ) + + (set! *vag-player* (process-spawn vag-player :from *pc-dead-pool* :to *pc-pool*)) + ) + + +(defun vag-player-play-from-index ((index int)) + "play a vag from its index in the vag list" + (if (not *vag-player*) + (vag-player-start)) + + (send-event (ppointer->process *vag-player*) 'play-index index)) + +(defun vag-player-play-from-name ((name string)) + "play a vag from its name" + (if (not *vag-player*) + (vag-player-start)) + + (send-event (ppointer->process *vag-player*) 'play name)) + +(defun vag-list-to-file ((file-name string)) + (if *vag-list* + (let ((file (new 'stack 'file-stream file-name 'write))) + (dotimes (i (-> *vag-list* allocated-length)) + (format file "~S~%" (-> *vag-list* i)) + ) + (file-stream-close file) + ) + #f + ) + ) + +;; start the vag-player process when this file loads. +(vag-player-start) + + +(defun scene-find-and-play ((name string)) + "go through the scene player list to find and play the requested scene" + (vag-player-stop) + (let* ((find-scene-in-act + (lambda ((scene-list (array hud-scene-info)) (name string)) + ;; for each scene in list + (doarray (scene-info scene-list) + ;; scene name matches - return that immediately + (if (and (string? (-> scene-info info)) (string= (the string (-> scene-info info)) name)) + (return scene-info)) + ;; scene name didn't match, see if there is a scene playlist + ;; if there is, then find our scene there + (when (pair? (-> scene-info info)) + (let ((iter (the pair (-> scene-info info)))) + (while (not (null? iter)) + (if (and (string? (car iter)) (string= (the string (car iter)) name)) + (return scene-info)) + (set! iter (cdr iter)) + ) + ) + ) + ) + (the hud-scene-info #f)))) + (awhen (or (find-scene-in-act *hud-select-scene-act1* name) + (find-scene-in-act *hud-select-scene-act2* name) + (find-scene-in-act *hud-select-scene-act3* name)) + (process-spawn scene-player :init scene-player-init name #t (-> (the hud-scene-info it) continue)) + ) + ) + 0) + diff --git a/goal_src/jak3/pc/subtitle3-h.gc b/goal_src/jak3/pc/subtitle3-h.gc new file mode 100644 index 00000000000..d6cd494c650 --- /dev/null +++ b/goal_src/jak3/pc/subtitle3-h.gc @@ -0,0 +1,381 @@ +;;-*-Lisp-*- +(in-package goal) + +#| + + Code for subtitles for the PC port. A PC actor pool is provided, and the subtitle3 process lives there. + Jak 3 has subtitles, but only for cutscenes and only for the actual spoken text. + The subtitle process automatically looks for currently-playing audio in the gui control. + It looks for specific channels there, NOT including the movie or subtitle channel. + + This updated subtitle system has a few different features than the Jak 1 subtitle system: + - you can have multiple playing subtitles at once. Additional subtitles are rendered above the older ones, + just like real subtitles. This goes for both multiple subtitles within the same scene, and also multiple scenes + playing at once. + - it can "merge" with the pre-existing subtitle system. Some code in scene.gc is changed to redirect subtitles + to here to do that. + - you supply the start AND end times as opposed to just the start time. + - the speaker names are color-coded. + Note that subtitle images are NOT supported with this! Merge mode will also NOT work with subtitle images. + + Similarly to the generic text file, only one subtitles text file is loaded at once, stored in a specific + heap. + + |# + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; constants +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defconstant PC_SUBTITLE_FILE_SIZE (* 600 1024)) ;; 600K heap for subtitles. adjust later if necessary. +(defconstant PC_SUBTITLE_FILE_NAME "subti3") +(defconstant PC_SUBTITLE_QUEUE_SIZE 5) ;; up to 5 things that display subtitles can be detected at once +(defconstant PC_SUBTITLE_QUEUE_MAX_LINES 2) ;; up to 2 lines can be queued per queueable thing +(defconstant PC_SUBTITLE_MAX_LINES 10) ;; max subtitles that can be displayed at once: queue-size * queue-lines + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; types and enums +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;------------------------ +;; data +;;;------------------------ + + +(defenum pc-subtitle3-flags + :bitfield #t + :type uint16 + (offscreen) ;; speaker is offscreen. + (merge) ;; line of text comes from movie subtitles + ) + +;; the list of available speakers for subtitles +(defenum pc-subtitle3-speaker + :type uint16 + (none) ;; won't display a speaker - use this for tutorial messages etc. + + (jak) + (darkjak) + (daxter) + (pecker) + (ashelin) + (veger) + (samos) + (damas) + (kleiver) + (seem) + (errol) + (errol-hologram) ;; desert-hover-res + (sig) + (torn) + (tess) + (guard) + (guard-a) + (guard-b) + (keira) + (vin) + (onin) + (jinx) + (wastelander-male) + (wastelander-female) + (citizen-male) + (citizen-female) + (marauder) + (oracle) + (precursor) + (ottsel-leader) + (ottsel-surfer) + (ottsel-dummy) + (ottsel-veger) + (ottsel-tess) + (computer) + + ;; museum + (krew) + (baron) + + ;; naughty dog developer commentary + (scherr) + (arey) + (baldwin) + (schimpf) + (martinsen) + (phillips) + (yates) + + (max)) + +;; information about a single line of subtitles +(deftype subtitle3-line (structure) + ( + (start-frame float) ;; the first frame to show the line on + (end-frame float) ;; the last frame to show the line on + (text string) ;; the text for the subtitle3 line + (speaker pc-subtitle3-speaker) ;; who the line speaker is + (flags pc-subtitle3-flags) ;; flags + ) + :pack-me + ) + +;; an individual entry to a subtitle3 text making up a "scene" (audio file, spool), comprised of a series of lines +(deftype subtitle3-scene (structure) + ( + ;; the name of the spool-anim or audio file + (name string) + ;; the amount of lines + (length int32) + ;; line data + (lines (inline-array subtitle3-line)) + ) + :pack-me + :size-assert #xc ;; compact! + + (:methods + (get-line-at-pos (_type_ float int) subtitle3-line) + ) + ) + +;; the global subtitle3 text info bank +(deftype subtitle3-text-info (basic) + ((length int16) + (version int16) + (lang pc-language) + (speaker-length int16) + (speaker-names (pointer string)) + (data subtitle3-scene :inline :dynamic) + ) + + (:methods + (get-speaker (_type_ pc-subtitle3-speaker) string) + (get-scene-by-name (_type_ string) subtitle3-scene) + ) + ) + + +(defmacro subtitle3-flags? (sub &rest flags) + `(logtest? (-> ,sub flags) (pc-subtitle3-flags ,@flags))) + + +(defmethod inspect ((obj subtitle3-text-info)) + (if (not obj) + (return (the subtitle3-text-info #f))) + (format #t "[~8x] ~A~%" obj (-> obj type)) + (format #t "~1Tlength: ~D~%" (-> obj length)) + (format #t "~1Tversion: ~D~%" (-> obj version)) + (format #t "~1Tlang: ~D~%" (-> obj lang)) + (format #t "~1Tspeaker-names[~D] @ #x~x~%" (-> obj speaker-length) (-> obj speaker-names)) + (dotimes (i (-> obj speaker-length)) + (format #t "~2T[~D]: ~A~%" i (-> obj speaker-names i))) + (format #t "~1Tdata[0] @ #x~x~%" (-> obj data)) + (dotimes (i (-> obj length)) + (format #t "~2T--------~%") + (format #t "~2Tname: ~A~%" (-> obj data i name)) + (format #t "~2Tlines[~D] @ #x~x~%" (-> obj data i length) (-> obj data i lines)) + (dotimes (ii (-> obj data i length)) + (format #t "~3T[~f to ~f] (#x~x)(~S) ~A~%" (-> obj data i lines ii start-frame) (-> obj data i lines ii end-frame) + (-> obj data i lines ii flags) + (enum->string pc-subtitle3-speaker (-> obj data i lines ii speaker)) + (-> obj data i lines ii text))) + ) + obj) + + +;;;---------------------------------- +;; process type +;;;---------------------------------- + + +;; graphic parameters for subtitles +(deftype subtitle3-bank (structure) + ((scale float) + (width float) + (lines float) + ) + ) + +(define *SUBTITLE3-bank* + (new 'static 'subtitle3-bank + :scale 0.9 + :width 0.65 + :lines 2.0 + )) + + +(deftype subtitle3-queue-element (structure) + ((id sound-id) + (gui gui-connection) + ) + :pack-me + + (:methods + (clear-line (_type_) int)) + ) + +(deftype subtitle3-line-queue-element (structure) + ((line subtitle3-line) + (y float) + ) + :pack-me + + (:methods + (set-params! (_type_ subtitle3-line float) int)) + ) + +(deftype subtitle3-line-queue (structure) + ((elts subtitle3-line-queue-element PC_SUBTITLE_MAX_LINES :inline) + ) + :pack-me + ) + +;; the subtitle3 process! it lives on the PC actor pool +(deftype subtitle3 (process) + ( + (font font-context) ;; the font to use for the subtitles. + + (have-message? symbol) ;; if there is a message displaying at the bottom, move subtitles up + (have-minimap? symbol) ;; if there is a minimap displaying at the bottom, shrink subtitles + (have-subtitles? symbol) ;; #t if we rendered any subtitles on the last frame. + + (movie-mode? symbol) ;; #t if we're in movie mode + (movie-line string) ;; a copy of the current movie line + (movie-gui gui-connection) ;; the gui entry for the movie. we need this to put it in the gui queue + (movie-pos float) + + (gui-id sound-id) + ;; store the gui id of channels with subtitles that we find. + ;; that way if subtitle B appears above A, it wont move back down + ;; if A ends before B + (queue subtitle3-queue-element PC_SUBTITLE_QUEUE_SIZE :inline) + (lines subtitle3-line-queue 2 :inline) + (line-queue-idx int8) + + ;; debug + (cheat-backup symbol) + (checking-lines? symbol) + (current-debug-subtitle subtitle3-line) + (current-debug-scene int32) + (current-debug-line int32) + ) + + (:methods + (clear-queue (_type_) int) + (update-gui-connections (_type_) int) + (get-empty-queue (_type_) int) + (gui-queued? (_type_ gui-connection) symbol) + (add-to-queue (_type_ gui-connection) gui-connection) + (get-active-subtitles (_type_) int) + (subtitle-format (_type_ subtitle3-line) string) + (draw-subtitles (_type_) int) + (debug-print-queue (_type_) int) + (debug-print-speakers (_type_) int) + (start-gui (_type_) sound-id) + (stop-gui (_type_) sound-id) + ) + (:states + subtitle3-debug + subtitle3-debug-checking-lines) + ) + + + + +;;;---------------------------------------------- +;; globals +;;;---------------------------------------------- + + +;; the subtitle3 process. +(define *subtitle3* (the (pointer subtitle3) #f)) + +;; subtitle3 text data +(define *subtitle3-text* (the subtitle3-text-info #f)) +(kheap-alloc (define *subtitle3-text-heap* (new 'global 'kheap)) PC_SUBTITLE_FILE_SIZE) + +;; temp strings for name look-up +(define *vag-temp-string* (new 'global 'string 128 (the string #f))) +(define *vag-temp-string-2* (new 'global 'string 128 (the string #f))) + +;; speaker color table +(define *subtitle3-speaker-color-table* (the (pointer rgba) (malloc 'global (* (size-of rgba) (pc-subtitle3-speaker max))))) + +;; debug option +(define *display-subtitle-speakers* #f) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; helper functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defmethod length ((obj subtitle3-text-info)) + "Get the length (number of subtitle3 scenes) in a subtitle3-text-info." + (-> obj length) + ) + +(defmethod length ((obj subtitle3-scene)) + "Get the length (number of subtitle3 lines) in a subtitle3-scene." + (-> obj length) + ) + + +(defmacro set-subtitle-speaker-color! (speaker color) + "macro for setting a color in *subtitle3-speaker-color-table*" + `(set! (-> *subtitle3-speaker-color-table* (pc-subtitle3-speaker ,speaker)) ,color)) +(defmacro set-subtitle-speaker-color<-speaker! (speaker speaker-from) + "macro for setting a color in *subtitle3-speaker-color-table* the same as a different speaker" + `(set-subtitle-speaker-color! ,speaker (-> *subtitle3-speaker-color-table* (pc-subtitle3-speaker ,speaker-from)))) + +(defun set-subtitle-speaker-colors () + "fill the subtitle speaker color table" + + (dotimes (i (pc-subtitle3-speaker max)) + (set! (-> *subtitle3-speaker-color-table* i) (-> *font-work* color-table (font-color red) color 0)) + ) + + (set-subtitle-speaker-color! jak (static-rgba #x70 #x80 #x00 #x80)) + (set-subtitle-speaker-color! darkjak (static-rgba #x68 #x68 #x80 #x80)) + (set-subtitle-speaker-color! daxter (static-rgba #x80 #x35 #x00 #x80)) + (set-subtitle-speaker-color! samos (static-rgba #x30 #x80 #x08 #x80)) + (set-subtitle-speaker-color! pecker (static-rgba #x80 #x80 #x00 #x80)) + (set-subtitle-speaker-color! damas (static-rgba #x30 #x45 #x75 #x80)) + (set-subtitle-speaker-color! kleiver (static-rgba #x40 #x30 #x15 #x80)) + (set-subtitle-speaker-color! marauder (static-rgba #x50 #x30 #x15 #x80)) + (set-subtitle-speaker-color! seem (static-rgba #x80 #x45 #x00 #x80)) + (set-subtitle-speaker-color! veger (static-rgba #x40 #x10 #x10 #x80)) + (set-subtitle-speaker-color! krew (static-rgba #x10 #x48 #x10 #x80)) + (set-subtitle-speaker-color! baron (static-rgba #x60 #x00 #x00 #x80)) + (set-subtitle-speaker-color! ashelin (static-rgba #x80 #x18 #x18 #x80)) + (set-subtitle-speaker-color! torn (static-rgba #x40 #x40 #x50 #x80)) + (set-subtitle-speaker-color! errol (static-rgba #x80 #x10 #x00 #x80)) + (set-subtitle-speaker-color! sig (static-rgba #x70 #x70 #x80 #x80)) + (set-subtitle-speaker-color! vin (static-rgba #x38 #x80 #x80 #x80)) + (set-subtitle-speaker-color! guard (static-rgba #x00 #x50 #x80 #x80)) + (set-subtitle-speaker-color! keira (static-rgba #x00 #x40 #x28 #x80)) + (set-subtitle-speaker-color! tess (static-rgba #x80 #x80 #x38 #x80)) + (set-subtitle-speaker-color! onin (static-rgba #x80 #x80 #x80 #x80)) + (set-subtitle-speaker-color! jinx (static-rgba #x50 #x40 #x00 #x80)) + (set-subtitle-speaker-color! precursor (static-rgba #x00 #x60 #x80 #x80)) + (set-subtitle-speaker-color! computer (static-rgba #x60 #x60 #x60 #x80)) + (set-subtitle-speaker-color! citizen-male (static-rgba #x70 #x70 #x70 #x80)) + (set-subtitle-speaker-color! citizen-female (static-rgba #x70 #x70 #x70 #x80)) + + (set-subtitle-speaker-color<-speaker! ottsel-leader daxter) + (set-subtitle-speaker-color<-speaker! ottsel-surfer daxter) + (set-subtitle-speaker-color<-speaker! ottsel-dummy daxter) + (set-subtitle-speaker-color<-speaker! ottsel-veger veger) + (set-subtitle-speaker-color<-speaker! ottsel-tess tess) + (set-subtitle-speaker-color<-speaker! errol-hologram errol) + (set-subtitle-speaker-color<-speaker! guard-a guard) + (set-subtitle-speaker-color<-speaker! guard-b guard) + (set-subtitle-speaker-color<-speaker! kleiver wastelander-male) + (set-subtitle-speaker-color<-speaker! kleiver wastelander-female) + ) + + + diff --git a/goal_src/jak3/pc/subtitle3.gc b/goal_src/jak3/pc/subtitle3.gc new file mode 100644 index 00000000000..b34c653e4a2 --- /dev/null +++ b/goal_src/jak3/pc/subtitle3.gc @@ -0,0 +1,885 @@ +;;-*-Lisp-*- +(in-package goal) + +#| + + Code for subtitles for the PC port. A PC actor pool is provided, and the subtitle3 process lives there. + Jak 3 has subtitles, but only for cutscenes and only for the actual spoken text. + The subtitle process automatically looks for currently-playing audio in the gui control. + It looks for specific channels there, NOT including the movie or subtitle channel. + + This updated subtitle system has a few different features than the Jak 1 subtitle system: + - you can have multiple playing subtitles at once. Additional subtitles are rendered above the older ones, + just like real subtitles. This goes for both multiple subtitles within the same scene, and also multiple scenes + playing at once. + - it can "merge" with the pre-existing subtitle system. Some code in scene.gc is changed to redirect subtitles + to here to do that. + - you supply the start AND end times as opposed to just the start time. + - the speaker names are color-coded. + Note that subtitle images are NOT supported with this! Merge mode will also NOT work with subtitle images. + + Similarly to the generic text file, only one subtitles text file is loaded at once, stored in a specific + heap. + + |# + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; constants +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defconstant PC_SUBTITLE_Y_RECALC -99.0) + +(defconstant PC_SUBTITLE_DISABLE_MOVIE_MODE #f) + +(defconstant PC_SUB_DBG_Y 60) +(defconstant PC_SUB_DBG_CHECK_GROUP_SIZE 64) +(defglobalconstant PC_SUBTITLE_DEBUG #f) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; access subtitle heap +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defmethod get-speaker ((obj subtitle3-text-info) (speaker pc-subtitle3-speaker)) + "get the translated string for that speaker" + (if (and (> speaker (pc-subtitle3-speaker none)) (< speaker (-> obj speaker-length))) + (-> obj speaker-names speaker) + (the string #f)) + ) + +(defmethod get-scene-by-name ((obj subtitle3-text-info) (name string)) + "get a subtitle scene info with the corresponding name. #f = none found" + + ;; invalid name so return invalid scene. + (if (not name) + (return (the subtitle3-scene #f))) + + ;; bounds checking + (when (> (length name) (-> *vag-temp-string* allocated-length)) + (format 0 "vag temp string is too short!! wanted: ~D chars~%" (length name))) + + ;; uppercase the string so we have a consistent name format + (string-upcase name *vag-temp-string* #f) + (dotimes (i (length obj)) + ;; bounds checking + (when (> (length (-> obj data i name)) (-> *vag-temp-string-2* allocated-length)) + (format 0 "vag temp string is too short!! wanted: ~D chars~%" (length name))) + ;; name and kind matches, return that! + (string-upcase (-> obj data i name) *vag-temp-string-2* #f) + (when (string= *vag-temp-string-2* *vag-temp-string*) + (return (-> obj data i))) + ) + + (the subtitle3-scene #f)) + + +(defmethod get-line-at-pos ((obj subtitle3-scene) (pos float) (index int)) + "return the subtitle line at that position. #f = none found + index is which line to return, since you can have multiple lines that cover the same position." + + (let ((found 0)) + + (dotimes (i (length obj)) + (when (and (>= pos (-> obj lines i start-frame)) + (< pos (-> obj lines i end-frame))) + (when (= found index) + (return (-> obj lines i))) + (1+! found) + ))) + + (the subtitle3-line #f)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; loading files +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defun load-subtitle3-text-info ((txt-name string) (curr-text symbol) (heap kheap)) + "load a subtitles text file onto a heap. + txt-name = file name suffix + curr-text = a symbol to a subtitle3-text-info to link the file to + heap = the text heap to load the file onto" + + (let ((heap-sym-heap (the-as subtitle3-text-info (-> curr-text value))) + (lang (-> *setting-control* user-current subtitle-language)) + (load-status 0) + (heap-free (&- (-> heap top) (the-as uint (-> heap base))))) + + ;; current text has nothing loaded, or language doesn't match. + (when (or (= heap-sym-heap #f) + (!= (-> heap-sym-heap lang) lang)) + ;; so reload. + + ;; reset the text heap. + (kheap-reset heap) + + ;; try to load load... + (while (not (str-load (string-format "~D~S.TXT" lang txt-name) -1 (logand -64 (&+ (-> heap current) 63)) (&- (-> heap top) (-> heap current)))) + (return 0) + ) + ;; load succeeded. check status. + + (label retry) + (let ((status (str-load-status (the-as (pointer int32) (& load-status))))) + (when (= status 'error) + (format 0 "Error loading subtitle3~%") + (return 0) + (goto loaded) + ) + (cond + ((>= load-status (+ heap-free -300)) + (format 0 "Game subtitle3 heap overrun!~%") + (return 0) + ) + ((= status 'busy) + ;; still loading. + (goto retry) + ) + ) + ) + (label loaded) + + ;; link the text file! + (let ((new-mem (logand -64 (&+ (-> heap current) 63)))) + (flush-cache 0) + (set! (-> curr-text value) (link new-mem (-> (string-format "~D~S.TXT" lang txt-name) data) load-status heap 0)) + ) + ;; if linking failed just make the text invalid. + (if (<= (the-as int (-> curr-text value)) 0) + (set! (-> curr-text value) (the-as object #f)) + ) + )) + 0) + +(defun load-level-subtitle3-files ((idx int)) + "Load the subtitle3 files needed for level idx. + This function made more sense back when text files were split up, but in the end they put everything + in a single text group and file." + + ;; just load common. + (if (or *level-text-file-load-flag* (>= idx 0)) + (load-subtitle3-text-info PC_SUBTITLE_FILE_NAME '*subtitle3-text* *subtitle3-text-heap*) + ) + + (none)) + + +(defmacro reload-subtitles () + "rebuild and reload subtitles." + `(begin + (asm-text-file subtitle-v2 :files ("game/assets/jak3/game_subtitle.gp")) + (if *subtitle3-text* + (+! (-> *subtitle3-text* lang) 1)) + (load-level-subtitle3-files 0))) + +(defmacro reload-text () + "rebuild and reload text." + `(begin + (mng) + (if *common-text* + (+! (-> *common-text* language-id) 1)) + (load-level-text-files 0))) + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; subtitle3 queue +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defun subtitle-channel? ((ch gui-channel)) + "can this gui channel be checked for subtitles?" + (and (>= ch (gui-channel jak)) (<= ch (gui-channel task))) + ) + +(defun valid-subtitle-gui? ((gui gui-connection)) + "is this gui connection valid for checking subtitles?" + (and gui (nonzero? (-> gui id)) + (subtitle-channel? (-> gui channel)) + (or (= (-> gui action) (gui-action playing)) + (= (-> gui action) (gui-action play))) + (let ((status (get-status *gui-control* (-> gui id)))) + (or (= status (gui-status ready)) + (= status (gui-status active))))) + ) + +(defun subtitle-bump-up? () + "should subtitles be moved up?" + ;; have a query or message up? + (or (= (gui-status active) (get-status *gui-control* (lookup-gui-connection-id *gui-control* (the string #f) (gui-channel query) (gui-action none)))) + (= (gui-status active) (get-status *gui-control* (lookup-gui-connection-id *gui-control* (the string #f) (gui-channel message) (gui-action none)))) + (= (gui-status active) (get-status *gui-control* (lookup-gui-connection-id *gui-control* (the string #f) (gui-channel notice-low) (gui-action none)))) + (= (gui-status active) (get-status *gui-control* (lookup-gui-connection-id *gui-control* "hud-race-final-stats" (gui-channel hud-middle-right) (gui-action none)))) + ) + ) + + +(defmethod clear-line ((obj subtitle3-queue-element)) + "make this queue element invalid" + + (set! (-> obj gui) #f) + (set! (-> obj id) (new 'static 'sound-id)) + 0) + +(defmethod clear-queue ((obj subtitle3)) + "mark all slots in the gui queue as available" + + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + (clear-line (-> obj queue i))) + 0) + +(defmethod update-gui-connections ((obj subtitle3)) + "mark all inactive slots in the gui queue as available" + + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + + (let ((gui (lookup-gui-connection *gui-control* (the process #f) (gui-channel none) (the string #f) (-> obj queue i id)))) + + (if (not (valid-subtitle-gui? gui)) + (clear-line (-> obj queue i))))) + 0) + +(defmethod gui-queued? ((obj subtitle3) (gui gui-connection)) + "return #t is the gui is in the queue" + + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + (if (= (-> gui id) (-> obj queue i id)) + (return #t))) + #f) + +(defmethod get-empty-queue ((obj subtitle3)) + "return the first available gui queue slot" + + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + (if (not (-> obj queue i gui)) + (return i))) + (format #t "ran out of subtitle queue slots!") + 0 + ) + +(defmethod add-to-queue ((obj subtitle3) (gui gui-connection)) + "add a gui connection to the first empty queue slot available" + + (let ((slot (get-empty-queue obj))) + (set! (-> obj queue slot id) (-> gui id)) + (set! (-> obj queue slot gui) gui)) + gui) + + +(defmethod set-params! ((obj subtitle3-line-queue-element) (line subtitle3-line) (y float)) + "set the parameters for this line queue element" + + (set! (-> obj line) line) + (set! (-> obj y) y) + 0) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; subtitle3 process and drawing! +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defun set-speaker-color ((speaker pc-subtitle3-speaker)) + "set the color for the speaker font color" + (let ((spk-col (-> *subtitle3-speaker-color-table* speaker))) + (set-font-color (font-color font-color-42) spk-col spk-col spk-col spk-col)) + speaker) + + +(defmethod get-active-subtitles ((obj subtitle3)) + "collect active subtitles and add them to the queue + if a gui connection is already in the queue, + it will stay in the same slot when it was first added" + + ;; todo + (-> *gui-control* engine) + (let ((current (-> *gui-control* engine alive-list-end prev0))) + (-> *gui-control* engine) + (let ((next (-> current prev0))) + (while (!= current (-> *gui-control* engine alive-list)) + (let ((gui-conn (the gui-connection current))) + (when (and (valid-subtitle-gui? gui-conn) + (not (gui-queued? obj gui-conn))) + + (add-to-queue obj gui-conn) + ) + ) + (set! current next) + (-> *gui-control* engine) + (set! next (-> next prev0)) + ) + ) + ) + 0) + + +(defmethod subtitle-format ((obj subtitle3) (line subtitle3-line)) + "format the string for a subtitle line to *temp-string*" + + (when (subtitle3-flags? line merge) + (if (and (-> obj movie-mode?) (< 0 (length (-> obj movie-line)))) + (set! (-> line text) (-> obj movie-line)) + (return (the string #f)))) + + (cond + ((= (pc-subtitle3-speaker none) (-> line speaker)) + ;; there's no speaker so who cares. + (string-format "~S" (-> line text))) + ((or (= #t (-> *pc-settings* subtitle-speaker?)) + (and (= 'auto (-> *pc-settings* subtitle-speaker?)) (subtitle3-flags? line offscreen))) + ;; there is a speaker and we do want it. + ;; we use color 42 which gets set at runtime to any color we want + (string-format "~42L~S:~0L ~S" (get-speaker *subtitle3-text* (-> line speaker)) (-> line text))) + (else + (string-format "~S" (-> line text))) + ) + *temp-string*) + +(defbehavior current-subtitle3-pos subtitle3 ((id sound-id)) + "get the str position for this sound id in a 30/sec measurement" + (if (and (-> self movie-mode?) (= id (-> self movie-gui id))) + (return (-> self movie-pos))) + (let ((pos (the float (current-str-pos id)))) + (if (< pos 0.0) -1.0 (/ pos (/ 1024.0 30))))) + + +(defbehavior setup-subtitle3-font subtitle3 ((font font-context)) + "setup a font and parameters for the subtitle3 subtitles." + + ;; set font settings. + (if (!= (language-enum japanese) (-> *setting-control* user-current subtitle-language)) + (set-scale! font (* 0.5 (-> *SUBTITLE3-bank* scale))) + (set-scale! font (* 0.5 (-> *SUBTITLE3-bank* scale) 1.2))) + (set-width! font (the int (* (-> *SUBTITLE3-bank* width) 0.91 512))) + (set-origin! font (the int (/ (- 512.0 (-> font width)) 2)) + (the int (* (if (-> self have-message?) 0.524 0.698) 416))) + (set-height! font (the int (* (-> *SUBTITLE3-bank* lines) 44))) + + ;; if we have the minimap, set the right border to 74.4% of screen width. shrink if larger than that. + ;; TODO scale this with aspect. + (when (and (-> self have-minimap?) + (< (get-screen-x 0.744) (+ (-> font width) (-> font origin x)))) + (let ((new-width (- (get-screen-x 0.744) (-> font origin x)))) + (set-scale! font (* (-> font scale) (/ (the float new-width) (-> font width)))) + (set-width! font new-width))) + ) + + +(defmethod draw-subtitles ((self subtitle3)) + "do the subtitle drawing" + + ;; check the gui queue for lines to add to the line queue + (let ((line-queue-old (if (zero? (-> self line-queue-idx)) (-> self lines 0) (-> self lines 1))) + (line-queue (if (zero? (-> self line-queue-idx)) (-> self lines 1) (-> self lines 0))) + + (find-line (lambda ((queue subtitle3-line-queue) (line subtitle3-line)) + (dotimes (i PC_SUBTITLE_MAX_LINES) + (if (= line (-> queue elts i line)) + (return i))) + -1))) + (logxor! (-> self line-queue-idx) 1) + ;; clear the queue we're writing to first + (dotimes (i PC_SUBTITLE_MAX_LINES) + (set-params! (-> line-queue elts i) (the subtitle3-line #f) PC_SUBTITLE_Y_RECALC) + ) + + ;; we won't be able to render any subtitles with no text loaded. + (when (not *subtitle3-text*) + (false! (-> self have-subtitles?)) + (return 0)) + + ;; font has already been set up in movie mode + (unless (-> self movie-mode?) + ;; set up our font to the initial parameters + (let ((map-gui (lookup-gui-connection *gui-control* (the process #f) (gui-channel hud-lower-right) "hud-map" (new 'static 'sound-id)))) + (set! (-> self have-message?) (or (subtitle-bump-up?) (and (-> self have-message?) (-> self have-subtitles?)))) + (set! (-> self have-minimap?) (and (logtest? (minimap-flag minimap) (-> *setting-control* user-current minimap)) + (!= map-gui #f) + (!= (gui-status pending) (get-status *gui-control* (-> map-gui id))) + (!= (gui-action hidden) (-> map-gui action)))) + ) + (setup-subtitle3-font (-> self font))) + + ;; do two passes - on the first one we add lines that were already being used, + ;; on the second pass we add new lines + (dotimes (q 2) + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + (when (-> self queue i gui) + (let ((pos (current-subtitle3-pos (-> self queue i id)))) + (when (and (zero? q) *debug-segment*) + (format *stdcon0* "subtitle pos: ~3L~D~0L (~S)~%" (the int pos) (-> self queue i gui name))) + + (let ((scene (get-scene-by-name *subtitle3-text* (-> self queue i gui name)))) + (when scene + (dotimes (ii PC_SUBTITLE_QUEUE_MAX_LINES) + (awhen (get-line-at-pos scene pos ii) + (case q + ((0) + (let ((index-in-old (find-line line-queue-old it))) + (when (!= -1 index-in-old) + ;; this line exists in the previous frame, put it in the new queue at the same spot + (set-params! (-> line-queue elts index-in-old) it (-> line-queue-old elts index-in-old y))))) + ((1) + (when (= -1 (find-line line-queue it)) + ;; line not in the queue. find empty spot. + (let ((index-empty (find-line line-queue (the subtitle3-line #f)))) + (if (!= -1 index-empty) + (set-params! (-> line-queue elts index-empty) it PC_SUBTITLE_Y_RECALC))) + )) + ) + ) + )) + ) + ) + ) + )) + + (let ((cur-y (-> self font origin y)) ;; the current y for the text + (start-y (-> self font origin y)) ;; the starting y for the text + (last-height 0.0) ;; the height of the previous subtitle + (this-height 0.0) ;; the height of the current subtitle + (lines-done 0) + (subtitles-drawn? #f) + ) + + (dotimes (i PC_SUBTITLE_QUEUE_MAX_LINES) + (when (and (-> line-queue elts i line) (subtitle-format self (-> line-queue elts i line))) + + (set! this-height (print-game-text *temp-string* (-> self font) #t 44 (bucket-id debug-no-zbuf2))) + + ;; push subtitle up since we are not the first one + (when (nonzero? lines-done) + (-! cur-y (/ last-height 2)) + (-! cur-y (/ this-height 2)) + ) + + ;; set the current y, it shall not be lower than the previous line! + (if (= (-> line-queue elts i y) PC_SUBTITLE_Y_RECALC) + (set! (-> line-queue elts i y) (- start-y cur-y)) + (set! cur-y (the float (min (the int cur-y) (the int (- start-y (-> line-queue elts i y))))))) + (set! (-> self font origin y) cur-y) + + ;; check if we should actually draw subtitles and do it + (when (and (if (-> self movie-mode?) (-> *setting-control* user-current subtitle) + (-> *pc-settings* hinttitles?)) + (or *gui-kick-str* (= *master-mode* 'game))) + (set-action! *gui-control* (gui-action play) (-> self gui-id) + (gui-channel none) (gui-action none) (the-as string #f) (the-as (function gui-connection symbol) #f) (the-as process #f)) + + (when (= (gui-status active) (get-status *gui-control* (-> self gui-id))) + (true! subtitles-drawn?) + (protect (*display-text-box*) + (set! *display-text-box* (or *display-text-box* PC_SUBTITLE_DEBUG)) + (set-speaker-color (-> line-queue elts i line speaker)) + (print-game-text *temp-string* (-> self font) #f 44 (bucket-id debug-no-zbuf2)))) + ) + + ;; save this for later usage + (set! last-height this-height) + (1+! lines-done) + ) + ) + + (set! (-> self have-subtitles?) subtitles-drawn?) + (when (not (-> self have-subtitles?)) + (set-action! *gui-control* (gui-action hidden) (-> self gui-id) + (gui-channel none) (gui-action none) (the-as string #f) (the-as (function gui-connection symbol) #f) (the-as process #f))) + + (set! (-> self font origin y) start-y))) + + 0) + +(when *debug-segment* +(defmethod debug-print-queue ((self subtitle3)) + "print the queue to *stdcon0*" + + (format *stdcon0* "q: ~%") + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + (if (-> self queue i gui) + (format *stdcon0* "~D: ~S ~3L~D~0L ~D ~`gui-connection`P~%" i + (-> self queue i gui name) + (the int (current-subtitle3-pos (-> self queue i id))) + (-> self queue i id) + (-> self queue i gui)))) + + (format *stdcon0* "l: ~%") + (let ((line-queue (if (zero? (-> self line-queue-idx)) (-> self lines 0) (-> self lines 1)))) + (dotimes (i PC_SUBTITLE_MAX_LINES) + (format *stdcon0* "~D: ~D ~S~%" i (the int (-> line-queue elts i y)) (aif (-> line-queue elts i line) (-> it text))))) + + 0) + +(defmethod debug-print-speakers ((self subtitle3)) + "print all speakers onscreen" + + (if (not *subtitle3-text*) + (return 0)) + + (let ((font (new 'stack 'font-context *font-default-matrix* 0 0 0.0 (font-color default) (font-flags shadow kerning large))) + (col-wid (/ 512.0 3))) + (set-width! font (the int col-wid)) + (set-height! font 44) + (set-scale! font 0.5) + + (dotimes (i (-> *subtitle3-text* speaker-length)) + (set-speaker-color (the pc-subtitle3-speaker i)) + (+! (-> font origin y) (print-game-text (string-format "~33L~S" (get-speaker *subtitle3-text* (the pc-subtitle3-speaker i))) + font #f 44 (bucket-id debug-no-zbuf2))) + (when (< 416.0 (-> font origin y)) + (set! (-> font origin y) 0.0) + (+! (-> font origin x) col-wid)) + )) + + 0) +) + +(defmethod start-gui ((self subtitle3)) + "start gui queueing" + (set! (-> self gui-id) (add-process *gui-control* self (gui-channel subtitle-pc) (gui-action hidden) "subtitle3" (meters 20) 0)) + ) + +(defmethod stop-gui ((self subtitle3)) + "stop gui queueing" + (set-action! *gui-control* (gui-action stop) (-> self gui-id) + (gui-channel none) + (gui-action none) + (the-as string #f) + (the-as (function gui-connection symbol) #f) + (the-as process #f)) + (set! (-> self gui-id) (new 'static 'sound-id)) + ) + +(defstate subtitle3-process (subtitle3) + + :event (behavior ((from process) (argc int) (msg symbol) (block event-message-block)) + (case msg + (('movie 'movie-no-subtitle) + ;; we are receiving parameters for a movie subtitle! + (when (not *subtitle3-text*) + (format 0 "movie subtitle: no text loaded~%") + (return #f)) + + (set! (-> self movie-gui) (lookup-gui-connection *gui-control* (the process #f) (gui-channel art-load) (the-as string (-> block param 0)) (new 'static 'sound-id))) + (when (not (-> self movie-gui)) + (format 0 "movie subtitle: no gui found~%") + (return #f)) + + (set! (-> self movie-mode?) #t) + (set! (-> self movie-pos) (the-as float (-> block param 2))) + + (when (!= msg 'movie-no-subtitle) + (copyn-charp<-string (-> self movie-line data) (the-as string (-> block param 1)) + (-> self movie-line allocated-length)) + (set! (-> self have-message?) #f) + (set! (-> self have-minimap?) #f) + (set! (-> self have-subtitles?) #f) + (setup-subtitle3-font (-> self font)) + ;; we're gonna use the same font as the movie subtitles + (set-origin! (-> self font) 20 290) + (set-width! (-> self font) 465) + (set-height! (-> self font) 70) + (set-scale! (-> self font) 0.5) + + (when (= (-> *setting-control* user-current subtitle-language) (language-enum korean)) + (set-scale! (-> self font) 0.6)) + ) + #t) + ) + ) + + :code (behavior () + (loop + (suspend)) + ) + + :trans (behavior () + (when *debug-segment* + (when (and (cpad-hold? 0 l3) (cpad-pressed? 0 r3)) + (cpad-clear! 0 r3) + (set! (-> self cheat-backup) *cheat-mode*) + (set! *cheat-mode* 'camera) + (set-master-mode 'pause) + (go subtitle3-debug) + ) + ) + + (load-level-subtitle3-files 0) + + ;; get subtitles + (cond + ((not (-> self movie-mode?)) + ;; get rid of invalid gui entries + (update-gui-connections self) + ;; queue up valid ones + (get-active-subtitles self) + ) + ((-> self movie-gui) + ;; wipe the queue + (clear-queue self) + ;; queue up the movie gui - this is the only one we want in movie mode + (add-to-queue self (-> self movie-gui)) + ) + (else + ;; something weird happened + (if *debug-segment* + (format #t "bad movie gui~%")) + (set! (-> self movie-mode?) #f) + (clear-queue self)) + ) + ) + + :post (behavior () + + (draw-subtitles self) + + (when *debug-segment* + (if *display-subtitle-speakers* + (debug-print-speakers self)) + (if PC_SUBTITLE_DEBUG + (debug-print-queue self)) + ) + + (when (-> self movie-mode?) + (set! (-> self movie-gui) #f) + (set! (-> self movie-mode?) #f) + (clear (-> self movie-line)) + ) + 0) + + ) + + +(defstate subtitle3-debug (subtitle3) + + :enter (behavior () + (process-mask-clear! (-> self mask) pause) + ) + :exit (behavior () + (unless (= (-> self next-state name) 'subtitle3-debug-checking-lines) + (process-mask-set! (-> self mask) pause)) + ) + + :trans (behavior () + + (with-dma-buffer-add-bucket ((buf (-> (current-frame) debug-buf)) + (bucket-id debug-no-zbuf2)) + + (draw-string-xy "~3LSUBTITLE DEBUG!~0L" buf 14 (+ PC_SUB_DBG_Y (* 0 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy "L3+R3: exit" buf 14 (+ PC_SUB_DBG_Y (* 1 15)) (font-color default) (font-flags shadow kerning)) + (if (!= 'pause *master-mode*) + (draw-string-xy "Pause the game to continue" buf 14 (+ PC_SUB_DBG_Y (* 2 15)) (font-color default) (font-flags shadow kerning))) + + (when (= 'pause *master-mode*) + ;(draw-string-xy "L3+X: debug lines" buf 14 (+ PC_SUB_DBG_Y (* 2 15)) (font-color default) (font-flags shadow kerning)) + ;(draw-string-xy "L3+Triangle: debug box" buf 14 (+ PC_SUB_DBG_Y (* 3 15)) (font-color default) (font-flags shadow kerning)) + + (cond + ((or (not *subtitle3-text*) (zero? (-> *subtitle3-text* length))) + (draw-string-xy "NO SUBTITLES LOADED!!!" buf 14 (+ PC_SUB_DBG_Y (* 10 15)) (font-color red) (font-flags shadow kerning)) + (load-level-subtitle3-files 0) + (set! (-> self current-debug-scene) 0) + (set! (-> self current-debug-line) 0) + ) + (else + + (cond + ((cpad-pressed? 0 square) + (true! (-> self checking-lines?)) + ) + ((cpad-pressed? 0 left) + (if (> (-> self current-debug-line) 0) + (1-! (-> self current-debug-line))) + ) + ((cpad-pressed? 0 right) + (if (< (-> self current-debug-line) (1- (-> *subtitle3-text* data (-> self current-debug-scene) length))) + (1+! (-> self current-debug-line))) + ) + ((or (cpad-pressed? 0 up) (and (cpad-hold? 0 l2) (cpad-hold? 0 up))) + (when (> (-> self current-debug-scene) 0) + (1-! (-> self current-debug-scene)) + (set! (-> self current-debug-line) 0)) + ) + ((or (cpad-pressed? 0 down) (and (cpad-hold? 0 l2) (cpad-hold? 0 down))) + (when (< (-> self current-debug-scene) (1- (-> *subtitle3-text* length))) + (1+! (-> self current-debug-scene)) + (set! (-> self current-debug-line) 0)) + ) + ) + + (let ((cur-scene (-> *subtitle3-text* data (-> self current-debug-scene)))) + (if (nonzero? (-> cur-scene length)) + (set! (-> self current-debug-subtitle) (-> *subtitle3-text* data (-> self current-debug-scene) lines (-> self current-debug-line))) + (set! (-> self current-debug-subtitle) #f)) + + (draw-string-xy "Up/down: Pick scene" buf 14 (+ PC_SUB_DBG_Y (* 4 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy "L2+Up/down: Pick scene (fast)" buf 14 (+ PC_SUB_DBG_Y (* 5 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy "Left/right: Pick line" buf 14 (+ PC_SUB_DBG_Y (* 6 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy "Square: Check all line heights" buf 14 (+ PC_SUB_DBG_Y (* 7 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy (string-format "Scene: ~D/~D (~S)" (1+ (-> self current-debug-scene)) (-> *subtitle3-text* length) (-> cur-scene name)) + buf 14 (+ PC_SUB_DBG_Y (* 8 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy (string-format "Line: ~D/~D" (1+ (-> self current-debug-line)) (-> cur-scene length)) + buf 14 (+ PC_SUB_DBG_Y (* 9 15)) (font-color default) (font-flags shadow kerning)) + ) + + ) + ) + )) + + (when (-> self checking-lines?) + (false! (-> self checking-lines?)) + (go subtitle3-debug-checking-lines) + ) + (when (and (cpad-hold? 0 l3) (cpad-pressed? 0 r3)) + (cpad-clear! 0 r3) + (set! *cheat-mode* (-> self cheat-backup)) + (set-master-mode 'game) + (go subtitle3-process) + ) + ) + + :code (-> subtitle3-process code) + :post (behavior () + (set! (-> self movie-mode?) #f) + (set! (-> self have-message?) #f) + (set! (-> self have-minimap?) #f) + (set! (-> self have-subtitles?) #f) + (setup-subtitle3-font (-> self font)) + (when (-> self current-debug-subtitle) + (set-speaker-color (-> self current-debug-subtitle speaker)) + (print-game-text (subtitle-format self (-> self current-debug-subtitle)) (-> self font) #f 44 (bucket-id debug-no-zbuf2)) + ) + 0) + + ) + +(defstate subtitle3-debug-checking-lines (subtitle3) + + :trans (behavior () + (set! (-> self movie-mode?) #f) + (set! (-> self have-message?) #f) + (set! (-> self have-minimap?) #f) + (set! (-> self have-subtitles?) #f) + (setup-subtitle3-font (-> self font)) + ) + + :code (behavior () + (protect ((-> *pc-settings* subtitle-speaker?)) + (set! (-> *pc-settings* subtitle-speaker?) #t) + (let ((lines-so-far 0) + (lines-this-frame 0) + (bad-lines 0)) + (dotimes (i (length *subtitle3-text*)) + (dotimes (ii (length (-> *subtitle3-text* data i))) + (when (= lines-this-frame PC_SUB_DBG_CHECK_GROUP_SIZE) + (set! lines-this-frame 0) + (suspend)) + + (1+! lines-this-frame) + (set! (-> self current-debug-subtitle) (-> *subtitle3-text* data i lines ii)) + (set-speaker-color (-> self current-debug-subtitle speaker)) + (when (< (* (-> *SUBTITLE3-bank* lines) 22) (print-game-text (subtitle-format self (-> self current-debug-subtitle)) (-> self font) #f 44 (bucket-id debug-no-zbuf2))) + (format 0 "ERROR: LINE ~D IN SCENE ~D IS TOO LARGE!~%" (1+ ii) (1+ i)) + (format #t "ERROR: LINE ~D IN SCENE ~D IS TOO LARGE!~%" (1+ ii) (1+ i)) + (1+! bad-lines) + ) + ) + ) + (suspend) + (if (> bad-lines 0) + (format 0 "error: ~D bad lines detected.~%" bad-lines) + (format 0 "no bad lines detected!~%" bad-lines)) + )) + (go subtitle3-debug) + ) + :post (behavior () + (with-dma-buffer-add-bucket ((buf (-> (current-frame) debug-buf)) + (bucket-id debug)) + (draw-string-xy "Checking for bad lines... See console for info" buf 14 PC_SUB_DBG_Y (font-color red) (font-flags shadow kerning)) + ) + (draw-debug-text-box (-> self font)) + 0) + + ) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; helper functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +(defmethod deactivate ((self subtitle3)) + + (stop-gui self) + ;; not sure this works... + (if (= (ppointer->process *subtitle3*) self) + (set! *subtitle3* #f)) + + ((method-of-type process deactivate) self) + (none) + ) + +(defbehavior subtitle3-init-by-other subtitle3 () + "external initializer for subtitle3 process" + + (process-mask-clear! (-> self mask) menu) + + (set! (-> self font) (new 'process 'font-context *font-default-matrix* + 0 0 0.0 (font-color default) (font-flags shadow kerning middle-vert middle large))) + (clear-queue self) + (dotimes (i PC_SUBTITLE_MAX_LINES) + (set! (-> self lines 0 elts i line) #f) + (set! (-> self lines 0 elts i y) PC_SUBTITLE_Y_RECALC) + (set! (-> self lines 1 elts i line) #f) + (set! (-> self lines 1 elts i y) PC_SUBTITLE_Y_RECALC) + ) + + (set! (-> self have-message?) #f) + (set! (-> self have-minimap?) #f) + (set! (-> self have-subtitles?) #f) + + (set! (-> self movie-mode?) #f) + (set! (-> self movie-line) (new 'process 'string (+ 7 (* 15 16)) (the string #f))) + + (set! (-> self current-debug-scene) 0) + (set! (-> self current-debug-line) 0) + (set! (-> self current-debug-subtitle) #f) + (set! (-> self checking-lines?) #f) + + (start-gui self) + + (go subtitle3-process) + ) + + +(defun subtitle3-stop () + "kill the subtitle3 process" + + (if *subtitle3* + (deactivate (ppointer->process *subtitle3*))) + *subtitle3*) + +(defun subtitle3-start () + "start the subtitle3 process" + + ;; fill the subtitle speaker table + (set-subtitle-speaker-colors) + + (if *subtitle3* + (subtitle3-stop)) + + (set! *subtitle3* (process-spawn subtitle3 :from *pc-dead-pool* :to *pc-pool*)) + ) + +;; start the subtitle3 process when this file loads. +(subtitle3-start) + + + diff --git a/goalc/data_compiler/game_text_common.cpp b/goalc/data_compiler/game_text_common.cpp index 6e2e015a994..1282af22a46 100644 --- a/goalc/data_compiler/game_text_common.cpp +++ b/goalc/data_compiler/game_text_common.cpp @@ -171,7 +171,11 @@ void compile_subtitles_v2(GameSubtitleDB& db, const std::string& output_prefix) for (const auto& [lang, bank] : db.m_banks) { auto font = get_font_bank(bank->m_text_version); DataObjectGenerator gen; - gen.add_type_tag("subtitle2-text-info"); // type + if (get_text_version_name(bank->m_text_version) == "jak3") { + gen.add_type_tag("subtitle3-text-info"); // type + } else { + gen.add_type_tag("subtitle2-text-info"); // type + } gen.add_word((bank->m_scenes.size() & 0xffff) | (1 << 16)); // length (lo) + version (hi) // note: we add 1 because "none" isn't included gen.add_word((lang & 0xffff) | ((bank->m_speakers.size() + 1) << 16)); // lang + speaker-length @@ -220,9 +224,10 @@ void compile_subtitles_v2(GameSubtitleDB& db, const std::string& output_prefix) auto data = gen.generate_v2(); file_util::create_dir_if_needed(file_util::get_file_path({"out", output_prefix, "iso"})); + auto file_name = get_text_version_name(bank->m_text_version) == "jak3" ? "subti3" : "subti2"; file_util::write_binary_file( file_util::get_file_path( - {"out", output_prefix, "iso", fmt::format("{}{}.TXT", lang, uppercase("subti2"))}), + {"out", output_prefix, "iso", fmt::format("{}{}.TXT", lang, uppercase(file_name))}), data.data(), data.size()); } } diff --git a/test/decompiler/reference/jak3/decompiler-macros.gc b/test/decompiler/reference/jak3/decompiler-macros.gc index 6fc7f55c9ee..a8875a6bbb1 100644 --- a/test/decompiler/reference/jak3/decompiler-macros.gc +++ b/test/decompiler/reference/jak3/decompiler-macros.gc @@ -989,7 +989,7 @@ (with-gensyms (new-proc) `(let ((,new-proc (the-as ,proc-type (get-process ,from ,proc-type ,stack-size ,unk)))) (when ,new-proc - ((method-of-type ,proc-type activate) ,new-proc ,to ,(if name name `(symbol->string ,proc-type)) ,stack) + ((method-of-type ,proc-type activate) ,new-proc ,to ,(if name name `(symbol->string ',proc-type)) ,stack) (run-now-in-process ,new-proc ,(if init init (string->symbol (fmt #f "{}-init-by-other" proc-type))) ,@args) (the (pointer ,proc-type) (-> ,new-proc ppointer)) ) diff --git a/test/decompiler/reference/jak3/engine/gfx/font-h_REF.gc b/test/decompiler/reference/jak3/engine/gfx/font-h_REF.gc index 0ca4eecc4fb..b6231ed637f 100644 --- a/test/decompiler/reference/jak3/engine/gfx/font-h_REF.gc +++ b/test/decompiler/reference/jak3/engine/gfx/font-h_REF.gc @@ -766,13 +766,17 @@ ) ;; definition for function set-font-color -(defun set-font-color ((arg0 font-color) (arg1 int) (arg2 rgba) (arg3 rgba) (arg4 rgba)) - (set! (-> *font-work* color-table arg0 color 0) (the-as rgba arg1)) - (set! (-> *font-work* color-table arg0 color 1) arg2) - (set! (-> *font-work* color-table arg0 color 2) arg3) - (set! (-> *font-work* color-table arg0 color 3) arg4) +(defun set-font-color ((idx font-color) (clr0 rgba) (clr1 rgba) (clr2 rgba) (clr3 rgba)) + (set! (-> *font-work* color-table idx color 0) clr0) + (set! (-> *font-work* color-table idx color 1) clr1) + (set! (-> *font-work* color-table idx color 2) clr2) + (set! (-> *font-work* color-table idx color 3) clr3) 0 ) ;; failed to figure out what this is: 0 + + + + diff --git a/test/decompiler/reference/jak3/engine/ui/progress/progress-draw_REF.gc b/test/decompiler/reference/jak3/engine/ui/progress/progress-draw_REF.gc index 1f54acdf13c..50f0179c58c 100644 --- a/test/decompiler/reference/jak3/engine/ui/progress/progress-draw_REF.gc +++ b/test/decompiler/reference/jak3/engine/ui/progress/progress-draw_REF.gc @@ -158,14 +158,14 @@ (if (< (seconds 0.027) (logand (-> pp clock integral-frame-counter) 15)) (set-font-color (the-as font-color gp-0) - (the-as int (the-as uint #x80ffffff)) + (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) ) (set-font-color (the-as font-color gp-0) - (the-as int (the-as uint #x80606060)) + (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) @@ -5245,3 +5245,7 @@ 0 (none) ) + + + +