SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
CameraAnim.cpp
1#include "Game/Camera/CameraAnim.hpp"
2#include "Game/Camera/CamTranslatorAnim.hpp"
3
4KeyCamAnmDataAccessor::~KeyCamAnmDataAccessor() {
5
6}
7
8void KeyCamAnmDataAccessor::set(void *pInfo, void *pValues) {
9 mInfo = reinterpret_cast<CanmKeyFrameInfo *>(pInfo);
10 mValues = reinterpret_cast<f32 *>(pValues);
11}
12
13void KeyCamAnmDataAccessor::getPos(TVec3f *pPos, float key) const {
14 CanmKeyFrameComponentInfo &infoZ = mInfo->mPosZ;
15 CanmKeyFrameComponentInfo &infoY = mInfo->mPosY;
16 CanmKeyFrameComponentInfo &infoX = mInfo->mPosX;
17
18 f32 x;
19 f32 y;
20 f32 z;
21
22 z = get(key, infoZ.mOffset, infoZ.mCount, infoZ.mType);
23 y = get(key, infoY.mOffset, infoY.mCount, infoY.mType);
24 x = get(key, infoX.mOffset, infoX.mCount, infoX.mType);
25
26 pPos->set(x, y, z);
27}
28
29void KeyCamAnmDataAccessor::getWatchPos(TVec3f *pWatchPos, float key) const {
30 CanmKeyFrameComponentInfo &infoZ = mInfo->mWatchPosZ;
31 CanmKeyFrameComponentInfo &infoY = mInfo->mWatchPosY;
32 CanmKeyFrameComponentInfo &infoX = mInfo->mWatchPosX;
33
34 f32 x;
35 f32 y;
36 f32 z;
37
38 z = get(key, infoZ.mOffset, infoZ.mCount, infoZ.mType);
39 y = get(key, infoY.mOffset, infoY.mCount, infoY.mType);
40 x = get(key, infoX.mOffset, infoX.mCount, infoX.mType);
41
42 pWatchPos->set(x, y, z);
43}
44
45float KeyCamAnmDataAccessor::getTwist(float key) const {
46 CanmKeyFrameComponentInfo &info = mInfo->mTwist;
47
48 return get(key, info.mOffset, info.mCount, info.mType);
49}
50
51float KeyCamAnmDataAccessor::getFovy(float key) const {
52 CanmKeyFrameComponentInfo &info = mInfo->mFovy;
53
54 return get(key, info.mOffset, info.mCount, info.mType);
55}
56
57float KeyCamAnmDataAccessor::get(float key, unsigned long offset, unsigned long count, unsigned long type) const {
58 if (count == 1) {
59 return mValues[offset];
60 }
61
62 if (type == 0) {
63 return get3f(key, offset, count);
64 }
65 else {
66 return get4f(key, offset, count);
67 }
68}
69
70u32 KeyCamAnmDataAccessor::searchKeyFrameIndex(float key, unsigned long offset, unsigned long count, unsigned long stride) const {
71 u32 low = 0;
72 u32 high = count;
73
74 while (low < high) {
75 u32 middle = (low + high) / 2;
76
77 if (mValues[offset + middle * stride] <= key) {
78 low = middle + 1;
79 }
80 else {
81 high = middle;
82 }
83 }
84
85 return low - 1;
86}
87
88float KeyCamAnmDataAccessor::get3f(float key, unsigned long offset, unsigned long count) const {
89 u32 index = searchKeyFrameIndex(key, offset, count, 3);
90 f32 *values = mValues + offset + index * 3;
91
92 return calcHermite(key, values[0], values[1], values[2], values[3], values[4], values[5]);
93}
94
95float KeyCamAnmDataAccessor::get4f(float key, unsigned long offset, unsigned long count) const {
96 u32 index = searchKeyFrameIndex(key, offset, count, 4);
97 f32 *values = mValues + offset + index * 4;
98
99 return calcHermite(key, values[0], values[1], values[2], values[3], values[4], values[5]);
100}
101
102#ifdef NON_MATCHING
103// Float instruction order, register mismatch
104float KeyCamAnmDataAccessor::calcHermite(float key, float a2, float a3, float a4, float a5, float a6, float a7) const {
105 float fVar1 = a4 / 30.0f;
106 float fVar2 = (key - a2) / (a5 - a2);
107 float fVar3 = fVar2 * fVar2 - fVar2;
108
109 return -(key - a2) * (fVar2 * fVar1 - a7 / 30.0f * fVar3 + fVar1 * fVar3 + fVar1) - (((fVar2 + fVar2) * fVar3 - fVar2 * fVar2) * (a3 - a6) + a3);
110}
111#endif
112
113CamAnmDataAccessor::~CamAnmDataAccessor() {
114
115}
116
117void CamAnmDataAccessor::set(void *pInfo, void *pValues) {
118 mInfo = reinterpret_cast<CanmFrameInfo *>(pInfo);
119 mValues = reinterpret_cast<f32 *>(pValues);
120}
121
122void CamAnmDataAccessor::getPos(TVec3f *pPos, float key) const {
123 CamnFrameComponentInfo &infoZ = mInfo->mPosZ;
124 CamnFrameComponentInfo &infoY = mInfo->mPosY;
125 CamnFrameComponentInfo &infoX = mInfo->mPosX;
126
127 f32 x;
128 f32 y;
129 f32 z;
130
131 z = get(key, infoZ.mOffset, infoZ.mCount);
132 y = get(key, infoY.mOffset, infoY.mCount);
133 x = get(key, infoX.mOffset, infoX.mCount);
134
135 pPos->set(x, y, z);
136}
137
138void CamAnmDataAccessor::getWatchPos(TVec3f *pWatchPos, float key) const {
139 CamnFrameComponentInfo &infoZ = mInfo->mWatchPosZ;
140 CamnFrameComponentInfo &infoY = mInfo->mWatchPosY;
141 CamnFrameComponentInfo &infoX = mInfo->mWatchPosX;
142
143 f32 x;
144 f32 y;
145 f32 z;
146
147 z = get(key, infoZ.mOffset, infoZ.mCount);
148 y = get(key, infoY.mOffset, infoY.mCount);
149 x = get(key, infoX.mOffset, infoX.mCount);
150
151 pWatchPos->set(x, y, z);
152}
153
154float CamAnmDataAccessor::getTwist(float key) const {
155 CamnFrameComponentInfo &info = mInfo->mTwist;
156
157 return get(key, info.mOffset, info.mCount);
158}
159
160float CamAnmDataAccessor::getFovy(float key) const {
161 CamnFrameComponentInfo &info = mInfo->mFovy;
162
163 return get(key, info.mOffset, info.mCount);
164}
165
166/*float CamAnmDataAccessor::get(float key, unsigned long offset, unsigned long count) const {
167 u32 intKey = static_cast<u32>(key);
168 f32 fKey = static_cast<f32>(intKey);
169
170 f32 diff = key - fKey;
171
172 if (diff < 0.0f) {
173
174 }
175}*/
176
177CameraAnim::CameraAnim(const char *pName) : Camera(pName) {
178 _4C = 0;
179 _50 = 1;
180 mNrFrames = 0;
181 mIsKey = 0;
182 mSpeed = 1.0f;
183 mFileDataAccessor = nullptr;
184 mDataAccessor = new CamAnmDataAccessor();
185 mKeyDataAccessor = new KeyCamAnmDataAccessor();
186 mNrValues = 0;
187 _74 = 0;
188 mFileData = nullptr;
189 _7C = 0;
190}
191
192CameraAnim::~CameraAnim() {
193
194}
195
196bool CameraAnim::isZeroFrameMoveOff() const {
197 return true;
198}
199
200bool CameraAnim::isCollisionOff() const {
201 return true;
202}
203
204bool CameraAnim::isInterpolationOff() const {
205 return true;
206}
207
208CamTranslatorBase *CameraAnim::createTranslator() {
209 return new CamTranslatorAnim(this);
210}
211
212void CameraAnim::setParam(unsigned char *pFile, float speed) {
213 loadBin(pFile);
214 mFileData = pFile;
215 mSpeed = speed;
216}
217
218bool CameraAnim::isAnimEnd() const {
219 bool hasEnded = true;
220 u32 nrFrames = mNrFrames;
221
222 if (nrFrames != 0) {
223 if (!(mCurrentFrame >= nrFrames)) {
224 hasEnded = false;
225 }
226 }
227
228 return hasEnded;
229}
230
231u32 CameraAnim::getAnimFrame(unsigned char *pFile) {
232 if (pFile == nullptr) {
233 return 0;
234 }
235
236 CanmFileHeader *pHeader = reinterpret_cast<CanmFileHeader *>(pFile);
237
238 if (pHeader->mMagic[0] != 'A' || pHeader->mMagic[1] != 'N' || pHeader->mMagic[2] != 'D' || pHeader->mMagic[3] != 'O') {
239 return 0;
240 }
241
242 if ((pHeader->mType[0] != 'C' || pHeader->mType[1] != 'A' || pHeader->mType[2] != 'N' || pHeader->mType[3] != 'M') &&
243 (pHeader->mType[0] != 'C' || pHeader->mType[1] != 'K' || pHeader->mType[2] != 'A' || pHeader->mType[3] != 'N')) {
244 return 0;
245 }
246
247 if (pHeader->_8 == 0) {
248 return 0;
249 }
250
251 return pHeader->mNrFrames;
252}
253
254bool CameraAnim::loadBin(unsigned char *pFile) {
255 CanmFileHeader *pHeader = reinterpret_cast<CanmFileHeader *>(pFile);
256
257 if (pHeader->mMagic[0] != 'A' || pHeader->mMagic[1] != 'N' || pHeader->mMagic[2] != 'D' || pHeader->mMagic[3] != 'O') {
258 return false;
259 }
260
261 if (pHeader->mType[0] == 'C' && pHeader->mType[1] == 'A' && pHeader->mType[2] == 'N' && pHeader->mType[3] == 'M') {
262 mIsKey = 0;
263 mFileDataAccessor = mDataAccessor;
264 }
265 else if (pHeader->mType[0] == 'C' && pHeader->mType[1] == 'K' && pHeader->mType[2] == 'A' && pHeader->mType[3] == 'N') {
266 mIsKey = 1;
267 mFileDataAccessor = mKeyDataAccessor;
268 }
269 else {
270 return false;
271 }
272
273 if (pHeader->_8 == 0) {
274 return false;
275 }
276
277 u8 *pEntry = reinterpret_cast<u8 *>(pFile + sizeof(CanmFileHeader));
278 _4C = pHeader->_C;
279 _50 = pHeader->_10;
280 mNrFrames = pHeader->mNrFrames;
281
282 u32 valueOffset = pHeader->mValueOffset;
283
284 mNrValues = *(reinterpret_cast<u32 *>(&pEntry[valueOffset])) / sizeof(f32);
285
286 mFileDataAccessor->set(pEntry, pEntry + valueOffset + 4);
287
288 return true;
289}