summaryrefslogtreecommitdiff
path: root/src/TObject.cpp
blob: d133fd746db5436c0386bbf60f9e9e8135a93615 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#include "pso/TObject.h"
#define MATCHING

#define o(name) const char *name##_name = #name;
OBJECT_NAMES
#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;
	for (child = this->down; child != NULL; child = child->next) {
		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() {
	for (TObject *child = this->down; child != NULL; child = child->next) {
		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() {
	for (TObject *child = this->down; child != NULL; child = child->next) {
		if (!child->get_flags(0x100)) {
			child->func_0x14();
			child->call_func_0x14_for_each_node();
		}
	}
}

void TObject::call_func_0x10_for_each_node() {
	for (TObject *child = this->down; child != NULL; child = child->next) {
		if (!child->get_flags(0x10)) {
			child->func_0x10();
			child->call_func_0x10_for_each_node();
		}
	}
}

#ifndef MATCHING
// Near perfect match, just a single register allocation issue.
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)) {
			if (node->get_flags(1)) {
				node->clear_flags(1);
				if (!node->get_flags(0x20)) {
					delete node;
				} else {
					// Clearing child's flags with nothing here
					// causes the redundant load to appear.
					child->clear_flags(0);
					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.

						// Register allocation still wrong.

						// If `node` was used, it'd use the
						// proper register, but it'd also add
						// an unwanted `sth`.
						child->clear_flags(0);
					}
				}
			}
		} else {
			node->run_task();
			node->run_tasks();
		}
	}
}
#else
asm void TObject::run_tasks() {
	nofralloc
	/* 80229828 9421FFE0 */ stwu        r1, -0x20(r1)
	/* 8022982C 7C0802A6 */ mflr        r0
	/* 80229830 90010024 */ stw         r0, 0x24(r1)
	/* 80229834 BFA10014 */ stmw        r29, 0x14(r1)
	/* 80229838 7C7D1B78 */ mr          r29, r3
	/* 8022983C 83E30014 */ lwz         r31, 0x14(r3)
	/* 80229840 480000B8 */ b           lbl_802298f8
	lbl_80229844:
	/* 80229844 7FFEFB78 */ mr          r30, r31
	/* 80229848 83FF000C */ lwz         r31, 0xc(r31)
	/* 8022984C A07E0004 */ lhz         r3, 4(r30)
	/* 80229850 5460073F */ clrlwi.     r0, r3, 0x1c
	/* 80229854 41820088 */ beq-        lbl_802298dc
	/* 80229858 546007FF */ clrlwi.     r0, r3, 0x1f
	/* 8022985C 4182003C */ beq-        lbl_80229898
	/* 80229860 5460043C */ rlwinm      r0, r3, 0, 0x10, 0x1e
	/* 80229864 B01E0004 */ sth         r0, 4(r30)
	/* 80229868 A01E0004 */ lhz         r0, 4(r30)
	/* 8022986C 540006B5 */ rlwinm.     r0, r0, 0, 0x1a, 0x1a
	/* 80229870 40820028 */ bne-        lbl_80229898
	/* 80229874 281E0000 */ cmplwi      r30, 0
	/* 80229878 41820080 */ beq-        lbl_802298f8
	/* 8022987C 7FC3F378 */ mr          r3, r30
	/* 80229880 38800001 */ li          r4, 0x1
	/* 80229884 819E0018 */ lwz         r12, 0x18(r30)
	/* 80229888 818C0008 */ lwz         r12, 8(r12)
	/* 8022988C 7D8903A6 */ mtctr       r12
	/* 80229890 4E800421 */ bctrl
	/* 80229894 48000064 */ b           lbl_802298f8
	lbl_80229898:
	/* 80229898 A01E0004 */ lhz         r0, 4(r30)
	/* 8022989C 540007BD */ rlwinm.     r0, r0, 0, 0x1e, 0x1e
	/* 802298A0 4182002C */ beq-        lbl_802298cc
	/* 802298A4 7FC3F378 */ mr          r3, r30
	/* 802298A8 480000C1 */ bl          delete_children
	/* 802298AC 7FC3F378 */ mr          r3, r30
	/* 802298B0 819E0018 */ lwz         r12, 0x18(r30)
	/* 802298B4 818C000C */ lwz         r12, 0xc(r12)
	/* 802298B8 7D8903A6 */ mtctr       r12
	/* 802298BC 4E800421 */ bctrl
	/* 802298C0 A01E0004 */ lhz         r0, 4(r30)
	/* 802298C4 540007FA */ rlwinm      r0, r0, 0, 0x1f, 0x1d
	/* 802298C8 B01E0004 */ sth         r0, 4(r30)
	lbl_802298cc:
	/* 802298CC A07E0004 */ lhz         r3, 4(r30)
	/* 802298D0 5460077B */ rlwinm.     r0, r3, 0, 0x1d, 0x1d
	/* 802298D4 40820024 */ bne-        lbl_802298f8
	/* 802298D8 48000020 */ b           lbl_802298f8
	lbl_802298dc:
	/* 802298DC 7FC3F378 */ mr          r3, r30
	/* 802298E0 819E0018 */ lwz         r12, 0x18(r30)
	/* 802298E4 818C000C */ lwz         r12, 0xc(r12)
	/* 802298E8 7D8903A6 */ mtctr       r12
	/* 802298EC 4E800421 */ bctrl
	/* 802298F0 7FC3F378 */ mr          r3, r30
	/* 802298F4 4BFFFF35 */ bl          run_tasks
	lbl_802298f8:
	/* 802298F8 801D0014 */ lwz         r0, 0x14(r29)
	/* 802298FC 28000000 */ cmplwi      r0, 0
	/* 80229900 4182000C */ beq-        lbl_8022990c
	/* 80229904 281F0000 */ cmplwi      r31, 0
	/* 80229908 4082FF3C */ bne+        lbl_80229844
	lbl_8022990c:
	/* 8022990C BBA10014 */ lmw         r29, 0x14(r1)
	/* 80229910 80010024 */ lwz         r0, 0x24(r1)
	/* 80229914 7C0803A6 */ mtlr        r0
	/* 80229918 38210020 */ addi        r1, r1, 0x20
	/* 8022991C 4E800020 */ blr
}
#endif

void TObject::set_flag_0_for_each_node() {
	for (TObject *child = this->down; child != NULL; child = child->next) {
		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);
}

void TObject::clear_flag_9() {
	clear_flags(0x200);
}

void TObject::set_flag_9() {
	set_flags(0x200);
}

u32 TObject::get_flag_9() {
	return get_flags(0x200);
}

void TObject::set_flag_0() {
	set_flags(1);
}