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
|
/* Only implemented to the extent necessary to match data sections. */
#include "nw4r/snd/snd_AnimSoundReader.h"
#include "nw4r/snd/snd_BasicSound.h"
#include "nw4r/snd/snd_SoundHandle.h"
#include "nw4r/snd/snd_SoundStartable.h"
// Class and non-inlined function names from InazumaWii
// Names of automatically inlined functions from BBA
namespace nw4r {
namespace snd {
namespace detail {
class AnimEventPlayer {
public:
AnimEventPlayer();
~AnimEventPlayer();
SoundHandle *GetHandle() {
return &mHandle;
}
bool IsAttachedSound() const {
return mHandle.IsAttachedSound();
}
bool IsCurrentEvent(const AnimEvent *event) const {
return event == mpEvent;
}
int GetPriority() const {
if (!IsAttachedSound()) {
return 0;
}
return mHandle.detail_GetAttachedSound()->GetPriority();
}
bool IsRunning() const {
return mIsRunning;
}
void UpdateFrame();
void ForceStop();
void StopEvent(const AnimEvent *event) {
if (mpEvent == event) {
ForceStop();
}
}
void SetVolume(f32 volume) {
if (IsAttachedSound()) {
mHandle.detail_GetAttachedSound()->SetVolume(volume, 0);
}
}
void SetPitch(f32 pitch) {
if (IsAttachedSound()) {
mHandle.detail_GetAttachedSound()->SetPitch(pitch);
}
}
void StartEvent(const AnimEvent *event, SoundStartable *startable, bool b);
void HoldEvent(const AnimEvent *event, SoundStartable *startable, bool b);
// Not sure about these, this could be related to
// InitParam__Q44nw4r3snd6detail15AnimEventPlayerFPCQ44nw4r3snd6detail9AnimEventb
// from BBA, but SetVariable is almost certainly an inline (duplicated code)
// but the float argument is read from AnimSoundImpl so something seems to have
// changed.
void SetVolumePitch(const AnimEvent *event, bool b);
void SetVariable(const AnimEvent *event, u32 varNo, f32 f);
private:
SoundHandle mHandle; // at 0x00
const AnimEvent *mpEvent; // at 0x04
bool mIsRunning; // at 0x08
};
class AnimSoundImpl {
public:
enum PlayDirection {
FORWARD,
BACKWARD,
};
AnimSoundImpl(SoundStartable &startable, AnimEventPlayer *player, int);
~AnimSoundImpl();
bool Setup(const void *data);
void Shutdown();
void ResetFrame(f32, int cycle);
void UpdateFrame(f32 frame, PlayDirection dir);
void UpdateForward(f32 frame);
void UpdateBackward(f32 frame);
void UpdateOneFrame(s32 duration, PlayDirection direction);
void UpdateTrigger(const AnimEventRef *, s32, PlayDirection);
void UpdateForwardRange(const AnimEventRef *, s32);
void UpdateBackwardRange(const AnimEventRef *, s32);
void StartEvent(const AnimEvent *, bool);
void HoldEvent(const AnimEvent *, bool);
void StopEvent(const AnimEvent *);
bool IsPlayableLoopCount(const nw4r::snd::detail::AnimEventFrameInfo &);
typedef void (*Callback)(int, s32, const char *, UNKWORD, void *userData);
void SetCallback(Callback cb, void *userData) {
mCallback = cb;
mUserData = userData;
}
u32 GetAnimDuration() const {
return mReader.GetAnimDuration();
}
private:
/* 0x00 */ SoundStartable &mStartable;
/* 0x04 */ AnimSoundFileReader mReader;
/* 0x0C */ f32 mCurrentFrame;
/* 0x10 */ AnimEventPlayer *mpSounds;
/* 0x14 */ int mNumSounds;
/* 0x18 */ bool mIsActive;
/* 0x19 */ bool mNeedFrameReset;
/* 0x1A */ bool mNeedTriggerEventsAtCurrentFrame;
/* 0x1C */ int mCycleCounter;
/* 0x20 */ Callback mCallback;
/* 0x24 */ void *mUserData;
/* 0x28 */ f32 field_0x28;
/* 0x2C */ f32 mVariableValue;
};
} // namespace detail
// Not sure about this one but it appears game code isn't meant to access the "detail"
// namespace so I guess some way for game code to use the above things need to exist
class AnimSound {
public:
AnimSound(SoundStartable &startable) : mImpl(startable, mPlayers, 8) {}
enum PlayDirection {
FORWARD,
BACKWARD,
};
typedef void (*Callback)(int, s32, const char *, UNKWORD, void *userData);
bool Setup(const void *data) {
return mImpl.Setup(data);
}
void UpdateFrame(f32 frame, PlayDirection dir) {
mImpl.UpdateFrame(frame, (detail::AnimSoundImpl::PlayDirection)dir);
}
void ResetFrame(f32 frame, int cycle) {
mImpl.ResetFrame(frame, cycle);
}
void Shutdown() {
mImpl.Shutdown();
}
void SetCallback(Callback cb, void *userData) {
mImpl.SetCallback(cb, userData);
}
u32 GetAnimDuration() const {
return mImpl.GetAnimDuration();
}
private:
/* 0x00 */ detail::AnimSoundImpl mImpl;
/* 0x30 */ detail::AnimEventPlayer mPlayers[8];
};
} // namespace snd
} // namespace nw4r
|