jak3: subtitle3, vag-player (#3758)

This commit is contained in:
Hat Kid
2024-11-12 02:45:16 +01:00
committed by GitHub
parent b55a918902
commit af5cb9b1cb
48 changed files with 12292 additions and 126 deletions
+6 -2
View File
@@ -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,
+1 -1
View File
@@ -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 ;;
+1 -1
View File
@@ -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,
+234 -1
View File
@@ -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"]
}
}
+1 -1
View File
@@ -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');
+6 -6
View File
@@ -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;
}
+65 -38
View File
@@ -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": {}
}
+1 -1
View File
@@ -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
/*
+42
View File
@@ -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;
}
+1
View File
@@ -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;
}
+1 -1
View File
@@ -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)))
+3
View File
@@ -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)
+5 -5
View File
@@ -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
)
+9 -1
View File
@@ -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))
+12 -1
View File
@@ -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)
+2 -2
View File
@@ -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*)
+5
View File
@@ -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))
+1 -2
View File
@@ -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))
)
+33 -35
View File
@@ -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*
+456
View File
@@ -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)
+381
View File
@@ -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)
)
+885
View File
@@ -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)
+7 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
)