[decomp] get started on game info (#674)

* temp

* menu text

* wip

* recognize handle to process

* more
This commit is contained in:
water111
2021-07-03 16:18:41 -04:00
committed by GitHub
parent bc41241234
commit 784cd5debb
63 changed files with 9250 additions and 2542 deletions
+5
View File
@@ -7,6 +7,7 @@
#include "decompiler/ObjectFile/LinkedObjectFile.h"
#include "AtomicOp.h"
#include "OpenGoalMapping.h"
#include "Form.h"
namespace decompiler {
/////////////////////////////
@@ -297,6 +298,8 @@ std::string get_simple_expression_op_name(SimpleExpression::Kind kind) {
return "vector-!2";
case SimpleExpression::Kind::VECTOR_FLOAT_PRODUCT:
return "vector-float*!2";
case SimpleExpression::Kind::SUBU_L32_S7:
return "subu-s7";
default:
assert(false);
return {};
@@ -352,6 +355,8 @@ int get_simple_expression_arg_count(SimpleExpression::Kind kind) {
case SimpleExpression::Kind::VECTOR_MINUS:
case SimpleExpression::Kind::VECTOR_FLOAT_PRODUCT:
return 3;
case SimpleExpression::Kind::SUBU_L32_S7:
return 1;
default:
assert(false);
return -1;
+2 -1
View File
@@ -225,7 +225,8 @@ class SimpleExpression {
PCPYLD,
VECTOR_PLUS,
VECTOR_MINUS,
VECTOR_FLOAT_PRODUCT
VECTOR_FLOAT_PRODUCT,
SUBU_L32_S7, // use SUBU X, src0, s7 to check if lower 32-bits are s7.
};
// how many arguments?
+13 -1
View File
@@ -200,6 +200,8 @@ TP_Type SimpleExpression::get_type(const TypeState& input,
return TP_Type::make_from_ts("vector");
case Kind::VECTOR_FLOAT_PRODUCT:
return TP_Type::make_from_ts("vector");
case Kind::SUBU_L32_S7:
return TP_Type::make_from_ts("int");
default:
throw std::runtime_error("Simple expression cannot get_type: " +
to_form(env.file->labels, env).print());
@@ -672,7 +674,6 @@ TypeState AsmOp::propagate_types_internal(const TypeState& input,
// pextuw t0, r0, gp
if (m_instr.kind == InstructionKind::PEXTUW) {
if (m_src[0] && m_src[0]->reg() == Register(Reg::GPR, Reg::R0)) {
// sponge
assert(m_src[1]);
auto type = dts.ts.lookup_type(result.get(m_src[1]->reg()).typespec());
auto as_bitfield = dynamic_cast<BitFieldType*>(type);
@@ -685,6 +686,17 @@ TypeState AsmOp::propagate_types_internal(const TypeState& input,
}
}
// sllv out, in, r0
if (m_instr.kind == InstructionKind::SLLV && m_src[1]->reg() == Register(Reg::GPR, Reg::R0)) {
auto type = dts.ts.lookup_type(result.get(m_src[0]->reg()).typespec());
auto as_bitfield = dynamic_cast<BitFieldType*>(type);
if (as_bitfield) {
auto field = find_field(dts.ts, as_bitfield, 0, 32, {});
result.get(m_dst->reg()) = TP_Type::make_from_ts(field.type());
return result;
}
}
if (m_dst.has_value()) {
auto kind = m_dst->reg().get_kind();
if (kind == Reg::FPR) {
+2
View File
@@ -1548,6 +1548,8 @@ std::string fixed_operator_to_string(FixedOperatorKind kind) {
return "vector+!";
case FixedOperatorKind::VECTOR_FLOAT_PRODUCT:
return "vector-float*!";
case FixedOperatorKind::L32_NOT_FALSE_CBOOL:
return "l32-false-check";
default:
assert(false);
return "";
+5
View File
@@ -154,6 +154,11 @@ class SimpleExpressionElement : public FormElement {
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects);
void update_from_stack_subu_l32_s7(const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects);
void update_from_stack_float_to_int(const Env& env,
FormPool& pool,
FormStack& stack,
+174 -37
View File
@@ -128,6 +128,39 @@ bool is_power_of_two(int in, int* out) {
return false;
}
/*!
* Imagine:
* x = foo
* { // some macro/inlined thing
* read from x
* return x;
* }
*
* and you want to transform it to
* x = some_macro(foo, blah, ...)
*
* this will get you foo (and pop it from the stack), assuming the stack is sitting right after the
* point where the inline thing evaluated foo.
*
* For later book-keeping of reg use, if it gets you something new, it will set found_orig_out,
* and also give you the regaccess for the x of the x = foo.
*
* If you use this, you are responsible for adding code that sets x again.
*/
Form* repop_passthrough_arg(Form* in,
FormStack& stack,
const Env& env,
RegisterAccess* orig_out,
bool* found_orig_out) {
*found_orig_out = false;
auto as_atom = form_as_atom(in);
if (as_atom && as_atom->is_var()) {
return stack.pop_reg(as_atom->var().reg(), {}, env, true, -1, orig_out, found_orig_out);
}
return in;
}
/*!
* Create a form which represents a variable.
*/
@@ -654,7 +687,7 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
input.stride = 1;
input.base_type = arg1_type.typespec();
auto out = env.dts->ts.reverse_field_lookup(input);
if (out.success) {
if (out.success && out.has_variable_token()) {
// it is. now we have to modify things
// first, look for the index
@@ -673,6 +706,7 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
tokens.push_back(to_token(tok));
}
}
assert(used_index);
result->push_back(pool.alloc_element<DerefElement>(args.at(1), out.addr_of, tokens));
return;
} else {
@@ -686,7 +720,7 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
input.stride = arg0_type.get_mult_int_constant();
input.base_type = arg1_type.typespec();
auto out = env.dts->ts.reverse_field_lookup(input);
if (out.success) {
if (out.success && out.has_variable_token()) {
// it is. now we have to modify things
// first, look for the index
int p2;
@@ -710,6 +744,7 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
tokens.push_back(to_token(tok));
}
}
assert(used_index);
result->push_back(pool.alloc_element<DerefElement>(args.at(1), out.addr_of, tokens));
return;
} else {
@@ -736,6 +771,7 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
tokens.push_back(to_token(tok));
}
}
assert(used_index);
result->push_back(pool.alloc_element<DerefElement>(args.at(1), out.addr_of, tokens));
return;
} else {
@@ -755,7 +791,7 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
rd_in.base_type = arg0_type.typespec();
auto rd = env.dts->ts.reverse_field_lookup(rd_in);
if (rd.success) {
if (rd.success && rd.has_variable_token()) {
auto arg1_matcher = Matcher::match_or(
{Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::MULTIPLICATION),
{Matcher::any(0), Matcher::integer(rd_in.stride)}),
@@ -774,6 +810,7 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
tokens.push_back(to_token(tok));
}
}
assert(used_index);
result->push_back(pool.alloc_element<DerefElement>(args.at(0), rd.addr_of, tokens));
return;
} else {
@@ -1474,6 +1511,28 @@ void SimpleExpressionElement::update_from_stack_float_to_int(const Env& env,
}
}
namespace {
GenericElement* allocate_fixed_op(FormPool& pool, FixedOperatorKind kind, Form* op1) {
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(kind), op1);
}
} // namespace
void SimpleExpressionElement::update_from_stack_subu_l32_s7(const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects) {
auto var = m_expr.get_arg(0).var();
auto arg = pop_to_forms({var}, env, pool, stack, allow_side_effects).at(0);
auto type = env.get_types_before_op(var.idx()).get(var.reg()).typespec();
if (type != TypeSpec("handle")) {
env.func->warnings.general_warning(
".subu (32-bit) used on a {} at idx {}. This probably should be a handle.", type.print(),
var.idx());
}
result->push_back(allocate_fixed_op(pool, FixedOperatorKind::L32_NOT_FALSE_CBOOL, arg));
}
void SimpleExpressionElement::update_from_stack(const Env& env,
FormPool& pool,
FormStack& stack,
@@ -1613,6 +1672,9 @@ void SimpleExpressionElement::update_from_stack(const Env& env,
case SimpleExpression::Kind::VECTOR_FLOAT_PRODUCT:
update_from_stack_vector_float_product(env, pool, stack, result, allow_side_effects);
break;
case SimpleExpression::Kind::SUBU_L32_S7:
update_from_stack_subu_l32_s7(env, pool, stack, result, allow_side_effects);
break;
default:
throw std::runtime_error(
fmt::format("SimpleExpressionElement::update_from_stack NYI for {}", to_string(env)));
@@ -2633,6 +2695,108 @@ void CondWithElseElement::push_to_stack(const Env& env, FormPool& pool, FormStac
// ShortCircuitElement
///////////////////
FormElement* sc_to_handle_get_proc(ShortCircuitElement* elt,
const Env& env,
FormPool& pool,
FormStack& stack) {
if (elt->kind != ShortCircuitElement::AND) {
return nullptr;
}
if (elt->entries.size() != 2) {
return nullptr;
}
// fmt::print("candidate: {}\n", elt->to_string(env));
constexpr int reg_input_1 = 0;
constexpr int reg_input_2 = 1;
constexpr int reg_input_3 = 2;
constexpr int reg_temp_1 = 10;
constexpr int reg_temp_2 = 11;
constexpr int reg_temp_3 = 12;
// check first.
auto first_matcher =
Matcher::op(GenericOpMatcher::condition(IR2_Condition::Kind::NONZERO),
{Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::L32_NOT_FALSE_CBOOL),
{Matcher::any_reg(reg_input_1)})});
auto first_result = match(first_matcher, elt->entries.at(0).condition);
if (!first_result.matched) {
return nullptr;
}
// auto first_use_of_in = *first_result.maps.regs.at(reg_input_1);
// fmt::print("reg1: {}\n", first_use_of_in.to_string(env));
auto setup_matcher = Matcher::set_var(
Matcher::deref(Matcher::any_reg(reg_input_2), false,
{DerefTokenMatcher::string("process"), DerefTokenMatcher::integer(0)}),
reg_temp_1);
auto if_matcher = Matcher::if_no_else(
Matcher::op(
GenericOpMatcher::fixed(FixedOperatorKind::EQ),
{Matcher::deref(Matcher::any_reg(reg_input_3), false, {DerefTokenMatcher::string("pid")}),
Matcher::deref(Matcher::any_reg(reg_temp_2), false,
{DerefTokenMatcher::string("pid")})}),
Matcher::any_reg(reg_temp_3));
auto second_matcher = Matcher::begin({setup_matcher, if_matcher});
auto second_result = match(second_matcher, elt->entries.at(1).condition);
if (!second_result.matched) {
return nullptr;
}
auto in1 = *first_result.maps.regs.at(reg_input_1);
auto in2 = *second_result.maps.regs.at(reg_input_2);
auto in3 = *second_result.maps.regs.at(reg_input_3);
auto in_name = in1.to_string(env);
if (in_name != in2.to_string(env)) {
return nullptr;
}
if (in_name != in3.to_string(env)) {
return nullptr;
}
auto temp_name = second_result.maps.regs.at(reg_temp_1)->to_string(env);
if (temp_name != second_result.maps.regs.at(reg_temp_2)->to_string(env)) {
return nullptr;
}
if (temp_name != second_result.maps.regs.at(reg_temp_3)->to_string(env)) {
return nullptr;
}
const auto& temp_use_def = env.get_use_def_info(*second_result.maps.regs.at(reg_temp_1));
if (temp_use_def.use_count() != 2 || temp_use_def.def_count() != 1) {
return nullptr;
}
// modify use def:
auto* menv = const_cast<Env*>(&env);
menv->disable_use(in2);
menv->disable_use(in3);
auto repopped = stack.pop_reg(in1, {}, env, true);
// fmt::print("repopped: {}\n", repopped->to_string(env));
if (!repopped) {
repopped = var_to_form(in1, pool);
}
return pool.alloc_element<GenericElement>(
GenericOperator::make_function(
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, "handle->process")),
repopped);
return nullptr;
}
void ShortCircuitElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
mark_popped();
if (!used_as_value.value_or(false)) {
@@ -2678,8 +2842,14 @@ void ShortCircuitElement::push_to_stack(const Env& env, FormPool& pool, FormStac
}
}
FormElement* to_push = this;
auto as_handle_get = sc_to_handle_get_proc(this, env, pool, stack);
if (as_handle_get) {
to_push = as_handle_get;
}
assert(used_as_value.has_value());
stack.push_value_to_reg(final_result, pool.alloc_single_form(nullptr, this), true,
stack.push_value_to_reg(final_result, pool.alloc_single_form(nullptr, to_push), true,
env.get_variable_type(final_result, false));
already_rewritten = true;
}
@@ -3844,39 +4014,6 @@ Form* is_load_store_vector_to_reg(const Register& reg,
return mr.maps.forms.at(0);
}
/*!
* Imagine:
* x = foo
* { // some macro/inlined thing
* read from x
* return x;
* }
*
* and you want to transform it to
* x = some_macro(foo, blah, ...)
*
* this will get you foo (and pop it from the stack), assuming the stack is sitting right after the
* point where the inline thing evaluated foo.
*
* For later book-keeping of reg use, if it gets you something new, it will set found_orig_out,
* and also give you the regaccess for the x of the x = foo.
*
* If you use this, you are responsible for adding code that sets x again.
*/
Form* repop_passthrough_arg(Form* in,
FormStack& stack,
const Env& env,
RegisterAccess* orig_out,
bool* found_orig_out) {
*found_orig_out = false;
auto as_atom = form_as_atom(in);
if (as_atom && as_atom->is_var()) {
return stack.pop_reg(as_atom->var().reg(), {}, env, true, -1, orig_out, found_orig_out);
}
return in;
}
/*!
* Try to convert a form to a regaccess.
*/
+47
View File
@@ -137,6 +137,14 @@ Matcher Matcher::set(const Matcher& dst, const Matcher& src) {
return m;
}
Matcher Matcher::set_var(const Matcher& src, int dst_match_id) {
Matcher m;
m.m_kind = Kind::SET_VAR;
m.m_sub_matchers = {src};
m.m_reg_out_id = dst_match_id;
return m;
}
Matcher Matcher::while_loop(const Matcher& condition, const Matcher& body) {
Matcher m;
m.m_kind = Kind::WHILE_LOOP;
@@ -151,6 +159,13 @@ Matcher Matcher::any_constant_token(int match_id) {
return m;
}
Matcher Matcher::begin(const std::vector<Matcher>& elts) {
Matcher m;
m.m_kind = Kind::BEGIN;
m.m_sub_matchers = elts;
return m;
}
bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out) const {
switch (m_kind) {
case Kind::ANY:
@@ -527,6 +542,38 @@ bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out) const {
return true;
} break;
case Kind::BEGIN: {
if ((int)m_sub_matchers.size() != input->size()) {
return false;
}
for (int i = 0; i < input->size(); i++) {
Form fake;
fake.elts().push_back(input->elts().at(i));
if (!m_sub_matchers.at(i).do_match(&fake, maps_out)) {
return false;
}
}
return true;
}
case Kind::SET_VAR: {
auto as_set = dynamic_cast<SetVarElement*>(input->try_as_single_active_element());
if (!as_set) {
return false;
}
if (!m_sub_matchers.at(0).do_match(as_set->src(), maps_out)) {
return false;
}
if (m_reg_out_id != -1) {
maps_out->regs.resize(std::max((int)maps_out->regs.size(), m_reg_out_id + 1));
maps_out->regs.at(m_reg_out_id) = as_set->dst();
}
return true;
}
default:
assert(false);
return false;
+5 -1
View File
@@ -28,7 +28,8 @@ class Matcher {
static Matcher any_label(int match_id = -1);
static Matcher op(const GenericOpMatcher& op, const std::vector<Matcher>& args);
static Matcher op_with_rest(const GenericOpMatcher& op, const std::vector<Matcher>& args);
static Matcher set(const Matcher& dst, const Matcher& src);
static Matcher set(const Matcher& dst, const Matcher& src); // form-form
static Matcher set_var(const Matcher& src, int dst_match_id); // var-form
static Matcher fixed_op(FixedOperatorKind op, const std::vector<Matcher>& args);
static Matcher match_or(const std::vector<Matcher>& args);
static Matcher cast(const std::string& type, Matcher value);
@@ -49,6 +50,7 @@ class Matcher {
static Matcher while_loop(const Matcher& condition, const Matcher& body);
static Matcher any_constant_token(int match_id = -1);
static Matcher or_expression(const std::vector<Matcher>& elts);
static Matcher begin(const std::vector<Matcher>& elts);
enum class Kind {
ANY_REG, // matching any register
@@ -63,6 +65,7 @@ class Matcher {
ANY_SYMBOL,
DEREF_OP,
SET,
SET_VAR,
ANY_LABEL,
SYMBOL,
IF_WITH_ELSE,
@@ -70,6 +73,7 @@ class Matcher {
WHILE_LOOP,
ANY_CONSTANT_TOKEN,
SC_OR,
BEGIN,
INVALID
};
+1
View File
@@ -151,6 +151,7 @@ enum class FixedOperatorKind {
VECTOR_PLUS,
VECTOR_MINUS,
VECTOR_FLOAT_PRODUCT,
L32_NOT_FALSE_CBOOL,
INVALID
};
+14
View File
@@ -723,6 +723,18 @@ std::unique_ptr<AtomicOp> convert_bnel_1(const Instruction& i0, int idx, bool li
return make_branch_no_delay(condition, likely, dest, idx);
}
std::unique_ptr<AtomicOp> convert_subu_1(const Instruction& i0, int idx) {
// subu a2, v1, s7
if (i0.get_src(1).is_reg(rs7())) {
auto src = make_src_atom(i0.get_src(0).get_reg(), idx);
auto expr = SimpleExpression(SimpleExpression::Kind::SUBU_L32_S7, src);
auto dst = make_dst_var(i0.get_dst(0).get_reg(), idx);
return std::make_unique<SetVarOp>(dst, expr, idx);
} else {
return nullptr; // go to asm fallback
}
}
std::unique_ptr<AtomicOp> convert_1(const Instruction& i0, int idx, bool hint_inline_asm) {
switch (i0.kind) {
case InstructionKind::OR:
@@ -856,6 +868,8 @@ std::unique_ptr<AtomicOp> convert_1(const Instruction& i0, int idx, bool hint_in
return convert_beql_1(i0, idx, true);
case InstructionKind::BNEL:
return convert_bnel_1(i0, idx, true);
case InstructionKind::SUBU:
return convert_subu_1(i0, idx); // may fail
default:
return nullptr;
}
+397 -150
View File
@@ -594,10 +594,17 @@
(defenum entity-perm-status
:bitfield #t
:type uint16
(bit-0 0)
(bit-1 1)
(dead 2)
(unknown 5) ;; TODO - task-control::task-cstage::14
(complete 6))
(bit-3 3)
(bit-4 4)
(user-set-from-cstage 5)
(complete 6) ;; wrong!
(bit-7 7)
(real-complete 8)
(bit-9 9)
)
(defenum path-control-flag
:bitfield #t
@@ -624,7 +631,6 @@
(need-reminder 5)
(need-reward-speech 6)
(need-resolution 7)
(*unknown* 999999)
)
(defenum game-task
@@ -749,6 +755,189 @@
(*unknown* 255))
(defenum game-text-id
:type uint32
:bitfield #f
(zero 0)
(sfx-volume #x10a)
(music-volume #x10b)
(speech-volume #x10c)
(language #x10d)
(vibrations #x10e)
(play-hints #x10f)
(center-screen #x110)
(english #x114)
(french #x115)
(german #x116)
(spanish #x117)
(italian #x118)
(japanese #x119)
(aspect-ratio #x125)
(video-mode #x126)
(game-options #x127)
(graphic-options #x128)
(sound-options #x129)
(hidden-power-cell #x12f) ;; why is this here??
(continue-without-saving #x13f)
(back #x13e)
(load-game #x14b)
(save-game #x14c)
(options #x150)
(new-game #x15c)
(ok #x15e)
(exit-demo #x15f)
(quit-game #x16f)
(village1-mayor-money #x200)
(vollage1-uncle-money #x201)
(village1-yakow-herd #x202)
(village1-yakow-return #x203)
(village1-oracle #x204)
(beach-ecorocks #x205)
(beach-flutflut-push #x206)
(beach-flutflut-meet #x207)
(beach-pelican #x208)
(beach-seagull #x209)
(beach-cannon #x20a)
(beach-buzzer #x20b)
(jungle-lurkerm-connect #x20c)
(jungle-tower #x20d)
(jungle-eggtop #x20e)
(jungle-plant #x20f)
(jungle-fishgame #x210)
(misty-muse-catch #x211)
(misty-muse-return #x212)
(misty-boat #x213)
(misty-cannon #x214)
(misty-return-to-pool #x215) ;; task name??
(misty-find-transpad #x216) ;; task name?
(misty-balloon-lurkers #x217)
(village1-level-name #x220)
(beach-level-name #x221)
(jungle-level-name #x222)
(misty-level-name #x223)
(beach-seagull-get #x22e)
(jungle-lurkerm-unblock #x22f)
(jungle-lurkerm-return #x230)
(MISSING-orb-hint #x233)
(beach-gimmie #x262)
(beach-sentinel #x263)
(jungle-canyon-end #x264)
(jungle-temple-door #x265)
(misty-bike-jump #x266)
(misty-eco-challenge #x267)
(village2-gambler-money #x300)
(village2-geologist-money #x301)
(village2-warrior-money #x302)
(village2-oracle-money #x303)
(swamp-tether #x304)
(swamp-flutflut #x307)
(swamp-billy #x309)
(sunken-elevator-raise #x30a)
(sunken-elevator-get-to-roof #x30b)
(sunken-pipe #x30c)
(sunken-climb-tube #x30d) ;; task name?
(sunken-pool #x30e) ;; task name?
(sunken-platforms #x30f)
(rolling-moles #x310)
(rolling-moles-return #x311)
(rolling-robbers #x312)
(rolling-race #x313)
(rolling-race-return #x314)
(rolling-lake #x315)
(rolling-plants #x316)
(unknown-buzzers #x317)
(village2-level-name #x319)
(rolling-level-name #x31b)
(swamp-level-name #x31c)
(sunken-level-name #x31d)
(ogre-level-name #x31e)
(swamp-battle #x321)
(sunken-bottom #x322) ;; task name?
(reach-center #x323) ;; task name?
(rolling-ring-chase-1 #x324)
(rolling-ring-chase-2 #x325)
(village3-miner-money #x400)
(village3-oracle-money #x401)
(snow-ram-3-left #x402)
(snow-ram-2-left #x403)
(snow-ram-1-left #x404)
(snow-fort #x405)
(snow-bunnies #x406)
(snow-open-door #x408) ;; task name?
(cave-robot-climb #x40e)
(cave-dark-climb #x40f) ;; destroy crystals
(cave-gnawers #x410)
(cave-dark-crystals #x411)
(village3-buzzer #x413)
(village3-level-name #x415)
(snowy-level-name #x417)
(cave-level-name #x419)
(lavatube-level-name #x41b)
(snow-eggtop #x421)
(cave-spider-tunnel #x423)
(cave-platforms #x424)
(cave-swing-poles #x426)
(snow-frozen-crate #x42b) ;; task name?
(snow-bumpers #x42c)
(fire-canyon-end #x500)
(fire-canyon-buzzer #x501)
(fire-canyon-level-name #x50c)
(ogre-end #x600)
(ogre-buzzer #x601)
(ogre-boss #x603)
(lavatube-end #x700)
(lavatube-buzzer #x701)
(citadel-buzzer #x800)
(citadel-level-name #x801)
(citadel-sage-blue #x802)
(citadel-sage-red #x803)
(citadel-sage-yellow #x804)
(citadel-sage-green #x805)
(training-gimmie-task-name #x91b)
(training-buzzer-task-name #x91c)
(training-door-task-name #x91d)
(training-climb-task-name #x91e)
(training-level-name #x91f)
(inc #xf10)
(europe #xf11)
)
;; ----------------------
;; File - gstring-h
;; Source Path - kernel/gstring-h.gc
@@ -1374,7 +1563,7 @@
(get-bit (_type_ int) symbol 9)
(clear-bit (_type_ int) int 10)
(set-bit (_type_ int) int 11)
(clear (_type_) _type_ 12)
(clear-all! (_type_) _type_ 12)
)
)
@@ -1921,7 +2110,7 @@
)
(deftype border-plane (basic)
((name basic :offset-assert 4)
((name symbol :offset-assert 4)
(action basic :offset-assert 8)
(slot int8 :offset-assert 12)
(trans vector :inline :offset-assert 16)
@@ -1931,8 +2120,8 @@
:size-assert #x30
:flag-assert #xb00000030
(:methods
(dummy-9 () none 9)
(dummy-10 () none 10)
(debug-draw! (_type_) none 9)
(point-past-plane? (_type_ vector) symbol 10)
)
)
@@ -5142,7 +5331,7 @@
:size-assert #x10
:flag-assert #xa00000010
(:methods
(dummy-9 (_type_ uint symbol) string 9)
(lookup-text! (_type_ game-text-id symbol) string 9)
)
)
@@ -8574,11 +8763,11 @@
)
(deftype continue-point (basic)
((name basic :offset-assert 4)
((name string :offset-assert 4)
(level basic :offset-assert 8)
(flags uint32 :offset-assert 12)
(trans vector :inline :offset-assert 16)
(quat vector :inline :offset-assert 32)
(quat quaternion :inline :offset-assert 32)
(camera-trans vector :inline :offset-assert 48)
(camera-rot float 9 :offset-assert 64)
(load-commands pair :offset-assert 100)
@@ -8592,11 +8781,12 @@
:size-assert #x7c
:flag-assert #xa0000007c
(:methods
(dummy-9 () none 9)
(debug-draw! (_type_) none 9)
)
)
(declare-type entity-perm structure)
(declare-type game-save basic)
(declare-type entity-perm-array basic)
(deftype game-info (basic)
((mode symbol :offset-assert 4)
@@ -8614,7 +8804,7 @@
(current-continue continue-point :offset-assert 108)
(text-ids-seen bit-array :offset-assert 112)
(level-opened uint8 32 :offset-assert 116)
(hint-control array :offset-assert 148)
(hint-control (array level-hint-control) :offset-assert 148)
(task-hint-control array :offset-assert 152)
(total-deaths int32 :offset-assert 156)
(continue-deaths int32 :offset-assert 160)
@@ -8624,9 +8814,9 @@
(death-time uint64 :offset-assert 184)
(hit-time uint64 :offset-assert 192)
(fuel-cell-pickup-time uint64 :offset-assert 200)
(fuel-cell-time array :offset-assert 208)
(enter-level-time array :offset-assert 212)
(in-level-time array :offset-assert 216)
(fuel-cell-time (array uint64) :offset-assert 208)
(enter-level-time (array uint64) :offset-assert 212)
(in-level-time (array uint64) :offset-assert 216)
(blackout-time uint64 :offset-assert 224)
(letterbox-time uint64 :offset-assert 232)
(hint-play-time uint64 :offset-assert 240)
@@ -8634,7 +8824,7 @@
(display-text-handle uint64 :offset-assert 256)
(death-movie-tick int32 :offset-assert 264)
(want-auto-save symbol :offset-assert 268)
(auto-save-proc uint64 :offset-assert 272)
(auto-save-proc handle :offset-assert 272)
(auto-save-status uint32 :offset-assert 280)
(auto-save-card int32 :offset-assert 284)
(auto-save-which int32 :offset-assert 288)
@@ -8649,26 +8839,26 @@
:flag-assert #x1d00000144
;; field dummy is a basic loaded with a signed load
(:methods
(dummy-9 (_type_ symbol symbol string) none 9)
(dummy-10 () none 10)
(dummy-11 () none 11)
(dummy-12 () none 12)
(dummy-13 (_type_ uint) entity-perm 13) ; TODO - not totally confirmed
(dummy-14 (_type_) none 14)
(dummy-15 (_type_) none 15)
(dummy-16 () none 16)
(dummy-17 (_type_) continue-point 17)
(dummy-18 () none 18)
(dummy-19 (_type_ continue-point) none 19)
(dummy-20 () none 20)
(dummy-21 () none 21)
(dummy-22 () none 22)
(dummy-23 () none 23)
(initialize! (_type_ symbol game-save string) _type_ 9)
(adjust (_type_ symbol float handle) float 10)
(task-complete? (_type_ game-task) symbol 11)
(lookup-entity-perm-by-aid (_type_ uint) entity-perm 12)
(get-entity-task-perm (_type_ game-task) entity-perm 13)
(copy-perms-from-level! (_type_ level) none 14)
(copy-perms-to-level! (_type_ level) none 15)
(debug-print (_type_ symbol) _type_ 16)
(get-or-create-continue! (_type_) continue-point 17)
(get-continue-by-name (_type_ string) continue-point 18)
(set-continue! (_type_ basic) continue-point 19)
(buzzer-count (_type_ game-task) int 20)
(seen-text? (_type_ game-text-id) symbol 21)
(mark-text-as-seen (_type_ game-text-id) none 22)
(got-buzzer? (_type_ game-task int) symbol 23)
(dummy-24 () none 24)
(dummy-25 () none 25)
(dummy-26 () none 26)
(dummy-27 () none 27)
(dummy-28 () none 28)
(load-game! (_type_ game-save) game-save 25)
(clear-text-seen! (_type_ game-text-id) none 26)
(get-death-count (_type_ symbol) int 27)
(get-health-percent-lost (_type_) float 28)
)
)
@@ -9394,7 +9584,7 @@
(:methods
(new (symbol type process pickup-type float) _type_ 0)
(dummy-9 () none 9)
(dummy-10 (_type_ symbol) none 10)
(reset! (_type_ symbol) none 10)
(dummy-11 (_type_) float 11)
)
)
@@ -12582,14 +12772,14 @@
:size-assert #x10
:flag-assert #xa00000010
(:methods
(dummy-9 () none 9)
(update-perm! (_type_ symbol entity-perm-status) _type_ 9)
)
)
(deftype entity-links (structure)
((prev-link entity-links :offset-assert 0)
(next-link entity-links :offset-assert 4)
(entity basic :offset-assert 8)
(entity entity :offset-assert 8)
(process process :offset-assert 12)
(level level :offset-assert 16)
(vis-id int32 :offset-assert 20)
@@ -12615,7 +12805,7 @@
)
(deftype entity-links-array (inline-array-class)
()
((data entity-links :inline :dynamic :offset-assert 16))
:method-count-assert 9
:size-assert #x10
:flag-assert #x900000010
@@ -13702,8 +13892,8 @@
)
(deftype task-info-data (basic)
((task-id uint8 :offset-assert 4)
(task-name symbol 4 :offset-assert 8)
((task-id game-task :offset-assert 4)
(task-name game-text-id 4 :offset-assert 8)
(text-index-when-resolved int32 :offset-assert 24)
)
:method-count-assert 9
@@ -13712,7 +13902,7 @@
)
(deftype level-tasks-info (basic)
((level-name-id uint32 :offset-assert 4)
((level-name-id game-text-id :offset-assert 4)
(text-group-index int32 :offset-assert 8)
(nb-of-tasks int32 :offset-assert 12)
(buzzer-task-index int32 :offset-assert 16)
@@ -13725,7 +13915,7 @@
(deftype game-option (basic)
((option-type uint64 :offset-assert 8)
(name uint32 :offset-assert 16)
(name game-text-id :offset-assert 16)
(scale basic :offset-assert 20)
(param1 float :offset-assert 24)
(param2 float :offset-assert 28)
@@ -15880,11 +16070,11 @@
;; - Unknowns
;;(define-extern *global-toggle* object) ;; unknown type
;;(define-extern *part-id-table* object) ;; unknown type
(define-extern *part-id-table* (array sparticle-launcher)) ;; unknown type
;;(define-extern *particle-300hz-timer* object) ;; unknown type
;;(define-extern *sp-launch-queue* object) ;; unknown type
;;(define-extern *death-adgif* object) ;; unknown type
;;(define-extern *part-group-id-table* object) ;; unknown type
(define-extern *part-group-id-table* (array sparticle-launch-group))
;;(define-extern *sp-launcher-lock* object) ;; unknown type
;;(define-extern *sp-launcher-enable* object) ;; unknown type
;;(define-extern *particle-adgif-cache* object) ;; unknown type
@@ -15959,7 +16149,7 @@
(define-extern ja-channel-push! (function int int int))
(define-extern ja-channel-set! (function int int))
(define-extern kill-current-level-hint function)
(define-extern kill-current-level-hint (function pair pair symbol none))
(define-extern level-hint-surpress! function)
(define-extern ja-aframe-num (function int float))
(define-extern ja-abort-spooled-anim function)
@@ -15988,24 +16178,32 @@
;; - Types
(defenum task-flags
:type uint8
:bitfield #t
(closed 0)
(has-entity 1)
(closed-by-default 2)
)
(declare-type task-control basic)
(deftype task-cstage (structure)
((game-task game-task :offset-assert 0)
(status task-status :offset-assert 8)
(flags uint8 :offset-assert 16)
(flags task-flags :offset-assert 16)
(condition (function task-control symbol) :offset-assert 20)
)
:method-count-assert 16
:size-assert #x18
:flag-assert #x1000000018
(:methods
(get-game-task (_type_) uint 9)
(get-task-status (_type_) uint 10)
(TODO-RENAME-11 (_type_ task-control) symbol 11)
(first-flag-bit? (_type_) symbol 12)
(third-flag-bit? (_type_) symbol 13)
(TODO-RENAME-14 (_type_) int 14)
(clear-all-but-first-flag-bit (_type_) int 15)
(get-game-task (_type_) game-task 9)
(get-task-status (_type_) task-status 10)
(task-available? (_type_ task-control) symbol 11)
(closed? (_type_) symbol 12)
(closed-by-default? (_type_) symbol 13)
(close-task! (_type_) int 14)
(open-task! (_type_) int 15)
)
)
@@ -16020,13 +16218,13 @@
(current-task (_type_) int 9)
(current-status (_type_) int 10)
(close-current! (_type_) none 11)
(close-status! (_type_ int) int 12)
(close-status! (_type_ task-status) int 12)
(first-any (_type_ symbol) int 13)
(reset! (_type_ symbol symbol) int 14)
(closed? (_type_ int int) symbol 15)
(closed? (_type_ game-task task-status) symbol 15)
(get-reminder (_type_ int) int 16)
(save-reminder (_type_ int int) int 17) ;; TODO - i believe this is none
(exists? (_type_ int int) symbol 18)
(exists? (_type_ game-task task-status) symbol 18)
)
)
@@ -16123,20 +16321,20 @@
;; - Functions
(define-extern get-task-control (function int task-control))
(define-extern level-hint-spawn function)
(define-extern get-game-count function)
(define-extern activate-orb-all function)
(define-extern close-specific-task! (function task-control int int))
(define-extern reset-all-hint-controls function)
(define-extern reset-actors function)
(define-extern get-task-control (function game-task task-control))
(define-extern level-hint-spawn (function game-text-id string symbol process-tree int none))
(define-extern get-game-count (function int count-info))
(define-extern activate-orb-all (function int int))
(define-extern close-specific-task! (function game-task task-status int))
(define-extern reset-all-hint-controls (function none))
(define-extern reset-actors (function symbol none))
(define-extern set-blackout-frames (function int uint))
(define-extern set-master-mode (function symbol none))
(define-extern stop (function symbol int))
(define-extern start (function symbol continue-point target))
(define-extern position-in-front-of-camera! (function vector float float vector))
(define-extern game-task->string (function int string))
(define-extern trsq->continue-point function)
(define-extern game-task->string (function game-task string))
(define-extern trsq->continue-point (function trsq none))
;; - Symbols
@@ -16145,9 +16343,8 @@
;; - Unknowns
;;(define-extern *level-task-data-remap* object) ;; unknown type
(define-extern *spawn-actors* symbol)
(define-extern *default-continue* symbol)
(define-extern *default-continue* continue-point)
;; ----------------------
@@ -16158,57 +16355,105 @@
;; - Types
; (deftype game-save-tag (structure)
; ((user-object UNKNOWN 2 :offset-assert 0)
; (user-uint64 uint64 :offset-assert 0)
; (user-float0 float :offset-assert 0)
; (user-float UNKNOWN 2 :offset-assert 0)
; (user-int32 UNKNOWN 2 :offset-assert 0)
; (user-uint32 UNKNOWN 2 :offset-assert 0)
; (user-int16 UNKNOWN 4 :offset-assert 0)
; (user-uint16 UNKNOWN 4 :offset-assert 0)
; (user-int8 UNKNOWN 8 :offset-assert 0)
; (user-int80 int8 :offset-assert 0)
; (user-int81 int8 :offset-assert 1)
; (user-uint8 UNKNOWN 8 :offset-assert 0)
; (elt-count int32 :offset-assert 8)
; (elt-size uint16 :offset-assert 12)
; (elt-type uint16 :offset-assert 14)
; )
; :method-count-assert 9
; :size-assert #x10
; :flag-assert #x900000010
; )
(defenum game-save-elt
:type uint16
(name 100)
(base-time 101)
(real-time 102)
(game-time 103)
(integral-time 104)
(continue 200)
(life 201)
(money 202)
(money-total 203)
(moeny-per-level 204)
(buzzer-total 205)
(fuel-cell 206)
(death-movie-tick 207)
(task-list 300)
(perm-list 301)
(hint-list 303)
(text-list 304)
(level-open-list 305)
(total-deaths 400)
(continue-deaths 401)
(fuel-cell-deaths 402)
(game-start-time 403)
(continue-timke 404) ;; typo in game
(death-time 405)
(hit-time 406)
(fuel-cell-pickup-time 407)
(continue-time 408)
(fuel-cell-time 409)
(enter-level-time 410)
(deaths-per-level 411)
(death-pos 412)
(auto-save-count 413)
(in-level-time 414)
(sfx-volume 500)
(music-volume 501)
(dialog-volume 502)
(language 503)
(screenx 504)
(screeny 505)
(vibration 506)
(play-hints 507)
(video-mode 508)
(aspect-ratio 509)
)
; (deftype game-save (basic)
; ((version int32 :offset-assert 4)
; (allocated-length int32 :offset-assert 8)
; (length int32 :offset-assert 12)
; (info-int32 UNKNOWN 16 :offset-assert 16)
; (info-int8 UNKNOWN 64 :offset-assert 16)
; (level-index int32 :offset-assert 16)
; (fuel-cell-count float :offset-assert 20)
; (money-count float :offset-assert 24)
; (buzzer-count float :offset-assert 28)
; (completion-percentage float :offset-assert 32)
; (minute uint8 :offset-assert 36)
; (hour uint8 :offset-assert 37)
; (week uint8 :offset-assert 38)
; (day uint8 :offset-assert 39)
; (month uint8 :offset-assert 40)
; (year uint8 :offset-assert 41)
; (new-game int32 :offset-assert 44)
; (tag UNKNOWN :dynamic :offset-assert 80)
; )
; :method-count-assert 12
; :size-assert #x50
; :flag-assert #xc00000050
; (:methods
; (dummy-9 () none 9)
; (dummy-10 () none 10)
; (dummy-11 () none 11)
; )
; )
(deftype game-save-tag (structure)
((user-object object 2 :offset-assert 0)
(user-uint64 uint64 :offset 0)
(user-float0 float :offset 0)
(user-float float 2 :offset 0)
(user-int32 int32 2 :offset 0)
(user-uint32 uint32 2 :offset 0)
(user-int16 int16 4 :offset 0)
(user-uint16 uint16 4 :offset 0)
(user-int8 int8 8 :offset 0)
(user-int80 int8 :offset 0)
(user-int81 int8 :offset 1)
(user-uint8 uint8 8 :offset 0)
(elt-count int32 :offset-assert 8)
(elt-size uint16 :offset-assert 12)
(elt-type game-save-elt :offset-assert 14)
)
:method-count-assert 9
:size-assert #x10
:flag-assert #x900000010
)
(deftype game-save (basic)
((version int32 :offset-assert 4)
(allocated-length int32 :offset-assert 8)
(length int32 :offset-assert 12)
(info-int32 int32 16 :offset-assert 16)
(info-int8 int8 64 :offset 16)
(level-index int32 :offset 16)
(fuel-cell-count float :offset 20)
(money-count float :offset 24)
(buzzer-count float :offset 28)
(completion-percentage float :offset 32)
(minute uint8 :offset 36)
(hour uint8 :offset 37)
(week uint8 :offset 38)
(day uint8 :offset 39)
(month uint8 :offset 40)
(year uint8 :offset 41)
(new-game int32 :offset 44)
(tag game-save-tag :inline :dynamic :offset-assert 80)
)
:method-count-assert 12
:size-assert #x50
:flag-assert #xc00000050
(:methods
(new (symbol type int) _type_ 0)
(save-to-file (_type_ string) _type_ 9)
(load-from-file! (_type_ string) _type_ 10)
(debug-print (_type_ symbol) _type_ 11)
)
)
(deftype auto-save (process)
((card int32 :offset-assert 112)
@@ -16248,19 +16493,19 @@
(define-extern progress-allowed? (function symbol))
(define-extern print-game-text (function string font-context symbol int int float)) ; TODO decomp error, this seems correct though
(define-extern get-aspect-ratio (function symbol))
(define-extern get-task-status (function task-control int))
(define-extern get-task-status (function game-task task-status))
(define-extern lookup-level-info (function symbol level-load-info))
(define-extern calculate-completion function)
(define-extern game-save-elt->string function)
(define-extern progress-level-index->string function)
(define-extern game-save-elt->string (function game-save-elt string))
(define-extern progress-level-index->string (function int string))
(define-extern auto-save-post function)
(define-extern auto-save-check function)
;; - Unknowns
;;(define-extern *auto-save-info* object) ;; unknown type
(define-extern *auto-save-info* mc-slot-info) ;; unknown type
;;(define-extern scf-get-time object) ;; unknown type
;;(define-extern *level-task-data* object) ;; unknown type
;; ;; unknown type
;; ----------------------
@@ -18232,7 +18477,7 @@
(define-extern hide-bottom-hud function)
(define-extern ambient-hint-init-by-other function)
(define-extern level-hint-process-cmd function)
(define-extern task-known? (function task-control symbol))
(define-extern task-known? (function game-task symbol))
(define-extern can-grab-display? function)
(define-extern level-hint-displayed? function)
(define-extern ambient-inspect function)
@@ -18890,7 +19135,7 @@
(define-extern target-hit-push function)
(define-extern velocity-set-to-target! function)
(define-extern start-sequence-a function)
(define-extern task-closed? (function int int symbol))
(define-extern task-closed? (function game-task task-status symbol))
(define-extern next-level function)
;; - Unknowns
@@ -19803,15 +20048,15 @@
;; - Functions
(define-extern task-status->string (function int string))
(define-extern open-specific-task! (function task-control int int))
(define-extern task-exists? (function task-control int symbol))
(define-extern task-status->string (function task-status string))
(define-extern open-specific-task! (function game-task task-status int))
(define-extern task-exists? (function game-task task-status symbol))
(define-extern sages-kidnapped? (function symbol))
;; - Symbols
(define-extern *null-task-control* task-control)
(define-extern *task-controls* (array task-control))
(define-extern *task-controls* (array basic))
(define-extern *assistant-tasks* task-control)
(define-extern *assistant-village2-tasks* task-control)
(define-extern *gambler-tasks* task-control)
@@ -20357,28 +20602,30 @@
;; Containing DGOs - ['GAME', 'ENGINE']
;; Version - 3
;; - Unknowns
;; - Symbols
;;(define-extern *main-options* object) ;; unknown type
;;(define-extern *title* object) ;; unknown type
;;(define-extern *options* object) ;; unknown type
;;(define-extern *main-options-demo* object) ;; unknown type
;;(define-extern *main-options-demo-shared* object) ;; unknown type
;;(define-extern *game-options* object) ;; unknown type
;;(define-extern *game-options-japan* object) ;; unknown type
;;(define-extern *game-options-demo* object) ;; unknown type
;;(define-extern *graphic-options* object) ;; unknown type
;;(define-extern *graphic-title-options-pal* object) ;; unknown type
;;(define-extern *sound-options* object) ;; unknown type
;;(define-extern *yes-no-options* object) ;; unknown type
;;(define-extern *ok-options* object) ;; unknown type
;;(define-extern *load-options* object) ;; unknown type
;;(define-extern *save-options* object) ;; unknown type
;;(define-extern *save-options-title* object) ;; unknown type
;;(define-extern *options-remap* object) ;; unknown type
;;(define-extern *language-name-remap* object) ;; unknown type
;;(define-extern *task-egg-starting-x* object) ;; unknown type
;;(define-extern *game-counts* object) ;; unknown type
(define-extern *main-options* (array game-option))
(define-extern *title* (array game-option))
(define-extern *options* (array game-option))
(define-extern *main-options-demo* (array game-option))
(define-extern *main-options-demo-shared* (array game-option))
(define-extern *game-options* (array game-option))
(define-extern *game-options-japan* (array game-option))
(define-extern *game-options-demo* (array game-option))
(define-extern *graphic-options* (array game-option))
(define-extern *graphic-title-options-pal* (array game-option))
(define-extern *sound-options* (array game-option))
(define-extern *yes-no-options* (array game-option))
(define-extern *ok-options* (array game-option))
(define-extern *load-options* (array game-option))
(define-extern *save-options* (array game-option))
(define-extern *save-options-title* (array game-option))
(define-extern *options-remap* (array array))
(define-extern *language-name-remap* (array game-text-id))
(define-extern *task-egg-starting-x* (array int32))
(define-extern *game-counts* game-count-info)
(define-extern *level-task-data-remap* (array int32))
(define-extern *level-task-data* (array level-tasks-info))
;; ----------------------
@@ -505,5 +505,9 @@
[496, "(function task-control symbol)"]
],
"game-info": [
[17, "(function symbol symbol continue-point symbol none)"]
],
"placeholder-do-not-add-below": []
}
@@ -471,7 +471,8 @@
"(method 12 level)",
"update-sound-banks",
"(method 16 level-group)",
"bg"
"bg",
"(method 18 game-info)"
],
// If format is used with the wrong number of arguments,
@@ -584,7 +584,7 @@
],
"task-control": [
["L634", "(array task-control)", true],
["L634", "(array basic)", true],
["L1322", "task-control", true],
["L1297", "task-control", true],
["L1103", "task-control", true],
@@ -1092,6 +1092,44 @@
["L560", "_lambda_", true]
],
"game-info": [
["L466", "float", true],
["L467", "float", true],
["L468", "rgba", true],
["L470", "rgba", true],
["L185", "float", true],
["L186", "float", true],
["L191", "float", true],
["L183", "continue-point", true],
["L154", "_lambda_", true],
["L464", "vector2h", true],
["L469", "rgba", true]
],
"progress-static": [
["L2", "(array int32)", true],
["L3", "(array level-tasks-info)", true],
["L121", "(array game-text-id)", true],
["L122", "(array int32)", true],
["L123", "(array array)", true],
["L124", "(array game-option)", true],
["L131", "(array game-option)", true],
["L137", "(array game-option)", true],
["L143", "(array game-option)", true],
["L145", "(array game-option)", true],
["L147", "(array game-option)", true],
["L152", "(array game-option)", true],
["L157", "(array game-option)", true],
["L161", "(array game-option)", true],
["L165", "(array game-option)", true],
["L169", "(array game-option)", true],
["L174", "(array game-option)", true],
["L180", "(array game-option)", true],
["L185", "(array game-option)", true],
["L190", "(array game-option)", true],
["L195", "(array game-option)", true]
],
// please do not add things after this entry! git is dumb.
"object-file-that-doesnt-actually-exist-and-i-just-put-this-here-to-prevent-merge-conflicts-with-this-file": []
}
@@ -394,17 +394,20 @@
[32, "tracking-spline-sampler"]
],
"draw-ocean-transition": [
[16, "sphere"]
],
"draw-ocean-transition": [[16, "sphere"]],
"(method 22 level)": [[16, "event-message-block"]],
"(method 9 level)": [[16, "event-message-block"]],
"(method 10 load-state)": [[16, "event-message-block"]],
"draw-joint-spheres": [[16, "vector"]],
"(method 16 process-drawable)": [[16, "matrix"], [80, "matrix"], [144, "vector"], [160, "vector"]],
"(method 16 process-drawable)": [
[16, "matrix"],
[80, "matrix"],
[144, "vector"],
[160, "vector"]
],
"draw-ocean-transition": [[16, "sphere"]],
"(anon-function 494 task-control)": [[16, "event-message-block"]],
@@ -440,5 +443,10 @@
"(anon-function 286 task-control)": [[16, "event-message-block"]],
"(anon-function 227 task-control)": [[16, "event-message-block"]],
"(anon-function 38 task-control)": [[16, "event-message-block"]],
"(anon-function 28 task-control)": [[16, "event-message-block"]]
"(anon-function 28 task-control)": [[16, "event-message-block"]],
"(method 10 border-plane)": [[16, "vector"]],
"(method 9 game-info)": [[16, "event-message-block"]],
"(method 9 continue-point)": [[16, "vector"]],
"(method 9 game-save)": [[16, "file-stream"]],
"(method 10 game-save)": [[16, "file-stream"]]
}
@@ -46,12 +46,6 @@
[243, "gp", "(array basic)"]
],
// GKERNEL-H
"(method 2 handle)": [
[10, "a2", "(pointer process)"],
[11, "a3", "process"]
],
// GKERNEL
"(method 0 cpu-thread)": [[[13, 28], "v0", "cpu-thread"]],
@@ -814,6 +808,11 @@
[165, "v1", "symbol"]
],
"task-control-reset": [
[[7, 13], "a0", "task-control"],
[[17, 21], "a0", "task-control"]
],
"(anon-function 494 task-control)": [[32, "v0", "float"]],
"(anon-function 493 task-control)": [[32, "v0", "float"]],
"(anon-function 480 task-control)": [[13, "v0", "float"]],
@@ -885,5 +884,68 @@
"(anon-function 38 task-control)": [[13, "v0", "float"]],
"(anon-function 28 task-control)": [[13, "v0", "float"]],
"(method 18 game-info)": [
[4, "v1", "symbol"],
[5, "v1", "level-load-info"],
[10, "s3", "continue-point"]
],
"(method 9 game-info)": [
[[270, 286], "s2", "(function cpu-thread function object object object object pointer)"]
],
"(method 25 game-info)" :[
[4, "v1", "game-save-tag"],
[53, "v1", "pointer"],
[[7, 53], "v1", "game-save-tag"],
[[72, 138], "s4", "game-save-tag"],
[154, "s4", "pointer"],
[[166, 205], "s4", "game-save-tag"],
[206, "s4", "pointer"],
[498, "s4", "pointer"],
[207, "a1", "(pointer uint8)"],
[[219, 220], "s4", "game-save-tag"],
[223, "s4", "pointer"],
[224, "a1", "(pointer uint8)"],
[[235, 236], "s4", "game-save-tag"],
[249, "s4", "pointer"],
[[261, 262], "s4", "game-save-tag"],
[275, "s4", "pointer"],
[293, "s4", "game-save-tag"],
[302, "s4", "pointer"],
[303, "a2", "(pointer uint8)"],
[315, "s4", "game-save-tag"],
[319, "s4", "pointer"],
[343, "v1", "(pointer uint8)"],
[352, "v1", "(pointer uint8)"],
[[360, 420], "s4", "game-save-tag"],
[423, "s4", "pointer"],
[424, "a1", "(pointer uint8)"],
[436, "s4", "game-save-tag"],
[440, "s4", "pointer"],
[456, "s4", "game-save-tag"],
[460, "s4", "pointer"],
[476, "s4", "game-save-tag"],
[480, "s4", "pointer"],
[[493, 495], "s4", "game-save-tag"]
],
"(method 11 game-save)": [
[126, "v1", "pointer"],
[213, "s4", "pointer"],
[[74, 88], "s4", "game-save-tag"],
[98, "s4", "pointer"],
[107, "s4", "game-save-tag"],
[125, "s4", "(pointer uint8)"],
[131, "s4", "game-save-tag"],
[155, "s4", "game-save-tag"],
[148, "s4", "pointer"],
[172, "s4", "pointer"],
[179, "s4", "game-save-tag"],
[196, "s4", "pointer"],
[[203, 210], "s4", "game-save-tag"]
],
"placeholder-do-not-add-below": []
}
@@ -1253,15 +1253,15 @@
},
"texture-page-dir-inspect": {
"args":["dir", "mode"],
"args": ["dir", "mode"],
"vars": {
"v1-0":"pool",
"s4-0":"level-idx",
"a1-3":"lev",
"s4-1":"entry-idx",
"s3-0":"entry-page",
"s2-0":"entry-link",
"s1-0":"entry-list-length"
"v1-0": "pool",
"s4-0": "level-idx",
"a1-3": "lev",
"s4-1": "entry-idx",
"s3-0": "entry-page",
"s2-0": "entry-link",
"s1-0": "entry-list-length"
}
},
@@ -2100,13 +2100,13 @@
"level-update-after-load": {
"args": ["loaded-level", "level-login-state"],
"vars": {
"s3-0":"level-drawable-trees",
"s5-0":"initial-timer",
"v1-4":"current-timer",
"v1-5":"elapsed-timer",
"s2-0":"current-login-pos",
"s2-1":["current-drawable", "drawable-tree"],
"s1-0":"idx-in-drawable"
"s3-0": "level-drawable-trees",
"s5-0": "initial-timer",
"v1-4": "current-timer",
"v1-5": "elapsed-timer",
"s2-0": "current-login-pos",
"s2-1": ["current-drawable", "drawable-tree"],
"s1-0": "idx-in-drawable"
}
},
@@ -2115,28 +2115,99 @@
"s3-0": ["conn", "connection"]
}
},
"(method 12 level)": {
"vars": {
"s5-3": ["s5-3", "pair"]
}
},
"update-sound-banks": {
"vars": {
"t0-0": ["t0-0", "symbol"]
}
},
"(method 16 level-group)": {
"vars": {
"s1-0": ["s1-0", "continue-point"]
}
},
"(method 20 level)": {
"vars": {
"s3-0": ["s3-0", "ramdisk-rpc-fill"]
}
},
"(method 9 game-info)": {
"args": ["obj", "cause", "save-to-load", "continue-point-override"],
"vars": {
"v1-0": "selected-cause",
"s4-1": "lev-info"
}
},
"(method 10 game-info)": {
"args": ["obj", "item", "amount", "source"],
"vars": {
"v1-10":"proc",
"s4-1":"level-idx",
"a0-35":"buzz-task",
"s4-2":"buzz-index",
"f30-0":"buzz-count",
"s3-0":"ctrl",
"s5-2":"buzz-bits"
}
},
"(method 14 game-info)": {
"args":["obj", "lev"],
"vars": {
"s5-0":"perms",
"s4-0":"lev-entities",
"s3-0":"lev-entity-idx",
"s2-0":"lev-entity-perm",
"v1-8":"info-entity-perm"
}
},
"(method 15 game-info)": {
"args":["obj", "lev"],
"vars": {
"s5-0":"lev-entities",
"s4-0":"lev-entity-idx",
"s3-0":"lev-entity-perm",
"v1-7":"info-entity-perm"
}
},
"(method 25 game-info)": {
"args": ["obj", "save"],
"vars": {
"v1-0": ["save-data", "game-save-tag"],
"s4-0": ["data", "game-save-tag"],
"v1-9": "old-base-frame",
"v1-10": "frame-counter-diff"
}
},
"(method 10 game-save)": {
"args": ["obj", "filename"],
"vars": {
"s5-0": "stream",
"s3-0": "in-size",
"s4-0": "my-size"
}
},
"(method 11 game-save)": {
"args": ["obj", "detail"],
"vars": {
"s4-0": ["tag", "game-save-tag"],
"s3-0": "tag-idx",
"s2-1":"prog-lev-idx",
"a2-13":"lev-name"
}
}
}
+17 -8
View File
@@ -164,7 +164,11 @@ goos::Object decompile_at_label(const TypeSpec& type,
}
if (ts.tc(TypeSpec("array"), type)) {
return decompile_boxed_array(label, labels, words, ts, file);
std::optional<TypeSpec> content_type_spec;
if (type.has_single_arg()) {
content_type_spec = type.get_single_arg();
}
return decompile_boxed_array(label, labels, words, ts, file, content_type_spec);
}
if (ts.tc(TypeSpec("structure"), type)) {
@@ -522,10 +526,10 @@ goos::Object decompile_structure(const TypeSpec& type,
} else if (word.kind == LinkedWord::EMPTY_PTR) {
array_def.push_back(pretty_print::to_symbol("'()"));
} else {
throw std::runtime_error(
fmt::format("Field {} in type {} offset {} did not have a proper reference for "
"array element {}",
field.name(), actual_type.print(), field.offset(), elt));
throw std::runtime_error(fmt::format(
"Field {} in type {} offset {} did not have a proper reference for "
"array element {} k = {}",
field.name(), actual_type.print(), field.offset(), elt, (int)word.kind));
}
}
field_defs_out.emplace_back(field.name(), pretty_print::build_list(array_def));
@@ -715,7 +719,8 @@ goos::Object decompile_boxed_array(const DecompilerLabel& label,
const std::vector<DecompilerLabel>& labels,
const std::vector<std::vector<LinkedWord>>& words,
const TypeSystem& ts,
const LinkedObjectFile* file) {
const LinkedObjectFile* file,
const std::optional<TypeSpec>& content_type_override) {
TypeSpec content_type;
auto type_ptr_word_idx = (label.offset / 4) - 1;
if ((label.offset % 8) == 4) {
@@ -737,6 +742,10 @@ goos::Object decompile_boxed_array(const DecompilerLabel& label,
throw std::runtime_error("Invalid alignment in decompile_boxed_array");
}
if (content_type_override) {
content_type = *content_type_override;
}
// now get the size
auto& size_word_1 = words.at(label.target_segment).at(type_ptr_word_idx + 1);
auto& size_word_2 = words.at(label.target_segment).at(type_ptr_word_idx + 2);
@@ -1057,7 +1066,7 @@ std::string decompile_int_enum_from_int(const TypeSpec& type, const TypeSystem&
}
}
throw std::runtime_error(
fmt::format("Failed to decompile integer enum. Value {} wasn't found in enum {}", value,
type_info->get_name()));
fmt::format("Failed to decompile integer enum. Value {} (0x{:x}) wasn't found in enum {}",
value, value, type_info->get_name()));
}
} // namespace decompiler
+2 -1
View File
@@ -49,7 +49,8 @@ goos::Object decompile_boxed_array(const DecompilerLabel& label,
const std::vector<DecompilerLabel>& labels,
const std::vector<std::vector<LinkedWord>>& words,
const TypeSystem& ts,
const LinkedObjectFile* file);
const LinkedObjectFile* file,
const std::optional<TypeSpec>& content_type_override);
goos::Object decompile_value(const TypeSpec& type,
const std::vector<u8>& bytes,
const TypeSystem& ts);