SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
CameraManEvent.cpp
1#include "Game/Camera/Camera.hpp"
2#include "Game/Camera/CamTranslatorAnim.hpp"
3#include "Game/Camera/CameraDirector.hpp"
4#include "Game/Camera/CameraHeightArrange.hpp"
5#include "Game/Camera/CameraLocalUtil.hpp"
6#include "Game/Camera/CameraManEvent.hpp"
7#include "Game/Camera/CameraHolder.hpp"
8#include "Game/Camera/CameraParamChunk.hpp"
9#include "Game/Camera/CameraParamChunkHolder.hpp"
10#include "Game/Util/CameraUtil.hpp"
11
12#ifdef NON_MATCHING
13// Constructor for mTargetArg is called. The constructor exists in the symbol so
14// it's not fully inlined. It also exists in the code (not inlined), but the code below
15// matches the constructor exactly.
16CameraManEvent::ChunkFIFOItem::ChunkFIFOItem() {
17 mTargetArg.mTargetObj = nullptr;
18 mTargetArg.mTargetMtx = nullptr;
19 mTargetArg.mLiveActor = nullptr;
20 mTargetArg.mMarioActor = nullptr;
21}
22#endif
23
24CameraManEvent::CameraManEvent(CameraHolder *pHolder, CameraParamChunkHolder *pChunkHolder, const char *pName) :
25 CameraMan(pName), mHolder(pHolder), mChunkHolder(pChunkHolder), mCamera(nullptr) {
26 mChunk = nullptr;
27 _B8 = 0;
28 _BC = false;
29
30 for (u32 i = 0; i < NR_FIFO_ITEMS; i++) {
31 mItems[i].mFirst.mChunk = nullptr;
32 mItems[i].mSecond.mChunk = nullptr;
33 }
34}
35
36CameraManEvent::~CameraManEvent() {
37
38}
39
41
42}
43
44void CameraManEvent::calc() {
45 updateChunkFIFO();
46 applyChunk();
47 changeCamera();
48 resetCameraIfRequested();
49 CameraTargetObj *target = mCamera->calc();
50 CameraLocalUtil::setUsedTarget(this, target);
51 setSafePose();
52}
53
54void CameraManEvent::notifyActivate() {
55 _BC = true;
56}
57
58void CameraManEvent::notifyDeactivate() {
59 mCamera = nullptr;
60}
61
62bool CameraManEvent::isInterpolationOff() const {
63 if (mCamera != nullptr && mCamera->isInterpolationOff()) {
64 return true;
65 }
66
67 if (mChunk != nullptr && mChunk->isAntiBlurOff()) {
68 return true;
69 }
70
71 return false;
72}
73
74bool CameraManEvent::isCollisionOff() const {
75 if (mCamera != nullptr && mCamera->isCollisionOff()) {
76 return true;
77 }
78
79 if (mChunk != nullptr && mChunk->isCollisionOff()) {
80 return true;
81 }
82
83 return false;
84}
85
86bool CameraManEvent::isZeroFrameMoveOff() const {
87 if (mCamera != nullptr) {
88 return mCamera->isZeroFrameMoveOff();
89 }
90
91 return false;
92}
93
94bool CameraManEvent::isCorrectingErpPositionOff() const {
95 bool off = false;
96
97 if (mCamera != nullptr && mCamera->isCorrectingErpPositionOff()) {
98 off = true;
99 }
100
101 return off;
102}
103
104void CameraManEvent::start(long zoneID, const char *pName, const CameraTargetArg &rTargetArg, long a4) {
105 CameraParamChunkEvent *chunk = findChunk(zoneID, pName);
106 requestChunk(chunk, static_cast<EPriority>(chunk->mEvPriority), rTargetArg, a4);
107 rTargetArg.setTarget();
108}
109
110void CameraManEvent::end(long zoneID, const char *pName, long a3) {
111 CameraParamChunkEvent *chunk = findChunk(zoneID, pName);
112 searchPriority(chunk);
113
114 if (cleanChunkFIFO(chunk)) {
115 sendFinishInterpolateFrame(chunk, a3);
116 }
117
118 if (isChunkFIFOEmpty()) {
119 mChunk = nullptr;
120 MR::cleanEventCameraTarget_temporally();
121 }
122}
123
124bool CameraManEvent::isEventActive(long zoneID, const char *pName) const {
125 if (mCamera != nullptr) {
127 chunkID.createEventID(zoneID, pName);
128
129 CameraParamChunkEvent *chunk = reinterpret_cast<CameraParamChunkEvent *>(mChunkHolder->getChunk(chunkID));
130
131 // Nice loop, probably they wanted i--
132 for (s32 i = NR_FIFO_ITEMS - 1; i >= 0; i++) {
133 if (mItems[i].mSecond.mChunk != nullptr) {
134 return mItems[i].mSecond.mChunk == chunk;
135 }
136
137 if (mItems[i].mFirst.mChunk != nullptr) {
138 return mItems[i].mFirst.mChunk == chunk;
139 }
140 }
141 }
142
143 return false;
144}
145
146bool CameraManEvent::isActive() const {
147 return !isChunkFIFOEmpty();
148}
149
150bool CameraManEvent::doesNextChunkHaveInterpolation() const {
151 const ChunkFIFOItem *item = nullptr;
152
153 for (u32 i = 0; i < NR_FIFO_ITEMS; i++) {
154 if (mItems[i].mSecond.mChunk != nullptr) {
155 item = &mItems[i].mSecond;
156 break;
157 }
158
159 if (mItems[i].mFirst.mChunk != nullptr) {
160 break;
161 }
162 }
163
164 if (item != nullptr && getInterpolateFrame(item->mChunk, item->_14) > 0) {
165 return true;
166 }
167
168 return false;
169}
170
171u32 CameraManEvent::getAnimCameraFrame(long zoneID, const char *pName) const {
172 mHolder->getIndexOf("CAM_TYPE_ANIM");
173 CameraParamChunkEvent *chunk = findChunk(zoneID, pName);
174 CamTranslatorAnim *translator = reinterpret_cast<CamTranslatorAnim *>(mHolder->getTranslator(chunk->mCameraTypeIndex));
175
176 return translator->getAnimFrame(chunk);
177}
178
179void CameraManEvent::pauseOnAnimCamera(long zoneID, const char *pName) {
180 mHolder->getIndexOf("CAM_TYPE_ANIM");
181 CameraParamChunkEvent *chunk = findChunk(zoneID, pName);
182
183 if (chunk == mChunk && mCamera != nullptr) {
184 CameraAnim *animCamera = reinterpret_cast<CameraAnim *>(mCamera);
185 animCamera->_7C = 1;
186 }
187}
188
189void CameraManEvent::pauseOffAnimCamera(long zoneID, const char *pName) {
190 mHolder->getIndexOf("CAM_TYPE_ANIM");
191 CameraParamChunkEvent *chunk = findChunk(zoneID, pName);
192
193 if (chunk == mChunk && mCamera != nullptr) {
194 CameraAnim *animCamera = reinterpret_cast<CameraAnim *>(mCamera);
195 animCamera->_7C = 0;
196 }
197}
198
199#ifdef NON_MATCH
200// LWZ wrong instruction order, register mismatch
201void CameraManEvent::updateChunkFIFO() {
202 for (u32 i = 0; i < NR_FIFO_ITEMS; i++) {
203 CameraParamChunkEvent *chunk = mItems[i].mSecond.mChunk;
204
205 if (chunk != nullptr) {
206 mItems[i].mFirst.mChunk = chunk;
207
208 CameraTargetMtx *mtx = mItems[i].mSecond.mTargetArg.mTargetMtx;
209 CameraTargetObj *obj = mItems[i].mSecond.mTargetArg.mTargetObj;
210
211 mItems[i].mFirst.mTargetArg.mTargetObj = obj;
212 mItems[i].mFirst.mTargetArg.mTargetMtx = mtx;
213
214 const LiveActor *liveActor = mItems[i].mSecond.mTargetArg.mLiveActor;
215 MarioActor *marioActor = mItems[i].mSecond.mTargetArg.mMarioActor;
216
217 mItems[i].mFirst.mTargetArg.mLiveActor = liveActor;
218 mItems[i].mFirst.mTargetArg.mMarioActor = marioActor;
219
220 mItems[i].mFirst._14 = mItems[i].mSecond._14;
221
222 mItems[i].mSecond.mChunk = nullptr;
223 }
224 }
225}
226#endif
227
228void CameraManEvent::applyChunk() {
229 ChunkFIFOItem *item = nullptr;
230
231 for (u32 i = 0; i < NR_FIFO_ITEMS; i++) {
232 if (mItems[i].mFirst.mChunk != nullptr) {
233 item = &mItems[i].mFirst;
234 break;
235 }
236 }
237
238 checkReset(item);
239 mChunk = item->mChunk;
240}
241
242void CameraManEvent::checkReset(ChunkFIFOItem *pItem) {
243 CameraParamChunkEvent *itemChunk = pItem->mChunk;
244
245 if (mChunk != itemChunk) {
246 _BC = true;
247 sendStartInterpolateFrame(pItem->mChunk, pItem->_14);
248 pItem->mTargetArg.setTarget();
249 }
250 else {
251 u8 cameraIndex = itemChunk->mCameraTypeIndex;
252
253 if (cameraIndex != mHolder->getIndexOf(mCamera)) {
254 _BC = true;
255 }
256 }
257}
258
259void CameraManEvent::changeCamera() {
260 mCamera = mHolder->getCameraInner(mChunk->mCameraTypeIndex);
261 CamTranslatorBase *translator = mHolder->getTranslator(mChunk->mCameraTypeIndex);
262 translator->setParam(mChunk);
263 setExtraParam();
264 setVPanParam();
265}
266
267void CameraManEvent::setExtraParam() {
268 s32 zoneID = mChunk->getZoneID();
269 mCamera->setZoneMtx(zoneID);
270
271 CameraLocalUtil::setGlobalOffset(mCamera, mChunk->mExParam.mWOffset);
272
273 TVec3f *localOffset = CameraLocalUtil::getLocalOffset(this);
274 CameraLocalUtil::setLocalOffset(mCamera, *localOffset);
275
276 CameraLocalUtil::setFrontOffset(mCamera, mChunk->mExParam.mLOffset);
277 CameraLocalUtil::setUpperOffset(mCamera, mChunk->mExParam.mLOffsetV);
278
279 if (mChunk->isOnUseFovy()) {
280 CameraLocalUtil::setFovy(mCamera, mChunk->mExParam.mFovy);
281 }
282 else {
283 f32 fovy = mDirector->getDefaultFovy();
284 CameraLocalUtil::setFovy(mCamera, fovy);
285 }
286
287 if (mChunk->isLOfsErpOff()) {
288 mCamera->mIsLOfsErpOff = true;
289 }
290 else {
291 mCamera->mIsLOfsErpOff = false;
292 }
293
294 CameraLocalUtil::setRoll(mCamera, mChunk->mExParam.mRoll);
295}
296
297#ifdef NON_MATCHING
298// r0 nonsense
299void CameraManEvent::setVPanParam() {
300 if (mCamera->mVPan != nullptr) {
301 CameraHeightArrange *vPan = mCamera->mVPan;
302 vPan->resetParameter();
303
304 vPan->mUpper = mChunk->mExParam.mUpper;
305 vPan->mLower = mChunk->mExParam.mLower;
306 vPan->mGndInt = mChunk->mExParam.mGndInt;
307 vPan->mUPlay = mChunk->mExParam.mUPlay;
308 vPan->mLPlay = mChunk->mExParam.mLPlay;
309 vPan->mPushDelay = mChunk->mExParam.mPushDelay;
310 vPan->mPushDelayLow = mChunk->mExParam.mPushDelayLow;
311 vPan->mUDown = mChunk->mExParam.mUDown;
312 vPan->mVPanUse = mChunk->mExParam.mVPanUse != 0;
313
314 TVec3f axis;
315 mChunk->getVPanAxis(&axis);
316
317 vPan->mVPanAxis.set(axis);
318
319 vPan->_60 = 1;
320 }
321}
322#endif
323
324void CameraManEvent::resetCameraIfRequested() {
325 if (_BC) {
326 mCamera->mCameraMan = this;
327 mCamera->reset();
328 _BC = false;
329 }
330}
331
332/*void CameraManEvent::setSafePose() {
333 TVec3f pos = TVec3f(*CameraLocalUtil::getPos(mCamera));
334 TVec3f watchPos = TVec3f(*CameraLocalUtil::getWatchPos(mCamera));
335 TVec3f up = TVec3f(*CameraLocalUtil::getUpVec(mCamera));
336
337 TVec3f dir = watchPos - pos;
338
339 float length = PSVECMag(reinterpret_cast<Vec *>(&dir));
340
341 if (length < 300.0f) {
342 if (length < 1.0f) {
343
344 }
345 }
346}*/
347
348CameraParamChunkEvent *CameraManEvent::findChunk(long zoneID, const char *pName) const {
350 chunkID.createEventID(zoneID, pName);
351
352 return reinterpret_cast<CameraParamChunkEvent *>(mChunkHolder->getChunk(chunkID));
353}
354
355void CameraManEvent::requestChunk(CameraParamChunkEvent *pChunk, EPriority priority, const CameraTargetArg &rArg, long a4) {
356 mItems[priority].mSecond.mChunk = pChunk;
357 mItems[priority].mSecond.mTargetArg.mTargetObj = rArg.mTargetObj;
358 mItems[priority].mSecond.mTargetArg.mTargetMtx = rArg.mTargetMtx;
359 mItems[priority].mSecond.mTargetArg.mLiveActor = rArg.mLiveActor;
360 mItems[priority].mSecond.mTargetArg.mMarioActor = rArg.mMarioActor;
361 mItems[priority].mSecond._14 = a4;
362}
363
364bool CameraManEvent::cleanChunkFIFO(CameraParamChunk *pChunk) {
365 s32 nr = 0;
366
367 for (u32 i = 0; i < NR_FIFO_ITEMS; i++) {
368 if (mItems[i].mSecond.mChunk != nullptr && mItems[i].mSecond.mChunk == pChunk) {
369 mItems[i].mFirst.mChunk = nullptr;
370 mItems[i].mSecond.mChunk = nullptr;
371 break;
372 }
373
374 if (mItems[i].mFirst.mChunk != nullptr && mItems[i].mFirst.mChunk == pChunk) {
375 mItems[i].mFirst.mChunk = nullptr;
376 break;
377 }
378
379 if (mItems[i].mFirst.mChunk != nullptr || mItems[i].mSecond.mChunk != nullptr) {
380 nr++;
381 }
382 }
383
384 return nr == 0;
385}
386
387bool CameraManEvent::isChunkFIFOEmpty() const {
388 for (u32 i = 0; i < NR_FIFO_ITEMS; i++) {
389 if (mItems[i].mFirst.mChunk != nullptr) {
390 return false;
391 }
392
393 if (mItems[i].mSecond.mChunk != nullptr) {
394 return false;
395 }
396 }
397
398 return true;
399}
400
401void CameraManEvent::sendStartInterpolateFrame(CameraParamChunkEvent *pChunk, long a2) {
402 u32 frames = getInterpolateFrame(pChunk, a2);
403
404 if (frames == 0) {
405 _15 = 1;
406 }
407
408 mDirector->setInterpolation(frames);
409}
410
411s32 CameraManEvent::getInterpolateFrame(CameraParamChunkEvent *pChunk, long a2) const {
412 s32 frames = -1;
413
414 if (pChunk->mEnableErpFrame != 0) {
415 frames = pChunk->mExParam.mCamInt;
416 }
417
418 if (frames < 0 && a2 >= 0) {
419 frames = a2;
420 }
421
422 if (frames < 0) {
423 frames = 60;
424 }
425
426 return frames;
427}
428
429void CameraManEvent::sendFinishInterpolateFrame(CameraParamChunkEvent *pChunk, long a2) {
430 s32 frames = -1;
431
432 if (pChunk->mEnableEndErpFrame) {
433 frames = pChunk->mCamEndInt;
434 }
435 else if (pChunk->mEnableErpFrame) {
436 frames = pChunk->mExParam.mCamInt;
437 }
438
439 if (frames < 0 && a2 >= 0) {
440 frames = a2;
441 }
442
443 if (frames < 0) {
444 frames = 60;
445 }
446
447 mDirector->setInterpolation(frames);
448}
449
450s32 CameraManEvent::searchPriority(CameraParamChunk *pChunk) const {
451 s32 i;
452
453 for (i = 0; i < NR_FIFO_ITEMS; i++) {
454 if (mItems[i].mFirst.mChunk == pChunk) {
455 break;
456 }
457
458 if (mItems[i].mSecond.mChunk == pChunk) {
459 break;
460 }
461 }
462
463 return i;
464}
465
466bool CameraManEvent::isInFIFO(CameraParamChunk *pChunk) const {
467 for (u32 i = 0; i < NR_FIFO_ITEMS; i++) {
468 if (mItems[i].mFirst.mChunk == pChunk || mItems[i].mSecond.mChunk == pChunk) {
469 return true;
470 }
471 }
472
473 return false;
474}
475
476bool CameraManEvent::isAnimCameraEnd(long zoneID, const char *pName) const {
477 mHolder->getIndexOf("CAM_TYPE_ANIM");
478 CameraParamChunkEvent *chunk = findChunk(zoneID, pName);
479
480 if (isInFIFO(chunk)) {
481 if (chunk == mChunk && mCamera != nullptr) {
482 return reinterpret_cast<CameraAnim *>(mCamera)->isAnimEnd();
483 }
484 else {
485 return false;
486 }
487 }
488
489 return true;
490}
virtual void init(const JMapInfoIter &)
Intializes the NameObj and can set various settings and construct necessary classes.
The basis of a drawable actor that can contain states (see: Nerve)
Definition LiveActor.hpp:24