mirror of
https://github.com/open-goal/jak-project
synced 2026-07-10 23:22:17 -04:00
add support for non virtual states (#764)
* add support for non virtual states * typecheck go * start on virtual states * more support for virtual states * offline passes * fix tests * use behavior shortcut instead of lambda * final cleanup of virtual go * unused var warnings and fix inconsistent enum decompile order on win vs linux * fix thread safety bug with goal symbol table and vif1 interrupt handler * fix type mistake
This commit is contained in:
@@ -626,7 +626,8 @@ void insertSpecialBreaks(NodePool& pool, PrettyPrinterNode* node) {
|
||||
}
|
||||
|
||||
if (name == "defun" || name == "defmethod" || name == "defun-debug" || name == "let" ||
|
||||
name == "let*" || name == "rlet" || name == "defbehavior" || name == "lambda") {
|
||||
name == "let*" || name == "rlet" || name == "defbehavior" || name == "lambda" ||
|
||||
name == "defstate" || name == "behavior") {
|
||||
auto* first_list = getNextListOrEmptyListOnLine(node);
|
||||
if (first_list) {
|
||||
if (first_list->tok->kind == FormToken::TokenKind::EMPTY_PAIR) {
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
* Representation of a GOAL type in the type system.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "common/util/assert.h"
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -525,8 +525,9 @@ MethodInfo TypeSystem::declare_method(Type* type,
|
||||
if (!existing_info.type.is_compatible_child_method(ts, type->get_name())) {
|
||||
throw_typesystem_error(
|
||||
"The method {} of type {} was originally declared as {}, but has been "
|
||||
"redeclared as {}\n",
|
||||
method_name, type->get_name(), existing_info.type.print(), ts.print());
|
||||
"redeclared as {}. Originally declared in {}\n",
|
||||
method_name, type->get_name(), existing_info.type.print(), ts.print(),
|
||||
existing_info.defined_in_type);
|
||||
}
|
||||
|
||||
if ((existing_info.no_virtual || no_virtual) &&
|
||||
@@ -1665,6 +1666,10 @@ std::string TypeSystem::generate_deftype_footer(const Type* type) const {
|
||||
methods_string.append(fmt::format(":behavior {} ", *behavior));
|
||||
}
|
||||
|
||||
if (info.type.base_type() == "state") {
|
||||
methods_string.append(":state ");
|
||||
}
|
||||
|
||||
methods_string.append(fmt::format("{})\n ", info.id));
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ void add_bitfield(BitFieldType* bitfield_type, TypeSystem* ts, const goos::Objec
|
||||
void declare_method(Type* type, TypeSystem* type_system, const goos::Object& def) {
|
||||
for_each_in_list(def, [&](const goos::Object& _obj) {
|
||||
auto obj = &_obj;
|
||||
// (name args return-type [:no-virtual] [id])
|
||||
// (name args return-type [:no-virtual] [:replace] [:state] [id])
|
||||
auto method_name = symbol_string(car(obj));
|
||||
obj = cdr(obj);
|
||||
auto& args = car(obj);
|
||||
@@ -201,6 +201,11 @@ void declare_method(Type* type, TypeSystem* type_system, const goos::Object& def
|
||||
replace_method = true;
|
||||
}
|
||||
|
||||
if (!obj->is_empty_list() && car(obj).is_symbol(":state")) {
|
||||
obj = cdr(obj);
|
||||
function_typespec = TypeSpec("state");
|
||||
}
|
||||
|
||||
if (!obj->is_empty_list() && car(obj).is_symbol(":behavior")) {
|
||||
obj = cdr(obj);
|
||||
function_typespec.add_new_tag("behavior", symbol_string(obj->as_pair()->car));
|
||||
|
||||
@@ -11,5 +11,74 @@ TypeSpec state_to_go_function(const TypeSpec& state_type) {
|
||||
}
|
||||
|
||||
arg_types.push_back(TypeSpec("none")); // none for the return.
|
||||
return TypeSpec("function", arg_types);
|
||||
auto result = TypeSpec("function", arg_types);
|
||||
result.add_new_tag("behavior", state_type.last_arg().base_type());
|
||||
return result;
|
||||
}
|
||||
|
||||
StateHandler handler_name_to_kind(const std::string& name) {
|
||||
if (name == "enter") {
|
||||
return StateHandler::ENTER;
|
||||
} else if (name == "exit") {
|
||||
return StateHandler::EXIT;
|
||||
} else if (name == "code") {
|
||||
return StateHandler::CODE;
|
||||
} else if (name == "event") {
|
||||
return StateHandler::EVENT;
|
||||
} else if (name == "trans") {
|
||||
return StateHandler::TRANS;
|
||||
} else if (name == "post") {
|
||||
return StateHandler::POST;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
std::string handler_kind_to_name(StateHandler kind) {
|
||||
switch (kind) {
|
||||
case StateHandler::ENTER:
|
||||
return "enter";
|
||||
case StateHandler::EXIT:
|
||||
return "exit";
|
||||
case StateHandler::CODE:
|
||||
return "code";
|
||||
case StateHandler::EVENT:
|
||||
return "event";
|
||||
case StateHandler::TRANS:
|
||||
return "trans";
|
||||
case StateHandler::POST:
|
||||
return "post";
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
TypeSpec get_state_handler_type(const std::string& handler_name, const TypeSpec& state_type) {
|
||||
return get_state_handler_type(handler_name_to_kind(handler_name), state_type);
|
||||
}
|
||||
|
||||
TypeSpec get_state_handler_type(StateHandler kind, const TypeSpec& state_type) {
|
||||
TypeSpec result;
|
||||
switch (kind) {
|
||||
case StateHandler::CODE:
|
||||
case StateHandler::ENTER:
|
||||
result = state_to_go_function(state_type);
|
||||
break;
|
||||
|
||||
case StateHandler::TRANS:
|
||||
case StateHandler::POST:
|
||||
case StateHandler::EXIT:
|
||||
result = TypeSpec("function", {TypeSpec("none")});
|
||||
break;
|
||||
|
||||
case StateHandler::EVENT:
|
||||
result = TypeSpec("function", {TypeSpec("process"), TypeSpec("int"), TypeSpec("symbol"),
|
||||
TypeSpec("event-message-block"), TypeSpec("object")});
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
result.add_or_modify_tag("behavior", state_type.last_arg().base_type());
|
||||
return result;
|
||||
}
|
||||
@@ -6,4 +6,10 @@
|
||||
* This contains type system utilities related to state and process
|
||||
*/
|
||||
|
||||
enum class StateHandler { ENTER, EXIT, CODE, TRANS, POST, EVENT };
|
||||
|
||||
TypeSpec state_to_go_function(const TypeSpec& state_type);
|
||||
StateHandler handler_name_to_kind(const std::string& name);
|
||||
std::string handler_kind_to_name(StateHandler kind);
|
||||
TypeSpec get_state_handler_type(const std::string& handler_name, const TypeSpec& state_type);
|
||||
TypeSpec get_state_handler_type(StateHandler kind, const TypeSpec& state_type);
|
||||
@@ -6,6 +6,7 @@ add_library(
|
||||
analysis/cfg_builder.cpp
|
||||
analysis/expression_build.cpp
|
||||
analysis/final_output.cpp
|
||||
analysis/find_defstates.cpp
|
||||
analysis/inline_asm_rewrite.cpp
|
||||
analysis/insert_lets.cpp
|
||||
analysis/reg_usage.cpp
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "common/type_system/TypeSpec.h"
|
||||
#include "decompiler/config.h"
|
||||
#include "Warnings.h"
|
||||
#include "common/type_system/state.h"
|
||||
|
||||
namespace decompiler {
|
||||
class DecompilerTypeSystem;
|
||||
@@ -24,11 +25,15 @@ struct FunctionName {
|
||||
UNIDENTIFIED, // hasn't been identified yet.
|
||||
GLOBAL, // global named function
|
||||
METHOD,
|
||||
TOP_LEVEL_INIT,
|
||||
NV_STATE,
|
||||
V_STATE,
|
||||
TOP_LEVEL_INIT
|
||||
} kind = FunctionKind::UNIDENTIFIED;
|
||||
|
||||
std::string function_name; // only applicable for GLOBAL
|
||||
std::string type_name; // only applicable for METHOD
|
||||
std::string type_name; // only applicable for METHOD or v state
|
||||
std::string state_name; // for nv state or v state
|
||||
StateHandler handler_kind; // for nv state or v state
|
||||
int method_id = -1; // only applicable for METHOD
|
||||
int unique_id = -1;
|
||||
|
||||
@@ -45,6 +50,10 @@ struct FunctionName {
|
||||
return "(top-level-login " + object_name + ")";
|
||||
case FunctionKind::UNIDENTIFIED:
|
||||
return "(anon-function " + std::to_string(id_in_object) + " " + object_name + ")";
|
||||
case FunctionKind::NV_STATE:
|
||||
return fmt::format("({} {})", handler_kind_to_name(handler_kind), state_name);
|
||||
case FunctionKind::V_STATE:
|
||||
return fmt::format("({} {} {})", handler_kind_to_name(handler_kind), state_name, type_name);
|
||||
default:
|
||||
throw std::runtime_error("Unsupported FunctionKind");
|
||||
}
|
||||
@@ -72,6 +81,19 @@ struct FunctionName {
|
||||
type_name = std::move(tn);
|
||||
method_id = id;
|
||||
}
|
||||
|
||||
void set_as_nv_state(const std::string& state, StateHandler hk) {
|
||||
state_name = state;
|
||||
handler_kind = hk;
|
||||
kind = FunctionKind::NV_STATE;
|
||||
}
|
||||
|
||||
void set_as_v_state(const std::string& type, const std::string& state, StateHandler hk) {
|
||||
state_name = state;
|
||||
handler_kind = hk;
|
||||
kind = FunctionKind::V_STATE;
|
||||
type_name = type;
|
||||
}
|
||||
};
|
||||
|
||||
class Function {
|
||||
|
||||
@@ -991,7 +991,14 @@ TP_Type LoadVarOp::get_src_type(const TypeState& input,
|
||||
auto rd = dts.ts.reverse_field_lookup(rd_in);
|
||||
|
||||
if (rd.success) {
|
||||
return TP_Type::make_from_ts(coerce_to_reg_type(rd.result_type));
|
||||
if (rd_in.base_type.base_type() == "state" && rd.tokens.size() == 1 &&
|
||||
rd.tokens.front().kind == FieldReverseLookupOutput::Token::Kind::FIELD &&
|
||||
rd.tokens.front().name == "enter" && rd_in.base_type.arg_count() > 0) {
|
||||
// special case for accessing the enter field of state
|
||||
return TP_Type::make_from_ts(state_to_go_function(rd_in.base_type));
|
||||
} else {
|
||||
return TP_Type::make_from_ts(coerce_to_reg_type(rd.result_type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2807,6 +2807,69 @@ void GetSymbolStringPointer::get_modified_regs(RegSet& regs) const {
|
||||
return m_src->get_modified_regs(regs);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// DefstateElement
|
||||
////////////////////////////////
|
||||
|
||||
DefstateElement::DefstateElement(const std::string& process_type,
|
||||
const std::string& state_name,
|
||||
const std::vector<Entry>& entries,
|
||||
bool is_virtual)
|
||||
: m_process_type(process_type),
|
||||
m_state_name(state_name),
|
||||
m_entries(entries),
|
||||
m_is_virtual(is_virtual) {
|
||||
for (auto& e : m_entries) {
|
||||
e.val->parent_element = this;
|
||||
}
|
||||
}
|
||||
|
||||
void DefstateElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
f(this);
|
||||
for (auto& e : m_entries) {
|
||||
e.val->apply(f);
|
||||
}
|
||||
}
|
||||
|
||||
void DefstateElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
for (auto& e : m_entries) {
|
||||
e.val->apply_form(f);
|
||||
}
|
||||
}
|
||||
|
||||
void DefstateElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
for (auto& e : m_entries) {
|
||||
e.val->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DefstateElement::get_modified_regs(RegSet& regs) const {
|
||||
for (auto& e : m_entries) {
|
||||
e.val->get_modified_regs(regs);
|
||||
}
|
||||
}
|
||||
|
||||
goos::Object DefstateElement::to_form_internal(const Env& env) const {
|
||||
std::vector<goos::Object> forms;
|
||||
forms.push_back(pretty_print::to_symbol("defstate"));
|
||||
forms.push_back(pretty_print::to_symbol(m_state_name));
|
||||
forms.push_back(pretty_print::build_list(m_process_type));
|
||||
|
||||
if (m_is_virtual) {
|
||||
forms.push_back(pretty_print::to_symbol(":virtual #t"));
|
||||
}
|
||||
|
||||
for (const auto& e : m_entries) {
|
||||
forms.push_back(pretty_print::to_symbol(fmt::format(":{}", handler_kind_to_name(e.kind))));
|
||||
auto to_print = e.val;
|
||||
forms.push_back(to_print->to_form(env));
|
||||
}
|
||||
|
||||
return pretty_print::build_list(forms);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// Utilities
|
||||
////////////////////////////////
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "common/goos/Object.h"
|
||||
#include "common/type_system/TypeSystem.h"
|
||||
#include "decompiler/Disasm/DecompilerLabel.h"
|
||||
#include "common/type_system/state.h"
|
||||
|
||||
namespace decompiler {
|
||||
class Form;
|
||||
@@ -1353,6 +1354,7 @@ class DecompiledDataElement : public FormElement {
|
||||
void collect_vars(RegAccessSet& vars, bool recursive) const override;
|
||||
void get_modified_regs(RegSet& regs) const override;
|
||||
void do_decomp(const Env& env, const LinkedObjectFile* file);
|
||||
DecompilerLabel label() const { return m_label; }
|
||||
|
||||
private:
|
||||
bool m_decompiled = false;
|
||||
@@ -1566,6 +1568,37 @@ class GetSymbolStringPointer : public FormElement {
|
||||
Form* m_src = nullptr;
|
||||
};
|
||||
|
||||
class DefstateElement : public FormElement {
|
||||
public:
|
||||
struct Entry {
|
||||
StateHandler kind;
|
||||
Form* val = nullptr;
|
||||
bool is_behavior = false;
|
||||
};
|
||||
DefstateElement(const std::string& process_type,
|
||||
const std::string& state_name,
|
||||
const std::vector<Entry>& entries,
|
||||
bool is_virtual);
|
||||
|
||||
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;
|
||||
void collect_vars(RegAccessSet& vars, bool recursive) const override;
|
||||
void update_from_stack(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects) override;
|
||||
void get_modified_regs(RegSet& regs) const override;
|
||||
std::vector<Entry>& entries() { return m_entries; }
|
||||
|
||||
private:
|
||||
std::string m_process_type;
|
||||
std::string m_state_name;
|
||||
std::vector<Entry> m_entries;
|
||||
bool m_is_virtual = false;
|
||||
};
|
||||
|
||||
/*!
|
||||
* A Form is a wrapper around one or more FormElements.
|
||||
* This is done for two reasons:
|
||||
|
||||
@@ -2602,6 +2602,22 @@ void FunctionCallElement::update_from_stack(const Env& env,
|
||||
FormElement* new_form = nullptr;
|
||||
|
||||
if (go_next_state) {
|
||||
// see if we're a virtual go
|
||||
Matcher virtual_go_state_matcher =
|
||||
Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::METHOD_OF_OBJECT),
|
||||
{Matcher::any(0), Matcher::any_constant_token(1)});
|
||||
auto virtual_go_mr = match(virtual_go_state_matcher, go_next_state);
|
||||
if (virtual_go_mr.matched && virtual_go_mr.maps.forms.at(0)->to_string(env) == "self") {
|
||||
arg_forms.insert(arg_forms.begin(), pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, virtual_go_mr.maps.strings.at(1)));
|
||||
auto go_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, "go-virtual")),
|
||||
arg_forms);
|
||||
result->push_back(go_form);
|
||||
return;
|
||||
}
|
||||
|
||||
arg_forms.insert(arg_forms.begin(), go_next_state);
|
||||
auto go_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_function(
|
||||
@@ -4888,6 +4904,15 @@ void GetSymbolStringPointer::update_from_stack(const Env&,
|
||||
result->push_back(this);
|
||||
}
|
||||
|
||||
void DefstateElement::update_from_stack(const Env&,
|
||||
FormPool&,
|
||||
FormStack&,
|
||||
std::vector<FormElement*>* result,
|
||||
bool) {
|
||||
mark_popped();
|
||||
result->push_back(this);
|
||||
}
|
||||
|
||||
void LabelElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
|
||||
mark_popped();
|
||||
stack.push_form_element(this, true);
|
||||
|
||||
@@ -103,6 +103,21 @@ Function& LinkedObjectFile::get_function_at_label(int label_id) {
|
||||
/*!
|
||||
* Get the function starting at this label, or nullptr if there is none.
|
||||
*/
|
||||
Function* LinkedObjectFile::try_get_function_at_label(int label_id) {
|
||||
const auto& label = labels.at(label_id);
|
||||
return try_get_function_at_label(label);
|
||||
}
|
||||
|
||||
Function* LinkedObjectFile::try_get_function_at_label(const DecompilerLabel& label) {
|
||||
for (auto& func : functions_by_seg.at(label.target_segment)) {
|
||||
// + 4 to skip past type tag to the first word, which is were the label points.
|
||||
if (func.start_word * 4 + 4 == label.offset) {
|
||||
return &func;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Function* LinkedObjectFile::try_get_function_at_label(int label_id) const {
|
||||
const auto& label = labels.at(label_id);
|
||||
return try_get_function_at_label(label);
|
||||
@@ -115,7 +130,6 @@ const Function* LinkedObjectFile::try_get_function_at_label(const DecompilerLabe
|
||||
return &func;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,9 @@ class LinkedObjectFile {
|
||||
LinkedWord::Kind kind);
|
||||
void symbol_link_offset(int source_segment, int source_offset, const char* name);
|
||||
Function& get_function_at_label(int label_id);
|
||||
Function* try_get_function_at_label(int label_id);
|
||||
Function* try_get_function_at_label(const DecompilerLabel& label);
|
||||
|
||||
const Function* try_get_function_at_label(int label_id) const;
|
||||
const Function* try_get_function_at_label(const DecompilerLabel& label) const;
|
||||
std::string get_label_name(int label_id) const;
|
||||
|
||||
@@ -67,20 +67,21 @@ class ObjectFileDB {
|
||||
const Config& config,
|
||||
bool skip_debug_output = false);
|
||||
void ir2_top_level_pass(const Config& config);
|
||||
void ir2_stack_spill_slot_pass();
|
||||
void ir2_basic_block_pass(const Config& config);
|
||||
void ir2_atomic_op_pass(const Config& config);
|
||||
void ir2_type_analysis_pass(const Config& config);
|
||||
void ir2_register_usage_pass();
|
||||
void ir2_variable_pass();
|
||||
void ir2_cfg_build_pass();
|
||||
void ir2_store_current_forms();
|
||||
void ir2_build_expressions(const Config& config);
|
||||
void ir2_insert_lets();
|
||||
void ir2_rewrite_inline_asm_instructions();
|
||||
void ir2_insert_anonymous_functions();
|
||||
void ir2_stack_spill_slot_pass(int seg);
|
||||
void ir2_basic_block_pass(int seg, const Config& config);
|
||||
void ir2_atomic_op_pass(int seg, const Config& config);
|
||||
void ir2_type_analysis_pass(int seg, const Config& config);
|
||||
void ir2_register_usage_pass(int seg);
|
||||
void ir2_variable_pass(int seg);
|
||||
void ir2_cfg_build_pass(int seg);
|
||||
void ir2_store_current_forms(int seg);
|
||||
void ir2_build_expressions(int seg, const Config& config);
|
||||
void ir2_insert_lets(int seg);
|
||||
void ir2_rewrite_inline_asm_instructions(int seg);
|
||||
void ir2_insert_anonymous_functions(int seg);
|
||||
void ir2_symbol_definition_map(const std::string& output_dir);
|
||||
void ir2_write_results(const std::string& output_dir, const Config& config);
|
||||
void ir2_do_common_segment_analysis(int seg, const Config& config);
|
||||
std::string ir2_to_file(ObjectFileData& data, const Config& config);
|
||||
std::string ir2_function_to_string(ObjectFileData& data, Function& function, int seg);
|
||||
std::string ir2_final_out(ObjectFileData& data,
|
||||
@@ -153,6 +154,17 @@ class ObjectFileDB {
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
void for_each_function_in_seg(int seg, Func f) {
|
||||
for_each_obj([&](ObjectFileData& data) {
|
||||
int fn = 0;
|
||||
for (size_t j = data.linked_data.functions_by_seg.at(seg).size(); j-- > 0;) {
|
||||
f(data.linked_data.functions_by_seg.at(seg).at(j), data);
|
||||
fn++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Danger: after adding all object files, we assume that the vector never reallocates.
|
||||
std::unordered_map<std::string, std::vector<ObjectFileData>> obj_files_by_name;
|
||||
std::unordered_map<std::string, std::vector<ObjectFileRecord>> obj_files_by_dgo;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "decompiler/analysis/type_analysis.h"
|
||||
#include "decompiler/analysis/reg_usage.h"
|
||||
#include "decompiler/analysis/insert_lets.h"
|
||||
#include "decompiler/analysis/find_defstates.h"
|
||||
#include "decompiler/analysis/variable_naming.h"
|
||||
#include "decompiler/analysis/cfg_builder.h"
|
||||
#include "decompiler/analysis/final_output.h"
|
||||
@@ -33,45 +34,40 @@ namespace decompiler {
|
||||
void ObjectFileDB::analyze_functions_ir2(const std::string& output_dir,
|
||||
const Config& config,
|
||||
bool skip_debug_output) {
|
||||
(void)skip_debug_output;
|
||||
// First, do basic analysis on the top level:
|
||||
lg::info("Using IR2 analysis...");
|
||||
lg::info("Processing top-level functions...");
|
||||
ir2_top_level_pass(config);
|
||||
lg::info("Processing basic blocks and control flow graph...");
|
||||
ir2_basic_block_pass(config);
|
||||
lg::info("Finding stack spills...");
|
||||
ir2_stack_spill_slot_pass();
|
||||
lg::info("Converting to atomic ops...");
|
||||
ir2_atomic_op_pass(config);
|
||||
|
||||
ir2_do_common_segment_analysis(TOP_LEVEL_SEGMENT, config);
|
||||
|
||||
for_each_obj([&](ObjectFileData& data) {
|
||||
try {
|
||||
run_defstate(data.linked_data.functions_by_seg.at(2).front());
|
||||
} catch (const std::exception& e) {
|
||||
lg::error("Failed to find defstates: {}", e.what());
|
||||
}
|
||||
});
|
||||
|
||||
ir2_do_common_segment_analysis(DEBUG_SEGMENT, config);
|
||||
ir2_do_common_segment_analysis(MAIN_SEGMENT, config);
|
||||
|
||||
if (config.generate_symbol_definition_map) {
|
||||
lg::info("Generating symbol definition map...");
|
||||
ir2_symbol_definition_map(output_dir);
|
||||
}
|
||||
|
||||
lg::info("Running type analysis...");
|
||||
ir2_type_analysis_pass(config);
|
||||
lg::info("Register usage analysis...");
|
||||
ir2_register_usage_pass();
|
||||
lg::info("Variable analysis...");
|
||||
ir2_variable_pass();
|
||||
lg::info("Initial structuring...");
|
||||
ir2_cfg_build_pass();
|
||||
|
||||
if (!skip_debug_output) {
|
||||
lg::info("Storing temporary form result...");
|
||||
ir2_store_current_forms();
|
||||
}
|
||||
|
||||
lg::info("Expression building...");
|
||||
ir2_build_expressions(config);
|
||||
lg::info("Re-writing inline asm instructions...");
|
||||
ir2_rewrite_inline_asm_instructions();
|
||||
|
||||
lg::info("Inserting lets...");
|
||||
ir2_insert_lets();
|
||||
// if (!skip_debug_output) {
|
||||
// lg::info("Storing temporary form result...");
|
||||
// ir2_store_current_forms();
|
||||
// }
|
||||
|
||||
lg::info("Inserting anonymous function definitions...");
|
||||
ir2_insert_anonymous_functions();
|
||||
|
||||
ir2_insert_anonymous_functions(DEBUG_SEGMENT);
|
||||
ir2_insert_anonymous_functions(MAIN_SEGMENT);
|
||||
ir2_insert_anonymous_functions(TOP_LEVEL_SEGMENT);
|
||||
|
||||
if (!output_dir.empty()) {
|
||||
lg::info("Writing results...");
|
||||
@@ -79,6 +75,31 @@ void ObjectFileDB::analyze_functions_ir2(const std::string& output_dir,
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectFileDB::ir2_do_common_segment_analysis(int seg, const Config& config) {
|
||||
lg::info("Processing basic blocks and control flow graph...");
|
||||
ir2_basic_block_pass(seg, config);
|
||||
lg::info("Finding stack spills...");
|
||||
ir2_stack_spill_slot_pass(seg);
|
||||
lg::info("Converting to atomic ops...");
|
||||
ir2_atomic_op_pass(seg, config);
|
||||
lg::info("Running type analysis...");
|
||||
ir2_type_analysis_pass(seg, config);
|
||||
lg::info("Register usage analysis...");
|
||||
ir2_register_usage_pass(seg);
|
||||
lg::info("Variable analysis...");
|
||||
ir2_variable_pass(seg);
|
||||
lg::info("Initial structuring...");
|
||||
ir2_cfg_build_pass(seg);
|
||||
|
||||
lg::info("Expression building...");
|
||||
ir2_build_expressions(seg, config);
|
||||
lg::info("Re-writing inline asm instructions...");
|
||||
ir2_rewrite_inline_asm_instructions(seg);
|
||||
|
||||
lg::info("Inserting lets...");
|
||||
ir2_insert_lets(seg);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Analyze the top level function of each object.
|
||||
* - Find global function definitions
|
||||
@@ -146,6 +167,13 @@ void ObjectFileDB::ir2_top_level_pass(const Config& config) {
|
||||
|
||||
unique_names.insert(name);
|
||||
|
||||
TypeSpec ts;
|
||||
if (lookup_function_type(func.guessed_name, data.to_unique_name(), config, &ts)) {
|
||||
func.type = ts;
|
||||
} else {
|
||||
func.type = TypeSpec("function");
|
||||
}
|
||||
|
||||
if (config.hacks.asm_functions_by_name.find(name) !=
|
||||
config.hacks.asm_functions_by_name.end()) {
|
||||
func.warnings.info("Flagged as asm by config");
|
||||
@@ -180,7 +208,7 @@ void ObjectFileDB::ir2_top_level_pass(const Config& config) {
|
||||
* - Analyze prologue and epilogue
|
||||
* - Build control flow graph
|
||||
*/
|
||||
void ObjectFileDB::ir2_basic_block_pass(const Config& config) {
|
||||
void ObjectFileDB::ir2_basic_block_pass(int seg, const Config& config) {
|
||||
Timer timer;
|
||||
// Main Pass over each function...
|
||||
int total_basic_blocks = 0;
|
||||
@@ -190,14 +218,14 @@ void ObjectFileDB::ir2_basic_block_pass(const Config& config) {
|
||||
int suspected_asm = 0;
|
||||
int failed_to_build_cfg = 0;
|
||||
|
||||
for_each_function_def_order([&](Function& func, int segment_id, ObjectFileData& data) {
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData& data) {
|
||||
total_functions++;
|
||||
func.ir2.env.file = &data.linked_data;
|
||||
func.ir2.env.dts = &dts;
|
||||
func.ir2.env.func = &func;
|
||||
|
||||
// first, find basic blocks.
|
||||
auto blocks = find_blocks_in_function(data.linked_data, segment_id, func);
|
||||
auto blocks = find_blocks_in_function(data.linked_data, seg, func);
|
||||
total_basic_blocks += blocks.size();
|
||||
if (blocks.size() == 1) {
|
||||
functions_with_one_block++;
|
||||
@@ -232,7 +260,7 @@ void ObjectFileDB::ir2_basic_block_pass(const Config& config) {
|
||||
asm_br_blocks = asm_lookup->second;
|
||||
}
|
||||
|
||||
func.cfg = build_cfg(data.linked_data, segment_id, func, hack, asm_br_blocks);
|
||||
func.cfg = build_cfg(data.linked_data, seg, func, hack, asm_br_blocks);
|
||||
if (!func.cfg->is_fully_resolved()) {
|
||||
lg::warn("Function {} from {} failed to build control flow graph!",
|
||||
func.guessed_name.to_string(), data.to_unique_name());
|
||||
@@ -260,11 +288,11 @@ void ObjectFileDB::ir2_basic_block_pass(const Config& config) {
|
||||
100.f * inspect_methods / total_functions);
|
||||
}
|
||||
|
||||
void ObjectFileDB::ir2_stack_spill_slot_pass() {
|
||||
void ObjectFileDB::ir2_stack_spill_slot_pass(int seg) {
|
||||
Timer timer;
|
||||
int functions_with_spills = 0;
|
||||
int total_slots = 0;
|
||||
for_each_function_def_order([&](Function& func, int, ObjectFileData&) {
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData&) {
|
||||
if (!func.cfg_ok) {
|
||||
return;
|
||||
}
|
||||
@@ -288,16 +316,15 @@ void ObjectFileDB::ir2_stack_spill_slot_pass() {
|
||||
* Conversion of MIPS instructions into AtomicOps. The AtomicOps represent what we
|
||||
* think are IR of the original GOAL compiler.
|
||||
*/
|
||||
void ObjectFileDB::ir2_atomic_op_pass(const Config& config) {
|
||||
void ObjectFileDB::ir2_atomic_op_pass(int seg, const Config& config) {
|
||||
Timer timer;
|
||||
int total_functions = 0;
|
||||
int attempted = 0;
|
||||
int successful = 0;
|
||||
for_each_function_def_order([&](Function& func, int segment_id, ObjectFileData& data) {
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData& data) {
|
||||
if (!func.cfg_ok) {
|
||||
return;
|
||||
}
|
||||
(void)segment_id;
|
||||
total_functions++;
|
||||
if (!func.suspected_asm) {
|
||||
func.ir2.atomic_ops_attempted = true;
|
||||
@@ -363,15 +390,14 @@ Value try_lookup(const std::unordered_map<Key, Value>& map, const Key& key) {
|
||||
* - Propagate types.
|
||||
* - NOTE: this will update register info usage more accurately for functions.
|
||||
*/
|
||||
void ObjectFileDB::ir2_type_analysis_pass(const Config& config) {
|
||||
void ObjectFileDB::ir2_type_analysis_pass(int seg, const Config& config) {
|
||||
Timer timer;
|
||||
int total_functions = 0;
|
||||
int non_asm_functions = 0;
|
||||
int attempted_functions = 0;
|
||||
int successful_functions = 0;
|
||||
|
||||
for_each_function_def_order([&](Function& func, int segment_id, ObjectFileData& data) {
|
||||
(void)segment_id;
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData& data) {
|
||||
total_functions++;
|
||||
if (!func.suspected_asm) {
|
||||
non_asm_functions++;
|
||||
@@ -408,7 +434,7 @@ void ObjectFileDB::ir2_type_analysis_pass(const Config& config) {
|
||||
func.warnings.type_prop_warning("Type analysis failed");
|
||||
}
|
||||
} else {
|
||||
// lg::warn("Function {} didn't know its type", func.guessed_name.to_string());
|
||||
lg::warn("Function {} didn't know its type", func.guessed_name.to_string());
|
||||
func.warnings.type_prop_warning("Function {} has unknown type",
|
||||
func.guessed_name.to_string());
|
||||
}
|
||||
@@ -419,12 +445,11 @@ void ObjectFileDB::ir2_type_analysis_pass(const Config& config) {
|
||||
attempted_functions, non_asm_functions, total_functions, timer.getMs());
|
||||
}
|
||||
|
||||
void ObjectFileDB::ir2_register_usage_pass() {
|
||||
void ObjectFileDB::ir2_register_usage_pass(int seg) {
|
||||
Timer timer;
|
||||
|
||||
int total_funcs = 0, analyzed_funcs = 0;
|
||||
for_each_function_def_order([&](Function& func, int segment_id, ObjectFileData& data) {
|
||||
(void)segment_id;
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData& data) {
|
||||
(void)data;
|
||||
total_funcs++;
|
||||
if (!func.suspected_asm && func.ir2.atomic_ops_succeeded) {
|
||||
@@ -476,12 +501,11 @@ void ObjectFileDB::ir2_register_usage_pass() {
|
||||
total_funcs, timer.getMs());
|
||||
}
|
||||
|
||||
void ObjectFileDB::ir2_variable_pass() {
|
||||
void ObjectFileDB::ir2_variable_pass(int seg) {
|
||||
Timer timer;
|
||||
int attempted = 0;
|
||||
int successful = 0;
|
||||
for_each_function_def_order([&](Function& func, int segment_id, ObjectFileData& data) {
|
||||
(void)segment_id;
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData& data) {
|
||||
(void)data;
|
||||
if (!func.suspected_asm && func.ir2.atomic_ops_succeeded && func.ir2.env.has_type_analysis()) {
|
||||
try {
|
||||
@@ -501,13 +525,12 @@ void ObjectFileDB::ir2_variable_pass() {
|
||||
attempted, timer.getMs());
|
||||
}
|
||||
|
||||
void ObjectFileDB::ir2_cfg_build_pass() {
|
||||
void ObjectFileDB::ir2_cfg_build_pass(int seg) {
|
||||
Timer timer;
|
||||
int total = 0;
|
||||
int attempted = 0;
|
||||
int successful = 0;
|
||||
for_each_function_def_order([&](Function& func, int segment_id, ObjectFileData& data) {
|
||||
(void)segment_id;
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData& data) {
|
||||
(void)data;
|
||||
total++;
|
||||
if (!func.suspected_asm && func.ir2.atomic_ops_succeeded && func.cfg->is_fully_resolved()) {
|
||||
@@ -528,12 +551,11 @@ void ObjectFileDB::ir2_cfg_build_pass() {
|
||||
lg::info("{}/{}/{} cfg build in {:.2f} ms\n", successful, attempted, total, timer.getMs());
|
||||
}
|
||||
|
||||
void ObjectFileDB::ir2_store_current_forms() {
|
||||
void ObjectFileDB::ir2_store_current_forms(int seg) {
|
||||
Timer timer;
|
||||
int total = 0;
|
||||
|
||||
for_each_function_def_order([&](Function& func, int segment_id, ObjectFileData& data) {
|
||||
(void)segment_id;
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData& data) {
|
||||
(void)data;
|
||||
|
||||
if (func.ir2.top_form) {
|
||||
@@ -546,13 +568,12 @@ void ObjectFileDB::ir2_store_current_forms() {
|
||||
lg::info("Stored debug forms for {} functions in {:.2f} ms\n", total, timer.getMs());
|
||||
}
|
||||
|
||||
void ObjectFileDB::ir2_build_expressions(const Config& config) {
|
||||
void ObjectFileDB::ir2_build_expressions(int seg, const Config& config) {
|
||||
Timer timer;
|
||||
int total = 0;
|
||||
int attempted = 0;
|
||||
int successful = 0;
|
||||
for_each_function_def_order([&](Function& func, int segment_id, ObjectFileData& data) {
|
||||
(void)segment_id;
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData& data) {
|
||||
(void)data;
|
||||
total++;
|
||||
if (func.ir2.top_form && func.ir2.env.has_type_analysis() && func.ir2.env.has_local_vars() &&
|
||||
@@ -579,12 +600,12 @@ void ObjectFileDB::ir2_build_expressions(const Config& config) {
|
||||
lg::info("{}/{}/{} expression build in {:.2f} ms\n", successful, attempted, total, timer.getMs());
|
||||
}
|
||||
|
||||
void ObjectFileDB::ir2_insert_lets() {
|
||||
void ObjectFileDB::ir2_insert_lets(int seg) {
|
||||
Timer timer;
|
||||
LetStats combined_stats;
|
||||
int attempted = 0;
|
||||
|
||||
for_each_function_def_order([&](Function& func, int, ObjectFileData&) {
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData&) {
|
||||
if (func.ir2.expressions_succeeded) {
|
||||
attempted++;
|
||||
combined_stats += insert_lets(func, func.ir2.env, *func.ir2.form_pool, func.ir2.top_form);
|
||||
@@ -595,13 +616,12 @@ void ObjectFileDB::ir2_insert_lets() {
|
||||
combined_stats.vars_in_lets, combined_stats.total_vars, timer.getMs());
|
||||
}
|
||||
|
||||
void ObjectFileDB::ir2_rewrite_inline_asm_instructions() {
|
||||
void ObjectFileDB::ir2_rewrite_inline_asm_instructions(int seg) {
|
||||
Timer timer;
|
||||
int total = 0;
|
||||
int attempted = 0;
|
||||
int successful = 0;
|
||||
for_each_function_def_order([&](Function& func, int segment_id, ObjectFileData& data) {
|
||||
(void)segment_id;
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData& data) {
|
||||
(void)data;
|
||||
total++;
|
||||
if (func.ir2.top_form && func.ir2.env.has_type_analysis()) {
|
||||
@@ -617,11 +637,10 @@ void ObjectFileDB::ir2_rewrite_inline_asm_instructions() {
|
||||
timer.getMs());
|
||||
}
|
||||
|
||||
void ObjectFileDB::ir2_insert_anonymous_functions() {
|
||||
void ObjectFileDB::ir2_insert_anonymous_functions(int seg) {
|
||||
Timer timer;
|
||||
int total = 0;
|
||||
for_each_function_def_order([&](Function& func, int segment_id, ObjectFileData& data) {
|
||||
(void)segment_id;
|
||||
for_each_function_in_seg(seg, [&](Function& func, ObjectFileData& data) {
|
||||
(void)data;
|
||||
if (func.ir2.top_form && func.ir2.env.has_type_analysis()) {
|
||||
try {
|
||||
@@ -998,6 +1017,20 @@ bool ObjectFileDB::lookup_function_type(const FunctionName& name,
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (name.kind == FunctionName::FunctionKind::NV_STATE) {
|
||||
auto sym_type = dts.symbol_types.find(name.state_name);
|
||||
if (sym_type == dts.symbol_types.end()) {
|
||||
lg::error("Could not find symbol with name {} for state. This is likely a decompiler bug.",
|
||||
name.state_name);
|
||||
return false;
|
||||
}
|
||||
*result = get_state_handler_type(name.handler_kind, sym_type->second);
|
||||
return true;
|
||||
} else if (name.kind == FunctionName::FunctionKind::V_STATE) {
|
||||
auto mi = dts.ts.lookup_method(name.type_name, name.state_name);
|
||||
*result = get_state_handler_type(name.handler_kind,
|
||||
mi.type.substitute_for_method_call(name.type_name));
|
||||
return true;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,9 @@ bool convert_to_expressions(
|
||||
// set argument names to some reasonable defaults. these will be used if the user doesn't
|
||||
// give us anything more specific.
|
||||
if (f.guessed_name.kind == FunctionName::FunctionKind::GLOBAL ||
|
||||
f.guessed_name.kind == FunctionName::FunctionKind::UNIDENTIFIED) {
|
||||
f.guessed_name.kind == FunctionName::FunctionKind::UNIDENTIFIED ||
|
||||
f.guessed_name.kind == FunctionName::FunctionKind::NV_STATE ||
|
||||
f.guessed_name.kind == FunctionName::FunctionKind::V_STATE) {
|
||||
f.ir2.env.set_remap_for_function(f.type);
|
||||
} else if (f.guessed_name.kind == FunctionName::FunctionKind::METHOD) {
|
||||
auto method_type =
|
||||
|
||||
@@ -62,6 +62,16 @@ goos::Object final_output_lambda(const Function& func) {
|
||||
}
|
||||
}
|
||||
|
||||
goos::Object final_output_defstate_anonymous_behavior(const Function& func) {
|
||||
std::vector<goos::Object> inline_body;
|
||||
func.ir2.top_form->inline_forms(inline_body, func.ir2.env);
|
||||
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));
|
||||
append_body_to_function_definition(&result, inline_body, var_dec, func.type);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string final_defun_out(const Function& func,
|
||||
const Env& env,
|
||||
const DecompilerTypeSystem& dts,
|
||||
@@ -144,6 +154,21 @@ std::string final_defun_out(const Function& func,
|
||||
append_body_to_function_definition(&top_form, inline_body, var_dec, func.type);
|
||||
return pretty_print::to_string(top_form);
|
||||
}
|
||||
|
||||
if (func.guessed_name.kind == FunctionName::FunctionKind::NV_STATE ||
|
||||
func.guessed_name.kind == FunctionName::FunctionKind::V_STATE) {
|
||||
std::vector<goos::Object> top;
|
||||
top.push_back(pretty_print::to_symbol("state-handler"));
|
||||
|
||||
top.push_back(pretty_print::to_symbol(func.guessed_name.to_string()));
|
||||
|
||||
top.push_back(arguments);
|
||||
auto top_form = pretty_print::build_list(top);
|
||||
|
||||
append_body_to_function_definition(&top_form, inline_body, var_dec, func.type);
|
||||
return pretty_print::to_string(top_form);
|
||||
}
|
||||
|
||||
return "nyi";
|
||||
}
|
||||
|
||||
|
||||
@@ -17,4 +17,5 @@ std::string write_from_top_level(const Function& top_level,
|
||||
|
||||
goos::Object get_arg_list_for_function(const Function& func, const Env& env);
|
||||
goos::Object final_output_lambda(const Function& function);
|
||||
goos::Object final_output_defstate_anonymous_behavior(const Function& func);
|
||||
} // namespace decompiler
|
||||
|
||||
@@ -0,0 +1,453 @@
|
||||
|
||||
|
||||
#include "find_defstates.h"
|
||||
#include "decompiler/IR2/Form.h"
|
||||
#include "common/goos/PrettyPrinter.h"
|
||||
#include "decompiler/IR2/GenericElementMatcher.h"
|
||||
#include "decompiler/ObjectFile/LinkedObjectFile.h"
|
||||
#include "common/type_system/state.h"
|
||||
|
||||
namespace decompiler {
|
||||
|
||||
constexpr bool debug_defstates = false;
|
||||
constexpr bool print_renames = false;
|
||||
|
||||
namespace {
|
||||
|
||||
/*!
|
||||
* Given the (set! <the-state> <reg-with-static-state>), returns the name of the state and the
|
||||
* more specific type.
|
||||
*/
|
||||
std::pair<std::string, TypeSpec> get_state_info(FormElement* state_set, const Env& env) {
|
||||
auto sff = dynamic_cast<SetFormFormElement*>(state_set);
|
||||
if (!sff) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Failed to identify defstate. The state symbol set was supposed to be: {}, but "
|
||||
"this doesn't look like a set.",
|
||||
state_set->to_string(env)));
|
||||
}
|
||||
|
||||
auto atom = form_as_atom(sff->dst());
|
||||
if (!atom || atom->get_kind() != SimpleAtom::Kind::SYMBOL_VAL) {
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Failed to identify defstate. The state symbol set was: {}, which doesn't set a symbol",
|
||||
state_set->to_string(env)));
|
||||
}
|
||||
|
||||
std::string state_name = atom->get_str();
|
||||
|
||||
auto type = env.dts->symbol_types.find(state_name);
|
||||
if (type == env.dts->symbol_types.end()) {
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Identified a defstate for state {}, but there is no type information for this state.",
|
||||
state_name));
|
||||
}
|
||||
|
||||
if (type->second.base_type() != "state") {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Identified a defstate for state {}, but our type information thinks it is a "
|
||||
"{}, not a state.",
|
||||
type->second.print()));
|
||||
}
|
||||
|
||||
if (type->second.arg_count() == 0) {
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Identified a defstate for state {}, but there is no argument information.", state_name));
|
||||
}
|
||||
|
||||
if (type->second.last_arg() == TypeSpec("none")) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Identified a defstate for state {}, but the process type is none. You must "
|
||||
"provide a process type as the final argument of a state",
|
||||
state_name));
|
||||
}
|
||||
|
||||
return {atom->get_str(), type->second};
|
||||
}
|
||||
|
||||
std::vector<DefstateElement::Entry> get_defstate_entries(
|
||||
Form* body,
|
||||
int body_index,
|
||||
const Env& env,
|
||||
const std::string& state_name,
|
||||
const RegisterAccess& let_dest_var,
|
||||
const TypeSpec& state_type,
|
||||
FormPool& pool,
|
||||
const std::optional<std::string>& virtual_child = {}) {
|
||||
std::vector<DefstateElement::Entry> entries;
|
||||
|
||||
// next, all the handlers
|
||||
for (; body_index < body->size(); body_index++) {
|
||||
DefstateElement::Entry this_entry;
|
||||
auto matcher =
|
||||
Matcher::set(Matcher::deref(Matcher::any_reg(0), false, {DerefTokenMatcher::any_string(1)}),
|
||||
Matcher::any(2));
|
||||
Form temp;
|
||||
temp.elts().push_back(body->at(body_index));
|
||||
auto mr = match(matcher, &temp);
|
||||
|
||||
if (!mr.matched) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("In defstate for state {}, failed to recognize handler set: {}", state_name,
|
||||
temp.to_string(env)));
|
||||
}
|
||||
|
||||
auto var = mr.maps.regs.at(0);
|
||||
auto name = mr.maps.strings.at(1);
|
||||
auto val = mr.maps.forms.at(2);
|
||||
|
||||
auto handler_kind = handler_name_to_kind(name);
|
||||
while (val->try_as_element<CastElement>()) {
|
||||
val = val->try_as_element<CastElement>()->source();
|
||||
}
|
||||
this_entry.val = val;
|
||||
this_entry.kind = handler_kind;
|
||||
this_entry.is_behavior = false;
|
||||
|
||||
if (!var || env.get_variable_name(*var) != env.get_variable_name(let_dest_var)) {
|
||||
if (var) {
|
||||
throw std::runtime_error(fmt::format("Messed up defstate. State is in {}, but we set {}",
|
||||
env.get_variable_name(let_dest_var),
|
||||
env.get_variable_name(*var)));
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_defstates) {
|
||||
fmt::print("SET: {} to {}\n", name, val->to_string(env));
|
||||
}
|
||||
|
||||
// now we try to find a function
|
||||
|
||||
auto handler_atom = form_as_atom(val);
|
||||
if (handler_atom && handler_atom->is_label()) {
|
||||
auto handler_func = env.file->try_get_function_at_label(handler_atom->label());
|
||||
if (!handler_func) {
|
||||
throw std::runtime_error("Failed to find handler function.");
|
||||
}
|
||||
|
||||
this_entry.is_behavior = true;
|
||||
if (print_renames) {
|
||||
fmt::print("RENAME: {} to ", handler_func->guessed_name.to_string());
|
||||
}
|
||||
|
||||
if (virtual_child) {
|
||||
handler_func->guessed_name.set_as_v_state(*virtual_child, state_name, handler_kind);
|
||||
} else {
|
||||
handler_func->guessed_name.set_as_nv_state(state_name, handler_kind);
|
||||
}
|
||||
if (print_renames) {
|
||||
fmt::print("{}\n", handler_func->guessed_name.to_string());
|
||||
}
|
||||
|
||||
// scary part - modify the function type!
|
||||
handler_func->type = get_state_handler_type(handler_kind, state_type);
|
||||
} else if (handler_atom && handler_atom->is_sym_val()) {
|
||||
auto sym_type = env.dts->lookup_symbol_type(handler_atom->get_str());
|
||||
auto expected_type = get_state_handler_type(handler_kind, state_type);
|
||||
if (!env.dts->ts.tc(expected_type, sym_type)) {
|
||||
this_entry.val =
|
||||
pool.alloc_single_element_form<CastElement>(nullptr, expected_type, this_entry.val);
|
||||
}
|
||||
}
|
||||
entries.push_back(this_entry);
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
FormElement* rewrite_nonvirtual_defstate(LetElement* elt,
|
||||
const Env& env,
|
||||
const std::string& expected_state_name,
|
||||
FormPool& pool) {
|
||||
// first thing in the body should be something like:
|
||||
// (set! teetertotter-idle (the-as (state none) v1-3))
|
||||
assert(elt->body()->size() > 0);
|
||||
int body_index = 0;
|
||||
|
||||
// the setup
|
||||
auto first_in_body = elt->body()->at(body_index);
|
||||
auto info = get_state_info(first_in_body, env);
|
||||
if (info.first != expected_state_name) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Inconsistent defstate name. code has {}, static state has {}", info.first,
|
||||
expected_state_name));
|
||||
}
|
||||
if (debug_defstates) {
|
||||
fmt::print("State: {} Type: {}\n", info.first, info.second.print());
|
||||
}
|
||||
body_index++;
|
||||
|
||||
auto entries = get_defstate_entries(elt->body(), body_index, env, info.first,
|
||||
elt->entries().at(0).dest, info.second, pool);
|
||||
|
||||
return pool.alloc_element<DefstateElement>(info.second.last_arg().base_type(), info.first,
|
||||
entries, false);
|
||||
}
|
||||
|
||||
struct VirtualStateInfo {
|
||||
TypeSpec type_from_ts;
|
||||
};
|
||||
|
||||
FormElement* strip_cast(FormElement* in) {
|
||||
auto casted = dynamic_cast<CastElement*>(in);
|
||||
while (casted) {
|
||||
in = casted->source()->try_as_single_element();
|
||||
casted = dynamic_cast<CastElement*>(in);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
std::string verify_empty_state_and_get_name(DecompiledDataElement* state, const Env& env) {
|
||||
auto lab = state->label();
|
||||
// should have:
|
||||
/*
|
||||
.type state
|
||||
L25:
|
||||
.symbol teetertotter-launch
|
||||
.symbol #f
|
||||
.symbol #f
|
||||
.symbol #f
|
||||
.symbol #f
|
||||
.symbol #f
|
||||
.symbol #f
|
||||
.symbol #f
|
||||
*/
|
||||
|
||||
int start_word_idx = (lab.offset / 4) - 1;
|
||||
auto& words = env.file->words_by_seg.at(lab.target_segment);
|
||||
|
||||
auto first_word = words.at(start_word_idx);
|
||||
if (first_word.kind != LinkedWord::TYPE_PTR || first_word.symbol_name != "state") {
|
||||
throw std::runtime_error("Reference to state bad: invalid type pointer");
|
||||
}
|
||||
|
||||
auto name_word = words.at(start_word_idx + 1);
|
||||
if (name_word.kind != LinkedWord::SYM_PTR) {
|
||||
throw std::runtime_error("Reference to state bad: invalid name");
|
||||
}
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
auto& word = words.at(start_word_idx + 2 + i);
|
||||
if (word.kind != LinkedWord::SYM_PTR || word.symbol_name != "#f") {
|
||||
throw std::runtime_error("Reference to state bad: got a non #f in the initial fields");
|
||||
}
|
||||
}
|
||||
|
||||
return name_word.symbol_name;
|
||||
}
|
||||
|
||||
FormElement* rewrite_virtual_defstate(LetElement* elt,
|
||||
const Env& env,
|
||||
const std::string& expected_state_name,
|
||||
FormPool& pool) {
|
||||
assert(elt->body()->size() > 1);
|
||||
// variable at the top of let, contains the static state with name exptected_state_name
|
||||
auto state_var_from_let_def = elt->entries().at(0).dest;
|
||||
// our index into the let body
|
||||
int body_idx = 0;
|
||||
|
||||
// see if the first thing is an inherit-state.
|
||||
auto maybe_inherit_form = elt->body()->at(body_idx);
|
||||
// fmt::print("first is {}\n", maybe_inherit_form->to_string(env));
|
||||
Form temp;
|
||||
temp.elts().push_back(maybe_inherit_form);
|
||||
// (inherit-state gp-1 (method-of-type plat-button dummy-24))
|
||||
auto inherit_matcher = Matcher::op(GenericOpMatcher::func(Matcher::symbol("inherit-state")),
|
||||
{Matcher::any_reg(0), Matcher::any(1)});
|
||||
|
||||
struct InheritInfo {
|
||||
std::string parent_type_name;
|
||||
std::string method_name;
|
||||
};
|
||||
std::optional<InheritInfo> inherit_info;
|
||||
|
||||
auto inherit_mr = match(inherit_matcher, &temp);
|
||||
if (!inherit_mr.matched) {
|
||||
// no inherit. This means that we should be the first in the type tree to define this state.
|
||||
inherit_info = {};
|
||||
} else {
|
||||
// found the inherit. advance body_idx so we move on to the next form.
|
||||
body_idx++;
|
||||
|
||||
// expect this to match the variable in the top let
|
||||
auto state_var = *inherit_mr.maps.regs.at(0);
|
||||
// this expression should be the thing we inherit from.
|
||||
auto parent_state = inherit_mr.maps.forms.at(1);
|
||||
|
||||
if (env.get_variable_name(state_var_from_let_def) != env.get_variable_name(state_var)) {
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Variable name disagreement in virtual defstate: began with {}, but did method "
|
||||
"set using {}",
|
||||
env.get_variable_name(state_var_from_let_def), env.get_variable_name(state_var)));
|
||||
}
|
||||
|
||||
// if there's a cast here, it probably means that there's no :state in the deftype.
|
||||
// let's warn here instead of trying to go on.
|
||||
auto parent_state_cast = parent_state->try_as_element<CastElement>();
|
||||
if (parent_state_cast) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("virtual defstate attempted on something that isn't a state: {}\nDid you "
|
||||
"forget to put :state in the method definition?",
|
||||
parent_state_cast->to_string(env)));
|
||||
}
|
||||
|
||||
// identify the (method-of-type ...) form that grabs the parent state.
|
||||
auto mot_matcher = Matcher::op(GenericOpMatcher::fixed(FixedOperatorKind::METHOD_OF_TYPE),
|
||||
{Matcher::any_symbol(0), Matcher::any_constant_token(1)});
|
||||
auto mot_mr = match(mot_matcher, parent_state);
|
||||
if (!mot_mr.matched) {
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Failed to recognize virtual defstate. Got a {} as the parent to inherit from.",
|
||||
parent_state->to_string(env)));
|
||||
}
|
||||
|
||||
inherit_info = {{mot_mr.maps.strings.at(0), mot_mr.maps.strings.at(1)}};
|
||||
}
|
||||
|
||||
// checks to check: method type is a state
|
||||
// if inherit matches expected.
|
||||
|
||||
// next, find (method-set! sunken-elevator 22 (the-as function gp-0))
|
||||
auto method_set_form = elt->body()->at(body_idx);
|
||||
temp = Form();
|
||||
temp.elts().push_back(method_set_form);
|
||||
auto mset_matcher =
|
||||
Matcher::op(GenericOpMatcher::func(Matcher::symbol("method-set!")),
|
||||
{Matcher::any_symbol(0), Matcher::any_integer(1), Matcher::any(2)});
|
||||
auto mset_mr = match(mset_matcher, &temp);
|
||||
if (!mset_mr.matched) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Failed to recognize virtual defstate. Got a {} as the second thing, but was "
|
||||
"expecting method-set! call",
|
||||
temp.to_string(env)));
|
||||
}
|
||||
|
||||
// the actual type that gets this as a state
|
||||
auto type_name = mset_mr.maps.strings.at(0);
|
||||
auto method_id = mset_mr.maps.ints.at(1);
|
||||
|
||||
// should be the state again.
|
||||
auto val = strip_cast(mset_mr.maps.forms.at(2)->try_as_single_element());
|
||||
if (val->to_string(env) != env.get_variable_name(state_var_from_let_def)) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Variable name disagreement in virtual defstate: began with {}, but did method "
|
||||
"set using {}",
|
||||
val->to_string(env), env.get_variable_name(state_var_from_let_def)));
|
||||
}
|
||||
|
||||
// we should double check that the type in the defstate is correct
|
||||
auto method_info = env.dts->ts.lookup_method(type_name, method_id);
|
||||
if (method_info.type.base_type() != "state" ||
|
||||
method_info.type.last_arg().base_type() != "_type_") {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Virtual defstate is defining a virtual state in method {} of {}, but the type "
|
||||
"of this method is {}, which is not a valid virtual state type (must be "
|
||||
"\"(state ... _type_)\")",
|
||||
method_info.name, type_name, method_info.type.print()));
|
||||
}
|
||||
|
||||
{
|
||||
MethodInfo parent_method_info;
|
||||
auto parent_type_name = env.dts->ts.lookup_type(type_name)->get_parent();
|
||||
if (env.dts->ts.try_lookup_method(parent_type_name, method_info.name, &parent_method_info)) {
|
||||
if (!inherit_info) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Virtual defstate for state {} in type {}: the state was defined in the "
|
||||
"parent but wasn't inherited.",
|
||||
expected_state_name, type_name));
|
||||
}
|
||||
} else {
|
||||
if (inherit_info) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Virtual defstate for state {} in type {}: the state wasn't defined in the "
|
||||
"parent but was inherited.",
|
||||
expected_state_name, type_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// checks: parent_type_name is the parent
|
||||
if (inherit_info) {
|
||||
auto child_type_info = env.dts->ts.lookup_type(type_name);
|
||||
if (child_type_info->get_parent() != inherit_info->parent_type_name) {
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Parent type disagreement in virtual defstate. The state is inherited from {}, but the "
|
||||
"parent is {}",
|
||||
inherit_info->parent_type_name, child_type_info->get_parent()));
|
||||
}
|
||||
|
||||
auto parent_method_info = env.dts->ts.lookup_method(inherit_info->parent_type_name, method_id);
|
||||
if (parent_method_info.name != inherit_info->method_name) {
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Disagreement between inherit and define. We inherited from method {}, but redefine {}",
|
||||
inherit_info->method_name, parent_method_info.name));
|
||||
}
|
||||
}
|
||||
|
||||
// name matches
|
||||
|
||||
if (expected_state_name != method_info.name) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Disagreement between state name and type system name. The state is named {}, "
|
||||
"but the slot is named {}, defined in type {}",
|
||||
expected_state_name, method_info.name, method_info.defined_in_type));
|
||||
}
|
||||
|
||||
// fmt::print("is a {}\n", typeid(*parent_state->try_as_single_element()).name());
|
||||
|
||||
auto entries = get_defstate_entries(
|
||||
elt->body(), body_idx + 1, env, expected_state_name, elt->entries().at(0).dest,
|
||||
method_info.type.substitute_for_method_call(type_name), pool, type_name);
|
||||
|
||||
return pool.alloc_element<DefstateElement>(type_name, expected_state_name, entries, true);
|
||||
}
|
||||
|
||||
bool is_nonvirtual_state(LetElement* elt) {
|
||||
return dynamic_cast<SetFormFormElement*>(elt->body()->at(0));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void run_defstate(Function& top_level_func) {
|
||||
auto& env = top_level_func.ir2.env;
|
||||
auto& pool = *top_level_func.ir2.form_pool;
|
||||
top_level_func.ir2.top_form->apply_form([&](Form* form) {
|
||||
for (auto& fe : form->elts()) {
|
||||
auto as_let = dynamic_cast<LetElement*>(fe);
|
||||
if (as_let && as_let->entries().size() == 1) {
|
||||
/* Looks something like this:
|
||||
(let ((v1-3 <static-data L28>))
|
||||
(set! teetertotter-idle (the-as (state none) v1-3))
|
||||
(set! (-> v1-3 event) L17)
|
||||
(set! (-> v1-3 code) L15)
|
||||
(set! (-> v1-3 post) transform-post)
|
||||
)
|
||||
*/
|
||||
|
||||
// first, see if we get a label:
|
||||
auto src_as_label = as_let->entries().at(0).src->try_as_element<DecompiledDataElement>();
|
||||
if (src_as_label &&
|
||||
env.get_variable_type(as_let->entries().at(0).dest, false) == TypeSpec("state")) {
|
||||
std::string expected_state_name = verify_empty_state_and_get_name(src_as_label, env);
|
||||
if (debug_defstates) {
|
||||
fmt::print("got state let:\n{}\n", pretty_print::to_string(as_let->to_form(env)));
|
||||
}
|
||||
|
||||
if (is_nonvirtual_state(as_let)) {
|
||||
auto rewritten = rewrite_nonvirtual_defstate(as_let, env, expected_state_name, pool);
|
||||
if (rewritten) {
|
||||
fe = rewritten;
|
||||
}
|
||||
} else {
|
||||
auto rewritten = rewrite_virtual_defstate(as_let, env, expected_state_name, pool);
|
||||
if (rewritten) {
|
||||
fe = rewritten;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} // namespace decompiler
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "decompiler/util/DecompilerTypeSystem.h"
|
||||
#include "decompiler/Function/Function.h"
|
||||
|
||||
namespace decompiler {
|
||||
void run_defstate(Function& top_level_func);
|
||||
}
|
||||
@@ -5,25 +5,53 @@
|
||||
#include "decompiler/analysis/final_output.h"
|
||||
|
||||
namespace decompiler {
|
||||
|
||||
namespace {
|
||||
bool try_convert_lambda(const Function& parent_function,
|
||||
FormPool& pool,
|
||||
Form* f,
|
||||
bool defstate_behavior) {
|
||||
auto atom = form_as_atom(f);
|
||||
if (atom && atom->is_static_addr()) {
|
||||
auto lab = parent_function.ir2.env.file->labels.at(atom->label());
|
||||
auto& env = parent_function.ir2.env;
|
||||
auto label_kv = env.label_types().find(lab.name);
|
||||
if (label_kv != env.label_types().end()) {
|
||||
if (label_kv->second.type_name == "_lambda_") {
|
||||
auto& file = env.file;
|
||||
auto other_func = file->try_get_function_at_label(atom->label());
|
||||
if (other_func) {
|
||||
goos::Object result;
|
||||
if (defstate_behavior) {
|
||||
result = final_output_defstate_anonymous_behavior(*other_func);
|
||||
} else {
|
||||
result = final_output_lambda(*other_func);
|
||||
}
|
||||
|
||||
f->clear();
|
||||
f->push_back(pool.alloc_element<LambdaDefinitionElement>(result));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int insert_static_refs(Form* top_level_form,
|
||||
FormPool& pool,
|
||||
const Function& function,
|
||||
const DecompilerTypeSystem&) {
|
||||
int replaced = 0;
|
||||
top_level_form->apply_form([&](Form* f) {
|
||||
auto atom = form_as_atom(f);
|
||||
if (atom && atom->is_static_addr()) {
|
||||
auto lab = function.ir2.env.file->labels.at(atom->label());
|
||||
auto& env = function.ir2.env;
|
||||
auto label_kv = env.label_types().find(lab.name);
|
||||
if (label_kv != env.label_types().end()) {
|
||||
if (label_kv->second.type_name == "_lambda_") {
|
||||
auto& file = env.file;
|
||||
auto other_func = file->try_get_function_at_label(atom->label());
|
||||
if (other_func) {
|
||||
auto result = final_output_lambda(*other_func);
|
||||
f->clear();
|
||||
f->push_back(pool.alloc_element<LambdaDefinitionElement>(result));
|
||||
|
||||
// first, look for defstates and lambdas to behaviors.
|
||||
top_level_form->apply([&](FormElement* fe) {
|
||||
auto as_defstate = dynamic_cast<DefstateElement*>(fe);
|
||||
if (as_defstate) {
|
||||
for (auto& e : as_defstate->entries()) {
|
||||
if (e.is_behavior) {
|
||||
if (try_convert_lambda(function, pool, e.val, true)) {
|
||||
replaced++;
|
||||
}
|
||||
}
|
||||
@@ -31,6 +59,13 @@ int insert_static_refs(Form* top_level_form,
|
||||
}
|
||||
});
|
||||
|
||||
// next, all the rest.
|
||||
top_level_form->apply_form([&](Form* f) {
|
||||
if (try_convert_lambda(function, pool, f, false)) {
|
||||
replaced++;
|
||||
}
|
||||
});
|
||||
|
||||
top_level_form->apply([&](FormElement* fe) {
|
||||
auto as_static_data = dynamic_cast<DecompiledDataElement*>(fe);
|
||||
if (as_static_data) {
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
(define-extern false-func (function symbol))
|
||||
(define-extern true-func (function symbol))
|
||||
(define-extern _format (function _varargs_ object))
|
||||
(define-extern method-set! (function type int function none)) ;; may actually return function.
|
||||
(define-extern method-set! (function type int object none)) ;; may actually return function.
|
||||
(define-extern basic-type? (function basic type symbol))
|
||||
(define-extern find-parent-method (function type int function))
|
||||
(define-extern ref (function object int object))
|
||||
@@ -1162,10 +1162,10 @@
|
||||
)
|
||||
|
||||
(deftype protect-frame (stack-frame)
|
||||
((exit (function object) :offset-assert 12)
|
||||
((exit (function none) :offset-assert 12)
|
||||
)
|
||||
(:methods
|
||||
(new (symbol type (function object)) protect-frame)
|
||||
(new (symbol type (function none)) protect-frame)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
@@ -1183,16 +1183,16 @@
|
||||
(declare-type event-message-block structure)
|
||||
(deftype state (protect-frame)
|
||||
((code function :offset-assert 16)
|
||||
(trans (function object) :offset-assert 20)
|
||||
(trans (function none) :offset-assert 20)
|
||||
(post function :offset-assert 24)
|
||||
(enter (function object object object object object object object) :offset-assert 28)
|
||||
(event (function process int symbol event-message-block object) :offset-assert 32)
|
||||
(enter function :offset-assert 28)
|
||||
(event (function process int symbol event-message-block object) :offset-assert 32)
|
||||
)
|
||||
(:methods
|
||||
(new (symbol type basic function
|
||||
(function object)
|
||||
(function object object object object object object object)
|
||||
(function object)
|
||||
(function none)
|
||||
function
|
||||
(function none)
|
||||
(function process int symbol event-message-block object)) _type_ 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
@@ -1297,7 +1297,7 @@
|
||||
|
||||
;; - Symbols
|
||||
|
||||
(define-extern dead-state state)
|
||||
(define-extern dead-state (state process))
|
||||
(define-extern *kernel-context* kernel-context)
|
||||
(define-extern *enable-method-set* int)
|
||||
(define-extern *listener-process* process)
|
||||
@@ -5396,8 +5396,8 @@
|
||||
(define-extern draw-sprite2d-xy (function dma-buffer int int int int rgba none))
|
||||
(define-extern screen-gradient (function dma-buffer rgba rgba rgba rgba none))
|
||||
(define-extern vif1-handler-debug (function none))
|
||||
(define-extern vif1-handler (function int))
|
||||
(define-extern install-handler (function int (function int) int)) ;; GOAL thinks it returns something.
|
||||
(define-extern vif1-handler (function none))
|
||||
(define-extern install-handler (function int function int)) ;; GOAL thinks it returns something.
|
||||
(define-extern vblank-handler (function int))
|
||||
(define-extern set-display-gs-state (function dma-buffer int int int int int dma-buffer))
|
||||
(define-extern set-display-gs-state-offset (function dma-buffer int int int int int int int dma-buffer))
|
||||
@@ -14486,7 +14486,7 @@
|
||||
(dummy-11 (_type_ vector) none 11)
|
||||
(dummy-12 () none 12)
|
||||
(dummy-13 () none 13)
|
||||
(dummy-14 () none 14)
|
||||
(dummy-14 (_type_) none 14)
|
||||
(set-target-pos! (_type_ vector) none 15)
|
||||
(dummy-16 (_type_ vector) symbol 16) ; see - nav-enemy-test-point-in-nav-mesh?
|
||||
(dummy-17 () none 17)
|
||||
@@ -17768,8 +17768,8 @@
|
||||
:flag-assert #x1e007000d4
|
||||
;; inherited inspect of process-drawable
|
||||
(:methods
|
||||
(water-vol-idle () none 20) ;; state
|
||||
(water-vol-startup () none 21) ;; state
|
||||
(water-vol-idle () _type_ :state 20)
|
||||
(water-vol-startup () _type_ :state 21)
|
||||
(TODO-RENAME-22 (_type_) ripple-wave-set 22)
|
||||
(dummy-23 () none 23)
|
||||
(dummy-24 () none 24)
|
||||
@@ -18133,7 +18133,7 @@
|
||||
|
||||
;; - Symbols
|
||||
|
||||
(define-extern cam-combiner-active state)
|
||||
(define-extern cam-combiner-active (state camera-combiner))
|
||||
|
||||
|
||||
;; ----------------------
|
||||
@@ -18574,7 +18574,7 @@
|
||||
(define-extern rider-post (function int))
|
||||
(define-extern pusher-post (function int))
|
||||
(define-extern process-drawable-delay-player (function int int))
|
||||
(define-extern process-drawable-fuel-cell-handler (function process-drawable object symbol (pointer int64) symbol))
|
||||
(define-extern process-drawable-fuel-cell-handler (function process int symbol event-message-block none))
|
||||
(define-extern process-drawable-birth-fuel-cell function)
|
||||
(define-extern process-drawable-valid? (function process-drawable symbol))
|
||||
|
||||
@@ -21809,10 +21809,6 @@
|
||||
:heap-base #x70
|
||||
:size-assert #xdc
|
||||
:flag-assert #x1e007000dc
|
||||
(:methods
|
||||
(water-vol-idle () none 20) ;; state
|
||||
(water-vol-startup () none 21) ;; state
|
||||
)
|
||||
)
|
||||
|
||||
(deftype water-anim-look (structure)
|
||||
@@ -21893,10 +21889,6 @@
|
||||
:heap-base #x70
|
||||
:flag-assert #x1e007000dc
|
||||
;; not enough basic ops
|
||||
(:methods
|
||||
(water-vol-idle () none 20) ;; state
|
||||
(water-vol-startup () none 21) ;; state
|
||||
)
|
||||
)
|
||||
|
||||
;; - Unknowns
|
||||
@@ -21979,8 +21971,8 @@
|
||||
:flag-assert #x23027002d4
|
||||
;; inherited inspect of process-drawable
|
||||
(:methods
|
||||
(rigid-body-platform-idle () none 20) ;; state
|
||||
(rigid-body-platform-float () none 21) ;; state
|
||||
(rigid-body-platform-idle () _type_ :state 20)
|
||||
(rigid-body-platform-float () _type_ :state 21)
|
||||
(TODO-RENAME-22 (_type_ vector basic) float 22) ;; TODO - basic is seemingly unused
|
||||
(TODO-RENAME-23 (_type_ basic) none 23) ;; TODO - basic is seemingly unused
|
||||
(TODO-RENAME-24 (_type_ rigid-body-control-point basic) none 24) ;; TODO - basic is seemingly unused
|
||||
@@ -22100,7 +22092,7 @@
|
||||
(touch-time uint64 :offset-assert 368)
|
||||
(nav-enemy-flags uint32 :offset-assert 376)
|
||||
(incomming-attack-id uint64 :offset-assert 384)
|
||||
(jump-return-state basic :offset-assert 392)
|
||||
(jump-return-state (state process) :offset-assert 392)
|
||||
(rand-gen random-generator :offset-assert 396)
|
||||
)
|
||||
:heap-base #x120
|
||||
@@ -22109,23 +22101,23 @@
|
||||
:flag-assert #x4c01200190
|
||||
;; inherited inspect of process-drawable
|
||||
(:methods
|
||||
(nav-enemy-attack () none 20) ;; state
|
||||
(nav-enemy-chase () none 21) ;; state
|
||||
(dummy-22 () none 22)
|
||||
(nav-enemy-die () none 23) ;; state
|
||||
(nav-enemy-fuel-cell () none 24) ;; state
|
||||
(nav-enemy-give-up () none 25) ;; state
|
||||
(nav-enemy-jump () none 26) ;; state
|
||||
(nav-enemy-jump-land () none 27) ;; state
|
||||
(nav-enemy-idle () none 28) ;; state
|
||||
(nav-enemy-notice () none 29) ;; state
|
||||
(nav-enemy-patrol () none 30) ;; state
|
||||
(nav-enemy-stare () none 31) ;; state
|
||||
(nav-enemy-stop-chase () none 32) ;; state
|
||||
(nav-enemy-victory () none 33) ;; state
|
||||
(nav-enemy-attack () _type_ :state 20)
|
||||
(nav-enemy-chase () _type_ :state 21)
|
||||
(nav-enemy-flee () _type_ :state 22)
|
||||
(nav-enemy-die () _type_ :state 23)
|
||||
(nav-enemy-fuel-cell () _type_ :state 24)
|
||||
(nav-enemy-give-up () _type_ :state 25)
|
||||
(nav-enemy-jump () _type_ :state 26)
|
||||
(nav-enemy-jump-land () _type_ :state 27)
|
||||
(nav-enemy-idle () _type_ :state 28)
|
||||
(nav-enemy-notice () _type_ :state 29)
|
||||
(nav-enemy-patrol () _type_ :state 30)
|
||||
(nav-enemy-stare () _type_ :state 31)
|
||||
(nav-enemy-stop-chase () _type_ :state 32)
|
||||
(nav-enemy-victory () _type_ :state 33)
|
||||
(dummy-34 (_type_) none 34)
|
||||
(dummy-35 (_type_) none 35)
|
||||
(dummy-36 (_type_) none 36)
|
||||
(nav-enemy-wait-for-cue () _type_ :state 35)
|
||||
(nav-enemy-jump-to-point () _type_ :state 36)
|
||||
(TODO-RENAME-37 (_type_) none 37)
|
||||
(TODO-RENAME-38 (_type_) none 38)
|
||||
(TODO-RENAME-39 (_type_) none 39)
|
||||
@@ -22163,7 +22155,7 @@
|
||||
(dummy-71 (_type_) none 71)
|
||||
(dummy-72 (_type_ process event-message-block) object 72) ;; TODO - args unknown, 3rd arg contains a touching-shapes-entry offset 16/20
|
||||
(TODO-RENAME-73 (_type_ process) symbol 73)
|
||||
(dummy-74 (_type_) none 74)
|
||||
(nav-enemy-jump-blocked () _type_ :state 74)
|
||||
(dummy-75 (_type_) none 75)
|
||||
)
|
||||
)
|
||||
@@ -22206,7 +22198,7 @@
|
||||
(define-extern nav-enemy-rnd-int-count (function int int))
|
||||
(define-extern nav-enemy-rnd-float (function float))
|
||||
(define-extern nav-enemy-rnd-percent? (function float symbol))
|
||||
(define-extern nav-enemy-default-event-handler (function process int symbol event-message-block object :behavior nav-enemy)) ;; TODO - last arg is definitely a vector...but also not?
|
||||
(define-extern nav-enemy-default-event-handler (function process int symbol event-message-block none :behavior nav-enemy)) ;; TODO - last arg is definitely a vector...but also not?
|
||||
(define-extern nav-enemy-jump-event-handler (function process int symbol event-message-block object :behavior nav-enemy))
|
||||
(define-extern process-drawable-death-event-handler (function process int symbol event-message-block uint :behavior process-drawable)) ;; First two args are unused
|
||||
(define-extern nav-enemy-patrol-post (function none :behavior nav-enemy))
|
||||
@@ -22223,7 +22215,7 @@
|
||||
(define-extern ja-group-index? (function int symbol :behavior nav-enemy))
|
||||
(define-extern nav-enemy-jump-post (function none :behavior nav-enemy))
|
||||
(define-extern nav-enemy-jump-land-post (function none :behavior nav-enemy))
|
||||
(define-extern nav-enemy-init-by-other (function nav-enemy vector vector nav-enemy :behavior nav-enemy))
|
||||
(define-extern nav-enemy-init-by-other (function nav-enemy vector vector none :behavior nav-enemy))
|
||||
|
||||
;; - Unknowns
|
||||
|
||||
@@ -22265,13 +22257,13 @@
|
||||
(open-distance float :offset-assert 180)
|
||||
(close-distance float :offset-assert 184)
|
||||
(out-dir vector :inline :offset-assert 192)
|
||||
(open-sound uint128 :offset-assert 208)
|
||||
(close-sound uint128 :offset-assert 224)
|
||||
(open-sound sound-name :offset-assert 208)
|
||||
(close-sound sound-name :offset-assert 224)
|
||||
(state-actor basic :offset-assert 240)
|
||||
(flags int32 :offset-assert 244)
|
||||
(locked symbol :offset-assert 248)
|
||||
(auto-close symbol :offset-assert 252)
|
||||
(one-way symbol :offset-assert 256)
|
||||
(locked symbol :offset-assert 248)
|
||||
(auto-close symbol :offset-assert 252)
|
||||
(one-way symbol :offset-assert 256)
|
||||
)
|
||||
:method-count-assert 27
|
||||
:size-assert #x104
|
||||
@@ -22541,12 +22533,6 @@
|
||||
:heap-base #x120
|
||||
:flag-assert #x4c01200190
|
||||
;; not enough basic ops
|
||||
(:methods
|
||||
(nav-enemy-die () none 23) ;; state
|
||||
(nav-enemy-fuel-cell () none 24) ;; state
|
||||
(nav-enemy-idle () none 28) ;; state
|
||||
(nav-enemy-patrol () none 30) ;; state
|
||||
)
|
||||
)
|
||||
|
||||
;; - Unknowns
|
||||
@@ -22720,9 +22706,9 @@
|
||||
(:methods
|
||||
(plat-button-at-end () none 20) ;; state
|
||||
(dummy-21 () none 21)
|
||||
(plat-button-pressed () none 22) ;; state
|
||||
(plat-button-move-downward () none 23) ;; state
|
||||
(plat-button-move-upward () none 24) ;; state
|
||||
(plat-button-pressed () _type_ :state 22)
|
||||
(plat-button-move-downward () _type_ :state 23)
|
||||
(plat-button-move-upward () _type_ :state 24)
|
||||
(dummy-25 () none 25)
|
||||
(dummy-26 () none 26)
|
||||
(TODO-RENAME-27 (_type_) none 27)
|
||||
@@ -33049,9 +33035,9 @@
|
||||
|
||||
(define-extern *rounddoor-sg* skeleton-group)
|
||||
(define-extern *silostep-sg* skeleton-group)
|
||||
(define-extern silostep-rise (state none)) ;; unknown type
|
||||
(define-extern silostep-idle (state none)) ;; unknown type
|
||||
(define-extern silostep-camera (state none)) ;; unknown type
|
||||
(define-extern silostep-rise (state symbol silostep))
|
||||
(define-extern silostep-idle (state silostep))
|
||||
(define-extern silostep-camera (state silostep))
|
||||
|
||||
|
||||
;; ----------------------
|
||||
@@ -33533,9 +33519,9 @@
|
||||
;; - Unknowns
|
||||
|
||||
(define-extern *teetertotter-sg* skeleton-group)
|
||||
(define-extern teetertotter-idle (state none)) ;; unknown type
|
||||
(define-extern teetertotter-launch (state none)) ;; unknown type
|
||||
(define-extern teetertotter-bend (state none)) ;; unknown type
|
||||
(define-extern teetertotter-idle (state teetertotter))
|
||||
(define-extern teetertotter-launch (state teetertotter))
|
||||
(define-extern teetertotter-bend (state teetertotter))
|
||||
|
||||
|
||||
;; ----------------------
|
||||
@@ -35327,13 +35313,6 @@
|
||||
:heap-base #x180
|
||||
:flag-assert #x4c018001f0
|
||||
;; inherited inspect of nav-enemy
|
||||
(:methods
|
||||
(nav-enemy-chase () none 21)
|
||||
(nav-enemy-die () none 23)
|
||||
(nav-enemy-idle () none 28)
|
||||
(nav-enemy-stare () none 31)
|
||||
(nav-enemy-victory () none 33)
|
||||
)
|
||||
)
|
||||
|
||||
;; - Functions
|
||||
@@ -39391,10 +39370,6 @@
|
||||
:heap-base #x1a0
|
||||
:flag-assert #x4c01a0020c
|
||||
;; inherited inspect of nav-enemy
|
||||
(:methods
|
||||
(nav-enemy-chase () none 21)
|
||||
(nav-enemy-stop-chase () none 32)
|
||||
)
|
||||
)
|
||||
|
||||
; (deftype lightning-mole (fleeing-nav-enemy)
|
||||
|
||||
@@ -588,14 +588,6 @@
|
||||
[0, "(function none)"]
|
||||
],
|
||||
|
||||
"misty-teetertotter": [
|
||||
[1, "(function none :behavior teetertotter)"],
|
||||
[2, "(function none :behavior teetertotter)"],
|
||||
[3, "(function process int symbol event-message-block symbol :behavior teetertotter)"],
|
||||
[4, "(function none :behavior teetertotter)"],
|
||||
[5, "(function process int symbol event-message-block object :behavior teetertotter)"]
|
||||
],
|
||||
|
||||
"misty-warehouse": [
|
||||
[3, "(function symbol none :behavior silostep)"],
|
||||
[4, "(function none :behavior silostep)"],
|
||||
@@ -611,12 +603,6 @@
|
||||
[8, "(function none :behavior rigid-body-platform)"]
|
||||
],
|
||||
|
||||
"water-anim": [
|
||||
[4, "(function none :behavior water-anim)"],
|
||||
[5, "(function none :behavior water-anim)"],
|
||||
[6, "(function process int symbol event-message-block process-mask :behavior water-anim)"]
|
||||
],
|
||||
|
||||
"plat-eco": [
|
||||
[9, "(function none :behavior plat-eco)"]
|
||||
],
|
||||
|
||||
@@ -694,7 +694,7 @@
|
||||
[128, "vector"]
|
||||
],
|
||||
|
||||
"(anon-function 1 cam-combiner)": [
|
||||
"(code cam-combiner-active)": [
|
||||
[16, "vector"],
|
||||
[32, "matrix"],
|
||||
[80, "vector"],
|
||||
@@ -854,7 +854,7 @@
|
||||
[32, "vector"]
|
||||
],
|
||||
|
||||
"(anon-function 3 misty-teetertotter)": [
|
||||
"(event teetertotter-launch)": [
|
||||
[16, "event-message-block"]
|
||||
],
|
||||
|
||||
@@ -917,7 +917,7 @@
|
||||
[96, "vector"]
|
||||
],
|
||||
|
||||
"(anon-function 3 sunken-elevator)": [
|
||||
"(trans plat-button-move-downward sunken-elevator)": [
|
||||
[16, "vector"],
|
||||
[32, "vector"],
|
||||
[48, "event-message-block"]
|
||||
@@ -991,19 +991,19 @@
|
||||
[32, "vector"]
|
||||
],
|
||||
|
||||
"(anon-function 17 nav-enemy)": [
|
||||
"(enter nav-enemy-jump-land nav-enemy)": [
|
||||
[16, "vector"]
|
||||
],
|
||||
"(anon-function 29 nav-enemy)": [
|
||||
"(code nav-enemy-die nav-enemy)": [
|
||||
[16, "event-message-block"]
|
||||
],
|
||||
"(anon-function 30 nav-enemy)": [
|
||||
"(enter nav-enemy-die nav-enemy)": [
|
||||
[16, "event-message-block"]
|
||||
],
|
||||
"(anon-function 51 nav-enemy)": [
|
||||
"(trans nav-enemy-flee nav-enemy)": [
|
||||
[16, "event-message-block"]
|
||||
],
|
||||
"(anon-function 57 nav-enemy)": [
|
||||
"(trans nav-enemy-patrol nav-enemy)": [
|
||||
[16, "event-message-block"]
|
||||
],
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
],
|
||||
|
||||
// GSTATE
|
||||
"enter-state": [[68, "s0", "protect-frame"]],
|
||||
"enter-state": [[68, "s0", "protect-frame"], [101, "t9", "(function object object object object object object none)"]],
|
||||
|
||||
// MATH
|
||||
"log2": [[3, "v1", "int"]],
|
||||
@@ -1707,13 +1707,12 @@
|
||||
"cam-curve-pos": [[[0, 224], "s6", "camera-slave"]],
|
||||
|
||||
"cam-combiner-init": [
|
||||
[[0, 999], "s6", "camera-combiner"],
|
||||
[[28, 33], "t9", "(function object)"]
|
||||
[[0, 999], "s6", "camera-combiner"]
|
||||
],
|
||||
|
||||
"(anon-function 1 cam-combiner)": [[[0, 999], "s6", "camera-combiner"]],
|
||||
"(code cam-combiner-active)": [[[0, 999], "s6", "camera-combiner"]],
|
||||
|
||||
"(anon-function 2 cam-combiner)": [
|
||||
"(event cam-combiner-active)": [
|
||||
[10, "a0", "vector"],
|
||||
[[0, 20], "s6", "camera-slave"],
|
||||
[[20, 231], "s6", "camera-combiner"],
|
||||
@@ -1872,30 +1871,12 @@
|
||||
[[78, 79], "a0", "dma-packet"],
|
||||
[79, "a0", "(pointer uint64)"]
|
||||
],
|
||||
"(anon-function 6 water-anim)": [
|
||||
"(event water-vol-idle water-anim)": [
|
||||
[6, "a0", "vector"]
|
||||
],
|
||||
|
||||
"(anon-function 5 water-anim)": [
|
||||
[2, "v1", "(state none)"]
|
||||
],
|
||||
|
||||
"(anon-function 8 rigid-body)": [
|
||||
[[16, 21], "t9", "(function object)"]
|
||||
],
|
||||
|
||||
"(anon-function 6 rigid-body)": [
|
||||
[[16, 21], "t9", "(function object)"]
|
||||
],
|
||||
|
||||
"(method 34 rigid-body-platform)": [
|
||||
[[0, 5], "t9", "(function object)"]
|
||||
],
|
||||
|
||||
"(method 22 water-anim)": [
|
||||
[[9, 14], "t9", "(function object object)"],
|
||||
[25, "s3", "basic"],
|
||||
[[32, 37], "t9", "(function object object)"]
|
||||
[25, "s3", "basic"]
|
||||
],
|
||||
|
||||
"(method 25 water-anim)": [
|
||||
@@ -1953,11 +1934,11 @@
|
||||
[82, "s4", "twist-joint"]
|
||||
],
|
||||
|
||||
"(anon-function 2 misty-teetertotter)": [
|
||||
"(code teetertotter-launch)": [
|
||||
[11, "v1", "art-joint-anim"]
|
||||
],
|
||||
|
||||
"(anon-function 1 misty-teetertotter)": [
|
||||
"(code teetertotter-bend)": [
|
||||
[10, "v1", "art-joint-anim"]
|
||||
],
|
||||
|
||||
@@ -1970,29 +1951,17 @@
|
||||
[100, "v1", "art-joint-anim"]
|
||||
],
|
||||
|
||||
"(anon-function 6 sunken-elevator)": [
|
||||
[2, "v1", "(state none)"],
|
||||
[2, "t9", "(function object)"],
|
||||
[4, "t9", "(function object)"],
|
||||
"(enter plat-button-pressed sunken-elevator)": [
|
||||
[40, "v1", "village2cam"],
|
||||
[73, "v1", "village2cam"]
|
||||
],
|
||||
|
||||
"(anon-function 5 sunken-elevator)": [
|
||||
[2, "v1", "(state none)"],
|
||||
[2, "t9", "(function object)"],
|
||||
[4, "t9", "(function object)"]
|
||||
],
|
||||
|
||||
"(anon-function 4 sunken-elevator)": [
|
||||
[2, "v1", "(state none)"],
|
||||
[2, "t9", "(function object)"],
|
||||
[4, "t9", "(function object)"],
|
||||
"(trans plat-button-move-upward sunken-elevator)": [
|
||||
[49, "v1", "village2cam"]
|
||||
],
|
||||
|
||||
"(anon-function 3 sunken-elevator)": [
|
||||
[13, "v0", "(state none)"]
|
||||
"(trans plat-button-move-downward sunken-elevator)": [
|
||||
[13, "v0", "(state sunken-elevator)"]
|
||||
],
|
||||
|
||||
"(method 27 sunken-elevator)": [
|
||||
@@ -2017,127 +1986,34 @@
|
||||
[39, "v1", "art-joint-anim"]
|
||||
],
|
||||
|
||||
"(anon-function 8 nav-enemy)": [
|
||||
[[42, 46], "t9", "(function object)"]
|
||||
"(code nav-enemy-victory nav-enemy)": [
|
||||
[27, "v1", "art-joint-anim"]
|
||||
],
|
||||
"(anon-function 31 nav-enemy)": [
|
||||
[27, "v1", "art-joint-anim"],
|
||||
[[70, 74], "t9", "(function object)"]
|
||||
"(code nav-enemy-notice nav-enemy)": [
|
||||
[27, "v1", "art-joint-anim"]
|
||||
],
|
||||
"(anon-function 51 nav-enemy)": [
|
||||
[[39, 43], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 54 nav-enemy)": [
|
||||
[27, "v1", "art-joint-anim"],
|
||||
[[80, 84], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 55 nav-enemy)": [
|
||||
[[9, 13], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 56 nav-enemy)": [
|
||||
"(code nav-enemy-patrol nav-enemy)": [
|
||||
[23, "v1", "art-joint-anim"],
|
||||
[105, "v1", "art-joint-anim"],
|
||||
[167, "v1", "art-joint-anim"],
|
||||
[249, "v1", "art-joint-anim"]
|
||||
],
|
||||
"(anon-function 61 nav-enemy)": [
|
||||
[[35, 39], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 57 nav-enemy)": [
|
||||
[[47, 51], "t9", "(function object)"],
|
||||
[[89, 93], "t9", "(function object)"],
|
||||
[[98, 102], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 42 nav-enemy)": [
|
||||
[[10, 14], "t9", "(function object)"],
|
||||
[[31, 35], "t9", "(function object)"],
|
||||
[[67, 71], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 43 nav-enemy)": [
|
||||
[[33, 37], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 50 nav-enemy)": [
|
||||
|
||||
"(code nav-enemy-flee nav-enemy)": [
|
||||
[27, "v1", "art-joint-anim"],
|
||||
[91, "v1", "art-joint-anim"]
|
||||
],
|
||||
"(anon-function 45 nav-enemy)": [
|
||||
[[5, 9], "t9", "(function object)"],
|
||||
[[14, 18], "t9", "(function object)"],
|
||||
[[75, 79], "t9", "(function object)"],
|
||||
[[91, 95], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 37 nav-enemy)": [
|
||||
[[1, 5], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 38 nav-enemy)": [
|
||||
[[10, 14], "t9", "(function object)"],
|
||||
[[38, 42], "t9", "(function object)"],
|
||||
[[94, 98], "t9", "(function object)"],
|
||||
[[124, 128], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 33 nav-enemy)": [
|
||||
[[1, 5], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 34 nav-enemy)": [
|
||||
[[1, 5], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 35 nav-enemy)": [
|
||||
[[15, 20], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 29 nav-enemy)": [
|
||||
[[36, 40], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 21 nav-enemy)": [
|
||||
[[15, 19], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 19 nav-enemy)": [
|
||||
[[19, 23], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 16 nav-enemy)": [
|
||||
[[15, 19], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 15 nav-enemy)": [
|
||||
[[3, 6], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 13 nav-enemy)": [
|
||||
[[6, 9], "t9", "(function object)"]
|
||||
],
|
||||
"(anon-function 11 nav-enemy)": [
|
||||
[[80, 84], "t9", "(function object)"]
|
||||
],
|
||||
|
||||
"nav-enemy-init-by-other": [
|
||||
[[54, 58], "t9", "(function object object)"]
|
||||
],
|
||||
|
||||
"nav-enemy-set-hit-from-direction": [
|
||||
[19, "v1", "process-drawable"]
|
||||
],
|
||||
|
||||
"(method 59 nav-enemy)": [
|
||||
[[1, 5], "t9", "(function object)"]
|
||||
],
|
||||
|
||||
"(method 73 nav-enemy)": [
|
||||
[[19, 23], "t9", "(function object)"]
|
||||
],
|
||||
|
||||
"(method 43 nav-enemy)": [
|
||||
[[22, 26], "t9", "(function object)"]
|
||||
],
|
||||
|
||||
"(method 45 nav-enemy)": [
|
||||
[14, "v1", "process-mask"]
|
||||
],
|
||||
|
||||
"nav-enemy-default-event-handler": [
|
||||
[62, "a0", "vector"],
|
||||
[82, "a0", "vector"],
|
||||
[[49, 53], "t9", "(function object)"],
|
||||
[[70, 74], "t9", "(function object)"],
|
||||
[[92, 96], "t9", "(function object)"],
|
||||
[[100, 104], "t9", "(function object)"],
|
||||
[[108, 112], "t9", "(function object)"]
|
||||
[82, "a0", "vector"]
|
||||
],
|
||||
|
||||
"(method 7 nav-enemy)": [
|
||||
@@ -2146,11 +2022,11 @@
|
||||
[19, "t9", "(function process-drawable int none)"]
|
||||
],
|
||||
|
||||
"(anon-function 59 nav-enemy)": [
|
||||
"(enter nav-enemy-patrol nav-enemy)": [
|
||||
[8, "v1", "int"]
|
||||
],
|
||||
|
||||
"(anon-function 28 nav-enemy)": [
|
||||
"(code nav-enemy-fuel-cell nav-enemy)": [
|
||||
[31, "v1", "int"]
|
||||
],
|
||||
|
||||
|
||||
@@ -1281,13 +1281,23 @@ std::string decompile_int_enum_from_int(const TypeSpec& type, const TypeSystem&
|
||||
auto type_info = ts.try_enum_lookup(type.base_type());
|
||||
assert(type_info);
|
||||
assert(!type_info->is_bitfield());
|
||||
|
||||
std::vector<std::string> matches;
|
||||
for (auto& field : type_info->entries()) {
|
||||
if ((u64)field.second == value) {
|
||||
return field.first;
|
||||
matches.push_back(field.first);
|
||||
}
|
||||
}
|
||||
throw std::runtime_error(
|
||||
fmt::format("Failed to decompile integer enum. Value {} (0x{:x}) wasn't found in enum {}",
|
||||
value, value, type_info->get_name()));
|
||||
|
||||
if (matches.size() == 0) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Failed to decompile integer enum. Value {} (0x{:x}) wasn't found in enum {}",
|
||||
value, value, type_info->get_name()));
|
||||
} else if (matches.size() == 1) {
|
||||
return matches.front();
|
||||
} else {
|
||||
std::sort(matches.begin(), matches.end());
|
||||
return matches.front();
|
||||
}
|
||||
}
|
||||
} // namespace decompiler
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
- [Macro Support](/goos.md)
|
||||
- [Object File Formats](/object_file_formats.md)
|
||||
- [Process and State System](/process_and_state.md)
|
||||
- [States in the Decompiler](/decompiler_states.md)
|
||||
|
||||
- Working with OpenGOAL
|
||||
- [The REPL](/repl.md)
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
# States in the Decompiler
|
||||
|
||||
## How can I tell if a file has states?
|
||||
Search in the `ir2.asm` file for `.type state`. If you see something like this:
|
||||
```
|
||||
.type state
|
||||
L28:
|
||||
.symbol plat-button-move-downward
|
||||
.symbol #f
|
||||
.symbol #f
|
||||
.symbol #f
|
||||
```
|
||||
that's a state, and you can expect the file to have `defstate`s.
|
||||
|
||||
## Virtual vs. Non-Virtual States
|
||||
A non-virtual state is stored in a global variable with the same name as the state. This is just like a global function. You don't have to do anything special with this - the decompiler will insert a `defstate` with the appropriate name and make sure that the name of the symbol and the name stored in the `state` itself match.
|
||||
|
||||
A virtual state is stored in the method table of a type, similar to a method. When doing a `go`, the virtual state will be looked up from the method table of the current process, allowing a child type of process to override the state of its parent. You can tell if a state is virtual by looking for a call to `inherit-state` or `method-set!`.
|
||||
|
||||
## Decompiling state handers
|
||||
Each state has up to 6 handler functions: `enter`, `post`, `exit`, `trans`, `code`, and `event`. In order for the decompiler to recognize these, you _must_ have the top-level function decompile. Do not attempt to decompile these functions until the top-level function passes.
|
||||
|
||||
The top-level analysis will find state handlers and name them appropriately. For non-virtual states, they will be named like `(<handler-name> <state-name>)`. Like `(code teetertotter-launch)`. For virtual states, the name will be `(<handler-name> <state-name> <type-name>)`. Use these names in type casts, stack structures, etc. These names will not work unless the top-level has been decompiled.
|
||||
|
||||
The type of the state handlers will be set up automatically by the type system, but requires that you get the type of the state itself correct.
|
||||
|
||||
Note: inside of `find_defstates.cpp` there is an option to enable rename prints that will print out the old name of the function before the rename.
|
||||
|
||||
## State Types
|
||||
Each state object must have its type set. The type of a state is:
|
||||
```
|
||||
(state <arg0> <arg1> ... <parent-type>)
|
||||
```
|
||||
|
||||
The args are the arguments given to the enter/code function. Both enter and code get the same arguments, and some may be unused, but this is ok.
|
||||
|
||||
The parent type is the type that the state belongs to. It must be `process` or a child of `process`. All state handlers are automatically behaviors of this type.
|
||||
|
||||
Here are two examples:
|
||||
```
|
||||
(define-extern silostep-rise (state symbol silostep))
|
||||
```
|
||||
will make all the `silostep-rise` handlers a behavior of `silostep` and will make `enter` and `code` take a single `symbol` argument.
|
||||
|
||||
## Go
|
||||
The `go` macro changes state. Internally it uses `enter-state`. Do not insert casts for `go`, it should work automatically.
|
||||
|
||||
TODO: there may be issues with the decompiler casting arguments to `go` - this is a bit tricky and I couldn't find a test case yet.
|
||||
|
||||
## Special Cases for Virtual States
|
||||
There are a few special cases for virtual states.
|
||||
|
||||
1. The state must be declared in the `deftype`, within the list of methods.
|
||||
2. The name of the method must be correct.
|
||||
3. Any `go` should be in a behavior of the appropriate process.
|
||||
|
||||
The next three sections explain these in more detail
|
||||
|
||||
### Declaring a virtual state
|
||||
Do not use `define-extern` to declare a virtual state. Instead, use the method list in the `deftype`.
|
||||
|
||||
As an example:
|
||||
```
|
||||
lui v1, L30 ;; [ 25] (set! gp-0 L30) [] -> [gp: state ]
|
||||
ori gp, v1, L30
|
||||
lw t9, inherit-state(s7)
|
||||
or a0, gp, r0
|
||||
lw v1, plat-button(s7)
|
||||
lwu a1, 104(v1)
|
||||
jalr ra, t9
|
||||
sll v0, ra, 0
|
||||
|
||||
lw t9, method-set!(s7)
|
||||
lw a0, sunken-elevator(s7)
|
||||
addiu a1, r0, 22
|
||||
or a2, gp, r0
|
||||
jalr ra, t9
|
||||
```
|
||||
|
||||
This means
|
||||
- The state object is `L30`.
|
||||
- The state is for type `sunken-elevator`.
|
||||
- The parent type of `sunken-elevator` should be `plat-button`
|
||||
- The method ID is 22.
|
||||
|
||||
The correct declaration should go under `:methods`. Like a normal method, it only needs to be defined in the parent type that first defines it. So we only have to put it in `plat-button` and can leave it out of `sunken-elevator`.
|
||||
|
||||
```
|
||||
(plat-button-pressed () _type_ :state 22)
|
||||
```
|
||||
|
||||
The first thing is the state name (described more in the next section). The next thing is a list of argument types given to the `enter` and `code` functions.
|
||||
|
||||
The ID should match the ID given to `method-set!` and it will be checked just like the normal method IDs.
|
||||
|
||||
If you get this wrong, you will get an error message like this:
|
||||
```
|
||||
virtual defstate attempted on something that isn't a state: (the-as state (method-of-type plat-button plat-button-move-upward))
|
||||
Did you forget to put :state in the method declaration?
|
||||
```
|
||||
which means that the `plat-button-move-upward` entry in `:methods` in `(deftype plat-button` is missing the `:state`
|
||||
|
||||
### Name of a virtual state
|
||||
The decompiler will check that the name in the method is correct. If you get it wrong, there will be an error that tells you the right name.
|
||||
|
||||
For example:
|
||||
```
|
||||
Disagreement between state name and type system name. The state is named plat-button-move-upward, but the slot is named dummy-24, defined in type plat-button
|
||||
```
|
||||
|
||||
This means you should rename `dummy-24` in `plat-button` to `plat-button-move-upward`.
|
||||
|
||||
|
||||
### Go to a virtual state
|
||||
You must be in a behavior in order for `go-virtual` to decompile successfully.
|
||||
|
||||
## The return value of `event` problem.
|
||||
There is one place that seems to rely on the return value of `event`. As a result, the default is to assume that `event` returns an `object`. However, there are sometimes `event` functions that clearly don't return a value and will refuse to decompile. The recommendation is:
|
||||
- Try to make all `event` functions return a value.
|
||||
- If it is absolutely not possible, make the function type return `none`, then the defstate should automatically insert a cast.
|
||||
|
||||
|
||||
## Unsupported
|
||||
Calls to `find-parent-method` that actually return a `state` will have type `function`. You must manually cast it. Make sure you get the argument types correct. This same problem exists for finding methods, but it has been very rare. If needed we can add special support in the decompiler/compiler to make this work.
|
||||
|
||||
If there is a function with multiple virtual `go`s which assume a different type at compile-time (accessing different parts of the type tree), then it is not possible to insert the right kind of cast yet.
|
||||
|
||||
@@ -188,4 +188,6 @@
|
||||
- The register allocator has been dramatically improved and generates ~5x fewer spill instructions and is able to eliminate more moves.
|
||||
- Added a `(print-debug-compiler-stats)` form to print out statistics related to register allocation and move elimination
|
||||
- Added `get-enum-vals` which returns a list of pairs. Each pair is the name (symbol) and value (int) for each value in the enum
|
||||
- It is now possible to set a 64-bit memory location from a float, if you insert a cast. It will zero-extend the float, just like any other float -> 64-bit conversion.
|
||||
- It is now possible to set a 64-bit memory location from a float, if you insert a cast. It will zero-extend the float, just like any other float -> 64-bit conversion.
|
||||
- Added `:state` option to `:methods`.
|
||||
- Accessing the `enter` field of `state` will now magically give you a function with the right type.
|
||||
@@ -616,6 +616,7 @@ void DirectRenderer::handle_xyzf2_common(u32 x,
|
||||
u32 z,
|
||||
u8 f,
|
||||
SharedRenderState* render_state) {
|
||||
(void)f; // TODO: do something with this.
|
||||
if (m_prim_buffer.is_full()) {
|
||||
flush_pending(render_state);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ const char* init_types[] = {"fakeiso", "deviso", "iso_cd"};
|
||||
Timer ee_clock_timer;
|
||||
|
||||
// added
|
||||
bool machine_booted = false;
|
||||
u32 vif1_interrupt_handler = 0;
|
||||
|
||||
void kmachine_init_globals() {
|
||||
isodrv = iso_cd;
|
||||
@@ -65,7 +65,7 @@ void kmachine_init_globals() {
|
||||
reboot = 1;
|
||||
memset(pad_dma_buf, 0, sizeof(pad_dma_buf));
|
||||
ee_clock_timer = Timer();
|
||||
machine_booted = false;
|
||||
vif1_interrupt_handler = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -534,8 +534,9 @@ u64 CPadGetData(u64 cpad_info) {
|
||||
}
|
||||
|
||||
// TODO InstallHandler
|
||||
void InstallHandler() {
|
||||
assert(false);
|
||||
void InstallHandler(u32 handler_idx, u32 handler_func) {
|
||||
assert(handler_idx == 5); // vif1
|
||||
vif1_interrupt_handler = handler_func;
|
||||
}
|
||||
// TODO InstallDebugHandler
|
||||
void InstallDebugHandler() {
|
||||
@@ -733,11 +734,8 @@ void InitMachine_PCPort() {
|
||||
|
||||
void vif_interrupt_callback() {
|
||||
// added for the PC port for faking VIF interrupts from the graphics system.
|
||||
if (machine_booted && MasterExit == 0) {
|
||||
auto sym = intern_from_c("vif1-handler-debug");
|
||||
if (sym->value) {
|
||||
call_goal(Ptr<Function>(sym->value), 0, 0, 0, s7.offset, g_ee_main_mem);
|
||||
}
|
||||
if (vif1_interrupt_handler && MasterExit == 0) {
|
||||
call_goal(Ptr<Function>(vif1_interrupt_handler), 0, 0, 0, s7.offset, g_ee_main_mem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -813,5 +811,4 @@ void InitMachineScheme() {
|
||||
lg::info("calling fake play~");
|
||||
call_goal_function_by_name("play");
|
||||
}
|
||||
machine_booted = true;
|
||||
}
|
||||
|
||||
+10
-10
@@ -19,7 +19,7 @@ int scePadPortOpen(int port, int slot, void*) {
|
||||
return port + 1;
|
||||
}
|
||||
|
||||
int scePadGetState(int port, int slot) {
|
||||
int scePadGetState(int /*port*/, int /*slot*/) {
|
||||
// pretend we always have a controller connected
|
||||
return scePadStateStable;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ static const int libpad_DualShock2_ModeIDs[2] = {
|
||||
(int)PadMode::Controller, // no vibration or pressure sensitive buttons
|
||||
(int)PadMode::DualShock2 // vibration + pressure sensitive buttons
|
||||
};
|
||||
int scePadInfoMode(int port, int slot, int term, int offs) {
|
||||
int scePadInfoMode(int /*port*/, int /*slot*/, int term, int offs) {
|
||||
if (term == InfoModeCurExID) {
|
||||
// return vibration mode ID. that's just dualshock mode.
|
||||
return libpad_DualShock2_ModeIDs[1];
|
||||
@@ -61,7 +61,7 @@ static const Pad::Button libpad_PadPressureButtons[] = {
|
||||
Pad::Button::L1, Pad::Button::R1, Pad::Button::L2, Pad::Button::R2};
|
||||
// reads controller data and writes it to a buffer in rdata (must be at least 32 bytes large).
|
||||
// returns buffer size (32) or 0 on error.
|
||||
int scePadRead(int port, int slot, u8* rdata) {
|
||||
int scePadRead(int port, int /*slot*/, u8* rdata) {
|
||||
auto cpad = (CPadInfo*)(rdata);
|
||||
Gfx::poll_events();
|
||||
|
||||
@@ -88,24 +88,24 @@ int scePadRead(int port, int slot, u8* rdata) {
|
||||
}
|
||||
|
||||
// buzzer control. We don't care right now, return success.
|
||||
int scePadSetActDirect(int port, int slot, const u8* data) {
|
||||
int scePadSetActDirect(int /*port*/, int /*slot*/, const u8* /*data*/) {
|
||||
return 1;
|
||||
}
|
||||
int scePadSetActAlign(int port, int slot, const u8* data) {
|
||||
int scePadSetActAlign(int /*port*/, int /*slot*/, const u8* /*data*/) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// we also don't care
|
||||
int scePadSetMainMode(int port, int slot, int offs, int lock) {
|
||||
int scePadSetMainMode(int /*port*/, int /*slot*/, int /*offs*/, int /*lock*/) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// async pad functions are gonna be synchronous so this always succeeds
|
||||
int scePadGetReqState(int port, int slot) {
|
||||
int scePadGetReqState(int /*port*/, int /*slot*/) {
|
||||
return scePadReqStateComplete;
|
||||
}
|
||||
|
||||
int scePadInfoAct(int port, int slot, int actno, int term) {
|
||||
int scePadInfoAct(int /*port*/, int /*slot*/, int actno, int term) {
|
||||
if (actno == -1)
|
||||
return 2; // i think?
|
||||
if (actno < 2) {
|
||||
@@ -122,11 +122,11 @@ int scePadInfoAct(int port, int slot, int actno, int term) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scePadInfoPressMode(int port, int slot) {
|
||||
int scePadInfoPressMode(int /*port*/, int /*slot*/) {
|
||||
return 0; // we do NOT support pressure sensitive buttons right now
|
||||
}
|
||||
|
||||
int scePadEnterPressMode(int port, int slot) {
|
||||
int scePadEnterPressMode(int /*port*/, int /*slot*/) {
|
||||
return 1; // we dont support pressure button, but if we did this would work straight away
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -443,7 +443,7 @@
|
||||
(define-extern cam-calc-follow! (function cam-rotation-tracker vector symbol vector))
|
||||
(define-extern slave-set-rotation! (function cam-rotation-tracker vector float float symbol none))
|
||||
;; TODO - for cam-combiner
|
||||
(define-extern cam-combiner-active state)
|
||||
(define-extern cam-combiner-active (state camera-combiner))
|
||||
(define-extern paused? (function symbol))
|
||||
;; TODO - for cam-start
|
||||
(define-extern cam-master-init (function none :behavior camera-master))
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
(define-extern rider-trans (function int))
|
||||
;; TODO - for nav-enemy
|
||||
(define-extern ja-blend-eval (function int))
|
||||
(define-extern process-drawable-fuel-cell-handler (function process-drawable object symbol (pointer int64) symbol))
|
||||
(define-extern process-drawable-fuel-cell-handler (function process int symbol event-message-block none))
|
||||
(define-extern ja-aframe-num (function int float))
|
||||
(define-extern ja-aframe (function float int float))
|
||||
|
||||
@@ -530,7 +530,7 @@
|
||||
|
||||
;; There was also a vblank hanlder that incremented *vblank-counter*, but it is disabled.
|
||||
|
||||
(defun vif1-handler-debug ()
|
||||
(defun-debug vif1-handler-debug ()
|
||||
"Add a profile bar to the VU1 profiler. This will be called from the graphics thread, which will grab it
|
||||
directly from the symbol table, no need to register this handler."
|
||||
(let ((c0 (/ (* 128 (-> *display* frames (-> *display* on-screen) frame profile-bar 1 profile-frame-count)) 69))
|
||||
@@ -547,6 +547,10 @@
|
||||
(none)
|
||||
)
|
||||
|
||||
(if *debug-segment*
|
||||
(install-handler 5 vif1-handler-debug)
|
||||
)
|
||||
|
||||
(define *oddeven* 0)
|
||||
|
||||
|
||||
|
||||
@@ -99,8 +99,8 @@
|
||||
:flag-assert #x1e007000d4
|
||||
;; inherited inspect of process-drawable
|
||||
(:methods
|
||||
(water-vol-idle () none 20) ;; state
|
||||
(water-vol-startup () none 21) ;; state
|
||||
(water-vol-idle () _type_ :state 20)
|
||||
(water-vol-startup () _type_ :state 21)
|
||||
(TODO-RENAME-22 (_type_) ripple-wave-set 22)
|
||||
(dummy-23 () none 23)
|
||||
(dummy-24 () none 24)
|
||||
|
||||
@@ -241,7 +241,7 @@
|
||||
(dummy-11 (_type_ vector) none 11)
|
||||
(dummy-12 () none 12)
|
||||
(dummy-13 () none 13)
|
||||
(dummy-14 () none 14)
|
||||
(dummy-14 (_type_) none 14)
|
||||
(set-target-pos! (_type_ vector) none 15)
|
||||
(dummy-16 (_type_ vector) symbol 16) ; see - nav-enemy-test-point-in-nav-mesh?
|
||||
(dummy-17 () none 17)
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
(define-extern malloc (function symbol int pointer))
|
||||
(define-extern kmalloc (function kheap int kmalloc-flags string pointer))
|
||||
(define-extern new-dynamic-structure (function symbol type int structure))
|
||||
(define-extern method-set! (function type int function none)) ;; may actually return function.
|
||||
(define-extern method-set! (function type int object none)) ;; may actually return function.
|
||||
(define-extern link (function pointer pointer int kheap int pointer))
|
||||
(define-extern dgo-load (function string kheap int int none))
|
||||
(define-extern link-begin (function pointer (pointer uint8) int kheap link-flag int))
|
||||
@@ -151,7 +151,7 @@
|
||||
(declare-type cpad-info basic)
|
||||
(define-extern cpad-open (function cpad-info int cpad-info))
|
||||
(define-extern cpad-get-data (function cpad-info cpad-info))
|
||||
(define-extern install-handler (function int (function int) int)) ;; check return val
|
||||
(define-extern install-handler (function int function int)) ;; check return val
|
||||
;; install-debug-handler
|
||||
(define-extern file-stream-open (function file-stream basic basic file-stream))
|
||||
(define-extern file-stream-close (function file-stream file-stream))
|
||||
|
||||
@@ -364,10 +364,10 @@
|
||||
|
||||
;; A protect frame is a frame which has a cleanup function called on exit.
|
||||
(deftype protect-frame (stack-frame)
|
||||
((exit (function object) :offset-assert 12)) ;; function to call to clean up
|
||||
((exit (function none) :offset-assert 12)) ;; function to call to clean up
|
||||
|
||||
(:methods
|
||||
(new (symbol type (function object)) protect-frame)
|
||||
(new (symbol type (function none)) protect-frame)
|
||||
)
|
||||
:size-assert 16
|
||||
:method-count-assert 9
|
||||
@@ -438,17 +438,17 @@
|
||||
)
|
||||
|
||||
(deftype state (protect-frame)
|
||||
((code function :offset-assert 16)
|
||||
(trans (function object) :offset-assert 20)
|
||||
(post function :offset-assert 24)
|
||||
(enter (function object object object object object object object) :offset-assert 28)
|
||||
(event (function process int symbol event-message-block object) :offset-assert 32)
|
||||
((code function :offset-assert 16)
|
||||
(trans (function none) :offset-assert 20)
|
||||
(post function :offset-assert 24)
|
||||
(enter function :offset-assert 28)
|
||||
(event (function process int symbol event-message-block object) :offset-assert 32)
|
||||
)
|
||||
(:methods
|
||||
(new (symbol type basic function
|
||||
(function object)
|
||||
(function object object object object object object object)
|
||||
(function object)
|
||||
(function none)
|
||||
function
|
||||
(function none)
|
||||
(function process int symbol event-message-block object)) _type_ 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
|
||||
+10
-10
@@ -1957,7 +1957,7 @@
|
||||
(break)
|
||||
)
|
||||
|
||||
(defmethod new protect-frame ((allocation symbol) (type-to-make type) (func (function object)))
|
||||
(defmethod new protect-frame ((allocation symbol) (type-to-make type) (func (function none)))
|
||||
(let ((obj (the protect-frame (&+ allocation *gtype-basic-offset*))))
|
||||
(set! (-> obj type) type-to-make)
|
||||
(set! (-> obj name) 'protect-frame)
|
||||
@@ -2322,15 +2322,15 @@
|
||||
|
||||
;; The defstate macro isn't defined yet, so we do it manually.
|
||||
(define dead-state
|
||||
(new 'static 'state
|
||||
:name #f
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f))
|
||||
(the (state process) (new 'static 'state
|
||||
:name #f
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f)))
|
||||
|
||||
(set! (-> dead-state code) nothing)
|
||||
|
||||
|
||||
+71
-65
@@ -38,24 +38,36 @@ There are several ways to "go"
|
||||
- go from the main thread of the main process. This causes the (-> pp state) to change, the stack frames
|
||||
to be cleaned up, and the old state's exit to be called. It will reset the stack, then run the code.
|
||||
Unlike the others, this means you "go" immediately.
|
||||
|
||||
The compiler has two special hooks related to states: go-hook and define-state-hook.
|
||||
These take care of doing a go and a state definition and properly checking types.
|
||||
|
||||
The define-state-hook takes a state object and handlers and defines a global symbol
|
||||
with the appropriate state type.
|
||||
|
||||
The go-hook calls enter state and sets (-> proc next-state) for the given process.
|
||||
It type checks the arguments for the entry function.
|
||||
|
||||
|#
|
||||
|
||||
;; cause the current process to change state
|
||||
(defmacro go (next-state &rest args)
|
||||
`(with-pp
|
||||
(set! (-> pp next-state) ,next-state)
|
||||
((the (function _varargs_ object) enter-state) ,@args)
|
||||
(go-hook pp ,next-state ,@args)
|
||||
)
|
||||
)
|
||||
|
||||
(defmacro go-virtual (state-name &key (proc self) &rest args)
|
||||
"Change the current process to the virtual state of the given process."
|
||||
`(go (method-of-object ,proc ,state-name) ,@args)
|
||||
)
|
||||
|
||||
;; cause the given process to change state.
|
||||
(defmacro go-process (proc state &rest args)
|
||||
(defmacro go-process (proc next-state &rest args)
|
||||
`(with-pp
|
||||
(protect (pp)
|
||||
(set! pp ,proc)
|
||||
(set! (-> pp next-state) ,state)
|
||||
((the (function _varargs_ object) enter-state) ,@args)
|
||||
(go-hook pp ,next-state ,@args)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -126,20 +138,21 @@ There are several ways to "go"
|
||||
)
|
||||
|
||||
(defmacro defstate (state-name parents
|
||||
&key (event #f)
|
||||
&key (enter #f)
|
||||
&key (trans #f)
|
||||
&key (exit #f)
|
||||
&key (code #f)
|
||||
&key (post #f)
|
||||
)
|
||||
&key (virtual #f)
|
||||
&key (event #f)
|
||||
&key (enter #f)
|
||||
&key (trans #f)
|
||||
&key (exit #f)
|
||||
&key (code #f)
|
||||
&key (post #f)
|
||||
)
|
||||
"Define a new state!"
|
||||
|
||||
|
||||
(with-gensyms (new-state)
|
||||
(let ((defstate-type (first parents)))
|
||||
(when (not (null? *defstate-type-stack*))
|
||||
(ferror "*defstate-type-stack* leaked! An error probably happened in a previous defstate. stack is: {}" *defstate-type-stack*)
|
||||
)
|
||||
(ferror "*defstate-type-stack* leaked! An error probably happened in a previous defstate. stack is: {}" *defstate-type-stack*)
|
||||
)
|
||||
(set! *defstate-type-stack* '())
|
||||
(def-state-check-behavior event defstate-type)
|
||||
(def-state-check-behavior enter defstate-type)
|
||||
@@ -148,53 +161,36 @@ There are several ways to "go"
|
||||
(def-state-check-behavior code defstate-type)
|
||||
(def-state-check-behavior post defstate-type)
|
||||
`(let ((,new-state (new 'static 'state
|
||||
:name (quote ,state-name)
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
))
|
||||
(define ,state-name ,new-state)
|
||||
,(if event
|
||||
`(set! (-> ,new-state event) ,event)
|
||||
`(none)
|
||||
)
|
||||
,(if enter
|
||||
`(set! (-> ,new-state enter) (the (function object object object object object object object) ,enter))
|
||||
`(none)
|
||||
)
|
||||
,(if trans
|
||||
`(set! (-> ,new-state trans) ,trans)
|
||||
`(none)
|
||||
)
|
||||
,(if exit
|
||||
`(set! (-> ,new-state exit) ,exit)
|
||||
`(none)
|
||||
)
|
||||
,(if code
|
||||
`(set! (-> ,new-state code) ,code)
|
||||
`(none)
|
||||
)
|
||||
,(if post
|
||||
`(set! (-> ,new-state post) ,post)
|
||||
`(none)
|
||||
)
|
||||
)
|
||||
:name (quote ,state-name)
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
))
|
||||
;; the compiler will set the fields of the given state and define the symbol.
|
||||
;; This way it can check the individual function types, make sure they make sense, and create
|
||||
;; a state with the appropriate type.
|
||||
,(if virtual
|
||||
`(define-virtual-state-hook ,state-name ,defstate-type ,new-state :event ,event :enter ,enter :trans ,trans :exit ,exit :code ,code :post ,post)
|
||||
`(define-state-hook ,state-name ,defstate-type ,new-state :event ,event :enter ,enter :trans ,trans :exit ,exit :code ,code :post ,post)
|
||||
)
|
||||
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(defmacro behavior (bindings &rest body)
|
||||
"Define an anonymous behavior for a process state. This may only be used inside a defstate!"
|
||||
|
||||
|
||||
(let ((behavior-type (first *defstate-type-stack*)))
|
||||
(pop! *defstate-type-stack*)
|
||||
`(the-as (function object) (lambda :behavior ,behavior-type ,bindings ,@body))
|
||||
)
|
||||
(pop! *defstate-type-stack*)
|
||||
`(lambda :behavior ,behavior-type ,bindings ,@body)
|
||||
)
|
||||
)
|
||||
|
||||
(defmethod new state
|
||||
@@ -202,9 +198,9 @@ There are several ways to "go"
|
||||
(type-to-make type)
|
||||
(name basic)
|
||||
(code function)
|
||||
(trans (function object))
|
||||
(enter (function object object object object object object object))
|
||||
(exit (function object))
|
||||
(trans (function none))
|
||||
(enter function)
|
||||
(exit (function none))
|
||||
(event (function process int symbol event-message-block object)))
|
||||
"Allocate a new state. It seems like this isn't really used much and most states are
|
||||
statically allocated and as a result don't have the constructor called."
|
||||
@@ -223,12 +219,22 @@ There are several ways to "go"
|
||||
|
||||
(defun inherit-state ((child state) (parent state))
|
||||
"Copy handler functions from parent to child"
|
||||
(set! (-> child exit) (-> parent exit))
|
||||
(set! (-> child code) (-> parent code))
|
||||
(set! (-> child trans) (-> parent trans))
|
||||
(set! (-> child post) (-> parent post))
|
||||
(set! (-> child enter) (-> parent enter))
|
||||
(set! (-> child event) (-> parent event))
|
||||
(cond
|
||||
((nonzero? parent)
|
||||
(set! (-> child exit) (-> parent exit))
|
||||
(set! (-> child code) (-> parent code))
|
||||
(set! (-> child trans) (-> parent trans))
|
||||
(set! (-> child post) (-> parent post))
|
||||
(set! (-> child enter) (-> parent enter))
|
||||
(set! (-> child event) (-> parent event))
|
||||
)
|
||||
(else
|
||||
;; Note: this is added to let us defstate on a child before the parent.
|
||||
;; The child won't be usable like this, but it will prevent a crash.
|
||||
(format 0 "[STATE ERROR] inherit-state got a null parent state. Child is ~A~%" (-> child name))
|
||||
)
|
||||
)
|
||||
|
||||
child
|
||||
)
|
||||
|
||||
@@ -306,7 +312,7 @@ There are several ways to "go"
|
||||
;; now do the enter
|
||||
(let ((enter-func (-> new-state enter)))
|
||||
(if enter-func
|
||||
(enter-func arg0 arg1 arg2 arg3 arg4 arg5)
|
||||
((the (function _varargs_ none) enter-func) arg0 arg1 arg2 arg3 arg4 arg5)
|
||||
)
|
||||
)
|
||||
;; now do the trans
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
(open-distance float :offset-assert 180)
|
||||
(close-distance float :offset-assert 184)
|
||||
(out-dir vector :inline :offset-assert 192)
|
||||
(open-sound uint128 :offset-assert 208)
|
||||
(close-sound uint128 :offset-assert 224)
|
||||
(open-sound sound-name :offset-assert 208)
|
||||
(close-sound sound-name :offset-assert 224)
|
||||
(state-actor basic :offset-assert 240)
|
||||
(flags int32 :offset-assert 244)
|
||||
(locked symbol :offset-assert 248)
|
||||
(auto-close symbol :offset-assert 252)
|
||||
(one-way symbol :offset-assert 256)
|
||||
(locked symbol :offset-assert 248)
|
||||
(auto-close symbol :offset-assert 252)
|
||||
(one-way symbol :offset-assert 256)
|
||||
)
|
||||
:method-count-assert 27
|
||||
:size-assert #x104
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
(touch-time uint64 :offset-assert 368)
|
||||
(nav-enemy-flags uint32 :offset-assert 376)
|
||||
(incomming-attack-id uint64 :offset-assert 384)
|
||||
(jump-return-state basic :offset-assert 392)
|
||||
(jump-return-state (state process) :offset-assert 392)
|
||||
(rand-gen random-generator :offset-assert 396)
|
||||
)
|
||||
:heap-base #x120
|
||||
@@ -97,23 +97,23 @@
|
||||
:flag-assert #x4c01200190
|
||||
;; inherited inspect of process-drawable
|
||||
(:methods
|
||||
(nav-enemy-attack () none 20) ;; state
|
||||
(nav-enemy-chase () none 21) ;; state
|
||||
(dummy-22 () none 22)
|
||||
(nav-enemy-die () none 23) ;; state
|
||||
(nav-enemy-fuel-cell () none 24) ;; state
|
||||
(nav-enemy-give-up () none 25) ;; state
|
||||
(nav-enemy-jump () none 26) ;; state
|
||||
(nav-enemy-jump-land () none 27) ;; state
|
||||
(nav-enemy-idle () none 28) ;; state
|
||||
(nav-enemy-notice () none 29) ;; state
|
||||
(nav-enemy-patrol () none 30) ;; state
|
||||
(nav-enemy-stare () none 31) ;; state
|
||||
(nav-enemy-stop-chase () none 32) ;; state
|
||||
(nav-enemy-victory () none 33) ;; state
|
||||
(nav-enemy-attack () _type_ :state 20)
|
||||
(nav-enemy-chase () _type_ :state 21)
|
||||
(nav-enemy-flee () _type_ :state 22)
|
||||
(nav-enemy-die () _type_ :state 23)
|
||||
(nav-enemy-fuel-cell () _type_ :state 24)
|
||||
(nav-enemy-give-up () _type_ :state 25)
|
||||
(nav-enemy-jump () _type_ :state 26)
|
||||
(nav-enemy-jump-land () _type_ :state 27)
|
||||
(nav-enemy-idle () _type_ :state 28)
|
||||
(nav-enemy-notice () _type_ :state 29)
|
||||
(nav-enemy-patrol () _type_ :state 30)
|
||||
(nav-enemy-stare () _type_ :state 31)
|
||||
(nav-enemy-stop-chase () _type_ :state 32)
|
||||
(nav-enemy-victory () _type_ :state 33)
|
||||
(dummy-34 (_type_) none 34)
|
||||
(dummy-35 (_type_) none 35)
|
||||
(dummy-36 (_type_) none 36)
|
||||
(nav-enemy-wait-for-cue () _type_ :state 35)
|
||||
(nav-enemy-jump-to-point () _type_ :state 36)
|
||||
(TODO-RENAME-37 (_type_) none 37)
|
||||
(TODO-RENAME-38 (_type_) none 38)
|
||||
(TODO-RENAME-39 (_type_) none 39)
|
||||
@@ -151,7 +151,7 @@
|
||||
(dummy-71 (_type_) none 71)
|
||||
(dummy-72 (_type_ process event-message-block) object 72) ;; TODO - args unknown, 3rd arg contains a touching-shapes-entry offset 16/20
|
||||
(TODO-RENAME-73 (_type_ process) symbol 73)
|
||||
(dummy-74 (_type_) none 74)
|
||||
(nav-enemy-jump-blocked () _type_ :state 74)
|
||||
(dummy-75 (_type_) none 75)
|
||||
)
|
||||
)
|
||||
|
||||
+1431
-2004
File diff suppressed because it is too large
Load Diff
@@ -26,9 +26,9 @@
|
||||
(:methods
|
||||
(plat-button-at-end () none 20) ;; state
|
||||
(dummy-21 () none 21)
|
||||
(plat-button-pressed () none 22) ;; state
|
||||
(plat-button-move-downward () none 23) ;; state
|
||||
(plat-button-move-upward () none 24) ;; state
|
||||
(plat-button-pressed () _type_ :state 22)
|
||||
(plat-button-move-downward () _type_ :state 23)
|
||||
(plat-button-move-upward () _type_ :state 24)
|
||||
(dummy-25 () none 25)
|
||||
(dummy-26 () none 26)
|
||||
(TODO-RENAME-27 (_type_) none 27)
|
||||
|
||||
@@ -379,6 +379,44 @@
|
||||
:flag-assert #x900000068
|
||||
)
|
||||
|
||||
;; definition for method 3 of type rigid-body-platform-constants
|
||||
(defmethod
|
||||
inspect
|
||||
rigid-body-platform-constants
|
||||
((obj rigid-body-platform-constants))
|
||||
(format #t "[~8x] ~A~%" obj 'rigid-body-platform-constants)
|
||||
(format #t "~Tdrag-factor: ~f~%" (-> obj drag-factor))
|
||||
(format #t "~Tbuoyancy-factor: ~f~%" (-> obj buoyancy-factor))
|
||||
(format #t "~Tmax-buoyancy-depth: (meters ~m)~%" (-> obj max-buoyancy-depth))
|
||||
(format #t "~Tgravity-factor: ~f~%" (-> obj gravity-factor))
|
||||
(format #t "~Tgravity: (meters ~m)~%" (-> obj gravity))
|
||||
(format #t "~Tplayer-weight: (meters ~m)~%" (-> obj player-weight))
|
||||
(format #t "~Tplayer-bonk-factor: ~f~%" (-> obj player-bonk-factor))
|
||||
(format #t "~Tplayer-dive-factor: ~f~%" (-> obj player-dive-factor))
|
||||
(format
|
||||
#t
|
||||
"~Tplayer-force-distance: (meters ~m)~%"
|
||||
(-> obj player-force-distance)
|
||||
)
|
||||
(format #t "~Tplayer-force-clamp: (meters ~m)~%" (-> obj player-force-clamp))
|
||||
(format #t "~Tplayer-force-timeout: ~D~%" (-> obj player-force-timeout))
|
||||
(format #t "~Texplosion-force: (meters ~m)~%" (-> obj explosion-force))
|
||||
(format #t "~Tlinear-damping: ~f~%" (-> obj linear-damping))
|
||||
(format #t "~Tangular-damping: ~f~%" (-> obj angular-damping))
|
||||
(format #t "~Tcontrol-point-count: ~D~%" (-> obj control-point-count))
|
||||
(format #t "~Tmass: ~f~%" (-> obj mass))
|
||||
(format #t "~Tinertial-tensor-x: (meters ~m)~%" (-> obj inertial-tensor-x))
|
||||
(format #t "~Tinertial-tensor-y: (meters ~m)~%" (-> obj inertial-tensor-y))
|
||||
(format #t "~Tinertial-tensor-z: (meters ~m)~%" (-> obj inertial-tensor-z))
|
||||
(format #t "~Tcm-joint-x: (meters ~m)~%" (-> obj cm-joint-x))
|
||||
(format #t "~Tcm-joint-y: (meters ~m)~%" (-> obj cm-joint-y))
|
||||
(format #t "~Tcm-joint-z: (meters ~m)~%" (-> obj cm-joint-z))
|
||||
(format #t "~Tidle-distance: (meters ~m)~%" (-> obj idle-distance))
|
||||
(format #t "~Tplatform: ~A~%" (-> obj platform))
|
||||
(format #t "~Tsound-name: ~A~%" (-> obj sound-name))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type rigid-body-control-point-inline-array
|
||||
(deftype rigid-body-control-point-inline-array (inline-array-class)
|
||||
((data rigid-body-control-point :inline :dynamic :offset 16)
|
||||
@@ -388,6 +426,18 @@
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
;; definition for method 3 of type rigid-body-control-point-inline-array
|
||||
(defmethod
|
||||
inspect
|
||||
rigid-body-control-point-inline-array
|
||||
((obj rigid-body-control-point-inline-array))
|
||||
(format #t "[~8x] ~A~%" obj (-> obj type))
|
||||
(format #t "~Tlength: ~D~%" (-> obj length))
|
||||
(format #t "~Tallocated-length: ~D~%" (-> obj allocated-length))
|
||||
(format #t "~Tdata[0] @ #x~X~%" (-> obj data))
|
||||
obj
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(set! (-> rigid-body-control-point-inline-array heap-base) (the-as uint 48))
|
||||
|
||||
@@ -414,8 +464,8 @@
|
||||
:size-assert #x2d4
|
||||
:flag-assert #x23027002d4
|
||||
(:methods
|
||||
(rigid-body-platform-idle () none 20)
|
||||
(rigid-body-platform-float () none 21)
|
||||
(rigid-body-platform-idle () _type_ :state 20)
|
||||
(rigid-body-platform-float () _type_ :state 21)
|
||||
(TODO-RENAME-22 (_type_ vector basic) float 22)
|
||||
(TODO-RENAME-23 (_type_ basic) none 23)
|
||||
(TODO-RENAME-24 (_type_ rigid-body-control-point basic) none 24)
|
||||
@@ -432,6 +482,40 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 3 of type rigid-body-platform
|
||||
(defmethod inspect rigid-body-platform ((obj rigid-body-platform))
|
||||
(let ((t9-0 (method-of-type process-drawable inspect)))
|
||||
(t9-0 obj)
|
||||
)
|
||||
(format
|
||||
#t
|
||||
"~T~Tinfo: #<rigid-body-platform-constants @ #x~X>~%"
|
||||
(-> obj info)
|
||||
)
|
||||
(format #t "~T~Trbody: #<rigid-body @ #x~X>~%" (-> obj rbody))
|
||||
(format #t "~T~Tcontrol-point-array: ~A~%" (-> obj control-point-array))
|
||||
(format #t "~T~Tplayer-velocity: #<vector @ #x~X>~%" (-> obj player-velocity))
|
||||
(format
|
||||
#t
|
||||
"~T~Tplayer-velocity-prev: #<vector @ #x~X>~%"
|
||||
(-> obj player-velocity-prev)
|
||||
)
|
||||
(format
|
||||
#t
|
||||
"~T~Tplayer-force-position: #<vector @ #x~X>~%"
|
||||
(-> obj player-force-position)
|
||||
)
|
||||
(format #t "~T~Tplayer-force: #<vector @ #x~X>~%" (-> obj player-force))
|
||||
(format #t "~T~Tsim-time-remaining: ~f~%" (-> obj sim-time-remaining))
|
||||
(format #t "~T~Tfloat-height-offset: ~f~%" (-> obj float-height-offset))
|
||||
(format #t "~T~Tplayer-attack-id: ~D~%" (-> obj player-attack-id))
|
||||
(format #t "~T~Tplayer-bonk-timeout: ~D~%" (-> obj player-bonk-timeout))
|
||||
(format #t "~T~Twater-anim: ~A~%" (-> obj water-anim))
|
||||
(format #t "~T~Tplayer-contact: ~A~%" (-> obj player-contact))
|
||||
(format #t "~T~Tplayer-impulse: ~A~%" (-> obj player-impulse))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for method 7 of type rigid-body-platform
|
||||
;; INFO: Return type mismatch process-drawable vs rigid-body-platform.
|
||||
(defmethod relocate rigid-body-platform ((obj rigid-body-platform) (arg0 int))
|
||||
@@ -647,7 +731,6 @@
|
||||
)
|
||||
|
||||
;; definition for function rigid-body-platform-event-handler
|
||||
;; INFO: Return type mismatch vector vs object.
|
||||
;; Used lq/sq
|
||||
(defbehavior
|
||||
rigid-body-platform-event-handler rigid-body-platform
|
||||
@@ -897,113 +980,71 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((gp-0
|
||||
(new 'static 'state
|
||||
:name 'rigid-body-platform-idle
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(method-set! rigid-body-platform 20 (the-as function gp-0))
|
||||
(set!
|
||||
(-> gp-0 trans)
|
||||
(the-as
|
||||
(function object)
|
||||
(lambda :behavior rigid-body-platform
|
||||
()
|
||||
(when
|
||||
(and
|
||||
*target*
|
||||
(>=
|
||||
(-> self info idle-distance)
|
||||
(vector-vector-distance
|
||||
(-> self root-overlay trans)
|
||||
(-> *target* control trans)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((t9-1 (the-as (function object) enter-state)))
|
||||
(set!
|
||||
(-> self next-state)
|
||||
(the-as state (method-of-object self rigid-body-platform-float))
|
||||
)
|
||||
(t9-1)
|
||||
(defstate rigid-body-platform-idle (rigid-body-platform)
|
||||
:virtual #t
|
||||
:trans
|
||||
(behavior ()
|
||||
(if
|
||||
(and
|
||||
*target*
|
||||
(>=
|
||||
(-> self info idle-distance)
|
||||
(vector-vector-distance
|
||||
(-> self root-overlay trans)
|
||||
(-> *target* control trans)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(go-virtual rigid-body-platform-float)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set! (-> gp-0 code) (lambda :behavior rigid-body-platform () (while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
:code
|
||||
(behavior ()
|
||||
(while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set! (-> gp-0 post) ja-post)
|
||||
:post
|
||||
(the-as (function none :behavior rigid-body-platform) ja-post)
|
||||
)
|
||||
|
||||
;; TODO - something here is causing the tests to crash!
|
||||
; (let
|
||||
; ((gp-1
|
||||
; (new 'static 'state
|
||||
; :name 'rigid-body-platform-float
|
||||
; :next #f
|
||||
; :exit #f
|
||||
; :code #f
|
||||
; :trans #f
|
||||
; :post #f
|
||||
; :enter #f
|
||||
; :event #f
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; (method-set! rigid-body-platform 21 (the-as function gp-1))
|
||||
; (set! (-> gp-1 event) rigid-body-platform-event-handler)
|
||||
; (set!
|
||||
; (-> gp-1 trans)
|
||||
; (the-as
|
||||
; (function object)
|
||||
; (lambda :behavior rigid-body-platform
|
||||
; ()
|
||||
; (when
|
||||
; (or
|
||||
; (not *target*)
|
||||
; (<
|
||||
; (-> self info idle-distance)
|
||||
; (vector-vector-distance
|
||||
; (-> self root-overlay trans)
|
||||
; (-> *target* control trans)
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; (let ((t9-1 (the-as (function object) enter-state)))
|
||||
; (set!
|
||||
; (-> self next-state)
|
||||
; (the-as state (method-of-object self rigid-body-platform-idle))
|
||||
; )
|
||||
; (t9-1)
|
||||
; )
|
||||
; )
|
||||
; (none)
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; (set! (-> gp-1 code) (lambda :behavior rigid-body-platform () (while #t
|
||||
; (suspend)
|
||||
; )
|
||||
; (none)
|
||||
; )
|
||||
; )
|
||||
; (set! (-> gp-1 post) rigid-body-platform-post)
|
||||
; )
|
||||
;; failed to figure out what this is:
|
||||
(defstate rigid-body-platform-float (rigid-body-platform)
|
||||
:virtual #t
|
||||
:event
|
||||
rigid-body-platform-event-handler
|
||||
:trans
|
||||
(behavior ()
|
||||
(if
|
||||
(or
|
||||
(not *target*)
|
||||
(<
|
||||
(-> self info idle-distance)
|
||||
(vector-vector-distance
|
||||
(-> self root-overlay trans)
|
||||
(-> *target* control trans)
|
||||
)
|
||||
)
|
||||
)
|
||||
(go-virtual rigid-body-platform-idle)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
:code
|
||||
(behavior ()
|
||||
(while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
:post
|
||||
(the-as
|
||||
(function none :behavior rigid-body-platform)
|
||||
rigid-body-platform-post
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 29 of type rigid-body-platform
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
@@ -1132,17 +1173,9 @@
|
||||
;; definition for method 34 of type rigid-body-platform
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
(defmethod TODO-RENAME-34 rigid-body-platform ((obj rigid-body-platform))
|
||||
(with-pp
|
||||
(let ((t9-0 (the-as (function object) enter-state)))
|
||||
(set!
|
||||
(-> pp next-state)
|
||||
(the-as state (method-of-object obj rigid-body-platform-idle))
|
||||
)
|
||||
(t9-0)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
(go (method-of-object obj rigid-body-platform-idle))
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for method 31 of type rigid-body-platform
|
||||
@@ -1179,4 +1212,4 @@
|
||||
(TODO-RENAME-34 obj)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
)
|
||||
@@ -867,6 +867,15 @@
|
||||
:flag-assert #x90000000c
|
||||
)
|
||||
|
||||
;; definition for method 3 of type water-anim-look
|
||||
(defmethod inspect water-anim-look ((obj water-anim-look))
|
||||
(format #t "[~8x] ~A~%" obj 'water-anim-look)
|
||||
(format #t "~Tskel-group: ~A~%" (-> obj skel-group))
|
||||
(format #t "~Tanim: ~D~%" (-> obj anim))
|
||||
(format #t "~Tambient-sound-spec: ~A~%" (-> obj ambient-sound-spec))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for symbol *water-anim-look*, type (array water-anim-look)
|
||||
(define
|
||||
*water-anim-look*
|
||||
@@ -1766,88 +1775,54 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; TODO - something here is causing the tests to crash!
|
||||
; (let
|
||||
; ((gp-0
|
||||
; (new 'static 'state
|
||||
; :name 'water-vol-idle
|
||||
; :next #f
|
||||
; :exit #f
|
||||
; :code #f
|
||||
; :trans #f
|
||||
; :post #f
|
||||
; :enter #f
|
||||
; :event #f
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; (inherit-state gp-0 (the-as state (method-of-type water-vol water-vol-idle)))
|
||||
; (method-set! water-anim 20 (the-as function gp-0))
|
||||
; (set!
|
||||
; (-> gp-0 event)
|
||||
; (lambda :behavior water-anim
|
||||
; ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
; (case arg2
|
||||
; (('move-to)
|
||||
; (set!
|
||||
; (-> self root trans quad)
|
||||
; (-> (the-as vector (-> arg3 param 0)) quad)
|
||||
; )
|
||||
; (set! (-> self water-height) (-> self root trans y))
|
||||
; (if (nonzero? (-> self sound))
|
||||
; (update-trans! (-> self sound) (-> self root trans))
|
||||
; )
|
||||
; (let ((v0-0 (logclear (-> self mask) (process-mask sleep-code))))
|
||||
; (set! (-> self mask) v0-0)
|
||||
; v0-0
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; (set!
|
||||
; (-> gp-0 trans)
|
||||
; (the-as
|
||||
; (function object)
|
||||
; (lambda :behavior water-anim
|
||||
; ()
|
||||
; (let
|
||||
; ((t9-0
|
||||
; (->
|
||||
; (the-as (state none) (method-of-type water-vol water-vol-idle))
|
||||
; trans
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; (if t9-0
|
||||
; (t9-0)
|
||||
; )
|
||||
; )
|
||||
; (if (< (-> (math-camera-pos) y) (+ -8192.0 (-> self root trans y)))
|
||||
; (logior! (-> self draw status) 2)
|
||||
; (set! (-> self draw status) (logand -3 (-> self draw status)))
|
||||
; )
|
||||
; (if (and (-> self play-ambient-sound?) (nonzero? (-> self sound)))
|
||||
; (update! (-> self sound))
|
||||
; )
|
||||
; (none)
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
; (set! (-> gp-0 code) (lambda :behavior water-anim () (while #t
|
||||
; (ja-post)
|
||||
; (logior!
|
||||
; (-> self mask)
|
||||
; (process-mask
|
||||
; sleep-code
|
||||
; )
|
||||
; )
|
||||
; (suspend)
|
||||
; )
|
||||
; (none)
|
||||
; )
|
||||
; )
|
||||
; )
|
||||
;; failed to figure out what this is:
|
||||
(defstate water-vol-idle (water-anim)
|
||||
:virtual #t
|
||||
:event
|
||||
(behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(case arg2
|
||||
(('move-to)
|
||||
(set!
|
||||
(-> self root trans quad)
|
||||
(-> (the-as vector (-> arg3 param 0)) quad)
|
||||
)
|
||||
(set! (-> self water-height) (-> self root trans y))
|
||||
(if (nonzero? (-> self sound))
|
||||
(update-trans! (-> self sound) (-> self root trans))
|
||||
)
|
||||
(let ((v0-0 (logclear (-> self mask) (process-mask sleep-code))))
|
||||
(set! (-> self mask) v0-0)
|
||||
v0-0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
:trans
|
||||
(behavior ()
|
||||
(let ((t9-0 (-> (method-of-type water-vol water-vol-idle) trans)))
|
||||
(if t9-0
|
||||
(t9-0)
|
||||
)
|
||||
)
|
||||
(if (< (-> (math-camera-pos) y) (+ -8192.0 (-> self root trans y)))
|
||||
(logior! (-> self draw status) 2)
|
||||
(set! (-> self draw status) (logand -3 (-> self draw status)))
|
||||
)
|
||||
(if (and (-> self play-ambient-sound?) (nonzero? (-> self sound)))
|
||||
(update! (-> self sound))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
:code
|
||||
(behavior ()
|
||||
(while #t
|
||||
(ja-post)
|
||||
(logior! (-> self mask) (process-mask sleep-code))
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 28 of type water-anim
|
||||
(defmethod get-ripple-height water-anim ((obj water-anim) (arg0 vector))
|
||||
@@ -1928,58 +1903,46 @@
|
||||
;; definition for method 22 of type water-anim
|
||||
;; INFO: Return type mismatch int vs ripple-wave-set.
|
||||
(defmethod TODO-RENAME-22 water-anim ((obj water-anim))
|
||||
(with-pp
|
||||
(let ((s5-0 (-> obj look)))
|
||||
(when (or (< s5-0 0) (>= s5-0 (-> *water-anim-look* length)))
|
||||
(let ((t9-0 (the-as (function object object) enter-state))
|
||||
(a0-2 "skel group")
|
||||
)
|
||||
(set! (-> pp next-state) process-drawable-art-error)
|
||||
(t9-0 a0-2)
|
||||
)
|
||||
)
|
||||
(let ((s5-1 (-> *water-anim-look* s5-0)))
|
||||
(let ((s4-0 (-> s5-1 skel-group value)))
|
||||
(let ((s3-0 s4-0))
|
||||
(when
|
||||
(not
|
||||
(if
|
||||
(and
|
||||
(nonzero? s3-0)
|
||||
(type-type? (-> (the-as basic s3-0) type) skeleton-group)
|
||||
)
|
||||
s3-0
|
||||
(let ((s5-0 (-> obj look)))
|
||||
(if (or (< s5-0 0) (>= s5-0 (-> *water-anim-look* length)))
|
||||
(go process-drawable-art-error "skel group")
|
||||
)
|
||||
(let ((s5-1 (-> *water-anim-look* s5-0)))
|
||||
(let ((s4-0 (-> s5-1 skel-group value)))
|
||||
(let ((s3-0 s4-0))
|
||||
(if
|
||||
(not
|
||||
(if
|
||||
(and
|
||||
(nonzero? s3-0)
|
||||
(type-type? (-> (the-as basic s3-0) type) skeleton-group)
|
||||
)
|
||||
)
|
||||
(let ((t9-2 (the-as (function object object) enter-state))
|
||||
(a0-5 "skel group")
|
||||
)
|
||||
(set! (-> pp next-state) process-drawable-art-error)
|
||||
(t9-2 a0-5)
|
||||
s3-0
|
||||
)
|
||||
)
|
||||
(go process-drawable-art-error "skel group")
|
||||
)
|
||||
(dummy-14 obj (the-as skeleton-group s4-0) '())
|
||||
)
|
||||
(ja-channel-set! 1)
|
||||
(let ((s4-1 (-> obj skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
s4-1
|
||||
(the-as art-joint-anim (-> obj draw art-group data (-> s5-1 anim)))
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> s4-1 frame-num) 0.0)
|
||||
(dummy-14 obj (the-as skeleton-group s4-0) '())
|
||||
)
|
||||
(ja-channel-set! 1)
|
||||
(let ((s4-1 (-> obj skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
s4-1
|
||||
(the-as art-joint-anim (-> obj draw art-group data (-> s5-1 anim)))
|
||||
num-func-identity
|
||||
)
|
||||
(let ((a2-2 (-> s5-1 ambient-sound-spec)))
|
||||
(when a2-2
|
||||
(let ((a3-0 (new 'stack-no-clear 'vector)))
|
||||
(vector+! a3-0 (-> obj root trans) (-> obj draw bounds))
|
||||
(set! (-> obj sound) (new 'process 'ambient-sound a2-2 a3-0))
|
||||
)
|
||||
(set! (-> s4-1 frame-num) 0.0)
|
||||
)
|
||||
(let ((a2-2 (-> s5-1 ambient-sound-spec)))
|
||||
(when a2-2
|
||||
(let ((a3-0 (new 'stack-no-clear 'vector)))
|
||||
(vector+! a3-0 (-> obj root trans) (-> obj draw bounds))
|
||||
(set! (-> obj sound) (new 'process 'ambient-sound a2-2 a3-0))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(the-as ripple-wave-set (ja-post))
|
||||
)
|
||||
)
|
||||
(the-as ripple-wave-set (ja-post))
|
||||
)
|
||||
@@ -17,10 +17,12 @@
|
||||
:flag-assert #x14005000bc
|
||||
)
|
||||
|
||||
|
||||
(define-extern *teetertotter-sg* skeleton-group)
|
||||
(define-extern teetertotter-idle (state none)) ;; unknown type
|
||||
(define-extern teetertotter-launch (state none)) ;; unknown type
|
||||
(define-extern teetertotter-bend (state none)) ;; unknown type
|
||||
(define-extern teetertotter-idle (state teetertotter))
|
||||
(define-extern teetertotter-launch (state teetertotter))
|
||||
(define-extern teetertotter-bend (state teetertotter))
|
||||
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
@@ -70,295 +72,233 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-3
|
||||
(new 'static 'state
|
||||
:name 'teetertotter-idle
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! teetertotter-idle (the-as (state none) v1-3))
|
||||
(set!
|
||||
(-> v1-3 event)
|
||||
(lambda :behavior teetertotter
|
||||
((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(let ((v1-0 arg2))
|
||||
(the-as object (cond
|
||||
((= v1-0 'attack)
|
||||
(case (-> arg3 param 1)
|
||||
(('flop)
|
||||
(when (target-on-end-of-teetertotter? self)
|
||||
(set! (-> self in-launch-window) #f)
|
||||
(increment-success-for-hint
|
||||
(the-as level-hint-control 676)
|
||||
)
|
||||
(go teetertotter-launch)
|
||||
(defstate teetertotter-idle (teetertotter)
|
||||
:event
|
||||
(behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(let ((v1-0 arg2))
|
||||
(the-as object (cond
|
||||
((= v1-0 'attack)
|
||||
(case (-> arg3 param 1)
|
||||
(('flop)
|
||||
(when (target-on-end-of-teetertotter? self)
|
||||
(set! (-> self in-launch-window) #f)
|
||||
(increment-success-for-hint
|
||||
(the-as level-hint-control 676)
|
||||
)
|
||||
(go teetertotter-launch)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= v1-0 'bonk)
|
||||
(when (target-on-end-of-teetertotter? self)
|
||||
(level-hint-spawn
|
||||
(game-text-id misty-teetertotter-bonk-dax-tutorial)
|
||||
"sksp0070"
|
||||
#f
|
||||
*entity-pool*
|
||||
0
|
||||
)
|
||||
(go teetertotter-bend)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= v1-0 'bonk)
|
||||
(when (target-on-end-of-teetertotter? self)
|
||||
(level-hint-spawn
|
||||
(game-text-id misty-teetertotter-bonk-dax-tutorial)
|
||||
"sksp0070"
|
||||
#f
|
||||
*entity-pool*
|
||||
0
|
||||
)
|
||||
(go teetertotter-bend)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> v1-3 code)
|
||||
(lambda :behavior teetertotter () (let ((gp-0 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-0
|
||||
(the-as
|
||||
art-joint-anim
|
||||
(-> self draw art-group data 4)
|
||||
)
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> gp-0 frame-num) 0.0)
|
||||
)
|
||||
(while #t
|
||||
(suspend)
|
||||
:code
|
||||
(behavior ()
|
||||
(let ((gp-0 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-0
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
num-func-identity
|
||||
)
|
||||
(none)
|
||||
(set! (-> gp-0 frame-num) 0.0)
|
||||
)
|
||||
(while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-3 post) transform-post)
|
||||
:post
|
||||
(the-as (function none :behavior teetertotter) transform-post)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-4
|
||||
(new 'static 'state
|
||||
:name 'teetertotter-launch
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! teetertotter-launch (the-as (state none) v1-4))
|
||||
(set!
|
||||
(-> v1-4 event)
|
||||
(lambda :behavior teetertotter
|
||||
((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(when (= arg2 'touch)
|
||||
(when
|
||||
(and
|
||||
((method-of-type touching-shapes-entry prims-touching?)
|
||||
(the-as touching-shapes-entry (-> arg3 param 0))
|
||||
(the-as collide-shape-moving (-> self root))
|
||||
(the-as uint 1)
|
||||
)
|
||||
(-> self rock-is-dangerous)
|
||||
)
|
||||
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-2 from) self)
|
||||
(set! (-> a1-2 num-params) 2)
|
||||
(set! (-> a1-2 message) 'attack)
|
||||
(set! (-> a1-2 param 0) (-> arg3 param 0))
|
||||
(let ((a0-2 (new 'static 'attack-info :mask #x20)))
|
||||
(set! (-> a0-2 mode) 'deadly)
|
||||
(set! (-> a1-2 param 1) (the-as uint a0-2))
|
||||
)
|
||||
(send-event-function arg0 a1-2)
|
||||
(defstate teetertotter-launch (teetertotter)
|
||||
:event
|
||||
(behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(when (= arg2 'touch)
|
||||
(when
|
||||
(and
|
||||
((method-of-type touching-shapes-entry prims-touching?)
|
||||
(the-as touching-shapes-entry (-> arg3 param 0))
|
||||
(the-as collide-shape-moving (-> self root))
|
||||
(the-as uint 1)
|
||||
)
|
||||
(-> self rock-is-dangerous)
|
||||
)
|
||||
(when
|
||||
(and
|
||||
((method-of-type touching-shapes-entry prims-touching?)
|
||||
(the-as touching-shapes-entry (-> arg3 param 0))
|
||||
(the-as collide-shape-moving (-> self root))
|
||||
(the-as uint 2)
|
||||
)
|
||||
(target-on-end-of-teetertotter? self)
|
||||
(not (-> self launched-player))
|
||||
(-> self in-launch-window)
|
||||
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-2 from) self)
|
||||
(set! (-> a1-2 num-params) 2)
|
||||
(set! (-> a1-2 message) 'attack)
|
||||
(set! (-> a1-2 param 0) (-> arg3 param 0))
|
||||
(let ((a0-2 (new 'static 'attack-info :mask #x20)))
|
||||
(set! (-> a0-2 mode) 'deadly)
|
||||
(set! (-> a1-2 param 1) (the-as uint a0-2))
|
||||
)
|
||||
(let ((a1-4 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-4 from) self)
|
||||
(set! (-> a1-4 num-params) 2)
|
||||
(set! (-> a1-4 message) 'shove)
|
||||
(set! (-> a1-4 param 0) (the-as uint #f))
|
||||
(let ((v1-16 (new 'static 'attack-info :mask #xcc0)))
|
||||
(set! (-> v1-16 shove-back) 0.0)
|
||||
(set! (-> v1-16 shove-up) 53248.0)
|
||||
(set! (-> v1-16 angle) 'jump)
|
||||
(set! (-> v1-16 control) 1.0)
|
||||
(set! (-> a1-4 param 1) (the-as uint v1-16))
|
||||
)
|
||||
(when (send-event-function arg0 a1-4)
|
||||
(let ((v0-0 #t))
|
||||
(set! (-> self launched-player) v0-0)
|
||||
v0-0
|
||||
)
|
||||
(send-event-function arg0 a1-2)
|
||||
)
|
||||
)
|
||||
(when
|
||||
(and
|
||||
((method-of-type touching-shapes-entry prims-touching?)
|
||||
(the-as touching-shapes-entry (-> arg3 param 0))
|
||||
(the-as collide-shape-moving (-> self root))
|
||||
(the-as uint 2)
|
||||
)
|
||||
(target-on-end-of-teetertotter? self)
|
||||
(not (-> self launched-player))
|
||||
(-> self in-launch-window)
|
||||
)
|
||||
(let ((a1-4 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-4 from) self)
|
||||
(set! (-> a1-4 num-params) 2)
|
||||
(set! (-> a1-4 message) 'shove)
|
||||
(set! (-> a1-4 param 0) (the-as uint #f))
|
||||
(let ((v1-16 (new 'static 'attack-info :mask #xcc0)))
|
||||
(set! (-> v1-16 shove-back) 0.0)
|
||||
(set! (-> v1-16 shove-up) 53248.0)
|
||||
(set! (-> v1-16 angle) 'jump)
|
||||
(set! (-> v1-16 control) 1.0)
|
||||
(set! (-> a1-4 param 1) (the-as uint v1-16))
|
||||
)
|
||||
(when (send-event-function arg0 a1-4)
|
||||
(let ((v0-0 #t))
|
||||
(set! (-> self launched-player) v0-0)
|
||||
v0-0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> v1-4 code)
|
||||
(lambda :behavior teetertotter
|
||||
()
|
||||
(local-vars (v1-16 symbol) (f0-4 float))
|
||||
(set! (-> self launched-player) #f)
|
||||
(let ((a0-0 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-0 frame-group)
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
)
|
||||
(set!
|
||||
(-> a0-0 param 0)
|
||||
(the
|
||||
float
|
||||
(+
|
||||
(->
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
data
|
||||
0
|
||||
length
|
||||
)
|
||||
-1
|
||||
:code
|
||||
(behavior ()
|
||||
(local-vars (v1-16 symbol) (f0-4 float))
|
||||
(set! (-> self launched-player) #f)
|
||||
(let ((a0-0 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-0 frame-group)
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
)
|
||||
(set!
|
||||
(-> a0-0 param 0)
|
||||
(the
|
||||
float
|
||||
(+
|
||||
(->
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
data
|
||||
0
|
||||
length
|
||||
)
|
||||
-1
|
||||
)
|
||||
)
|
||||
(set! (-> a0-0 param 1) 1.0)
|
||||
(set! (-> a0-0 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-0
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(until (begin
|
||||
(set! (-> self rock-is-dangerous) (and v1-16 (>= 76.0 f0-4)))
|
||||
(suspend)
|
||||
(let ((a0-2 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-2 param 0)
|
||||
(the float (+ (-> a0-2 frame-group data 0 length) -1))
|
||||
)
|
||||
(set! (-> a0-2 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-2
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
(set! (-> a0-0 param 1) 1.0)
|
||||
(set! (-> a0-0 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-0
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(until (begin
|
||||
(set! (-> self rock-is-dangerous) (and v1-16 (>= 76.0 f0-4)))
|
||||
(suspend)
|
||||
(let ((a0-2 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-2 param 0)
|
||||
(the float (+ (-> a0-2 frame-group data 0 length) -1))
|
||||
)
|
||||
(set! (-> a0-2 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-2
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(set! f0-4 (ja-aframe-num 0))
|
||||
(set! (-> self in-launch-window) (and (>= f0-4 76.0) (>= 82.0 f0-4)))
|
||||
(set! v1-16 (>= f0-4 12.0))
|
||||
)
|
||||
(go teetertotter-idle)
|
||||
(none)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(set! f0-4 (ja-aframe-num 0))
|
||||
(set! (-> self in-launch-window) (and (>= f0-4 76.0) (>= 82.0 f0-4)))
|
||||
(set! v1-16 (>= f0-4 12.0))
|
||||
)
|
||||
(go teetertotter-idle)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-4 post) rider-post)
|
||||
:post
|
||||
(the-as (function none :behavior teetertotter) rider-post)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-5
|
||||
(new 'static 'state
|
||||
:name 'teetertotter-bend
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
(defstate teetertotter-bend (teetertotter)
|
||||
:code
|
||||
(behavior ()
|
||||
(let ((a0-0 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-0 frame-group)
|
||||
(the-as art-joint-anim (-> self draw art-group data 5))
|
||||
)
|
||||
(set!
|
||||
(-> a0-0 param 0)
|
||||
(the
|
||||
float
|
||||
(+
|
||||
(->
|
||||
(the-as art-joint-anim (-> self draw art-group data 5))
|
||||
data
|
||||
0
|
||||
length
|
||||
)
|
||||
-1
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> a0-0 param 1) 1.0)
|
||||
(set! (-> a0-0 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-0
|
||||
(the-as art-joint-anim (-> self draw art-group data 5))
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! teetertotter-bend (the-as (state none) v1-5))
|
||||
(set!
|
||||
(-> v1-5 code)
|
||||
(lambda :behavior teetertotter () (let ((a0-0 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-0 frame-group)
|
||||
(the-as
|
||||
art-joint-anim
|
||||
(-> self draw art-group data 5)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> a0-0 param 0)
|
||||
(the
|
||||
float
|
||||
(+
|
||||
(->
|
||||
(the-as
|
||||
art-joint-anim
|
||||
(-> self draw art-group data 5)
|
||||
)
|
||||
data
|
||||
0
|
||||
length
|
||||
)
|
||||
-1
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> a0-0 param 1) 1.0)
|
||||
(set! (-> a0-0 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-0
|
||||
(the-as
|
||||
art-joint-anim
|
||||
(-> self draw art-group data 5)
|
||||
)
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(until (begin
|
||||
(suspend)
|
||||
(let ((a0-1 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-1 param 0)
|
||||
(the float (+ (-> a0-1 frame-group data 0 length) -1))
|
||||
)
|
||||
(set! (-> a0-1 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-1
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
(until (begin
|
||||
(suspend)
|
||||
(let ((a0-1 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-1 param 0)
|
||||
(the float (+ (-> a0-1 frame-group data 0 length) -1))
|
||||
)
|
||||
(set! (-> a0-1 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-1
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
(go teetertotter-idle)
|
||||
(none)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
(go teetertotter-idle)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-5 post) rider-post)
|
||||
:post
|
||||
(the-as (function none :behavior teetertotter) rider-post)
|
||||
)
|
||||
|
||||
;; definition for method 11 of type teetertotter
|
||||
@@ -478,4 +418,4 @@
|
||||
(set! (-> obj rock-is-dangerous) #f)
|
||||
(go teetertotter-idle)
|
||||
(none)
|
||||
)
|
||||
)
|
||||
@@ -7,9 +7,7 @@
|
||||
|
||||
(define-extern *rounddoor-sg* skeleton-group)
|
||||
(define-extern *silostep-sg* skeleton-group)
|
||||
(define-extern silostep-rise (state none)) ;; unknown type
|
||||
(define-extern silostep-idle (state none)) ;; unknown type
|
||||
(define-extern silostep-camera (state none)) ;; unknown type
|
||||
|
||||
|
||||
;; definition of type silostep
|
||||
(deftype silostep (process-drawable)
|
||||
@@ -22,6 +20,11 @@
|
||||
:flag-assert #x14005000c0
|
||||
)
|
||||
|
||||
(define-extern silostep-rise (state symbol silostep))
|
||||
(define-extern silostep-idle (state silostep))
|
||||
(define-extern silostep-camera (state silostep))
|
||||
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-1
|
||||
@@ -41,61 +44,39 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-2
|
||||
(new 'static 'state
|
||||
:name 'silostep-idle
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
(defstate silostep-idle (silostep)
|
||||
:event
|
||||
(behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(let ((v1-0 arg2))
|
||||
(the-as object (cond
|
||||
((= v1-0 'trigger)
|
||||
(go silostep-camera)
|
||||
)
|
||||
((= v1-0 'trigger-rise)
|
||||
(go silostep-rise #f)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! silostep-idle (the-as (state none) v1-2))
|
||||
(set!
|
||||
(-> v1-2 event)
|
||||
(the-as
|
||||
(function process int symbol event-message-block object)
|
||||
(lambda :behavior silostep
|
||||
((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(case arg2
|
||||
(('trigger)
|
||||
(go silostep-camera)
|
||||
)
|
||||
(('trigger-rise)
|
||||
enter-state
|
||||
(go silostep-rise)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
:code
|
||||
(behavior ()
|
||||
(let ((gp-0 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-0
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> gp-0 frame-num) 0.0)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> v1-2 code)
|
||||
(lambda :behavior silostep () (let ((gp-0 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-0
|
||||
(the-as
|
||||
art-joint-anim
|
||||
(-> self draw art-group data 2)
|
||||
)
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> gp-0 frame-num) 0.0)
|
||||
)
|
||||
(transform-post)
|
||||
(while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
(transform-post)
|
||||
(while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-2 post) ja-post)
|
||||
:post
|
||||
(the-as (function none :behavior silostep) ja-post)
|
||||
)
|
||||
|
||||
;; definition for function misty-camera-view
|
||||
@@ -159,129 +140,96 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-4
|
||||
(new 'static 'state
|
||||
:name 'silostep-camera
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
(defstate silostep-camera (silostep)
|
||||
:code
|
||||
(behavior ()
|
||||
(misty-camera-view)
|
||||
(let* ((gp-0 (get-task-control (game-task misty-warehouse)))
|
||||
(v1-1 (get-reminder gp-0 0))
|
||||
)
|
||||
(save-reminder gp-0 (logior v1-1 2) 0)
|
||||
)
|
||||
(set! (-> self state-time) (-> *display* base-frame-counter))
|
||||
(let ((gp-1 (-> *display* base-frame-counter)))
|
||||
(until (begin
|
||||
(suspend)
|
||||
(>= (the-as int (- (-> *display* base-frame-counter) gp-1)) 300)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! silostep-camera (the-as (state none) v1-4))
|
||||
(set!
|
||||
(-> v1-4 code)
|
||||
(lambda :behavior silostep
|
||||
()
|
||||
(misty-camera-view)
|
||||
(let* ((gp-0 (get-task-control (game-task misty-warehouse)))
|
||||
(v1-1 (get-reminder gp-0 0))
|
||||
)
|
||||
(save-reminder gp-0 (logior v1-1 2) 0)
|
||||
)
|
||||
(set! (-> self state-time) (-> *display* base-frame-counter))
|
||||
(let ((gp-1 (-> *display* base-frame-counter)))
|
||||
(until (begin
|
||||
(suspend)
|
||||
(>= (the-as int (- (-> *display* base-frame-counter) gp-1)) 300)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
)
|
||||
(sound-play-by-name
|
||||
(static-sound-name "arena-steps")
|
||||
(new-sound-id)
|
||||
1024
|
||||
0
|
||||
0
|
||||
(the-as uint 1)
|
||||
(the-as vector #t)
|
||||
)
|
||||
(send-to-all-after (-> self link) 'trigger-rise)
|
||||
enter-state
|
||||
(go silostep-rise)
|
||||
(none)
|
||||
(sound-play-by-name
|
||||
(static-sound-name "arena-steps")
|
||||
(new-sound-id)
|
||||
1024
|
||||
0
|
||||
0
|
||||
(the-as uint 1)
|
||||
(the-as vector #t)
|
||||
)
|
||||
(send-to-all-after (-> self link) 'trigger-rise)
|
||||
(go silostep-rise #f)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-4 post) ja-post)
|
||||
:post
|
||||
(the-as (function none :behavior silostep) ja-post)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-5
|
||||
(new 'static 'state
|
||||
:name 'silostep-rise
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! silostep-rise (the-as (state none) v1-5))
|
||||
(set!
|
||||
(-> v1-5 code)
|
||||
(lambda :behavior silostep
|
||||
((arg0 symbol))
|
||||
(process-entity-status! self (entity-perm-status complete) #t)
|
||||
(when (not arg0)
|
||||
(let ((a0-2 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-2 frame-group)
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
)
|
||||
(set! (-> a0-2 param 0) (-> self anim-limit))
|
||||
(set! (-> a0-2 param 1) 1.0)
|
||||
(set! (-> a0-2 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-2
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(until (begin
|
||||
(rider-trans)
|
||||
(rider-post)
|
||||
(suspend)
|
||||
(let ((a0-3 (-> self skel root-channel 0)))
|
||||
(set! (-> a0-3 param 0) (-> self anim-limit))
|
||||
(set! (-> a0-3 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-3
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
)
|
||||
(let ((gp-1 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-1
|
||||
(defstate silostep-rise (silostep)
|
||||
:code
|
||||
(behavior ((arg0 symbol))
|
||||
(process-entity-status! self (entity-perm-status complete) #t)
|
||||
(when (not arg0)
|
||||
(let ((a0-2 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-2 frame-group)
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> gp-1 frame-num) (-> self anim-limit))
|
||||
(set! (-> a0-2 param 0) (-> self anim-limit))
|
||||
(set! (-> a0-2 param 1) 1.0)
|
||||
(set! (-> a0-2 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-2
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(rider-post)
|
||||
(while #t
|
||||
(ja-post)
|
||||
(suspend)
|
||||
(until (begin
|
||||
(rider-trans)
|
||||
(rider-post)
|
||||
(suspend)
|
||||
(let ((a0-3 (-> self skel root-channel 0)))
|
||||
(set! (-> a0-3 param 0) (-> self anim-limit))
|
||||
(set! (-> a0-3 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-3
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(let ((gp-1 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-1
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> gp-1 frame-num) (-> self anim-limit))
|
||||
)
|
||||
(rider-post)
|
||||
(while #t
|
||||
(ja-post)
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-5 post) #f)
|
||||
:post
|
||||
(the-as (function none :behavior silostep) #f)
|
||||
)
|
||||
|
||||
;; definition for method 11 of type silostep
|
||||
@@ -346,20 +294,15 @@
|
||||
)
|
||||
)
|
||||
(set! (-> obj link) (new 'process 'actor-link-info obj))
|
||||
(cond
|
||||
((and
|
||||
(-> obj entity)
|
||||
(nonzero?
|
||||
(logand (-> obj entity extra perm status) (entity-perm-status complete))
|
||||
)
|
||||
(if
|
||||
(and
|
||||
(-> obj entity)
|
||||
(nonzero?
|
||||
(logand (-> obj entity extra perm status) (entity-perm-status complete))
|
||||
)
|
||||
enter-state
|
||||
#t
|
||||
(go silostep-rise)
|
||||
)
|
||||
(else
|
||||
(go silostep-idle)
|
||||
)
|
||||
(go silostep-rise #t)
|
||||
(go silostep-idle)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
@@ -440,20 +383,8 @@
|
||||
(dummy-14 obj *rounddoor-sg* '())
|
||||
(set! (-> obj open-distance) 69632.0)
|
||||
(set! (-> obj close-distance) 81920.0)
|
||||
(set!
|
||||
(-> obj open-sound)
|
||||
(the-as
|
||||
uint128
|
||||
(make-u128 (the-as uint #x6e65706f2d72) (the-as uint #x6f6f64616e657261))
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> obj close-sound)
|
||||
(the-as
|
||||
uint128
|
||||
(make-u128 (the-as uint #x65736f6c632d72) (the-as uint #x6f6f64616e657261))
|
||||
)
|
||||
)
|
||||
(set! (-> obj open-sound) (static-sound-name "arenadoor-open"))
|
||||
(set! (-> obj close-sound) (static-sound-name "arenadoor-close"))
|
||||
(set! (-> obj speed) 1.5)
|
||||
(set! (-> obj auto-close) #t)
|
||||
(set! (-> obj one-way) #t)
|
||||
@@ -465,4 +396,4 @@
|
||||
(dummy-47 (-> obj root-override))
|
||||
0
|
||||
(none)
|
||||
)
|
||||
)
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
(define-extern *sunken-elevator-sg* skeleton-group)
|
||||
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-1
|
||||
@@ -57,284 +58,180 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((gp-0
|
||||
(new 'static 'state
|
||||
:name 'plat-button-pressed
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
(defstate plat-button-pressed (sunken-elevator)
|
||||
:virtual #t
|
||||
:enter
|
||||
(behavior ()
|
||||
(let ((t9-0 (-> (method-of-type plat-button plat-button-pressed) enter)))
|
||||
(if t9-0
|
||||
(t9-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(inherit-state
|
||||
gp-0
|
||||
(the-as state (method-of-type plat-button plat-button-pressed))
|
||||
)
|
||||
(method-set! sunken-elevator 22 (the-as function gp-0))
|
||||
(set!
|
||||
(-> gp-0 enter)
|
||||
(the-as
|
||||
(function object object object object object object object)
|
||||
(lambda :behavior sunken-elevator
|
||||
()
|
||||
(let
|
||||
((t9-0
|
||||
(the-as
|
||||
function
|
||||
(->
|
||||
(the-as (state none) (method-of-type plat-button plat-button-pressed))
|
||||
enter
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(the-as (function object object object object object object object) t9-0)
|
||||
((the-as (function object) t9-0))
|
||||
)
|
||||
)
|
||||
(case (-> self path-pos)
|
||||
((0.0)
|
||||
(load-state-want-display-level 'sunken 'display)
|
||||
(let ((gp-0 (get-process *default-dead-pool* village2cam #x4000)))
|
||||
(set! (-> (the-as village2cam (-> (when gp-0
|
||||
(let
|
||||
((t9-3
|
||||
(method-of-type
|
||||
village2cam
|
||||
activate
|
||||
)
|
||||
)
|
||||
)
|
||||
(t9-3
|
||||
(the-as village2cam gp-0)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
(case (-> self path-pos)
|
||||
((0.0)
|
||||
(load-state-want-display-level 'sunken 'display)
|
||||
(let ((gp-0 (get-process *default-dead-pool* village2cam #x4000)))
|
||||
(set! (-> (the-as village2cam (-> (when gp-0
|
||||
(let
|
||||
((t9-3
|
||||
(method-of-type
|
||||
village2cam
|
||||
activate
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-0
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-0 ppointer)
|
||||
)
|
||||
0
|
||||
)
|
||||
)
|
||||
seq
|
||||
)
|
||||
(the-as uint 0)
|
||||
)
|
||||
)
|
||||
0
|
||||
)
|
||||
((1.0)
|
||||
(let* ((gp-1 (get-process *default-dead-pool* village2cam #x4000))
|
||||
(v1-10 (when gp-1
|
||||
(let ((t9-6 (method-of-type village2cam activate)))
|
||||
(t9-6
|
||||
(the-as village2cam gp-1)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-1
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-1 ppointer)
|
||||
)
|
||||
)
|
||||
(v0-5 1)
|
||||
(t9-3
|
||||
(the-as village2cam gp-0)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-0
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-0 ppointer)
|
||||
)
|
||||
0
|
||||
)
|
||||
)
|
||||
seq
|
||||
)
|
||||
(set! (-> (the-as village2cam (-> v1-10 0)) seq) (the-as uint v0-5))
|
||||
v0-5
|
||||
(the-as uint 0)
|
||||
)
|
||||
)
|
||||
0
|
||||
)
|
||||
((1.0)
|
||||
(let* ((gp-1 (get-process *default-dead-pool* village2cam #x4000))
|
||||
(v1-10 (when gp-1
|
||||
(let ((t9-6 (method-of-type village2cam activate)))
|
||||
(t9-6
|
||||
(the-as village2cam gp-1)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-1
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-1 ppointer)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> (the-as village2cam (-> v1-10 0)) seq) (the-as uint 1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((gp-1
|
||||
(new 'static 'state
|
||||
:name 'plat-button-move-upward
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
(defstate plat-button-move-upward (sunken-elevator)
|
||||
:virtual #t
|
||||
:enter
|
||||
(behavior ()
|
||||
(let ((t9-0 (-> (method-of-type plat-button plat-button-move-upward) enter)))
|
||||
(if t9-0
|
||||
(t9-0)
|
||||
)
|
||||
)
|
||||
(set! (-> self play-at-top-going-up-camera?) #t)
|
||||
(none)
|
||||
)
|
||||
(inherit-state
|
||||
gp-1
|
||||
(the-as state (method-of-type plat-button plat-button-move-upward))
|
||||
)
|
||||
(method-set! sunken-elevator 24 (the-as function gp-1))
|
||||
(set!
|
||||
(-> gp-1 enter)
|
||||
(the-as
|
||||
(function object object object object object object object)
|
||||
(lambda :behavior sunken-elevator
|
||||
()
|
||||
(let
|
||||
((t9-0
|
||||
(the-as
|
||||
function
|
||||
(->
|
||||
(the-as
|
||||
(state none)
|
||||
(method-of-type plat-button plat-button-move-upward)
|
||||
:trans
|
||||
(behavior ()
|
||||
(let ((t9-0 (-> (method-of-type plat-button plat-button-move-upward) trans)))
|
||||
(if t9-0
|
||||
(t9-0)
|
||||
)
|
||||
)
|
||||
(when
|
||||
(and (-> self play-at-top-going-up-camera?) (>= 0.14 (-> self path-pos)))
|
||||
(set! *teleport* #t)
|
||||
(set! (-> self play-at-top-going-up-camera?) #f)
|
||||
(load-state-want-display-level 'sunken 'special)
|
||||
(let* ((gp-0 (get-process *default-dead-pool* village2cam #x4000))
|
||||
(v1-8 (when gp-0
|
||||
(let ((t9-3 (method-of-type village2cam activate)))
|
||||
(t9-3
|
||||
(the-as village2cam gp-0)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-0
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-0 ppointer)
|
||||
)
|
||||
)
|
||||
)
|
||||
enter
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(the-as (function object object object object object object object) t9-0)
|
||||
((the-as (function object) t9-0))
|
||||
)
|
||||
)
|
||||
(let ((v0-1 #t))
|
||||
(set! (-> self play-at-top-going-up-camera?) v0-1)
|
||||
v0-1
|
||||
)
|
||||
(set! (-> (the-as village2cam (-> v1-8 0)) seq) (the-as uint 2))
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set!
|
||||
(-> gp-1 trans)
|
||||
(lambda :behavior sunken-elevator
|
||||
()
|
||||
(let
|
||||
((t9-0
|
||||
(->
|
||||
(the-as
|
||||
(state none)
|
||||
(method-of-type plat-button plat-button-move-upward)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(defstate plat-button-move-downward (sunken-elevator)
|
||||
:virtual #t
|
||||
:trans
|
||||
(behavior ()
|
||||
(let ((s5-0 (new 'stack-no-clear 'vector))
|
||||
(gp-0 (new 'stack-no-clear 'vector))
|
||||
)
|
||||
(set! *teleport* #t)
|
||||
(set! (-> s5-0 quad) (-> self root-override trans quad))
|
||||
(let
|
||||
((t9-1
|
||||
(->
|
||||
(the-as (state sunken-elevator) (find-parent-method sunken-elevator 23))
|
||||
trans
|
||||
)
|
||||
)
|
||||
)
|
||||
(if t9-0
|
||||
(t9-0)
|
||||
(if t9-1
|
||||
(t9-1)
|
||||
)
|
||||
)
|
||||
(when
|
||||
(and (-> self play-at-top-going-up-camera?) (>= 0.14 (-> self path-pos)))
|
||||
(set! *teleport* #t)
|
||||
(set! (-> self play-at-top-going-up-camera?) #f)
|
||||
(load-state-want-display-level 'sunken 'special)
|
||||
(let* ((gp-0 (get-process *default-dead-pool* village2cam #x4000))
|
||||
(v1-8 (when gp-0
|
||||
(let ((t9-3 (method-of-type village2cam activate)))
|
||||
(t9-3
|
||||
(the-as village2cam gp-0)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-0
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-0 ppointer)
|
||||
)
|
||||
)
|
||||
(v0-1 2)
|
||||
)
|
||||
(set! (-> (the-as village2cam (-> v1-8 0)) seq) (the-as uint v0-1))
|
||||
v0-1
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((gp-2
|
||||
(new 'static 'state
|
||||
:name 'plat-button-move-downward
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(inherit-state
|
||||
gp-2
|
||||
(the-as state (method-of-type plat-button plat-button-move-downward))
|
||||
)
|
||||
(method-set! sunken-elevator 23 (the-as function gp-2))
|
||||
(set!
|
||||
(-> gp-2 trans)
|
||||
(lambda :behavior sunken-elevator
|
||||
()
|
||||
(let ((s5-0 (new 'stack-no-clear 'vector))
|
||||
(gp-0 (new 'stack-no-clear 'vector))
|
||||
)
|
||||
(set! *teleport* #t)
|
||||
(set! (-> s5-0 quad) (-> self root-override trans quad))
|
||||
(let
|
||||
((t9-1
|
||||
(-> (the-as (state none) (find-parent-method sunken-elevator 23)) trans)
|
||||
)
|
||||
)
|
||||
(if t9-1
|
||||
(t9-1)
|
||||
)
|
||||
)
|
||||
(vector-! gp-0 (-> self root-override trans) s5-0)
|
||||
)
|
||||
(when (< (-> self path-pos) 0.9)
|
||||
((method-of-object (-> *target* control) dummy-28))
|
||||
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-2 from) self)
|
||||
(set! (-> a1-2 num-params) 0)
|
||||
(set! (-> a1-2 message) 'reset-height)
|
||||
(send-event-function *target* a1-2)
|
||||
)
|
||||
(vector-! gp-0 (-> self root-override trans) s5-0)
|
||||
)
|
||||
(when (< (-> self path-pos) 0.9)
|
||||
((method-of-object (-> *target* control) dummy-28))
|
||||
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-2 from) self)
|
||||
(set! (-> a1-2 num-params) 0)
|
||||
(set! (-> a1-2 message) 'reset-height)
|
||||
(send-event-function *target* a1-2)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -402,4 +299,4 @@
|
||||
(dummy-14 obj *sunken-elevator-sg* '())
|
||||
0
|
||||
(none)
|
||||
)
|
||||
)
|
||||
@@ -103,7 +103,7 @@
|
||||
(defconstant PC_PAD_INPUT_NOTICE_TIME (seconds 1.5))
|
||||
|
||||
|
||||
(define-extern pc-pi-mapping-button state)
|
||||
(define-extern pc-pi-mapping-button (state pc-pad-proc))
|
||||
|
||||
(defstate pc-pi-new-mapping (pc-pad-proc)
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ add_library(compiler
|
||||
compiler/compilation/Function.cpp
|
||||
compiler/compilation/ControlFlow.cpp
|
||||
compiler/compilation/Type.cpp
|
||||
compiler/compilation/State.cpp
|
||||
compiler/compilation/Static.cpp
|
||||
compiler/Util.cpp
|
||||
data_compiler/game_text.cpp
|
||||
|
||||
@@ -605,6 +605,13 @@ class Compiler {
|
||||
Val* compile_defenum(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
Val* compile_size_of(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
Val* compile_psize_of(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
|
||||
// State
|
||||
Val* compile_define_state_hook(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
Val* compile_define_virtual_state_hook(const goos::Object& form,
|
||||
const goos::Object& rest,
|
||||
Env* env);
|
||||
Val* compile_go_hook(const goos::Object& form, const goos::Object& rest, Env* env);
|
||||
};
|
||||
|
||||
extern const std::unordered_map<
|
||||
|
||||
@@ -251,6 +251,11 @@ const std::unordered_map<
|
||||
|
||||
// UTIL
|
||||
{"set-config!", &Compiler::compile_set_config},
|
||||
|
||||
// STATE
|
||||
{"define-state-hook", &Compiler::compile_define_state_hook},
|
||||
{"go-hook", &Compiler::compile_go_hook},
|
||||
{"define-virtual-state-hook", &Compiler::compile_define_virtual_state_hook},
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
#include "goalc/compiler/Compiler.h"
|
||||
#include "common/type_system/state.h"
|
||||
|
||||
/*!
|
||||
* The define-state-hook compiler form is used from a macro in gstate.gc.
|
||||
* Args:
|
||||
* - state_name, a symbol of the state's name.
|
||||
* - state_parent, a symbol with the type name. Must be child of process
|
||||
* - state, the actual state object to initialize.
|
||||
*/
|
||||
Val* Compiler::compile_define_state_hook(const goos::Object& form,
|
||||
const goos::Object& rest,
|
||||
Env* env) {
|
||||
auto args = get_va(form, rest);
|
||||
// args:
|
||||
// state_name
|
||||
// state_parent
|
||||
// state object
|
||||
// named args for enter/exit/trans/post/event/code
|
||||
va_check(form, args, {goos::ObjectType::SYMBOL, goos::ObjectType::SYMBOL, {}},
|
||||
{
|
||||
{"enter", {true, {}}},
|
||||
{"exit", {true, {}}},
|
||||
{"trans", {true, {}}},
|
||||
{"post", {true, {}}},
|
||||
{"event", {true, {}}},
|
||||
{"code", {true, {}}},
|
||||
});
|
||||
|
||||
// check parent
|
||||
auto state_parent = args.unnamed.at(1).as_symbol()->name;
|
||||
auto state_parent_type = m_ts.make_typespec(state_parent);
|
||||
if (!m_ts.tc(TypeSpec("process"), state_parent_type)) {
|
||||
throw_compiler_error(form, "define-state got a type {} which is not a child of process",
|
||||
state_parent_type.print());
|
||||
}
|
||||
|
||||
// get state object
|
||||
auto state_object = compile_error_guard(args.unnamed.at(2), env)->to_gpr(env);
|
||||
if (state_object->type() != TypeSpec("state")) {
|
||||
throw_compiler_error(form, "define-state-hook got an invalid state object: had type {}",
|
||||
state_object->type().print());
|
||||
}
|
||||
|
||||
auto state_type_info = m_ts.get_type_of_type<StructureType>("state");
|
||||
|
||||
// set the easy ones
|
||||
for (auto name : {"exit", "trans", "post", "event"}) {
|
||||
auto field = get_field_of_structure(state_type_info, state_object, name, env);
|
||||
auto value = compile_error_guard(args.named.at(name), env);
|
||||
do_set(form, field, value->to_gpr(env), value, env);
|
||||
}
|
||||
|
||||
auto enter_field = get_field_of_structure(state_type_info, state_object, "enter", env);
|
||||
auto enter_value = compile_error_guard(args.named.at("enter"), env);
|
||||
do_set(form, enter_field, enter_value->to_gpr(env), enter_value, env);
|
||||
|
||||
auto code_field = get_field_of_structure(state_type_info, state_object, "code", env);
|
||||
auto code_value = compile_error_guard(args.named.at("code"), env);
|
||||
do_set(form, code_field, code_value->to_gpr(env), code_value, env);
|
||||
|
||||
// state name
|
||||
TypeSpec state_type("state");
|
||||
|
||||
for (int i = 0; i < (int)code_value->type().arg_count() - 1; i++) {
|
||||
state_type.add_arg(code_value->type().get_arg(i));
|
||||
}
|
||||
state_type.add_arg(state_parent_type);
|
||||
auto state_name = args.unnamed.at(0).as_symbol()->name;
|
||||
auto existing_var = m_symbol_types.find(state_name);
|
||||
if (existing_var != m_symbol_types.end() && existing_var->second != state_type) {
|
||||
throw_compiler_error(form, "define-state would redefine the type of symbol {} from {} to {}",
|
||||
state_name, existing_var->second.print(), state_type.print());
|
||||
}
|
||||
m_symbol_types[state_name] = state_type;
|
||||
auto sym_val =
|
||||
get_parent_env_of_type<FunctionEnv>(env)->alloc_val<SymbolVal>(state_name, state_type);
|
||||
env->emit(std::make_unique<IR_SetSymbolValue>(sym_val, state_object));
|
||||
|
||||
return get_none();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The define-state-hook compiler form is used from a macro in gstate.gc.
|
||||
* Args:
|
||||
* - state_name, a symbol of the state's name.
|
||||
* - state_parent, a symbol with the type name. Must be child of process
|
||||
* - state, the actual state object to initialize.
|
||||
*/
|
||||
Val* Compiler::compile_define_virtual_state_hook(const goos::Object& form,
|
||||
const goos::Object& rest,
|
||||
Env* env) {
|
||||
auto args = get_va(form, rest);
|
||||
// args:
|
||||
// state_name
|
||||
// state_parent
|
||||
// state object
|
||||
// named args for enter/exit/trans/post/event/code
|
||||
va_check(form, args, {goos::ObjectType::SYMBOL, goos::ObjectType::SYMBOL, {}},
|
||||
{
|
||||
{"enter", {true, {}}},
|
||||
{"exit", {true, {}}},
|
||||
{"trans", {true, {}}},
|
||||
{"post", {true, {}}},
|
||||
{"event", {true, {}}},
|
||||
{"code", {true, {}}},
|
||||
});
|
||||
|
||||
// check parent
|
||||
auto state_parent = args.unnamed.at(1).as_symbol()->name;
|
||||
auto state_parent_type = m_ts.make_typespec(state_parent);
|
||||
if (!m_ts.tc(TypeSpec("process"), state_parent_type)) {
|
||||
throw_compiler_error(form, "define-state got a type {} which is not a child of process",
|
||||
state_parent_type.print());
|
||||
}
|
||||
|
||||
// get state object
|
||||
auto state_object = compile_error_guard(args.unnamed.at(2), env)->to_gpr(env);
|
||||
if (state_object->type() != TypeSpec("state")) {
|
||||
throw_compiler_error(form, "define-state-hook got an invalid state object: had type {}",
|
||||
state_object->type().print());
|
||||
}
|
||||
|
||||
auto state_type_info = m_ts.get_type_of_type<StructureType>("state");
|
||||
|
||||
// set the easy ones
|
||||
for (auto name : {"exit", "trans", "post", "event"}) {
|
||||
auto field = get_field_of_structure(state_type_info, state_object, name, env);
|
||||
auto value = compile_error_guard(args.named.at(name), env);
|
||||
do_set(form, field, value->to_gpr(env), value, env);
|
||||
}
|
||||
|
||||
auto enter_field = get_field_of_structure(state_type_info, state_object, "enter", env);
|
||||
auto enter_value = compile_error_guard(args.named.at("enter"), env);
|
||||
do_set(form, enter_field, enter_value->to_gpr(env), enter_value, env);
|
||||
|
||||
auto code_field = get_field_of_structure(state_type_info, state_object, "code", env);
|
||||
auto code_value = compile_error_guard(args.named.at("code"), env);
|
||||
do_set(form, code_field, code_value->to_gpr(env), code_value, env);
|
||||
|
||||
// state name
|
||||
TypeSpec state_type("state");
|
||||
|
||||
for (int i = 0; i < (int)code_value->type().arg_count() - 1; i++) {
|
||||
state_type.add_arg(code_value->type().get_arg(i));
|
||||
}
|
||||
state_type.add_arg(TypeSpec("_type_"));
|
||||
auto state_name = args.unnamed.at(0).as_symbol()->name;
|
||||
|
||||
MethodInfo child_method_info;
|
||||
if (!m_ts.try_lookup_method(state_parent, state_name, &child_method_info)) {
|
||||
throw_compiler_error(
|
||||
form, "Tried to define a virtual state {} for type {}, but the state was not declared.",
|
||||
state_name, state_parent);
|
||||
}
|
||||
|
||||
if (state_type != child_method_info.type) {
|
||||
throw_compiler_error(
|
||||
form, "Virtual state {} of {} was declared as {}, but got {}. First declared in type {}.",
|
||||
state_name, state_parent, child_method_info.type.print(), state_type.print(),
|
||||
child_method_info.defined_in_type);
|
||||
}
|
||||
|
||||
MethodInfo parent_method_info;
|
||||
auto parent_of_parent_type = m_ts.lookup_type(state_parent)->get_parent();
|
||||
if (m_ts.try_lookup_method(parent_of_parent_type, state_name, &parent_method_info)) {
|
||||
// need to call inherit state TODO
|
||||
auto inherit_state_func = compile_get_symbol_value(form, "inherit-state", env)->to_gpr(env);
|
||||
auto parents_state =
|
||||
compile_get_method_of_type(form, TypeSpec(parent_of_parent_type), state_name, env)
|
||||
->to_gpr(env);
|
||||
compile_real_function_call(form, inherit_state_func, {state_object, parents_state}, env);
|
||||
}
|
||||
|
||||
// call method set.
|
||||
// (method-set! sunken-elevator 22 (the-as function gp-0))
|
||||
auto method_set_func = compile_get_symbol_value(form, "method-set!", env)->to_gpr(env);
|
||||
auto type_obj = compile_get_symbol_value(form, state_parent, env)->to_gpr(env);
|
||||
auto method_id = compile_integer(child_method_info.id, env)->to_gpr(env);
|
||||
compile_real_function_call(form, method_set_func, {type_obj, method_id, state_object}, env);
|
||||
|
||||
return get_none();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The go-hook compiler form is used within go macros.
|
||||
* Args:
|
||||
* - process to perform the go on
|
||||
* - state
|
||||
* - args to enter the state with.
|
||||
*/
|
||||
Val* Compiler::compile_go_hook(const goos::Object& form, const goos::Object& rest, Env* env) {
|
||||
auto args = get_va(form, rest);
|
||||
if (!args.named.empty()) {
|
||||
throw_compiler_error(form, "go-hook does not take named arguments");
|
||||
}
|
||||
|
||||
if (args.unnamed.size() < 2) {
|
||||
throw_compiler_error(form, "go-hook must get at least 2 arguments");
|
||||
}
|
||||
|
||||
// get the process
|
||||
auto proc = compile_error_guard(args.unnamed.at(0), env)->to_gpr(env);
|
||||
if (!m_ts.tc(TypeSpec("process"), proc->type())) {
|
||||
throw_compiler_error(form, "First argument to go-hook should be a process, got {} instead",
|
||||
proc->type().print());
|
||||
}
|
||||
|
||||
// get the state
|
||||
auto state = compile_error_guard(args.unnamed.at(1), env)->to_gpr(env);
|
||||
if (!m_ts.tc(TypeSpec("state"), state->type())) {
|
||||
throw_compiler_error(form, "Second argument to go-hook should be a state, got {} instead",
|
||||
state->type().print());
|
||||
}
|
||||
|
||||
// make sure the state is ok.
|
||||
if (state->type().arg_count() == 0) {
|
||||
throw_compiler_error(form, "Attempting to go to a state with incomplete type.");
|
||||
}
|
||||
|
||||
// if we wanted to typecheck the process, we could do it here:
|
||||
// auto expected_proc_type = state->type().last_arg();
|
||||
// if (!m_ts.tc(expected_proc_type, proc->type())) {
|
||||
// print_compiler_warning("Going to state of type {} from process of type {}.",
|
||||
// expected_proc_type.print(), proc->type().print());
|
||||
// }
|
||||
|
||||
// set the next state
|
||||
auto proc_type_info = m_ts.get_type_of_type<StructureType>("process");
|
||||
auto next_state_field = get_field_of_structure(proc_type_info, proc, "next-state", env);
|
||||
do_set(form, next_state_field, state, state, env);
|
||||
|
||||
// now we have to call the function.
|
||||
auto enter_state_func = compile_get_symbol_value(form, "enter-state", env);
|
||||
enter_state_func->set_type(state_to_go_function(state->type()));
|
||||
|
||||
std::vector<RegVal*> function_arguments;
|
||||
for (size_t i = 2; i < args.unnamed.size(); i++) {
|
||||
function_arguments.push_back(compile_error_guard(args.unnamed.at(i), env)->to_gpr(env));
|
||||
}
|
||||
|
||||
// typechecking here will make sure the go is possible.
|
||||
compile_real_function_call(form, enter_state_func->to_gpr(env), function_arguments, env);
|
||||
|
||||
return get_none();
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "common/type_system/deftype.h"
|
||||
#include "goalc/emitter/CallingConvention.h"
|
||||
#include "common/util/math_util.h"
|
||||
#include "common/type_system/state.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -702,7 +703,16 @@ Val* Compiler::compile_deref(const goos::Object& form, const goos::Object& _rest
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
const auto& in_type = result->type();
|
||||
result = get_field_of_structure(struct_type, result, field_name, env);
|
||||
|
||||
// special case (-> <state> enter) should return the appropriate function type.
|
||||
if (in_type.arg_count() > 0 && in_type.base_type() == "state") {
|
||||
if (field_name == "enter") {
|
||||
result->set_type(state_to_go_function(in_type));
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,9 @@ bool Debugger::attach_and_break() {
|
||||
update_break_info();
|
||||
|
||||
auto signal_count = get_signal_count();
|
||||
assert(signal_count == 0);
|
||||
if (signal_count != 0) {
|
||||
fmt::print("[Debugger] got signal count of {} in attach_and_break\n", signal_count);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
||||
+71
@@ -214,6 +214,11 @@
|
||||
)
|
||||
)
|
||||
|
||||
(defmacro go-virtual (state-name &key (proc self) &rest args)
|
||||
"Change the current process to the virtual state of the given process."
|
||||
`(go (method-of-object ,proc ,state-name) ,@args)
|
||||
)
|
||||
|
||||
(defmacro static-sound-name (str)
|
||||
"Convert a string constant to a static sound-name."
|
||||
|
||||
@@ -331,6 +336,72 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; use a compile-time list to keep track of the type of an anonymous behavior.
|
||||
(seval (define *defstate-type-stack* '()))
|
||||
(desfun def-state-check-behavior (beh-form beh-type)
|
||||
"check if code block is an anonymous behavior. needed for anonymous behaviors on defstate."
|
||||
|
||||
(when (and (pair? beh-form) (eq? (first beh-form) 'behavior))
|
||||
(push! *defstate-type-stack* beh-type)
|
||||
)
|
||||
)
|
||||
(defmacro defstate (state-name parents
|
||||
&key (virtual #f)
|
||||
&key (event #f)
|
||||
&key (enter #f)
|
||||
&key (trans #f)
|
||||
&key (exit #f)
|
||||
&key (code #f)
|
||||
&key (post #f)
|
||||
)
|
||||
"Define a new state!"
|
||||
|
||||
(with-gensyms (new-state)
|
||||
(let ((defstate-type (first parents)))
|
||||
(when (not (null? *defstate-type-stack*))
|
||||
(ferror "*defstate-type-stack* leaked! An error probably happened in a previous defstate. stack is: {}" *defstate-type-stack*)
|
||||
)
|
||||
(set! *defstate-type-stack* '())
|
||||
(def-state-check-behavior event defstate-type)
|
||||
(def-state-check-behavior enter defstate-type)
|
||||
(def-state-check-behavior trans defstate-type)
|
||||
(def-state-check-behavior exit defstate-type)
|
||||
(def-state-check-behavior code defstate-type)
|
||||
(def-state-check-behavior post defstate-type)
|
||||
`(let ((,new-state (new 'static 'state
|
||||
:name (quote ,state-name)
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
))
|
||||
;; the compiler will set the fields of the given state and define the symbol.
|
||||
;; This way it can check the individual function types, make sure they make sense, and create
|
||||
;; a state with the appropriate type.
|
||||
,(if virtual
|
||||
`(define-virtual-state-hook ,state-name ,defstate-type ,new-state :event ,event :enter ,enter :trans ,trans :exit ,exit :code ,code :post ,post)
|
||||
`(define-state-hook ,state-name ,defstate-type ,new-state :event ,event :enter ,enter :trans ,trans :exit ,exit :code ,code :post ,post)
|
||||
)
|
||||
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(defmacro behavior (bindings &rest body)
|
||||
"Define an anonymous behavior for a process state. This may only be used inside a defstate!"
|
||||
|
||||
(let ((behavior-type (first *defstate-type-stack*)))
|
||||
(pop! *defstate-type-stack*)
|
||||
`(lambda :behavior ,behavior-type ,bindings ,@body)
|
||||
)
|
||||
)
|
||||
|
||||
(defmacro sext32 (in)
|
||||
`(sar (shl ,in 32) 32)
|
||||
)
|
||||
|
||||
+647
-694
File diff suppressed because it is too large
Load Diff
+3
-8
@@ -757,14 +757,9 @@
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(install-handler 5 (the-as (function int) (the-as (function none) (if *debug-segment*
|
||||
vif1-handler-debug
|
||||
(the-as
|
||||
(function none)
|
||||
vif1-handler
|
||||
)
|
||||
)
|
||||
)
|
||||
(install-handler 5 (if *debug-segment*
|
||||
vif1-handler-debug
|
||||
vif1-handler
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -149,8 +149,8 @@
|
||||
:size-assert #xd4
|
||||
:flag-assert #x1e007000d4
|
||||
(:methods
|
||||
(water-vol-idle () none 20)
|
||||
(water-vol-startup () none 21)
|
||||
(water-vol-idle () _type_ :state 20)
|
||||
(water-vol-startup () _type_ :state 21)
|
||||
(TODO-RENAME-22 (_type_) ripple-wave-set 22)
|
||||
(dummy-23 () none 23)
|
||||
(dummy-24 () none 24)
|
||||
|
||||
+2
-2
@@ -384,7 +384,7 @@
|
||||
(dummy-11 (_type_ vector) none 11)
|
||||
(dummy-12 () none 12)
|
||||
(dummy-13 () none 13)
|
||||
(dummy-14 () none 14)
|
||||
(dummy-14 (_type_) none 14)
|
||||
(set-target-pos! (_type_ vector) none 15)
|
||||
(dummy-16 (_type_ vector) symbol 16)
|
||||
(dummy-17 () none 17)
|
||||
@@ -591,7 +591,7 @@
|
||||
(defmethod should-display? nav-control ((obj nav-control))
|
||||
(and
|
||||
*display-nav-marks*
|
||||
(nonzero? (logand (-> obj flags) (nav-control-flags display-marks bit0)))
|
||||
(nonzero? (logand (-> obj flags) (nav-control-flags bit0 display-marks)))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
+8
-8
@@ -246,13 +246,13 @@
|
||||
|
||||
;; definition of type protect-frame
|
||||
(deftype protect-frame (stack-frame)
|
||||
((exit (function object) :offset-assert 12)
|
||||
((exit (function none) :offset-assert 12)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
(:methods
|
||||
(new (symbol type (function object)) protect-frame 0)
|
||||
(new (symbol type (function none)) protect-frame 0)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -300,17 +300,17 @@
|
||||
|
||||
;; definition of type state
|
||||
(deftype state (protect-frame)
|
||||
((code function :offset-assert 16)
|
||||
(trans (function object) :offset-assert 20)
|
||||
(post function :offset-assert 24)
|
||||
(enter (function object object object object object object object) :offset-assert 28)
|
||||
(event (function process int symbol event-message-block object) :offset-assert 32)
|
||||
((code function :offset-assert 16)
|
||||
(trans (function none) :offset-assert 20)
|
||||
(post function :offset-assert 24)
|
||||
(enter function :offset-assert 28)
|
||||
(event (function process int symbol event-message-block object) :offset-assert 32)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x24
|
||||
:flag-assert #x900000024
|
||||
(:methods
|
||||
(new (symbol type basic function (function object) (function object object object object object object object) (function object) (function process int symbol event-message-block object)) _type_ 0)
|
||||
(new (symbol type basic function (function none) function (function none) (function process int symbol event-message-block object)) _type_ 0)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
+4
-17
@@ -1488,7 +1488,7 @@
|
||||
(defmethod
|
||||
new
|
||||
protect-frame
|
||||
((allocation symbol) (type-to-make type) (arg0 (function object)))
|
||||
((allocation symbol) (type-to-make type) (arg0 (function none)))
|
||||
(with-pp
|
||||
(let ((v0-0 (the-as object (+ (the-as int allocation) 4))))
|
||||
(set! (-> (the-as protect-frame v0-0) type) type-to-make)
|
||||
@@ -1760,22 +1760,9 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((a0-40
|
||||
(new 'static 'state
|
||||
:name 'dead-state
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! dead-state a0-40)
|
||||
(set! (-> a0-40 code) nothing)
|
||||
(defstate dead-state (process)
|
||||
:code
|
||||
(the-as (function none :behavior process) nothing)
|
||||
)
|
||||
|
||||
;; definition for symbol entity-deactivate-handler, type (function process object none)
|
||||
|
||||
+11
-4
@@ -9,9 +9,9 @@
|
||||
(type-to-make type)
|
||||
(name basic)
|
||||
(code function)
|
||||
(trans (function object))
|
||||
(enter (function object object object object object object object))
|
||||
(exit (function object))
|
||||
(trans (function none))
|
||||
(enter function)
|
||||
(exit (function none))
|
||||
(event (function process int symbol event-message-block object))
|
||||
)
|
||||
(let
|
||||
@@ -105,7 +105,14 @@
|
||||
(set! (-> pp trans-hook) (-> s0-2 trans))
|
||||
(let ((t9-4 (-> s0-2 enter)))
|
||||
(if t9-4
|
||||
(t9-4 arg0 arg1 arg2 arg3 arg4 arg5)
|
||||
((the-as (function object object object object object object none) t9-4)
|
||||
arg0
|
||||
arg1
|
||||
arg2
|
||||
arg3
|
||||
arg4
|
||||
arg5
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((t9-5 (-> s0-2 trans)))
|
||||
|
||||
+18
-18
@@ -163,7 +163,7 @@
|
||||
(touch-time uint64 :offset-assert 368)
|
||||
(nav-enemy-flags uint32 :offset-assert 376)
|
||||
(incomming-attack-id uint64 :offset-assert 384)
|
||||
(jump-return-state basic :offset-assert 392)
|
||||
(jump-return-state (state process) :offset-assert 392)
|
||||
(rand-gen random-generator :offset-assert 396)
|
||||
)
|
||||
:heap-base #x120
|
||||
@@ -171,23 +171,23 @@
|
||||
:size-assert #x190
|
||||
:flag-assert #x4c01200190
|
||||
(:methods
|
||||
(nav-enemy-attack () none 20)
|
||||
(nav-enemy-chase () none 21)
|
||||
(dummy-22 () none 22)
|
||||
(nav-enemy-die () none 23)
|
||||
(nav-enemy-fuel-cell () none 24)
|
||||
(nav-enemy-give-up () none 25)
|
||||
(nav-enemy-jump () none 26)
|
||||
(nav-enemy-jump-land () none 27)
|
||||
(nav-enemy-idle () none 28)
|
||||
(nav-enemy-notice () none 29)
|
||||
(nav-enemy-patrol () none 30)
|
||||
(nav-enemy-stare () none 31)
|
||||
(nav-enemy-stop-chase () none 32)
|
||||
(nav-enemy-victory () none 33)
|
||||
(nav-enemy-attack () _type_ :state 20)
|
||||
(nav-enemy-chase () _type_ :state 21)
|
||||
(nav-enemy-flee () _type_ :state 22)
|
||||
(nav-enemy-die () _type_ :state 23)
|
||||
(nav-enemy-fuel-cell () _type_ :state 24)
|
||||
(nav-enemy-give-up () _type_ :state 25)
|
||||
(nav-enemy-jump () _type_ :state 26)
|
||||
(nav-enemy-jump-land () _type_ :state 27)
|
||||
(nav-enemy-idle () _type_ :state 28)
|
||||
(nav-enemy-notice () _type_ :state 29)
|
||||
(nav-enemy-patrol () _type_ :state 30)
|
||||
(nav-enemy-stare () _type_ :state 31)
|
||||
(nav-enemy-stop-chase () _type_ :state 32)
|
||||
(nav-enemy-victory () _type_ :state 33)
|
||||
(dummy-34 (_type_) none 34)
|
||||
(dummy-35 (_type_) none 35)
|
||||
(dummy-36 (_type_) none 36)
|
||||
(nav-enemy-wait-for-cue () _type_ :state 35)
|
||||
(nav-enemy-jump-to-point () _type_ :state 36)
|
||||
(TODO-RENAME-37 (_type_) none 37)
|
||||
(TODO-RENAME-38 (_type_) none 38)
|
||||
(TODO-RENAME-39 (_type_) none 39)
|
||||
@@ -225,7 +225,7 @@
|
||||
(dummy-71 (_type_) none 71)
|
||||
(dummy-72 (_type_ process event-message-block) object 72)
|
||||
(TODO-RENAME-73 (_type_ process) symbol 73)
|
||||
(dummy-74 (_type_) none 74)
|
||||
(nav-enemy-jump-blocked () _type_ :state 74)
|
||||
(dummy-75 (_type_) none 75)
|
||||
)
|
||||
)
|
||||
|
||||
+1430
-2003
File diff suppressed because it is too large
Load Diff
+54
-104
@@ -460,8 +460,8 @@
|
||||
:size-assert #x2d4
|
||||
:flag-assert #x23027002d4
|
||||
(:methods
|
||||
(rigid-body-platform-idle () none 20)
|
||||
(rigid-body-platform-float () none 21)
|
||||
(rigid-body-platform-idle () _type_ :state 20)
|
||||
(rigid-body-platform-float () _type_ :state 21)
|
||||
(TODO-RENAME-22 (_type_ vector basic) float 22)
|
||||
(TODO-RENAME-23 (_type_ basic) none 23)
|
||||
(TODO-RENAME-24 (_type_ rigid-body-control-point basic) none 24)
|
||||
@@ -976,112 +976,70 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((gp-0
|
||||
(new 'static 'state
|
||||
:name 'rigid-body-platform-idle
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(method-set! rigid-body-platform 20 (the-as function gp-0))
|
||||
(set!
|
||||
(-> gp-0 trans)
|
||||
(the-as
|
||||
(function object)
|
||||
(lambda :behavior rigid-body-platform
|
||||
()
|
||||
(when
|
||||
(and
|
||||
*target*
|
||||
(>=
|
||||
(-> self info idle-distance)
|
||||
(vector-vector-distance
|
||||
(-> self root-overlay trans)
|
||||
(-> *target* control trans)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((t9-1 (the-as (function object) enter-state)))
|
||||
(set!
|
||||
(-> self next-state)
|
||||
(the-as state (method-of-object self rigid-body-platform-float))
|
||||
)
|
||||
(t9-1)
|
||||
(defstate rigid-body-platform-idle (rigid-body-platform)
|
||||
:virtual #t
|
||||
:trans
|
||||
(behavior ()
|
||||
(if
|
||||
(and
|
||||
*target*
|
||||
(>=
|
||||
(-> self info idle-distance)
|
||||
(vector-vector-distance
|
||||
(-> self root-overlay trans)
|
||||
(-> *target* control trans)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(go-virtual rigid-body-platform-float)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set! (-> gp-0 code) (lambda :behavior rigid-body-platform () (while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
:code
|
||||
(behavior ()
|
||||
(while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set! (-> gp-0 post) ja-post)
|
||||
:post
|
||||
(the-as (function none :behavior rigid-body-platform) ja-post)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((gp-1
|
||||
(new 'static 'state
|
||||
:name 'rigid-body-platform-float
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(method-set! rigid-body-platform 21 (the-as function gp-1))
|
||||
(set! (-> gp-1 event) rigid-body-platform-event-handler)
|
||||
(set!
|
||||
(-> gp-1 trans)
|
||||
(the-as
|
||||
(function object)
|
||||
(lambda :behavior rigid-body-platform
|
||||
()
|
||||
(when
|
||||
(or
|
||||
(not *target*)
|
||||
(<
|
||||
(-> self info idle-distance)
|
||||
(vector-vector-distance
|
||||
(-> self root-overlay trans)
|
||||
(-> *target* control trans)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((t9-1 (the-as (function object) enter-state)))
|
||||
(set!
|
||||
(-> self next-state)
|
||||
(the-as state (method-of-object self rigid-body-platform-idle))
|
||||
)
|
||||
(t9-1)
|
||||
(defstate rigid-body-platform-float (rigid-body-platform)
|
||||
:virtual #t
|
||||
:event
|
||||
rigid-body-platform-event-handler
|
||||
:trans
|
||||
(behavior ()
|
||||
(if
|
||||
(or
|
||||
(not *target*)
|
||||
(<
|
||||
(-> self info idle-distance)
|
||||
(vector-vector-distance
|
||||
(-> self root-overlay trans)
|
||||
(-> *target* control trans)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(go-virtual rigid-body-platform-idle)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set! (-> gp-1 code) (lambda :behavior rigid-body-platform () (while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
:code
|
||||
(behavior ()
|
||||
(while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
:post
|
||||
(the-as
|
||||
(function none :behavior rigid-body-platform)
|
||||
rigid-body-platform-post
|
||||
)
|
||||
(set! (-> gp-1 post) rigid-body-platform-post)
|
||||
)
|
||||
|
||||
;; definition for method 29 of type rigid-body-platform
|
||||
@@ -1211,17 +1169,9 @@
|
||||
;; definition for method 34 of type rigid-body-platform
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
(defmethod TODO-RENAME-34 rigid-body-platform ((obj rigid-body-platform))
|
||||
(with-pp
|
||||
(let ((t9-0 (the-as (function object) enter-state)))
|
||||
(set!
|
||||
(-> pp next-state)
|
||||
(the-as state (method-of-object obj rigid-body-platform-idle))
|
||||
)
|
||||
(t9-0)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
(go (method-of-object obj rigid-body-platform-idle))
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for method 31 of type rigid-body-platform
|
||||
|
||||
+70
-116
@@ -1782,85 +1782,51 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((gp-0
|
||||
(new 'static 'state
|
||||
:name 'water-vol-idle
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(inherit-state gp-0 (the-as state (method-of-type water-vol water-vol-idle)))
|
||||
(method-set! water-anim 20 (the-as function gp-0))
|
||||
(set!
|
||||
(-> gp-0 event)
|
||||
(lambda :behavior water-anim
|
||||
((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(case arg2
|
||||
(('move-to)
|
||||
(set!
|
||||
(-> self root trans quad)
|
||||
(-> (the-as vector (-> arg3 param 0)) quad)
|
||||
)
|
||||
(set! (-> self water-height) (-> self root trans y))
|
||||
(if (nonzero? (-> self sound))
|
||||
(update-trans! (-> self sound) (-> self root trans))
|
||||
)
|
||||
(let ((v0-0 (logclear (-> self mask) (process-mask sleep-code))))
|
||||
(set! (-> self mask) v0-0)
|
||||
v0-0
|
||||
)
|
||||
(defstate water-vol-idle (water-anim)
|
||||
:virtual #t
|
||||
:event
|
||||
(behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(case arg2
|
||||
(('move-to)
|
||||
(set!
|
||||
(-> self root trans quad)
|
||||
(-> (the-as vector (-> arg3 param 0)) quad)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> gp-0 trans)
|
||||
(the-as
|
||||
(function object)
|
||||
(lambda :behavior water-anim
|
||||
()
|
||||
(let
|
||||
((t9-0
|
||||
(->
|
||||
(the-as (state none) (method-of-type water-vol water-vol-idle))
|
||||
trans
|
||||
)
|
||||
)
|
||||
(set! (-> self water-height) (-> self root trans y))
|
||||
(if (nonzero? (-> self sound))
|
||||
(update-trans! (-> self sound) (-> self root trans))
|
||||
)
|
||||
(if t9-0
|
||||
(t9-0)
|
||||
(let ((v0-0 (logclear (-> self mask) (process-mask sleep-code))))
|
||||
(set! (-> self mask) v0-0)
|
||||
v0-0
|
||||
)
|
||||
)
|
||||
(if (< (-> (math-camera-pos) y) (+ -8192.0 (-> self root trans y)))
|
||||
(logior! (-> self draw status) 2)
|
||||
(set! (-> self draw status) (logand -3 (-> self draw status)))
|
||||
)
|
||||
(if (and (-> self play-ambient-sound?) (nonzero? (-> self sound)))
|
||||
(update! (-> self sound))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> gp-0 code) (lambda :behavior water-anim () (while #t
|
||||
(ja-post)
|
||||
(logior!
|
||||
(-> self mask)
|
||||
(process-mask
|
||||
sleep-code
|
||||
)
|
||||
)
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
:trans
|
||||
(behavior ()
|
||||
(let ((t9-0 (-> (method-of-type water-vol water-vol-idle) trans)))
|
||||
(if t9-0
|
||||
(t9-0)
|
||||
)
|
||||
)
|
||||
(if (< (-> (math-camera-pos) y) (+ -8192.0 (-> self root trans y)))
|
||||
(logior! (-> self draw status) 2)
|
||||
(set! (-> self draw status) (logand -3 (-> self draw status)))
|
||||
)
|
||||
(if (and (-> self play-ambient-sound?) (nonzero? (-> self sound)))
|
||||
(update! (-> self sound))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
:code
|
||||
(behavior ()
|
||||
(while #t
|
||||
(ja-post)
|
||||
(logior! (-> self mask) (process-mask sleep-code))
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1943,58 +1909,46 @@
|
||||
;; definition for method 22 of type water-anim
|
||||
;; INFO: Return type mismatch int vs ripple-wave-set.
|
||||
(defmethod TODO-RENAME-22 water-anim ((obj water-anim))
|
||||
(with-pp
|
||||
(let ((s5-0 (-> obj look)))
|
||||
(when (or (< s5-0 0) (>= s5-0 (-> *water-anim-look* length)))
|
||||
(let ((t9-0 (the-as (function object object) enter-state))
|
||||
(a0-2 "skel group")
|
||||
)
|
||||
(set! (-> pp next-state) process-drawable-art-error)
|
||||
(t9-0 a0-2)
|
||||
)
|
||||
)
|
||||
(let ((s5-1 (-> *water-anim-look* s5-0)))
|
||||
(let ((s4-0 (-> s5-1 skel-group value)))
|
||||
(let ((s3-0 s4-0))
|
||||
(when
|
||||
(not
|
||||
(if
|
||||
(and
|
||||
(nonzero? s3-0)
|
||||
(type-type? (-> (the-as basic s3-0) type) skeleton-group)
|
||||
)
|
||||
s3-0
|
||||
(let ((s5-0 (-> obj look)))
|
||||
(if (or (< s5-0 0) (>= s5-0 (-> *water-anim-look* length)))
|
||||
(go process-drawable-art-error "skel group")
|
||||
)
|
||||
(let ((s5-1 (-> *water-anim-look* s5-0)))
|
||||
(let ((s4-0 (-> s5-1 skel-group value)))
|
||||
(let ((s3-0 s4-0))
|
||||
(if
|
||||
(not
|
||||
(if
|
||||
(and
|
||||
(nonzero? s3-0)
|
||||
(type-type? (-> (the-as basic s3-0) type) skeleton-group)
|
||||
)
|
||||
)
|
||||
(let ((t9-2 (the-as (function object object) enter-state))
|
||||
(a0-5 "skel group")
|
||||
)
|
||||
(set! (-> pp next-state) process-drawable-art-error)
|
||||
(t9-2 a0-5)
|
||||
s3-0
|
||||
)
|
||||
)
|
||||
(go process-drawable-art-error "skel group")
|
||||
)
|
||||
(dummy-14 obj (the-as skeleton-group s4-0) '())
|
||||
)
|
||||
(ja-channel-set! 1)
|
||||
(let ((s4-1 (-> obj skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
s4-1
|
||||
(the-as art-joint-anim (-> obj draw art-group data (-> s5-1 anim)))
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> s4-1 frame-num) 0.0)
|
||||
(dummy-14 obj (the-as skeleton-group s4-0) '())
|
||||
)
|
||||
(ja-channel-set! 1)
|
||||
(let ((s4-1 (-> obj skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
s4-1
|
||||
(the-as art-joint-anim (-> obj draw art-group data (-> s5-1 anim)))
|
||||
num-func-identity
|
||||
)
|
||||
(let ((a2-2 (-> s5-1 ambient-sound-spec)))
|
||||
(when a2-2
|
||||
(let ((a3-0 (new 'stack-no-clear 'vector)))
|
||||
(vector+! a3-0 (-> obj root trans) (-> obj draw bounds))
|
||||
(set! (-> obj sound) (new 'process 'ambient-sound a2-2 a3-0))
|
||||
)
|
||||
(set! (-> s4-1 frame-num) 0.0)
|
||||
)
|
||||
(let ((a2-2 (-> s5-1 ambient-sound-spec)))
|
||||
(when a2-2
|
||||
(let ((a3-0 (new 'stack-no-clear 'vector)))
|
||||
(vector+! a3-0 (-> obj root trans) (-> obj draw bounds))
|
||||
(set! (-> obj sound) (new 'process 'ambient-sound a2-2 a3-0))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(the-as ripple-wave-set (ja-post))
|
||||
)
|
||||
(the-as ripple-wave-set (ja-post))
|
||||
)
|
||||
|
||||
+187
-253
@@ -72,295 +72,233 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-3
|
||||
(new 'static 'state
|
||||
:name 'teetertotter-idle
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! teetertotter-idle (the-as (state none) v1-3))
|
||||
(set!
|
||||
(-> v1-3 event)
|
||||
(lambda :behavior teetertotter
|
||||
((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(let ((v1-0 arg2))
|
||||
(the-as object (cond
|
||||
((= v1-0 'attack)
|
||||
(case (-> arg3 param 1)
|
||||
(('flop)
|
||||
(when (target-on-end-of-teetertotter? self)
|
||||
(set! (-> self in-launch-window) #f)
|
||||
(increment-success-for-hint
|
||||
(the-as level-hint-control 676)
|
||||
)
|
||||
(go teetertotter-launch)
|
||||
(defstate teetertotter-idle (teetertotter)
|
||||
:event
|
||||
(behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(let ((v1-0 arg2))
|
||||
(the-as object (cond
|
||||
((= v1-0 'attack)
|
||||
(case (-> arg3 param 1)
|
||||
(('flop)
|
||||
(when (target-on-end-of-teetertotter? self)
|
||||
(set! (-> self in-launch-window) #f)
|
||||
(increment-success-for-hint
|
||||
(the-as level-hint-control 676)
|
||||
)
|
||||
(go teetertotter-launch)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= v1-0 'bonk)
|
||||
(when (target-on-end-of-teetertotter? self)
|
||||
(level-hint-spawn
|
||||
(game-text-id misty-teetertotter-bonk-dax-tutorial)
|
||||
"sksp0070"
|
||||
#f
|
||||
*entity-pool*
|
||||
0
|
||||
)
|
||||
(go teetertotter-bend)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= v1-0 'bonk)
|
||||
(when (target-on-end-of-teetertotter? self)
|
||||
(level-hint-spawn
|
||||
(game-text-id misty-teetertotter-bonk-dax-tutorial)
|
||||
"sksp0070"
|
||||
#f
|
||||
*entity-pool*
|
||||
0
|
||||
)
|
||||
(go teetertotter-bend)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> v1-3 code)
|
||||
(lambda :behavior teetertotter () (let ((gp-0 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-0
|
||||
(the-as
|
||||
art-joint-anim
|
||||
(-> self draw art-group data 4)
|
||||
)
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> gp-0 frame-num) 0.0)
|
||||
)
|
||||
(while #t
|
||||
(suspend)
|
||||
:code
|
||||
(behavior ()
|
||||
(let ((gp-0 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-0
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
num-func-identity
|
||||
)
|
||||
(none)
|
||||
(set! (-> gp-0 frame-num) 0.0)
|
||||
)
|
||||
(while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-3 post) transform-post)
|
||||
:post
|
||||
(the-as (function none :behavior teetertotter) transform-post)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-4
|
||||
(new 'static 'state
|
||||
:name 'teetertotter-launch
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! teetertotter-launch (the-as (state none) v1-4))
|
||||
(set!
|
||||
(-> v1-4 event)
|
||||
(lambda :behavior teetertotter
|
||||
((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(when (= arg2 'touch)
|
||||
(when
|
||||
(and
|
||||
((method-of-type touching-shapes-entry prims-touching?)
|
||||
(the-as touching-shapes-entry (-> arg3 param 0))
|
||||
(the-as collide-shape-moving (-> self root))
|
||||
(the-as uint 1)
|
||||
)
|
||||
(-> self rock-is-dangerous)
|
||||
)
|
||||
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-2 from) self)
|
||||
(set! (-> a1-2 num-params) 2)
|
||||
(set! (-> a1-2 message) 'attack)
|
||||
(set! (-> a1-2 param 0) (-> arg3 param 0))
|
||||
(let ((a0-2 (new 'static 'attack-info :mask #x20)))
|
||||
(set! (-> a0-2 mode) 'deadly)
|
||||
(set! (-> a1-2 param 1) (the-as uint a0-2))
|
||||
)
|
||||
(send-event-function arg0 a1-2)
|
||||
(defstate teetertotter-launch (teetertotter)
|
||||
:event
|
||||
(behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(when (= arg2 'touch)
|
||||
(when
|
||||
(and
|
||||
((method-of-type touching-shapes-entry prims-touching?)
|
||||
(the-as touching-shapes-entry (-> arg3 param 0))
|
||||
(the-as collide-shape-moving (-> self root))
|
||||
(the-as uint 1)
|
||||
)
|
||||
(-> self rock-is-dangerous)
|
||||
)
|
||||
(when
|
||||
(and
|
||||
((method-of-type touching-shapes-entry prims-touching?)
|
||||
(the-as touching-shapes-entry (-> arg3 param 0))
|
||||
(the-as collide-shape-moving (-> self root))
|
||||
(the-as uint 2)
|
||||
)
|
||||
(target-on-end-of-teetertotter? self)
|
||||
(not (-> self launched-player))
|
||||
(-> self in-launch-window)
|
||||
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-2 from) self)
|
||||
(set! (-> a1-2 num-params) 2)
|
||||
(set! (-> a1-2 message) 'attack)
|
||||
(set! (-> a1-2 param 0) (-> arg3 param 0))
|
||||
(let ((a0-2 (new 'static 'attack-info :mask #x20)))
|
||||
(set! (-> a0-2 mode) 'deadly)
|
||||
(set! (-> a1-2 param 1) (the-as uint a0-2))
|
||||
)
|
||||
(let ((a1-4 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-4 from) self)
|
||||
(set! (-> a1-4 num-params) 2)
|
||||
(set! (-> a1-4 message) 'shove)
|
||||
(set! (-> a1-4 param 0) (the-as uint #f))
|
||||
(let ((v1-16 (new 'static 'attack-info :mask #xcc0)))
|
||||
(set! (-> v1-16 shove-back) 0.0)
|
||||
(set! (-> v1-16 shove-up) 53248.0)
|
||||
(set! (-> v1-16 angle) 'jump)
|
||||
(set! (-> v1-16 control) 1.0)
|
||||
(set! (-> a1-4 param 1) (the-as uint v1-16))
|
||||
)
|
||||
(when (send-event-function arg0 a1-4)
|
||||
(let ((v0-0 #t))
|
||||
(set! (-> self launched-player) v0-0)
|
||||
v0-0
|
||||
)
|
||||
(send-event-function arg0 a1-2)
|
||||
)
|
||||
)
|
||||
(when
|
||||
(and
|
||||
((method-of-type touching-shapes-entry prims-touching?)
|
||||
(the-as touching-shapes-entry (-> arg3 param 0))
|
||||
(the-as collide-shape-moving (-> self root))
|
||||
(the-as uint 2)
|
||||
)
|
||||
(target-on-end-of-teetertotter? self)
|
||||
(not (-> self launched-player))
|
||||
(-> self in-launch-window)
|
||||
)
|
||||
(let ((a1-4 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-4 from) self)
|
||||
(set! (-> a1-4 num-params) 2)
|
||||
(set! (-> a1-4 message) 'shove)
|
||||
(set! (-> a1-4 param 0) (the-as uint #f))
|
||||
(let ((v1-16 (new 'static 'attack-info :mask #xcc0)))
|
||||
(set! (-> v1-16 shove-back) 0.0)
|
||||
(set! (-> v1-16 shove-up) 53248.0)
|
||||
(set! (-> v1-16 angle) 'jump)
|
||||
(set! (-> v1-16 control) 1.0)
|
||||
(set! (-> a1-4 param 1) (the-as uint v1-16))
|
||||
)
|
||||
(when (send-event-function arg0 a1-4)
|
||||
(let ((v0-0 #t))
|
||||
(set! (-> self launched-player) v0-0)
|
||||
v0-0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> v1-4 code)
|
||||
(lambda :behavior teetertotter
|
||||
()
|
||||
(local-vars (v1-16 symbol) (f0-4 float))
|
||||
(set! (-> self launched-player) #f)
|
||||
(let ((a0-0 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-0 frame-group)
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
)
|
||||
(set!
|
||||
(-> a0-0 param 0)
|
||||
(the
|
||||
float
|
||||
(+
|
||||
(->
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
data
|
||||
0
|
||||
length
|
||||
)
|
||||
-1
|
||||
:code
|
||||
(behavior ()
|
||||
(local-vars (v1-16 symbol) (f0-4 float))
|
||||
(set! (-> self launched-player) #f)
|
||||
(let ((a0-0 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-0 frame-group)
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
)
|
||||
(set!
|
||||
(-> a0-0 param 0)
|
||||
(the
|
||||
float
|
||||
(+
|
||||
(->
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
data
|
||||
0
|
||||
length
|
||||
)
|
||||
-1
|
||||
)
|
||||
)
|
||||
(set! (-> a0-0 param 1) 1.0)
|
||||
(set! (-> a0-0 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-0
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(until (begin
|
||||
(set! (-> self rock-is-dangerous) (and v1-16 (>= 76.0 f0-4)))
|
||||
(suspend)
|
||||
(let ((a0-2 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-2 param 0)
|
||||
(the float (+ (-> a0-2 frame-group data 0 length) -1))
|
||||
)
|
||||
(set! (-> a0-2 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-2
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
(set! (-> a0-0 param 1) 1.0)
|
||||
(set! (-> a0-0 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-0
|
||||
(the-as art-joint-anim (-> self draw art-group data 4))
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(until (begin
|
||||
(set! (-> self rock-is-dangerous) (and v1-16 (>= 76.0 f0-4)))
|
||||
(suspend)
|
||||
(let ((a0-2 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-2 param 0)
|
||||
(the float (+ (-> a0-2 frame-group data 0 length) -1))
|
||||
)
|
||||
(set! (-> a0-2 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-2
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(set! f0-4 (ja-aframe-num 0))
|
||||
(set! (-> self in-launch-window) (and (>= f0-4 76.0) (>= 82.0 f0-4)))
|
||||
(set! v1-16 (>= f0-4 12.0))
|
||||
)
|
||||
(go teetertotter-idle)
|
||||
(none)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(set! f0-4 (ja-aframe-num 0))
|
||||
(set! (-> self in-launch-window) (and (>= f0-4 76.0) (>= 82.0 f0-4)))
|
||||
(set! v1-16 (>= f0-4 12.0))
|
||||
)
|
||||
(go teetertotter-idle)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-4 post) rider-post)
|
||||
:post
|
||||
(the-as (function none :behavior teetertotter) rider-post)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-5
|
||||
(new 'static 'state
|
||||
:name 'teetertotter-bend
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
(defstate teetertotter-bend (teetertotter)
|
||||
:code
|
||||
(behavior ()
|
||||
(let ((a0-0 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-0 frame-group)
|
||||
(the-as art-joint-anim (-> self draw art-group data 5))
|
||||
)
|
||||
(set!
|
||||
(-> a0-0 param 0)
|
||||
(the
|
||||
float
|
||||
(+
|
||||
(->
|
||||
(the-as art-joint-anim (-> self draw art-group data 5))
|
||||
data
|
||||
0
|
||||
length
|
||||
)
|
||||
-1
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> a0-0 param 1) 1.0)
|
||||
(set! (-> a0-0 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-0
|
||||
(the-as art-joint-anim (-> self draw art-group data 5))
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! teetertotter-bend (the-as (state none) v1-5))
|
||||
(set!
|
||||
(-> v1-5 code)
|
||||
(lambda :behavior teetertotter () (let ((a0-0 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-0 frame-group)
|
||||
(the-as
|
||||
art-joint-anim
|
||||
(-> self draw art-group data 5)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> a0-0 param 0)
|
||||
(the
|
||||
float
|
||||
(+
|
||||
(->
|
||||
(the-as
|
||||
art-joint-anim
|
||||
(-> self draw art-group data 5)
|
||||
)
|
||||
data
|
||||
0
|
||||
length
|
||||
)
|
||||
-1
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> a0-0 param 1) 1.0)
|
||||
(set! (-> a0-0 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-0
|
||||
(the-as
|
||||
art-joint-anim
|
||||
(-> self draw art-group data 5)
|
||||
)
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(until (begin
|
||||
(suspend)
|
||||
(let ((a0-1 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-1 param 0)
|
||||
(the float (+ (-> a0-1 frame-group data 0 length) -1))
|
||||
)
|
||||
(set! (-> a0-1 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-1
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
(until (begin
|
||||
(suspend)
|
||||
(let ((a0-1 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-1 param 0)
|
||||
(the float (+ (-> a0-1 frame-group data 0 length) -1))
|
||||
)
|
||||
(set! (-> a0-1 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-1
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
(go teetertotter-idle)
|
||||
(none)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
(go teetertotter-idle)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-5 post) rider-post)
|
||||
:post
|
||||
(the-as (function none :behavior teetertotter) rider-post)
|
||||
)
|
||||
|
||||
;; definition for method 11 of type teetertotter
|
||||
@@ -481,7 +419,3 @@
|
||||
(go teetertotter-idle)
|
||||
(none)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+112
-184
@@ -41,61 +41,39 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-2
|
||||
(new 'static 'state
|
||||
:name 'silostep-idle
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
(defstate silostep-idle (silostep)
|
||||
:event
|
||||
(behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(let ((v1-0 arg2))
|
||||
(the-as object (cond
|
||||
((= v1-0 'trigger)
|
||||
(go silostep-camera)
|
||||
)
|
||||
((= v1-0 'trigger-rise)
|
||||
(go silostep-rise #f)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! silostep-idle (the-as (state none) v1-2))
|
||||
(set!
|
||||
(-> v1-2 event)
|
||||
(the-as
|
||||
(function process int symbol event-message-block object)
|
||||
(lambda :behavior silostep
|
||||
((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
||||
(case arg2
|
||||
(('trigger)
|
||||
(go silostep-camera)
|
||||
)
|
||||
(('trigger-rise)
|
||||
enter-state
|
||||
(go silostep-rise)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
:code
|
||||
(behavior ()
|
||||
(let ((gp-0 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-0
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> gp-0 frame-num) 0.0)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> v1-2 code)
|
||||
(lambda :behavior silostep () (let ((gp-0 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-0
|
||||
(the-as
|
||||
art-joint-anim
|
||||
(-> self draw art-group data 2)
|
||||
)
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> gp-0 frame-num) 0.0)
|
||||
)
|
||||
(transform-post)
|
||||
(while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
(transform-post)
|
||||
(while #t
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-2 post) ja-post)
|
||||
:post
|
||||
(the-as (function none :behavior silostep) ja-post)
|
||||
)
|
||||
|
||||
;; definition for function misty-camera-view
|
||||
@@ -159,129 +137,96 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-4
|
||||
(new 'static 'state
|
||||
:name 'silostep-camera
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
(defstate silostep-camera (silostep)
|
||||
:code
|
||||
(behavior ()
|
||||
(misty-camera-view)
|
||||
(let* ((gp-0 (get-task-control (game-task misty-warehouse)))
|
||||
(v1-1 (get-reminder gp-0 0))
|
||||
)
|
||||
(save-reminder gp-0 (logior v1-1 2) 0)
|
||||
)
|
||||
(set! (-> self state-time) (-> *display* base-frame-counter))
|
||||
(let ((gp-1 (-> *display* base-frame-counter)))
|
||||
(until (begin
|
||||
(suspend)
|
||||
(>= (the-as int (- (-> *display* base-frame-counter) gp-1)) 300)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! silostep-camera (the-as (state none) v1-4))
|
||||
(set!
|
||||
(-> v1-4 code)
|
||||
(lambda :behavior silostep
|
||||
()
|
||||
(misty-camera-view)
|
||||
(let* ((gp-0 (get-task-control (game-task misty-warehouse)))
|
||||
(v1-1 (get-reminder gp-0 0))
|
||||
)
|
||||
(save-reminder gp-0 (logior v1-1 2) 0)
|
||||
)
|
||||
(set! (-> self state-time) (-> *display* base-frame-counter))
|
||||
(let ((gp-1 (-> *display* base-frame-counter)))
|
||||
(until (begin
|
||||
(suspend)
|
||||
(>= (the-as int (- (-> *display* base-frame-counter) gp-1)) 300)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
)
|
||||
(sound-play-by-name
|
||||
(static-sound-name "arena-steps")
|
||||
(new-sound-id)
|
||||
1024
|
||||
0
|
||||
0
|
||||
(the-as uint 1)
|
||||
(the-as vector #t)
|
||||
)
|
||||
(send-to-all-after (-> self link) 'trigger-rise)
|
||||
enter-state
|
||||
(go silostep-rise)
|
||||
(none)
|
||||
(sound-play-by-name
|
||||
(static-sound-name "arena-steps")
|
||||
(new-sound-id)
|
||||
1024
|
||||
0
|
||||
0
|
||||
(the-as uint 1)
|
||||
(the-as vector #t)
|
||||
)
|
||||
(send-to-all-after (-> self link) 'trigger-rise)
|
||||
(go silostep-rise #f)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-4 post) ja-post)
|
||||
:post
|
||||
(the-as (function none :behavior silostep) ja-post)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((v1-5
|
||||
(new 'static 'state
|
||||
:name 'silostep-rise
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! silostep-rise (the-as (state none) v1-5))
|
||||
(set!
|
||||
(-> v1-5 code)
|
||||
(lambda :behavior silostep
|
||||
((arg0 symbol))
|
||||
(process-entity-status! self (entity-perm-status complete) #t)
|
||||
(when (not arg0)
|
||||
(let ((a0-2 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-2 frame-group)
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
)
|
||||
(set! (-> a0-2 param 0) (-> self anim-limit))
|
||||
(set! (-> a0-2 param 1) 1.0)
|
||||
(set! (-> a0-2 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-2
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(until (begin
|
||||
(rider-trans)
|
||||
(rider-post)
|
||||
(suspend)
|
||||
(let ((a0-3 (-> self skel root-channel 0)))
|
||||
(set! (-> a0-3 param 0) (-> self anim-limit))
|
||||
(set! (-> a0-3 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-3
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
)
|
||||
(let ((gp-1 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-1
|
||||
(defstate silostep-rise (silostep)
|
||||
:code
|
||||
(behavior ((arg0 symbol))
|
||||
(process-entity-status! self (entity-perm-status complete) #t)
|
||||
(when (not arg0)
|
||||
(let ((a0-2 (-> self skel root-channel 0)))
|
||||
(set!
|
||||
(-> a0-2 frame-group)
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> gp-1 frame-num) (-> self anim-limit))
|
||||
(set! (-> a0-2 param 0) (-> self anim-limit))
|
||||
(set! (-> a0-2 param 1) 1.0)
|
||||
(set! (-> a0-2 frame-num) 0.0)
|
||||
(joint-control-channel-group!
|
||||
a0-2
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(rider-post)
|
||||
(while #t
|
||||
(ja-post)
|
||||
(suspend)
|
||||
(until (begin
|
||||
(rider-trans)
|
||||
(rider-post)
|
||||
(suspend)
|
||||
(let ((a0-3 (-> self skel root-channel 0)))
|
||||
(set! (-> a0-3 param 0) (-> self anim-limit))
|
||||
(set! (-> a0-3 param 1) 1.0)
|
||||
(joint-control-channel-group-eval!
|
||||
a0-3
|
||||
(the-as art-joint-anim #f)
|
||||
num-func-seek!
|
||||
)
|
||||
)
|
||||
(ja-done? 0)
|
||||
)
|
||||
(empty)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(let ((gp-1 (-> self skel root-channel 0)))
|
||||
(joint-control-channel-group-eval!
|
||||
gp-1
|
||||
(the-as art-joint-anim (-> self draw art-group data 2))
|
||||
num-func-identity
|
||||
)
|
||||
(set! (-> gp-1 frame-num) (-> self anim-limit))
|
||||
)
|
||||
(rider-post)
|
||||
(while #t
|
||||
(ja-post)
|
||||
(suspend)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set! (-> v1-5 post) #f)
|
||||
:post
|
||||
(the-as (function none :behavior silostep) #f)
|
||||
)
|
||||
|
||||
;; definition for method 11 of type silostep
|
||||
@@ -346,20 +291,15 @@
|
||||
)
|
||||
)
|
||||
(set! (-> obj link) (new 'process 'actor-link-info obj))
|
||||
(cond
|
||||
((and
|
||||
(-> obj entity)
|
||||
(nonzero?
|
||||
(logand (-> obj entity extra perm status) (entity-perm-status complete))
|
||||
)
|
||||
(if
|
||||
(and
|
||||
(-> obj entity)
|
||||
(nonzero?
|
||||
(logand (-> obj entity extra perm status) (entity-perm-status complete))
|
||||
)
|
||||
enter-state
|
||||
#t
|
||||
(go silostep-rise)
|
||||
)
|
||||
(else
|
||||
(go silostep-idle)
|
||||
)
|
||||
(go silostep-rise #t)
|
||||
(go silostep-idle)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
@@ -440,20 +380,8 @@
|
||||
(dummy-14 obj *rounddoor-sg* '())
|
||||
(set! (-> obj open-distance) 69632.0)
|
||||
(set! (-> obj close-distance) 81920.0)
|
||||
(set!
|
||||
(-> obj open-sound)
|
||||
(the-as
|
||||
uint128
|
||||
(make-u128 (the-as uint #x6e65706f2d72) (the-as uint #x6f6f64616e657261))
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> obj close-sound)
|
||||
(the-as
|
||||
uint128
|
||||
(make-u128 (the-as uint #x65736f6c632d72) (the-as uint #x6f6f64616e657261))
|
||||
)
|
||||
)
|
||||
(set! (-> obj open-sound) (static-sound-name "arenadoor-open"))
|
||||
(set! (-> obj close-sound) (static-sound-name "arenadoor-close"))
|
||||
(set! (-> obj speed) 1.5)
|
||||
(set! (-> obj auto-close) #t)
|
||||
(set! (-> obj one-way) #t)
|
||||
|
||||
+143
-251
@@ -66,284 +66,180 @@
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((gp-0
|
||||
(new 'static 'state
|
||||
:name 'plat-button-pressed
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
(defstate plat-button-pressed (sunken-elevator)
|
||||
:virtual #t
|
||||
:enter
|
||||
(behavior ()
|
||||
(let ((t9-0 (-> (method-of-type plat-button plat-button-pressed) enter)))
|
||||
(if t9-0
|
||||
(t9-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(inherit-state
|
||||
gp-0
|
||||
(the-as state (method-of-type plat-button plat-button-pressed))
|
||||
)
|
||||
(method-set! sunken-elevator 22 (the-as function gp-0))
|
||||
(set!
|
||||
(-> gp-0 enter)
|
||||
(the-as
|
||||
(function object object object object object object object)
|
||||
(lambda :behavior sunken-elevator
|
||||
()
|
||||
(let
|
||||
((t9-0
|
||||
(the-as
|
||||
function
|
||||
(->
|
||||
(the-as (state none) (method-of-type plat-button plat-button-pressed))
|
||||
enter
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(the-as (function object object object object object object object) t9-0)
|
||||
((the-as (function object) t9-0))
|
||||
)
|
||||
)
|
||||
(case (-> self path-pos)
|
||||
((0.0)
|
||||
(load-state-want-display-level 'sunken 'display)
|
||||
(let ((gp-0 (get-process *default-dead-pool* village2cam #x4000)))
|
||||
(set! (-> (the-as village2cam (-> (when gp-0
|
||||
(let
|
||||
((t9-3
|
||||
(method-of-type
|
||||
village2cam
|
||||
activate
|
||||
)
|
||||
)
|
||||
)
|
||||
(t9-3
|
||||
(the-as village2cam gp-0)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
(case (-> self path-pos)
|
||||
((0.0)
|
||||
(load-state-want-display-level 'sunken 'display)
|
||||
(let ((gp-0 (get-process *default-dead-pool* village2cam #x4000)))
|
||||
(set! (-> (the-as village2cam (-> (when gp-0
|
||||
(let
|
||||
((t9-3
|
||||
(method-of-type
|
||||
village2cam
|
||||
activate
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-0
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-0 ppointer)
|
||||
)
|
||||
0
|
||||
)
|
||||
)
|
||||
seq
|
||||
)
|
||||
(the-as uint 0)
|
||||
)
|
||||
)
|
||||
0
|
||||
)
|
||||
((1.0)
|
||||
(let* ((gp-1 (get-process *default-dead-pool* village2cam #x4000))
|
||||
(v1-10 (when gp-1
|
||||
(let ((t9-6 (method-of-type village2cam activate)))
|
||||
(t9-6
|
||||
(the-as village2cam gp-1)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-1
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-1 ppointer)
|
||||
)
|
||||
)
|
||||
(v0-5 1)
|
||||
(t9-3
|
||||
(the-as village2cam gp-0)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-0
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-0 ppointer)
|
||||
)
|
||||
0
|
||||
)
|
||||
)
|
||||
seq
|
||||
)
|
||||
(set! (-> (the-as village2cam (-> v1-10 0)) seq) (the-as uint v0-5))
|
||||
v0-5
|
||||
(the-as uint 0)
|
||||
)
|
||||
)
|
||||
0
|
||||
)
|
||||
((1.0)
|
||||
(let* ((gp-1 (get-process *default-dead-pool* village2cam #x4000))
|
||||
(v1-10 (when gp-1
|
||||
(let ((t9-6 (method-of-type village2cam activate)))
|
||||
(t9-6
|
||||
(the-as village2cam gp-1)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-1
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-1 ppointer)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> (the-as village2cam (-> v1-10 0)) seq) (the-as uint 1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((gp-1
|
||||
(new 'static 'state
|
||||
:name 'plat-button-move-upward
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
(defstate plat-button-move-upward (sunken-elevator)
|
||||
:virtual #t
|
||||
:enter
|
||||
(behavior ()
|
||||
(let ((t9-0 (-> (method-of-type plat-button plat-button-move-upward) enter)))
|
||||
(if t9-0
|
||||
(t9-0)
|
||||
)
|
||||
)
|
||||
(set! (-> self play-at-top-going-up-camera?) #t)
|
||||
(none)
|
||||
)
|
||||
(inherit-state
|
||||
gp-1
|
||||
(the-as state (method-of-type plat-button plat-button-move-upward))
|
||||
)
|
||||
(method-set! sunken-elevator 24 (the-as function gp-1))
|
||||
(set!
|
||||
(-> gp-1 enter)
|
||||
(the-as
|
||||
(function object object object object object object object)
|
||||
(lambda :behavior sunken-elevator
|
||||
()
|
||||
(let
|
||||
((t9-0
|
||||
(the-as
|
||||
function
|
||||
(->
|
||||
(the-as
|
||||
(state none)
|
||||
(method-of-type plat-button plat-button-move-upward)
|
||||
:trans
|
||||
(behavior ()
|
||||
(let ((t9-0 (-> (method-of-type plat-button plat-button-move-upward) trans)))
|
||||
(if t9-0
|
||||
(t9-0)
|
||||
)
|
||||
)
|
||||
(when
|
||||
(and (-> self play-at-top-going-up-camera?) (>= 0.14 (-> self path-pos)))
|
||||
(set! *teleport* #t)
|
||||
(set! (-> self play-at-top-going-up-camera?) #f)
|
||||
(load-state-want-display-level 'sunken 'special)
|
||||
(let* ((gp-0 (get-process *default-dead-pool* village2cam #x4000))
|
||||
(v1-8 (when gp-0
|
||||
(let ((t9-3 (method-of-type village2cam activate)))
|
||||
(t9-3
|
||||
(the-as village2cam gp-0)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-0
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-0 ppointer)
|
||||
)
|
||||
)
|
||||
)
|
||||
enter
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(the-as (function object object object object object object object) t9-0)
|
||||
((the-as (function object) t9-0))
|
||||
)
|
||||
)
|
||||
(let ((v0-1 #t))
|
||||
(set! (-> self play-at-top-going-up-camera?) v0-1)
|
||||
v0-1
|
||||
)
|
||||
(set! (-> (the-as village2cam (-> v1-8 0)) seq) (the-as uint 2))
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(set!
|
||||
(-> gp-1 trans)
|
||||
(lambda :behavior sunken-elevator
|
||||
()
|
||||
(let
|
||||
((t9-0
|
||||
(->
|
||||
(the-as
|
||||
(state none)
|
||||
(method-of-type plat-button plat-button-move-upward)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(defstate plat-button-move-downward (sunken-elevator)
|
||||
:virtual #t
|
||||
:trans
|
||||
(behavior ()
|
||||
(let ((s5-0 (new 'stack-no-clear 'vector))
|
||||
(gp-0 (new 'stack-no-clear 'vector))
|
||||
)
|
||||
(set! *teleport* #t)
|
||||
(set! (-> s5-0 quad) (-> self root-override trans quad))
|
||||
(let
|
||||
((t9-1
|
||||
(->
|
||||
(the-as (state sunken-elevator) (find-parent-method sunken-elevator 23))
|
||||
trans
|
||||
)
|
||||
)
|
||||
)
|
||||
(if t9-0
|
||||
(t9-0)
|
||||
(if t9-1
|
||||
(t9-1)
|
||||
)
|
||||
)
|
||||
(when
|
||||
(and (-> self play-at-top-going-up-camera?) (>= 0.14 (-> self path-pos)))
|
||||
(set! *teleport* #t)
|
||||
(set! (-> self play-at-top-going-up-camera?) #f)
|
||||
(load-state-want-display-level 'sunken 'special)
|
||||
(let* ((gp-0 (get-process *default-dead-pool* village2cam #x4000))
|
||||
(v1-8 (when gp-0
|
||||
(let ((t9-3 (method-of-type village2cam activate)))
|
||||
(t9-3
|
||||
(the-as village2cam gp-0)
|
||||
self
|
||||
'village2cam
|
||||
(the-as pointer #x70004000)
|
||||
)
|
||||
)
|
||||
(run-function-in-process
|
||||
gp-0
|
||||
pov-camera-init-by-other
|
||||
(-> self spawn-pos)
|
||||
*village2cam-sg*
|
||||
"elevator-at-top-going-down"
|
||||
0
|
||||
#f
|
||||
'()
|
||||
)
|
||||
(-> gp-0 ppointer)
|
||||
)
|
||||
)
|
||||
(v0-1 2)
|
||||
)
|
||||
(set! (-> (the-as village2cam (-> v1-8 0)) seq) (the-as uint v0-1))
|
||||
v0-1
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let
|
||||
((gp-2
|
||||
(new 'static 'state
|
||||
:name 'plat-button-move-downward
|
||||
:next #f
|
||||
:exit #f
|
||||
:code #f
|
||||
:trans #f
|
||||
:post #f
|
||||
:enter #f
|
||||
:event #f
|
||||
)
|
||||
)
|
||||
)
|
||||
(inherit-state
|
||||
gp-2
|
||||
(the-as state (method-of-type plat-button plat-button-move-downward))
|
||||
)
|
||||
(method-set! sunken-elevator 23 (the-as function gp-2))
|
||||
(set!
|
||||
(-> gp-2 trans)
|
||||
(lambda :behavior sunken-elevator
|
||||
()
|
||||
(let ((s5-0 (new 'stack-no-clear 'vector))
|
||||
(gp-0 (new 'stack-no-clear 'vector))
|
||||
)
|
||||
(set! *teleport* #t)
|
||||
(set! (-> s5-0 quad) (-> self root-override trans quad))
|
||||
(let
|
||||
((t9-1
|
||||
(-> (the-as (state none) (find-parent-method sunken-elevator 23)) trans)
|
||||
)
|
||||
)
|
||||
(if t9-1
|
||||
(t9-1)
|
||||
)
|
||||
)
|
||||
(vector-! gp-0 (-> self root-override trans) s5-0)
|
||||
)
|
||||
(when (< (-> self path-pos) 0.9)
|
||||
((method-of-object (-> *target* control) dummy-28))
|
||||
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-2 from) self)
|
||||
(set! (-> a1-2 num-params) 0)
|
||||
(set! (-> a1-2 message) 'reset-height)
|
||||
(send-event-function *target* a1-2)
|
||||
)
|
||||
(vector-! gp-0 (-> self root-override trans) s5-0)
|
||||
)
|
||||
(when (< (-> self path-pos) 0.9)
|
||||
((method-of-object (-> *target* control) dummy-28))
|
||||
(let ((a1-2 (new 'stack-no-clear 'event-message-block)))
|
||||
(set! (-> a1-2 from) self)
|
||||
(set! (-> a1-2 num-params) 0)
|
||||
(set! (-> a1-2 message) 'reset-height)
|
||||
(send-event-function *target* a1-2)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -412,7 +308,3 @@
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -101,8 +101,8 @@
|
||||
|
||||
|
||||
(defstate die-state (process)
|
||||
:enter (lambda () (format #t "enter die~%"))
|
||||
:exit (lambda () (format #t "exit die~%"))
|
||||
:enter (lambda () (format #t "enter die~%") (none))
|
||||
:exit (lambda () (format #t "exit die~%") (none))
|
||||
:code (lambda ()
|
||||
(format #t "time to die!~%")
|
||||
(process-deactivate)
|
||||
@@ -145,14 +145,14 @@
|
||||
|
||||
;; a state.
|
||||
(defstate xmm-check-state (process)
|
||||
:enter (lambda (x y z w) (format #t "enter check: ~D ~D ~D ~D~%" x y z w))
|
||||
:exit (lambda () (format #t "exit check~%"))
|
||||
:enter (lambda (x y z w) (format #t "enter check: ~D ~D ~D ~D~%" x y z w) (none))
|
||||
:exit (lambda () (format #t "exit check~%") (none))
|
||||
:code xmm-check-code
|
||||
)
|
||||
|
||||
(defstate xmm-wreck-state (process)
|
||||
:enter (lambda (x y z w) (format #t "enter wreck: ~D ~D ~D ~D~%" x y z w))
|
||||
:exit (lambda () (format #t "exit wreck~%"))
|
||||
:enter (lambda (x y z w) (format #t "enter wreck: ~D ~D ~D ~D~%" x y z w) (none))
|
||||
:exit (lambda () (format #t "exit wreck~%") (none))
|
||||
:code xmm-wreck-code
|
||||
)
|
||||
|
||||
|
||||
@@ -327,46 +327,6 @@ TEST_F(OfflineDecompilation, CheckBasicDecode) {
|
||||
EXPECT_EQ(obj_count, config->allowed_objects.size());
|
||||
}
|
||||
|
||||
/*!
|
||||
* Not a super great test, but check that we find functions, methods, and logins.
|
||||
* This is a test of ir2_top_level_pass, which isn't tested as part of the normal decompiler
|
||||
tests.
|
||||
*/
|
||||
TEST_F(OfflineDecompilation, FunctionDetect) {
|
||||
int function_count = 0; // global functions
|
||||
int method_count = 0; // methods
|
||||
int login_count = 0; // top-level logins
|
||||
int unknown_count = 0; // unknown functions, like anonymous lambdas
|
||||
|
||||
db->for_each_function(
|
||||
[&](decompiler::Function& func, int segment_id, decompiler::ObjectFileData&) {
|
||||
if (segment_id == TOP_LEVEL_SEGMENT) {
|
||||
EXPECT_EQ(func.guessed_name.kind, decompiler::FunctionName::FunctionKind::TOP_LEVEL_INIT);
|
||||
} else {
|
||||
EXPECT_NE(func.guessed_name.kind, decompiler::FunctionName::FunctionKind::TOP_LEVEL_INIT);
|
||||
}
|
||||
switch (func.guessed_name.kind) {
|
||||
case decompiler::FunctionName::FunctionKind::GLOBAL:
|
||||
function_count++;
|
||||
break;
|
||||
case decompiler::FunctionName::FunctionKind::METHOD:
|
||||
method_count++;
|
||||
break;
|
||||
case decompiler::FunctionName::FunctionKind::TOP_LEVEL_INIT:
|
||||
login_count++;
|
||||
break;
|
||||
case decompiler::FunctionName::FunctionKind::UNIDENTIFIED:
|
||||
unknown_count++;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
});
|
||||
|
||||
// one login per object file
|
||||
EXPECT_EQ(config->allowed_objects.size(), login_count);
|
||||
}
|
||||
|
||||
TEST_F(OfflineDecompilation, AsmFunction) {
|
||||
int failed_count = 0;
|
||||
db->for_each_function([&](decompiler::Function& func, int, decompiler::ObjectFileData&) {
|
||||
|
||||
Reference in New Issue
Block a user