mirror of
https://github.com/open-goal/jak-project
synced 2026-07-09 14:55:51 -04:00
decomp: support part-tracker-spawn in jak2, part group constants (#4082)
This commit is contained in:
@@ -1515,10 +1515,10 @@ FormElement* rewrite_joint_macro(LetElement* in, const Env& env, FormPool& pool)
|
||||
args);
|
||||
}
|
||||
|
||||
FormElement* rewrite_part_tracker_new(const std::string& type,
|
||||
LetElement* in,
|
||||
const Env& env,
|
||||
FormPool& pool) {
|
||||
FormElement* rewrite_part_tracker_new_jak3(const std::string& type,
|
||||
LetElement* in,
|
||||
const Env& env,
|
||||
FormPool& pool) {
|
||||
// (let ((s4-11 (get-process *default-dead-pool* part-tracker #x4000 0)))
|
||||
// (when s4-11
|
||||
// (let ((t9-26 (method-of-type part-tracker activate)))
|
||||
@@ -1673,6 +1673,139 @@ FormElement* rewrite_part_tracker_new(const std::string& type,
|
||||
->try_as_single_element();
|
||||
}
|
||||
|
||||
FormElement* rewrite_part_tracker_new_jak2(const std::string& type,
|
||||
LetElement* in,
|
||||
const Env& env,
|
||||
FormPool& pool) {
|
||||
// (let ((s5-8 (get-process *default-dead-pool* part-tracker #x4000)))
|
||||
// (when s5-8
|
||||
// (let ((t9-17 (method-of-type part-tracker activate)))
|
||||
// (t9-17 (the-as part-tracker s5-8) self (symbol->string (-> part-tracker symbol)) (the-as
|
||||
// pointer #x70004000))
|
||||
// )
|
||||
// (let ((t9-18 run-function-in-process)
|
||||
// (a0-34 s5-8)
|
||||
// (a1-21 part-tracker-init)
|
||||
// (a2-11 (-> *part-group-id-table* 126))
|
||||
// (a3-9 0)
|
||||
// (t0-6 #f)
|
||||
// (t1-4 #f)
|
||||
// (t2-4 #f)
|
||||
// (t3-0 *launch-matrix*)
|
||||
// )
|
||||
// (set! (-> t3-0 trans quad) (-> self root trans quad))
|
||||
// ((the-as (function object object object object object object object object none) t9-18)
|
||||
// a0-34
|
||||
// a1-21
|
||||
// a2-11
|
||||
// a3-9
|
||||
// t0-6
|
||||
// t1-4
|
||||
// t2-4
|
||||
// t3-0
|
||||
// )
|
||||
// )
|
||||
// (-> s5-8 ppointer)
|
||||
// )
|
||||
// )
|
||||
auto cond = dynamic_cast<CondNoElseElement*>(in->body()->at(0));
|
||||
if (!cond) {
|
||||
return nullptr;
|
||||
}
|
||||
auto when_body = cond->entries.at(0).body;
|
||||
auto activate_let = dynamic_cast<LetElement*>(when_body->at(0));
|
||||
if (!activate_let) {
|
||||
return nullptr;
|
||||
}
|
||||
auto activate_matcher = Matcher::let(
|
||||
false,
|
||||
{LetEntryMatcher::any(Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::METHOD_OF_TYPE),
|
||||
{Matcher::any(), Matcher::constant_token("activate")}),
|
||||
0)},
|
||||
{Matcher::func(Matcher::reg(Register(Reg::GPR, Reg::T9)),
|
||||
{Matcher::any(), Matcher::any(1), Matcher::any(2), Matcher::any()})});
|
||||
auto activate_mr = match(activate_matcher, when_body->at(0));
|
||||
if (!activate_mr.matched) {
|
||||
return nullptr;
|
||||
}
|
||||
auto name = activate_mr.maps.forms.find(2);
|
||||
auto to = activate_mr.maps.forms.find(1);
|
||||
auto params_let = dynamic_cast<LetElement*>(when_body->at(1));
|
||||
if (!params_let) {
|
||||
return nullptr;
|
||||
}
|
||||
auto params_matcher = Matcher::unmerged_let(
|
||||
{
|
||||
LetEntryMatcher::any(Matcher::symbol("run-function-in-process")),
|
||||
LetEntryMatcher::any(Matcher::any()),
|
||||
LetEntryMatcher::any(Matcher::symbol("part-tracker-init")),
|
||||
LetEntryMatcher::any(Matcher::any(0)), // group
|
||||
LetEntryMatcher::any(Matcher::any(1)), // duration
|
||||
LetEntryMatcher::any(Matcher::any(2)), // callback
|
||||
LetEntryMatcher::any(Matcher::any(3)), // userdata
|
||||
LetEntryMatcher::any(Matcher::any(4)), // target
|
||||
LetEntryMatcher::any(Matcher::any()) // *launch-matrix*
|
||||
},
|
||||
{Matcher::set(Matcher::any(), Matcher::any(5))});
|
||||
auto params_mr = match(params_matcher, when_body->at(1));
|
||||
if (!params_mr.matched) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Form*> macro_args;
|
||||
macro_args.push_back(pool.form<ConstantTokenElement>(":to"));
|
||||
macro_args.push_back(to->second);
|
||||
auto name_str = dynamic_cast<StringConstantElement*>(name->second->try_as_single_element());
|
||||
if (name_str && name_str->value() != type) {
|
||||
macro_args.push_back(pool.form<ConstantTokenElement>(":name"));
|
||||
macro_args.push_back(name->second);
|
||||
}
|
||||
auto group = params_mr.maps.forms.find(0);
|
||||
macro_args.push_back(pool.form<ConstantTokenElement>(":group"));
|
||||
macro_args.push_back(group->second);
|
||||
auto duration = params_mr.maps.forms.find(1);
|
||||
if (duration->second->to_string(env) != "0") {
|
||||
macro_args.push_back(pool.form<ConstantTokenElement>(":duration"));
|
||||
macro_args.push_back(duration->second);
|
||||
}
|
||||
auto callback = params_mr.maps.forms.find(2);
|
||||
if (callback->second->to_string(env) != "#f") {
|
||||
macro_args.push_back(pool.form<ConstantTokenElement>(":callback"));
|
||||
macro_args.push_back(callback->second);
|
||||
}
|
||||
auto userdata = params_mr.maps.forms.find(3);
|
||||
if (userdata->second->to_string(env) != "#f") {
|
||||
macro_args.push_back(pool.form<ConstantTokenElement>(":userdata"));
|
||||
macro_args.push_back(userdata->second);
|
||||
}
|
||||
auto target = params_mr.maps.forms.find(4);
|
||||
if (target->second->to_string(env) != "#f") {
|
||||
macro_args.push_back(pool.form<ConstantTokenElement>(":target"));
|
||||
macro_args.push_back(target->second);
|
||||
}
|
||||
auto mat_joint = params_mr.maps.forms.find(5);
|
||||
auto as_deref = mat_joint->second->try_as_element<DerefElement>();
|
||||
if (!as_deref) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!as_deref->tokens().back().is_field_name("quad")) {
|
||||
return nullptr;
|
||||
}
|
||||
as_deref->tokens().pop_back();
|
||||
macro_args.push_back(pool.form<ConstantTokenElement>(":mat-joint"));
|
||||
if (as_deref->tokens().empty()) {
|
||||
macro_args.push_back(as_deref->base());
|
||||
} else {
|
||||
macro_args.push_back(
|
||||
pool.form<DerefElement>(as_deref->base(), as_deref->is_addr_of(), as_deref->tokens()));
|
||||
}
|
||||
return pool
|
||||
.form<GenericElement>(
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("part-tracker-spawn")),
|
||||
macro_args)
|
||||
->try_as_single_element();
|
||||
}
|
||||
|
||||
FormElement* rewrite_call_parent_state_handler(LetElement* in, const Env& env, FormPool& pool) {
|
||||
// (let ((t9-3 (-> (find-parent-state) code)))
|
||||
// (if t9-3
|
||||
@@ -1794,7 +1927,18 @@ FormElement* rewrite_proc_new(LetElement* in, const Env& env, FormPool& pool) {
|
||||
// part-tracker-spawn macro for jak 3
|
||||
if (env.version >= GameVersion::Jak3 &&
|
||||
(proc_type == "part-tracker" || proc_type == "part-tracker-subsampler")) {
|
||||
return rewrite_part_tracker_new(proc_type, in, env, pool);
|
||||
auto form = rewrite_part_tracker_new_jak3(proc_type, in, env, pool);
|
||||
if (form) {
|
||||
return form;
|
||||
}
|
||||
}
|
||||
|
||||
// part-tracker-spawn macro for jak 2
|
||||
if (env.version == GameVersion::Jak2 && proc_type == "part-tracker") {
|
||||
auto form = rewrite_part_tracker_new_jak2(proc_type, in, env, pool);
|
||||
if (form) {
|
||||
return form;
|
||||
}
|
||||
}
|
||||
|
||||
auto macro_form =
|
||||
|
||||
Reference in New Issue
Block a user