mirror of
https://github.com/open-goal/jak-project
synced 2026-07-07 14:13:45 -04:00
jak3: subtitle3, vag-player (#3758)
This commit is contained in:
@@ -61,7 +61,10 @@ const std::unordered_map<GameVersion, std::vector<std::string>> 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<GameVersion, std::vector<int>> 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) {
|
||||
|
||||
@@ -93,6 +93,55 @@ const std::unordered_map<std::string, u16> 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<std::string, u16> 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<std::string> GameSubtitleBank::speaker_names_ordered_by_enum_value() {
|
||||
// Create a temporary vector of pairs (key, value)
|
||||
std::vector<std::pair<std::string, u16>> temp_vec(jak2_speaker_name_to_enum_val.begin(),
|
||||
jak2_speaker_name_to_enum_val.end());
|
||||
std::vector<std::pair<std::string, u16>> 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<std::string> 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<std::string, u16> 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,
|
||||
|
||||
@@ -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 ;;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -2141,5 +2141,8 @@
|
||||
"a2-1": ["a2-1", "uint"],
|
||||
"a3-0": ["a3-0", "uint"]
|
||||
}
|
||||
},
|
||||
"set-font-color": {
|
||||
"args": ["idx", "clr0", "clr1", "clr2", "clr3"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"cutscenes": {},
|
||||
"other": {}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"cutscenes": {},
|
||||
"other": {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"cutscenes": {},
|
||||
"other": {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"cutscenes": {},
|
||||
"other": {}
|
||||
}
|
||||
@@ -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
|
||||
/*
|
||||
|
||||
@@ -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<char, 9> 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<u64>)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<u64>(s7.offset) + true_symbol_offset(g_game_version) : s7.offset;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ Ptr<Type> 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> type, u32 method_id, u32 a1, u32 a2);
|
||||
u64 alloc_heap_memory(u32 heap, u32 size);
|
||||
template <typename T>
|
||||
Ptr<Ptr<String>> sym_to_string_ptr(Ptr<Symbol4<T>> in) {
|
||||
return Ptr<Ptr<String>>(SymbolString.offset + in.offset - s7.offset);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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*)
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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))
|
||||
)
|
||||
|
||||
@@ -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<?))
|
||||
#t)
|
||||
|
||||
;; ;; sort by vag name - note: already sorted from before
|
||||
;; ;(set! (-> menu items) (sort (-> menu items) debug-menu-node<?))
|
||||
;; #t)
|
||||
|
||||
;; (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)
|
||||
;; )
|
||||
;; )
|
||||
(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*
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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))
|
||||
)
|
||||
|
||||
+9
-5
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+6
-2
@@ -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)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user