SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
CameraShaker.cpp
1#include "Game/Camera/CameraShaker.hpp"
2#include "Game/Camera/CameraShakePatternImpl.hpp"
3#include "Game/Camera/CameraShakeTask.hpp"
4#include "Game/Util/CameraUtil.hpp"
5
6f32 sVerticalTaskTable[7] = {
7 0.08f,
8 0.2f,
9 0.5f,
10 1.0f,
11 3.0f,
12 6.0f,
13 9.0f
14};
15
16f32 sHorizontalTable[3] = {
17 0.3f,
18 1.0f,
19 3.0f
20};
21
22CameraShaker::CameraShaker(const char *pName) : NameObj(pName) {
23 createSinglyVerticalTask();
24 createSinglyHorizontalTask();
25 createInfinityTask();
26}
27
28CameraShaker::~CameraShaker() {
29
30}
31
32void CameraShaker::movement() {
33 updateSinglyVerticalTask();
34 updateSinglyHorizontalTask();
35 updateInfinityTask();
36 setOffset();
37}
38
39void CameraShaker::shakeVertical(ESinglyVerticalPower power) {
40 if (mVerticalTasks[power]->isEnd()) {
41 mVerticalTasks[power]->start(1, 0);
42 }
43}
44
45void CameraShaker::shakeInfinity(NameObj *pNameObj, float a2, float a3) {
46 for (u32 i = 0; i < NR_INFINITY_TASKS; i++) {
47 if (mInfinityTasks[i]->isEnd()) {
48 startInfinity(i, a2, a3);
49 mInfinityNameObjs[i] = pNameObj;
50 break;
51 }
52 }
53}
54
55void CameraShaker::stopShakingInfinity(NameObj *pNameObj) {
56 for (u32 i = 0; i < NR_INFINITY_TASKS; i++) {
57 if (mInfinityNameObjs[i] == pNameObj) {
58 mInfinityTasks[i]->endForce();
59 mInfinityNameObjs[i] = nullptr;
60 break;
61 }
62 }
63}
64
65void CameraShaker::createSinglyVerticalTask() {
66 for (u32 i = 0; i < NR_VERTICAL_TASKS; i++) {
67 CameraShakePatternSingly *singly = new CameraShakePatternSingly(sVerticalTaskTable[i]);
68 CameraShakeTask *task = new CameraShakeTask(singly);
69
70 mVerticalTasks[i] = task;
71 }
72}
73
74void CameraShaker::createSinglyHorizontalTask() {
75 // There is a bug with Nintendo's code.
76 // There are 3 horizontal tasks, but the loop runs seven, probably because the
77 // count was confused with vertical tasks. The game will read garbage memory from
78 // the horizontal float table and will set infinity tasks for values out of range,
79 // but it works because the infinity tasks are created afterwards and then set correctly.
80
81 // Should be i < NR_HORIZONTAL_TASKS
82 for (u32 i = 0; i < NR_VERTICAL_TASKS; i++) {
83 CameraShakePatternSingly *singly = new CameraShakePatternSingly(sHorizontalTable[i]);
84
85 TVec2f dir;
86 dir.x = 1.0f;
87 dir.y = 0.0f;
88
89 singly->setDirection(dir);
90
91 CameraShakeTask *task = new CameraShakeTask(singly);
92
93 mHorizontalTasks[i] = task;
94 }
95}
96
97void CameraShaker::createInfinityTask() {
98 for (u32 i = 0; i < NR_INFINITY_TASKS; i++) {
100 CameraShakeTask *task = new CameraShakeTask(sin);
101
102 mInfinityTasks[i] = task;
103 mInfinityNameObjs[i] = nullptr;
104 }
105}
106
107void CameraShaker::updateSinglyVerticalTask() {
108 for (u32 i = 0; i < NR_VERTICAL_TASKS; i++) {
109 mVerticalTasks[i]->movement();
110 }
111}
112
113void CameraShaker::updateSinglyHorizontalTask() {
114 for (u32 i = 0; i < NR_HORIZONTAL_TASKS; i++) {
115 mHorizontalTasks[i]->movement();
116 }
117}
118
119void CameraShaker::updateInfinityTask() {
120 for (u32 i = 0; i < NR_INFINITY_TASKS; i++) {
121 mInfinityTasks[i]->movement();
122 }
123}
124
125void CameraShaker::setOffset() {
126 TVec2f offset = TVec2f(0.0f, 0.0f);
127
128 addSinglyVerticalTaskOffset(&offset);
129 addSinglyHorizontalTaskOffset(&offset);
130 addInfinityTaskOffset(&offset);
131 adjustOffsetToScreen(&offset);
132 MR::setShakeOffset(offset.x, offset.y);
133}
134
135void CameraShaker::addSinglyVerticalTaskOffset(TVec2f *pOffset) {
136 for (u32 i = 0; i < NR_VERTICAL_TASKS; i++) {
137 if (!mVerticalTasks[i]->isEnd()) {
138 TVec2f offset;
139 mVerticalTasks[i]->getOffset(&offset);
140
141 pOffset->x += offset.x;
142 pOffset->y += offset.y;
143 }
144 }
145}
146
147void CameraShaker::addSinglyHorizontalTaskOffset(TVec2f *pOffset) {
148 for (u32 i = 0; i < NR_HORIZONTAL_TASKS; i++) {
149 if (!mHorizontalTasks[i]->isEnd()) {
150 TVec2f offset;
151 mHorizontalTasks[i]->getOffset(&offset);
152
153 pOffset->x += offset.x;
154 pOffset->y += offset.y;
155 }
156 }
157}
158
159void CameraShaker::addInfinityTaskOffset(TVec2f *pOffset) {
160 for (u32 i = 0; i < NR_INFINITY_TASKS; i++) {
161 if (!mInfinityTasks[i]->isEnd()) {
162 TVec2f offset;
163 mInfinityTasks[i]->getOffset(&offset);
164
165 pOffset->x += offset.x;
166 pOffset->y += offset.y;
167 }
168 }
169}
170
171void CameraShaker::startInfinity(unsigned long index, float a2, float a3) {
172 CameraShakePatternVerticalSin *sin = reinterpret_cast<CameraShakePatternVerticalSin *>(mInfinityTasks[index]->mPattern);
173
174 sin->_8 = a2;
175 sin->_C = a3;
176
177 mInfinityTasks[index]->startInfinity(0);
178}
The most basic form of an object.
Definition NameObj.hpp:11