[decomp] fisher and FIN.DGO (finalboss) level (#899)

* decomp `fisher`, `robotboss`, `light-eco`, `green-eco-lurker`, `sage-finalboss`, `robotboss-weapon`, `robotboss-misc`

* fixes

* add files

* add `:states` list to `deftype` and fix files

* test state forward decl's on a few more types

* also the refs

* add light-eco

* whatever
This commit is contained in:
ManDude
2021-10-16 19:06:33 +01:00
committed by GitHub
parent 9225d28444
commit caac740aff
185 changed files with 30529 additions and 4422 deletions
+37 -1
View File
@@ -246,6 +246,21 @@ std::string Type::common_type_info_diff(const Type& other) const {
}
}
}
if (m_states != other.m_states) {
if (m_states.size() != other.m_states.size()) {
result += fmt::format("Number of additional states {} vs. {}\n", m_states.size(),
other.m_states.size());
}
for (size_t i = 0; i < std::min(m_states.size(), other.m_states.size()); i++) {
if (m_states.at(i) != other.m_states.at(i)) {
result +=
fmt::format("State {} ({}/{}):\n", i, m_states.at(i).name, other.m_states.at(i).name);
result += m_states.at(i).diff(other.m_states.at(i));
result += "\n";
}
}
}
if (m_new_method_info != other.m_new_method_info) {
result += m_new_method_info.diff(other.m_new_method_info);
}
@@ -381,6 +396,27 @@ std::string Type::print_method_info() const {
return result;
}
const StateInfo& Type::add_state(const StateInfo& info) {
m_states.push_back(info);
return m_states.back();
}
bool StateInfo::operator==(const StateInfo& other) const {
return name == other.name && type == other.type;
}
std::string StateInfo::diff(const StateInfo& other) const {
std::string result;
if (name != other.name) {
result += fmt::format("name: {} vs. {}\n", name, other.name);
}
if (type != other.type) {
result += fmt::format("type: {} vs. {}\n", type.print(), other.type.print());
}
return result;
}
std::string Type::incompatible_diff(const Type& other) const {
return fmt::format("diff is not implemented between {} and {}\n", typeid((*this)).name(),
typeid(other).name());
@@ -1067,4 +1103,4 @@ std::string EnumType::diff_impl(const Type& other_) const {
}
return result;
}
}
+12
View File
@@ -27,6 +27,15 @@ struct MethodInfo {
std::string diff(const MethodInfo& other) const;
};
struct StateInfo {
std::string name;
TypeSpec type;
bool operator==(const StateInfo& other) const;
bool operator!=(const StateInfo& other) const { return !((*this) == other); }
std::string diff(const StateInfo& other) const;
};
/*!
* Parent class of all Types.
*/
@@ -80,12 +89,14 @@ class Type {
const MethodInfo& add_method(const MethodInfo& info);
const MethodInfo& add_new_method(const MethodInfo& info);
std::string print_method_info() const;
const StateInfo& add_state(const StateInfo& info);
void disallow_in_runtime() { m_allow_in_runtime = false; }
virtual ~Type() = default;
const std::vector<MethodInfo>& get_methods_defined_for_type() const { return m_methods; }
const std::vector<StateInfo>& get_states_declared_for_type() const { return m_states; }
const MethodInfo* get_new_method_defined_for_type() const {
if (m_new_method_info_defined) {
@@ -105,6 +116,7 @@ class Type {
std::string incompatible_diff(const Type& other) const;
std::vector<MethodInfo> m_methods;
std::vector<StateInfo> m_states;
MethodInfo m_new_method_info;
bool m_new_method_info_defined = false;
+20
View File
@@ -1692,6 +1692,26 @@ std::string TypeSystem::generate_deftype_footer(const Type* type) const {
result.append(")\n ");
}
std::string states_string;
for (auto& info : type->get_states_declared_for_type()) {
if (info.type.arg_count() > 1) {
states_string.append(fmt::format(" ({}", info.name));
for (size_t i = 0; i < info.type.arg_count() - 1; i++) {
states_string.push_back(' ');
states_string.append(info.type.get_arg(i).print());
}
states_string.append(")\n");
} else {
states_string.append(fmt::format(" {}\n", info.name));
}
}
if (!states_string.empty()) {
result.append("(:states\n");
result.append(states_string);
result.append(" )\n ");
}
result.append(")\n");
return result;
}
+32 -1
View File
@@ -243,6 +243,34 @@ void declare_method(Type* type, TypeSystem* type_system, const goos::Object& def
});
}
void declare_state(Type* type, TypeSystem* type_system, const goos::Object& def) {
for_each_in_list(def, [&](const goos::Object& _obj) {
auto obj = &_obj;
if (obj->is_list()) {
// (name ,@args)
auto state_name = symbol_string(car(obj));
auto args = cdr(obj);
TypeSpec state_typespec("state");
for_each_in_list(*args, [&](const goos::Object& o) {
state_typespec.add_arg(parse_typespec(type_system, o));
});
state_typespec.add_arg(TypeSpec(type->get_name()));
type->add_state({state_name, state_typespec});
} else {
// name
auto state_name = symbol_string(*obj);
TypeSpec state_typespec("state");
state_typespec.add_arg(TypeSpec(type->get_name()));
type->add_state({state_name, state_typespec});
}
});
}
struct StructureDefResult {
TypeFlags flags;
bool generate_runtime_type = true;
@@ -274,8 +302,11 @@ StructureDefResult parse_structure_def(StructureType* type,
auto& first = car(opt_list);
opt_list = cdr(opt_list);
if (symbol_string(first) == ":methods") {
auto list_name = symbol_string(first);
if (list_name == ":methods") {
declare_method(type, ts, *opt_list);
} else if (list_name == ":states") {
declare_state(type, ts, *opt_list);
} else {
throw std::runtime_error("Invalid option list in field specification: " +
car(rest).print());