mirror of
https://github.com/open-goal/jak-project
synced 2026-08-05 09:34:51 -04:00
decompiler fixes
This commit is contained in:
+43
-3
@@ -562,6 +562,18 @@ FunctionVariableDefinitions Env::local_var_type_list(const Form* top_level_form,
|
||||
std::vector<goos::Object> elts;
|
||||
elts.push_back(pretty_print::to_symbol("local-vars"));
|
||||
int count = 0;
|
||||
std::unordered_map<std::string, std::string> emitted_local_types;
|
||||
|
||||
// A user may deliberately give an argument and its saved stack copy the same preferred name.
|
||||
// Treat the argument as the existing lexical binding so the spill is not emitted as a second
|
||||
// local with the same name.
|
||||
for (int i = 0; i < nargs_to_ignore; i++) {
|
||||
auto remapped = m_var_remap.find(get_reg_name(i));
|
||||
if (remapped != m_var_remap.end() && func && i < func->type.arg_count() - 1) {
|
||||
emitted_local_types.emplace(remapped->second, func->type.get_arg(i).print());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& x : vars) {
|
||||
if (x.reg_id.reg.get_kind() == Reg::GPR && x.reg_id.reg.get_gpr() < Reg::A0 + nargs_to_ignore &&
|
||||
x.reg_id.reg.get_gpr() >= Reg::A0 && x.reg_id.id == 0) {
|
||||
@@ -579,12 +591,27 @@ FunctionVariableDefinitions Env::local_var_type_list(const Form* top_level_form,
|
||||
lookup_name = remapped->second;
|
||||
}
|
||||
|
||||
if (m_vars_defined_in_let.find(lookup_name) != m_vars_defined_in_let.end()) {
|
||||
if (m_vars_defined_in_let.find(x.name()) != m_vars_defined_in_let.end() ||
|
||||
m_vars_defined_in_let.find(lookup_name) != m_vars_defined_in_let.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto type_name = x.type.typespec().print();
|
||||
auto retype = m_var_retype.find(x.name());
|
||||
if (retype != m_var_retype.end()) {
|
||||
type_name = retype->second.print();
|
||||
}
|
||||
const auto [existing, inserted] = emitted_local_types.emplace(lookup_name, type_name);
|
||||
if (!inserted) {
|
||||
if (existing->second != type_name) {
|
||||
lg::warn("Local variable {} has conflicting remapped types {} and {}", lookup_name,
|
||||
existing->second, type_name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
count++;
|
||||
elts.push_back(pretty_print::build_list(lookup_name, x.type.typespec().print()));
|
||||
elts.push_back(pretty_print::build_list(lookup_name, type_name));
|
||||
}
|
||||
|
||||
// sort in increasing offset.
|
||||
@@ -602,7 +629,20 @@ FunctionVariableDefinitions Env::local_var_type_list(const Form* top_level_form,
|
||||
if (m_vars_defined_in_let.find(x.name()) != m_vars_defined_in_let.end()) {
|
||||
continue;
|
||||
}
|
||||
elts.push_back(pretty_print::build_list(x.name(), x.typespec.print()));
|
||||
auto type_name = x.typespec.print();
|
||||
auto retype = m_var_retype.find(x.name());
|
||||
if (retype != m_var_retype.end()) {
|
||||
type_name = retype->second.print();
|
||||
}
|
||||
const auto [existing, inserted] = emitted_local_types.emplace(x.name(), type_name);
|
||||
if (!inserted) {
|
||||
if (existing->second != type_name) {
|
||||
lg::warn("Local variable {} has conflicting remapped types {} and {}", x.name(),
|
||||
existing->second, type_name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
elts.push_back(pretty_print::build_list(x.name(), type_name));
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,11 +131,13 @@ FormElement* handle_get_property_data_or_structure(const std::vector<Form*>& for
|
||||
time = nullptr;
|
||||
}
|
||||
|
||||
// get the default value. It must be (the-as pointer #f)
|
||||
// get the default value. The ordinary macro default can be omitted.
|
||||
Form* default_value = forms.at(4);
|
||||
// but let's see if it's 0, because that's the default in the macro
|
||||
if (default_value->to_string(env) != expcted_default) {
|
||||
lg::error("fail data: bad default {}", default_value->to_string(env));
|
||||
if (default_value->to_string(env) == expcted_default) {
|
||||
default_value = nullptr;
|
||||
} else if (kind != ResLumpMacroElement::Kind::STRUCT ||
|
||||
env.version != GameVersion::Jak1) {
|
||||
// Only Jak 1's res-lump-struct macro currently exposes a custom default.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -153,7 +155,7 @@ FormElement* handle_get_property_data_or_structure(const std::vector<Form*>& for
|
||||
}
|
||||
|
||||
return pool.alloc_element<ResLumpMacroElement>(kind, lump_object, property_name,
|
||||
nullptr, // default, must be #f
|
||||
default_value,
|
||||
tag_pointer, time, default_type);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -1555,6 +1555,7 @@ class StackSpillStoreElement : public FormElement {
|
||||
void push_to_stack(const Env& env, FormPool& pool, FormStack& stack) override;
|
||||
const std::optional<TypeSpec>& cast_type() const { return m_cast_type; }
|
||||
const RegisterAccess& access() const { return m_access; }
|
||||
const SimpleAtom& value() const { return m_value; }
|
||||
int stack_offset() const { return m_stack_offset; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -2746,13 +2746,19 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||
if (src_as_se) {
|
||||
if (src_as_se->expr().kind() == SimpleExpression::Kind::IDENTITY &&
|
||||
src_as_se->expr().get_arg(0).is_var()) {
|
||||
// this can happen late in the case of coloring moves which are also gpr -> fpr's
|
||||
// so they don't get caught by SetVarOp::get_as_form's check.
|
||||
if (env.op_id_is_eliminated_coloring_move(src_as_se->expr().get_arg(0).var().idx())) {
|
||||
const auto src_var = src_as_se->expr().get_arg(0).var();
|
||||
if (env.get_variable_name(m_dst) == env.get_variable_name(src_var) &&
|
||||
env.get_variable_type(m_dst, true) == env.get_variable_type(src_var, true)) {
|
||||
m_var_info.is_eliminated_coloring_move = true;
|
||||
}
|
||||
|
||||
auto var = src_as_se->expr().get_arg(0).var();
|
||||
// this can happen late in the case of coloring moves which are also gpr -> fpr's
|
||||
// so they don't get caught by SetVarOp::get_as_form's check.
|
||||
if (env.op_id_is_eliminated_coloring_move(src_var.idx())) {
|
||||
m_var_info.is_eliminated_coloring_move = true;
|
||||
}
|
||||
|
||||
auto var = src_var;
|
||||
bool is_consumed_reg_move = false;
|
||||
if (is_stack_slot_access(var)) {
|
||||
auto& use_def = env.get_use_def_info(var);
|
||||
@@ -2793,7 +2799,12 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||
// stripped off by update_children_from_stack.
|
||||
if (src_as_se->expr().kind() == SimpleExpression::Kind::IDENTITY &&
|
||||
src_as_se->expr().get_arg(0).is_var()) {
|
||||
if (env.op_id_is_eliminated_coloring_move(src_as_se->expr().get_arg(0).var().idx())) {
|
||||
const auto src_var = src_as_se->expr().get_arg(0).var();
|
||||
if (env.get_variable_name(m_dst) == env.get_variable_name(src_var) &&
|
||||
env.get_variable_type(m_dst, true) == env.get_variable_type(src_var, true)) {
|
||||
m_var_info.is_eliminated_coloring_move = true;
|
||||
}
|
||||
if (env.op_id_is_eliminated_coloring_move(src_var.idx())) {
|
||||
m_var_info.is_eliminated_coloring_move = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ struct LetRewriteStats {
|
||||
int abs2 = 0;
|
||||
int unused = 0;
|
||||
int ja = 0;
|
||||
int ja_play = 0;
|
||||
int case_no_else = 0;
|
||||
int case_with_else = 0;
|
||||
int set_vector = 0;
|
||||
@@ -85,7 +86,7 @@ struct LetRewriteStats {
|
||||
int light_trail_tracker_spawn = 0;
|
||||
|
||||
int total() const {
|
||||
return dotimes + countdown + abs + abs2 + unused + ja + case_no_else + case_with_else +
|
||||
return dotimes + countdown + abs + abs2 + unused + ja + ja_play + case_no_else + case_with_else +
|
||||
set_vector + set_vector2 + send_event + font_context_meth + proc_new + attack_info +
|
||||
vector_dot + rand_float_gen + set_let + with_dma_buf_add_bucket + dma_buffer_add_gs_set +
|
||||
launch_particles + call_parent_state_handler + suspend_for + font_method +
|
||||
@@ -100,6 +101,7 @@ struct LetRewriteStats {
|
||||
out += fmt::format(" abs: {}\n", abs);
|
||||
out += fmt::format(" abs2: {}\n", abs2);
|
||||
out += fmt::format(" ja: {}\n", ja);
|
||||
out += fmt::format(" ja-play: {}\n", ja_play);
|
||||
out += fmt::format(" set_vector: {}\n", set_vector);
|
||||
out += fmt::format(" set_vector2: {}\n", set_vector2);
|
||||
out += fmt::format(" set_vector3: {}\n", set_vector3);
|
||||
@@ -130,6 +132,7 @@ struct LetRewriteStats {
|
||||
result.abs = abs + other.abs;
|
||||
result.abs2 = abs2 + other.abs2;
|
||||
result.ja = ja + other.ja;
|
||||
result.ja_play = ja_play + other.ja_play;
|
||||
result.set_vector = set_vector + other.set_vector;
|
||||
result.set_vector2 = set_vector2 + other.set_vector2;
|
||||
result.case_no_else = case_no_else + other.case_no_else;
|
||||
@@ -156,6 +159,7 @@ struct LetRewriteStats {
|
||||
abs += other.abs;
|
||||
abs2 += other.abs2;
|
||||
ja += other.ja;
|
||||
ja_play += other.ja_play;
|
||||
set_vector += other.set_vector;
|
||||
set_vector2 += other.set_vector2;
|
||||
case_no_else += other.case_no_else;
|
||||
|
||||
@@ -791,6 +791,11 @@ void ObjectFileDB::ir2_build_expressions(int seg, const Config& config, ObjectFi
|
||||
func.ir2.env.types_succeeded) {
|
||||
auto name = func.name();
|
||||
auto arg_config = config.function_arg_names.find(name);
|
||||
if (arg_config == config.function_arg_names.end() &&
|
||||
func.guessed_name.kind == FunctionName::FunctionKind::UNIDENTIFIED) {
|
||||
arg_config = config.function_arg_names.find(
|
||||
fmt::format("(anon-function * {})", func.guessed_name.object_name));
|
||||
}
|
||||
auto var_config = config.function_var_overrides.find(name);
|
||||
if (convert_to_expressions(func.ir2.top_form, *func.ir2.form_pool, func,
|
||||
arg_config != config.function_arg_names.end()
|
||||
|
||||
@@ -1171,12 +1171,9 @@ std::unique_ptr<AtomicOp> convert_slt_2(const Instruction& i0,
|
||||
auto temp = i0.get_dst(0).get_reg();
|
||||
auto left = i0.get_src(0).get_reg();
|
||||
auto right = i0.get_src(1).get_reg();
|
||||
if (temp == left) {
|
||||
if (temp == left || temp == right || left == right) {
|
||||
return nullptr;
|
||||
}
|
||||
ASSERT(temp != left);
|
||||
ASSERT(temp != right);
|
||||
ASSERT(left != right);
|
||||
std::unique_ptr<AtomicOp> result;
|
||||
SimpleExpression::Kind kind;
|
||||
if (is_gpr_3(i1, InstructionKind::MOVZ, left, right, temp)) {
|
||||
@@ -1338,12 +1335,12 @@ std::unique_ptr<AtomicOp> convert_dsubu_3(const Instruction& i0,
|
||||
auto a = i0.get_src(0).get_reg();
|
||||
auto b = i0.get_src(1).get_reg();
|
||||
auto dest = i1.get_dst(0).get_reg();
|
||||
ASSERT(i1.get_src(0).is_reg(rs7()));
|
||||
ASSERT(i1.get_src(1).is_imm(true_symbol_offset(version)));
|
||||
ASSERT(i2.get_dst(0).get_reg() == dest);
|
||||
ASSERT(i2.get_src(0).is_reg(rs7()));
|
||||
ASSERT(i2.get_src(1).get_reg() == temp);
|
||||
ASSERT(temp != dest);
|
||||
if (!i1.get_src(0).is_reg(rs7()) ||
|
||||
!i1.get_src(1).is_imm(true_symbol_offset(version)) ||
|
||||
i2.get_dst(0).get_reg() != dest || !i2.get_src(0).is_reg(rs7()) ||
|
||||
i2.get_src(1).get_reg() != temp || temp == dest) {
|
||||
return nullptr;
|
||||
}
|
||||
auto kind = i2.kind == InstructionKind::MOVN ? IR2_Condition::Kind::EQUAL
|
||||
: IR2_Condition::Kind::NOT_EQUAL;
|
||||
std::unique_ptr<AtomicOp> result;
|
||||
@@ -1397,8 +1394,9 @@ std::unique_ptr<AtomicOp> convert_slt_3(const Instruction& i0,
|
||||
// delay slot
|
||||
auto temp = i0.get_dst(0).get_reg();
|
||||
auto dest = i1.get_src(2).get_label();
|
||||
ASSERT(i1.get_src(0).get_reg() == temp);
|
||||
ASSERT(i1.get_src(1).is_reg(rr0()));
|
||||
if (i1.get_src(0).get_reg() != temp || !i1.get_src(1).is_reg(rr0())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IR2_Condition condition;
|
||||
if (s1 == rr0()) {
|
||||
@@ -1430,12 +1428,12 @@ std::unique_ptr<AtomicOp> convert_slt_3(const Instruction& i0,
|
||||
// movz dest, s7, temp
|
||||
auto temp = i0.get_dst(0).get_reg();
|
||||
auto dest = i1.get_dst(0).get_reg();
|
||||
ASSERT(i1.get_src(0).is_reg(rs7()));
|
||||
ASSERT(i1.get_src(1).is_imm(true_symbol_offset(version)));
|
||||
ASSERT(i2.get_dst(0).get_reg() == dest);
|
||||
ASSERT(i2.get_src(0).is_reg(rs7()));
|
||||
ASSERT(i2.get_src(1).get_reg() == temp);
|
||||
ASSERT(temp != dest);
|
||||
if (!i1.get_src(0).is_reg(rs7()) ||
|
||||
!i1.get_src(1).is_imm(true_symbol_offset(version)) ||
|
||||
i2.get_dst(0).get_reg() != dest || !i2.get_src(0).is_reg(rs7()) ||
|
||||
i2.get_src(1).get_reg() != temp || temp == dest) {
|
||||
return nullptr;
|
||||
}
|
||||
IR2_Condition condition;
|
||||
if (s1 == rr0()) {
|
||||
auto kind = is_signed ? IR2_Condition::Kind::LESS_THAN_ZERO_SIGNED
|
||||
@@ -1477,8 +1475,9 @@ std::unique_ptr<AtomicOp> convert_slti_3(const Instruction& i0,
|
||||
// delay slot
|
||||
auto temp = i0.get_dst(0).get_reg();
|
||||
auto dest = i1.get_src(2).get_label();
|
||||
ASSERT(i1.get_src(0).get_reg() == temp);
|
||||
ASSERT(i1.get_src(1).is_reg(rr0()));
|
||||
if (i1.get_src(0).get_reg() != temp || !i1.get_src(1).is_reg(rr0())) {
|
||||
return nullptr;
|
||||
}
|
||||
auto kind =
|
||||
is_signed ? IR2_Condition::Kind::LESS_THAN_SIGNED : IR2_Condition::Kind::LESS_THAN_UNSIGNED;
|
||||
auto condition = IR2_Condition(kind, make_src_atom(s0, idx), s1);
|
||||
@@ -1496,12 +1495,12 @@ std::unique_ptr<AtomicOp> convert_slti_3(const Instruction& i0,
|
||||
// movz dest, s7, temp
|
||||
auto temp = i0.get_dst(0).get_reg();
|
||||
auto dest = i1.get_dst(0).get_reg();
|
||||
ASSERT(i1.get_src(0).is_reg(rs7()));
|
||||
ASSERT(i1.get_src(1).is_imm(true_symbol_offset(version)));
|
||||
ASSERT(i2.get_dst(0).get_reg() == dest);
|
||||
ASSERT(i2.get_src(0).is_reg(rs7()));
|
||||
ASSERT(i2.get_src(1).get_reg() == temp);
|
||||
ASSERT(temp != dest);
|
||||
if (!i1.get_src(0).is_reg(rs7()) ||
|
||||
!i1.get_src(1).is_imm(true_symbol_offset(version)) ||
|
||||
i2.get_dst(0).get_reg() != dest || !i2.get_src(0).is_reg(rs7()) ||
|
||||
i2.get_src(1).get_reg() != temp || temp == dest) {
|
||||
return nullptr;
|
||||
}
|
||||
IR2_Condition condition;
|
||||
|
||||
auto kind =
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "expression_build.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "common/goos/PrettyPrinter.h"
|
||||
#include "common/log/log.h"
|
||||
|
||||
@@ -151,6 +153,34 @@ bool convert_to_expressions(
|
||||
}
|
||||
}
|
||||
|
||||
// A saved argument may intentionally share its preferred name with the argument itself. Once
|
||||
// both accesses print as the same, the prologue spill assignment is a lexical self-assignment;
|
||||
// subsequent spill loads already name the argument binding. Drop only exact, same-typed
|
||||
// top-level aliases so independent same-named variables in nested scopes remain untouched.
|
||||
new_entries.erase(
|
||||
std::remove_if(new_entries.begin(), new_entries.end(), [&](FormElement* entry) {
|
||||
auto* spill = dynamic_cast<StackSpillStoreElement*>(entry);
|
||||
if (spill && spill->value().is_var()) {
|
||||
const auto& source = spill->value().var();
|
||||
const auto slot = f.ir2.env.stack_slot_entries.find(spill->stack_offset());
|
||||
return slot != f.ir2.env.stack_slot_entries.end() &&
|
||||
slot->second.name() == f.ir2.env.get_variable_name(source) &&
|
||||
slot->second.typespec == f.ir2.env.get_variable_type(source, true);
|
||||
}
|
||||
|
||||
auto* set = dynamic_cast<SetVarElement*>(entry);
|
||||
if (!set) {
|
||||
return false;
|
||||
}
|
||||
const auto source = form_element_as_atom(set->src()->try_as_single_element());
|
||||
return source && source->is_var() &&
|
||||
f.ir2.env.get_variable_name(set->dst()) ==
|
||||
f.ir2.env.get_variable_name(source->var()) &&
|
||||
f.ir2.env.get_variable_type(set->dst(), true) ==
|
||||
f.ir2.env.get_variable_type(source->var(), true);
|
||||
}),
|
||||
new_entries.end());
|
||||
|
||||
// if we are a totally empty function, insert a placeholder so we don't have to handle
|
||||
// the zero element case ever.
|
||||
if (new_entries.empty()) {
|
||||
|
||||
@@ -41,6 +41,15 @@ std::string fix_docstring_indent(const std::string& input) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void set_metadata_docstring(std::vector<goos::Object>* body, const std::string& docstring) {
|
||||
auto replacement = pretty_print::new_string(docstring);
|
||||
if (!body->empty() && body->front().is_string()) {
|
||||
body->front() = replacement;
|
||||
} else {
|
||||
body->insert(body->begin(), replacement);
|
||||
}
|
||||
}
|
||||
|
||||
void append_body_to_function_definition(goos::Object* top_form,
|
||||
const std::vector<goos::Object>& inline_body,
|
||||
const FunctionVariableDefinitions& var_dec,
|
||||
@@ -106,6 +115,7 @@ goos::Object final_output_lambda(const Function& func, GameVersion version) {
|
||||
goos::Object final_output_defstate_anonymous_behavior(const Function& func,
|
||||
const DecompilerTypeSystem& dts) {
|
||||
std::vector<goos::Object> inline_body;
|
||||
std::optional<std::string> metadata_docstring;
|
||||
|
||||
// docstring if available - lookup the appropriate info
|
||||
const auto& type_name = func.guessed_name.type_name;
|
||||
@@ -116,22 +126,23 @@ goos::Object final_output_defstate_anonymous_behavior(const Function& func,
|
||||
if (dts.virtual_state_metadata.count(type_name) != 0 &&
|
||||
dts.virtual_state_metadata.at(type_name).count(state_name) != 0 &&
|
||||
dts.virtual_state_metadata.at(type_name).at(state_name).count(handler_name) != 0) {
|
||||
inline_body.insert(inline_body.begin(),
|
||||
pretty_print::new_string(dts.virtual_state_metadata.at(type_name)
|
||||
.at(state_name)
|
||||
.at(handler_name)
|
||||
.docstring.value()));
|
||||
metadata_docstring = dts.virtual_state_metadata.at(type_name)
|
||||
.at(state_name)
|
||||
.at(handler_name)
|
||||
.docstring.value();
|
||||
}
|
||||
} else if (func.guessed_name.kind == FunctionName::FunctionKind::NV_STATE) {
|
||||
if (dts.state_metadata.count(state_name) != 0 &&
|
||||
dts.state_metadata.at(state_name).count(handler_name) != 0) {
|
||||
inline_body.insert(inline_body.begin(),
|
||||
pretty_print::new_string(
|
||||
dts.state_metadata.at(state_name).at(handler_name).docstring.value()));
|
||||
metadata_docstring =
|
||||
dts.state_metadata.at(state_name).at(handler_name).docstring.value();
|
||||
}
|
||||
}
|
||||
|
||||
func.ir2.top_form->inline_forms(inline_body, func.ir2.env);
|
||||
if (metadata_docstring) {
|
||||
set_metadata_docstring(&inline_body, *metadata_docstring);
|
||||
}
|
||||
auto var_dec = func.ir2.env.local_var_type_list(func.ir2.top_form, func.type.arg_count() - 1);
|
||||
|
||||
auto result = pretty_print::build_list("behavior", get_arg_list_for_function(func, func.ir2.env));
|
||||
@@ -183,7 +194,7 @@ std::string final_defun_out(const Function& func,
|
||||
if (dts.symbol_metadata_map.count(func.name()) != 0) {
|
||||
auto& meta = dts.symbol_metadata_map.at(func.name());
|
||||
if (meta.docstring) {
|
||||
inline_body.insert(inline_body.begin(), pretty_print::new_string(meta.docstring.value()));
|
||||
set_metadata_docstring(&inline_body, meta.docstring.value());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,8 +216,7 @@ std::string final_defun_out(const Function& func,
|
||||
auto top_form = pretty_print::build_list(top);
|
||||
|
||||
if (method_info.docstring) {
|
||||
inline_body.insert(inline_body.begin(),
|
||||
pretty_print::new_string(method_info.docstring.value()));
|
||||
set_metadata_docstring(&inline_body, method_info.docstring.value());
|
||||
}
|
||||
append_body_to_function_definition(&top_form, inline_body, var_dec, method_info.type,
|
||||
dts.version());
|
||||
|
||||
@@ -124,7 +124,6 @@ FormElement* rewrite_as_dotimes(LetElement* in, const Env& env, FormPool& pool)
|
||||
|
||||
// look for setting a var to zero.
|
||||
auto ra = in->entries().at(0).dest;
|
||||
auto var = env.get_variable_name(ra);
|
||||
if (!is_constant_int(in->entries().at(0).src, 0)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -143,7 +142,7 @@ FormElement* rewrite_as_dotimes(LetElement* in, const Env& env, FormPool& pool)
|
||||
// check the lt operation:
|
||||
auto lt_var = mr.maps.regs.at(0);
|
||||
ASSERT(lt_var);
|
||||
if (env.get_variable_name(*lt_var) != var) {
|
||||
if (env.get_program_var_id(*lt_var) != env.get_program_var_id(ra)) {
|
||||
return nullptr; // wrong variable checked
|
||||
}
|
||||
|
||||
@@ -161,7 +160,7 @@ FormElement* rewrite_as_dotimes(LetElement* in, const Env& env, FormPool& pool)
|
||||
|
||||
auto inc_var = int_mr.maps.regs.at(0);
|
||||
ASSERT(inc_var);
|
||||
if (env.get_variable_name(*inc_var) != var) {
|
||||
if (env.get_program_var_id(*inc_var) != env.get_program_var_id(ra)) {
|
||||
return nullptr; // wrong variable incremented
|
||||
}
|
||||
|
||||
@@ -630,8 +629,6 @@ FormElement* rewrite_as_countdown(LetElement* in, const Env& env, FormPool& pool
|
||||
|
||||
// look for setting a var to the initial value.
|
||||
auto ra = in->entries().at(0).dest;
|
||||
auto idx_var = env.get_variable_name(ra);
|
||||
|
||||
// still have to check body for the increment and have to check that the lt operates on the right
|
||||
// thing.
|
||||
Matcher while_matcher = Matcher::while_loop(
|
||||
@@ -646,7 +643,7 @@ FormElement* rewrite_as_countdown(LetElement* in, const Env& env, FormPool& pool
|
||||
// check the zero operation:
|
||||
auto lt_var = mr.maps.regs.at(0);
|
||||
ASSERT(lt_var);
|
||||
if (env.get_variable_name(*lt_var) != idx_var) {
|
||||
if (env.get_program_var_id(*lt_var) != env.get_program_var_id(ra)) {
|
||||
return nullptr; // wrong variable checked
|
||||
}
|
||||
|
||||
@@ -664,7 +661,7 @@ FormElement* rewrite_as_countdown(LetElement* in, const Env& env, FormPool& pool
|
||||
|
||||
auto inc_var = int_mr.maps.regs.at(0);
|
||||
ASSERT(inc_var);
|
||||
if (env.get_variable_name(*inc_var) != idx_var) {
|
||||
if (env.get_program_var_id(*inc_var) != env.get_program_var_id(ra)) {
|
||||
return nullptr; // wrong variable incremented
|
||||
}
|
||||
|
||||
@@ -3912,6 +3909,79 @@ FormElement* rewrite_let_sequence(const std::vector<LetElement*>& in,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FormElement* rewrite_ja_play_sequence(FormElement* setup,
|
||||
FormElement* wait,
|
||||
const Env& env,
|
||||
FormPool& pool) {
|
||||
auto setup_call = dynamic_cast<GenericElement*>(setup);
|
||||
if (!setup_call || !setup_call->op().is_func() ||
|
||||
!setup_call->op().func()->to_form(env).is_symbol("ja-no-eval")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto wait_loop = dynamic_cast<UntilElement*>(wait);
|
||||
if (!wait_loop || wait_loop->body->size() < 2) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto find_keyword_arg = [&](const GenericElement* call, const std::string& keyword) -> Form* {
|
||||
const auto& args = call->elts();
|
||||
for (size_t i = 0; i + 1 < args.size(); i++) {
|
||||
if (args.at(i)->to_form(env).is_symbol(keyword)) {
|
||||
return args.at(i + 1);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
auto setup_num = find_keyword_arg(setup_call, ":num!");
|
||||
if (!setup_num) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto setup_chan = find_keyword_arg(setup_call, ":chan");
|
||||
const auto setup_chan_text = setup_chan ? setup_chan->to_form(env).print() : "0";
|
||||
|
||||
if (wait_loop->condition->to_string(env) !=
|
||||
fmt::format("(ja-done? {})", setup_chan_text)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto& wait_body = wait_loop->body->elts();
|
||||
auto suspend_op = dynamic_cast<AtomicOpElement*>(wait_body.at(wait_body.size() - 2));
|
||||
if (!suspend_op || !suspend_op->op() || !dynamic_cast<SpecialOp*>(suspend_op->op()) ||
|
||||
dynamic_cast<SpecialOp*>(suspend_op->op())->kind() != SpecialOp::Kind::SUSPEND) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto advance_call = dynamic_cast<GenericElement*>(wait_body.back());
|
||||
if (!advance_call || !advance_call->op().is_func() ||
|
||||
!advance_call->op().func()->to_form(env).is_symbol("ja")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto advance_num = find_keyword_arg(advance_call, ":num!");
|
||||
auto advance_chan = find_keyword_arg(advance_call, ":chan");
|
||||
const auto advance_chan_text = advance_chan ? advance_chan->to_form(env).print() : "0";
|
||||
if (!advance_num || advance_num->to_form(env).print() != setup_num->to_form(env).print() ||
|
||||
advance_chan_text != setup_chan_text) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t expected_advance_args = advance_chan ? 4 : 2;
|
||||
if (advance_call->elts().size() != expected_advance_args) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Form*> macro_args = setup_call->elts();
|
||||
for (size_t i = 0; i + 2 < wait_body.size(); i++) {
|
||||
macro_args.push_back(pool.alloc_single_form(nullptr, wait_body.at(i)));
|
||||
}
|
||||
|
||||
return pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_function(pool.form<ConstantTokenElement>("ja-play")), macro_args);
|
||||
}
|
||||
|
||||
Form* insert_cast_for_let(RegisterAccess dst,
|
||||
const TypeSpec& src_type,
|
||||
Form* src,
|
||||
@@ -3968,7 +4038,7 @@ LetStats insert_lets(const Function& func,
|
||||
|
||||
// Stored per variable.
|
||||
struct PerVarInfo {
|
||||
std::string var_name; // name used to uniquely identify
|
||||
std::string unique_name; // displayed name used to join deliberately co-named SSA variables
|
||||
RegisterAccess access;
|
||||
std::unordered_set<FormElement*> elts_using_var; // all FormElements using var
|
||||
Form* lca_form = nullptr; // the lowest common form that contains all the above elts
|
||||
@@ -4001,10 +4071,10 @@ LetStats insert_lets(const Function& func,
|
||||
// and add it.
|
||||
for (auto& access : reg_accesses) {
|
||||
if (register_can_hold_var(access.reg())) {
|
||||
auto name = env.get_variable_name(access);
|
||||
var_info[name].elts_using_var.insert(elt);
|
||||
var_info[name].var_name = name;
|
||||
var_info[name].access = access;
|
||||
auto unique_name = env.get_variable_name(access);
|
||||
var_info[unique_name].elts_using_var.insert(elt);
|
||||
var_info[unique_name].unique_name = unique_name;
|
||||
var_info[unique_name].access = access;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -4036,7 +4106,7 @@ LetStats insert_lets(const Function& func,
|
||||
bool uses = false;
|
||||
for (auto& ra : ras) {
|
||||
if ((ra.reg().get_kind() == Reg::FPR || ra.reg().get_kind() == Reg::GPR) &&
|
||||
env.get_variable_name(ra) == kv.second.var_name) {
|
||||
env.get_variable_name(ra) == kv.second.unique_name) {
|
||||
uses = true;
|
||||
}
|
||||
}
|
||||
@@ -4082,7 +4152,8 @@ LetStats insert_lets(const Function& func,
|
||||
auto first_form = info.lca_form->at(info.start_idx);
|
||||
auto first_form_as_set = dynamic_cast<SetVarElement*>(first_form);
|
||||
if (first_form_as_set && register_can_hold_var(first_form_as_set->dst().reg()) &&
|
||||
env.get_variable_name(first_form_as_set->dst()) == env.get_variable_name(info.access) &&
|
||||
env.get_variable_name(first_form_as_set->dst()) ==
|
||||
env.get_variable_name(info.access) &&
|
||||
!first_form_as_set->info().is_eliminated_coloring_move) {
|
||||
bool allowed = true;
|
||||
|
||||
@@ -4105,7 +4176,7 @@ LetStats insert_lets(const Function& func,
|
||||
li.start_elt = info.start_idx;
|
||||
li.end_elt = info.end_idx;
|
||||
li.set_form = first_form_as_set;
|
||||
li.name = info.var_name;
|
||||
li.name = info.unique_name;
|
||||
possible_insertions[li.form].push_back(li);
|
||||
stats.vars_in_lets++;
|
||||
}
|
||||
@@ -4291,6 +4362,21 @@ LetStats insert_lets(const Function& func,
|
||||
}
|
||||
});
|
||||
|
||||
// Part 11: recover the animation-play convenience macro after individual JA setup/eval forms
|
||||
// have been recognized.
|
||||
top_level_form->apply_form([&](Form* f) {
|
||||
auto& form_elts = f->elts();
|
||||
for (size_t i = 0; i + 1 < form_elts.size(); ++i) {
|
||||
auto rewritten = rewrite_ja_play_sequence(form_elts.at(i), form_elts.at(i + 1), env, pool);
|
||||
if (rewritten) {
|
||||
form_elts.erase(form_elts.begin() + i + 1);
|
||||
form_elts.at(i) = rewritten;
|
||||
rewritten->parent_form = f;
|
||||
let_rewrite_stats.ja_play++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
|
||||
+16001
-4111
File diff suppressed because it is too large
Load Diff
@@ -151,7 +151,7 @@
|
||||
|
||||
"collide-probe": [
|
||||
["L100", "vector"],
|
||||
["L102", "vector"]
|
||||
["L102", "vu-function"]
|
||||
],
|
||||
|
||||
"collide-cache": [
|
||||
|
||||
@@ -342,8 +342,8 @@
|
||||
[333, "(function task-control symbol :behavior process-taskable)"],
|
||||
[334, "(function task-control symbol :behavior process-taskable)"],
|
||||
[335, "(function task-control symbol :behavior process-taskable)"],
|
||||
[336, "(function task-control task-control symbol)"],
|
||||
[337, "(function task-control task-control symbol)"],
|
||||
[336, "(function task-control symbol :behavior process-taskable)"],
|
||||
[337, "(function task-control symbol :behavior process-taskable)"],
|
||||
[338, "(function task-control symbol :behavior process-taskable)"],
|
||||
[339, "(function task-control symbol :behavior process-taskable)"],
|
||||
[340, "(function task-control symbol :behavior process-taskable)"],
|
||||
@@ -368,10 +368,10 @@
|
||||
[359, "(function task-control symbol :behavior process-taskable)"],
|
||||
[360, "(function task-control symbol :behavior process-taskable)"],
|
||||
[361, "(function task-control symbol :behavior process-taskable)"],
|
||||
[362, "(function task-control task-control symbol)"],
|
||||
[363, "(function task-control task-control symbol)"],
|
||||
[364, "(function task-control task-control symbol)"],
|
||||
[365, "(function task-control task-control symbol)"],
|
||||
[362, "(function task-control symbol :behavior process-taskable)"],
|
||||
[363, "(function task-control symbol :behavior process-taskable)"],
|
||||
[364, "(function task-control symbol :behavior process-taskable)"],
|
||||
[365, "(function task-control symbol :behavior process-taskable)"],
|
||||
[366, "(function task-control symbol :behavior process-taskable)"],
|
||||
[367, "(function task-control symbol :behavior process-taskable)"],
|
||||
[368, "(function task-control symbol :behavior process-taskable)"],
|
||||
@@ -420,8 +420,8 @@
|
||||
[411, "(function task-control symbol :behavior process-taskable)"],
|
||||
[412, "(function task-control symbol :behavior process-taskable)"],
|
||||
[413, "(function task-control symbol :behavior process-taskable)"],
|
||||
[414, "(function task-control task-control symbol)"],
|
||||
[415, "(function task-control task-control symbol)"],
|
||||
[414, "(function task-control symbol :behavior process-taskable)"],
|
||||
[415, "(function task-control symbol :behavior process-taskable)"],
|
||||
[416, "(function task-control symbol :behavior process-taskable)"],
|
||||
[417, "(function task-control symbol :behavior process-taskable)"],
|
||||
[418, "(function task-control symbol :behavior process-taskable)"],
|
||||
@@ -431,40 +431,40 @@
|
||||
[422, "(function task-control symbol :behavior process-taskable)"],
|
||||
[423, "(function task-control symbol :behavior process-taskable)"],
|
||||
[424, "(function task-control symbol :behavior process-taskable)"],
|
||||
[425, "(function task-control task-control symbol)"],
|
||||
[426, "(function task-control task-control symbol)"],
|
||||
[425, "(function task-control symbol :behavior process-taskable)"],
|
||||
[426, "(function task-control symbol :behavior process-taskable)"],
|
||||
[427, "(function task-control symbol :behavior process-taskable)"],
|
||||
[428, "(function task-control symbol :behavior process-taskable)"],
|
||||
[429, "(function task-control symbol :behavior process-taskable)"],
|
||||
[430, "(function task-control symbol :behavior process-taskable)"],
|
||||
[431, "(function task-control symbol :behavior process-taskable)"],
|
||||
[432, "(function task-control task-control symbol)"],
|
||||
[433, "(function task-control task-control symbol)"],
|
||||
[434, "(function task-control task-control symbol)"],
|
||||
[432, "(function task-control symbol :behavior process-taskable)"],
|
||||
[433, "(function task-control symbol :behavior process-taskable)"],
|
||||
[434, "(function task-control symbol :behavior process-taskable)"],
|
||||
[435, "(function task-control symbol :behavior process-taskable)"],
|
||||
[436, "(function task-control task-control symbol)"],
|
||||
[437, "(function task-control task-control symbol)"],
|
||||
[438, "(function task-control task-control symbol)"],
|
||||
[436, "(function task-control symbol :behavior process-taskable)"],
|
||||
[437, "(function task-control symbol :behavior process-taskable)"],
|
||||
[438, "(function task-control symbol :behavior process-taskable)"],
|
||||
[439, "(function task-control symbol :behavior process-taskable)"],
|
||||
[440, "(function task-control symbol :behavior process-taskable)"],
|
||||
[441, "(function task-control symbol :behavior process-taskable)"],
|
||||
[442, "(function task-control symbol :behavior process-taskable)"],
|
||||
[443, "(function task-control task-control symbol)"],
|
||||
[444, "(function task-control task-control symbol)"],
|
||||
[443, "(function task-control symbol :behavior process-taskable)"],
|
||||
[444, "(function task-control symbol :behavior process-taskable)"],
|
||||
[445, "(function task-control symbol :behavior process-taskable)"],
|
||||
[446, "(function task-control task-control symbol)"],
|
||||
[447, "(function task-control task-control symbol)"],
|
||||
[448, "(function task-control task-control symbol)"],
|
||||
[446, "(function task-control symbol :behavior process-taskable)"],
|
||||
[447, "(function task-control symbol :behavior process-taskable)"],
|
||||
[448, "(function task-control symbol :behavior process-taskable)"],
|
||||
[449, "(function task-control symbol :behavior process-taskable)"],
|
||||
[450, "(function task-control symbol :behavior process-taskable)"],
|
||||
[451, "(function task-control symbol :behavior process-taskable)"],
|
||||
[452, "(function task-control symbol :behavior process-taskable)"],
|
||||
[453, "(function task-control task-control symbol)"],
|
||||
[454, "(function task-control task-control symbol)"],
|
||||
[453, "(function task-control symbol :behavior process-taskable)"],
|
||||
[454, "(function task-control symbol :behavior process-taskable)"],
|
||||
[455, "(function task-control symbol :behavior process-taskable)"],
|
||||
[456, "(function task-control task-control symbol)"],
|
||||
[457, "(function task-control task-control symbol)"],
|
||||
[458, "(function task-control task-control symbol)"],
|
||||
[456, "(function task-control symbol :behavior process-taskable)"],
|
||||
[457, "(function task-control symbol :behavior process-taskable)"],
|
||||
[458, "(function task-control symbol :behavior process-taskable)"],
|
||||
[459, "(function task-control symbol :behavior process-taskable)"],
|
||||
[460, "(function task-control symbol :behavior process-taskable)"],
|
||||
[461, "(function task-control symbol :behavior process-taskable)"],
|
||||
@@ -480,10 +480,10 @@
|
||||
[471, "(function task-control symbol :behavior process-taskable)"],
|
||||
[472, "(function task-control symbol :behavior process-taskable)"],
|
||||
[473, "(function task-control symbol :behavior process-taskable)"],
|
||||
[474, "(function task-control task-control symbol)"],
|
||||
[475, "(function task-control task-control symbol)"],
|
||||
[476, "(function task-control task-control symbol)"],
|
||||
[477, "(function task-control task-control symbol)"],
|
||||
[474, "(function task-control symbol :behavior process-taskable)"],
|
||||
[475, "(function task-control symbol :behavior process-taskable)"],
|
||||
[476, "(function task-control symbol :behavior process-taskable)"],
|
||||
[477, "(function task-control symbol :behavior process-taskable)"],
|
||||
[478, "(function task-control symbol :behavior process-taskable)"],
|
||||
[479, "(function task-control symbol :behavior process-taskable)"],
|
||||
[480, "(function task-control symbol :behavior process-taskable)"],
|
||||
@@ -694,7 +694,7 @@
|
||||
]
|
||||
],
|
||||
|
||||
"projectiles": [[27, "(function projectile int)"]],
|
||||
"projectiles": [[27, "(function process int)"]],
|
||||
|
||||
"sidekick-human": [
|
||||
[7, "(function sparticle-launch-control :behavior sequenceC)"],
|
||||
|
||||
@@ -230,16 +230,11 @@
|
||||
|
||||
"(method 12 collide-mesh)",
|
||||
|
||||
// process-drawable BUG
|
||||
"cspace-inspect-tree",
|
||||
//"(method 19 process-drawable)",
|
||||
|
||||
// ambient
|
||||
"ambient-inspect",
|
||||
|
||||
// target2 BUG
|
||||
"look-for-points-of-interest", // Failed to split nested sc - looks like dead code to me
|
||||
|
||||
// collide-cache
|
||||
"(method 10 collide-puss-work)", // CFG
|
||||
"(method 9 collide-puss-work)", // decompiler crash
|
||||
|
||||
@@ -1959,7 +1959,7 @@
|
||||
|
||||
"collide-probe": [
|
||||
["L100", "vector"],
|
||||
["L102", "vector"]
|
||||
["L102", "vu-function"]
|
||||
],
|
||||
|
||||
"collide-cache": [
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
"screen-gradient": [[16, "draw-context"]],
|
||||
"(method 10 oscillating-vector)": [[16, "vector"]],
|
||||
"show-mc-info": [[16, "mc-slot-info"]],
|
||||
"update-mood-erase-color2": [[16, "mood-fog"]],
|
||||
"update-mood-erase-color2": [[16, "vector"]],
|
||||
"make-light-kit": [[16, "matrix"]],
|
||||
"matrix<-parented-transformq!": [[16, "vector"]],
|
||||
"(method 20 trsqv)": [[16, "vector"]],
|
||||
@@ -333,7 +333,7 @@
|
||||
|
||||
"(method 18 tracking-spline)": [
|
||||
[16, "tracking-spline-sampler"],
|
||||
[32, "tracking-spline-sampler"]
|
||||
[32, "vector"]
|
||||
],
|
||||
|
||||
"draw-ocean-transition": [[16, "sphere"]],
|
||||
@@ -1545,7 +1545,7 @@
|
||||
],
|
||||
|
||||
"cam-string-line-of-sight": [
|
||||
[16, "clip-travel-vector-to-mesh-return-info"],
|
||||
[16, "collide-los-result"],
|
||||
[176, "vector"],
|
||||
[192, "vector"],
|
||||
[208, "vector"],
|
||||
@@ -3322,7 +3322,7 @@
|
||||
|
||||
"(trans launcher-active)": [[16, "event-message-block"]],
|
||||
|
||||
"(code touch-tracker-idle)": [[16, "touching-shapes-entry"]],
|
||||
"(code touch-tracker-idle)": [[16, "overlaps-others-params"]],
|
||||
|
||||
"(event manipy-idle)": [[16, "matrix"]],
|
||||
|
||||
@@ -3702,7 +3702,9 @@
|
||||
|
||||
"(method 44 collide-shape)": [[16, "pull-rider-info"]],
|
||||
|
||||
"(method 12 collide-mesh)": [[16, "matrix"]],
|
||||
"(method 12 collide-mesh)": [[16, "sopt-work"]],
|
||||
|
||||
"(method 11 collide-mesh)": [[16, "spat-work"]],
|
||||
|
||||
"target-attack-up": [
|
||||
[16, "vector"],
|
||||
@@ -3919,7 +3921,7 @@
|
||||
[48, "vector"]
|
||||
],
|
||||
|
||||
"(method 10 collide-mesh)": [[16, "matrix"]],
|
||||
"(method 10 collide-mesh)": [[16, "oot-work"]],
|
||||
|
||||
"(method 22 collide-shape-prim-mesh)": [[16, "collide-tri-result"]],
|
||||
|
||||
|
||||
@@ -1926,7 +1926,8 @@
|
||||
],
|
||||
"build-continue-menu": [
|
||||
[4, "v1", "symbol"],
|
||||
[[5, 15], "v1", "level-load-info"]
|
||||
[5, "v1", "level-load-info"],
|
||||
[[7, 15], "v1", "continue-point"]
|
||||
],
|
||||
"(method 26 basebutton)": [[31, "v1", "art-joint-anim"]],
|
||||
"debug-menu-item-var-make-float": [
|
||||
@@ -2006,8 +2007,11 @@
|
||||
],
|
||||
"(method 11 beach-rock)": [[77, "v1", "int"]],
|
||||
"(anon-function 27 projectiles)": [
|
||||
[16, "s5", "process-drawable"],
|
||||
[27, "s4", "collide-shape"],
|
||||
[36, "s4", "collide-shape"]
|
||||
[36, "s4", "collide-shape"],
|
||||
[53, "s5", "process-drawable"],
|
||||
[57, "s5", "process-drawable"]
|
||||
],
|
||||
"projectile-update-velocity-space-wars": [[60, "a0", "target"]],
|
||||
"projectile-init-by-other": [
|
||||
@@ -2021,6 +2025,7 @@
|
||||
],
|
||||
"(method 28 projectile-yellow)": [
|
||||
[26, "a0", "target"],
|
||||
[88, "a0", "collide-shape"],
|
||||
[118, "a1", "target"]
|
||||
],
|
||||
"(method 27 projectile-blue)": [
|
||||
@@ -4182,12 +4187,16 @@
|
||||
"(method 54 collide-shape)": [[[18, 33], "v1", "collide-shape-prim-group"]],
|
||||
"(method 45 collide-shape)": [
|
||||
[18, "v1", "connection"],
|
||||
[79, "v1", "int"],
|
||||
[[19, 146], "s3", "collide-shape-moving"],
|
||||
[146, "v1", "connection"],
|
||||
[207, "v1", "int"],
|
||||
[[147, 272], "s3", "collide-shape-moving"],
|
||||
[272, "v1", "connection"],
|
||||
[333, "v1", "int"],
|
||||
[[273, 398], "s3", "collide-shape-moving"],
|
||||
[398, "v1", "connection"],
|
||||
[459, "v1", "int"],
|
||||
[[399, 497], "s3", "collide-shape-moving"]
|
||||
],
|
||||
"(method 55 collide-shape)": [
|
||||
@@ -4497,8 +4506,8 @@
|
||||
[16, "gp", "process-drawable"]
|
||||
],
|
||||
"next-level": [
|
||||
[7, "a1", "level-load-info"],
|
||||
[10, "a1", "level-load-info"]
|
||||
[6, "a1", "symbol"],
|
||||
[[7, 14], "a1", "level-load-info"]
|
||||
],
|
||||
"target-generic-event-handler": [
|
||||
[10, "v1", "float"],
|
||||
@@ -5218,9 +5227,7 @@
|
||||
],
|
||||
"(method 23 joint-exploder)": [
|
||||
[[12, 102], "s3", "joint-exploder-joint"],
|
||||
[[144, 146], "v1", "joint-exploder-list"],
|
||||
[148, "v1", "matrix"],
|
||||
[152, "v1", "matrix"]
|
||||
[[144, 146], "v1", "joint-exploder-list"]
|
||||
],
|
||||
"(method 20 joint-exploder)": [
|
||||
[[8, 10], "a3", "joint-exploder-joint"],
|
||||
@@ -5619,17 +5626,17 @@
|
||||
[[319, 324], "v1", "dma-packet"],
|
||||
[[356, 362], "a0", "dma-packet"],
|
||||
[[365, 371], "a0", "gs-gif-tag"],
|
||||
[376, "a0", "(pointer gs-reg64)"],
|
||||
[376, "a0", "(pointer gs-alpha)"],
|
||||
[378, "a0", "(pointer gs-reg64)"],
|
||||
[[382, 387], "v1", "dma-packet"],
|
||||
[[415, 421], "a0", "dma-packet"],
|
||||
[[424, 430], "a0", "gs-gif-tag"],
|
||||
[435, "a0", "(pointer gs-reg64)"],
|
||||
[435, "a0", "(pointer gs-alpha)"],
|
||||
[437, "a0", "(pointer gs-reg64)"],
|
||||
[[441, 446], "v1", "dma-packet"],
|
||||
[[474, 480], "a0", "dma-packet"],
|
||||
[[483, 489], "a0", "gs-gif-tag"],
|
||||
[494, "a0", "(pointer gs-reg64)"],
|
||||
[494, "a0", "(pointer gs-alpha)"],
|
||||
[496, "a0", "(pointer gs-reg64)"],
|
||||
[[500, 505], "v1", "dma-packet"]
|
||||
],
|
||||
@@ -6159,11 +6166,19 @@
|
||||
[124, "v1", "terrain-context"]
|
||||
],
|
||||
"target-collision-reaction": [
|
||||
["_stack_", 96, "cshape-moving-flags"],
|
||||
["_stack_", 96, "collide-status"],
|
||||
["_stack_", 104, "cshape-reaction-flags"]
|
||||
],
|
||||
"cspace-inspect-tree": [
|
||||
[[27, 105], "s2", "cspace"],
|
||||
[[106, 138], "s2", "pair"]
|
||||
],
|
||||
"target-collision-low-coverage": [
|
||||
["_stack_", 32, "cshape-reaction-flags"],
|
||||
["_stack_", 40, "cshape-moving-flags"]
|
||||
["_stack_", 40, "collide-status"]
|
||||
],
|
||||
"poly-find-nearest-edge": [
|
||||
[72, "v1", "vector"],
|
||||
[81, "v1", "vector"]
|
||||
]
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user