#include "pso/TMainTask.h" #include "pso/TObject.h" #define MATCHING TMainTask main_task; TObject global_obj1; TObject global_obj2; #define o(name) OBJECT_NAME(name) OBJECT_NAMES #undef o #define o(var, name) const char *var##_name = #name; TL_OBJECTS #undef o void debug_print(const char *fmt) { } bool TObject::toggle_flag_9_if_flag_10_is_clear() { if (get_flags(0x400)) { return false; } if (!get_flag_9()) { set_flag_9(); return true; } else { clear_flag_9(); return false; } } void TObject::free(void *ptr) { } void *TObject::alloc(unsigned long size) { return NULL; } bool TObject::is_flag_0_clear_for_all_parents() { for (TObject *parent = this; parent != NULL; parent = parent->up) { if (parent->get_flags(1)) { return false; } } return true; } int TObject::get_node_count() { // NOTE: The order of the variable declarations matter for matching. TObject *child; int node_count = 0; FOREACH_NODE_NODECL(TObject, this->down, child) { node_count += child->get_node_count() + 1; } return node_count; } void TObject::log(const char *str) { debug_print(str); } void TObject::empty_func2() { } void TObject::func_0x14() { } void TObject::func_0x10() { } void TObject::run_task() { } void TObject::set_parent(TObject *parent) { remove_parent(); add_parent(parent, true); } void TObject::empty_func() { } void TObject::call_func_0x10_for_each_node2() { FOREACH_NODE(TObject, this->down, child) { if (child->get_flags(0x200)) { child->func_0x10(); child->clear_flag_9(); } child->call_func_0x10_for_each_node2(); } } void TObject::call_func_0x14_for_each_node() { FOREACH_NODE(TObject, this->down, child) { if (!child->get_flags(0x100)) { child->func_0x14(); child->call_func_0x14_for_each_node(); } } } void TObject::call_func_0x10_for_each_node() { FOREACH_NODE(TObject, this->down, child) { if (!child->get_flags(0x10)) { child->func_0x10(); child->call_func_0x10_for_each_node(); } } } // Perfect match, needed to do some weird stuff to get it to match, see below. void TObject::run_tasks() { TObject *child = this->down; while (this->down != NULL && child != NULL) { TObject *node = child; child = child->next; if (node->get_flags(0x0f)) { // Clearing flag 0 in the if statement is required to match. if (node->get_flags(1) && (node->clear_flags(1), !node->get_flags(0x20))) { delete node; } else { if (node->get_flags(2)) { node->delete_children(); node->run_task(); node->clear_flags(2); } if (!node->get_flags(4)) { // Adding this here somehow causes the // dead code to be compiled. // `volatile` typecast is required to match. (vu16)node->get_flags(1); } } } else { node->run_task(); node->run_tasks(); } } } void TObject::set_flag_0_for_each_node() { FOREACH_NODE(TObject, this->down, child) { child->set_flag_0(); child->set_flag_0_for_each_node(); } } void TObject::delete_children() { _delete_children(); } TObject::~TObject() { if (!get_flags(0x20)) { set_flags(0x20); _delete_children(); remove_parent(); } } TObject::TObject(TObject *parent) { flags = 0; up = parent; down = NULL; name = TObject_name; add_parent(parent, false); }