mirror of
https://github.com/open-goal/jak-project
synced 2026-07-07 22:22:21 -04:00
[decompiler] jak2-style rtype-of, setup gcommon stuff (#1616)
* [decompiler] support jak2-style rtype-of, get gcommon decompiling to use for tests * more decompiler debugging
This commit is contained in:
@@ -164,7 +164,7 @@ std::optional<TypeSpec> get_typecast_for_atom(const SimpleAtom& atom,
|
||||
const Env& env,
|
||||
const TypeSpec& expected_type,
|
||||
int my_idx) {
|
||||
auto type_info = env.dts->ts.lookup_type(expected_type);
|
||||
auto type_info = env.dts->ts.lookup_type_allow_partial_def(expected_type);
|
||||
switch (atom.get_kind()) {
|
||||
case SimpleAtom::Kind::VARIABLE: {
|
||||
if (atom.var().reg().get_kind() == Reg::VF) {
|
||||
|
||||
@@ -1552,8 +1552,7 @@ void AshElement::get_modified_regs(RegSet&) const {}
|
||||
// TypeOfElement
|
||||
/////////////////////////////
|
||||
|
||||
TypeOfElement::TypeOfElement(Form* _value, std::optional<RegisterAccess> _clobber)
|
||||
: value(_value), clobber(_clobber) {
|
||||
TypeOfElement::TypeOfElement(Form* _value) : value(_value) {
|
||||
value->parent_element = this;
|
||||
}
|
||||
|
||||
|
||||
@@ -951,8 +951,7 @@ class AshElement : public FormElement {
|
||||
class TypeOfElement : public FormElement {
|
||||
public:
|
||||
Form* value;
|
||||
std::optional<RegisterAccess> clobber;
|
||||
TypeOfElement(Form* _value, std::optional<RegisterAccess> _clobber);
|
||||
TypeOfElement(Form* _value);
|
||||
goos::Object to_form_internal(const Env& env) const override;
|
||||
void apply(const std::function<void(FormElement*)>& f) override;
|
||||
void apply_form(const std::function<void(Form*)>& f) override;
|
||||
|
||||
@@ -183,7 +183,7 @@ Form* try_cast_simplify(Form* in,
|
||||
}
|
||||
}
|
||||
|
||||
auto type_info = env.dts->ts.lookup_type(new_type);
|
||||
auto type_info = env.dts->ts.lookup_type_allow_partial_def(new_type);
|
||||
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
|
||||
if (bitfield_info) {
|
||||
// todo remove this.
|
||||
|
||||
@@ -1162,6 +1162,15 @@ bool is_set_symbol_value(SetVarOp& op, const std::string& name) {
|
||||
op.src().get_arg(0).get_str() == name;
|
||||
}
|
||||
|
||||
bool is_set_symbol_value(SetVarElement* op, const std::string& name) {
|
||||
auto src = op->src()->try_as_element<SimpleExpressionElement>();
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
return src->expr().is_identity() && src->expr().get_arg(0).is_sym_val() &&
|
||||
src->expr().get_arg(0).get_str() == name;
|
||||
}
|
||||
|
||||
SetVarOp get_delay_op(const Function& f, const BlockVtx* vtx) {
|
||||
auto delay_start = f.ir2.atomic_ops->block_id_to_first_atomic_op.at(vtx->block_id);
|
||||
auto delay_end = f.ir2.atomic_ops->block_id_to_end_atomic_op.at(vtx->block_id);
|
||||
@@ -1170,14 +1179,290 @@ SetVarOp get_delay_op(const Function& f, const BlockVtx* vtx) {
|
||||
}
|
||||
auto& delay_op = f.ir2.atomic_ops->ops.at(delay_start);
|
||||
auto* delay = dynamic_cast<SetVarOp*>(delay_op.get());
|
||||
if (!delay) {
|
||||
fmt::print("bad delay: {}\n", delay_op->to_string(f.ir2.env));
|
||||
ASSERT(false);
|
||||
}
|
||||
return *delay;
|
||||
}
|
||||
|
||||
LoadVarOp get_delay_load_op(const Function& f, const BlockVtx* vtx) {
|
||||
auto delay_start = f.ir2.atomic_ops->block_id_to_first_atomic_op.at(vtx->block_id);
|
||||
auto delay_end = f.ir2.atomic_ops->block_id_to_end_atomic_op.at(vtx->block_id);
|
||||
if (delay_end - delay_start != 1) {
|
||||
ASSERT(false);
|
||||
}
|
||||
auto& delay_op = f.ir2.atomic_ops->ops.at(delay_start);
|
||||
auto* delay = dynamic_cast<LoadVarOp*>(delay_op.get());
|
||||
if (!delay) {
|
||||
fmt::print("bad delay: {}\n", delay_op->to_string(f.ir2.env));
|
||||
ASSERT(false);
|
||||
}
|
||||
return *delay;
|
||||
}
|
||||
|
||||
Form* try_sc_as_type_of_jak2(FormPool& pool, Function& f, const ShortCircuit* vtx) {
|
||||
/*
|
||||
dsll32 a2, a0, 29 * temp_reg0, src
|
||||
dsrl32 a2, a2, 29 * temp_reg0, temp_reg0
|
||||
beql a2, r0, L289 branch0
|
||||
B1:
|
||||
lw a0, binteger(s7)
|
||||
|
||||
B2:
|
||||
addiu a3, r0, 4
|
||||
beql a2, a3, L289 branch1
|
||||
B3:
|
||||
lwu a0, -4(a0)
|
||||
|
||||
B4:
|
||||
addiu a0, r0, 2
|
||||
beql a2, a0, L289 branch2
|
||||
B5:
|
||||
lw a0, pair(s7)
|
||||
|
||||
B6:
|
||||
lw a0, symbol(s7)
|
||||
B7:
|
||||
L289:
|
||||
*/
|
||||
|
||||
if (vtx->entries.size() != 4) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto b0_c = dynamic_cast<CfgVtx*>(vtx->entries.at(0).condition);
|
||||
auto b0_d = dynamic_cast<BlockVtx*>(vtx->entries.at(0).likely_delay);
|
||||
auto b1_c = dynamic_cast<BlockVtx*>(vtx->entries.at(1).condition);
|
||||
auto b1_d = dynamic_cast<BlockVtx*>(vtx->entries.at(1).likely_delay);
|
||||
auto b2_c = dynamic_cast<BlockVtx*>(vtx->entries.at(2).condition);
|
||||
auto b2_d = dynamic_cast<BlockVtx*>(vtx->entries.at(2).likely_delay);
|
||||
auto b3_c = dynamic_cast<BlockVtx*>(vtx->entries.at(3).condition);
|
||||
|
||||
if (!b0_c || !b0_d || !b1_c || !b1_d || !b2_c || !b2_d || !b3_c ||
|
||||
vtx->entries.at(3).likely_delay) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// get the branch ir's
|
||||
auto b0_ptr = cfg_to_ir(pool, f, b0_c); // should be begin.
|
||||
if (b0_ptr->size() <= 2) {
|
||||
fmt::print("fail1\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto b1_ptr = cfg_to_ir(pool, f, b1_c);
|
||||
if (b1_ptr->size() <= 1) {
|
||||
fmt::print("fail2\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto b2_ptr = cfg_to_ir(pool, f, b2_c);
|
||||
if (b2_ptr->size() <= 1) {
|
||||
fmt::print("fail3\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto b3_ptr = cfg_to_ir(pool, f, b3_c);
|
||||
auto b3_ir = dynamic_cast<SetVarElement*>(b3_ptr->try_as_single_element());
|
||||
if (!b3_ir) {
|
||||
fmt::print("fail4\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// identify the left shift
|
||||
auto set_shift_left = dynamic_cast<SetVarElement*>(b0_ptr->at(b0_ptr->size() - 3));
|
||||
if (!set_shift_left) {
|
||||
fmt::print("fail5\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto temp_reg0 = set_shift_left->dst();
|
||||
auto shift_left =
|
||||
dynamic_cast<SimpleExpressionElement*>(set_shift_left->src()->try_as_single_element());
|
||||
if (!shift_left || shift_left->expr().kind() != SimpleExpression::Kind::LEFT_SHIFT) {
|
||||
fmt::print("fail6\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto src_reg = shift_left->expr().get_arg(0).var();
|
||||
auto sa_left = shift_left->expr().get_arg(1);
|
||||
if (!sa_left.is_int() || sa_left.get_int() != 61) {
|
||||
fmt::print("fail7\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// identify the right shift
|
||||
auto set_shift_right = dynamic_cast<SetVarElement*>(b0_ptr->at(b0_ptr->size() - 2));
|
||||
if (!set_shift_right) {
|
||||
fmt::print("fail8\n");
|
||||
return nullptr;
|
||||
}
|
||||
if (set_shift_right->dst().reg() != set_shift_left->dst().reg()) {
|
||||
fmt::print("fail9\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto shift_right =
|
||||
dynamic_cast<SimpleExpressionElement*>(set_shift_right->src()->try_as_single_element());
|
||||
if (!shift_right || shift_right->expr().kind() != SimpleExpression::Kind::RIGHT_SHIFT_LOGIC) {
|
||||
fmt::print("fail10\n");
|
||||
return nullptr;
|
||||
}
|
||||
if (temp_reg0.reg() != shift_right->expr().get_arg(0).var().reg()) {
|
||||
fmt::print("fail11\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto sa_right = shift_right->expr().get_arg(1);
|
||||
if (!sa_right.is_int() || sa_right.get_int() != 61) {
|
||||
fmt::print("fail12\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// branch 0
|
||||
auto first_branch = dynamic_cast<BranchElement*>(b0_ptr->back());
|
||||
auto b0_delay_op = get_delay_op(f, b0_d);
|
||||
if (!first_branch || !is_set_symbol_value(b0_delay_op, "binteger") ||
|
||||
first_branch->op()->condition().kind() != IR2_Condition::Kind::ZERO ||
|
||||
!first_branch->op()->likely()) {
|
||||
fmt::print("fail13\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto temp_reg = first_branch->op()->condition().src(0).var();
|
||||
ASSERT(temp_reg.reg() == temp_reg0.reg());
|
||||
auto dst_reg = b0_delay_op.dst();
|
||||
|
||||
// branch 1
|
||||
if (b1_ptr->size() != 2) {
|
||||
fmt::print("fail14\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto second_branch_pre_op = dynamic_cast<SetVarElement*>(b1_ptr->at(0));
|
||||
if (!second_branch_pre_op) {
|
||||
fmt::print("fail15\n");
|
||||
return nullptr;
|
||||
}
|
||||
{
|
||||
auto pos = second_branch_pre_op->src();
|
||||
auto pos_as_se = pos->try_as_element<SimpleExpressionElement>();
|
||||
if (!pos_as_se || !pos_as_se->expr().is_identity() || !pos_as_se->expr().get_arg(0).is_int(4)) {
|
||||
fmt::print("fail16\n");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
auto temp_reg1 = second_branch_pre_op->dst();
|
||||
auto second_branch = dynamic_cast<BranchElement*>(b1_ptr->at(1));
|
||||
/*
|
||||
beql a2, a3, L289 branch1
|
||||
B3:
|
||||
lwu a0, -4(a0)
|
||||
*/
|
||||
if (!second_branch || second_branch->op()->condition().kind() != IR2_Condition::Kind::EQUAL ||
|
||||
!second_branch->op()->likely() || !second_branch->op()->condition().src(0).is_var() ||
|
||||
second_branch->op()->condition().src(0).var().reg() != temp_reg0.reg() ||
|
||||
!second_branch->op()->condition().src(1).is_var() ||
|
||||
second_branch->op()->condition().src(1).var().reg() != temp_reg1.reg()) {
|
||||
fmt::print("fail17\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!b1_d) {
|
||||
fmt::print("fail18\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto b1_delay_op = get_delay_load_op(f, b1_d);
|
||||
if (b1_delay_op.kind() != LoadVarOp::Kind::UNSIGNED || b1_delay_op.size() != 4) {
|
||||
fmt::print("fail19\n");
|
||||
return nullptr;
|
||||
}
|
||||
IR2_RegOffset ro;
|
||||
if (!get_as_reg_offset(b1_delay_op.src(), &ro)) {
|
||||
fmt::print("fail20\n");
|
||||
return nullptr;
|
||||
}
|
||||
if (ro.offset != -4) {
|
||||
fmt::print("fail21\n");
|
||||
return nullptr;
|
||||
}
|
||||
if (ro.reg != src_reg.reg() || b1_delay_op.get_set_destination().reg() != dst_reg.reg()) {
|
||||
fmt::print("fail22\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
// branch2
|
||||
/*
|
||||
* B4:
|
||||
addiu a0, r0, 2
|
||||
beql a2, a0, L289 branch2
|
||||
B5:
|
||||
lw a0, pair(s7)
|
||||
*/
|
||||
if (b2_ptr->size() != 2) {
|
||||
fmt::print("fail23\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto third_branch_pre_op = dynamic_cast<SetVarElement*>(b2_ptr->at(0));
|
||||
if (!third_branch_pre_op) {
|
||||
fmt::print("fail24\n");
|
||||
return nullptr;
|
||||
}
|
||||
{
|
||||
auto pos = third_branch_pre_op->src();
|
||||
auto pos_as_se = pos->try_as_element<SimpleExpressionElement>();
|
||||
if (!pos_as_se || !pos_as_se->expr().is_identity() || !pos_as_se->expr().get_arg(0).is_int(2)) {
|
||||
fmt::print("fail25\n");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
auto temp_reg2 = third_branch_pre_op->dst();
|
||||
auto third_branch = dynamic_cast<BranchElement*>(b2_ptr->at(1));
|
||||
if (!third_branch || third_branch->op()->condition().kind() != IR2_Condition::Kind::EQUAL ||
|
||||
!third_branch->op()->likely() || !third_branch->op()->condition().src(0).is_var() ||
|
||||
third_branch->op()->condition().src(0).var().reg() != temp_reg0.reg() ||
|
||||
!third_branch->op()->condition().src(1).is_var() ||
|
||||
third_branch->op()->condition().src(1).var().reg() != temp_reg2.reg()) {
|
||||
fmt::print("fail26\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!b2_d) {
|
||||
fmt::print("fail27\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto b2_delay_op = get_delay_op(f, b2_d);
|
||||
if (!is_set_symbol_value(b2_delay_op, "pair") || b2_delay_op.dst().reg() != dst_reg.reg()) {
|
||||
fmt::print("fail28\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!is_set_symbol_value(b3_ir, "symbol")) {
|
||||
fmt::print("fail29\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// we passed, time to clean things up...
|
||||
|
||||
// remove the stuff from the back of block 0.
|
||||
b0_ptr->pop_back();
|
||||
b0_ptr->pop_back();
|
||||
b0_ptr->pop_back();
|
||||
|
||||
auto obj = pool.alloc_single_element_form<SimpleExpressionElement>(
|
||||
nullptr, shift_left->expr().get_arg(0).as_expr(), set_shift_right->dst().idx());
|
||||
auto type_op = pool.alloc_single_element_form<TypeOfElement>(nullptr, obj);
|
||||
auto op = pool.alloc_element<SetVarElement>(dst_reg, type_op, true, TypeSpec("type"));
|
||||
b0_ptr->push_back(op);
|
||||
// if (b1_delay_op.src().)
|
||||
|
||||
f.ir2.env.disable_def(b0_delay_op.dst(), f.warnings);
|
||||
f.ir2.env.disable_def(b1_delay_op.get_set_destination(), f.warnings);
|
||||
f.ir2.env.disable_def(b2_delay_op.dst(), f.warnings);
|
||||
f.ir2.env.disable_use(shift_left->expr().get_arg(0).var());
|
||||
|
||||
f.warnings.general_warning("Using new Jak 2 rtype-of");
|
||||
return b0_ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Try to convert a short circuiting expression into a "type-of" expression.
|
||||
* We do this before attempting the normal and/or expressions.
|
||||
*/
|
||||
Form* try_sc_as_type_of(FormPool& pool, Function& f, const ShortCircuit* vtx) {
|
||||
Form* try_sc_as_type_of_jak1(FormPool& pool, Function& f, const ShortCircuit* vtx) {
|
||||
// the assembly looks like this:
|
||||
/*
|
||||
dsll32 v1, a0, 29 ;; (set! v1 (shl a0 61))
|
||||
@@ -1285,11 +1570,6 @@ Form* try_sc_as_type_of(FormPool& pool, Function& f, const ShortCircuit* vtx) {
|
||||
ASSERT(src_reg3.var().reg() == src_reg.reg());
|
||||
ASSERT(offset.get_int() == -4);
|
||||
|
||||
std::optional<RegisterAccess> clobber;
|
||||
if (temp_reg.reg() != dst_reg.reg()) {
|
||||
clobber = first_branch->op()->condition().src(0).var();
|
||||
}
|
||||
|
||||
// remove the branch
|
||||
b0_ptr->pop_back();
|
||||
// remove the shift
|
||||
@@ -1298,7 +1578,7 @@ Form* try_sc_as_type_of(FormPool& pool, Function& f, const ShortCircuit* vtx) {
|
||||
// add the type-of
|
||||
auto obj = pool.alloc_single_element_form<SimpleExpressionElement>(
|
||||
nullptr, shift->expr().get_arg(0).as_expr(), set_shift->dst().idx());
|
||||
auto type_op = pool.alloc_single_element_form<TypeOfElement>(nullptr, obj, clobber);
|
||||
auto type_op = pool.alloc_single_element_form<TypeOfElement>(nullptr, obj);
|
||||
auto op = pool.alloc_element<SetVarElement>(else_case->dst(), type_op, true, TypeSpec("type"));
|
||||
b0_ptr->push_back(op);
|
||||
|
||||
@@ -1310,6 +1590,18 @@ Form* try_sc_as_type_of(FormPool& pool, Function& f, const ShortCircuit* vtx) {
|
||||
return b0_ptr;
|
||||
}
|
||||
|
||||
Form* try_sc_as_type_of(FormPool& pool, Function& f, const ShortCircuit* vtx, GameVersion version) {
|
||||
switch (version) {
|
||||
case GameVersion::Jak1:
|
||||
return try_sc_as_type_of_jak1(pool, f, vtx);
|
||||
case GameVersion::Jak2:
|
||||
return try_sc_as_type_of_jak2(pool, f, vtx);
|
||||
default:
|
||||
ASSERT(false);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Form* merge_cond_else_with_sc_cond(FormPool& pool,
|
||||
Function& f,
|
||||
const CondWithElse* cwe,
|
||||
@@ -1574,7 +1866,7 @@ Form* cfg_to_ir_helper(FormPool& pool, Function& f, const CfgVtx* vtx) {
|
||||
} else if (dynamic_cast<const ShortCircuit*>(vtx)) {
|
||||
auto* svtx = dynamic_cast<const ShortCircuit*>(vtx);
|
||||
// try as a type of expression first
|
||||
auto as_type_of = try_sc_as_type_of(pool, f, svtx);
|
||||
auto as_type_of = try_sc_as_type_of(pool, f, svtx, f.ir2.env.version);
|
||||
if (as_type_of) {
|
||||
return as_type_of;
|
||||
}
|
||||
|
||||
+496
-333
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,10 @@
|
||||
{
|
||||
|
||||
"gkernel": [
|
||||
[33, "(function process symbol)"],
|
||||
[31, "(function process symbol)"],
|
||||
[29, "(function process symbol)"],
|
||||
[26, "(function process symbol)"],
|
||||
[23, "(function process symbol)"],
|
||||
[17, "(function process symbol)"]
|
||||
]
|
||||
}
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
"asm_functions_by_name": [
|
||||
// checking boxed type is different now - these make the cfg stuff sad
|
||||
"type?", "print", "printl", "inspect", "valid?", "name=", "(method 8 res-lump)", "joint-control-remap!", "(method 21 game-info)", "(method 12 level)",
|
||||
"name=", "(method 8 res-lump)", "joint-control-remap!", "(method 21 game-info)", "(method 12 level)",
|
||||
"bg", "(anon-function 2 cam-combiner)", "cspace-inspect-tree", "command-get-process", "command-get-trans", "(method 10 script-context)",
|
||||
"(method 11 script-context)", "(method 9 script-context)", "(anon-function 64 script)", "(anon-function 61 script)", "(anon-function 60 script)",
|
||||
"(anon-function 54 script)", "(anon-function 52 script)", "(anon-function 49 script)", "(anon-function 33 script)", "debug-menu-func-decode",
|
||||
@@ -45,6 +45,10 @@
|
||||
"(method 24 nav-network)", "(method 11 predator-manager)", "(method 9 bot-speech-list)", "(method 9 bot-speech-list-shuffle)",
|
||||
"(anon-function 10 sig-recorder)", "(method 14 trail-graph)", "(method 12 trail-graph)", "(method 11 trail-graph)",
|
||||
// actual asm
|
||||
"quad-copy!", "return-from-thread", "return-from-thread-dead", "reset-and-call", "(method 10 cpu-thread)",
|
||||
"(method 11 cpu-thread)", "(method 0 catch-frame)", "throw-dispatch", "throw", "run-function-in-process",
|
||||
"set-to-run-bootstrap", "return-from-exception",
|
||||
|
||||
"symlink2", "blerc-a-fragment", "blerc-execute", "foreground-check-longest-edge-asm", "generic-light-proc",
|
||||
"shadow-add-single-edges","shadow-add-facing-single-tris", "shadow-add-double-tris", "shadow-add-double-edges",
|
||||
"(method 12 collide-mesh)", "(method 17 collide-edge-work)", "(method 42 collide-shape)", "(method 12 collide-shape-prim-sphere)",
|
||||
@@ -65,7 +69,21 @@
|
||||
// these functions use pairs and the decompiler
|
||||
// will be less picky about types related to pairs.
|
||||
"pair_functions_by_name": [
|
||||
|
||||
"ref",
|
||||
"(method 4 pair)",
|
||||
"last",
|
||||
"member",
|
||||
"nmember",
|
||||
"assoc",
|
||||
"assoce",
|
||||
"nassoc",
|
||||
"nassoce",
|
||||
"append!",
|
||||
"delete!",
|
||||
"delete-car!",
|
||||
"insert-cons!",
|
||||
"sort",
|
||||
"unload-package"
|
||||
],
|
||||
|
||||
// If format is used with the wrong number of arguments,
|
||||
|
||||
@@ -1,4 +1,69 @@
|
||||
{
|
||||
|
||||
"(method 2 array)": [
|
||||
[23, "gp", "(array int32)"],
|
||||
[43, "gp", "(array uint32)"],
|
||||
[63, "gp", "(array int64)"],
|
||||
[83, "gp", "(array uint64)"],
|
||||
[102, "gp", "(array int8)"],
|
||||
[121, "gp", "(array uint8)"],
|
||||
[141, "gp", "(array int16)"],
|
||||
[161, "gp", "(array uint16)"],
|
||||
[186, "gp", "(array uint128)"],
|
||||
[204, "gp", "(array int32)"],
|
||||
[223, "gp", "(array float)"],
|
||||
[232, "gp", "(array float)"],
|
||||
[249, "gp", "(array basic)"],
|
||||
[258, "gp", "(array basic)"]
|
||||
],
|
||||
"(method 3 array)": [
|
||||
[51, "gp", "(array int32)"],
|
||||
[69, "gp", "(array uint32)"],
|
||||
[87, "gp", "(array int64)"],
|
||||
[105, "gp", "(array uint64)"],
|
||||
[122, "gp", "(array int8)"],
|
||||
[139, "gp", "(array int8)"],
|
||||
[157, "gp", "(array int16)"],
|
||||
[175, "gp", "(array uint16)"],
|
||||
[198, "gp", "(array uint128)"],
|
||||
[214, "gp", "(array int32)"],
|
||||
[233, "gp", "(array float)"],
|
||||
[250, "gp", "(array basic)"]
|
||||
],
|
||||
"(method 0 cpu-thread)": [[[0, 28], "v0", "cpu-thread"]],
|
||||
"(method 0 process)": [
|
||||
[11, "a0", "int"],
|
||||
[[12, 45], "v0", "process"]
|
||||
],
|
||||
"inspect-process-heap": [
|
||||
[[4, 11], "s5", "basic"],
|
||||
[17, "s5", "pointer"]
|
||||
],
|
||||
"(method 14 dead-pool)": [
|
||||
[[24, 25], "v1", "(pointer process)"],
|
||||
[[30, 39], "s4", "(pointer process)"]
|
||||
],
|
||||
"(method 24 dead-pool-heap)": [
|
||||
[5, "v1", "pointer"],
|
||||
[13, "a0", "pointer"],
|
||||
[25, "v1", "pointer"]
|
||||
],
|
||||
"method-state": [
|
||||
[12, "a2", "state"]
|
||||
],
|
||||
"(method 9 process)": [[[46,49], "s5", "process"]],
|
||||
"(method 10 process)": [[[24, 30], "s4", "protect-frame"]],
|
||||
"(method 0 protect-frame)": [
|
||||
[0, "a0", "int"],
|
||||
[[1, 8], "v0", "protect-frame"]
|
||||
],
|
||||
"string-cat-to-last-char": [
|
||||
[3, "s5", "(pointer uint8)"],
|
||||
[4, "s5", "string"]
|
||||
],
|
||||
"enter-state": [
|
||||
[68, "s0", "protect-frame"],
|
||||
[101, "t9", "(function object object object object object object none)"]
|
||||
],
|
||||
"send-event-function": [[[7, 15], "a0", "process"]],
|
||||
"placeholder-do-not-add-below": []
|
||||
}
|
||||
|
||||
+4
-4
@@ -114,7 +114,7 @@
|
||||
:size-assert #x1f0
|
||||
:flag-assert #x11018001f0
|
||||
(:methods
|
||||
(create-the-flock! (_type_ vector) (pointer process) 14)
|
||||
(spawn-bird (_type_ vector) (pointer process) 14)
|
||||
(play-hint (_type_ int) none 15)
|
||||
(dummy-16 (_type_ seagull) float 16)
|
||||
)
|
||||
@@ -1435,7 +1435,7 @@
|
||||
(dotimes (v1-16 64)
|
||||
(set! (-> obj bird v1-16) (the-as (pointer seagull) #f))
|
||||
)
|
||||
(create-the-flock! obj (-> obj trans))
|
||||
(spawn-bird obj (-> obj trans))
|
||||
(dotimes (s5-1 20)
|
||||
(let ((s4-0 (new 'stack-no-clear 'vector)))
|
||||
(let* ((f30-0 (-> obj trans x))
|
||||
@@ -1456,7 +1456,7 @@
|
||||
)
|
||||
(set! (-> s4-0 y) (-> obj trans y))
|
||||
(set! (-> s4-0 w) 1.0)
|
||||
(create-the-flock! obj s4-0)
|
||||
(spawn-bird obj s4-0)
|
||||
)
|
||||
)
|
||||
(set! (-> obj squall) (new 'process 'ambient-sound sound-seagull-squall (-> obj trans)))
|
||||
@@ -1467,7 +1467,7 @@
|
||||
)
|
||||
|
||||
;; definition for method 14 of type seagullflock
|
||||
(defmethod create-the-flock! seagullflock ((obj seagullflock) (arg0 vector))
|
||||
(defmethod spawn-bird seagullflock ((obj seagullflock) (arg0 vector))
|
||||
(if (= (-> obj birds) 64)
|
||||
(return (the-as (pointer process) #f))
|
||||
)
|
||||
|
||||
+6
-8
@@ -253,25 +253,23 @@
|
||||
)
|
||||
|
||||
;; definition for function robotboss-yellow-eco-off
|
||||
;; INFO: Return type mismatch entity-perm-status vs none.
|
||||
(defbehavior robotboss-yellow-eco-off robotboss ()
|
||||
(logior! (-> self alts 7 extra perm status) (entity-perm-status bit-9))
|
||||
(logior! (-> self alts 8 extra perm status) (entity-perm-status bit-9))
|
||||
(logior! (-> self alts 9 extra perm status) (entity-perm-status bit-9))
|
||||
(let ((v0-0 (logior (-> self alts 10 extra perm status) (entity-perm-status bit-9))))
|
||||
(set! (-> self alts 10 extra perm status) v0-0)
|
||||
v0-0
|
||||
)
|
||||
(logior! (-> self alts 10 extra perm status) (entity-perm-status bit-9))
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function robotboss-yellow-eco-on
|
||||
;; INFO: Return type mismatch entity-perm-status vs none.
|
||||
(defbehavior robotboss-yellow-eco-on robotboss ()
|
||||
(logclear! (-> self alts 7 extra perm status) (entity-perm-status bit-9))
|
||||
(logclear! (-> self alts 8 extra perm status) (entity-perm-status bit-9))
|
||||
(logclear! (-> self alts 9 extra perm status) (entity-perm-status bit-9))
|
||||
(let ((v0-0 (logclear (-> self alts 10 extra perm status) (entity-perm-status bit-9))))
|
||||
(set! (-> self alts 10 extra perm status) v0-0)
|
||||
v0-0
|
||||
)
|
||||
(logclear! (-> self alts 10 extra perm status) (entity-perm-status bit-9))
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function robotboss-anim-blend-loop
|
||||
|
||||
Reference in New Issue
Block a user