mirror of
https://github.com/open-goal/jak-project.git
synced 2024-11-27 00:10:31 +00:00
Jak 2 pc subtitle support (#2672)
Adds support for adding custom subtitles to Jak 2 audio. Comes with a new editor for the new system and format. Compared to the Jak 1 system, this is much simpler to make an editor for. Comes with a few subtitles already made as an example. Cutscenes are not officially supported but you can technically subtitle those with editor, so please don't right now. This new system supports multiple subtitles playing at once (even from a single source!) and will smartly push the subtitles up if there's a message already playing: ![image](https://github.com/open-goal/jak-project/assets/7569514/033e6374-a05a-4c31-b029-51868153a932) ![image](https://github.com/open-goal/jak-project/assets/7569514/5298aa6d-a183-446e-bdb6-61c4682df917) Unlike in Jak 1, it will not hide the bottom HUD when subtitles are active: ![image](https://github.com/open-goal/jak-project/assets/7569514/d466bfc0-55d0-4689-a6e1-b7784b9fff59) Sadly this leaves us with not much space for the subtitle region (and the subtitles are shrunk when the minimap is enabled) but when you have guards and citizens talking all the time, hiding the HUD every time anyone spoke would get really frustrating. The subtitle speaker is also color-coded now, because I thought that would be fun to do. TODO: - [x] proper cutscene support. - [x] merge mode for cutscenes so we don't have to rewrite the script? --------- Co-authored-by: Hat Kid <6624576+Hat-Kid@users.noreply.github.com>
This commit is contained in:
parent
3dbaee1ecc
commit
18ddd1613c
1
.gitignore
vendored
1
.gitignore
vendored
@ -74,3 +74,4 @@ __pycache__/
|
||||
/jak1-*.json
|
||||
/jak2-*.json
|
||||
/TODO.md
|
||||
unifont-15.0.03.ttf
|
||||
|
@ -114,7 +114,7 @@
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
"projectTarget": "gk.exe (bin\\gk.exe)",
|
||||
"name": "Game - Jak 2 - Runtime",
|
||||
"name": "Game - Jak 2 - Runtime (no boot)",
|
||||
"args": ["-v", "--game", "jak2", "--", "-fakeiso", "-debug"]
|
||||
},
|
||||
{
|
||||
@ -124,6 +124,13 @@
|
||||
"name": "Game - Jak 2 - Runtime (boot)",
|
||||
"args": ["-v", "--game", "jak2", "--", "-boot", "-fakeiso", "-debug"]
|
||||
},
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
"projectTarget": "gk.exe (bin\\gk.exe)",
|
||||
"name": "Game - Jak 2 - Runtime (release)",
|
||||
"args": ["-v", "--game", "jak2", "--", "-boot", "-fakeiso"]
|
||||
},
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
|
@ -53,6 +53,8 @@ add_library(common
|
||||
repl/util.cpp
|
||||
serialization/subtitles/subtitles_deser.cpp
|
||||
serialization/subtitles/subtitles_ser.cpp
|
||||
serialization/subtitles2/subtitles2_deser.cpp
|
||||
serialization/subtitles2/subtitles2_ser.cpp
|
||||
type_system/defenum.cpp
|
||||
type_system/deftype.cpp
|
||||
type_system/state.cpp
|
||||
|
27
common/serialization/subtitles2/subtitles2_deser.cpp
Normal file
27
common/serialization/subtitles2/subtitles2_deser.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "subtitles2_deser.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
#include "third-party/json.hpp"
|
||||
|
||||
const std::vector<std::string> locale_lookup = {"en-US", "fr-FR", "de-DE", "es-ES",
|
||||
"it-IT", "jp-JP", "ko-KR", "en-GB"};
|
||||
|
||||
bool write_subtitle_db_to_files(const GameSubtitle2DB& db, const GameVersion game_version) {
|
||||
try {
|
||||
for (const auto& [language_id, bank] : db.m_banks) {
|
||||
json data;
|
||||
to_json(data, *bank);
|
||||
std::string dump_path = (file_util::get_jak_project_dir() / "game" / "assets" /
|
||||
version_to_game_name(game_version) / "subtitle" /
|
||||
fmt::format("subtitle_{}.json", locale_lookup.at(language_id)))
|
||||
.string();
|
||||
file_util::write_text_file(dump_path, data.dump(2));
|
||||
}
|
||||
} catch (std::exception& ex) {
|
||||
lg::error(ex.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
5
common/serialization/subtitles2/subtitles2_deser.h
Normal file
5
common/serialization/subtitles2/subtitles2_deser.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/serialization/subtitles2/subtitles2_ser.h"
|
||||
|
||||
bool write_subtitle_db_to_files(const GameSubtitle2DB& db, const GameVersion game_version);
|
192
common/serialization/subtitles2/subtitles2_ser.cpp
Normal file
192
common/serialization/subtitles2/subtitles2_ser.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
#include "subtitles2_ser.h"
|
||||
|
||||
#include "common/goos/ParseHelpers.h"
|
||||
#include "common/goos/Reader.h"
|
||||
#include "common/log/log.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
#include "common/util/json_util.h"
|
||||
|
||||
// matches enum in `subtitle2.gc` with "none" (first) and "max" (last) removed
|
||||
const std::vector<std::string> s_speakers_jak2 = {
|
||||
"computer",
|
||||
"jak",
|
||||
"darkjak",
|
||||
"daxter",
|
||||
"samos",
|
||||
"keira",
|
||||
"keira-before-class-3",
|
||||
"kid",
|
||||
"kor",
|
||||
"metalkor",
|
||||
"baron",
|
||||
"errol",
|
||||
"torn",
|
||||
"tess",
|
||||
"guard",
|
||||
"guard-a",
|
||||
"guard-b",
|
||||
"krew",
|
||||
"sig",
|
||||
"brutter",
|
||||
"vin",
|
||||
"youngsamos",
|
||||
"youngsamos-before-rescue",
|
||||
"pecker",
|
||||
"onin",
|
||||
"ashelin",
|
||||
"jinx",
|
||||
"mog",
|
||||
"grim",
|
||||
"agent",
|
||||
"citizen-male",
|
||||
"citizen-female",
|
||||
"oracle",
|
||||
"precursor",
|
||||
};
|
||||
|
||||
const std::vector<std::string> get_speaker_names(GameVersion version) {
|
||||
switch (version) {
|
||||
case GameVersion::Jak2:
|
||||
return s_speakers_jak2;
|
||||
break;
|
||||
}
|
||||
throw std::runtime_error(
|
||||
fmt::format("no speakers for game version {} project", version_to_game_name(version)));
|
||||
}
|
||||
|
||||
void parse_subtitle2_json(GameSubtitle2DB& db, const GameSubtitle2DefinitionFile& file_info) {
|
||||
// TODO - some validation
|
||||
// Init Settings
|
||||
std::shared_ptr<GameSubtitle2Bank> bank;
|
||||
try {
|
||||
if (!db.bank_exists(file_info.language_id)) {
|
||||
// database has no lang yet
|
||||
bank = db.add_bank(std::make_shared<GameSubtitle2Bank>(file_info.language_id));
|
||||
} else {
|
||||
bank = db.bank_by_id(file_info.language_id);
|
||||
}
|
||||
bank->text_version = file_info.text_version;
|
||||
bank->file_path = file_info.file_path;
|
||||
// Parse the file
|
||||
auto file = parse_commented_json(
|
||||
file_util::read_text_file(file_util::get_jak_project_dir() / file_info.file_path),
|
||||
"subtitle2_json");
|
||||
from_json(file, *bank);
|
||||
} catch (std::exception& e) {
|
||||
lg::error("Unable to parse subtitle json entry, couldn't successfully load files - {}",
|
||||
e.what());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void to_json(json& j, const Subtitle2Line& obj) {
|
||||
j = json{{"start", obj.start}, {"end", obj.end}, {"offscreen", obj.offscreen},
|
||||
{"merge", obj.merge}, {"speaker", obj.speaker}, {"text", obj.text}};
|
||||
}
|
||||
void from_json(const json& j, Subtitle2Line& obj) {
|
||||
json_deserialize_if_exists(start);
|
||||
json_deserialize_if_exists(end);
|
||||
json_deserialize_if_exists(offscreen);
|
||||
json_deserialize_if_exists(merge);
|
||||
json_deserialize_if_exists(speaker);
|
||||
json_deserialize_if_exists(text);
|
||||
}
|
||||
void to_json(json& j, const Subtitle2Scene& obj) {
|
||||
j = json{{"scene", obj.scene}};
|
||||
json lines;
|
||||
for (const auto& line : obj.lines) {
|
||||
json l;
|
||||
to_json(l, line);
|
||||
lines.push_back(l);
|
||||
}
|
||||
j["lines"] = obj.lines.size() == 0 ? json::array({}) : lines;
|
||||
}
|
||||
void from_json(const json& j, Subtitle2Scene& obj) {
|
||||
json_deserialize_if_exists(scene);
|
||||
for (auto& kv : j.at("lines").items()) {
|
||||
auto& line = obj.lines.emplace_back();
|
||||
from_json(kv.value(), line);
|
||||
}
|
||||
}
|
||||
void to_json(json& j, const GameSubtitle2Bank& obj) {
|
||||
j = json{{"speakers", obj.speakers}, {"lang", obj.lang}};
|
||||
json scenes = json::object({});
|
||||
for (const auto& [name, scene] : obj.scenes) {
|
||||
json s;
|
||||
to_json(s, scene);
|
||||
scenes[name] = s;
|
||||
}
|
||||
j["scenes"] = scenes;
|
||||
}
|
||||
void from_json(const json& j, GameSubtitle2Bank& obj) {
|
||||
json_deserialize_if_exists(speakers);
|
||||
for (auto& kv : j.at("scenes").items()) {
|
||||
Subtitle2Scene scene;
|
||||
from_json(kv.value(), scene);
|
||||
obj.scenes[kv.key()] = scene;
|
||||
}
|
||||
json_deserialize_if_exists(lang);
|
||||
}
|
||||
|
||||
void open_subtitle2_project(const std::string& kind,
|
||||
const std::string& filename,
|
||||
std::vector<GameSubtitle2DefinitionFile>& subtitle_files) {
|
||||
goos::Reader reader;
|
||||
auto& proj = reader.read_from_file({filename}).as_pair()->cdr.as_pair()->car;
|
||||
if (!proj.is_pair() || !proj.as_pair()->car.is_symbol() ||
|
||||
proj.as_pair()->car.as_symbol()->name != kind) {
|
||||
throw std::runtime_error(fmt::format("invalid {} project", kind));
|
||||
}
|
||||
|
||||
goos::for_each_in_list(proj.as_pair()->cdr, [&](const goos::Object& o) {
|
||||
if (o.is_pair() && o.as_pair()->cdr.is_pair()) {
|
||||
auto args = o.as_pair();
|
||||
auto& action = args->car.as_symbol()->name;
|
||||
args = args->cdr.as_pair();
|
||||
|
||||
if (action == "file-json") {
|
||||
GameSubtitle2DefinitionFile new_file;
|
||||
while (true) {
|
||||
const auto& kwarg = args->car.as_symbol()->name;
|
||||
args = args->cdr.as_pair();
|
||||
if (kwarg == ":language-id") {
|
||||
new_file.language_id = args->car.as_int();
|
||||
} else if (kwarg == ":text-version") {
|
||||
new_file.text_version = get_text_version_from_name(args->car.as_string()->data);
|
||||
} else if (kwarg == ":data") {
|
||||
new_file.file_path = args->car.as_string()->data;
|
||||
}
|
||||
if (args->cdr.is_empty_list()) {
|
||||
break;
|
||||
}
|
||||
args = args->cdr.as_pair();
|
||||
}
|
||||
subtitle_files.push_back(new_file);
|
||||
} else {
|
||||
throw std::runtime_error(fmt::format("unknown action {} in {} project", action, kind));
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error(fmt::format("invalid entry in {} project", kind));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GameSubtitle2DB load_subtitle2_project(GameVersion game_version) {
|
||||
// Load the subtitle files
|
||||
GameSubtitle2DB db(game_version);
|
||||
try {
|
||||
goos::Reader reader;
|
||||
std::vector<GameSubtitle2DefinitionFile> files;
|
||||
std::string subtitle_project = (file_util::get_jak_project_dir() / "game" / "assets" /
|
||||
version_to_game_name(game_version) / "game_subtitle.gp")
|
||||
.string();
|
||||
open_subtitle2_project("subtitle2", subtitle_project, files);
|
||||
for (auto& file : files) {
|
||||
parse_subtitle2_json(db, file);
|
||||
}
|
||||
} catch (std::runtime_error& e) {
|
||||
lg::error("error loading subtitle project: {}", e.what());
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
107
common/serialization/subtitles2/subtitles2_ser.h
Normal file
107
common/serialization/subtitles2/subtitles2_ser.h
Normal file
@ -0,0 +1,107 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/util/Assert.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
#include "common/util/FontUtils.h"
|
||||
#include "common/util/json_util.h"
|
||||
#include "common/versions/versions.h"
|
||||
|
||||
const std::vector<std::string> get_speaker_names(GameVersion version);
|
||||
|
||||
struct Subtitle2Line {
|
||||
Subtitle2Line() {}
|
||||
Subtitle2Line(float start,
|
||||
float end,
|
||||
const std::string& text,
|
||||
const std::string& speaker,
|
||||
bool offscreen,
|
||||
bool merge)
|
||||
: start(start), end(end), text(text), speaker(speaker), offscreen(offscreen), merge(merge) {}
|
||||
|
||||
float start, end;
|
||||
|
||||
std::string text;
|
||||
|
||||
// name in enum. saved as int later.
|
||||
std::string speaker;
|
||||
|
||||
bool offscreen, merge;
|
||||
|
||||
bool operator<(const Subtitle2Line& other) const {
|
||||
return (start < other.start) || (start == other.start && end < other.end);
|
||||
}
|
||||
};
|
||||
void to_json(json& j, const Subtitle2Line& obj);
|
||||
void from_json(const json& j, Subtitle2Line& obj);
|
||||
|
||||
struct Subtitle2Scene {
|
||||
bool scene = false;
|
||||
|
||||
std::vector<Subtitle2Line> lines;
|
||||
};
|
||||
void to_json(json& j, const Subtitle2Scene& obj);
|
||||
void from_json(const json& j, Subtitle2Scene& obj);
|
||||
|
||||
struct GameSubtitle2Bank {
|
||||
GameSubtitle2Bank(int lang) : lang(lang) {}
|
||||
|
||||
int lang;
|
||||
|
||||
GameTextVersion text_version = GameTextVersion::JAK2;
|
||||
std::string file_path;
|
||||
|
||||
std::map<std::string, std::string> speakers;
|
||||
std::map<std::string, Subtitle2Scene> scenes;
|
||||
|
||||
bool scene_exists(const std::string& name) const { return scenes.find(name) != scenes.end(); }
|
||||
void add_scene(const std::string& name, Subtitle2Scene& scene) {
|
||||
ASSERT(!scene_exists(name));
|
||||
scenes.insert({name, scene});
|
||||
}
|
||||
};
|
||||
void to_json(json& j, const GameSubtitle2Bank& obj);
|
||||
void from_json(const json& j, GameSubtitle2Bank& obj);
|
||||
|
||||
class GameSubtitle2DB {
|
||||
public:
|
||||
GameSubtitle2DB(GameVersion version) : m_version(version) {}
|
||||
|
||||
const std::map<int, std::shared_ptr<GameSubtitle2Bank>>& banks() const { return m_banks; }
|
||||
|
||||
bool bank_exists(int id) const { return m_banks.find(id) != m_banks.end(); }
|
||||
|
||||
std::shared_ptr<GameSubtitle2Bank> add_bank(std::shared_ptr<GameSubtitle2Bank> bank) {
|
||||
ASSERT(!bank_exists(bank->lang));
|
||||
m_banks[bank->lang] = bank;
|
||||
return bank;
|
||||
}
|
||||
std::shared_ptr<GameSubtitle2Bank> bank_by_id(int id) {
|
||||
if (!bank_exists(id)) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_banks.at(id);
|
||||
}
|
||||
|
||||
std::map<int, std::shared_ptr<GameSubtitle2Bank>> m_banks;
|
||||
std::unique_ptr<GameSubtitle2Bank> m_subtitle_groups;
|
||||
|
||||
GameVersion version() const { return m_version; }
|
||||
|
||||
private:
|
||||
GameVersion m_version;
|
||||
};
|
||||
|
||||
struct GameSubtitle2DefinitionFile {
|
||||
std::string file_path = "";
|
||||
int language_id = -1;
|
||||
GameTextVersion text_version = GameTextVersion::JAK2;
|
||||
};
|
||||
|
||||
void parse_subtitle2_json(GameSubtitle2DB& db, const GameSubtitle2DefinitionFile& file_info);
|
||||
void open_subtitle2_project(const std::string& kind,
|
||||
const std::string& filename,
|
||||
std::vector<GameSubtitle2DefinitionFile>& inputs);
|
||||
GameSubtitle2DB load_subtitle2_project(GameVersion game_version);
|
@ -42,6 +42,10 @@ const std::string& get_text_version_name(GameTextVersion version) {
|
||||
throw std::runtime_error(fmt::format("invalid text version {}", fmt::underlying(version)));
|
||||
}
|
||||
|
||||
GameTextVersion get_text_version_from_name(const std::string& name) {
|
||||
return sTextVerEnumMap.at(name);
|
||||
}
|
||||
|
||||
GameTextFontBank::GameTextFontBank(GameTextVersion version,
|
||||
std::vector<EncodeInfo>* encode_info,
|
||||
std::vector<ReplaceInfo>* replace_info,
|
||||
@ -105,7 +109,7 @@ const EncodeInfo* GameTextFontBank::find_encode_to_game(const std::string& in, i
|
||||
}
|
||||
|
||||
/*!
|
||||
* Finds a remap info that best matches the byte sequence (is the longest match).
|
||||
* Finds a remap info that best matches the character sequence (is the longest match).
|
||||
*/
|
||||
const ReplaceInfo* GameTextFontBank::find_replace_to_utf8(const std::string& in, int off) const {
|
||||
const ReplaceInfo* best_info = nullptr;
|
||||
@ -113,14 +117,8 @@ const ReplaceInfo* GameTextFontBank::find_replace_to_utf8(const std::string& in,
|
||||
if (info.from.empty() || in.size() - off < info.from.size())
|
||||
continue;
|
||||
|
||||
bool found = true;
|
||||
for (int i = 0; found && i < (int)info.from.size(); ++i) {
|
||||
if (in.at(i + off) != info.from.at(i)) {
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (found && (!best_info || info.to.length() > best_info->to.length())) {
|
||||
bool found = memcmp(in.data() + off, info.from.data(), info.from.size()) == 0;
|
||||
if (found && (!best_info || info.from.length() > best_info->from.length())) {
|
||||
best_info = &info;
|
||||
}
|
||||
}
|
||||
@ -133,16 +131,10 @@ const ReplaceInfo* GameTextFontBank::find_replace_to_utf8(const std::string& in,
|
||||
const ReplaceInfo* GameTextFontBank::find_replace_to_game(const std::string& in, int off) const {
|
||||
const ReplaceInfo* best_info = nullptr;
|
||||
for (auto& info : *m_replace_info) {
|
||||
if (info.to.length() == 0 || in.size() - off < info.to.size())
|
||||
if (info.to.empty() || in.size() - off < info.to.size())
|
||||
continue;
|
||||
|
||||
bool found = true;
|
||||
for (int i = 0; found && i < (int)info.to.length(); ++i) {
|
||||
if (in.at(i + off) != info.to.at(i)) {
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool found = memcmp(in.data() + off, info.to.data(), info.to.size()) == 0;
|
||||
if (found && (!best_info || info.to.length() > best_info->to.length())) {
|
||||
best_info = &info;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ enum class GameTextVersion {
|
||||
extern const std::unordered_map<std::string, GameTextVersion> sTextVerEnumMap;
|
||||
|
||||
const std::string& get_text_version_name(GameTextVersion version);
|
||||
GameTextVersion get_text_version_from_name(const std::string& name);
|
||||
|
||||
/*!
|
||||
* What bytes a set of characters (UTF-8) correspond to. You can convert to and fro.
|
||||
|
@ -107,6 +107,14 @@ bool replace(std::string& str, const std::string& from, const std::string& to) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string lower(const std::string& str) {
|
||||
std::string res;
|
||||
for (auto c : str) {
|
||||
res.push_back(tolower(c));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string uuid() {
|
||||
static std::random_device dev;
|
||||
static std::mt19937 rng(dev());
|
||||
|
@ -21,6 +21,7 @@ std::vector<std::string> split(const ::std::string& str, char delimiter = '\n');
|
||||
std::string join(const std::vector<std::string>& strs, const std::string& join_with);
|
||||
std::vector<std::string> regex_get_capture_groups(const std::string& str, const std::string& regex);
|
||||
bool replace(std::string& str, const std::string& from, const std::string& to);
|
||||
std::string lower(const std::string& str);
|
||||
std::string uuid();
|
||||
std::string repeat(size_t n, const std::string& str);
|
||||
std::string current_local_timestamp();
|
||||
|
@ -13063,37 +13063,29 @@
|
||||
(defenum continue-flags
|
||||
:type uint32
|
||||
:bitfield #t
|
||||
(cf0 0)
|
||||
(cf1 1)
|
||||
(cf2 2)
|
||||
(cf3 3)
|
||||
(cf4 4)
|
||||
(cf5 5)
|
||||
(cf6 6)
|
||||
(cf7 7)
|
||||
(cf8 8)
|
||||
(cf9 9)
|
||||
(cf10 10)
|
||||
(cf11 11)
|
||||
(cf12 12)
|
||||
(cf13 13)
|
||||
(cf14 14)
|
||||
(cf15 15)
|
||||
(cf16 16)
|
||||
(cf17 17)
|
||||
(cf18 18)
|
||||
(cf19 19)
|
||||
(cf20 20)
|
||||
(cf21 21)
|
||||
(cf22 22)
|
||||
(cf23 23)
|
||||
(cf24 24)
|
||||
(cf25 25)
|
||||
(cf26 26)
|
||||
(cf27 27)
|
||||
(cf28 28)
|
||||
(cf29 29)
|
||||
(cf30 30)
|
||||
;(continue-flag-0 0)
|
||||
(scene-wait 1)
|
||||
(change-continue 2)
|
||||
(no-auto 3)
|
||||
(no-blackout 4)
|
||||
(game-start 5)
|
||||
(demo-end 6)
|
||||
(warp-gate 7)
|
||||
(demo 8)
|
||||
(intro 9)
|
||||
(hero-mode 10)
|
||||
(demo-movie 11)
|
||||
(title 12)
|
||||
(title-movie 13)
|
||||
(continue-flag-14 14)
|
||||
(continue-flag-15 15)
|
||||
(continue-flag-16 16)
|
||||
(test 17)
|
||||
(record-path 18)
|
||||
(pilot 19)
|
||||
(pilot-dax 20)
|
||||
(record-sig 21)
|
||||
(indax 22)
|
||||
)
|
||||
|
||||
(deftype continue-point (basic)
|
||||
@ -13367,6 +13359,7 @@
|
||||
(subtitle 69)
|
||||
(supertitle 70)
|
||||
(notice-low 71)
|
||||
(subtitle-pc 78) ;; custom
|
||||
(screen 79)
|
||||
(hud-upper-right 80)
|
||||
(hud-upper-left 81)
|
||||
@ -13441,7 +13434,7 @@
|
||||
(stop-str (_type_ gui-connection) int 11)
|
||||
(gui-control-method-12 (_type_ process gui-channel gui-action string int float sound-id) sound-id 12)
|
||||
(update (_type_ symbol) int 13)
|
||||
(lookup-gui-connection-id (_type_ string gui-channel gui-action) int 14)
|
||||
(lookup-gui-connection-id (_type_ string gui-channel gui-action) sound-id 14)
|
||||
(lookup-gui-connection (_type_ process gui-channel string sound-id) gui-connection 15)
|
||||
(set-action! (_type_ gui-action sound-id gui-channel gui-action string (function gui-connection symbol) process) int 16)
|
||||
(get-status (_type_ sound-id) gui-status 17)
|
||||
@ -30209,7 +30202,7 @@
|
||||
(define-extern entity-by-name (function string entity))
|
||||
(define-extern entity-by-type (function type entity-actor))
|
||||
(define-extern entity-by-aid (function uint entity))
|
||||
(define-extern entity-actor-from-level-name (function level entity-actor))
|
||||
(define-extern entity-actor-from-level-name (function symbol entity-actor))
|
||||
(define-extern entity-nav-mesh-by-aid (function actor-id entity-nav-mesh))
|
||||
(define-extern nav-mesh-from-res-tag (function entity symbol int nav-mesh))
|
||||
(define-extern entity-by-meters (function float float float entity-actor))
|
||||
@ -30227,7 +30220,7 @@
|
||||
(define-extern *pid-string* string)
|
||||
(define-extern debug-actor (function string none))
|
||||
(define-extern draw-actor-marks (function process none))
|
||||
(define-extern init-entity (function process entity-actor process none))
|
||||
(define-extern init-entity (function process entity-actor type none))
|
||||
;; (define-extern entity-deactivate-handler function) ;; (function process entity-actor none)
|
||||
(define-extern check-for-rougue-process (function process int int level none))
|
||||
(define-extern process-drawable-scale-from-entity! (function process-drawable entity none))
|
||||
@ -32779,7 +32772,7 @@
|
||||
(enemy-flag36 36)
|
||||
(enemy-flag37 37)
|
||||
(enemy-flag38 38)
|
||||
(enemy-flag39 39)
|
||||
(not-frustrated 39)
|
||||
(enemy-flag40 40)
|
||||
(enemy-flag41 41)
|
||||
(enemy-flag42 42)
|
||||
@ -36133,7 +36126,7 @@
|
||||
(kick-attack () _type_ :state 158)
|
||||
(attack () _type_ :state 159)
|
||||
(die-now () _type_ :state 160)
|
||||
(shoot (_type_ vector projectile-init-by-other-params int float float) none 161)
|
||||
(shoot (_type_ vector projectile-init-by-other-params int int float) none 161)
|
||||
(crimson-guard-hover-method-162 (_type_ process-focusable) symbol 162)
|
||||
)
|
||||
)
|
||||
@ -41516,7 +41509,7 @@
|
||||
(deftype sew-scare-grunt (grunt)
|
||||
((anim spool-anim :offset-assert 692)
|
||||
(manipy (pointer manipy) :offset-assert 696)
|
||||
(spooled-sound-id uint32 :offset-assert 700)
|
||||
(spooled-sound-id sound-id :offset-assert 700)
|
||||
(grill-actor entity-actor :offset-assert 704)
|
||||
)
|
||||
:method-count-assert 188
|
||||
@ -46196,7 +46189,7 @@
|
||||
|
||||
(deftype tomb-vibe (process-drawable)
|
||||
((spawn-pos vector :inline :offset-assert 208)
|
||||
(pat-tbl (array handle) :offset-assert 224) ;; pattern-table
|
||||
(pat-tbl (pointer int32) :offset-assert 224) ;; pattern-table
|
||||
(pat-count int32 :offset-assert 228)
|
||||
(pat-index int32 :offset-assert 232)
|
||||
(pat-entry-index int32 :offset-assert 236)
|
||||
@ -47743,13 +47736,23 @@
|
||||
)
|
||||
)
|
||||
|
||||
(defenum under-locking-mode
|
||||
:type int64
|
||||
(want-mech)
|
||||
(want-fill)
|
||||
(airlock-wait)
|
||||
(want-drain)
|
||||
(drain)
|
||||
(want-exit-mech)
|
||||
)
|
||||
|
||||
(deftype under-locking (process-drawable)
|
||||
((id int8 :offset-assert 200)
|
||||
(up-y float :offset-assert 204)
|
||||
(down-y float :offset-assert 208)
|
||||
(mode uint64 :offset-assert 216)
|
||||
(mode under-locking-mode :offset-assert 216)
|
||||
(which-reminder? symbol :offset-assert 224)
|
||||
(spooled-sound-id uint32 :offset-assert 228)
|
||||
(spooled-sound-id sound-id :offset-assert 228)
|
||||
(draining-part sparticle-launch-control :offset-assert 232)
|
||||
(actor-group (pointer actor-group) :offset-assert 236)
|
||||
(spooled-sound-delay int32 :offset-assert 240)
|
||||
|
@ -553,8 +553,7 @@
|
||||
],
|
||||
"print-game-text": [
|
||||
[225, "v1", "float"],
|
||||
[241, "v1", "float"],
|
||||
[[324, 327], "v1", "dma-packet"]
|
||||
[241, "v1", "float"]
|
||||
],
|
||||
"fx-copy-buf": [
|
||||
[[2, 8], "a2", "dma-packet"],
|
||||
|
@ -446,44 +446,95 @@ std::string write_spool_subtitles(
|
||||
file_util::create_dir_if_needed(image_out);
|
||||
}
|
||||
|
||||
for (auto& [spool_name, subs] : data) {
|
||||
int image_count = 0;
|
||||
result += "(\"" + spool_name + "\"\n";
|
||||
for (auto& sub : subs) {
|
||||
std::string temp_for_indent = fmt::format(" (({} {}) (", float_to_string(sub.start_frame),
|
||||
float_to_string(sub.end_frame));
|
||||
auto indent = temp_for_indent.length();
|
||||
result += temp_for_indent;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
const auto& msg = sub.message[i];
|
||||
if (i > 0) {
|
||||
result += "\n" + std::string(indent, ' ');
|
||||
constexpr bool as_json = true;
|
||||
if constexpr (as_json) {
|
||||
constexpr bool dump_text = false;
|
||||
constexpr int lang = 0;
|
||||
// no line data
|
||||
bool has_spools = false;
|
||||
for (auto& [spool_name, subs] : data) {
|
||||
result += " \"" + spool_name + "\": {\n";
|
||||
result += " \"scene\": true,\n";
|
||||
result += " \"lines\": [\n";
|
||||
bool has_subs = false;
|
||||
for (auto& sub : subs) {
|
||||
const auto& msg = sub.message[lang];
|
||||
if (msg.kind != SpoolSubtitleMessage::Kind::STRING) {
|
||||
continue;
|
||||
}
|
||||
if (msg.kind == SpoolSubtitleMessage::Kind::NIL) {
|
||||
result += "#f";
|
||||
result += " {\n";
|
||||
result += " \"end\": " + float_to_string(sub.end_frame) + ",\n";
|
||||
if (dump_text) {
|
||||
result += " \"merge\": false,\n";
|
||||
} else {
|
||||
result += "(";
|
||||
if (msg.kind == SpoolSubtitleMessage::Kind::IMAGE) {
|
||||
auto img_name = fmt::format("{}-{}-{}.png", spool_name, i, image_count++);
|
||||
result += "image " + img_name;
|
||||
if (dump_images) {
|
||||
std::vector<u32> rgba_out;
|
||||
rgba_out.resize(msg.w * msg.h);
|
||||
for (int px = 0; px < (int)rgba_out.size(); ++px) {
|
||||
int idx = px & 1 ? msg.data[px / 2] >> 4 : msg.data[px / 2] & 0xf;
|
||||
rgba_out.at(px) = msg.palette[idx];
|
||||
}
|
||||
file_util::write_rgba_png(image_out / img_name, rgba_out.data(), msg.w, msg.h);
|
||||
}
|
||||
} else if (msg.kind == SpoolSubtitleMessage::Kind::STRING) {
|
||||
result += "\"" + msg.text + "\"";
|
||||
}
|
||||
result += ")";
|
||||
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";
|
||||
} else {
|
||||
result += " \"text\": \"\"\n";
|
||||
}
|
||||
result += " },\n";
|
||||
has_subs = true;
|
||||
}
|
||||
result += ")\n )\n";
|
||||
if (has_subs) {
|
||||
result.pop_back();
|
||||
result.pop_back();
|
||||
result.push_back('\n');
|
||||
}
|
||||
|
||||
result += " ]\n";
|
||||
result += " },\n";
|
||||
has_spools = true;
|
||||
}
|
||||
if (has_spools) {
|
||||
result.pop_back();
|
||||
result.pop_back();
|
||||
result.push_back('\n');
|
||||
}
|
||||
} else {
|
||||
for (auto& [spool_name, subs] : data) {
|
||||
int image_count = 0;
|
||||
result += "(\"" + spool_name + "\"\n";
|
||||
for (auto& sub : subs) {
|
||||
std::string temp_for_indent = fmt::format(" (({} {}) (", float_to_string(sub.start_frame),
|
||||
float_to_string(sub.end_frame));
|
||||
auto indent = temp_for_indent.length();
|
||||
result += temp_for_indent;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
const auto& msg = sub.message[i];
|
||||
if (i > 0) {
|
||||
result += "\n" + std::string(indent, ' ');
|
||||
}
|
||||
if (msg.kind == SpoolSubtitleMessage::Kind::NIL) {
|
||||
result += "#f";
|
||||
} else {
|
||||
result += "(";
|
||||
if (msg.kind == SpoolSubtitleMessage::Kind::IMAGE) {
|
||||
auto img_name = fmt::format("{}-{}-{}.png", spool_name, i, image_count++);
|
||||
result += fmt::format("image \"{}\"", img_name);
|
||||
if (dump_images) {
|
||||
std::vector<u32> rgba_out;
|
||||
rgba_out.resize(msg.w * msg.h);
|
||||
for (int px = 0; px < (int)rgba_out.size(); ++px) {
|
||||
int idx = px & 1 ? msg.data[px / 2] >> 4 : msg.data[px / 2] & 0xf;
|
||||
rgba_out.at(px) = msg.palette[idx];
|
||||
}
|
||||
file_util::write_rgba_png(image_out / img_name, rgba_out.data(), msg.w, msg.h);
|
||||
}
|
||||
} else if (msg.kind == SpoolSubtitleMessage::Kind::STRING) {
|
||||
result += "\"" + msg.text + "\"";
|
||||
}
|
||||
result += ")";
|
||||
}
|
||||
}
|
||||
result += ")\n )\n";
|
||||
}
|
||||
result += " )\n\n";
|
||||
}
|
||||
result += " )\n\n";
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -213,6 +213,7 @@ set(RUNTIME_SOURCE
|
||||
system/vm/vm.cpp
|
||||
tools/filter_menu/filter_menu.cpp
|
||||
tools/subtitles/subtitle_editor.cpp
|
||||
tools/subtitles2/subtitle2_editor.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(sound)
|
||||
|
@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
BIN
game/assets/fonts/NotoSansJP-Medium.ttf
Normal file
BIN
game/assets/fonts/NotoSansJP-Medium.ttf
Normal file
Binary file not shown.
93
game/assets/fonts/OFL.txt
Normal file
93
game/assets/fonts/OFL.txt
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
Binary file not shown.
10
game/assets/jak2/game_subtitle.gp
Normal file
10
game/assets/jak2/game_subtitle.gp
Normal file
@ -0,0 +1,10 @@
|
||||
;; "project file" for subtitles make tool.
|
||||
|
||||
(subtitle2
|
||||
(file-json :text-version "jak2" :language-id 0
|
||||
:data "game/assets/jak2/subtitle/subtitle_en-US.json")
|
||||
(file-json :text-version "jak2" :language-id 5
|
||||
:data "game/assets/jak2/subtitle/subtitle_jp-JP.json")
|
||||
)
|
||||
|
||||
|
25553
game/assets/jak2/subtitle/subtitle_en-US.json
Normal file
25553
game/assets/jak2/subtitle/subtitle_en-US.json
Normal file
File diff suppressed because it is too large
Load Diff
70
game/assets/jak2/subtitle/subtitle_jp-JP.json
Normal file
70
game/assets/jak2/subtitle/subtitle_jp-JP.json
Normal file
@ -0,0 +1,70 @@
|
||||
{
|
||||
"lang": 5,
|
||||
"scenes": {
|
||||
"vin013": {
|
||||
"lines": [
|
||||
{
|
||||
"end": 74.0,
|
||||
"merge": false,
|
||||
"offscreen": true,
|
||||
"speaker": "vin",
|
||||
"start": 0.0,
|
||||
"text": "ジャック...コールが..."
|
||||
},
|
||||
{
|
||||
"end": 154.0,
|
||||
"merge": false,
|
||||
"offscreen": true,
|
||||
"speaker": "vin",
|
||||
"start": 75.0,
|
||||
"text": "爆弾...建造...エリア..."
|
||||
},
|
||||
{
|
||||
"end": 189.0,
|
||||
"merge": false,
|
||||
"offscreen": true,
|
||||
"speaker": "vin",
|
||||
"start": 155.0,
|
||||
"text": "フゥー..."
|
||||
}
|
||||
],
|
||||
"scene": false
|
||||
}
|
||||
},
|
||||
"speakers": {
|
||||
"agent": "エイジェント",
|
||||
"ashelin": "アシュリン",
|
||||
"baron": "バロンプラクシス",
|
||||
"brutter": "ブラッター",
|
||||
"citizen-female": "女性しみん",
|
||||
"citizen-male": "だん性しみん",
|
||||
"computer": "コンピュータ",
|
||||
"darkjak": "ダークジャック",
|
||||
"daxter": "ダックスター",
|
||||
"errol": "エロル",
|
||||
"grim": "グリム",
|
||||
"guard": "ガード",
|
||||
"guard-a": "ガードA",
|
||||
"guard-b": "ガードB",
|
||||
"jak": "ジャック",
|
||||
"jinx": "ジンクス",
|
||||
"keira": "ケイラ",
|
||||
"keira-before-class-3": "レーサー",
|
||||
"kid": "キッド",
|
||||
"kor": "コール",
|
||||
"krew": "クルー",
|
||||
"metalkor": "メタルコール",
|
||||
"mog": "モッグ",
|
||||
"onin": "オニン",
|
||||
"oracle": "オラクル",
|
||||
"pecker": "ペッカー",
|
||||
"precursor": "プリカーソル",
|
||||
"samos": "セイジィ",
|
||||
"sig": "ジーグ",
|
||||
"tess": "テス",
|
||||
"torn": "トーン",
|
||||
"vin": "ビン",
|
||||
"youngsamos": "セイモス",
|
||||
"youngsamos-before-rescue": "セイジィ"
|
||||
}
|
||||
}
|
@ -703,7 +703,16 @@ void OpenGLRenderer::render(DmaFollower dma, const RenderOptions& settings) {
|
||||
}
|
||||
|
||||
if (settings.draw_subtitle_editor_window) {
|
||||
m_subtitle_editor.draw_window();
|
||||
if (m_subtitle_editor == nullptr) {
|
||||
m_subtitle_editor = new SubtitleEditor();
|
||||
}
|
||||
m_subtitle_editor->draw_window();
|
||||
}
|
||||
if (settings.draw_subtitle2_editor_window) {
|
||||
if (m_subtitle2_editor == nullptr) {
|
||||
m_subtitle2_editor = new Subtitle2Editor(m_version);
|
||||
}
|
||||
m_subtitle2_editor->draw_window();
|
||||
}
|
||||
|
||||
if (settings.draw_filters_window) {
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "game/graphics/opengl_renderer/opengl_utils.h"
|
||||
#include "game/tools/filter_menu/filter_menu.h"
|
||||
#include "game/tools/subtitles/subtitle_editor.h"
|
||||
#include "game/tools/subtitles2/subtitle2_editor.h"
|
||||
|
||||
struct RenderOptions {
|
||||
bool draw_render_debug_window = false;
|
||||
@ -19,6 +20,7 @@ struct RenderOptions {
|
||||
bool draw_loader_window = false;
|
||||
bool draw_small_profiler_window = false;
|
||||
bool draw_subtitle_editor_window = false;
|
||||
bool draw_subtitle2_editor_window = false;
|
||||
bool draw_filters_window = false;
|
||||
|
||||
// internal rendering settings - The OpenGLRenderer will internally use this resolution/format.
|
||||
@ -140,7 +142,8 @@ class OpenGLRenderer {
|
||||
SharedRenderState m_render_state;
|
||||
Profiler m_profiler;
|
||||
SmallProfiler m_small_profiler;
|
||||
SubtitleEditor m_subtitle_editor;
|
||||
SubtitleEditor* m_subtitle_editor = nullptr;
|
||||
Subtitle2Editor* m_subtitle2_editor = nullptr;
|
||||
FiltersMenu m_filters_menu;
|
||||
|
||||
std::vector<std::unique_ptr<BucketRenderer>> m_bucket_renderers;
|
||||
|
@ -106,6 +106,12 @@ void OpenGlDebugGui::draw(const DmaStats& dma_stats) {
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Tools")) {
|
||||
if (m_version == GameVersion::Jak1) {
|
||||
ImGui::MenuItem("Subtitle Editor", nullptr, &m_subtitle_editor);
|
||||
} else {
|
||||
ImGui::MenuItem("Subtitle2 Editor", nullptr, &m_subtitle2_editor);
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Screenshot")) {
|
||||
ImGui::MenuItem("Screenshot Next Frame!", nullptr, &m_want_screenshot);
|
||||
ImGui::InputText("File", m_screenshot_save_name, 50);
|
||||
@ -127,7 +133,7 @@ void OpenGlDebugGui::draw(const DmaStats& dma_stats) {
|
||||
if (Gfx::g_debug_settings.alternate_style) {
|
||||
ImGui::applyAlternateStyle();
|
||||
} else {
|
||||
ImGui::StyleColorsClassic();
|
||||
ImGui::applyClassicStyle();
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "common/dma/dma.h"
|
||||
#include "common/util/Timer.h"
|
||||
#include "common/versions/versions.h"
|
||||
|
||||
class FrameTimeRecorder {
|
||||
public:
|
||||
@ -39,12 +40,15 @@ class FrameTimeRecorder {
|
||||
|
||||
class OpenGlDebugGui {
|
||||
public:
|
||||
OpenGlDebugGui(GameVersion version) : m_version(version) {}
|
||||
|
||||
void start_frame();
|
||||
void finish_frame();
|
||||
void draw(const DmaStats& dma_stats);
|
||||
bool should_draw_render_debug() const { return master_enable && m_draw_debug; }
|
||||
bool should_draw_profiler() const { return master_enable && m_draw_profiler; }
|
||||
bool should_draw_subtitle_editor() const { return master_enable && m_subtitle_editor; }
|
||||
bool should_draw_subtitle2_editor() const { return master_enable && m_subtitle2_editor; }
|
||||
bool should_draw_filters_menu() const { return master_enable && m_filters_menu; }
|
||||
bool should_draw_loader_menu() const { return master_enable && m_draw_loader; }
|
||||
const char* screenshot_name() const { return m_screenshot_save_name; }
|
||||
@ -79,8 +83,11 @@ class OpenGlDebugGui {
|
||||
bool m_draw_debug = false;
|
||||
bool m_draw_loader = false;
|
||||
bool m_subtitle_editor = false;
|
||||
bool m_subtitle2_editor = false;
|
||||
bool m_filters_menu = false;
|
||||
bool m_want_screenshot = false;
|
||||
char m_screenshot_save_name[256] = "screenshot.png";
|
||||
float target_fps_input = 60.f;
|
||||
|
||||
GameVersion m_version;
|
||||
};
|
||||
|
@ -82,6 +82,7 @@ struct GraphicsData {
|
||||
file_util::get_jak_project_dir() / "out" / game_version_names[version] / "fr3",
|
||||
fr3_level_count[version])),
|
||||
ogl_renderer(texture_pool, loader, version),
|
||||
debug_gui(version),
|
||||
version(version) {}
|
||||
};
|
||||
|
||||
@ -152,7 +153,7 @@ static void init_imgui(SDL_Window* window,
|
||||
if (!Gfx::g_debug_settings.monospaced_font) {
|
||||
// TODO - add or switch to Noto since it supports the entire unicode range
|
||||
std::string font_path =
|
||||
(file_util::get_jak_project_dir() / "game" / "assets" / "fonts" / "Roboto-Medium.ttf")
|
||||
(file_util::get_jak_project_dir() / "game" / "assets" / "fonts" / "NotoSansJP-Medium.ttf")
|
||||
.string();
|
||||
if (file_util::file_exists(font_path)) {
|
||||
static const ImWchar ranges[] = {
|
||||
@ -163,11 +164,11 @@ static void init_imgui(SDL_Window* window,
|
||||
0x3000, 0x30FF, // CJK Symbols and Punctuations, Hiragana, Katakana
|
||||
0x3131, 0x3163, // Korean alphabets
|
||||
0x31F0, 0x31FF, // Katakana Phonetic Extensions
|
||||
0x4E00, 0x9FAF, // CJK Ideograms
|
||||
0xA640, 0xA69F, // Cyrillic Extended-B
|
||||
0xAC00, 0xD7A3, // Korean characters
|
||||
0xFF00, 0xFFEF, // Half-width characters
|
||||
0xFFFD, 0xFFFD, // Invalid
|
||||
0x4e00, 0x9FAF, // CJK Ideograms
|
||||
0,
|
||||
};
|
||||
io.Fonts->AddFontFromFileTTF(font_path.c_str(), Gfx::g_debug_settings.imgui_font_size,
|
||||
@ -356,6 +357,7 @@ void render_game_frame(int game_width,
|
||||
options.draw_profiler_window = g_gfx_data->debug_gui.should_draw_profiler();
|
||||
options.draw_loader_window = g_gfx_data->debug_gui.should_draw_loader_menu();
|
||||
options.draw_subtitle_editor_window = g_gfx_data->debug_gui.should_draw_subtitle_editor();
|
||||
options.draw_subtitle2_editor_window = g_gfx_data->debug_gui.should_draw_subtitle2_editor();
|
||||
options.draw_filters_window = g_gfx_data->debug_gui.should_draw_filters_menu();
|
||||
options.save_screenshot = false;
|
||||
options.gpu_sync = g_gfx_data->debug_gui.should_gl_finish();
|
||||
|
@ -10,10 +10,10 @@ namespace game_settings {
|
||||
struct DebugSettings {
|
||||
DebugSettings();
|
||||
|
||||
std::string version = "1.1";
|
||||
std::string version = "1.2";
|
||||
|
||||
bool show_imgui = false;
|
||||
int imgui_font_size = 14;
|
||||
int imgui_font_size = 16;
|
||||
bool monospaced_font = true;
|
||||
bool alternate_style = false;
|
||||
bool ignore_hide_imgui = false;
|
||||
|
436
game/tools/subtitles2/subtitle2_editor.cpp
Normal file
436
game/tools/subtitles2/subtitle2_editor.cpp
Normal file
@ -0,0 +1,436 @@
|
||||
#include "subtitle2_editor.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "common/serialization/subtitles2/subtitles2_deser.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
#include "common/util/json_util.h"
|
||||
#include "common/util/string_util.h"
|
||||
|
||||
#include "game/runtime.h"
|
||||
|
||||
#include "third-party/fmt/core.h"
|
||||
#include "third-party/imgui/imgui.h"
|
||||
#include "third-party/imgui/imgui_stdlib.h"
|
||||
|
||||
static constexpr size_t LINE_DISPLAY_MAX_LEN = 38;
|
||||
|
||||
Subtitle2Editor::Subtitle2Editor(GameVersion version)
|
||||
: db_loaded(true),
|
||||
m_subtitle_db(load_subtitle2_project(version)),
|
||||
m_repl(8182),
|
||||
m_speaker_names(get_speaker_names(version)) {
|
||||
m_filter = m_filter_placeholder;
|
||||
m_filter_hints = m_filter_placeholder;
|
||||
}
|
||||
|
||||
bool Subtitle2Editor::is_scene_in_current_lang(const std::string& scene_name) {
|
||||
return m_subtitle_db.m_banks.at(m_current_language)->scenes.count(scene_name) > 0;
|
||||
}
|
||||
|
||||
void Subtitle2Editor::repl_rebuild_text() {
|
||||
// reload subtitles immediately
|
||||
m_repl.eval("(reload-subtitles)");
|
||||
}
|
||||
|
||||
void Subtitle2Editor::repl_play_vag(const std::string& name, bool is_scene) {
|
||||
if (is_scene) {
|
||||
m_repl.eval(fmt::format("(scene-find-and-play \"{}\")", name));
|
||||
} else {
|
||||
m_repl.eval(fmt::format("(vag-player-play-from-name \"{}\")", name));
|
||||
}
|
||||
}
|
||||
|
||||
void Subtitle2Editor::draw_window() {
|
||||
ImGui::Begin("Subtitle2 Editor");
|
||||
|
||||
if (!db_loaded) {
|
||||
if (ImGui::Button("Load Subtitles")) {
|
||||
m_subtitle_db = load_subtitle2_project(g_game_version);
|
||||
db_loaded = true;
|
||||
}
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::Button("Save Changes")) {
|
||||
m_files_saved_successfully =
|
||||
std::make_optional(write_subtitle_db_to_files(m_subtitle_db, g_game_version));
|
||||
repl_rebuild_text();
|
||||
}
|
||||
if (m_files_saved_successfully.has_value()) {
|
||||
ImGui::SameLine();
|
||||
if (m_files_saved_successfully.value()) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_success_text_color);
|
||||
ImGui::Text("Saved!");
|
||||
ImGui::PopStyleColor();
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_error_text_color);
|
||||
ImGui::Text("Error!");
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
}
|
||||
|
||||
draw_edit_options();
|
||||
draw_repl_options();
|
||||
draw_speaker_options();
|
||||
|
||||
if (!m_current_scene) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_disabled_text_color);
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_selected_text_color);
|
||||
}
|
||||
if (ImGui::TreeNode("Currently Selected Cutscene")) {
|
||||
ImGui::Text("%s", m_current_scene_name.c_str());
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Cutscene?", &m_current_scene->scene);
|
||||
ImGui::PopStyleColor();
|
||||
if (m_current_scene) {
|
||||
draw_subtitle_options(*m_current_scene, m_current_scene_name, true);
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255));
|
||||
ImGui::Text("Select a Scene from Below!");
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
} else {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("All Cutscenes")) {
|
||||
ImGui::InputText("New Scene Name", &m_new_scene_name);
|
||||
ImGui::InputText("Filter", &m_filter, ImGuiInputTextFlags_::ImGuiInputTextFlags_AutoSelectAll);
|
||||
if (is_scene_in_current_lang(m_new_scene_name)) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_error_text_color);
|
||||
ImGui::Text("Scene already exists with that name, no!");
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
if (!is_scene_in_current_lang(m_new_scene_name) && !m_new_scene_name.empty()) {
|
||||
if (ImGui::Button("Add Scene")) {
|
||||
Subtitle2Scene new_scene;
|
||||
m_subtitle_db.m_banks.at(m_current_language)->add_scene(m_new_scene_name, new_scene);
|
||||
if (m_add_new_scene_as_current) {
|
||||
auto& scenes = m_subtitle_db.m_banks.at(m_current_language)->scenes;
|
||||
auto& scene_info = scenes.at(m_new_scene_name);
|
||||
m_current_scene = &scene_info;
|
||||
m_current_scene_name = m_new_scene_name;
|
||||
}
|
||||
m_new_scene_name = "";
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Add as Current Scene", &m_add_new_scene_as_current);
|
||||
}
|
||||
|
||||
draw_all_scenes();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void Subtitle2Editor::draw_edit_options() {
|
||||
if (ImGui::TreeNode("Editing Options")) {
|
||||
if (ImGui::BeginCombo("Editor Language ID",
|
||||
fmt::format("[{}] {}", m_subtitle_db.m_banks[m_current_language]->lang,
|
||||
m_subtitle_db.m_banks[m_current_language]->file_path)
|
||||
.c_str())) {
|
||||
for (const auto& [key, value] : m_subtitle_db.m_banks) {
|
||||
const bool isSelected = m_current_language == key;
|
||||
if (ImGui::Selectable(fmt::format("[{}] {}", value->lang, value->file_path).c_str(),
|
||||
isSelected)) {
|
||||
m_current_language = key;
|
||||
}
|
||||
if (isSelected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (ImGui::BeginCombo("Base Language ID",
|
||||
fmt::format("[{}] {}", m_subtitle_db.m_banks[m_base_language]->lang,
|
||||
m_subtitle_db.m_banks[m_base_language]->file_path)
|
||||
.c_str())) {
|
||||
for (const auto& [key, value] : m_subtitle_db.m_banks) {
|
||||
const bool isSelected = m_base_language == key;
|
||||
if (ImGui::Selectable(fmt::format("[{}] {}", value->lang, value->file_path).c_str(),
|
||||
isSelected)) {
|
||||
m_base_language = key;
|
||||
}
|
||||
if (isSelected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::Checkbox("Show missing cutscenes from base", &m_base_show_missing_cutscenes);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
void Subtitle2Editor::draw_repl_options() {
|
||||
if (ImGui::TreeNode("REPL Options")) {
|
||||
// TODO - the ReplServer should eventually be able to return statuses to make this easier:
|
||||
// - Has the game been built before?
|
||||
// - Is the repl connected?
|
||||
ImGui::TextWrapped(
|
||||
"This tool requires a REPL connected to the game, with the game built. Run the following "
|
||||
"to do so:");
|
||||
ImGui::Text(" - `task repl`");
|
||||
ImGui::Text(" - `(lt)`");
|
||||
ImGui::Text(" - `(mi)`");
|
||||
ImGui::Text(" - Click Connect Below!");
|
||||
if (m_repl.is_connected()) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_success_text_color);
|
||||
ImGui::Text("REPL Connected, should be good to go!");
|
||||
ImGui::PopStyleColor();
|
||||
} else {
|
||||
if (ImGui::Button("Connect to REPL")) {
|
||||
m_repl.connect();
|
||||
if (!m_repl.is_connected()) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_error_text_color);
|
||||
ImGui::Text("Could not connect.");
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
void Subtitle2Editor::draw_speaker_options() {
|
||||
if (ImGui::TreeNode("Speakers")) {
|
||||
const auto bank = m_subtitle_db.m_banks[m_current_language];
|
||||
for (auto& speaker_name : m_speaker_names) {
|
||||
// ImGui::SameLine();
|
||||
if (bank->speakers.count(speaker_name) == 0) {
|
||||
// no speaker yet.
|
||||
std::string input = "";
|
||||
ImGui::InputText(speaker_name.c_str(), &input);
|
||||
if (!input.empty()) {
|
||||
// speaker got filled
|
||||
bank->speakers.insert({speaker_name, input});
|
||||
}
|
||||
} else {
|
||||
// existing speaker
|
||||
std::string input = bank->speakers.at(speaker_name);
|
||||
if (ImGui::InputText(speaker_name.c_str(), &input)) {
|
||||
if (input.empty()) {
|
||||
// speaker got deleted
|
||||
bank->speakers.erase(speaker_name);
|
||||
} else {
|
||||
// speaker got changed
|
||||
bank->speakers.at(speaker_name) = input;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
void Subtitle2Editor::draw_all_scenes(bool base_cutscenes) {
|
||||
auto& scenes =
|
||||
m_subtitle_db.m_banks.at(base_cutscenes ? m_base_language : m_current_language)->scenes;
|
||||
std::unordered_set<std::string> to_delete;
|
||||
for (auto& [name, scene] : scenes) {
|
||||
// Don't duplicate entries
|
||||
if (base_cutscenes && is_scene_in_current_lang(name)) {
|
||||
continue;
|
||||
}
|
||||
bool is_current_scene = m_current_scene && m_current_scene_name == name;
|
||||
if ((!m_filter.empty() && m_filter != m_filter_placeholder) &&
|
||||
name.find(m_filter) == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
bool color_pushed = false;
|
||||
if (!base_cutscenes && is_current_scene) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_selected_text_color);
|
||||
color_pushed = true;
|
||||
} else if (base_cutscenes) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_disabled_text_color);
|
||||
color_pushed = true;
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode(
|
||||
fmt::format("{}-{}", name, base_cutscenes ? m_base_language : m_current_language)
|
||||
.c_str(),
|
||||
"%s", name.c_str())) {
|
||||
if (color_pushed) {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
if (!base_cutscenes && !is_current_scene) {
|
||||
if (ImGui::Button("Select as Current")) {
|
||||
m_current_scene = &scene;
|
||||
m_current_scene_name = name;
|
||||
}
|
||||
}
|
||||
if (base_cutscenes) {
|
||||
if (ImGui::Button("Copy from Base Language")) {
|
||||
m_subtitle_db.m_banks.at(m_current_language)->add_scene(name, scene);
|
||||
}
|
||||
}
|
||||
draw_subtitle_options(scene, name);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, m_warning_color);
|
||||
if (ImGui::Button("Delete")) {
|
||||
if (&scene == m_current_scene || name == m_current_scene_name) {
|
||||
m_current_scene = nullptr;
|
||||
m_current_scene_name = "";
|
||||
}
|
||||
to_delete.insert(name);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::TreePop();
|
||||
} else if (color_pushed) {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
}
|
||||
for (auto& name : to_delete) {
|
||||
scenes.erase(name);
|
||||
}
|
||||
}
|
||||
|
||||
void Subtitle2Editor::draw_subtitle_options(Subtitle2Scene& scene,
|
||||
const std::string& name,
|
||||
bool current_scene) {
|
||||
if (!m_repl.is_connected()) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_error_text_color);
|
||||
ImGui::Text("REPL not connected, can't play!");
|
||||
ImGui::PopStyleColor();
|
||||
} else {
|
||||
// Cutscenes
|
||||
if (ImGui::Button("Play Scene")) {
|
||||
repl_play_vag(name, scene.scene);
|
||||
}
|
||||
}
|
||||
if (current_scene) {
|
||||
draw_new_cutscene_line_form();
|
||||
}
|
||||
const auto bank = m_subtitle_db.m_banks[m_current_language];
|
||||
int i = 0;
|
||||
for (auto line = scene.lines.begin(); line != scene.lines.end();) {
|
||||
float times[2] = {line->start, line->end};
|
||||
bool speaker_exists = bank->speakers.count(line->speaker) != 0;
|
||||
auto speaker_text = !speaker_exists ? "N/A" : bank->speakers.at(line->speaker);
|
||||
std::string full_line = line->text;
|
||||
if (speaker_exists) {
|
||||
full_line = speaker_text + ": " + full_line;
|
||||
}
|
||||
auto summary = fmt::format("[{} - {}] {}", line->start, line->end, full_line);
|
||||
if (line->text.empty()) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_disabled_text_color);
|
||||
} else if (line->offscreen) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_offscreen_text_color);
|
||||
}
|
||||
if (ImGui::TreeNode(fmt::format("{}", i).c_str(), "%s", summary.c_str())) {
|
||||
if (line->text.empty() || line->offscreen) {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
ImGui::InputFloat2("Start and End Frame", times, "%.0f",
|
||||
ImGuiInputTextFlags_::ImGuiInputTextFlags_CharsDecimal);
|
||||
if (ImGui::BeginCombo("Speaker",
|
||||
fmt::format("{} ({})", speaker_text.c_str(), line->speaker).c_str())) {
|
||||
const bool isSelected = line->speaker == "none";
|
||||
if (ImGui::Selectable("none", isSelected)) {
|
||||
line->speaker = "none";
|
||||
}
|
||||
if (isSelected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
for (auto& speaker_name : m_speaker_names) {
|
||||
if (bank->speakers.count(speaker_name) == 0) {
|
||||
continue;
|
||||
}
|
||||
const bool isSelected = line->speaker == speaker_name;
|
||||
if (ImGui::Selectable(
|
||||
fmt::format("{} ({})", bank->speakers.at(speaker_name), speaker_name).c_str(),
|
||||
isSelected)) {
|
||||
line->speaker = speaker_name;
|
||||
}
|
||||
if (isSelected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::InputText("Text", &line->text);
|
||||
ImGui::Checkbox("Offscreen?", &line->offscreen);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Merge text?", &line->merge);
|
||||
if (scene.lines.size() > 1) { // prevent creating an empty scene
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, m_warning_color);
|
||||
if (ImGui::Button("Delete")) {
|
||||
line = scene.lines.erase(line);
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::TreePop();
|
||||
continue;
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
} else if (line->text.empty() || line->offscreen) {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
line->start = times[0];
|
||||
line->end = times[1];
|
||||
i++;
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
void Subtitle2Editor::draw_new_cutscene_line_form() {
|
||||
auto bank = m_subtitle_db.m_banks[m_current_language];
|
||||
ImGui::InputFloat2("Start and End Frame", m_current_scene_frame, "%.0f",
|
||||
ImGuiInputTextFlags_::ImGuiInputTextFlags_CharsDecimal);
|
||||
const auto& speakers = bank->speakers;
|
||||
if (speakers.count(m_current_scene_speaker) == 0) {
|
||||
// pick whatever the first one it finds is
|
||||
m_current_scene_speaker = "none";
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Speaker",
|
||||
m_current_scene_speaker == "none"
|
||||
? "none"
|
||||
: fmt::format("{} ({})", speakers.at(m_current_scene_speaker),
|
||||
m_current_scene_speaker)
|
||||
.c_str())) {
|
||||
const bool isSelected = m_current_scene_speaker == "none";
|
||||
if (ImGui::Selectable("none", isSelected)) {
|
||||
m_current_scene_speaker = "none";
|
||||
}
|
||||
if (isSelected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
for (auto& speaker_name : m_speaker_names) {
|
||||
if (speakers.count(speaker_name) == 0) {
|
||||
continue;
|
||||
}
|
||||
const bool isSelected = m_current_scene_speaker == speaker_name;
|
||||
if (ImGui::Selectable(fmt::format("{} ({})", speakers.at(speaker_name), speaker_name).c_str(),
|
||||
isSelected)) {
|
||||
m_current_scene_speaker = speaker_name;
|
||||
}
|
||||
if (isSelected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::InputText("Text", &m_current_scene_text);
|
||||
ImGui::Checkbox("Offscreen?", &m_current_scene_offscreen);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Merge text?", &m_current_scene_merge);
|
||||
if (m_current_scene_frame[0] < 0 || m_current_scene_frame[1] < 0 ||
|
||||
(m_current_scene_text.empty() && !m_current_scene_merge)) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, m_error_text_color);
|
||||
ImGui::Text("Can't add a new text entry with the current fields!");
|
||||
ImGui::PopStyleColor();
|
||||
} else {
|
||||
if (ImGui::Button("Add Text Entry")) {
|
||||
m_current_scene->lines.emplace_back(m_current_scene_frame[0], m_current_scene_frame[1],
|
||||
m_current_scene_text, m_current_scene_speaker,
|
||||
m_current_scene_offscreen, m_current_scene_merge);
|
||||
// TODO - sorting after every insertion is slow, sort on the add scene instead
|
||||
std::sort(m_current_scene->lines.begin(), m_current_scene->lines.end());
|
||||
}
|
||||
}
|
||||
}
|
75
game/tools/subtitles2/subtitle2_editor.h
Normal file
75
game/tools/subtitles2/subtitle2_editor.h
Normal file
@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
|
||||
#include "common/repl/nrepl/ReplClient.h"
|
||||
#include "common/serialization/subtitles2/subtitles2_ser.h"
|
||||
|
||||
#include "third-party/imgui/imgui.h"
|
||||
|
||||
// TODO Later:
|
||||
// - Hints, these seem less annoying but there are a lot of them
|
||||
|
||||
class Subtitle2Editor {
|
||||
public:
|
||||
Subtitle2Editor(GameVersion version);
|
||||
void draw_window();
|
||||
|
||||
private:
|
||||
void draw_edit_options();
|
||||
void draw_repl_options();
|
||||
void draw_speaker_options();
|
||||
|
||||
void draw_all_scenes(bool base_cutscenes = false);
|
||||
void draw_subtitle_options(Subtitle2Scene& scene,
|
||||
const std::string& name,
|
||||
bool current_scene = false);
|
||||
void draw_new_cutscene_line_form();
|
||||
|
||||
bool db_loaded = false;
|
||||
|
||||
GameSubtitle2DB m_subtitle_db;
|
||||
Subtitle2Scene* m_current_scene = nullptr;
|
||||
std::string m_current_scene_name = "";
|
||||
std::string m_filter;
|
||||
std::string m_filter_hints;
|
||||
|
||||
ReplClient m_repl;
|
||||
|
||||
float m_current_scene_frame[2] = {0, 0};
|
||||
std::string m_current_scene_text = "";
|
||||
std::string m_current_scene_speaker = "";
|
||||
bool m_current_scene_offscreen = false;
|
||||
bool m_current_scene_merge = false;
|
||||
bool m_add_new_scene_as_current = false;
|
||||
|
||||
std::string m_new_scene_name = "";
|
||||
std::string m_new_scene_id = "0";
|
||||
|
||||
std::string m_filter_placeholder = "Filter List...";
|
||||
|
||||
std::optional<bool> m_files_saved_successfully = {};
|
||||
|
||||
int m_base_language = 0;
|
||||
int m_current_language = 0;
|
||||
// bool m_base_show_lines = false;
|
||||
bool m_base_show_missing_cutscenes = true;
|
||||
|
||||
// TODO - let the user customize these colors
|
||||
ImVec4 m_normal_text_color = ImVec4(1.0f, 0.0f, 1.0f, 1.0f);
|
||||
int m_selected_text_color = IM_COL32(89, 227, 225, 255);
|
||||
ImVec4 m_success_text_color = ImVec4(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
ImVec4 m_error_text_color = ImVec4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
ImVec4 m_disabled_text_color = ImVec4(1.0f, 1.0f, 1.0f, 0.7f);
|
||||
ImVec4 m_warning_color = ImVec4(0.619f, 0.443f, 0.0f, 1.0f);
|
||||
int m_offscreen_text_color = IM_COL32(240, 242, 102, 255);
|
||||
// TODO - cycle speaker colors
|
||||
|
||||
const std::vector<std::string> m_speaker_names;
|
||||
|
||||
void repl_rebuild_text();
|
||||
void repl_play_vag(const std::string& name, bool is_scene);
|
||||
|
||||
bool is_scene_in_current_lang(const std::string& scene_name);
|
||||
};
|
@ -1037,6 +1037,14 @@
|
||||
`(defconstant ,name (-> self draw art-group data ,idx))
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; built-in type stuff
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defmacro string? (val)
|
||||
`(type? ,val string))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Load Project
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -424,21 +424,19 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defun debug-menu-item-get-max-width ((arg0 debug-menu-item) (arg1 debug-menu))
|
||||
"Determine the width, in pixels"
|
||||
(local-vars (v0-1 int))
|
||||
"Determine the width, in screen units"
|
||||
0
|
||||
(cond
|
||||
((= (-> arg0 type) debug-menu-item-submenu)
|
||||
(set! v0-1 (+ (the int (get-string-length (-> arg0 name) (-> arg1 context font))) 16))
|
||||
((= (-> arg0 type) debug-menu-item-submenu)
|
||||
(+ (the int (get-string-length (-> arg0 name) (-> arg1 context font))) 16)
|
||||
)
|
||||
((= (-> arg0 type) debug-menu-item-var)
|
||||
(the int (get-string-length (-> (the-as debug-menu-item-var arg0) display-str) (-> arg1 context font)))
|
||||
)
|
||||
(else
|
||||
(+ (the int (get-string-length (-> arg0 name) (-> arg1 context font))) 6)
|
||||
)
|
||||
)
|
||||
((= (-> arg0 type) debug-menu-item-var)
|
||||
(set! v0-1 (the int (get-string-length (-> (the-as debug-menu-item-var arg0) display-str) (-> arg1 context font))))
|
||||
)
|
||||
(else
|
||||
(set! v0-1 (+ (the int (get-string-length (-> arg0 name) (-> arg1 context font))) 6))
|
||||
)
|
||||
)
|
||||
v0-1
|
||||
)
|
||||
|
||||
(defun debug-menu-context-default-selection ((ctxt debug-menu-context) (keep-current symbol))
|
||||
@ -761,8 +759,6 @@
|
||||
))
|
||||
(with-dma-buffer-add-bucket ((s3-0 (-> (current-frame) debug-buf))
|
||||
(bucket-id debug-no-zbuf))
|
||||
;; NOTE: the draw-string-adv advances too far on widescreen.
|
||||
;; NOTE 2: should be fixed?
|
||||
(draw-string-adv (-> item name) s3-0 s5-0)
|
||||
(draw-string-adv "..." s3-0 s5-0)
|
||||
)
|
||||
|
@ -1635,13 +1635,7 @@
|
||||
)
|
||||
|
||||
(defun get-string-length ((arg0 string) (arg1 font-context))
|
||||
(local-vars
|
||||
(v0-0 float) (a2-1 (inline-array vector)) (a2-4 (inline-array vector)) (a3-2 int) (a3-9 uint)
|
||||
(a3-10 int) (t0-0 uint) (t0-1 uint) (t0-3 int) (t0-4 int) (t0-5 int) (t1-1 uint) (t1-2 uint)
|
||||
(t1-3 uint) (t1-4 uint) (t1-5 uint) (t2-0 uint) (t2-2 uint) (t2-3 uint) (t2-4 uint) (t2-5 uint)
|
||||
(t2-6 uint) (t2-7 uint) (t2-8 uint) (t2-9 uint) (t2-10 uint) (t2-11 uint) (t2-12 uint)
|
||||
(t2-13 uint) (t2-14 uint) (t2-15 uint) (t2-16 uint) (t2-17 uint) (t3-0 uint) (t3-1 int)
|
||||
)
|
||||
(local-vars (v0-0 float))
|
||||
(rlet ((vf0 :class vf)
|
||||
(vf1 :class vf)
|
||||
(vf13 :class vf)
|
||||
@ -1652,171 +1646,132 @@
|
||||
(vf25 :class vf)
|
||||
(vf5 :class vf)
|
||||
)
|
||||
(init-vf0-vector)
|
||||
(.lvf vf25 (&-> arg1 context-vec quad))
|
||||
(.lvf vf23 (&-> arg1 origin quad))
|
||||
(.lvf vf24 (&-> arg1 origin quad))
|
||||
(let ((v1-0 (-> arg1 flags-signed)))
|
||||
(let ((a1-2 *video-parms*))
|
||||
(.lvf vf1 (+ (the int a1-2) 64))
|
||||
)
|
||||
(.mul.vf vf25 vf25 vf1 :mask #b11)
|
||||
(.mul.vf vf23 vf23 vf1 :mask #b11)
|
||||
;; hack! fixes small font widescreen
|
||||
(unless (logtest? (-> arg1 flags) (font-flags pc-hack))
|
||||
(.mul.vf vf24 vf24 vf1 :mask #b11)
|
||||
)
|
||||
(let ((a1-4 *font-work*))
|
||||
(set! (-> a1-4 str-ptr) (the-as uint arg0))
|
||||
(set! (-> a1-4 flags) (the-as font-flags v1-0))
|
||||
(.mov.vf vf1 vf0)
|
||||
(let ((a2-0 (logand v1-0 32)))
|
||||
(nop!)
|
||||
(b! (nonzero? a2-0) cfg-2 :delay (set! a2-1 *font12-table*))
|
||||
)
|
||||
(let ((a2-2 a2-1))
|
||||
(nop!)
|
||||
(.lvf vf13 (&-> a1-4 size1-small quad))
|
||||
(b! #t cfg-3 :delay (.lvf vf14 (&-> a1-4 size2-small quad)))
|
||||
(label cfg-2)
|
||||
(nop!)
|
||||
(set! a2-2 *font24-table*)
|
||||
(nop!)
|
||||
(.lvf vf13 (&-> a1-4 size1-large quad))
|
||||
(nop!)
|
||||
(.lvf vf14 (&-> a1-4 size2-large quad))
|
||||
(label cfg-3)
|
||||
(let ((a3-0 (-> (the-as (pointer uint8) arg0) 4)))
|
||||
(set! arg0 (the-as string (&-> (the-as (pointer uint8) arg0) 1)))
|
||||
(b! (zero? a3-0) cfg-51 :delay (set! t0-0 (+ a3-0 -1)))
|
||||
(b! (zero? t0-0) cfg-44 :delay (set! t0-1 (+ a3-0 -126)))
|
||||
(b! (nonzero? t0-1) cfg-45 :delay (nop!))
|
||||
(set! a3-0 (-> (the-as (pointer uint8) arg0) 4))
|
||||
(set! arg0 (the-as string (&-> (the-as (pointer uint8) arg0) 1)))
|
||||
(let ((t0-2 0)
|
||||
(t1-0 0)
|
||||
)
|
||||
(b! (zero? a3-0) cfg-51 :delay (set! t2-0 (+ a3-0 -43)))
|
||||
(.movz t0-3 a3-0 t2-0 t0-2)
|
||||
(let ((t2-1 (+ a3-0 -45)))
|
||||
(.movz t0-4 a3-0 t2-1 t0-3)
|
||||
)
|
||||
(nop!)
|
||||
(b! (nonzero? t0-4) cfg-14 :delay (set! t2-2 (+ a3-0 -121)))
|
||||
(b! (zero? t2-2) cfg-42 :delay (set! t1-1 (+ a3-0 -89)))
|
||||
(b! (zero? t1-1) cfg-42 :delay (set! t1-2 (+ a3-0 -122)))
|
||||
(b! (zero? t1-2) cfg-43 :delay (set! t1-3 (+ a3-0 -90)))
|
||||
(b! (zero? t1-3) cfg-43 :delay (set! t1-4 (+ a3-0 -48)))
|
||||
(b! (< (the-as int t1-4) 0) cfg-45 :delay (set! t1-5 (+ a3-0 -57)))
|
||||
(b!
|
||||
(> (the-as int t1-5) 0)
|
||||
cfg-45
|
||||
:delay
|
||||
(set! t1-0 (the-as int (+ a3-0 -48)))
|
||||
)
|
||||
(label cfg-14)
|
||||
(set! a3-0 (-> (the-as (pointer uint8) arg0) 4))
|
||||
(set! arg0 (the-as string (&-> (the-as (pointer uint8) arg0) 1)))
|
||||
(b! (zero? a3-0) cfg-51 :delay (set! t2-3 (+ a3-0 -110)))
|
||||
(b! (zero? t2-3) cfg-32 :delay (set! t2-4 (+ a3-0 -78)))
|
||||
(b! (zero? t2-4) cfg-32 :delay (set! t2-5 (+ a3-0 -108)))
|
||||
(b! (zero? t2-5) cfg-3 :delay (set! t2-6 (+ a3-0 -76)))
|
||||
(b! (zero? t2-6) cfg-3 :delay (set! t2-7 (+ a3-0 -119)))
|
||||
(b! (zero? t2-7) cfg-3 :delay (set! t2-8 (+ a3-0 -87)))
|
||||
(b! (zero? t2-8) cfg-3 :delay (set! t2-9 (+ a3-0 -107)))
|
||||
(b! (zero? t2-9) cfg-35 :delay (set! t2-10 (+ a3-0 -75)))
|
||||
(b! (zero? t2-10) cfg-35 :delay (set! t2-11 (+ a3-0 -106)))
|
||||
(b! (zero? t2-11) cfg-3 :delay (set! t2-12 (+ a3-0 -74)))
|
||||
(b! (zero? t2-12) cfg-3 :delay (set! t2-13 (+ a3-0 -104)))
|
||||
(b! (zero? t2-13) cfg-37 :delay (set! t2-14 (+ a3-0 -72)))
|
||||
(b! (zero? t2-14) cfg-37 :delay (set! t2-15 (+ a3-0 -118)))
|
||||
(b! (zero? t2-15) cfg-3 :delay (set! t2-16 (+ a3-0 -86)))
|
||||
(b! (zero? t2-16) cfg-3 :delay (set! t2-17 (+ a3-0 -48)))
|
||||
(b! (< (the-as int t2-17) 0) cfg-45 :delay (set! t3-0 (+ a3-0 -57)))
|
||||
(b! (> (the-as int t3-0) 0) cfg-45 :delay (.sll t3-1 t1-0 2))
|
||||
(let ((a3-1 (+ t1-0 t3-1)))
|
||||
(nop!)
|
||||
(.sll a3-2 a3-1 1)
|
||||
)
|
||||
(nop!)
|
||||
(b! #t cfg-14 :delay (set! t1-0 (+ a3-2 t2-17)))
|
||||
(label cfg-32)
|
||||
(b! (nonzero? t1-0) cfg-34 :delay (set! a2-4 *font12-table*))
|
||||
(set! a2-2 a2-4)
|
||||
(let ((a3-3 -33))
|
||||
(.lvf vf13 (&-> a1-4 size1-small quad))
|
||||
(nop!)
|
||||
(.lvf vf14 (&-> a1-4 size2-small quad))
|
||||
(b! #t cfg-3 :delay (set! v1-0 (logand v1-0 a3-3)))
|
||||
)
|
||||
(label cfg-34)
|
||||
(nop!)
|
||||
(set! a2-2 *font24-table*)
|
||||
(nop!)
|
||||
(.lvf vf13 (&-> a1-4 size1-large quad))
|
||||
(nop!)
|
||||
(.lvf vf14 (&-> a1-4 size2-large quad))
|
||||
(b! #t cfg-3 :delay (set! v1-0 (logior v1-0 32)))
|
||||
(label cfg-35)
|
||||
(let ((a3-4 -3))
|
||||
(nop!)
|
||||
(b! (zero? t1-0) cfg-3 :delay (set! v1-0 (logand v1-0 a3-4)))
|
||||
)
|
||||
(b! #t cfg-3 :delay (set! v1-0 (logior v1-0 2)))
|
||||
(label cfg-37)
|
||||
(.mov vf1 t1-0)
|
||||
(init-vf0-vector)
|
||||
(.lvf vf25 (&-> arg1 context-vec quad))
|
||||
(.lvf vf23 (&-> arg1 origin quad))
|
||||
(.lvf vf24 (&-> arg1 origin quad))
|
||||
(let ((flags (-> arg1 flags))
|
||||
(work *font-work*))
|
||||
(.lvf vf1 (&-> *video-parms* relative-x-scale-reciprical))
|
||||
(.mul.vf vf25 vf25 vf1 :mask #b11)
|
||||
(.mul.vf vf23 vf23 vf1 :mask #b11)
|
||||
;; hack! fixes small font widescreen
|
||||
(unless (logtest? (-> arg1 flags) (font-flags pc-hack))
|
||||
(.mul.vf vf24 vf24 vf1 :mask #b11)
|
||||
)
|
||||
(let ((a3-5 (+ t0-4 -45)))
|
||||
(b! (zero? t0-4) cfg-41 :delay (.itof.vf vf1 vf1))
|
||||
(b! (zero? a3-5) cfg-40 :delay (nop!))
|
||||
)
|
||||
(b! #t cfg-3 :delay (.add.x.vf vf23 vf23 vf1 :mask #b1))
|
||||
(label cfg-40)
|
||||
(b! #t cfg-3 :delay (.sub.x.vf vf23 vf23 vf1 :mask #b1))
|
||||
(label cfg-41)
|
||||
(b! #t cfg-3 :delay (.add.x.vf vf23 vf0 vf1 :mask #b1))
|
||||
(label cfg-42)
|
||||
(b! #t cfg-3 :delay (.svf (&-> a1-4 save quad) vf23))
|
||||
(label cfg-43)
|
||||
(b! #t cfg-3 :delay (.lvf vf23 (&-> a1-4 save quad)))
|
||||
(label cfg-44)
|
||||
(let ((a3-6 (-> (the-as (pointer uint8) arg0) 4)))
|
||||
(set! arg0 (the-as string (&-> (the-as (pointer uint8) arg0) 1)))
|
||||
(nop!)
|
||||
(let ((a3-7 (logand a3-6 127)))
|
||||
(nop!)
|
||||
(let ((a3-8 (+ a3-7 255)))
|
||||
(b! #t cfg-48 :delay (.sll t0-5 a3-8 4))
|
||||
(set! (-> work str-ptr) (the-as uint arg0))
|
||||
(set! (-> work flags) flags)
|
||||
(.mov.vf vf1 vf0)
|
||||
(let ((kerning-table (cond
|
||||
((logtest? flags (font-flags large))
|
||||
(.lvf vf13 (&-> work size1-large quad))
|
||||
(.lvf vf14 (&-> work size2-large quad))
|
||||
*font24-table*)
|
||||
(else
|
||||
(.lvf vf13 (&-> work size1-small quad))
|
||||
(.lvf vf14 (&-> work size2-small quad))
|
||||
*font12-table*)
|
||||
)))
|
||||
(label cfg-3)
|
||||
(let ((cur-char (-> arg0 data 0)))
|
||||
(set! arg0 (the-as string (&-> (the-as (pointer uint8) arg0) 1)))
|
||||
(if (zero? cur-char) (goto cfg-51))
|
||||
(when (= cur-char 1)
|
||||
(let ((a3-6 (-> arg0 data 0)))
|
||||
(set! arg0 (the-as string (&-> (the-as (pointer uint8) arg0) 1)))
|
||||
(set! cur-char (+ (logand a3-6 127) 255))
|
||||
(goto cfg-48)
|
||||
)
|
||||
)
|
||||
(when (= cur-char #\~)
|
||||
(set! cur-char (-> arg0 data 0))
|
||||
(set! arg0 (the-as string (&-> (the-as (pointer uint8) arg0) 1)))
|
||||
(if (zero? cur-char) (goto cfg-51))
|
||||
(when (or (= cur-char #\Y) (= cur-char #\y))
|
||||
(.svf (&-> work save quad) vf23)
|
||||
(goto cfg-3))
|
||||
(when (or (= cur-char #\Z) (= cur-char #\z))
|
||||
(.lvf vf23 (&-> work save quad))
|
||||
(goto cfg-3))
|
||||
(let ((sign-char (if (or (= cur-char #\-) (= cur-char #\+)) cur-char 0))
|
||||
(arg-val 0))
|
||||
(when (or (nonzero? sign-char)
|
||||
(and (>= cur-char #\0) (<= cur-char #\9)))
|
||||
(label cfg-14)
|
||||
(set! cur-char (-> arg0 data 0))
|
||||
(set! arg0 (the-as string (&-> (the-as (pointer uint8) arg0) 1)))
|
||||
(if (zero? cur-char) (goto cfg-51))
|
||||
(case cur-char
|
||||
((#\n #\N)
|
||||
(cond
|
||||
((nonzero? arg-val)
|
||||
(.lvf vf13 (&-> work size1-large quad))
|
||||
(.lvf vf14 (&-> work size2-large quad))
|
||||
(set! kerning-table *font24-table*)
|
||||
(logior! flags (font-flags large)))
|
||||
(else
|
||||
(.lvf vf13 (&-> work size1-small quad))
|
||||
(.lvf vf14 (&-> work size2-small quad))
|
||||
(set! kerning-table *font12-table*)
|
||||
(logclear! flags (font-flags large)))
|
||||
)
|
||||
(goto cfg-3)
|
||||
)
|
||||
((#\l #\L #\w #\W #\j #\J #\v #\V)
|
||||
(goto cfg-3)
|
||||
)
|
||||
((#\k #\K)
|
||||
(if (zero? arg-val)
|
||||
(logclear! flags (font-flags kerning))
|
||||
(logior! flags (font-flags kerning)))
|
||||
(goto cfg-3)
|
||||
)
|
||||
((#\h #\H)
|
||||
(.mov vf1 arg-val)
|
||||
(.itof.vf vf1 vf1)
|
||||
(cond
|
||||
((zero? sign-char)
|
||||
(.add.x.vf vf23 vf0 vf1 :mask #b1)
|
||||
)
|
||||
((= sign-char #\-)
|
||||
(.sub.x.vf vf23 vf23 vf1 :mask #b1)
|
||||
)
|
||||
(else
|
||||
(.add.x.vf vf23 vf23 vf1 :mask #b1)
|
||||
)
|
||||
)
|
||||
(goto cfg-3)
|
||||
)
|
||||
)
|
||||
(when (and (>= cur-char #\0) (<= cur-char #\9))
|
||||
(set! arg-val (+ (* arg-val 10) (- cur-char #\0)))
|
||||
(goto cfg-14)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(cond
|
||||
((and (!= cur-char 10) (!= cur-char 13))
|
||||
(label cfg-48)
|
||||
(.lvf vf5 (&-> kerning-table (- cur-char 16) quad))
|
||||
(.mul.vf vf19 vf5 vf13)
|
||||
(if (logtest? flags (font-flags kerning))
|
||||
(.add.w.vf vf23 vf23 vf19 :mask #b1)
|
||||
(.add.w.vf vf23 vf23 vf14 :mask #b1))
|
||||
)
|
||||
(else
|
||||
(.add.x.vf vf23 vf0 vf24 :mask #b1)
|
||||
)
|
||||
)
|
||||
(goto cfg-3)
|
||||
)
|
||||
)
|
||||
)
|
||||
(label cfg-45)
|
||||
(nop!)
|
||||
(.sll t0-5 a3-0 4)
|
||||
(nop!)
|
||||
(b! (= a3-0 10) cfg-47 :delay (set! a3-9 (+ a3-0 -13)))
|
||||
)
|
||||
(b! (nonzero? a3-9) cfg-48 :delay (nop!))
|
||||
(label cfg-47)
|
||||
(b! #t cfg-3 :delay (.add.x.vf vf23 vf0 vf24 :mask #b1))
|
||||
(label cfg-48)
|
||||
(.addu a3-10 t0-5 a2-2)
|
||||
)
|
||||
)
|
||||
(nop!)
|
||||
(.lvf vf5 (+ a3-10 -256))
|
||||
(nop!)
|
||||
(.mul.vf vf19 vf5 vf13)
|
||||
(b! (zero? (logand v1-0 2)) cfg-50 :delay (nop!))
|
||||
(label cfg-51)
|
||||
(.sub.vf vf23 vf23 vf24)
|
||||
(.mov v0-0 vf23)
|
||||
v0-0
|
||||
)
|
||||
(b! #t cfg-3 :delay (.add.w.vf vf23 vf23 vf19 :mask #b1))
|
||||
(label cfg-50)
|
||||
(b! #t cfg-3 :delay (.add.w.vf vf23 vf23 vf14 :mask #b1))
|
||||
(label cfg-51)
|
||||
(.sub.vf vf23 vf23 vf24)
|
||||
(.mov v0-0 vf23)
|
||||
v0-0
|
||||
)
|
||||
)
|
||||
|
||||
(defun draw-string-xy ((str string) (buf dma-buffer) (x int) (y int) (color font-color) (flags font-flags))
|
||||
|
@ -117,7 +117,7 @@
|
||||
(disable-level-text-file-loading)
|
||||
(protect ((-> *pc-settings* text-language))
|
||||
;; swap language and load new text files
|
||||
(set! (-> *pc-settings* text-language) (the pc-subtitle-lang (-> *setting-control* current language)))
|
||||
(set! (-> *pc-settings* text-language) (the pc-language (-> *setting-control* current language)))
|
||||
(load-level-text-files 0)))
|
||||
(let ((s4-0 (+ (- arg0) (the int (* 1.5 (the float (-> *video-parms* screen-sy))))))
|
||||
(gp-0 2815)
|
||||
|
@ -465,7 +465,7 @@
|
||||
(none)
|
||||
)
|
||||
|
||||
(defun print-game-text ((str string) (font-ctxt font-context) (opaque symbol) (alpha int) (line-height int))
|
||||
(defun print-game-text ((str string) (font-ctxt font-context) (no-draw symbol) (alpha int) (line-height int))
|
||||
"Print text. Not worth commenting until we get stack variables in lets, I think"
|
||||
(local-vars
|
||||
(sv-112 float)
|
||||
@ -619,7 +619,7 @@
|
||||
(if (nonzero? (-> *game-text-line* data 0))
|
||||
(set! sv-168 (+ sv-168 1))
|
||||
)
|
||||
(when (not opaque)
|
||||
(when (not no-draw)
|
||||
(let* ((s1-1 (-> *display* frames (-> *display* on-screen) frame global-buf))
|
||||
(s2-1 (-> s1-1 base))
|
||||
)
|
||||
|
@ -403,7 +403,11 @@
|
||||
(defstep :in "game/assets/jak1/game_subtitle.gp"
|
||||
:tool 'subtitle
|
||||
:out '("$OUT/iso/0SUBTIT.TXT"
|
||||
"$OUT/iso/1SUBTIT.TXT"
|
||||
"$OUT/iso/2SUBTIT.TXT"
|
||||
"$OUT/iso/3SUBTIT.TXT"
|
||||
"$OUT/iso/4SUBTIT.TXT"
|
||||
"$OUT/iso/5SUBTIT.TXT"
|
||||
"$OUT/iso/6SUBTIT.TXT")
|
||||
)
|
||||
|
||||
|
@ -429,7 +429,7 @@
|
||||
)
|
||||
|
||||
(defun dm-subtitle-language ((blang int) (msg debug-menu-msg))
|
||||
(let ((lang (the pc-subtitle-lang (/ blang 8))))
|
||||
(let ((lang (the pc-language (/ blang 8))))
|
||||
(when (= msg (debug-menu-msg press))
|
||||
(set! (-> *pc-settings* subtitle-language) lang))
|
||||
(= (-> *pc-settings* subtitle-language) lang)
|
||||
@ -437,7 +437,7 @@
|
||||
)
|
||||
|
||||
(defun dm-text-language ((blang int) (msg debug-menu-msg))
|
||||
(let ((lang (the pc-subtitle-lang (/ blang 8))))
|
||||
(let ((lang (the pc-language (/ blang 8))))
|
||||
(when (= msg (debug-menu-msg press))
|
||||
(set! (-> *pc-settings* text-language) lang))
|
||||
(= (-> *pc-settings* text-language) lang)
|
||||
|
@ -692,7 +692,6 @@
|
||||
(("lod-force-ocean") (set! (-> obj lod-force-ocean) (file-stream-read-int file)))
|
||||
(("lod-force-actor") (set! (-> obj lod-force-actor) (file-stream-read-int file)))
|
||||
(("game-language") (set-game-language! obj (the-as language-enum (file-stream-read-int file))))
|
||||
(("text-language") (set! (-> obj text-language) (the-as pc-subtitle-lang (file-stream-read-int file))))
|
||||
(("subtitle-speaker") (set! (-> obj subtitle-speaker?) (file-stream-read-symbol file)))
|
||||
|
||||
(("ignore-controller-win-unfocused?") (set-ignore-controller-in-bg! obj (file-stream-read-symbol file)))
|
||||
@ -834,7 +833,6 @@
|
||||
(format file " (music-fadeout? ~A)~%" (-> obj music-fadeout?))
|
||||
(format file " (hinttitles? ~A)~%" (-> obj hinttitles?))
|
||||
(format file " (game-language ~D)~%" (get-game-language obj))
|
||||
(format file " (text-language ~D)~%" (-> obj text-language))
|
||||
(format file " (subtitle-speaker ~A)~%" (-> obj subtitle-speaker?))
|
||||
|
||||
#|
|
||||
|
@ -81,39 +81,6 @@
|
||||
)
|
||||
|
||||
|
||||
;; subtitle languages.
|
||||
(defenum pc-subtitle-lang
|
||||
:type uint16
|
||||
(english 0)
|
||||
(french 1)
|
||||
(german 2)
|
||||
(spanish 3)
|
||||
(italian 4)
|
||||
(japanese 5)
|
||||
(uk-english 6)
|
||||
|
||||
;; additional languages.
|
||||
;; these don't neccessarily have to work but I'm future-proofing a bit here, just in case.
|
||||
|
||||
;; languages that use the existing glyphs
|
||||
(portuguese 7)
|
||||
(finnish 8)
|
||||
(swedish 9)
|
||||
(danish 10)
|
||||
(norwegian 11)
|
||||
(dutch 12)
|
||||
(br-portuguese 13)
|
||||
(hungarian 14)
|
||||
(catalan 15)
|
||||
(icelandic 16)
|
||||
|
||||
;; jak 1 has no glyphs for korean or cyrillic.
|
||||
(korean 98) ;; future-proofing here
|
||||
(russian 97) ;; same thing
|
||||
|
||||
(custom 100) ;; temp
|
||||
)
|
||||
|
||||
|
||||
;; concept arts
|
||||
(defenum pc-jak1-concept-art
|
||||
@ -275,7 +242,6 @@
|
||||
(force-actors? symbol) ;; skips vis check for actor entity
|
||||
(use-vis? symbol) ;; if off, don't use vis trees. this MUST be off for custom (non-cropping) aspect ratios.
|
||||
(hinttitles? symbol) ;; if on, non-cutscene subtitles will show up
|
||||
(text-language pc-subtitle-lang) ;; language for game text
|
||||
(subtitle-speaker? symbol) ;; #f (force off), #t (force on), auto (on for offscreen)
|
||||
(first-camera-h-inverted? symbol) ;; first-person horizontal camera inverted
|
||||
(first-camera-v-inverted? symbol) ;; first-person vertical camera inverted
|
||||
@ -535,7 +501,6 @@
|
||||
"Set the default misc settings"
|
||||
|
||||
(set! (-> obj force-actors?) #f)
|
||||
(set! (-> obj text-language) (the pc-subtitle-lang (scf-get-language)))
|
||||
(set! (-> obj hinttitles?) #t)
|
||||
(set! (-> obj subtitle-speaker?) 'auto)
|
||||
(reset-original-camera obj)
|
||||
|
@ -19,12 +19,40 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
;; pc enum for languages. this is the game's languages + custom ones.
|
||||
(defenum pc-language
|
||||
:type uint16
|
||||
(english 0)
|
||||
(french 1)
|
||||
(german 2)
|
||||
(spanish 3)
|
||||
(italian 4)
|
||||
(japanese 5)
|
||||
(uk-english 6)
|
||||
;; custom
|
||||
(portuguese 7)
|
||||
(finnish 8)
|
||||
(swedish 9)
|
||||
(danish 10)
|
||||
(norwegian 11)
|
||||
(dutch 12)
|
||||
(br-portuguese 13)
|
||||
(hungarian 14)
|
||||
(catalan 15)
|
||||
(icelandic 16)
|
||||
(korean 17)
|
||||
(russian 18)
|
||||
|
||||
(custom 999) ;; temp
|
||||
)
|
||||
|
||||
;; The Jak 1 version of the pc-settings object.
|
||||
(deftype pc-settings-jak1 (pc-settings)
|
||||
(
|
||||
(skip-movies? symbol) ;; if on, enable cutscene skipping
|
||||
(subtitles? symbol) ;; if on, cutscene subtitles will show up
|
||||
(subtitle-language pc-subtitle-lang) ;; language for subtitles
|
||||
(text-language pc-language) ;; language for game text
|
||||
(subtitle-language pc-language) ;; language for subtitles
|
||||
(money-starburst? symbol) ;; add a starburst to the money
|
||||
(extra-hud? symbol) ;; extra hud elements.
|
||||
)
|
||||
@ -72,18 +100,18 @@
|
||||
"Set the default misc settings"
|
||||
|
||||
((method-of-type pc-settings reset-misc) obj)
|
||||
(set! (-> obj text-language) (the pc-subtitle-lang (scf-get-language)))
|
||||
(set! (-> obj subtitle-language) (the pc-subtitle-lang (scf-get-language)))
|
||||
(set! (-> obj text-language) (the pc-language (scf-get-language)))
|
||||
(set! (-> obj subtitle-language) (the pc-language (scf-get-language)))
|
||||
(set! (-> obj skip-movies?) #t)
|
||||
(set! (-> obj subtitles?) *debug-segment*)
|
||||
(cond
|
||||
((and (= *jak1-territory* GAME_TERRITORY_SCEE) (= (-> obj text-language) (pc-subtitle-lang english)))
|
||||
(set! (-> obj text-language) (pc-subtitle-lang uk-english))
|
||||
;(set! (-> obj subtitle-language) (pc-subtitle-lang uk-english))
|
||||
((and (= *jak1-territory* GAME_TERRITORY_SCEE) (= (-> obj text-language) (pc-language english)))
|
||||
(set! (-> obj text-language) (pc-language uk-english))
|
||||
;(set! (-> obj subtitle-language) (pc-language uk-english))
|
||||
)
|
||||
((= *jak1-territory* GAME_TERRITORY_SCEI)
|
||||
(set! (-> obj text-language) (pc-subtitle-lang japanese))
|
||||
;(set! (-> obj subtitle-language) (pc-subtitle-lang japanese))
|
||||
(set! (-> obj text-language) (pc-language japanese))
|
||||
;(set! (-> obj subtitle-language) (pc-language japanese))
|
||||
)
|
||||
(else
|
||||
))
|
||||
|
@ -337,7 +337,8 @@
|
||||
(("extra-hud?") (set! (-> obj extra-hud?) (file-stream-read-symbol file)))
|
||||
(("skip-movies?") (set! (-> obj skip-movies?) (file-stream-read-symbol file)))
|
||||
(("subtitles?") (set! (-> obj subtitles?) (file-stream-read-symbol file)))
|
||||
(("subtitle-language") (set! (-> obj subtitle-language) (the-as pc-subtitle-lang (file-stream-read-int file))))
|
||||
(("subtitle-language") (set! (-> obj subtitle-language) (the-as pc-language (file-stream-read-int file))))
|
||||
(("text-language") (set! (-> obj text-language) (the-as pc-language (file-stream-read-int file))))
|
||||
)
|
||||
0)
|
||||
|
||||
@ -350,6 +351,7 @@
|
||||
(format file " (skip-movies? ~A)~%" (-> obj skip-movies?))
|
||||
(format file " (subtitles? ~A)~%" (-> obj subtitles?))
|
||||
(format file " (subtitle-language ~D)~%" (-> obj subtitle-language))
|
||||
(format file " (text-language ~D)~%" (-> obj text-language))
|
||||
0)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -69,7 +69,7 @@
|
||||
(deftype progress-carousell-state (structure)
|
||||
((int-backup int)
|
||||
(symbol-backup symbol)
|
||||
(subtitle-backup pc-subtitle-lang)
|
||||
(subtitle-backup pc-language)
|
||||
(aspect-native-choice symbol)
|
||||
(current-carousell (array text-id))
|
||||
|
||||
@ -506,7 +506,7 @@
|
||||
|
||||
|
||||
(defmacro def-language-remap-info (name langs)
|
||||
`(define ,name (quote ,(apply (lambda (x) `((the binteger (text-id ,x)) (the binteger (pc-subtitle-lang ,x)))) langs)))
|
||||
`(define ,name (quote ,(apply (lambda (x) `((the binteger (text-id ,x)) (the binteger (pc-language ,x)))) langs)))
|
||||
)
|
||||
|
||||
(def-language-remap-info *language-remap-info-pc*
|
||||
@ -756,10 +756,10 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
(defun get-language-name ((lang pc-subtitle-lang))
|
||||
(defun get-language-name ((lang pc-language))
|
||||
"get the text-id from a lang"
|
||||
(dolist (item *language-remap-info-pc*)
|
||||
(when (= lang (the pc-subtitle-lang (/ (the int (cadr (car item))) 8)))
|
||||
(when (= lang (the pc-language (/ (the int (cadr (car item))) 8)))
|
||||
(return (the text-id (/ (the int (car (car item))) 8))))
|
||||
)
|
||||
(text-id zero)
|
||||
@ -1862,12 +1862,12 @@
|
||||
)
|
||||
(((game-option-type language-subtitles))
|
||||
(let ((lang (assoc (the binteger (-> *subtitle-languages* (-> *progress-carousell* int-backup))) *language-remap-info-pc*)))
|
||||
(set! (-> *pc-settings* subtitle-language) (the pc-subtitle-lang (/ (the int (cadr lang)) 8)))
|
||||
(set! (-> *pc-settings* subtitle-language) (the pc-language (/ (the int (cadr lang)) 8)))
|
||||
)
|
||||
)
|
||||
(((game-option-type language-text))
|
||||
(let ((lang (assoc (the binteger (-> *text-languages* (-> *progress-carousell* int-backup))) *language-remap-info-pc*)))
|
||||
(set! (-> *pc-settings* text-language) (the pc-subtitle-lang (/ (the int (cadr lang)) 8)))
|
||||
(set! (-> *pc-settings* text-language) (the pc-language (/ (the int (cadr lang)) 8)))
|
||||
)
|
||||
(if (not (-> *progress-carousell* transition))
|
||||
(load-level-text-files (-> obj display-level-index)))
|
||||
|
@ -89,7 +89,7 @@
|
||||
;; the global subtitle text info bank
|
||||
(deftype subtitle-text-info (basic)
|
||||
((length int32)
|
||||
(lang pc-subtitle-lang)
|
||||
(lang pc-language)
|
||||
(dummy int32)
|
||||
(data subtitle-text :inline :dynamic)
|
||||
)
|
||||
@ -296,7 +296,7 @@
|
||||
`(begin
|
||||
(asm-text-file subtitle :files ("game/assets/game_subtitle.gp"))
|
||||
(if *subtitle-text*
|
||||
(+! (-> *subtitle-text* lang) (the-as pc-subtitle-lang 1)))
|
||||
(+! (-> *subtitle-text* lang) 1))
|
||||
(load-level-subtitle-files 0)))
|
||||
|
||||
(defmacro reload-text ()
|
||||
@ -316,7 +316,7 @@
|
||||
|
||||
|
||||
|
||||
(defun-recursive print-game-subtitle float ((str string) (font-ctxt font-context) (opaque symbol) (alpha int) (line-height int))
|
||||
(defun-recursive print-game-subtitle float ((str string) (font-ctxt font-context) (no-draw symbol) (alpha int) (line-height int))
|
||||
"Print text. Not worth commenting until we get stack variables in lets, I think"
|
||||
(local-vars
|
||||
(sv-112 float)
|
||||
@ -469,7 +469,7 @@
|
||||
(if (nonzero? (-> *game-text-line* data 0))
|
||||
(set! sv-168 (+ sv-168 1))
|
||||
)
|
||||
(when (not opaque)
|
||||
(when (not no-draw)
|
||||
(let* ((s1-1 (-> *display* frames (-> *display* on-screen) frame global-buf))
|
||||
(s2-1 (-> s1-1 base))
|
||||
)
|
||||
@ -693,19 +693,20 @@
|
||||
(((pc-subtitle-channel hint) (pc-subtitle-channel hint-named))
|
||||
;; hint! find it. or else.
|
||||
(set! (-> self hint-subtitle?) #t)
|
||||
(awhen (if (= (-> self cur-channel) (pc-subtitle-channel hint-named))
|
||||
(get-scene-by-name *subtitle-text* (-> self cur-channel) (-> self spool-name))
|
||||
(get-scene-by-text-id *subtitle-text* (-> self cur-channel) (-> self text-id))
|
||||
)
|
||||
|
||||
(let ((pos (subtitle-str-adjust (current-str-pos (-> *hint-semaphore* 0 sound-id)))))
|
||||
;; find closest keyframe
|
||||
(dotimes (i (-> it length))
|
||||
(when (>= pos (-> it keyframes i frame))
|
||||
(set! keyframe (-> it keyframes i)))
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((scene (get-scene-by-text-id *subtitle-text* (pc-subtitle-channel hint) (-> self text-id))))
|
||||
(if (not scene)
|
||||
(set! scene (get-scene-by-name *subtitle-text* (pc-subtitle-channel hint-named) (-> self spool-name))))
|
||||
|
||||
(when scene
|
||||
(let ((pos (subtitle-str-adjust (current-str-pos (-> *hint-semaphore* 0 sound-id)))))
|
||||
;; find closest keyframe
|
||||
(dotimes (i (-> scene length))
|
||||
(when (>= pos (-> scene keyframes i frame))
|
||||
(set! keyframe (-> scene keyframes i)))
|
||||
)
|
||||
)
|
||||
))
|
||||
)
|
||||
))
|
||||
|
||||
|
@ -1,384 +0,0 @@
|
||||
("ENGINE.CGO"
|
||||
("types-h.o"
|
||||
"vu1-macros.o"
|
||||
"math.o"
|
||||
"vector-h.o"
|
||||
"gravity-h.o"
|
||||
"bounding-box-h.o"
|
||||
"matrix-h.o"
|
||||
"quaternion-h.o"
|
||||
"euler-h.o"
|
||||
"transform-h.o"
|
||||
"geometry-h.o"
|
||||
"trigonometry-h.o"
|
||||
"transformq-h.o"
|
||||
"bounding-box.o"
|
||||
"matrix.o"
|
||||
"transform.o"
|
||||
"quaternion.o"
|
||||
"euler.o"
|
||||
"trigonometry.o"
|
||||
"gsound-h.o"
|
||||
"timer-h.o"
|
||||
"vif-h.o"
|
||||
"dma-h.o"
|
||||
"video-h.o"
|
||||
"vu1-user-h.o"
|
||||
"profile-h.o"
|
||||
"dma.o"
|
||||
"dma-buffer.o"
|
||||
"dma-bucket.o"
|
||||
"dma-disasm.o"
|
||||
"pckernel-h.o" ;; added
|
||||
"pckernel-impl.o" ;; added
|
||||
"pc-debug-common.o" ;; added
|
||||
"pad.o"
|
||||
"gs.o"
|
||||
"display-h.o"
|
||||
"geometry.o"
|
||||
"timer.o"
|
||||
"vector.o"
|
||||
"file-io.o"
|
||||
"loader-h.o"
|
||||
"texture-h.o"
|
||||
"texture-anim-h.o"
|
||||
"lights-h.o"
|
||||
"mood-h.o"
|
||||
"level-h.o"
|
||||
"capture-h.o"
|
||||
"math-camera-h.o"
|
||||
"math-camera.o"
|
||||
"font-h.o"
|
||||
"decomp-h.o"
|
||||
"profile.o"
|
||||
"display.o"
|
||||
"connect.o"
|
||||
"text-id-h.o"
|
||||
"text-h.o"
|
||||
"camera-defs-h.o"
|
||||
"trail-h.o"
|
||||
"minimap-h.o"
|
||||
"bigmap-h.o"
|
||||
"settings-h.o"
|
||||
"capture.o"
|
||||
"memory-usage-h.o"
|
||||
"blit-displays-h.o"
|
||||
"texture.o"
|
||||
"main-h.o"
|
||||
"mspace-h.o"
|
||||
"drawable-h.o"
|
||||
"drawable-group-h.o"
|
||||
"drawable-inline-array-h.o"
|
||||
"draw-node-h.o"
|
||||
"drawable-tree-h.o"
|
||||
"drawable-actor-h.o"
|
||||
"region-h.o"
|
||||
"traffic-h.o"
|
||||
"game-task-h.o"
|
||||
"task-control-h.o"
|
||||
"generic-h.o"
|
||||
"sky-h.o"
|
||||
"ocean-h.o"
|
||||
"ocean-trans-tables.o"
|
||||
"ocean-tables.o"
|
||||
"ocean-frames.o"
|
||||
"time-of-day-h.o"
|
||||
"art-h.o"
|
||||
"generic-vu1-h.o"
|
||||
"merc-h.o"
|
||||
"generic-merc-h.o"
|
||||
"generic-tie-h.o"
|
||||
"generic-work-h.o"
|
||||
"shadow-cpu-h.o"
|
||||
"shadow-vu1-h.o"
|
||||
"memcard-h.o"
|
||||
"game-info-h.o"
|
||||
"gui-h.o"
|
||||
"ambient-h.o"
|
||||
"speech-h.o"
|
||||
"wind-h.o"
|
||||
"prototype-h.o"
|
||||
"joint-h.o"
|
||||
"bones-h.o"
|
||||
"foreground-h.o"
|
||||
"engines.o"
|
||||
"lightning-h.o"
|
||||
"res-h.o"
|
||||
"res.o"
|
||||
"lights.o"
|
||||
"dynamics-h.o"
|
||||
"surface-h.o"
|
||||
"pat-h.o"
|
||||
"fact-h.o"
|
||||
"aligner-h.o"
|
||||
"penetrate-h.o"
|
||||
"game-h.o"
|
||||
"script-h.o"
|
||||
"scene-h.o"
|
||||
"sync-info-h.o"
|
||||
"pov-camera-h.o"
|
||||
"smush-control-h.o"
|
||||
"debug-h.o"
|
||||
"joint-mod-h.o"
|
||||
"collide-func-h.o"
|
||||
"collide-mesh-h.o"
|
||||
"collide-shape-h.o"
|
||||
"generic-obs-h.o"
|
||||
"trajectory-h.o"
|
||||
"collide-target-h.o"
|
||||
"collide-touch-h.o"
|
||||
"collide-edge-grab-h.o"
|
||||
"process-drawable-h.o"
|
||||
"process-focusable.o"
|
||||
"process-taskable-h.o"
|
||||
"focus.o"
|
||||
"effect-control-h.o"
|
||||
"collide-frag-h.o"
|
||||
"collide-hash-h.o"
|
||||
"chain-physics-h.o"
|
||||
"projectile-h.o"
|
||||
"find-nearest-h.o"
|
||||
"target-h.o"
|
||||
"stats-h.o"
|
||||
"bsp-h.o"
|
||||
"collide-cache-h.o"
|
||||
"collide-h.o"
|
||||
"shrubbery-h.o"
|
||||
"tie-h.o"
|
||||
"tfrag-h.o"
|
||||
"background-h.o"
|
||||
"subdivide-h.o"
|
||||
"entity-h.o"
|
||||
"sprite-h.o"
|
||||
"simple-sprite-h.o"
|
||||
"eye-h.o"
|
||||
"sparticle-launcher-h.o"
|
||||
"sparticle-h.o"
|
||||
"actor-link-h.o"
|
||||
"camera-h.o"
|
||||
"cam-debug-h.o"
|
||||
"cam-interface-h.o"
|
||||
"cam-update-h.o"
|
||||
"hud-h.o"
|
||||
"progress-h.o"
|
||||
"rpc-h.o"
|
||||
"path-h.o"
|
||||
"nav-mesh-h.o"
|
||||
"nav-control-h.o"
|
||||
"spatial-hash-h.o"
|
||||
"actor-hash-h.o"
|
||||
"load-dgo.o"
|
||||
"ramdisk.o"
|
||||
"gsound.o"
|
||||
"transformq.o"
|
||||
"collide-func.o"
|
||||
"joint.o"
|
||||
"joint-mod.o"
|
||||
"chain-physics.o"
|
||||
"cylinder.o"
|
||||
"wind-work.o"
|
||||
"wind.o"
|
||||
"bsp.o"
|
||||
"subdivide.o"
|
||||
"sprite.o"
|
||||
"sprite-distort.o"
|
||||
"sprite-glow.o"
|
||||
"debug-sphere.o"
|
||||
"debug.o"
|
||||
"history.o"
|
||||
"merc-vu1.o"
|
||||
"emerc-vu1.o"
|
||||
"merc-blend-shape.o"
|
||||
"merc.o"
|
||||
"emerc.o"
|
||||
"ripple.o"
|
||||
"bones.o"
|
||||
"debug-foreground.o"
|
||||
"foreground.o"
|
||||
"generic-vu0.o"
|
||||
"generic-vu1.o"
|
||||
"generic-effect.o"
|
||||
"generic-merc.o"
|
||||
"generic-tie.o"
|
||||
"shadow-cpu.o"
|
||||
"shadow-vu1.o"
|
||||
"warp.o"
|
||||
"texture-anim.o"
|
||||
"texture-anim-funcs.o"
|
||||
"texture-anim-tables.o"
|
||||
"blit-displays.o"
|
||||
"font-data.o"
|
||||
"font.o"
|
||||
"decomp.o"
|
||||
"background.o"
|
||||
"draw-node.o"
|
||||
"shrubbery.o"
|
||||
"shrub-work.o"
|
||||
"tfrag-near.o"
|
||||
"tfrag.o"
|
||||
"tfrag-methods.o"
|
||||
"tfrag-work.o"
|
||||
"tie.o"
|
||||
"etie-vu1.o"
|
||||
"etie-near-vu1.o"
|
||||
"tie-near.o"
|
||||
"tie-work.o"
|
||||
"tie-methods.o"
|
||||
"sync-info.o"
|
||||
"trajectory.o"
|
||||
"sparticle-launcher.o"
|
||||
"sparticle.o"
|
||||
"entity-table.o"
|
||||
"loader.o"
|
||||
"game-info.o"
|
||||
"game-task.o"
|
||||
"game-save.o"
|
||||
"settings.o"
|
||||
"autosplit-h.o" ;; added
|
||||
"autosplit.o" ;; added
|
||||
"speedruns-h.o" ;; added
|
||||
"speedruns.o" ;; added
|
||||
"mood-tables.o"
|
||||
"mood-tables2.o"
|
||||
"mood.o"
|
||||
"mood-funcs.o"
|
||||
"mood-funcs2.o"
|
||||
"weather-part.o"
|
||||
"time-of-day.o"
|
||||
"sky-data.o"
|
||||
"sky-tng.o"
|
||||
"load-state.o"
|
||||
"pc-debug-methods.o" ;; added
|
||||
"level-info.o"
|
||||
"level.o"
|
||||
"text.o"
|
||||
"collide-hash.o"
|
||||
"collide-probe.o"
|
||||
"collide-frag.o"
|
||||
"collide-mesh.o"
|
||||
"collide-touch.o"
|
||||
"collide-edge-grab.o"
|
||||
"collide-shape.o"
|
||||
"collide-shape-rider.o"
|
||||
"collide.o"
|
||||
;; "collide-planes.o"
|
||||
"spatial-hash.o"
|
||||
"actor-hash.o"
|
||||
"merc-death.o"
|
||||
"water-flow.o"
|
||||
"water-h.o"
|
||||
"camera.o"
|
||||
"cam-interface.o"
|
||||
"cam-master.o"
|
||||
"cam-states.o"
|
||||
"cam-states-dbg.o"
|
||||
"cam-combiner.o"
|
||||
"cam-update.o"
|
||||
"vol-h.o"
|
||||
"cam-layout.o"
|
||||
"cam-debug.o"
|
||||
"cam-start.o"
|
||||
"process-drawable.o"
|
||||
"ambient.o"
|
||||
"speech.o"
|
||||
"region.o"
|
||||
"fma-sphere.o"
|
||||
"script.o"
|
||||
"generic-obs.o"
|
||||
"lightning.o"
|
||||
"carry-h.o"
|
||||
"pilot-h.o"
|
||||
"gun-h.o"
|
||||
"board-h.o"
|
||||
"darkjak-h.o"
|
||||
"target-util.o"
|
||||
"target-part.o"
|
||||
"gun-part.o"
|
||||
"collide-reaction-target.o"
|
||||
"logic-target.o"
|
||||
"sidekick.o"
|
||||
"effect-control.o"
|
||||
"voicebox.o"
|
||||
"collectables-part.o"
|
||||
"debug-part.o"
|
||||
"find-nearest.o"
|
||||
"task-arrow.o"
|
||||
"projectile.o"
|
||||
"target-handler.o"
|
||||
"target-anim.o"
|
||||
"target.o"
|
||||
"target2.o"
|
||||
"target-swim.o"
|
||||
"target-carry.o"
|
||||
"target-darkjak.o"
|
||||
"target-death.o"
|
||||
"target-gun.o"
|
||||
"gun-util.o"
|
||||
"gun-blue-shot.o"
|
||||
"gun-yellow-shot.o"
|
||||
"gun-red-shot.o"
|
||||
"gun-dark-shot.o"
|
||||
"gun-states.o"
|
||||
"board-util.o"
|
||||
"target-board.o"
|
||||
"board-part.o"
|
||||
"board-states.o"
|
||||
"mech-h.o"
|
||||
"menu.o"
|
||||
"drawable.o"
|
||||
"drawable-group.o"
|
||||
"drawable-inline-array.o"
|
||||
"drawable-tree.o"
|
||||
"prototype.o"
|
||||
"main-collide.o"
|
||||
"video.o"
|
||||
"pckernel-common.o" ;; added
|
||||
"pckernel.o" ;; added
|
||||
"main.o"
|
||||
"collide-cache.o"
|
||||
"collide-debug.o"
|
||||
"relocate.o"
|
||||
"memory-usage.o"
|
||||
"entity.o"
|
||||
"path.o"
|
||||
"vol.o"
|
||||
"nav-mesh.o"
|
||||
"nav-control.o"
|
||||
"aligner.o"
|
||||
"water.o"
|
||||
"collectables.o"
|
||||
"task-control.o"
|
||||
"scene.o"
|
||||
"pov-camera.o"
|
||||
"powerups.o"
|
||||
"crates.o"
|
||||
"hud.o"
|
||||
"hud-classes.o"
|
||||
"progress-static.o"
|
||||
"progress.o"
|
||||
"progress-draw.o"
|
||||
"ocean.o"
|
||||
"ocean-vu0.o"
|
||||
"ocean-texture.o"
|
||||
"ocean-mid.o"
|
||||
"ocean-transition.o"
|
||||
"ocean-near.o"
|
||||
"minimap.o"
|
||||
"bigmap-data.o"
|
||||
"bigmap.o"
|
||||
"eye.o"
|
||||
"glist-h.o"
|
||||
"glist.o"
|
||||
"anim-tester.o"
|
||||
"viewer.o"
|
||||
"part-tester.o"
|
||||
"editable-h.o"
|
||||
"editable.o"
|
||||
"editable-player.o"
|
||||
"mysql-nav-graph.o"
|
||||
"nav-graph-editor.o"
|
||||
"sampler.o"
|
||||
"default-menu.o"
|
||||
"anim-tester-x.o" ;; added
|
||||
"default-menu-pc.o" ;; added
|
||||
))
|
@ -334,6 +334,8 @@
|
||||
"video.o"
|
||||
"pckernel-common.o" ;; added
|
||||
"pckernel.o" ;; added
|
||||
"subtitle2-h.o" ;; added
|
||||
"subtitle2.o" ;; added
|
||||
"main.o"
|
||||
"collide-cache.o"
|
||||
"collide-debug.o"
|
||||
@ -380,6 +382,7 @@
|
||||
"sampler.o"
|
||||
"default-menu.o"
|
||||
"anim-tester-x.o" ;; added
|
||||
"vag-player.o" ;; added
|
||||
"default-menu-pc.o" ;; added
|
||||
"dir-tpages.go"
|
||||
"tpage-11.go"
|
||||
|
@ -54,7 +54,7 @@
|
||||
(enemy-flag36 36)
|
||||
(enemy-flag37 37)
|
||||
(enemy-flag38 38)
|
||||
(enemy-flag39 39)
|
||||
(not-frustrated 39)
|
||||
(enemy-flag40 40)
|
||||
(enemy-flag41 41)
|
||||
(enemy-flag42 42)
|
||||
|
@ -175,9 +175,11 @@
|
||||
)
|
||||
(play-communicator-speech! arg0)
|
||||
)
|
||||
(set! s2-0 (lookup-gui-connection-id *gui-control* (-> arg0 name) (-> arg0 channel) (gui-action none)))
|
||||
(set! s2-0
|
||||
(the-as int (lookup-gui-connection-id *gui-control* (-> arg0 name) (-> arg0 channel) (gui-action none)))
|
||||
)
|
||||
(set! s2-0 (cond
|
||||
((zero? s2-0)
|
||||
((zero? (the-as sound-id s2-0))
|
||||
(let ((v1-17 (process-spawn talker :init talker-init arg0 arg2 arg3 :to arg1)))
|
||||
(cond
|
||||
(v1-17
|
||||
|
@ -734,7 +734,7 @@
|
||||
(quaternion-copy! (-> self root quat) (-> (the-as process-drawable (-> self parent 0)) root quat))
|
||||
(set! (-> self root scale quad) (-> (the-as process-drawable (-> self parent 0)) root scale quad))
|
||||
(when (-> arg3 art-level)
|
||||
(let ((a1-6 (entity-actor-from-level-name (the-as level (-> arg3 art-level)))))
|
||||
(let ((a1-6 (entity-actor-from-level-name (-> arg3 art-level))))
|
||||
(if a1-6
|
||||
(process-entity-set! self a1-6)
|
||||
)
|
||||
|
@ -643,6 +643,6 @@
|
||||
|
||||
(defmacro target-look-at-me! (&key trans &key (message 'nothing-special))
|
||||
"make target look at a trans in self. PC PORT NOTE : added check to see if lods have been set"
|
||||
`(if (and (logtest? (-> self draw status) (draw-control-status lod-set)) *target*)
|
||||
`(if (and (not (logtest? (-> self draw status) (draw-control-status uninited no-draw-temp))) *target*)
|
||||
(look-at! (-> *target* neck) ,trans ,message self)))
|
||||
|
||||
|
@ -2695,7 +2695,7 @@
|
||||
(a0-5 arg1)
|
||||
)
|
||||
(when (if (= a0-5 'test)
|
||||
(logtest? (continue-flags cf17) (-> (the-as continue-point v1-2) flags))
|
||||
(logtest? (continue-flags test) (-> (the-as continue-point v1-2) flags))
|
||||
#t
|
||||
)
|
||||
(let ((s2-0 (method-of-type pair new))
|
||||
|
@ -471,7 +471,7 @@
|
||||
(debug-menu-context-send-msg gp-0 (debug-menu-msg deactivate) (debug-menu-dest activation))
|
||||
)
|
||||
(set! (-> arg1 parent) arg0)
|
||||
(set! (-> arg0 items) (the-as pair (append! (-> arg0 items) (cons arg1 '()))))
|
||||
(set! (-> arg0 items) (the-as pair (append! (-> arg0 items) (dcons arg1 '())))) ;; changed to dcons
|
||||
(debug-menu-rebuild arg0)
|
||||
(if s4-0
|
||||
(debug-menu-context-send-msg gp-0 (debug-menu-msg activate) (debug-menu-dest activation))
|
||||
|
@ -270,6 +270,6 @@ This commonly includes things such as:
|
||||
;; WARN: Return type mismatch symbol vs object.
|
||||
(defun birth-viewer ((arg0 process) (arg1 entity-actor))
|
||||
(set! (-> arg0 type) viewer)
|
||||
(init-entity arg0 arg1 (the-as process viewer))
|
||||
(init-entity arg0 arg1 viewer)
|
||||
(the-as object #t)
|
||||
)
|
||||
|
@ -1348,7 +1348,7 @@
|
||||
(none)
|
||||
)
|
||||
|
||||
(defun main-debug-hook ()
|
||||
(defun-debug main-debug-hook ()
|
||||
"Execute the debug engine, collision renderer, and draw-instance-info."
|
||||
(when (not (or (= *master-mode* 'menu) (= *master-mode* 'progress)))
|
||||
(let ((a0-3 *col-rend*))
|
||||
|
@ -314,6 +314,7 @@ A "connection" is really just a function that gets called when the engine runs,
|
||||
(defmethod apply-to-connections-reverse engine ((obj engine) (arg0 (function connectable none)))
|
||||
"Apply f to all connections, reverse order.
|
||||
Do not use f to remove yourself from the list."
|
||||
(declare (inline))
|
||||
(let ((s4-0 (-> obj alive-list-end prev0)))
|
||||
(while (!= s4-0 (-> obj alive-list))
|
||||
(arg0 s4-0)
|
||||
|
@ -216,7 +216,7 @@
|
||||
)
|
||||
|
||||
;; WARN: Return type mismatch entity vs entity-actor.
|
||||
(defun entity-actor-from-level-name ((arg0 level))
|
||||
(defun entity-actor-from-level-name ((arg0 symbol))
|
||||
(let ((v0-0 (the-as entity #f)))
|
||||
(dotimes (s5-0 (-> *level* length))
|
||||
(let ((s4-0 (-> *level* level s5-0)))
|
||||
@ -1579,7 +1579,7 @@
|
||||
)
|
||||
|
||||
;; WARN: Return type mismatch process vs none.
|
||||
(defun init-entity ((arg0 process) (arg1 entity-actor) (arg2 process))
|
||||
(defun init-entity ((arg0 process) (arg1 entity-actor) (arg2 type))
|
||||
(activate arg0 *entity-pool* (res-lump-struct arg1 'name basic) (the-as pointer #x70004000))
|
||||
(set! (-> arg0 entity) arg1)
|
||||
(set! (-> arg0 level) (-> arg1 extra level))
|
||||
@ -1605,7 +1605,7 @@
|
||||
(set! (-> s4-0 type) s5-0)
|
||||
(and s5-0 (valid? s5-0 type (the-as string #f) #f 0) (valid? (method-of-object s4-0 init-from-entity!) function (the-as string #f) #f 0))
|
||||
)
|
||||
(init-entity s4-0 obj (the-as process s5-0))
|
||||
(init-entity s4-0 obj s5-0)
|
||||
)
|
||||
(else
|
||||
(when (not (birth-viewer s4-0 obj))
|
||||
@ -2229,9 +2229,15 @@
|
||||
(dotimes (s1-1 s2-3)
|
||||
(set! sv-48 (-> s3-4 data s1-1))
|
||||
(cond
|
||||
((and (#if PC_PORT (or (with-pc (and (-> *pc-settings* force-actors?) (not (let ((name (res-lump-struct (-> sv-48 entity) 'name string)))
|
||||
(or (string= name "fort-entry-gate-11")
|
||||
(string= name "com-airlock-outer-13"))))))
|
||||
((and (#if PC_PORT (or (with-pc (and (-> *pc-settings* force-actors?)
|
||||
;; ban specific entities
|
||||
(not (let ((name (res-lump-struct (-> sv-48 entity) 'name string)))
|
||||
(or (string= name "fort-entry-gate-11")
|
||||
(string= name "com-airlock-outer-13")
|
||||
(string= name "com-airlock-inner-41")
|
||||
(string= name "under-lift-4")
|
||||
(string= name "under-locking-1")
|
||||
(string= name "under-locking-2"))))))
|
||||
(is-object-visible? s4-1 (-> sv-48 vis-id)))
|
||||
(is-object-visible? s4-1 (-> sv-48 vis-id)))
|
||||
(not (logtest? (-> sv-48 perm status) (entity-perm-status bit-9 bit-10)))
|
||||
|
@ -12,37 +12,29 @@
|
||||
(defenum continue-flags
|
||||
:type uint32
|
||||
:bitfield #t
|
||||
(cf0 0)
|
||||
(cf1 1)
|
||||
(cf2 2)
|
||||
(cf3 3)
|
||||
(cf4 4)
|
||||
(cf5 5)
|
||||
(cf6 6)
|
||||
(cf7 7)
|
||||
(cf8 8)
|
||||
(cf9 9)
|
||||
(cf10 10)
|
||||
(cf11 11)
|
||||
(cf12 12)
|
||||
(cf13 13)
|
||||
(cf14 14)
|
||||
(cf15 15)
|
||||
(cf16 16)
|
||||
(cf17 17)
|
||||
(cf18 18)
|
||||
(cf19 19)
|
||||
(cf20 20)
|
||||
(cf21 21)
|
||||
(cf22 22)
|
||||
(cf23 23)
|
||||
(cf24 24)
|
||||
(cf25 25)
|
||||
(cf26 26)
|
||||
(cf27 27)
|
||||
(cf28 28)
|
||||
(cf29 29)
|
||||
(cf30 30)
|
||||
;(continue-flag-0 0)
|
||||
(scene-wait 1)
|
||||
(change-continue 2)
|
||||
(no-auto 3)
|
||||
(no-blackout 4)
|
||||
(game-start 5)
|
||||
(demo-end 6)
|
||||
(warp-gate 7)
|
||||
(demo 8)
|
||||
(intro 9)
|
||||
(hero-mode 10)
|
||||
(demo-movie 11)
|
||||
(title 12)
|
||||
(title-movie 13)
|
||||
(continue-flag-14 14)
|
||||
(continue-flag-15 15)
|
||||
(continue-flag-16 16)
|
||||
(test 17)
|
||||
(record-path 18)
|
||||
(pilot 19)
|
||||
(pilot-dax 20)
|
||||
(record-sig 21)
|
||||
(indax 22)
|
||||
)
|
||||
|
||||
;; +++game-secrets
|
||||
|
@ -79,7 +79,7 @@
|
||||
(new 'static 'continue-point
|
||||
:name "default"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :w 1.0)
|
||||
:quat (new 'static 'vector :w 1.0)
|
||||
:camera-trans (new 'static 'vector :w 1.0)
|
||||
@ -227,7 +227,7 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
(if (and (logtest? (-> obj current-continue flags) (continue-flags cf2))
|
||||
(if (and (logtest? (-> obj current-continue flags) (continue-flags change-continue))
|
||||
(and (!= (-> obj current-continue) *default-continue*) (not arg1))
|
||||
)
|
||||
(set! (-> obj current-continue) s5-0)
|
||||
@ -1373,7 +1373,7 @@
|
||||
(let ((conts (-> (the-as level-load-info (-> (the-as symbol (car levels)) value)) continues)))
|
||||
(while (not (null? conts))
|
||||
(let ((cont (the-as continue-point (car conts))))
|
||||
(if (not (logtest? (-> cont flags) (continue-flags cf2)))
|
||||
(if (not (logtest? (-> cont flags) (continue-flags change-continue)))
|
||||
(format #t "~S~%" (-> cont name))
|
||||
)
|
||||
)
|
||||
|
@ -722,8 +722,8 @@
|
||||
(set! (-> *font-work* color-table color color (* vert 2) r) (-> rgba-red r))
|
||||
(set! (-> *font-work* color-table color color (* vert 2) g) (-> rgba-green r))
|
||||
(set! (-> *font-work* color-table color color (* vert 2) b) (-> rgba-blue r))
|
||||
;; missing?
|
||||
;; (set! (-> *font-work* color-table color (1+ (* vert 2)) r) (-> rgba-red r))
|
||||
;; NOTE : this line was missing in the original code
|
||||
(set! (-> *font-work* color-table color color (1+ (* vert 2)) r) (-> rgba-red r))
|
||||
(set! (-> *font-work* color-table color color (1+ (* vert 2)) g) (-> rgba-green r))
|
||||
(set! (-> *font-work* color-table color color (1+ (* vert 2)) b) (-> rgba-blue r))
|
||||
0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,6 +27,7 @@ into 7 sections, which might explain the weird sizes in the center.
|
||||
(defglobalconstant NUM_LEVEL_PAGES 146)
|
||||
(defglobalconstant LEVEL_PAGE_SIZE_KB 126) ;; original value
|
||||
(defglobalconstant LEVEL_PAGE_SIZE (* LEVEL_PAGE_SIZE_KB 1024)) ;; original value
|
||||
|
||||
(defglobalconstant LEVEL_HEAP_SIZE (* NUM_LEVEL_PAGES LEVEL_PAGE_SIZE))
|
||||
;(defglobalconstant DEBUG_LEVEL_HEAP_MULT 1.5) ;; level heap in debug mode is 1.5x larger
|
||||
(defglobalconstant DEBUG_LEVEL_HEAP_MULT 1.1) ;; we're gonna use debug mode-style heaps but we don't actually need them at 1.5x size right now
|
||||
@ -955,7 +956,7 @@ into 7 sections, which might explain the weird sizes in the center.
|
||||
(cond
|
||||
;; are we using debug sized large level?
|
||||
((= (&- (-> *level* heap top) (the-as uint (-> *level* heap base))) DEBUG_LEVEL_HEAP_SIZE)
|
||||
;; if so, everything is 1.5x bigger!
|
||||
;; if so, everything is bigger!
|
||||
(let ((v1-44 (-> obj heap)))
|
||||
(set! (-> v1-44 base) (&+ (-> *level* heap base) (* DEBUG_LEVEL_PAGE_SIZE offset-in-level-heap)))
|
||||
(set! (-> v1-44 current) (-> v1-44 base))
|
||||
@ -1891,7 +1892,7 @@ into 7 sections, which might explain the weird sizes in the center.
|
||||
(load-package "common" global)
|
||||
)
|
||||
(let ((s5-1 (if (and arg0 (not *debug-segment*))
|
||||
LEVEL_HEAP_SIZE
|
||||
(#if PC_PORT DEBUG_LEVEL_HEAP_SIZE LEVEL_HEAP_SIZE)
|
||||
DEBUG_LEVEL_HEAP_SIZE
|
||||
)
|
||||
)
|
||||
@ -2747,9 +2748,9 @@ into 7 sections, which might explain the weird sizes in the center.
|
||||
(set! (-> *setting-control* user-default sound-reverb) (-> s4-1 info sound-reverb))
|
||||
#t
|
||||
)
|
||||
(or (-> *level* border?) (logtest? (-> *game-info* current-continue flags) (continue-flags cf2)))
|
||||
(or (-> *level* border?) (logtest? (-> *game-info* current-continue flags) (continue-flags change-continue)))
|
||||
(or (!= (-> s4-1 name) (-> *game-info* current-continue level))
|
||||
(logtest? (-> *game-info* current-continue flags) (continue-flags cf2))
|
||||
(logtest? (-> *game-info* current-continue flags) (continue-flags change-continue))
|
||||
)
|
||||
(not (null? (-> s4-1 info continues)))
|
||||
(-> *setting-control* user-current allow-continue)
|
||||
@ -2765,7 +2766,7 @@ into 7 sections, which might explain the weird sizes in the center.
|
||||
)
|
||||
(string= (-> *game-info* current-continue name) (-> (the-as continue-point s1-0) name))
|
||||
)
|
||||
(not (logtest? (-> (the-as continue-point s1-0) flags) (continue-flags cf2 cf3)))
|
||||
(not (logtest? (-> (the-as continue-point s1-0) flags) (continue-flags change-continue no-auto)))
|
||||
)
|
||||
(set! s3-0 (the-as continue-point s1-0))
|
||||
(if (string= (-> *game-info* current-continue name) (-> (the-as continue-point s1-0) name))
|
||||
@ -2778,7 +2779,7 @@ into 7 sections, which might explain the weird sizes in the center.
|
||||
)
|
||||
(label cfg-59)
|
||||
(if (and (the-as continue-point s3-0)
|
||||
(not (logtest? (-> (the-as continue-point s3-0) flags) (continue-flags cf2 cf3)))
|
||||
(not (logtest? (-> (the-as continue-point s3-0) flags) (continue-flags change-continue no-auto)))
|
||||
)
|
||||
(set-continue! *game-info* (the-as basic s3-0) #f)
|
||||
)
|
||||
@ -2974,9 +2975,10 @@ into 7 sections, which might explain the weird sizes in the center.
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((v1-186 (- #x2000000 (the-as int (-> global current)))))
|
||||
(if (and (not *debug-segment*) (< v1-186 #x10000))
|
||||
(format *stdcon* "~3Lglobal heap fatally low at ~DK free~%~0L" (sar v1-186 10))
|
||||
;; pc port note : this was hardcoded to the top of EE memory (#x2000000)
|
||||
(let ((v1-186 (&- (-> global top-base) (-> global current))))
|
||||
(if (and (not *debug-segment*) (< v1-186 (* 64 1024)))
|
||||
(format *stdcon* "~3Lglobal heap fatally low at ~DK free~%~0L" (/ v1-186 (* 1024 1024)))
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -1140,228 +1140,13 @@
|
||||
|
||||
|
||||
(defmethod print gui-connection ((obj gui-connection))
|
||||
(let* ((t9-0 format)
|
||||
(a0-1 #t)
|
||||
(a1-0 "#<gc ~12S ~2D ~6D ~6,,0f ~7S ~8S ")
|
||||
(a2-0 (-> obj name))
|
||||
(a3-0 (-> obj anim-part))
|
||||
(t0-0 (-> obj id))
|
||||
(t1-0 (-> obj priority))
|
||||
(v1-0 (-> obj channel))
|
||||
(t2-1 (cond
|
||||
((= v1-0 (gui-channel hud-lower-left))
|
||||
"hud-lower-left"
|
||||
)
|
||||
((= v1-0 (gui-channel citizen))
|
||||
"citizen"
|
||||
)
|
||||
((= v1-0 (gui-channel ashelin))
|
||||
"ashelin"
|
||||
)
|
||||
((= v1-0 (gui-channel hud-lower-left-1))
|
||||
"hud-lower-left-1"
|
||||
)
|
||||
((= v1-0 (gui-channel message))
|
||||
"message"
|
||||
)
|
||||
((= v1-0 (gui-channel hud-middle-left))
|
||||
"hud-middle-left"
|
||||
)
|
||||
((= v1-0 (gui-channel hud-upper-center-2))
|
||||
"hud-upper-center-2"
|
||||
)
|
||||
((= v1-0 (gui-channel hud-middle-right))
|
||||
"hud-middle-right"
|
||||
)
|
||||
((= v1-0 (gui-channel subtitle))
|
||||
"subtitle"
|
||||
)
|
||||
((= v1-0 (gui-channel notice))
|
||||
"notice"
|
||||
)
|
||||
((= v1-0 (gui-channel voicebox))
|
||||
"voicebox"
|
||||
)
|
||||
((= v1-0 (gui-channel art-load-next))
|
||||
"art-load-next"
|
||||
)
|
||||
((= v1-0 (gui-channel mog))
|
||||
"mog"
|
||||
)
|
||||
((= v1-0 (gui-channel sig))
|
||||
"sig"
|
||||
)
|
||||
((= v1-0 (gui-channel hud-center-left))
|
||||
"hud-center-left"
|
||||
)
|
||||
((= v1-0 (gui-channel hud-upper-right))
|
||||
"hud-upper-right"
|
||||
)
|
||||
((= v1-0 (gui-channel hud-center-right))
|
||||
"hud-center-right"
|
||||
)
|
||||
((= v1-0 (gui-channel alert))
|
||||
"alert"
|
||||
)
|
||||
((= v1-0 (gui-channel jinx))
|
||||
"jinx"
|
||||
)
|
||||
((= v1-0 (gui-channel hud-upper-left))
|
||||
"hud-upper-left"
|
||||
)
|
||||
((= v1-0 (gui-channel query))
|
||||
"query"
|
||||
)
|
||||
((= v1-0 (gui-channel grim))
|
||||
"grim"
|
||||
)
|
||||
((= v1-0 (gui-channel kor))
|
||||
"kor"
|
||||
)
|
||||
((= v1-0 (gui-channel hud-lower-right))
|
||||
"hud-lower-right"
|
||||
)
|
||||
((= v1-0 (gui-channel screen))
|
||||
"screen"
|
||||
)
|
||||
((= v1-0 (gui-channel guard))
|
||||
"guard"
|
||||
)
|
||||
((= v1-0 (gui-channel supertitle))
|
||||
"supertitle"
|
||||
)
|
||||
((= v1-0 (gui-channel hal))
|
||||
"hal"
|
||||
)
|
||||
((= v1-0 (gui-channel hud-upper-center))
|
||||
"hud-upper-center"
|
||||
)
|
||||
((= v1-0 (gui-channel blackout))
|
||||
"blackout"
|
||||
)
|
||||
((= v1-0 (gui-channel bbush))
|
||||
"bbush"
|
||||
)
|
||||
((= v1-0 (gui-channel hud))
|
||||
"hud"
|
||||
)
|
||||
((= v1-0 (gui-channel voice))
|
||||
"voice"
|
||||
)
|
||||
((= v1-0 (gui-channel max))
|
||||
"max"
|
||||
)
|
||||
((= v1-0 (gui-channel none))
|
||||
"none"
|
||||
)
|
||||
((= v1-0 (gui-channel notice-low))
|
||||
"notice-low"
|
||||
)
|
||||
((= v1-0 (gui-channel art-load))
|
||||
"art-load"
|
||||
)
|
||||
((= v1-0 (gui-channel kid))
|
||||
"kid"
|
||||
)
|
||||
((= v1-0 (gui-channel jak))
|
||||
"jak"
|
||||
)
|
||||
((= v1-0 (gui-channel daxter))
|
||||
"daxter"
|
||||
)
|
||||
((= v1-0 (gui-channel krew))
|
||||
"krew"
|
||||
)
|
||||
((= v1-0 (gui-channel hud-lower-left-2))
|
||||
"hud-lower-left-2"
|
||||
)
|
||||
((= v1-0 (gui-channel background))
|
||||
"background"
|
||||
)
|
||||
((= v1-0 (gui-channel crocadog))
|
||||
"crocadog"
|
||||
)
|
||||
((= v1-0 (gui-channel movie))
|
||||
"movie"
|
||||
)
|
||||
(else
|
||||
"*unknown*"
|
||||
)
|
||||
)
|
||||
)
|
||||
(v1-1 (-> obj action))
|
||||
)
|
||||
(t9-0 a0-1 a1-0 a2-0 a3-0 t0-0 t1-0 t2-1 (cond
|
||||
((= v1-1 (gui-action queue))
|
||||
"queue"
|
||||
)
|
||||
((= v1-1 (gui-action stop))
|
||||
"stop"
|
||||
)
|
||||
((= v1-1 (gui-action play))
|
||||
"play"
|
||||
)
|
||||
((= v1-1 (gui-action hide))
|
||||
"hide"
|
||||
)
|
||||
((= v1-1 (gui-action fade))
|
||||
"fade"
|
||||
)
|
||||
((= v1-1 (gui-action none))
|
||||
"none"
|
||||
)
|
||||
((= v1-1 (gui-action abort))
|
||||
"abort"
|
||||
)
|
||||
((= v1-1 (gui-action stopping))
|
||||
"stopping"
|
||||
)
|
||||
((= v1-1 (gui-action hidden))
|
||||
"hidden"
|
||||
)
|
||||
((= v1-1 (gui-action playing))
|
||||
"playing"
|
||||
)
|
||||
(else
|
||||
"*unknown*"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((s5-0 format)
|
||||
(s4-0 #t)
|
||||
(s3-0 " ~6S <@ #x~A>")
|
||||
(v1-3 (get-status *gui-control* (-> obj id)))
|
||||
)
|
||||
(s5-0
|
||||
s4-0
|
||||
s3-0
|
||||
(cond
|
||||
((= v1-3 (gui-status ready))
|
||||
"ready"
|
||||
)
|
||||
((= v1-3 (gui-status active))
|
||||
"active"
|
||||
)
|
||||
((= v1-3 (gui-status stop))
|
||||
"stop"
|
||||
)
|
||||
((= v1-3 (gui-status unknown))
|
||||
"unknown"
|
||||
)
|
||||
((= v1-3 (gui-status hide))
|
||||
"hide"
|
||||
)
|
||||
((= v1-3 (gui-status pending))
|
||||
"pending"
|
||||
)
|
||||
(else
|
||||
"*unknown*"
|
||||
)
|
||||
)
|
||||
obj
|
||||
)
|
||||
)
|
||||
(format #t "#<gc ~12S ~2D ~6D ~6,,0f ~7S ~8S " (-> obj name)
|
||||
(-> obj anim-part)
|
||||
(-> obj id)
|
||||
(-> obj priority)
|
||||
(enum->string gui-channel (-> obj channel))
|
||||
(enum->string gui-action (-> obj action)))
|
||||
(format #t " ~6S <@ #x~A>" (enum->string gui-status (get-status *gui-control* (-> obj id))) obj)
|
||||
obj
|
||||
)
|
||||
|
||||
@ -1404,6 +1189,7 @@
|
||||
(the-as gui-connection #f)
|
||||
)
|
||||
|
||||
;; WARN: Return type mismatch int vs sound-id.
|
||||
(defmethod lookup-gui-connection-id gui-control ((obj gui-control) (arg0 string) (arg1 gui-channel) (arg2 gui-action))
|
||||
(let ((s2-0 (the-as gui-connection (-> obj engine alive-list next0))))
|
||||
(-> obj engine)
|
||||
@ -1413,7 +1199,7 @@
|
||||
(or (= arg2 (gui-action none)) (= arg2 (-> s2-0 action)))
|
||||
(or (not arg0) (string= arg0 (-> s2-0 name)))
|
||||
)
|
||||
(return (the-as int (-> s2-0 id)))
|
||||
(return (the-as sound-id (-> s2-0 id)))
|
||||
)
|
||||
(set! s2-0 (the-as gui-connection s1-0))
|
||||
(-> obj engine)
|
||||
@ -1428,11 +1214,11 @@
|
||||
(or (= arg2 (gui-action none)) (= arg2 (-> s1-1 action)))
|
||||
(or (not arg0) (string= arg0 (-> s1-1 name)))
|
||||
)
|
||||
(return (the-as int (-> s1-1 id)))
|
||||
(return (the-as sound-id (-> s1-1 id)))
|
||||
)
|
||||
)
|
||||
)
|
||||
0
|
||||
(the-as sound-id 0)
|
||||
)
|
||||
|
||||
(defmethod set-falloff! gui-control ((obj gui-control) (arg0 sound-id) (arg1 symbol) (arg2 int) (arg3 int) (arg4 int))
|
||||
@ -2516,6 +2302,9 @@
|
||||
)
|
||||
(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
|
||||
(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)))
|
||||
(set! (-> gp-0 cmd 81) '((64 . wait) (65 . wait) (81 . wait) (70 . wait)))
|
||||
(set! (-> gp-0 cmd 82) '((64 . wait) (65 . wait) (67 . wait) (71 . wait) (69 . wait) (82 . wait)))
|
||||
|
@ -551,7 +551,7 @@
|
||||
)
|
||||
(set! (-> s5-0 y) 0.0)
|
||||
(vector-normalize! s5-0 1.0)
|
||||
|
||||
|
||||
;; modified for PC, see comment near definition in collide-shape-h.gc
|
||||
(normalized-heading-to-quaternion! (-> obj root-override2 quat) s5-0)
|
||||
)
|
||||
@ -956,7 +956,7 @@
|
||||
)
|
||||
|
||||
(defmethod nav-enemy-method-161 nav-enemy ((obj nav-enemy))
|
||||
(set! (-> obj enemy-flags) (the-as enemy-flag (logclear (-> obj enemy-flags) (enemy-flag enemy-flag39))))
|
||||
(set! (-> obj enemy-flags) (the-as enemy-flag (logclear (-> obj enemy-flags) (enemy-flag not-frustrated))))
|
||||
(set! (-> obj frustration-time) (current-time))
|
||||
(let ((v1-7 (handle->process (-> obj focus handle))))
|
||||
(if v1-7
|
||||
@ -982,7 +982,7 @@
|
||||
(when (>= (- (current-time) (-> obj frustration-time))
|
||||
(+ (-> obj reaction-time) (-> obj enemy-info-override frustration-time))
|
||||
)
|
||||
(set! (-> obj enemy-flags) (the-as enemy-flag (logior (enemy-flag enemy-flag39) (-> obj enemy-flags))))
|
||||
(set! (-> obj enemy-flags) (the-as enemy-flag (logior (enemy-flag not-frustrated) (-> obj enemy-flags))))
|
||||
0
|
||||
)
|
||||
)
|
||||
@ -1522,7 +1522,7 @@ This commonly includes things such as:
|
||||
(defmethod go-stare nav-enemy ((obj nav-enemy))
|
||||
(let ((s5-0 (-> obj focus aware)))
|
||||
(cond
|
||||
((or (and (-> obj enemy-info-override use-frustration) (logtest? (enemy-flag enemy-flag39) (-> obj enemy-flags)))
|
||||
((or (and (-> obj enemy-info-override use-frustration) (logtest? (enemy-flag not-frustrated) (-> obj enemy-flags)))
|
||||
(nav-enemy-method-163 obj)
|
||||
)
|
||||
(go-stare2 obj)
|
||||
@ -1542,7 +1542,7 @@ This commonly includes things such as:
|
||||
)
|
||||
|
||||
(defmethod go-hostile nav-enemy ((obj nav-enemy))
|
||||
(if (or (and (-> obj enemy-info-override use-frustration) (logtest? (enemy-flag enemy-flag39) (-> obj enemy-flags)))
|
||||
(if (or (and (-> obj enemy-info-override use-frustration) (logtest? (enemy-flag not-frustrated) (-> obj enemy-flags)))
|
||||
(nav-enemy-method-163 obj)
|
||||
)
|
||||
(go-stare2 obj)
|
||||
@ -1905,7 +1905,9 @@ This commonly includes things such as:
|
||||
)
|
||||
)
|
||||
)
|
||||
(when (and (-> self enemy-info-override use-frustration) (logtest? (enemy-flag enemy-flag39) (-> self enemy-flags)))
|
||||
(when (and (-> self enemy-info-override use-frustration)
|
||||
(logtest? (enemy-flag not-frustrated) (-> self enemy-flags))
|
||||
)
|
||||
(if (-> self enemy-info-override use-stop-chase)
|
||||
(go-virtual stop-chase)
|
||||
(go-stare self)
|
||||
@ -2094,7 +2096,9 @@ This commonly includes things such as:
|
||||
)
|
||||
((= gp-0 (enemy-aware enemy-aware-3))
|
||||
(if (and (get-enemy-target self)
|
||||
(not (and (-> self enemy-info-override use-frustration) (logtest? (enemy-flag enemy-flag39) (-> self enemy-flags)))
|
||||
(not (and (-> self enemy-info-override use-frustration)
|
||||
(logtest? (enemy-flag not-frustrated) (-> self enemy-flags))
|
||||
)
|
||||
)
|
||||
(>= (- (current-time) (-> self starting-time)) (-> self reaction-time))
|
||||
)
|
||||
|
@ -76,8 +76,8 @@
|
||||
(-> (the-as collide-shape-moving gp-0) gspot-pos)
|
||||
)
|
||||
((and (or (= arg0 2) (= arg0 3)) (type? gp-0 collide-shape))
|
||||
;; PC PORT NOTE : added lod-set check so we don't use invalid bones
|
||||
(if (not (logtest? (-> obj draw status) (draw-control-status lod-set)))
|
||||
;; PC PORT NOTE : added check here so we don't use invalid bones
|
||||
(if (logtest? (-> obj draw status) (draw-control-status uninited))
|
||||
(-> gp-0 trans)
|
||||
(-> gp-0 root-prim prim-core))
|
||||
)
|
||||
|
@ -217,7 +217,7 @@ Seen take in - `true-func` which takes no args TODO - seems fishy
|
||||
)
|
||||
)
|
||||
;; PC PORT NOTE : added check so we don't use the wrong position for the distance check
|
||||
(and (logtest? (-> self draw status) (draw-control-status lod-set))
|
||||
(and (not (logtest? (-> self draw status) (draw-control-status uninited)))
|
||||
(< (vector-vector-distance (target-pos 0) s5-0) f30-0))
|
||||
)
|
||||
)
|
||||
|
@ -673,6 +673,10 @@
|
||||
)
|
||||
(let ((v1-9 (-> self skel root-channel 0 frame-group)))
|
||||
(when v1-9
|
||||
;; 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 *subtitle2*) '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))
|
||||
@ -716,7 +720,12 @@
|
||||
(set! (-> s2-0 origin y) (+ 1.0 (-> s2-0 origin y)))
|
||||
(set! (-> s2-0 color) (font-color default))
|
||||
(set! (-> s2-0 flags) (font-flags shadow kerning middle left large))
|
||||
(print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id subtitle))
|
||||
(#if PC_PORT
|
||||
(if (or (!= (-> self type) scene-player)
|
||||
(not (send-event (ppointer->process *subtitle2*) '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 subtitle)))
|
||||
|
||||
(print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id subtitle)))
|
||||
(gui-control-method-12
|
||||
*gui-control*
|
||||
self
|
||||
@ -952,7 +961,7 @@
|
||||
(gui-action none)
|
||||
)
|
||||
)
|
||||
(v1-167 (get-status *gui-control* (the-as sound-id a1-26)))
|
||||
(v1-167 (get-status *gui-control* a1-26))
|
||||
)
|
||||
(not (or (= v1-167 (gui-status ready)) (= v1-167 (gui-status active))))
|
||||
)
|
||||
@ -1178,7 +1187,7 @@
|
||||
(let ((v1-41 (scene-player-method-24 self (-> self scene-list (-> self scene-index)) #t)))
|
||||
(when v1-41
|
||||
(let ((a0-21 (scene-decode-continue (the-as basic (-> v1-41 load-point-obj)))))
|
||||
(set! a0-24 (when (and a0-21 (logtest? (-> a0-21 flags) (continue-flags cf1)))
|
||||
(set! a0-24 (when (and a0-21 (logtest? (-> a0-21 flags) (continue-flags scene-wait)))
|
||||
(go-virtual wait a0-24)
|
||||
a0-24
|
||||
)
|
||||
@ -1487,7 +1496,7 @@
|
||||
(defbehavior scene-player-init scene-player ((arg0 object) (arg1 symbol) (arg2 string))
|
||||
"`object` arg can be an `(array scene)`, `pair of scene` or a `scene`"
|
||||
(process-entity-set! self (the-as entity #f))
|
||||
(stack-size-set! (-> self main-thread) 1024) ;; changed from 512
|
||||
(stack-size-set! (-> self main-thread) 768) ;; changed from 512
|
||||
(set! (-> self root) (new 'process 'trsqv))
|
||||
(case (rtype-of arg0)
|
||||
((array)
|
||||
|
@ -24,7 +24,7 @@
|
||||
(a3-0 (car a2-2))
|
||||
)
|
||||
(while (not (null? a2-2))
|
||||
(if (and v1-0 (logtest? (continue-flags cf17) (-> (the-as continue-point a3-0) flags)))
|
||||
(if (and v1-0 (logtest? (continue-flags test) (-> (the-as continue-point a3-0) flags)))
|
||||
(return (the-as continue-point a3-0))
|
||||
)
|
||||
(if (= a3-0 arg0)
|
||||
@ -122,12 +122,12 @@
|
||||
(if (-> *art-control* reserve-buffer)
|
||||
(reserve-free *art-control* (-> *art-control* reserve-buffer heap))
|
||||
)
|
||||
(when (logtest? (-> arg0 flags) (continue-flags cf8 cf11))
|
||||
(when (logtest? (-> arg0 flags) (continue-flags demo demo-movie))
|
||||
(set! (-> ctywide memory-mode) (load-buffer-mode small-edge))
|
||||
0
|
||||
)
|
||||
(kill-persister *setting-control* (the-as engine-pers 'fail) 'bg-a)
|
||||
(when (not (logtest? (-> arg0 flags) (continue-flags cf4)))
|
||||
(when (not (logtest? (-> arg0 flags) (continue-flags no-blackout)))
|
||||
(add-setting! 'bg-a 'abs 1.0 0)
|
||||
(set! (-> *setting-control* user-current bg-a) 1.0)
|
||||
)
|
||||
@ -163,7 +163,7 @@
|
||||
(if (not (string= (-> arg0 name) "default"))
|
||||
(set! *external-cam-mode* #f)
|
||||
)
|
||||
(if (not (logtest? (-> arg0 flags) (continue-flags cf4)))
|
||||
(if (not (logtest? (-> arg0 flags) (continue-flags no-blackout)))
|
||||
(cam-stop)
|
||||
)
|
||||
(suspend)
|
||||
@ -229,7 +229,7 @@
|
||||
(set! (-> *level* border?) s5-2)
|
||||
)
|
||||
(set! (-> *ACTOR-bank* birth-max) 1000)
|
||||
(when (not (logtest? (-> arg0 flags) (continue-flags cf4)))
|
||||
(when (not (logtest? (-> arg0 flags) (continue-flags no-blackout)))
|
||||
(new 'stack 'transformq)
|
||||
(cam-start #t)
|
||||
(suspend)
|
||||
@ -270,7 +270,7 @@
|
||||
(set! *spawn-actors* #t)
|
||||
(set! *teleport* #t)
|
||||
(set! (-> *ACTOR-bank* birth-max) 1000)
|
||||
(if (not (logtest? (-> arg0 flags) (continue-flags cf4)))
|
||||
(if (not (logtest? (-> arg0 flags) (continue-flags no-blackout)))
|
||||
(set-blackout-frames (seconds 0.1))
|
||||
)
|
||||
(let* ((a0-94 *game-info*)
|
||||
@ -290,7 +290,7 @@
|
||||
(t9-53 a0-94 a1-51 #f)
|
||||
)
|
||||
(cond
|
||||
((logtest? (-> arg0 flags) (continue-flags cf5))
|
||||
((logtest? (-> arg0 flags) (continue-flags game-start))
|
||||
(case *kernel-boot-message*
|
||||
(('kiosk)
|
||||
(let ((s5-5 (ppointer->handle (auto-save-command 'restore 0 0 *default-pool* #f))))
|
||||
@ -306,27 +306,27 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
((logtest? (-> arg0 flags) (continue-flags cf12))
|
||||
((logtest? (-> arg0 flags) (continue-flags title))
|
||||
(go target-title #t)
|
||||
)
|
||||
((logtest? (-> arg0 flags) (continue-flags cf13))
|
||||
((logtest? (-> arg0 flags) (continue-flags title-movie))
|
||||
(go target-title #f)
|
||||
)
|
||||
((logtest? (-> arg0 flags) (continue-flags cf8))
|
||||
((logtest? (-> arg0 flags) (continue-flags demo))
|
||||
(go target-demo #t)
|
||||
)
|
||||
((logtest? (-> arg0 flags) (continue-flags cf11))
|
||||
((logtest? (-> arg0 flags) (continue-flags demo-movie))
|
||||
(go target-demo #f)
|
||||
)
|
||||
((logtest? (-> arg0 flags) (continue-flags cf9))
|
||||
((logtest? (-> arg0 flags) (continue-flags intro))
|
||||
(intro-play)
|
||||
)
|
||||
((logtest? (-> arg0 flags) (continue-flags cf10))
|
||||
((logtest? (-> arg0 flags) (continue-flags hero-mode))
|
||||
(logior! (-> self game secrets) (game-secrets hero-mode))
|
||||
(logior! (-> self game purchase-secrets) (game-secrets hero-mode))
|
||||
(intro-play)
|
||||
)
|
||||
((logtest? (-> arg0 flags) (continue-flags cf7))
|
||||
((logtest? (-> arg0 flags) (continue-flags warp-gate))
|
||||
(let ((s5-7 (current-time)))
|
||||
(until (>= (- (current-time) s5-7) (seconds 0.05))
|
||||
(suspend)
|
||||
@ -342,22 +342,22 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
((logtest? (continue-flags cf22) (-> arg0 flags))
|
||||
((logtest? (continue-flags indax) (-> arg0 flags))
|
||||
enter-state
|
||||
(go target-indax-start)
|
||||
)
|
||||
((logtest? (continue-flags cf18) (-> arg0 flags))
|
||||
((logtest? (continue-flags record-path) (-> arg0 flags))
|
||||
)
|
||||
((logtest? (continue-flags cf21) (-> arg0 flags))
|
||||
((logtest? (continue-flags record-sig) (-> arg0 flags))
|
||||
(start-sig-recorder)
|
||||
)
|
||||
((logtest? (continue-flags cf19 cf20) (-> arg0 flags))
|
||||
((logtest? (continue-flags pilot pilot-dax) (-> arg0 flags))
|
||||
(set! (-> self focus-status) (logior (focus-status pilot) (-> self focus-status)))
|
||||
(while (not (-> self mode-cache))
|
||||
(suspend)
|
||||
)
|
||||
)
|
||||
((logtest? (-> arg0 flags) (continue-flags cf6))
|
||||
((logtest? (-> arg0 flags) (continue-flags demo-end))
|
||||
(go target-grab 'stance)
|
||||
)
|
||||
(else
|
||||
|
@ -53,6 +53,7 @@
|
||||
(subtitle 69)
|
||||
(supertitle 70)
|
||||
(notice-low 71)
|
||||
(subtitle-pc 78) ;; custom
|
||||
(screen 79)
|
||||
(hud-upper-right 80)
|
||||
(hud-upper-left 81)
|
||||
@ -138,7 +139,7 @@
|
||||
(stop-str (_type_ gui-connection) int 11)
|
||||
(gui-control-method-12 (_type_ process gui-channel gui-action string int float sound-id) sound-id 12)
|
||||
(update (_type_ symbol) int 13)
|
||||
(lookup-gui-connection-id (_type_ string gui-channel gui-action) int 14)
|
||||
(lookup-gui-connection-id (_type_ string gui-channel gui-action) sound-id 14)
|
||||
(lookup-gui-connection (_type_ process gui-channel string sound-id) gui-connection 15)
|
||||
(set-action! (_type_ gui-action sound-id gui-channel gui-action string (function gui-connection symbol) process) int 16)
|
||||
(get-status (_type_ sound-id) gui-status 17)
|
||||
|
@ -529,25 +529,11 @@ in a single text group and file."
|
||||
(set! sv-64 (+ sv-64 1))
|
||||
)
|
||||
(when (not arg2)
|
||||
(let* ((s2-1 (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
(s3-1 (-> s2-1 base))
|
||||
)
|
||||
(with-dma-buffer-add-bucket ((s2-1 (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
arg4
|
||||
)
|
||||
(draw-string *game-text-line* s2-1 arg1)
|
||||
(set! (-> arg1 color) (-> *font-work* last-color))
|
||||
(let ((a3-2 (-> s2-1 base)))
|
||||
(let ((v1-121 (the-as object (-> s2-1 base))))
|
||||
(set! (-> (the-as dma-packet v1-121) dma) (new 'static 'dma-tag :id (dma-tag-id next)))
|
||||
(set! (-> (the-as dma-packet v1-121) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet v1-121) vif1) (new 'static 'vif-tag))
|
||||
(set! (-> s2-1 base) (&+ (the-as pointer v1-121) 16))
|
||||
)
|
||||
(dma-bucket-insert-tag
|
||||
(-> *display* frames (-> *display* on-screen) bucket-group)
|
||||
arg4
|
||||
s3-1
|
||||
(the-as (pointer dma-tag) a3-2)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> arg1 origin y) f30-2)
|
||||
@ -575,6 +561,9 @@ in a single text group and file."
|
||||
(set! (-> arg1 origin y) sv-20)
|
||||
(set! (-> arg1 flags) sv-24)
|
||||
(set! (-> arg1 color) sv-28)
|
||||
(#when PC_PORT
|
||||
(if (and *debug-segment* *display-text-box*)
|
||||
(draw-debug-text-box arg1)))
|
||||
(if (> sv-64 0)
|
||||
(* sv-56 (the float sv-64))
|
||||
0.0
|
||||
|
@ -90,14 +90,13 @@
|
||||
)
|
||||
(hash-table-set! *file-entry-map* "dir-tpages.go" #f)
|
||||
|
||||
(cgo-file "engine.gd" '("$OUT/obj/gcommon.o" "$OUT/obj/gstate.o" "$OUT/obj/gstring.o" "$OUT/obj/gkernel.o"))
|
||||
(cgo-file "game.gd" '("$OUT/obj/gcommon.o" "$OUT/obj/gstate.o" "$OUT/obj/gstring.o" "$OUT/obj/gkernel.o"))
|
||||
|
||||
;; note: some of these dependencies are slightly wrong because cgo-file doesn't really handle
|
||||
;; the case of a .o appearing in multiple dgos. But, if we depend on the last item in both lists, it
|
||||
;; works out.
|
||||
|
||||
(define common-dep '("$OUT/obj/cty-guard-turret-button.o" "$OUT/obj/default-menu.o"))
|
||||
(define common-dep '("$OUT/obj/cty-guard-turret-button.o" "$OUT/obj/default-menu-pc.o"))
|
||||
(cgo-file "cwi.gd" common-dep)
|
||||
(cgo-file "lmeetbrt.gd" common-dep)
|
||||
(cgo-file "cta.gd" common-dep)
|
||||
@ -339,6 +338,11 @@
|
||||
"$OUT/iso/7COMMON.TXT")
|
||||
)
|
||||
|
||||
(defstep :in "game/assets/jak2/game_subtitle.gp"
|
||||
:tool 'subtitle2
|
||||
:out '("$OUT/iso/0SUBTI2.TXT")
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ISO Group
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
@ -346,6 +350,14 @@
|
||||
|
||||
(group-list "iso"
|
||||
`("$OUT/iso/0COMMON.TXT"
|
||||
"$OUT/iso/1COMMON.TXT"
|
||||
"$OUT/iso/2COMMON.TXT"
|
||||
"$OUT/iso/3COMMON.TXT"
|
||||
"$OUT/iso/4COMMON.TXT"
|
||||
"$OUT/iso/5COMMON.TXT"
|
||||
"$OUT/iso/6COMMON.TXT"
|
||||
"$OUT/iso/7COMMON.TXT"
|
||||
"$OUT/iso/0SUBTI2.TXT"
|
||||
"$OUT/iso/TWEAKVAL.MUS"
|
||||
"$OUT/iso/VAGDIR.AYB"
|
||||
,@(reverse *all-vis*)
|
||||
@ -357,7 +369,16 @@
|
||||
)
|
||||
|
||||
(group-list "text"
|
||||
`("$OUT/iso/0COMMON.TXT")
|
||||
`("$OUT/iso/0COMMON.TXT"
|
||||
"$OUT/iso/1COMMON.TXT"
|
||||
"$OUT/iso/2COMMON.TXT"
|
||||
"$OUT/iso/3COMMON.TXT"
|
||||
"$OUT/iso/4COMMON.TXT"
|
||||
"$OUT/iso/5COMMON.TXT"
|
||||
"$OUT/iso/6COMMON.TXT"
|
||||
"$OUT/iso/7COMMON.TXT"
|
||||
"$OUT/iso/0SUBTI2.TXT"
|
||||
)
|
||||
)
|
||||
|
||||
;; used for the type consistency test.
|
||||
@ -366,6 +387,8 @@
|
||||
)
|
||||
|
||||
(group "engine"
|
||||
"$OUT/iso/0COMMON.TXT"
|
||||
"$OUT/iso/0SUBTI2.TXT"
|
||||
"$OUT/iso/KERNEL.CGO"
|
||||
"$OUT/iso/GAME.CGO"
|
||||
)
|
||||
|
@ -675,12 +675,12 @@
|
||||
|
||||
(defmacro process-mask-set! (mask &rest enum-value)
|
||||
"Set the given bits in the process mask"
|
||||
`(set! ,mask (logior ,mask (process-mask ,@enum-value)))
|
||||
`(logior! ,mask (process-mask ,@enum-value))
|
||||
)
|
||||
|
||||
(defmacro process-mask-clear! (mask &rest enum-value)
|
||||
"Clear the given bits in the process mask."
|
||||
`(set! ,mask (logand ,mask (lognot (process-mask ,@enum-value))))
|
||||
`(logclear! ,mask (process-mask ,@enum-value))
|
||||
)
|
||||
|
||||
(defmacro suspend ()
|
||||
@ -730,6 +730,23 @@
|
||||
`(method-set! ,method-type ,method-id (__pc-get-mips2c ,name))
|
||||
)
|
||||
|
||||
(defmacro kheap-alloc (heap size)
|
||||
"allocate space for a kheap"
|
||||
`(let ((heap ,heap) (size ,size))
|
||||
(set! (-> heap base) (malloc 'global size))
|
||||
(set! (-> heap current) (-> heap base))
|
||||
(set! (-> heap top-base) (&+ (-> heap base) size))
|
||||
(set! (-> heap top) (-> heap top-base))
|
||||
)
|
||||
)
|
||||
|
||||
(defmacro kheap-reset (heap)
|
||||
"reset the kheap, so you can use its memory again"
|
||||
`(let ((heap ,heap))
|
||||
(set! (-> heap current) (-> heap base))
|
||||
)
|
||||
)
|
||||
|
||||
(defmacro scratchpad-object (type &key (offset 0))
|
||||
"Access an object on the scratchpad."
|
||||
`(the-as ,type (&+ *fake-scratchpad-data* ,offset))
|
||||
|
@ -2479,6 +2479,8 @@
|
||||
|
||||
;; categories within the active pool.
|
||||
(change-parent (define *display-pool* (new 'global 'process-tree "display-pool")) *active-pool*)
|
||||
(#when PC_PORT
|
||||
(change-parent (define *pc-pool* (new 'global 'process-tree "pc-pool")) *active-pool*))
|
||||
|
||||
(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))
|
||||
|
@ -1245,7 +1245,7 @@
|
||||
:end-point-obj (new 'static 'continue-point
|
||||
:name "atoll-start"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :x 2277804.5 :y 217672.9 :z -4571725.5 :w 1.0)
|
||||
:quat (new 'static 'vector :y -0.9671 :w 0.2541)
|
||||
:camera-trans (new 'static 'vector :x 2310242.8 :y 251249.05 :z -4513428.0 :w 1.0)
|
||||
@ -1651,7 +1651,7 @@
|
||||
:end-point-obj (new 'static 'continue-point
|
||||
:name "atoll-start"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :x 2277804.5 :y 217672.9 :z -4571725.5 :w 1.0)
|
||||
:quat (new 'static 'vector :y -0.9671 :w 0.2541)
|
||||
:camera-trans (new 'static 'vector :x 2310242.8 :y 251249.05 :z -4513428.0 :w 1.0)
|
||||
|
@ -624,7 +624,7 @@
|
||||
:end-point-obj (new 'static 'continue-point
|
||||
:name "ctyslumb-start"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :x 2620227.2 :y 31333.99 :z -400654.34 :w 1.0)
|
||||
:quat (new 'static 'vector :y 0.9997 :w -0.0234)
|
||||
:camera-trans (new 'static 'vector :x 2606159.8 :y 52533.656 :z -360011.78 :w 1.0)
|
||||
@ -797,7 +797,7 @@
|
||||
:end-point-obj (new 'static 'continue-point
|
||||
:name "ctyslumb-start"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :x 2588147.8 :y 32754.482 :z -150693.89 :w 1.0)
|
||||
:quat (new 'static 'vector :x -0.0012 :y -0.9819 :z -0.0008 :w 0.1889)
|
||||
:camera-trans (new 'static 'vector :x 2593185.8 :y 51852.492 :z -107130.88 :w 1.0)
|
||||
|
@ -2010,7 +2010,7 @@ This commonly includes things such as:
|
||||
:end-point-obj (new 'static 'continue-point
|
||||
:name "ctymarkb-tanker"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :x 1928400.1 :y 34444.902 :z 1788676.5 :w 1.0)
|
||||
:quat (new 'static 'vector :y 0.3641 :w -0.9313)
|
||||
:camera-trans (new 'static 'vector :x 1960564.4 :y 55543.81 :z 1760002.0 :w 1.0)
|
||||
|
@ -1292,10 +1292,7 @@ If the player is too far, play a warning speech."
|
||||
(let ((speech (-> obj course speeches idx)))
|
||||
(= (get-status
|
||||
*gui-control*
|
||||
(the-as
|
||||
sound-id
|
||||
(lookup-gui-connection-id *gui-control* (-> speech name) (gui-channel none) (gui-action none))
|
||||
)
|
||||
(lookup-gui-connection-id *gui-control* (-> speech name) (gui-channel none) (gui-action none))
|
||||
)
|
||||
(gui-status unknown)
|
||||
)
|
||||
@ -1316,10 +1313,7 @@ If the player is too far, play a warning speech."
|
||||
)
|
||||
(nonzero? (get-status
|
||||
*gui-control*
|
||||
(the-as
|
||||
sound-id
|
||||
(lookup-gui-connection-id *gui-control* (the-as string #f) (the-as gui-channel channel) (gui-action none))
|
||||
)
|
||||
(lookup-gui-connection-id *gui-control* (the-as string #f) (the-as gui-channel channel) (gui-action none))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -827,7 +827,7 @@
|
||||
(defmethod go-stare amphibian ((obj amphibian))
|
||||
(let ((s5-0 (-> obj focus aware)))
|
||||
(cond
|
||||
((or (and (-> obj enemy-info-override use-frustration) (logtest? (enemy-flag enemy-flag39) (-> obj enemy-flags)))
|
||||
((or (and (-> obj enemy-info-override use-frustration) (logtest? (enemy-flag not-frustrated) (-> obj enemy-flags)))
|
||||
(nav-enemy-method-163 obj)
|
||||
)
|
||||
(go-stare2 obj)
|
||||
|
@ -296,10 +296,7 @@
|
||||
)
|
||||
(if (nonzero? (get-status
|
||||
*gui-control*
|
||||
(the-as
|
||||
sound-id
|
||||
(lookup-gui-connection-id *gui-control* (the-as string #f) (gui-channel guard) (gui-action none))
|
||||
)
|
||||
(lookup-gui-connection-id *gui-control* (the-as string #f) (gui-channel guard) (gui-action none))
|
||||
)
|
||||
)
|
||||
(set! (-> self last-playing-time) (current-time))
|
||||
@ -348,10 +345,7 @@
|
||||
)
|
||||
(until (= (get-status
|
||||
*gui-control*
|
||||
(the-as
|
||||
sound-id
|
||||
(lookup-gui-connection-id *gui-control* (the-as string #f) (gui-channel guard) (gui-action none))
|
||||
)
|
||||
(lookup-gui-connection-id *gui-control* (the-as string #f) (gui-channel guard) (gui-action none))
|
||||
)
|
||||
(gui-status unknown)
|
||||
)
|
||||
|
@ -474,7 +474,7 @@
|
||||
(kick-attack () _type_ :state 158)
|
||||
(attack () _type_ :state 159)
|
||||
(die-now () _type_ :state 160)
|
||||
(shoot (_type_ vector projectile-init-by-other-params int float float) none 161)
|
||||
(shoot (_type_ vector projectile-init-by-other-params int int float) none 161)
|
||||
(crimson-guard-hover-method-162 (_type_ process-focusable) symbol 162)
|
||||
)
|
||||
)
|
||||
@ -671,8 +671,8 @@
|
||||
(set! (-> s5-0 attack-id) a0-6)
|
||||
)
|
||||
(set! (-> s5-0 timeout) (seconds 4))
|
||||
(shoot self gp-0 s5-0 9 0.000000000000000000000000000000000000000000017 1.0)
|
||||
(shoot self gp-0 s5-0 11 0.000000000000000000000000000000000000000000017 -1.0)
|
||||
(shoot self gp-0 s5-0 9 12 1.0)
|
||||
(shoot self gp-0 s5-0 11 12 -1.0)
|
||||
)
|
||||
(sound-play "hover-fire")
|
||||
(let ((v0-0 (the-as object (+ (-> self shots-fired) 1))))
|
||||
@ -866,8 +866,8 @@
|
||||
(set! (-> s5-0 attack-id) a0-6)
|
||||
)
|
||||
(set! (-> s5-0 timeout) (seconds 4))
|
||||
(shoot self gp-0 s5-0 9 0.000000000000000000000000000000000000000000017 1.0)
|
||||
(shoot self gp-0 s5-0 11 0.000000000000000000000000000000000000000000017 -1.0)
|
||||
(shoot self gp-0 s5-0 9 12 1.0)
|
||||
(shoot self gp-0 s5-0 11 12 -1.0)
|
||||
)
|
||||
(sound-play "hover-fire")
|
||||
(let ((v0-0 (the-as object (+ (-> self shots-fired) 1))))
|
||||
@ -1604,7 +1604,7 @@
|
||||
(arg0 vector)
|
||||
(arg1 projectile-init-by-other-params)
|
||||
(arg2 int)
|
||||
(arg3 float)
|
||||
(arg3 int)
|
||||
(arg4 float)
|
||||
)
|
||||
(vector<-cspace! (-> arg1 pos) (-> obj node-list data arg2))
|
||||
|
@ -1010,7 +1010,7 @@
|
||||
(let* ((gp-0 (-> obj race-state))
|
||||
(s3-0 (-> gp-0 info))
|
||||
)
|
||||
(if (or (logtest? (-> s3-0 flags) 2) (logtest? (continue-flags cf19) (-> *game-info* last-continue flags)))
|
||||
(if (or (logtest? (-> s3-0 flags) 2) (logtest? (continue-flags pilot) (-> *game-info* last-continue flags)))
|
||||
(logior! (-> gp-0 flags) 2)
|
||||
)
|
||||
(let ((s4-0 (new 'stack-no-clear 'mystery-traffic-object-spawn-params)))
|
||||
@ -1249,17 +1249,9 @@
|
||||
|
||||
(defmethod race-manager-method-24 race-manager ((obj race-manager))
|
||||
(when (= (get-status *gui-control* (-> obj message-id)) (gui-status active))
|
||||
(let ((gp-1 (new
|
||||
'stack
|
||||
'font-context
|
||||
*font-default-matrix*
|
||||
70
|
||||
20
|
||||
0.0
|
||||
(font-color orange)
|
||||
(font-flags shadow kerning)
|
||||
)
|
||||
)
|
||||
(let ((gp-1
|
||||
(new 'stack 'font-context *font-default-matrix* 70 20 0.0 (font-color orange) (font-flags shadow kerning))
|
||||
)
|
||||
)
|
||||
(let ((v1-4 gp-1))
|
||||
(set! (-> v1-4 scale) 0.7)
|
||||
@ -1285,17 +1277,9 @@
|
||||
|
||||
(defmethod race-manager-method-25 race-manager ((obj race-manager))
|
||||
(when (= (get-status *gui-control* (-> obj message-id)) (gui-status active))
|
||||
(let ((gp-1 (new
|
||||
'stack
|
||||
'font-context
|
||||
*font-default-matrix*
|
||||
70
|
||||
20
|
||||
0.0
|
||||
(font-color orange)
|
||||
(font-flags shadow kerning)
|
||||
)
|
||||
)
|
||||
(let ((gp-1
|
||||
(new 'stack 'font-context *font-default-matrix* 70 20 0.0 (font-color orange) (font-flags shadow kerning))
|
||||
)
|
||||
)
|
||||
(let ((v1-4 gp-1))
|
||||
(set! (-> v1-4 scale) 0.7)
|
||||
|
@ -690,7 +690,7 @@
|
||||
(ja :num! (loop!))
|
||||
(ja-post)
|
||||
)
|
||||
(if (not (logtest? (-> arg0 flags) (continue-flags cf4)))
|
||||
(if (not (logtest? (-> arg0 flags) (continue-flags no-blackout)))
|
||||
(set-blackout-frames (seconds 0.05))
|
||||
)
|
||||
(start 'play arg0)
|
||||
|
@ -920,7 +920,7 @@
|
||||
|
||||
(defmethod go-hostile ginsu ((obj ginsu))
|
||||
(cond
|
||||
((or (and (-> obj enemy-info-override use-frustration) (logtest? (enemy-flag enemy-flag39) (-> obj enemy-flags)))
|
||||
((or (and (-> obj enemy-info-override use-frustration) (logtest? (enemy-flag not-frustrated) (-> obj enemy-flags)))
|
||||
(nav-enemy-method-163 obj)
|
||||
)
|
||||
(go-stare2 obj)
|
||||
|
@ -559,7 +559,9 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
(when (and (-> self enemy-info-override use-frustration) (logtest? (enemy-flag enemy-flag39) (-> self enemy-flags)))
|
||||
(when (and (-> self enemy-info-override use-frustration)
|
||||
(logtest? (enemy-flag not-frustrated) (-> self enemy-flags))
|
||||
)
|
||||
(if (-> self enemy-info-override use-stop-chase)
|
||||
(go-virtual stop-chase)
|
||||
(go-stare self)
|
||||
|
@ -588,7 +588,9 @@ This commonly includes things such as:
|
||||
)
|
||||
)
|
||||
(when (>= (- (current-time) (-> self state-time)) (seconds 4))
|
||||
(if (and *target* (focus-test? *target* grabbed))
|
||||
(if (and *target* (focus-test? *target* grabbed)
|
||||
;; pc port note : added this check to make the beetle button not break everything!!
|
||||
(< (vector-vector-xz-distance (-> *target* control trans) (-> self root-override trans)) (meters 10)))
|
||||
(process-release? *target*)
|
||||
)
|
||||
(if (and *target*
|
||||
@ -1839,7 +1841,7 @@ This commonly includes things such as:
|
||||
|
||||
(deftype tomb-vibe (process-drawable)
|
||||
((spawn-pos vector :inline :offset-assert 208)
|
||||
(pat-tbl (array handle) :offset-assert 224)
|
||||
(pat-tbl (pointer int32) :offset-assert 224)
|
||||
(pat-count int32 :offset-assert 228)
|
||||
(pat-index int32 :offset-assert 232)
|
||||
(pat-entry-index int32 :offset-assert 236)
|
||||
@ -1932,16 +1934,14 @@ This commonly includes things such as:
|
||||
(case (-> (the-as attack-info (-> event param 1)) mode)
|
||||
(('flop 'spin 'punch)
|
||||
(cond
|
||||
((and (= (-> v1-0 0) (-> (the-as (pointer int32) (+ (the-as uint (-> self pat-tbl)) (* (-> self pat-index) 4)))))
|
||||
(!= (-> gp-0 0) (process->handle self))
|
||||
)
|
||||
((and (= (-> v1-0 0) (-> self pat-tbl (-> self pat-index))) (!= (-> gp-0 0) (process->handle self)))
|
||||
(send-event (handle->process (-> gp-0 0)) 'interrupt)
|
||||
(send-event (handle->process (-> gp-0 0)) 'die)
|
||||
(logior! (-> self flags) 1)
|
||||
(go-virtual vibrate)
|
||||
)
|
||||
(else
|
||||
(set! (-> v1-0 0) (-> (the-as (pointer int32) (+ (the-as uint (-> self pat-tbl)) (* (-> self pat-index) 4)))))
|
||||
(set! (-> v1-0 0) (-> self pat-tbl (-> self pat-index)))
|
||||
(set! (-> gp-0 0) (process->handle self))
|
||||
(go-virtual vibrate)
|
||||
)
|
||||
@ -2071,7 +2071,7 @@ This commonly includes things such as:
|
||||
'sound-tune
|
||||
#f
|
||||
0.0
|
||||
(+ (-> (the-as (pointer int32) (+ (the-as uint (-> self pat-tbl)) (* (-> self pat-index) 4)))) 18)
|
||||
(+ (-> self pat-tbl (-> self pat-index)) 18)
|
||||
)
|
||||
(let ((gp-1 (current-time)))
|
||||
(until (>= (- (current-time) gp-1) (seconds 0.2))
|
||||
@ -2227,11 +2227,11 @@ This commonly includes things such as:
|
||||
(let ((v1-26 (res-lump-data (-> obj entity) 'vibe-pattern pointer :tag-ptr (& sv-16))))
|
||||
(cond
|
||||
((and v1-26 (nonzero? (-> sv-16 elt-count)))
|
||||
(set! (-> obj pat-tbl) (the-as (array handle) v1-26))
|
||||
(set! (-> obj pat-tbl) (the-as (pointer int32) v1-26))
|
||||
(set! (-> obj pat-count) (the-as int (-> sv-16 elt-count)))
|
||||
)
|
||||
(else
|
||||
(set! (-> obj pat-tbl) #f)
|
||||
(set! (-> obj pat-tbl) (the-as (pointer int32) #f))
|
||||
(set! (-> obj pat-count) 0)
|
||||
0
|
||||
)
|
||||
|
@ -512,7 +512,7 @@
|
||||
:load-point-obj (new 'static 'continue-point
|
||||
:name "palroof-boss"
|
||||
:level #f
|
||||
:flags (continue-flags cf3 cf17)
|
||||
:flags (continue-flags no-auto test)
|
||||
:trans (new 'static 'vector :x 870794.06 :y 1671154.9 :z 2027482.4 :w 1.0)
|
||||
:quat (new 'static 'vector :y 0.4793 :w 0.8776)
|
||||
:camera-trans (new 'static 'vector :x 831816.06 :y 1693132.0 :z 2045632.9 :w 1.0)
|
||||
|
@ -1428,7 +1428,7 @@ This commonly includes things such as:
|
||||
(deftype sew-scare-grunt (grunt)
|
||||
((anim spool-anim :offset-assert 692)
|
||||
(manipy (pointer manipy) :offset-assert 696)
|
||||
(spooled-sound-id uint32 :offset-assert 700)
|
||||
(spooled-sound-id sound-id :offset-assert 700)
|
||||
(grill-actor entity-actor :offset-assert 704)
|
||||
)
|
||||
:heap-base #x250
|
||||
@ -1649,10 +1649,7 @@ This commonly includes things such as:
|
||||
)
|
||||
)
|
||||
(set! (-> self spooled-sound-id)
|
||||
(the-as
|
||||
uint
|
||||
(lookup-gui-connection-id *gui-control* (-> self anim name) (gui-channel art-load) (gui-action none))
|
||||
)
|
||||
(lookup-gui-connection-id *gui-control* (-> self anim name) (gui-channel art-load) (gui-action none))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
@ -1711,7 +1708,7 @@ This commonly includes things such as:
|
||||
(when *sound-player-enable*
|
||||
(let ((set-sound-param (the-as sound-rpc-set-param (get-sound-buffer-entry))))
|
||||
(set! (-> set-sound-param command) (sound-command set-param))
|
||||
(set! (-> set-sound-param id) (the-as sound-id (-> self spooled-sound-id)))
|
||||
(set! (-> set-sound-param id) (-> self spooled-sound-id))
|
||||
(set! (-> set-sound-param params volume) (the int (* 1024.0 scale)))
|
||||
(let ((position (-> self root-override2 trans)))
|
||||
(let ((_self self))
|
||||
|
@ -906,7 +906,7 @@
|
||||
:end-point-obj (new 'static 'continue-point
|
||||
:name "sewesc-start"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :x 5541148.0 :y -363968.9 :z 2435194.5 :w 1.0)
|
||||
:quat (new 'static 'vector :y 0.0482 :w 0.9988)
|
||||
:camera-trans (new 'static 'vector :x 5518817.0 :y -344878.7 :z 2399633.5 :w 1.0)
|
||||
@ -1175,7 +1175,7 @@
|
||||
:end-point-obj (new 'static 'continue-point
|
||||
:name "sewesc-start"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :x 5608474.5 :y -363960.3 :z 1988017.4 :w 1.0)
|
||||
:quat (new 'static 'vector :y -0.6775 :w -0.7354)
|
||||
:camera-trans (new 'static 'vector :x 5562796.5 :y -344327.78 :z 1985962.4 :w 1.0)
|
||||
|
@ -765,7 +765,7 @@
|
||||
:end-point-obj (new 'static 'continue-point
|
||||
:name "under-start"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :x -281437.8 :y -266239.6 :z 7897175.0 :w 1.0)
|
||||
:quat (new 'static 'vector :y -0.0077 :w 0.9999)
|
||||
:camera-trans (new 'static 'vector :x -251373.16 :y -249839.2 :z 7882176.0 :w 1.0)
|
||||
@ -1501,7 +1501,7 @@
|
||||
:end-point-obj (new 'static 'continue-point
|
||||
:name "under-start"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :x -277934.5 :y -273739.38 :z 8274381.0 :w 1.0)
|
||||
:quat (new 'static 'vector :y 0.1135 :w -0.9935)
|
||||
:camera-trans (new 'static 'vector :x -251817.98 :y -252642.1 :z 8230336.0 :w 1.0)
|
||||
@ -2324,7 +2324,7 @@
|
||||
:end-point-obj (new 'static 'continue-point
|
||||
:name "under-start"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :x -912500.75 :y -274436.5 :z 8332461.5 :w 1.0)
|
||||
:quat (new 'static 'vector :y -0.9997 :w 0.0214)
|
||||
:camera-trans (new 'static 'vector :x -910896.3 :y -257269.77 :z 8368969.0 :w 1.0)
|
||||
@ -2949,7 +2949,7 @@
|
||||
:end-point-obj (new 'static 'continue-point
|
||||
:name "under-start"
|
||||
:level #f
|
||||
:flags (continue-flags cf2)
|
||||
:flags (continue-flags change-continue)
|
||||
:trans (new 'static 'vector :x -934223.06 :y -290824.2 :z 7948726.0 :w 1.0)
|
||||
:quat (new 'static 'vector :y 0.4849 :w 0.8745)
|
||||
:camera-trans (new 'static 'vector :x -978344.75 :y -270091.06 :z 7925256.5 :w 1.0)
|
||||
|
@ -5,6 +5,16 @@
|
||||
;; name in dgo: underb-master
|
||||
;; dgos: UNB
|
||||
|
||||
(defenum under-locking-mode
|
||||
:type int64
|
||||
(want-mech)
|
||||
(want-fill)
|
||||
(airlock-wait)
|
||||
(want-drain)
|
||||
(drain)
|
||||
(want-exit-mech)
|
||||
)
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
(deftype under-warp (process-drawable)
|
||||
@ -84,7 +94,6 @@
|
||||
(s5-0 (new 'stack-no-clear 'vector))
|
||||
(gp-0 (new 'stack-no-clear 'vector))
|
||||
(f30-0 4096.0)
|
||||
(ratio (- 1.0 (/ 0.5 (-> *pc-settings* aspect-ratio-scale))))
|
||||
)
|
||||
;; changed for PC port: resize warp effect based on aspect ratio
|
||||
(let ((f0-4 (* 0.00013563369 (tan (* 0.5 (-> *math-camera* fov))) f30-0)))
|
||||
@ -636,9 +645,9 @@
|
||||
((id int8 :offset-assert 200)
|
||||
(up-y float :offset-assert 204)
|
||||
(down-y float :offset-assert 208)
|
||||
(mode uint64 :offset-assert 216)
|
||||
(mode under-locking-mode :offset-assert 216)
|
||||
(which-reminder? symbol :offset-assert 224)
|
||||
(spooled-sound-id uint32 :offset-assert 228)
|
||||
(spooled-sound-id sound-id :offset-assert 228)
|
||||
(draining-part sparticle-launch-control :offset-assert 232)
|
||||
(actor-group (pointer actor-group) :offset-assert 236)
|
||||
(spooled-sound-delay int32 :offset-assert 240)
|
||||
@ -721,7 +730,7 @@
|
||||
(let ((a1-6 *target*))
|
||||
(cond
|
||||
((and a1-6 (focus-test? a1-6 mech))
|
||||
(set! (-> self mode) (the-as uint 3))
|
||||
(set! (-> self mode) (under-locking-mode want-drain))
|
||||
(let ((a1-8 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-8 from) (process->ppointer self))
|
||||
(set! (-> a1-8 num-params) 1)
|
||||
@ -740,7 +749,7 @@
|
||||
)
|
||||
)
|
||||
(else
|
||||
(set! (-> self mode) (the-as uint 0))
|
||||
(set! (-> self mode) (under-locking-mode want-mech))
|
||||
(let ((a1-9 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-9 from) (process->ppointer self))
|
||||
(set! (-> a1-9 num-params) 1)
|
||||
@ -781,14 +790,14 @@
|
||||
(let ((v1-1 (-> self mode)))
|
||||
(cond
|
||||
((-> event param 0)
|
||||
(when (or (zero? v1-1) (= v1-1 5))
|
||||
(when (or (= v1-1 (under-locking-mode want-mech)) (= v1-1 (under-locking-mode want-exit-mech)))
|
||||
(let ((a0-4 *target*))
|
||||
(and a0-4 (not (logtest? (focus-status mech) (-> a0-4 focus-status))))
|
||||
)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(or (= v1-1 2) (= v1-1 3))
|
||||
(or (= v1-1 (under-locking-mode airlock-wait)) (= v1-1 (under-locking-mode want-drain)))
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -796,80 +805,78 @@
|
||||
)
|
||||
)
|
||||
:trans (behavior ()
|
||||
(let ((v1-0 (-> self mode)))
|
||||
(cond
|
||||
((zero? v1-0)
|
||||
(let ((v1-1 *target*)
|
||||
(a0-1 (-> self actor-group))
|
||||
(case (-> self mode)
|
||||
(((under-locking-mode want-mech))
|
||||
(let ((v1-1 *target*)
|
||||
(a0-1 (-> self actor-group))
|
||||
)
|
||||
(when (and v1-1 a0-1)
|
||||
(if (and (-> a0-1 0 data 0 actor)
|
||||
(focus-test? v1-1 mech)
|
||||
(send-event (ppointer->process *underb-master*) 'request 'mech #t)
|
||||
)
|
||||
(set! (-> self mode) (under-locking-mode want-fill))
|
||||
)
|
||||
(when (and v1-1 a0-1)
|
||||
(if (and (-> a0-1 0 data 0 actor)
|
||||
(focus-test? v1-1 mech)
|
||||
(send-event (ppointer->process *underb-master*) 'request 'mech #t)
|
||||
)
|
||||
)
|
||||
)
|
||||
(((under-locking-mode want-fill))
|
||||
(if (not (logtest? (-> self actor-group 0 data 0 actor extra perm status) (entity-perm-status subtask-complete)))
|
||||
(go-virtual filling)
|
||||
)
|
||||
)
|
||||
(((under-locking-mode airlock-wait))
|
||||
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-2 from) (process->ppointer self))
|
||||
(set! (-> a1-2 num-params) 0)
|
||||
(set! (-> a1-2 message) 'front)
|
||||
(let ((t9-2 send-event-function)
|
||||
(v1-24 (-> self actor-group 0 data 1 actor))
|
||||
)
|
||||
(if (not (t9-2
|
||||
(if v1-24
|
||||
(-> v1-24 extra process)
|
||||
)
|
||||
a1-2
|
||||
)
|
||||
(set! (-> self mode) (the-as uint 1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> self mode) (under-locking-mode want-drain))
|
||||
)
|
||||
)
|
||||
)
|
||||
((= v1-0 1)
|
||||
(if (not (logtest? (-> self actor-group 0 data 0 actor extra perm status) (entity-perm-status subtask-complete)))
|
||||
(go-virtual filling)
|
||||
)
|
||||
)
|
||||
((= v1-0 2)
|
||||
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-2 from) (process->ppointer self))
|
||||
(set! (-> a1-2 num-params) 0)
|
||||
(set! (-> a1-2 message) 'front)
|
||||
(let ((t9-2 send-event-function)
|
||||
(v1-24 (-> self actor-group 0 data 1 actor))
|
||||
)
|
||||
(if (not (t9-2
|
||||
(if v1-24
|
||||
(-> v1-24 extra process)
|
||||
)
|
||||
a1-2
|
||||
)
|
||||
)
|
||||
(set! (-> self mode) (the-as uint 3))
|
||||
)
|
||||
)
|
||||
)
|
||||
(((under-locking-mode want-drain))
|
||||
(if (>= 20480.0 (vector-vector-xz-distance (target-pos 0) (-> self root trans)))
|
||||
(set! (-> self mode) (under-locking-mode drain))
|
||||
)
|
||||
)
|
||||
(((under-locking-mode drain))
|
||||
(go-virtual draining)
|
||||
)
|
||||
(((under-locking-mode want-exit-mech))
|
||||
(let ((a1-4 *target*))
|
||||
(when (or (not a1-4) (not (logtest? (focus-status mech) (-> a1-4 focus-status))))
|
||||
(set! (-> self mode) (under-locking-mode want-mech))
|
||||
0
|
||||
)
|
||||
)
|
||||
((= v1-0 3)
|
||||
(if (>= 20480.0 (vector-vector-xz-distance (target-pos 0) (-> self root trans)))
|
||||
(set! (-> self mode) (the-as uint 4))
|
||||
)
|
||||
)
|
||||
((= v1-0 4)
|
||||
(go-virtual draining)
|
||||
)
|
||||
((= v1-0 5)
|
||||
(let ((a1-4 *target*))
|
||||
(when (or (not a1-4) (not (logtest? (focus-status mech) (-> a1-4 focus-status))))
|
||||
(set! (-> self mode) (the-as uint 0))
|
||||
0
|
||||
)
|
||||
)
|
||||
(when (>= (- (current-time) (-> self last-reminder-time)) (seconds 9))
|
||||
(set! (-> self last-reminder-time) (current-time))
|
||||
(add-process
|
||||
*gui-control*
|
||||
self
|
||||
(gui-channel ashelin)
|
||||
(gui-action play)
|
||||
(if (-> self which-reminder?)
|
||||
"cityv193"
|
||||
"cityv192"
|
||||
)
|
||||
-99.0
|
||||
0
|
||||
)
|
||||
(set! (-> self which-reminder?) (not (-> self which-reminder?)))
|
||||
(when (>= (- (current-time) (-> self last-reminder-time)) (seconds 9))
|
||||
(set! (-> self last-reminder-time) (current-time))
|
||||
(add-process
|
||||
*gui-control*
|
||||
self
|
||||
(gui-channel ashelin)
|
||||
(gui-action play)
|
||||
(if (-> self which-reminder?)
|
||||
"cityv193"
|
||||
"cityv192"
|
||||
)
|
||||
-99.0
|
||||
0
|
||||
)
|
||||
(set! (-> self which-reminder?) (not (-> self which-reminder?)))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
@ -881,7 +888,7 @@
|
||||
:event (-> (method-of-type under-locking active) event)
|
||||
:enter (behavior ()
|
||||
(set! (-> self spooled-sound-id)
|
||||
(the-as uint (add-process *gui-control* self (gui-channel ashelin) (gui-action queue) "wtrfill" -99.0 0))
|
||||
(add-process *gui-control* self (gui-channel ashelin) (gui-action queue) "wtrfill" -99.0 0)
|
||||
)
|
||||
(set! (-> self state-time) 0)
|
||||
(set! (-> self spooled-sound-delay) (if (= (-> self id) 1)
|
||||
@ -893,7 +900,7 @@
|
||||
)
|
||||
:trans (behavior ()
|
||||
(when (and (zero? (-> self state-time))
|
||||
(= (get-status *gui-control* (the-as sound-id (-> self spooled-sound-id))) (gui-status ready))
|
||||
(= (get-status *gui-control* (-> self spooled-sound-id)) (gui-status ready))
|
||||
)
|
||||
(set! (-> self state-time) (current-time))
|
||||
(set! (-> self last-reminder-time) (current-time))
|
||||
@ -905,7 +912,7 @@
|
||||
(set-action!
|
||||
*gui-control*
|
||||
(gui-action play)
|
||||
(the-as sound-id (-> self spooled-sound-id))
|
||||
(-> self spooled-sound-id)
|
||||
(gui-channel none)
|
||||
(gui-action none)
|
||||
(the-as string #f)
|
||||
@ -974,7 +981,7 @@
|
||||
(persist-with-delay *setting-control* 'interp-time (seconds 0.05) 'interp-time 'abs 0.0 0)
|
||||
(remove-setting! 'entity-name)
|
||||
(send-event (ppointer->process *underb-master*) 'request 'under-warp #t)
|
||||
(set! (-> self mode) (the-as uint 2))
|
||||
(set! (-> self mode) (under-locking-mode airlock-wait))
|
||||
(go-virtual active)
|
||||
)
|
||||
)
|
||||
@ -991,7 +998,7 @@
|
||||
:event (-> (method-of-type under-locking active) event)
|
||||
:enter (behavior ()
|
||||
(set! (-> self spooled-sound-id)
|
||||
(the-as uint (add-process *gui-control* self (gui-channel ashelin) (gui-action queue) "wtrdrain" -99.0 0))
|
||||
(add-process *gui-control* self (gui-channel ashelin) (gui-action queue) "wtrdrain" -99.0 0)
|
||||
)
|
||||
(set! (-> self state-time) 0)
|
||||
0
|
||||
@ -999,14 +1006,14 @@
|
||||
)
|
||||
:trans (behavior ()
|
||||
(when (and (zero? (-> self state-time))
|
||||
(= (get-status *gui-control* (the-as sound-id (-> self spooled-sound-id))) (gui-status ready))
|
||||
(= (get-status *gui-control* (-> self spooled-sound-id)) (gui-status ready))
|
||||
)
|
||||
(set! (-> self state-time) (current-time))
|
||||
(set! (-> self last-reminder-time) (current-time))
|
||||
(set-action!
|
||||
*gui-control*
|
||||
(gui-action play)
|
||||
(the-as sound-id (-> self spooled-sound-id))
|
||||
(-> self spooled-sound-id)
|
||||
(gui-channel none)
|
||||
(gui-action none)
|
||||
(the-as string #f)
|
||||
@ -1074,7 +1081,7 @@
|
||||
)
|
||||
(when v1-26
|
||||
(when (= (-> (the-as water-anim v1-26) root trans y) (-> self down-y))
|
||||
(set! (-> self mode) (the-as uint 5))
|
||||
(set! (-> self mode) (under-locking-mode want-exit-mech))
|
||||
(send-event (ppointer->process *underb-master*) 'request 'mech #f)
|
||||
(set! (-> self which-reminder?) #f)
|
||||
(go-virtual active)
|
||||
@ -1098,7 +1105,7 @@ This commonly includes things such as:
|
||||
- sounds"
|
||||
(local-vars (sv-16 res-tag))
|
||||
(set! (-> obj which-reminder?) #f)
|
||||
(set! (-> obj spooled-sound-id) (the-as uint 0))
|
||||
(set! (-> obj spooled-sound-id) (new 'static 'sound-id))
|
||||
(set! (-> obj root) (new 'process 'trsqv))
|
||||
(process-drawable-from-entity! obj arg0)
|
||||
(set! (-> obj id) (res-lump-value arg0 'extra-id int :time -1000000000.0))
|
||||
|
@ -463,16 +463,8 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; (defun dm-subtitle-language ((blang int) (msg debug-menu-msg))
|
||||
;; (let ((lang (the pc-subtitle-lang (/ blang 8))))
|
||||
;; (when (= msg (debug-menu-msg press))
|
||||
;; (set! (-> *pc-settings* subtitle-language) lang))
|
||||
;; (= (-> *pc-settings* subtitle-language) lang)
|
||||
;; )
|
||||
;; )
|
||||
;;
|
||||
;; (defun dm-text-language ((blang int) (msg debug-menu-msg))
|
||||
;; (let ((lang (the pc-subtitle-lang (/ blang 8))))
|
||||
;; (let ((lang (the pc-language (/ blang 8))))
|
||||
;; (when (= msg (debug-menu-msg press))
|
||||
;; (set! (-> *pc-settings* text-language) lang))
|
||||
;; (= (-> *pc-settings* text-language) lang)
|
||||
@ -712,208 +704,34 @@
|
||||
)
|
||||
|
||||
|
||||
(defun sort-string-array ((arr (array string)) (compare-func (function string string object)))
|
||||
"Sort an array, using compare-func to compare elements.
|
||||
The comparison function can return either an integer or a true/false.
|
||||
For integers, use a positive number to represent first > second
|
||||
Ex: (sort lst -) will sort in ascending order
|
||||
For booleans, you must explicitly use #t and not a truthy value.
|
||||
Ex: (sort my-list (lambda ((x int) (y int)) (< x y))) will sort ascending.
|
||||
NOTE: if you use an integer, don't accidentally return #t"
|
||||
(let ((sorted -1))
|
||||
(while (nonzero? sorted)
|
||||
(set! sorted 0)
|
||||
(dotimes (i (1- (-> arr allocated-length)))
|
||||
(let* ((cur (-> arr i))
|
||||
(next (-> arr (1+ i)))
|
||||
(result (compare-func cur next))
|
||||
)
|
||||
(when (and (or (not result) (> (the-as int result) 0)) (!= result #t))
|
||||
(+! sorted 1)
|
||||
(set! (-> arr i) next)
|
||||
(set! (-> arr (1+ i)) cur)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
arr
|
||||
)
|
||||
|
||||
(define *vag-play-menu* (the debug-menu #f))
|
||||
(define *vag-player* (the (pointer process) #f))
|
||||
(define *vagdir-names-list* (alloc-vagdir-names 'debug))
|
||||
|
||||
(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)
|
||||
|
||||
;; copy into a new string
|
||||
(set! (-> list i) (new 'debug 'string 0 *temp-string*)))
|
||||
|
||||
;; return the allocated, filled and sorted array
|
||||
(sort-string-array list string<=?))
|
||||
)
|
||||
|
||||
(define *vag-list* (alloc-vag-list))
|
||||
(define *vag-max-pos-list* (the (pointer int32) (malloc 'debug (* 4 (-> *vag-list* allocated-length)))))
|
||||
|
||||
|
||||
(defun dm-vag-play-pick-func ((idx int))
|
||||
(if *vag-player*
|
||||
(return #f))
|
||||
(set! *vag-player* (process-spawn-function process :to *display-pool*
|
||||
(lambda :behavior process ((idx int))
|
||||
|
||||
;; restore these settings when we're done
|
||||
(protect (*display-art-control* (-> *debug-menu-context* is-hidden) *gui-kick-str*)
|
||||
(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
|
||||
|
||||
(let* ((exit? #f)
|
||||
(old-speed 0.0)
|
||||
(speed 0.0)
|
||||
(id (new 'static 'sound-id))
|
||||
(stop! (lambda :behavior process ((id sound-id))
|
||||
(set-action! *gui-control* (gui-action stop) id (gui-channel none) (gui-action none) (the-as string #f) (the-as (function gui-connection symbol) #f) (the-as process #f))))
|
||||
(play! (lambda :behavior process ((idx int))
|
||||
(add-process *gui-control* self (gui-channel alert) (gui-action play) (-> *vag-list* idx) -10.0 0)))
|
||||
(playing? (lambda :behavior process ((id sound-id))
|
||||
(let ((status (get-status *gui-control* id))) (or (= status (gui-status ready)) (= status (gui-status active))))))
|
||||
(set-speed (lambda :behavior process ((id sound-id) (speed float))
|
||||
(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) id)
|
||||
(set! (-> cmd params pitch-mod) (the int (* 1524.0 speed)))
|
||||
(set! (-> cmd params mask) (the-as uint 2))
|
||||
(-> cmd id)
|
||||
)
|
||||
))))
|
||||
|
||||
(set! id (play! idx))
|
||||
(while (= (gui-status pending) (get-status *gui-control* id))
|
||||
(suspend))
|
||||
|
||||
(until (or exit? (!= *master-mode* 'menu))
|
||||
(format *stdcon* "Vag Player -- Press Triangle To Exit~%")
|
||||
(cond
|
||||
((zero? id)
|
||||
(format *stdcon* "No vag queued~%"))
|
||||
((not (playing? id))
|
||||
(format *stdcon* "Vag not playing~%"))
|
||||
(else
|
||||
(format *stdcon* "Vag playing: ~3L~D~0L~%" (the int (/ (the float (current-str-pos id)) 34.133335))))
|
||||
)
|
||||
(format *stdcon* "Vag: ~S <- ~S(max:~3L~D~0L) -> ~S~%" (if (> idx 0) (-> *vag-list* (1- idx)))
|
||||
(-> *vag-list* idx) (-> *vag-max-pos-list* idx)
|
||||
(if (< (1+ idx) (-> *vag-list* allocated-length)) (-> *vag-list* (1+ idx))))
|
||||
(format *stdcon* "X to Pause and Play~%R1 and L1 for Speed, Circle Resets~%Left and Right for Prev / Next~%")
|
||||
(format *stdcon* "Speed: ~f~%" speed)
|
||||
(cond
|
||||
((cpad-pressed? 0 triangle)
|
||||
(cpad-clear! 0 triangle)
|
||||
(stop! id)
|
||||
(true! exit?))
|
||||
((cpad-pressed? 0 x)
|
||||
(cpad-clear! 0 x)
|
||||
(cond
|
||||
((not (playing? id))
|
||||
(set! id (play! idx))
|
||||
(set! old-speed 0.0))
|
||||
((= speed -1000.0)
|
||||
(set! speed 0.0)
|
||||
(sound-continue 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) id)
|
||||
(set! (-> cmd params pitch-mod) 0)
|
||||
(set! (-> cmd params mask) (the-as uint 2))
|
||||
(-> cmd id)
|
||||
)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(set! speed -1000.0)
|
||||
(sound-pause id)
|
||||
)
|
||||
)
|
||||
)
|
||||
((and (cpad-pressed? 0 left) (> idx 0))
|
||||
(cpad-clear! 0 left)
|
||||
(stop! id)
|
||||
(1-! idx)
|
||||
(set! id (play! idx))
|
||||
(set! old-speed 0.0))
|
||||
((and (cpad-pressed? 0 right) (< (1+ idx) (-> *vag-list* allocated-length)))
|
||||
(cpad-clear! 0 right)
|
||||
(stop! id)
|
||||
(1+! idx)
|
||||
(set! id (play! idx))
|
||||
(set! old-speed 0.0))
|
||||
((and (cpad-hold? 0 r1 l1) (!= speed -1000.0))
|
||||
(seek! 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! speed 0.0))
|
||||
((cpad-pressed? 0 square)
|
||||
(cpad-clear! 0 square))
|
||||
)
|
||||
(when (playing? id)
|
||||
(max! (-> *vag-max-pos-list* idx) (the int (/ (the float (current-str-pos id)) 34.133335)))
|
||||
(when (and (!= speed old-speed) (!= speed -1000.0))
|
||||
(set-speed id speed)
|
||||
(set! old-speed speed)))
|
||||
(suspend))
|
||||
)
|
||||
|
||||
(sound-group-pause (sound-group dialog dialog2)) ;; re-pause dialog
|
||||
(remove-setting! 'music-volume)
|
||||
(remove-setting! 'sfx-volume)
|
||||
(remove-setting! 'ambient-volume)
|
||||
(remove-setting! 'dialog-volume)
|
||||
(apply-settings *setting-control*)
|
||||
|
||||
(set! *vag-player* #f)
|
||||
)) idx))
|
||||
#t)
|
||||
|
||||
(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*)
|
||||
|
||||
;; 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 dm-vag-play-pick-func))
|
||||
(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)
|
||||
|
||||
(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))
|
||||
@ -921,8 +739,6 @@
|
||||
(-> *setting-control* user-default subtitle))))
|
||||
;; pick channel
|
||||
|
||||
(build-vag-list *vag-play-menu*)
|
||||
|
||||
(new-dm-submenu "Vag" vag-menu)
|
||||
)
|
||||
)
|
||||
@ -1012,7 +828,7 @@
|
||||
;; (flag "hungarian" 14 dm-text-language)
|
||||
;; )
|
||||
(flag "Discord RPC" #t ,(dm-lambda-boolean-flag (-> *pc-settings* discord-rpc?)))
|
||||
(flag "SpeedRunner Mode" #t ,(dm-lambda-boolean-flag (-> *pc-settings* speedrunner-mode?)))
|
||||
(flag "Speedrunner Mode" #t ,(dm-lambda-boolean-flag (-> *pc-settings* speedrunner-mode?)))
|
||||
(flag "Jetboard Trick String" #t ,(dm-lambda-boolean-flag (-> *pc-settings* jetboard-trick-text?)))
|
||||
;; (flag "Speedrunner Mode" #t ,(dm-lambda-boolean-flag (-> *pc-settings* speedrunner-mode?)))
|
||||
(menu "PS2 settings"
|
||||
@ -1075,12 +891,12 @@
|
||||
(debug-menu-make-from-template *debug-menu-context*
|
||||
'(menu "Other"
|
||||
(flag "DECI Count" *display-deci-count* dm-boolean-toggle-pick-func)
|
||||
;(flag "Actor graph" *display-actor-graph* dm-boolean-toggle-pick-func)
|
||||
(flag "Actor graph" *display-actor-graph* dm-boolean-toggle-pick-func)
|
||||
(flag "Update vis outside bsp" *update-leaf-when-outside-bsp* dm-boolean-toggle-pick-func)
|
||||
;; (flag "Pad display" *display-pad-debug* dm-boolean-toggle-pick-func)
|
||||
(flag "Display actor bank" *display-actor-bank* dm-boolean-toggle-pick-func)
|
||||
(flag "Heap status" *display-heap-status* dm-boolean-toggle-pick-func)
|
||||
;; (flag "Text boxes" *display-text-box* dm-boolean-toggle-pick-func)
|
||||
(flag "Text boxes" *display-text-box* dm-boolean-toggle-pick-func)
|
||||
(flag "Display actor bank" *display-actor-bank* dm-boolean-toggle-pick-func)
|
||||
(float-var "Actor birth dist" #f ,(dm-lambda-meters-var (-> *ACTOR-bank* birth-dist)) 20 1 #t 0 10000 1)
|
||||
(float-var "Actor pause dist" #f ,(dm-lambda-meters-var (-> *ACTOR-bank* pause-dist)) 20 1 #t 0 10000 1)
|
||||
(flag "Display city info" *display-city-info* dm-boolean-toggle-pick-func)
|
||||
|
@ -23,6 +23,7 @@
|
||||
(defun entity-inspect-draw ((inspect-info entity-debug-inspect))
|
||||
"draw text about an entity on screen"
|
||||
|
||||
(mlet ((LINE_HEIGHT 15))
|
||||
(update-pad inspect-info 0)
|
||||
(let* ((e (-> inspect-info entity)) (name (res-lump-struct e 'name string)))
|
||||
(set! *debug-actor* (the string (and (type-type? (-> e type) entity-actor) (-> inspect-info show-actor-info) name)))
|
||||
@ -42,14 +43,14 @@
|
||||
)
|
||||
|
||||
;; start writing text
|
||||
(let* ((begin-y (- 16 (* (-> inspect-info scroll-y) 16))) (cur-y begin-y) (y-adv 16))
|
||||
(let* ((begin-y (- LINE_HEIGHT (* (-> inspect-info scroll-y) LINE_HEIGHT))) (cur-y begin-y) (y-adv 16))
|
||||
(with-dma-buffer-add-bucket ((debug-buf (-> (current-frame) debug-buf))
|
||||
(bucket-id debug-no-zbuf1))
|
||||
;; basic info, actor id, etc
|
||||
(draw-string-xy
|
||||
(string-format "~3L~A~0L ~A~%tags: ~D size: ~D aid: #x~x~%R1/L1 scroll L3 toggle display-actor-info~%--------------------" (-> e type) name (length e) (asize-of e) (-> e aid))
|
||||
debug-buf 352 cur-y (font-color default) (font-flags shadow kerning middle))
|
||||
(+! cur-y (* 14 4))
|
||||
(+! cur-y (* LINE_HEIGHT 4))
|
||||
(cond
|
||||
((type-type? (-> e type) entity-actor)
|
||||
(let ((actor (the entity-actor e)))
|
||||
@ -57,11 +58,11 @@
|
||||
(draw-string-xy
|
||||
(string-format "etype: ~A~%vis: ~D task: ~S" (-> actor etype) (-> actor vis-id) (game-task->string (-> actor task)))
|
||||
debug-buf 352 cur-y (font-color default) (font-flags shadow kerning middle))
|
||||
(+! cur-y (* 14 2))
|
||||
(format *debug-temp-string* "(~S)" (begin (bit-enum->string task-mask (-> actor kill-mask) (clear *temp-string*)) *temp-string*))
|
||||
(+! cur-y (* LINE_HEIGHT 2))
|
||||
(format (clear *debug-temp-string*) "(~S)" (begin (bit-enum->string task-mask (-> actor kill-mask) (clear *temp-string*)) *temp-string*))
|
||||
(draw-string-xy (string-format "kill-mask: ~S" *debug-temp-string*)
|
||||
debug-buf 352 cur-y (font-color default) (font-flags shadow kerning middle))
|
||||
(+! cur-y (* 14 1))
|
||||
(+! cur-y (* LINE_HEIGHT 1))
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -77,7 +78,7 @@
|
||||
(cond
|
||||
;; some water-height info
|
||||
((and (= (-> e tag i name) 'water-height) (= (-> e tag i elt-count) 4) (= (-> e tag i elt-type) float))
|
||||
(+! y-adv (* 14 1))
|
||||
(+! y-adv (* LINE_HEIGHT 1))
|
||||
(format *debug-temp-string* "~mm ~mm ~mm~%(~S)"
|
||||
(-> (the (pointer float) data) 0)
|
||||
(-> (the (pointer float) data) 1)
|
||||
@ -87,7 +88,7 @@
|
||||
)
|
||||
;; some water-height info but with 5 elts
|
||||
((and (= (-> e tag i name) 'water-height) (= (-> e tag i elt-count) 4) (= (-> e tag i elt-type) float))
|
||||
(+! y-adv (* 14 3))
|
||||
(+! y-adv (* LINE_HEIGHT 3))
|
||||
(format *debug-temp-string* "~mm ~mm ~mm~%(~S)~%~mm"
|
||||
(-> (the (pointer float) data) 0)
|
||||
(-> (the (pointer float) data) 1)
|
||||
@ -218,24 +219,24 @@
|
||||
'spawner-blocker-actor 'spawner-trigger-actor 'kill-actor 'fade-actor 'water-actor 'target-actor 'formation-actor)
|
||||
(format *debug-temp-string* "~%#x~x (~S)" (-> (the (pointer uint32) data) ii)
|
||||
(res-lump-struct (entity-by-aid (-> (the (pointer uint32) data) ii)) 'name string))
|
||||
(+! y-adv 14)
|
||||
(+! y-adv LINE_HEIGHT)
|
||||
)
|
||||
(('nav-mesh-actor)
|
||||
(format *debug-temp-string* "~%#x~x (~S)" (-> (the (pointer uint32) data) ii)
|
||||
(res-lump-struct (entity-nav-mesh-by-aid (-> (the (pointer actor-id) data) ii)) 'name string))
|
||||
(+! y-adv 14)
|
||||
(+! y-adv LINE_HEIGHT)
|
||||
)
|
||||
(('enemy-options)
|
||||
(format *debug-temp-string* "~%(~S)" (begin (bit-enum->string enemy-option (-> (the (pointer uint32) data) ii) (clear *temp-string*)) *temp-string*))
|
||||
(+! y-adv 14)
|
||||
(+! y-adv LINE_HEIGHT)
|
||||
)
|
||||
(('kill-mask)
|
||||
(format *debug-temp-string* "~%(~S)" (begin (bit-enum->string task-mask (-> (the (pointer uint32) data) ii) (clear *temp-string*)) *temp-string*))
|
||||
(+! y-adv 14)
|
||||
(+! y-adv LINE_HEIGHT)
|
||||
)
|
||||
(('elevator-flags)
|
||||
(format *debug-temp-string* "~%(~S)" (begin (bit-enum->string elevator-flags (-> (the (pointer uint32) data) ii) (clear *temp-string*)) *temp-string*))
|
||||
(+! y-adv 14)
|
||||
(+! y-adv LINE_HEIGHT)
|
||||
)
|
||||
(else
|
||||
(format *debug-temp-string* "#x~x" (-> (the (pointer uint32) data) ii))
|
||||
@ -281,10 +282,10 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
(+! y-adv 14))
|
||||
(+! y-adv LINE_HEIGHT))
|
||||
((pair)
|
||||
(format *debug-temp-string* "~%~A" (-> (the (pointer pair) data) 0))
|
||||
(+! y-adv 14)
|
||||
(+! y-adv LINE_HEIGHT)
|
||||
)
|
||||
((actor-group)
|
||||
(let* ((group (-> (the (pointer actor-group) data) ii))
|
||||
@ -292,9 +293,9 @@
|
||||
(format *debug-temp-string* "~%--- GROUP ~D: ---" ii len)
|
||||
(dotimes (iii len)
|
||||
(format *debug-temp-string* "~% #x~x (~S)" (-> group data iii id) (res-lump-struct (entity-by-aid (-> group data iii id)) 'name string))
|
||||
(+! y-adv 14))
|
||||
(+! y-adv LINE_HEIGHT))
|
||||
)
|
||||
(+! y-adv 14)
|
||||
(+! y-adv LINE_HEIGHT)
|
||||
)
|
||||
;; no clue! please report this.
|
||||
(else
|
||||
@ -310,13 +311,13 @@
|
||||
;; draw a string for each tag instead of all at once. allows using smaller strings.
|
||||
(draw-string-xy *debug-temp-string* debug-buf 352 cur-y (font-color default) (font-flags shadow kerning middle))
|
||||
(+! cur-y y-adv)
|
||||
(set! y-adv 14)
|
||||
(set! y-adv LINE_HEIGHT)
|
||||
|
||||
))
|
||||
;; set max scroll based on how large the whole text was, ignore first 20 lines.
|
||||
(set! (-> inspect-info scroll-y-max) (max 0 (+ -20 (/ (- cur-y begin-y) 14))))
|
||||
(set! (-> inspect-info scroll-y-max) (max 0 (+ -20 (/ (- cur-y begin-y) LINE_HEIGHT))))
|
||||
|
||||
)
|
||||
)))
|
||||
))))
|
||||
|
||||
|
||||
|
464
goal_src/jak2/pc/debug/vag-player.gc
Normal file
464
goal_src/jak2/pc/debug/vag-player.gc
Normal file
@ -0,0 +1,464 @@
|
||||
;;-*-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 sort-string-array ((arr (array string)) (compare-func (function string string object)))
|
||||
"Sort an array, using compare-func to compare elements.
|
||||
The comparison function can return either an integer or a true/false.
|
||||
For integers, use a positive number to represent first > second
|
||||
Ex: (sort lst -) will sort in ascending order
|
||||
For booleans, you must explicitly use #t and not a truthy value.
|
||||
Ex: (sort my-list (lambda ((x int) (y int)) (< x y))) will sort ascending.
|
||||
NOTE: if you use an integer, don't accidentally return #t"
|
||||
(let ((sorted -1))
|
||||
(while (nonzero? sorted)
|
||||
(set! sorted 0)
|
||||
(dotimes (i (1- (-> arr allocated-length)))
|
||||
(let* ((cur (-> arr i))
|
||||
(next (-> arr (1+ i)))
|
||||
(result (compare-func cur next))
|
||||
)
|
||||
(when (and (or (not result) (> (the-as int result) 0)) (!= result #t))
|
||||
(+! sorted 1)
|
||||
(set! (-> arr i) next)
|
||||
(set! (-> arr (1+ i)) cur)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
arr
|
||||
)
|
||||
|
||||
|
||||
(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
|
||||
(sort-string-array list string<=?))
|
||||
)
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; 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*)
|
||||
(dotimes (i (-> *vag-list* allocated-length))
|
||||
(string-upcase (-> *vag-list* i) *vag-temp-string-2*)
|
||||
(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-as string (-> block param 0)))))
|
||||
(when (!= vag-idx -1)
|
||||
(go vag-player-playing vag-idx)
|
||||
(return #t)))
|
||||
#f)
|
||||
(('play-index)
|
||||
(go vag-player-playing (the-as int (-> block param 0))))
|
||||
)
|
||||
)
|
||||
|
||||
:code (behavior ()
|
||||
(sleep-code)
|
||||
(none))
|
||||
|
||||
)
|
||||
|
||||
|
||||
(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-as 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-as 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)))
|
||||
(none))
|
||||
|
||||
: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)
|
||||
(none))
|
||||
)
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; 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-as 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))
|
||||
(go vag-player-idle)
|
||||
)
|
||||
|
||||
|
||||
(defun vag-player-stop ()
|
||||
"kill the subtitle2 process"
|
||||
|
||||
(kill-by-type vag-player *pc-pool*))
|
||||
|
||||
(defun vag-player-start ()
|
||||
"start the subtitle2 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)
|
||||
(cond
|
||||
;; hardcoded cases for the continue points
|
||||
((string= "intro-city-square" name)
|
||||
(process-spawn scene-player :init scene-player-init name #t "ctyindb-intro-start"))
|
||||
((string= "intro-prison" name)
|
||||
(process-spawn scene-player :init scene-player-init name #t "prison-intro-start"))
|
||||
((string= "outro-nest" name)
|
||||
(set! (-> palout memory-mode) (load-buffer-mode borrow))
|
||||
(set! (-> hiphog memory-mode) (load-buffer-mode small-center))
|
||||
(process-spawn scene-player :init scene-player-init name #t "nestb-outro"))
|
||||
((string= "outro-palace" name)
|
||||
(set! (-> palout memory-mode) (load-buffer-mode borrow))
|
||||
(set! (-> hiphog memory-mode) (load-buffer-mode small-center))
|
||||
(process-spawn scene-player :init scene-player-init name #t "throne-outro"))
|
||||
((string= "outro-hiphog" name)
|
||||
(set! (-> hiphog memory-mode) (load-buffer-mode small-center))
|
||||
(process-spawn scene-player :init scene-player-init name #t "hiphog-outro"))
|
||||
((string= "outro-port" name)
|
||||
(set! (-> hiphog memory-mode) (load-buffer-mode small-center))
|
||||
(process-spawn scene-player :init scene-player-init name #t "ctyport-outro"))
|
||||
(else
|
||||
(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)
|
||||
|
@ -19,11 +19,39 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
;; pc enum for languages. this is the game's languages + custom ones.
|
||||
(defenum pc-language
|
||||
:type uint16
|
||||
(english 0)
|
||||
(french 1)
|
||||
(german 2)
|
||||
(spanish 3)
|
||||
(italian 4)
|
||||
(japanese 5)
|
||||
(korean 6)
|
||||
(uk-english 7)
|
||||
;; custom
|
||||
(portuguese 8)
|
||||
(finnish 9)
|
||||
(swedish 10)
|
||||
(danish 11)
|
||||
(norwegian 12)
|
||||
(dutch 13)
|
||||
(br-portuguese 14)
|
||||
(hungarian 15)
|
||||
(catalan 16)
|
||||
(icelandic 17)
|
||||
(russian 18)
|
||||
|
||||
(custom 999) ;; temp
|
||||
)
|
||||
|
||||
;; The Jak 2 version of the pc-settings object.
|
||||
(deftype pc-settings-jak2 (pc-settings)
|
||||
(
|
||||
(fast-airlock? symbol)
|
||||
(fast-elevator? symbol)
|
||||
(text-language pc-language) ;; language for game text
|
||||
|
||||
;; debug
|
||||
(jetboard-trick-text? symbol) ;; enable rendering jetboard trick combo during minigame
|
||||
@ -51,6 +79,7 @@
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; resets
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -119,6 +119,7 @@
|
||||
(("jetboard-trick-text?") (set! (-> obj jetboard-trick-text?) (file-stream-read-symbol file)))
|
||||
(("fast-airlock?") (set! (-> obj fast-airlock?) (file-stream-read-symbol file)))
|
||||
(("fast-elevator?") (set! (-> obj fast-elevator?) (file-stream-read-symbol file)))
|
||||
(("text-language") (set! (-> obj text-language) (the-as pc-language (file-stream-read-int file))))
|
||||
)
|
||||
0)
|
||||
|
||||
@ -129,6 +130,7 @@
|
||||
(format file " (jetboard-trick-text? ~A)~%" (-> obj jetboard-trick-text?))
|
||||
(format file " (fast-airlock? ~A)~%" (-> obj fast-airlock?))
|
||||
(format file " (fast-elevator? ~A)~%" (-> obj fast-elevator?))
|
||||
(format file " (text-language ~D)~%" (-> obj text-language))
|
||||
0)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
355
goal_src/jak2/pc/subtitle2-h.gc
Normal file
355
goal_src/jak2/pc/subtitle2-h.gc
Normal file
@ -0,0 +1,355 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
#|
|
||||
|
||||
Code for subtitles for the PC port. A PC actor pool is provided, and the subtitle2 process lives there.
|
||||
Jak 2 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 (* 192 1024)) ;; 192K heap for subtitles. adjust later if necessary.
|
||||
(defconstant PC_SUBTITLE_FILE_NAME "subti2")
|
||||
(defconstant PC_SUBTITLE_QUEUE_SIZE 5) ;; up to 8 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-subtitle2-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-subtitle2-speaker
|
||||
:type uint16
|
||||
(none) ;; won't display a speaker - use this for tutorial messages etc.
|
||||
|
||||
(computer)
|
||||
(jak)
|
||||
(darkjak)
|
||||
(daxter)
|
||||
(samos)
|
||||
(keira)
|
||||
(keira-before-class-3)
|
||||
(kid)
|
||||
(kor)
|
||||
(metalkor)
|
||||
(baron)
|
||||
(errol)
|
||||
(torn)
|
||||
(tess)
|
||||
(guard)
|
||||
(guard-a)
|
||||
(guard-b)
|
||||
(krew)
|
||||
(sig)
|
||||
(brutter)
|
||||
(vin)
|
||||
(youngsamos)
|
||||
(youngsamos-before-rescue)
|
||||
(pecker)
|
||||
(onin)
|
||||
(ashelin)
|
||||
(jinx)
|
||||
(mog)
|
||||
(grim)
|
||||
(agent)
|
||||
(citizen-male)
|
||||
(citizen-female)
|
||||
(oracle)
|
||||
(precursor)
|
||||
|
||||
(max))
|
||||
|
||||
;; information about a single line of subtitles
|
||||
(deftype subtitle2-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 subtitle2 line
|
||||
(speaker pc-subtitle2-speaker) ;; who the line speaker is
|
||||
(flags pc-subtitle2-flags) ;; flags
|
||||
)
|
||||
:pack-me
|
||||
)
|
||||
|
||||
;; an individual entry to a subtitle2 text making up a "scene" (audio file, spool), comprised of a series of lines
|
||||
(deftype subtitle2-scene (structure)
|
||||
(
|
||||
;; the name of the spool-anim or audio file
|
||||
(name string)
|
||||
;; the amount of lines
|
||||
(length int32)
|
||||
;; line data
|
||||
(lines (inline-array subtitle2-line))
|
||||
)
|
||||
:pack-me
|
||||
:size-assert #xc ;; compact!
|
||||
|
||||
(:methods
|
||||
(get-line-at-pos (_type_ float int) subtitle2-line)
|
||||
)
|
||||
)
|
||||
|
||||
;; the global subtitle2 text info bank
|
||||
(deftype subtitle2-text-info (basic)
|
||||
((length int16)
|
||||
(version int16)
|
||||
(lang pc-language)
|
||||
(speaker-length int16)
|
||||
(speaker-names (pointer string))
|
||||
(data subtitle2-scene :inline :dynamic)
|
||||
)
|
||||
|
||||
(:methods
|
||||
(get-speaker (_type_ pc-subtitle2-speaker) string)
|
||||
(get-scene-by-name (_type_ string) subtitle2-scene)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(defmacro subtitle2-flags? (sub &rest flags)
|
||||
`(logtest? (-> ,sub flags) (pc-subtitle2-flags ,@flags)))
|
||||
|
||||
|
||||
(defmethod inspect subtitle2-text-info ((obj subtitle2-text-info))
|
||||
(if (not obj)
|
||||
(return (the subtitle2-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-subtitle2-speaker (-> obj data i lines ii speaker))
|
||||
(-> obj data i lines ii text)))
|
||||
)
|
||||
obj)
|
||||
|
||||
|
||||
;;;----------------------------------
|
||||
;; process type
|
||||
;;;----------------------------------
|
||||
|
||||
|
||||
;; graphic parameters for subtitles
|
||||
(deftype subtitle2-bank (structure)
|
||||
((scale float)
|
||||
(width float)
|
||||
(lines float)
|
||||
)
|
||||
)
|
||||
|
||||
(define *SUBTITLE2-bank*
|
||||
(new 'static 'subtitle2-bank
|
||||
:scale 0.9
|
||||
:width 0.65
|
||||
:lines 2.0
|
||||
))
|
||||
|
||||
|
||||
(deftype subtitle2-queue-element (structure)
|
||||
((id sound-id)
|
||||
(gui gui-connection)
|
||||
)
|
||||
:pack-me
|
||||
|
||||
(:methods
|
||||
(clear-line (_type_) int))
|
||||
)
|
||||
|
||||
(deftype subtitle2-line-queue-element (structure)
|
||||
((line subtitle2-line)
|
||||
(y float)
|
||||
)
|
||||
:pack-me
|
||||
)
|
||||
|
||||
;; the subtitle2 process! it lives on the PC actor pool
|
||||
(deftype subtitle2 (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 subtitle2-queue-element PC_SUBTITLE_QUEUE_SIZE :inline)
|
||||
(lines-0 subtitle2-line-queue-element PC_SUBTITLE_MAX_LINES :inline)
|
||||
(lines-1 subtitle2-line-queue-element PC_SUBTITLE_MAX_LINES :inline)
|
||||
(line-queue-idx int8)
|
||||
|
||||
;; debug
|
||||
(cheat-backup symbol)
|
||||
(checking-lines? symbol)
|
||||
(current-debug-subtitle subtitle2-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_ subtitle2-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
|
||||
subtitle2-debug
|
||||
subtitle2-debug-checking-lines)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
;;;----------------------------------------------
|
||||
;; globals
|
||||
;;;----------------------------------------------
|
||||
|
||||
|
||||
;; the subtitle2 process.
|
||||
(define *subtitle2* (the (pointer subtitle2) #f))
|
||||
|
||||
;; subtitle2 text data
|
||||
(define *subtitle2-text* (the subtitle2-text-info #f))
|
||||
(kheap-alloc (define *subtitle2-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 *subtitle2-speaker-color-table* (the (pointer rgba) (malloc 'global (* (size-of rgba) (pc-subtitle2-speaker max)))))
|
||||
|
||||
;; debug option
|
||||
(define *display-subtitle-speakers* #f)
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; helper functions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
(defmethod length subtitle2-text-info ((obj subtitle2-text-info))
|
||||
"Get the length (number of subtitle2 scenes) in a subtitle2-text-info."
|
||||
(-> obj length)
|
||||
)
|
||||
|
||||
(defmethod length subtitle2-scene ((obj subtitle2-scene))
|
||||
"Get the length (number of subtitle2 lines) in a subtitle2-scene."
|
||||
(-> obj length)
|
||||
)
|
||||
|
||||
|
||||
(defmacro set-subtitle-speaker-color! (speaker color)
|
||||
"macro for setting a color in *subtitle2-speaker-color-table*"
|
||||
`(set! (-> *subtitle2-speaker-color-table* (pc-subtitle2-speaker ,speaker)) ,color))
|
||||
(defmacro set-subtitle-speaker-color<-speaker! (speaker speaker-from)
|
||||
"macro for setting a color in *subtitle2-speaker-color-table* the same as a different speaker"
|
||||
`(set-subtitle-speaker-color! ,speaker (-> *subtitle2-speaker-color-table* (pc-subtitle2-speaker ,speaker-from))))
|
||||
|
||||
(defun set-subtitle-speaker-colors ()
|
||||
"fill the subtitle speaker color table"
|
||||
|
||||
(dotimes (i (pc-subtitle2-speaker max))
|
||||
(set! (-> *subtitle2-speaker-color-table* i) (-> *font-work* color-table (font-color red) color 0))
|
||||
)
|
||||
|
||||
(set-subtitle-speaker-color! computer (static-rgba #x60 #x60 #x60 #x80))
|
||||
(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! samos (static-rgba #x30 #x80 #x08 #x80))
|
||||
(set-subtitle-speaker-color! youngsamos (static-rgba #x58 #x80 #x08 #x80))
|
||||
(set-subtitle-speaker-color! kor (static-rgba #x00 #x50 #x80 #x80))
|
||||
(set-subtitle-speaker-color! torn (static-rgba #x40 #x40 #x50 #x80))
|
||||
(set-subtitle-speaker-color! metalkor (static-rgba #x00 #x28 #x40 #x80))
|
||||
(set-subtitle-speaker-color! baron (static-rgba #x60 #x00 #x00 #x80))
|
||||
(set-subtitle-speaker-color! errol (static-rgba #x80 #x10 #x00 #x80))
|
||||
(set-subtitle-speaker-color! ashelin (static-rgba #x80 #x18 #x18 #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! oracle (static-rgba #x80 #x40 #x00 #x80))
|
||||
(set-subtitle-speaker-color! brutter (static-rgba #x58 #x00 #x18 #x80))
|
||||
(set-subtitle-speaker-color! guard (static-rgba #x80 #x00 #x00 #x80))
|
||||
(set-subtitle-speaker-color! krew (static-rgba #x10 #x48 #x10 #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! pecker (static-rgba #x80 #x80 #x00 #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! mog (static-rgba #x08 #x08 #x80 #x80))
|
||||
(set-subtitle-speaker-color! grim (static-rgba #x80 #x08 #x20 #x80))
|
||||
(set-subtitle-speaker-color! precursor (static-rgba #x00 #x60 #x80 #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! kid jak)
|
||||
(set-subtitle-speaker-color<-speaker! guard-a guard)
|
||||
(set-subtitle-speaker-color<-speaker! guard-b guard)
|
||||
(set-subtitle-speaker-color<-speaker! keira-before-class-3 keira)
|
||||
(set-subtitle-speaker-color<-speaker! youngsamos-before-rescue youngsamos)
|
||||
)
|
||||
|
||||
|
||||
|
875
goal_src/jak2/pc/subtitle2.gc
Normal file
875
goal_src/jak2/pc/subtitle2.gc
Normal file
@ -0,0 +1,875 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
#|
|
||||
|
||||
Code for subtitles for the PC port. A PC actor pool is provided, and the subtitle2 process lives there.
|
||||
Jak 2 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 subtitle2-text-info ((obj subtitle2-text-info) (speaker pc-subtitle2-speaker))
|
||||
"get the translated string for that speaker"
|
||||
(if (and (> speaker (pc-subtitle2-speaker none)) (< speaker (-> obj speaker-length)))
|
||||
(-> obj speaker-names speaker)
|
||||
(the string #f))
|
||||
)
|
||||
|
||||
(defmethod get-scene-by-name subtitle2-text-info ((obj subtitle2-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 subtitle2-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*)
|
||||
(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*)
|
||||
(when (string= *vag-temp-string-2* *vag-temp-string*)
|
||||
(return (-> obj data i)))
|
||||
)
|
||||
|
||||
(the subtitle2-scene #f))
|
||||
|
||||
|
||||
(defmethod get-line-at-pos subtitle2-scene ((obj subtitle2-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 subtitle2-line #f))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; loading files
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
(defun load-subtitle2-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 subtitle2-text-info to link the file to
|
||||
heap = the text heap to load the file onto"
|
||||
|
||||
(let ((heap-sym-heap (the-as subtitle2-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 subtitle2~%")
|
||||
(return 0)
|
||||
(goto loaded)
|
||||
)
|
||||
(cond
|
||||
((>= load-status (+ heap-free -300))
|
||||
(format 0 "Game subtitle2 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-subtitle2-files ((idx int))
|
||||
"Load the subtitle2 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-subtitle2-text-info PC_SUBTITLE_FILE_NAME '*subtitle2-text* *subtitle2-text-heap*)
|
||||
)
|
||||
|
||||
(none))
|
||||
|
||||
|
||||
(defmacro reload-subtitles ()
|
||||
"rebuild and reload subtitles."
|
||||
`(begin
|
||||
(asm-text-file subtitle2 :files ("game/assets/jak2/game_subtitle.gp"))
|
||||
(if *subtitle2-text*
|
||||
(+! (-> *subtitle2-text* lang) 1))
|
||||
(load-level-subtitle2-files 0)))
|
||||
|
||||
(defmacro reload-text ()
|
||||
"rebuild and reload text."
|
||||
`(begin
|
||||
(mng)
|
||||
(if *common-text*
|
||||
(+! (-> *common-text* language-id) 1))
|
||||
(load-level-text-files 0)))
|
||||
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; subtitle2 queue
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
(defun subtitle-channel? ((ch gui-channel))
|
||||
"can this gui channel be checked for subtitles?"
|
||||
(and (>= ch (gui-channel jak)) (<= ch (gui-channel krew)))
|
||||
)
|
||||
|
||||
(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 (nonzero? (lookup-gui-connection-id *gui-control* (the string #f) (gui-channel query) (gui-action playing)))
|
||||
(nonzero? (lookup-gui-connection-id *gui-control* (the string #f) (gui-channel message) (gui-action playing)))
|
||||
(nonzero? (lookup-gui-connection-id *gui-control* (the string #f) (gui-channel notice-low) (gui-action playing)))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(defmethod clear-line subtitle2-queue-element ((obj subtitle2-queue-element))
|
||||
"make this queue element invalid"
|
||||
|
||||
(set! (-> obj gui) #f)
|
||||
(set! (-> obj id) (new 'static 'sound-id))
|
||||
0)
|
||||
|
||||
(defmethod clear-queue subtitle2 ((obj subtitle2))
|
||||
"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 subtitle2 ((obj subtitle2))
|
||||
"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? subtitle2 ((obj subtitle2) (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 subtitle2 ((obj subtitle2))
|
||||
"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 subtitle2 ((obj subtitle2) (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)
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; subtitle2 process and drawing!
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
(defun set-speaker-color ((speaker pc-subtitle2-speaker))
|
||||
"set the color for the speaker font color"
|
||||
(let ((spk-col (-> *subtitle2-speaker-color-table* speaker)))
|
||||
(set-font-color (font-color progress-selected) 0 (new 'static 'rgba :r (-> spk-col r))
|
||||
(new 'static 'rgba :r (-> spk-col g))
|
||||
(new 'static 'rgba :r (-> spk-col b)))
|
||||
(set-font-color (font-color progress-selected) 1 (new 'static 'rgba :r (-> spk-col r))
|
||||
(new 'static 'rgba :r (-> spk-col g))
|
||||
(new 'static 'rgba :r (-> spk-col b))))
|
||||
speaker)
|
||||
|
||||
|
||||
(defmethod get-active-subtitles subtitle2 ((obj subtitle2))
|
||||
"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 subtitle2 ((obj subtitle2) (line subtitle2-line))
|
||||
"format the string for a subtitle line to *temp-string*"
|
||||
|
||||
(when (subtitle2-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-subtitle2-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?)) (subtitle2-flags? line offscreen)))
|
||||
;; there is a speaker and we do want it.
|
||||
;; we use color 33 which gets set at runtime to any color we want
|
||||
(string-format "~33L~S:~0L ~S" (get-speaker *subtitle2-text* (-> line speaker)) (-> line text)))
|
||||
(else
|
||||
(string-format "~S" (-> line text)))
|
||||
)
|
||||
*temp-string*)
|
||||
|
||||
(defbehavior current-subtitle2-pos subtitle2 ((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-subtitle2-font subtitle2 ((font font-context))
|
||||
"setup a font and parameters for the subtitle2 subtitles."
|
||||
|
||||
;; set font settings.
|
||||
(if (!= (language-enum japanese) (-> *setting-control* user-current subtitle-language))
|
||||
(set-scale! font (* 0.5 (-> *SUBTITLE2-bank* scale)))
|
||||
(set-scale! font (* 0.5 (-> *SUBTITLE2-bank* scale) 1.2)))
|
||||
(set-width! font (the int (* (-> *SUBTITLE2-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 (* (-> *SUBTITLE2-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 subtitle2 ((self subtitle2))
|
||||
"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 (inline-array subtitle2-line-queue-element)) (line subtitle2-line))
|
||||
(dotimes (i PC_SUBTITLE_MAX_LINES)
|
||||
(if (= line (-> queue 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! (-> line-queue i line) #f)
|
||||
(set! (-> line-queue i y) PC_SUBTITLE_Y_RECALC)
|
||||
)
|
||||
|
||||
;; we won't be able to render any subtitles with no text loaded.
|
||||
(when (not *subtitle2-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-subtitle2-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-subtitle2-pos (-> self queue i id))))
|
||||
(when (and (zero? q) *debug-segment*)
|
||||
(format *stdcon* "subtitle pos: ~3L~D~0L (~S)~%" (the int pos) (-> self queue i gui name)))
|
||||
|
||||
(let ((scene (get-scene-by-name *subtitle2-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! (-> line-queue index-in-old line) it)
|
||||
(set! (-> line-queue index-in-old y) (-> line-queue-old 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 subtitle2-line #f))))
|
||||
(if (!= -1 index-empty)
|
||||
(set! (-> line-queue index-empty line) it)))
|
||||
))
|
||||
)
|
||||
)
|
||||
))
|
||||
)
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
(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 i line) (subtitle-format self (-> line-queue 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 i y) PC_SUBTITLE_Y_RECALC)
|
||||
(set! (-> line-queue i y) (- start-y cur-y))
|
||||
(set! cur-y (min cur-y (- start-y (-> line-queue i y)))))
|
||||
(set! (-> self font origin y) cur-y)
|
||||
|
||||
;; check if we should actually draw subtitles and do it
|
||||
(when (and (-> *setting-control* user-current subtitle) (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 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 subtitle2 ((self subtitle2))
|
||||
"print the queue to *stdcon*"
|
||||
|
||||
(format *stdcon* "q: ~%")
|
||||
(dotimes (i PC_SUBTITLE_QUEUE_SIZE)
|
||||
(if (-> self queue i gui)
|
||||
(format *stdcon* "~D: ~S ~3L~D~0L ~D ~`gui-connection`P~%" i
|
||||
(-> self queue i gui name)
|
||||
(the int (current-subtitle2-pos (-> self queue i id)))
|
||||
(-> self queue i id)
|
||||
(-> self queue i gui))))
|
||||
|
||||
(format *stdcon* "l: ~%")
|
||||
(let ((line-queue (if (zero? (-> self line-queue-idx)) (-> self lines-0) (-> self lines-1))))
|
||||
(dotimes (i PC_SUBTITLE_MAX_LINES)
|
||||
(format *stdcon* "~D: ~D ~S~%" i (the int (-> line-queue i y)) (aif (-> line-queue i line) (-> it text)))))
|
||||
|
||||
0)
|
||||
|
||||
(defmethod debug-print-speakers subtitle2 ((self subtitle2))
|
||||
"print all speakers onscreen"
|
||||
|
||||
(if (not *subtitle2-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 (-> *subtitle2-text* speaker-length))
|
||||
(set-speaker-color (the pc-subtitle2-speaker i))
|
||||
(+! (-> font origin y) (print-game-text (string-format "~33L~S" (get-speaker *subtitle2-text* (the pc-subtitle2-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 subtitle2 ((self subtitle2))
|
||||
"start gui queueing"
|
||||
(set! (-> self gui-id) (add-process *gui-control* self (gui-channel subtitle-pc) (gui-action hidden) "subtitle2" (meters 20) 0))
|
||||
)
|
||||
|
||||
(defmethod stop-gui subtitle2 ((self subtitle2))
|
||||
"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 subtitle2-process (subtitle2)
|
||||
|
||||
: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 *subtitle2-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-subtitle2-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 subtitle2-debug)
|
||||
)
|
||||
)
|
||||
|
||||
(load-level-subtitle2-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))
|
||||
)
|
||||
|
||||
(none))
|
||||
|
||||
: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?)
|
||||
(if *debug-segment*
|
||||
(format *stdcon* "subtitle2 movie-mode~%"))
|
||||
(set! (-> self movie-gui) #f)
|
||||
(set! (-> self movie-mode?) #f)
|
||||
(clear (-> self movie-line))
|
||||
)
|
||||
0)
|
||||
|
||||
)
|
||||
|
||||
|
||||
(defstate subtitle2-debug (subtitle2)
|
||||
|
||||
: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 *subtitle2-text*) (zero? (-> *subtitle2-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-subtitle2-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- (-> *subtitle2-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- (-> *subtitle2-text* length)))
|
||||
(1+! (-> self current-debug-scene))
|
||||
(set! (-> self current-debug-line) 0))
|
||||
)
|
||||
)
|
||||
|
||||
(let ((cur-scene (-> *subtitle2-text* data (-> self current-debug-scene))))
|
||||
(if (nonzero? (-> cur-scene length))
|
||||
(set! (-> self current-debug-subtitle) (-> *subtitle2-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)) (-> *subtitle2-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 subtitle2-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 subtitle2-process)
|
||||
)
|
||||
|
||||
(none))
|
||||
|
||||
:code (-> subtitle2-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-subtitle2-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 subtitle2-debug-checking-lines (subtitle2)
|
||||
|
||||
:trans (behavior ()
|
||||
(set! (-> self movie-mode?) #f)
|
||||
(set! (-> self have-message?) #f)
|
||||
(set! (-> self have-minimap?) #f)
|
||||
(set! (-> self have-subtitles?) #f)
|
||||
(setup-subtitle2-font (-> self font))
|
||||
(none))
|
||||
|
||||
: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 *subtitle2-text*))
|
||||
(dotimes (ii (length (-> *subtitle2-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) (-> *subtitle2-text* data i lines ii))
|
||||
(set-speaker-color (-> self current-debug-subtitle speaker))
|
||||
(when (< (* (-> *SUBTITLE2-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 subtitle2-debug)
|
||||
)
|
||||
:post (behavior ()
|
||||
(with-dma-buffer-add-bucket ((buf (-> (current-frame) debug-buf))
|
||||
(bucket-id debug2))
|
||||
(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 subtitle2 ((self subtitle2))
|
||||
|
||||
(stop-gui self)
|
||||
;; not sure this works...
|
||||
(if (= (ppointer->process *subtitle2*) self)
|
||||
(set! *subtitle2* #f))
|
||||
|
||||
((method-of-type process deactivate) self)
|
||||
(none)
|
||||
)
|
||||
|
||||
(defbehavior subtitle2-init-by-other subtitle2 ()
|
||||
"external initializer for subtitle2 process"
|
||||
|
||||
(set! (-> self font) (new 'process 'font-context *font-default-matrix*
|
||||
0 0 0.0 (font-color default) (font-flags shadow kerning left middle large)))
|
||||
(clear-queue self)
|
||||
(dotimes (i PC_SUBTITLE_MAX_LINES)
|
||||
(set! (-> self lines-0 i line) #f)
|
||||
(set! (-> self lines-0 i y) PC_SUBTITLE_Y_RECALC)
|
||||
(set! (-> self lines-1 i line) #f)
|
||||
(set! (-> self lines-1 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 subtitle2-process)
|
||||
)
|
||||
|
||||
|
||||
(defun subtitle2-stop ()
|
||||
"kill the subtitle2 process"
|
||||
|
||||
(if *subtitle2*
|
||||
(deactivate (ppointer->process *subtitle2*)))
|
||||
*subtitle2*)
|
||||
|
||||
(defun subtitle2-start ()
|
||||
"start the subtitle2 process"
|
||||
|
||||
;; fill the subtitle speaker table
|
||||
(set-subtitle-speaker-colors)
|
||||
|
||||
(if *subtitle2*
|
||||
(subtitle2-stop))
|
||||
|
||||
(set! *subtitle2* (process-spawn subtitle2 :from *pc-dead-pool* :to *pc-pool*))
|
||||
)
|
||||
|
||||
;; start the subtitle2 process when this file loads.
|
||||
(subtitle2-start)
|
||||
|
||||
|
||||
|
@ -103,6 +103,18 @@ Val* Compiler::compile_asm_text_file(const goos::Object& form, const goos::Objec
|
||||
db.m_subtitle_groups = std::make_unique<GameSubtitleGroups>();
|
||||
db.m_subtitle_groups->hydrate_from_asset_file();
|
||||
compile_game_subtitle(inputs, db, m_make.compiler_output_prefix());
|
||||
} else if (kind == "subtitle2") {
|
||||
std::vector<GameSubtitle2DefinitionFile> inputs;
|
||||
// open all project files specified (usually one).
|
||||
for_each_in_list(args.named.at("files"), [this, &inputs, &form, &kind](const goos::Object& o) {
|
||||
if (o.is_string()) {
|
||||
open_subtitle2_project(kind, o.as_string()->data, inputs);
|
||||
} else {
|
||||
throw_compiler_error(form, "Invalid object {} in asm-text-file files list.", o.print());
|
||||
}
|
||||
});
|
||||
GameSubtitle2DB db(m_version);
|
||||
compile_game_subtitle2(inputs, db, m_make.compiler_output_prefix());
|
||||
} else if (kind == "text") {
|
||||
std::vector<GameTextDefinitionFile> inputs;
|
||||
// open all project files specified (usually one).
|
||||
|
@ -143,6 +143,83 @@ void compile_subtitle(GameSubtitleDB& db, const std::string& output_prefix) {
|
||||
data.data(), data.size());
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Write game subtitle2 data to a file. Uses the V2 object format which is identical between GOAL
|
||||
* and OpenGOAL.
|
||||
*/
|
||||
void compile_subtitle2(GameSubtitle2DB& db, const std::string& output_prefix) {
|
||||
auto& speaker_names = get_speaker_names(db.version());
|
||||
for (const auto& [lang, bank] : db.banks()) {
|
||||
auto font = get_font_bank(bank->text_version);
|
||||
DataObjectGenerator gen;
|
||||
gen.add_type_tag("subtitle2-text-info"); // type
|
||||
gen.add_word((bank->scenes.size() & 0xffff) | (1 << 16)); // length (lo) + version (hi)
|
||||
// note: we add 1 because "none" isn't included
|
||||
gen.add_word((lang & 0xffff) | ((speaker_names.size() + 1) << 16)); // lang + speaker-length
|
||||
int speaker_array_link = gen.add_word(0); // speaker array (dummy for now)
|
||||
|
||||
auto speaker_index_by_name = [&speaker_names](const std::string& name) {
|
||||
for (int i = 0; i < speaker_names.size(); ++i) {
|
||||
if (speaker_names.at(i) == name) {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
// fifo queue for scene data arrays
|
||||
std::queue<int> array_link_sources;
|
||||
// now add all the scenes inline
|
||||
for (auto& [name, scene] : bank->scenes) {
|
||||
gen.add_ref_to_string_in_pool(name); // scene name
|
||||
gen.add_word(scene.lines.size()); // line amount
|
||||
array_link_sources.push(gen.words());
|
||||
gen.add_word(0); // line array (linked later)
|
||||
}
|
||||
// now add all the line arrays and link them to their scene
|
||||
for (auto& [name, scene] : bank->scenes) {
|
||||
// link inline-array with reference from earlier
|
||||
gen.link_word_to_word(array_link_sources.front(), gen.words());
|
||||
array_link_sources.pop();
|
||||
|
||||
for (auto& line : scene.lines) {
|
||||
gen.add_word_float(line.start); // start frame
|
||||
gen.add_word_float(line.end); // end frame
|
||||
if (!line.merge) {
|
||||
gen.add_ref_to_string_in_pool(font->convert_utf8_to_game(line.text)); // line text
|
||||
} else {
|
||||
gen.add_symbol_link("#f");
|
||||
}
|
||||
u16 speaker = speaker_index_by_name(line.speaker);
|
||||
u16 flags = 0;
|
||||
flags |= line.offscreen << 0;
|
||||
flags |= line.merge << 1;
|
||||
gen.add_word(speaker | (flags << 16)); // speaker (lo) + flags (hi)
|
||||
}
|
||||
}
|
||||
// now write the array of strings for the speakers
|
||||
gen.link_word_to_word(speaker_array_link, gen.words());
|
||||
// we write #f for invalid entries, including the "none" at the start
|
||||
gen.add_symbol_link("#f");
|
||||
for (auto& speaker_name : speaker_names) {
|
||||
if (bank->speakers.count(speaker_name) == 0) {
|
||||
// no speaker for this
|
||||
gen.add_symbol_link("#f");
|
||||
} else {
|
||||
gen.add_ref_to_string_in_pool(font->convert_utf8_to_game(bank->speakers.at(speaker_name)));
|
||||
}
|
||||
}
|
||||
|
||||
auto data = gen.generate_v2();
|
||||
|
||||
file_util::create_dir_if_needed(file_util::get_file_path({"out", output_prefix, "iso"}));
|
||||
file_util::write_binary_file(
|
||||
file_util::get_file_path(
|
||||
{"out", output_prefix, "iso", fmt::format("{}{}.TXT", lang, uppercase("subti2"))}),
|
||||
data.data(), data.size());
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/*!
|
||||
@ -183,3 +260,14 @@ void compile_game_subtitle(const std::vector<GameSubtitleDefinitionFile>& files,
|
||||
}
|
||||
compile_subtitle(db, output_prefix);
|
||||
}
|
||||
|
||||
void compile_game_subtitle2(const std::vector<GameSubtitle2DefinitionFile>& files,
|
||||
GameSubtitle2DB& db,
|
||||
const std::string& output_prefix) {
|
||||
goos::Reader reader;
|
||||
for (auto& file : files) {
|
||||
lg::print("[Build Game Subtitle] JSON {}\n", file.file_path);
|
||||
parse_subtitle2_json(db, file);
|
||||
}
|
||||
compile_subtitle2(db, output_prefix);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <unordered_set>
|
||||
|
||||
#include "common/serialization/subtitles/subtitles_ser.h"
|
||||
#include "common/serialization/subtitles2/subtitles2_ser.h"
|
||||
#include "common/util/Assert.h"
|
||||
#include "common/util/FontUtils.h"
|
||||
|
||||
@ -15,3 +16,6 @@ void compile_game_text(const std::vector<GameTextDefinitionFile>& filenames,
|
||||
void compile_game_subtitle(const std::vector<GameSubtitleDefinitionFile>& filenames,
|
||||
GameSubtitleDB& db,
|
||||
const std::string& output_prefix);
|
||||
void compile_game_subtitle2(const std::vector<GameSubtitle2DefinitionFile>& filenames,
|
||||
GameSubtitle2DB& db,
|
||||
const std::string& output_prefix);
|
||||
|
@ -31,7 +31,7 @@ int main(int argc, char** argv) {
|
||||
std::string cmd = "";
|
||||
std::string username = "#f";
|
||||
std::string game = "jak1";
|
||||
int nrepl_port = 8181;
|
||||
int nrepl_port = -1;
|
||||
fs::path project_path_override;
|
||||
|
||||
// TODO - a lot of these flags could be deprecated and moved into `repl-config.json`
|
||||
@ -40,7 +40,8 @@ int main(int argc, char** argv) {
|
||||
app.add_option("-c,--cmd", cmd, "Specify a command to run, no REPL is launched in this mode");
|
||||
app.add_option("-u,--user", username,
|
||||
"Specify the username to use for your user profile in 'goal_src/user/'");
|
||||
app.add_option("-p,--port", nrepl_port, "Specify the nREPL port. Defaults to 8181");
|
||||
app.add_option("-p,--port", nrepl_port,
|
||||
"Specify the nREPL port. Defaults to 8181 for Jak 1 and 8182 for Jak 2");
|
||||
app.add_flag("--user-auto", auto_find_user,
|
||||
"Attempt to automatically deduce the user, overrides '--user'");
|
||||
app.add_option("-g,--game", game, "The game name: 'jak1' or 'jak2'");
|
||||
@ -50,6 +51,17 @@ int main(int argc, char** argv) {
|
||||
CLI11_PARSE(app, argc, argv);
|
||||
|
||||
GameVersion game_version = game_name_to_version(game);
|
||||
if (nrepl_port == -1) {
|
||||
switch (game_version) {
|
||||
default:
|
||||
case GameVersion::Jak1:
|
||||
nrepl_port = 8181;
|
||||
break;
|
||||
case GameVersion::Jak2:
|
||||
nrepl_port = 8182;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!project_path_override.empty()) {
|
||||
if (!fs::exists(project_path_override)) {
|
||||
|
@ -100,6 +100,7 @@ MakeSystem::MakeSystem(const std::optional<REPL::Config> repl_config, const std:
|
||||
add_tool<GroupTool>();
|
||||
add_tool<TextTool>();
|
||||
add_tool<SubtitleTool>();
|
||||
add_tool<Subtitle2Tool>();
|
||||
add_tool<BuildLevelTool>();
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user