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
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
|
#include "JSystem/J3DGraphBase/J3DShape.h"
#include "JSystem/J3DGraphBase/J3DPacket.h"
#include "JSystem/J3DGraphBase/J3DVertex.h"
#include "JSystem/J3DGraphBase/J3DFifo.h"
#include <dolphin/gd.h>
void J3DGDSetVtxAttrFmtv(_GXVtxFmt, GXVtxAttrFmtList const*, bool);
void J3DFifoLoadPosMtxImm(Mtx, u32);
void J3DFifoLoadNrmMtxImm(Mtx, u32);
void J3DShape::initialize() {
mMaterial = NULL;
mIndex = -1;
mMtxGroupNum = 0;
mFlags = 0;
mRadius = 0.0f;
mMin.x = 0.0f;
mMin.y = 0.0f;
mMin.z = 0.0f;
mMax.x = 0.0f;
mMax.y = 0.0f;
mMax.z = 0.0f;
mVtxDesc = NULL;
mShapeMtx = NULL;
mShapeDraw = NULL;
mVertexData = NULL;
mDrawMtxData = NULL;
mScaleFlagArray = NULL;
mDrawMtx = NULL;
mNrmMtx = NULL;
mCurrentViewNo = &j3dDefaultViewNo;
mHasNBT = false;
mHasPNMTXIdx = false;
}
/* 80314BB8-80314CBC 30F4F8 0104+00 0/0 1/1 0/0 .text addTexMtxIndexInDL__8J3DShapeF7_GXAttrUl */
void J3DShape::addTexMtxIndexInDL(GXAttr attr, u32 valueBase) {
u32 kSize[] = {0, 1, 1, 2};
s32 pnmtxidxOffs = -1;
s32 attrOffs = -1;
s32 stride = 0;
bool found = false;
for (GXVtxDescList* vtxDesc = getVtxDesc(); vtxDesc->attr != GX_VA_NULL; vtxDesc++) {
if (vtxDesc->attr == GX_VA_PNMTXIDX)
pnmtxidxOffs = stride;
if (attr < vtxDesc->attr && !found) {
attrOffs = stride;
found = true;
}
stride = stride + kSize[vtxDesc->type];
}
if (pnmtxidxOffs == -1)
return;
for (u16 i = 0; i < (u16)getMtxGroupNum(); i++)
getShapeDraw(i)->addTexMtxIndexInDL(stride, attrOffs, (s32)valueBase);
}
/* 80314CBC-80314DA8 30F5FC 00EC+00 0/0 1/1 0/0 .text addTexMtxIndexInVcd__8J3DShapeF7_GXAttr */
void J3DShape::addTexMtxIndexInVcd(GXAttr attr) {
u32 kSize[] = {0, 1, 1, 2}; // stripped data
s32 attrIdx = -1;
s32 attrOffs = -1;
s32 stride = 0;
GXVtxDescList* vtxDesc = getVtxDesc();
s32 attrCount = 0;
for (; vtxDesc->attr != GX_VA_NULL; attrCount++, vtxDesc++) {
if (vtxDesc->attr == GX_VA_PNMTXIDX)
attrIdx = stride;
}
if (attrIdx == -1)
return;
GXVtxDescList* newVtxDesc = new GXVtxDescList[attrCount + 2];
bool inserted = false;
vtxDesc = getVtxDesc();
GXVtxDescList* dst = newVtxDesc;
for (; vtxDesc->attr != GX_VA_NULL; dst++, vtxDesc++) {
if ((attr < vtxDesc->attr) && !inserted) {
dst->attr = attr;
dst->type = GX_DIRECT;
attrOffs = stride;
dst++;
inserted = true;
}
dst->attr = vtxDesc->attr;
dst->type = vtxDesc->type;
stride = stride + kSize[vtxDesc->type];
}
dst->attr = GX_VA_NULL;
dst->type = GX_NONE;
mVtxDesc = newVtxDesc;
makeVcdVatCmd();
}
/* 80314DA8-80314E28 30F6E8 0080+00 0/0 1/1 0/0 .text
* calcNBTScale__8J3DShapeFRC3VecPA3_A3_fPA3_A3_f */
void J3DShape::calcNBTScale(const Vec& param_0, f32 (*param_1)[3][3], f32 (*param_2)[3][3]) {
for (u16 i = 0; i < mMtxGroupNum; i++)
mShapeMtx[i]->calcNBTScale(param_0, param_1, param_2);
}
/* 80314E28-80314E98 30F768 0070+00 0/0 1/1 0/0 .text countBumpMtxNum__8J3DShapeCFv */
u16 J3DShape::countBumpMtxNum() const {
u16 num = 0;
for (u16 i = 0; i < mMtxGroupNum; i++)
num += mShapeMtx[i]->getUseMtxNum();
return num;
}
/* 80314E98-80314EB0 30F7D8 0018+00 1/1 0/0 0/0 .text J3DLoadCPCmd__FUcUl */
void J3DLoadCPCmd(u8 addr, u32 val) {
GXCmd1u8(GX_LOAD_CP_REG);
GXCmd1u8(addr);
GXCmd1u32(val);
}
/* 80314EB0-80314EEC 30F7F0 003C+00 1/1 0/0 0/0 .text J3DLoadArrayBasePtr__F7_GXAttrPv */
static void J3DLoadArrayBasePtr(GXAttr attr, void* data) {
u32 idx = (attr == GX_VA_NBT) ? 1 : (attr - GX_VA_POS);
J3DLoadCPCmd(0xA0 + idx, ((uintptr_t)data & 0x7FFFFFFF));
}
/* 80314EEC-80314F5C 30F82C 0070+00 3/3 0/0 0/0 .text loadVtxArray__8J3DShapeCFv */
void J3DShape::loadVtxArray() const {
J3DLoadArrayBasePtr(GX_VA_POS, j3dSys.getVtxPos());
if (!mHasNBT) {
J3DLoadArrayBasePtr(GX_VA_NRM, j3dSys.getVtxNrm());
}
J3DLoadArrayBasePtr(GX_VA_CLR0, j3dSys.getVtxCol());
}
/* 80314F5C-80314F98 30F89C 003C+00 0/0 1/1 0/0 .text isSameVcdVatCmd__8J3DShapeFP8J3DShape */
bool J3DShape::isSameVcdVatCmd(J3DShape* other) {
u8* a = (u8*)other->getVcdVatCmd();
u8* b = mVcdVatCmd;
for (u32 i = 0; i < kVcdVatDLSize; i++)
if (a[i] != b[i])
return false;
return true;
}
/* 80314F98-80315260 30F8D8 02C8+00 1/1 0/0 0/0 .text makeVtxArrayCmd__8J3DShapeFv */
void J3DShape::makeVtxArrayCmd() {
GXVtxAttrFmtList* vtxAttr = mVertexData->getVtxAttrFmtList();
u8 stride[12];
void* array[12];
for (u32 i = 0; i < 12; i++) {
stride[i] = 0;
array[i] = 0;
}
for (; vtxAttr->attr != GX_VA_NULL; vtxAttr++) {
switch (vtxAttr->attr) {
case GX_VA_POS: {
if (vtxAttr->type == GX_F32)
stride[vtxAttr->attr - GX_VA_POS] = 12;
else
stride[vtxAttr->attr - GX_VA_POS] = 6;
array[vtxAttr->attr - GX_VA_POS] = mVertexData->getVtxPosArray();
mVertexData->setVtxPosFrac((u8)vtxAttr->frac);
mVertexData->setVtxPosType((GXCompType)vtxAttr->type);
} break;
case GX_VA_NRM: {
if (vtxAttr->type == GX_F32)
stride[vtxAttr->attr - GX_VA_POS] = 12;
else
stride[vtxAttr->attr - GX_VA_POS] = 6;
array[vtxAttr->attr - GX_VA_POS] = mVertexData->getVtxNrmArray();
mVertexData->setVtxNrmFrac((u8)vtxAttr->frac);
mVertexData->setVtxNrmType((GXCompType)vtxAttr->type);
} break;
case GX_VA_CLR0:
case GX_VA_CLR1: {
stride[vtxAttr->attr - GX_VA_POS] = 4;
array[vtxAttr->attr - GX_VA_POS] = mVertexData->getVtxColorArray(vtxAttr->attr - GX_VA_CLR0);
} break;
case GX_VA_TEX0:
case GX_VA_TEX1:
case GX_VA_TEX2:
case GX_VA_TEX3:
case GX_VA_TEX4:
case GX_VA_TEX5:
case GX_VA_TEX6:
case GX_VA_TEX7: {
if (vtxAttr->type == GX_F32)
stride[vtxAttr->attr - GX_VA_POS] = 8;
else
stride[vtxAttr->attr - GX_VA_POS] = 4;
array[vtxAttr->attr - GX_VA_POS] = mVertexData->getVtxTexCoordArray(vtxAttr->attr - GX_VA_TEX0);
} break;
default:
break;
}
}
GXVtxDescList* vtxDesc = mVtxDesc;
mHasPNMTXIdx = false;
for (; vtxDesc->attr != GX_VA_NULL; vtxDesc++) {
if (vtxDesc->attr == GX_VA_NBT && vtxDesc->type != GX_NONE) {
mHasNBT = true;
stride[GX_VA_NRM - GX_VA_POS] *= 3;
array[GX_VA_NRM - GX_VA_POS] = mVertexData->getVtxNBTArray();
} else if (vtxDesc->attr == GX_VA_PNMTXIDX && vtxDesc->type != GX_NONE) {
mHasPNMTXIdx = true;
}
}
for (u32 i = 0; i < 12; i++) {
if (array[i] != 0)
GDSetArray((GXAttr)(i + GX_VA_POS), array[i], stride[i]);
else
GDSetArrayRaw((GXAttr)(i + GX_VA_POS), NULL, stride[i]);
}
}
/* 80315260-80315300 30FBA0 00A0+00 1/1 2/2 0/0 .text makeVcdVatCmd__8J3DShapeFv */
void J3DShape::makeVcdVatCmd() {
static BOOL sInterruptFlag = OSDisableInterrupts();
OSDisableScheduler();
GDLObj gdl_obj;
GDInitGDLObj(&gdl_obj, mVcdVatCmd, kVcdVatDLSize);
GDSetCurrent(&gdl_obj);
GDSetVtxDescv(mVtxDesc);
makeVtxArrayCmd();
J3DGDSetVtxAttrFmtv(GX_VTXFMT0, mVertexData->getVtxAttrFmtList(), mHasNBT);
GDPadCurr32();
GDFlushCurrToMem();
GDSetCurrent(NULL);
OSEnableScheduler();
OSRestoreInterrupts(sInterruptFlag);
}
/* 804515D0-804515D4 000AD0 0004+00 5/5 25/25 9/9 .sbss sOldVcdVatCmd__8J3DShape */
void* J3DShape::sOldVcdVatCmd;
void J3DShape::loadCurrentMtx() const {
mCurrentMtx.load();
}
/* 80315300-80315398 30FC40 0098+00 2/2 6/6 3/3 .text loadPreDrawSetting__8J3DShapeCFv */
void J3DShape::loadPreDrawSetting() const {
if (sOldVcdVatCmd != mVcdVatCmd) {
GXCallDisplayList(mVcdVatCmd, kVcdVatDLSize);
sOldVcdVatCmd = mVcdVatCmd;
}
mCurrentMtx.load();
}
/* 804515D4-804515D8 000AD4 0004+00 3/3 0/0 0/0 .sbss None */
bool J3DShape::sEnvelopeFlag;
/* 80315398-8031544C 30FCD8 00B4+00 1/1 0/0 0/0 .text setArrayAndBindPipeline__8J3DShapeCFv */
void J3DShape::setArrayAndBindPipeline() const {
J3DShapeMtx::setCurrentPipeline((mFlags & 0x1C) >> 2);
loadVtxArray();
j3dSys.setModelDrawMtx(mDrawMtx[*mCurrentViewNo]);
j3dSys.setModelNrmMtx(mNrmMtx[*mCurrentViewNo]);
J3DShapeMtx::sCurrentScaleFlag = mScaleFlagArray;
J3DShapeMtx::sNBTFlag = mHasNBT;
sEnvelopeFlag = mHasPNMTXIdx;
J3DShapeMtx::sTexMtxLoadType = getTexMtxLoadType();
}
/* 8031544C-803155E0 30FD8C 0194+00 1/0 0/0 0/0 .text drawFast__8J3DShapeCFv */
void J3DShape::drawFast() const {
if (sOldVcdVatCmd != mVcdVatCmd) {
GXCallDisplayList(mVcdVatCmd, kVcdVatDLSize);
sOldVcdVatCmd = mVcdVatCmd;
}
if (sEnvelopeFlag != 0 && !mHasPNMTXIdx)
mCurrentMtx.load();
setArrayAndBindPipeline();
if (!checkFlag(J3DShpFlag_NoMtx)) {
if (J3DShapeMtx::getLODFlag())
J3DShapeMtx::resetMtxLoadCache();
for (u16 n = mMtxGroupNum, i = 0; i < n; i++) {
if (mShapeMtx[i] != NULL)
mShapeMtx[i]->load();
if (mShapeDraw[i] != NULL)
mShapeDraw[i]->draw();
}
} else {
J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), GX_PNMTX0);
J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), GX_PNMTX0);
for (u16 n = mMtxGroupNum, i = 0; i < n; i++)
if (mShapeDraw[i] != NULL)
mShapeDraw[i]->draw();
}
}
/* 803155E0-80315628 30FF20 0048+00 1/0 0/0 0/0 .text draw__8J3DShapeCFv */
void J3DShape::draw() const {
resetVcdVatCache();
loadPreDrawSetting();
drawFast();
}
/* 80315628-803156AC 30FF68 0084+00 1/0 0/0 0/0 .text simpleDraw__8J3DShapeCFv */
void J3DShape::simpleDraw() const {
resetVcdVatCache();
loadPreDrawSetting();
J3DShapeMtx::setCurrentPipeline((mFlags & 0x1C) >> 2);
loadVtxArray();
for (u16 n = mMtxGroupNum, i = 0; i < n; i++) {
if (mShapeDraw[i] != NULL) {
mShapeDraw[i]->draw();
}
}
}
/* 803156AC-803157A0 30FFEC 00F4+00 1/0 0/0 0/0 .text simpleDrawCache__8J3DShapeCFv */
void J3DShape::simpleDrawCache() const {
if (sOldVcdVatCmd != mVcdVatCmd) {
GXCallDisplayList(mVcdVatCmd, kVcdVatDLSize);
sOldVcdVatCmd = mVcdVatCmd;
}
if (sEnvelopeFlag && !mHasPNMTXIdx)
mCurrentMtx.load();
loadVtxArray();
for (u16 n = mMtxGroupNum, i = 0; i < n; i++)
if (mShapeDraw[i] != NULL)
mShapeDraw[i]->draw();
}
|