NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
snd_SeqPlayer.h
1#ifndef NW4R_SND_SEQ_PLAYER_H
2#define NW4R_SND_SEQ_PLAYER_H
3
4/*******************************************************************************
5 * headers
6 */
7
8#include <types.h>
9
10#include "nw4r/snd/snd_BasicPlayer.h"
11#include "nw4r/snd/snd_DisposeCallbackManager.h" // DisposeCallback
12#include "nw4r/snd/snd_SeqTrack.h"
13#include "nw4r/snd/snd_SoundThread.h"
14#include "nw4r/ut/ut_Lock.h"
15
16/*******************************************************************************
17 * types
18 */
19
20// forward declarations
21namespace nw4r { namespace snd { namespace detail { class Channel; }}}
22namespace nw4r { namespace snd { namespace detail { class NoteOnCallback; }}}
23namespace nw4r { namespace snd { namespace detail { struct NoteOnInfo; }}}
24namespace nw4r { namespace snd { namespace detail { class SeqTrack; }}}
25namespace nw4r { namespace snd { namespace detail { class SeqTrackAllocator; }}}
26
27namespace nw4r { namespace snd
28{
29 // [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2dbb2
31 {
32 s16 volatile *localVariable; // size 0x04, offset 0x00
33 s16 volatile *globalVariable; // size 0x04, offset 0x04
34 s16 volatile *trackVariable; // size 0x04, offset 0x08
35 bool cmpFlag; // size 0x01, offset 0x0C
36 /* 3 bytes padding */
37 }; // size 0x10
38}} // namespace nw4r::snd
39
40/*******************************************************************************
41 * classes
42 */
43
44namespace nw4r { namespace snd { namespace detail
45{
46 // [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2dfad
47 class SeqPlayer : public BasicPlayer,
48 public DisposeCallback,
50 {
51 // enums
52 public:
53 // [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2dee8
54 enum OffsetType
55 {
56 OFFSET_TYPE_TICK,
57 OFFSET_TYPE_MILLISEC,
58 };
59
60 // [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2df3b
61 enum SetupResult
62 {
63 SETUP_SUCCESS,
64
65 SETUP_ERR_CANNOT_ALLOCATE_TRACK,
66
67 SETUP_ERR_UNKNOWN
68 };
69
70 // nested types
71 public:
72 // [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2cce4
74 {
75 u8 volume; // size 0x01, offset 0x00
76 u8 priority; // size 0x01, offset 0x01
77 u8 timebase; // size 0x01, offset 0x02
78 /* 1 byte padding */
79 u16 tempo; // size 0x02, offset 0x04
80 /* 2 bytes padding */
81 NoteOnCallback *callback; // size 0x04, offset 0x08
82 }; // size 0x0c
83
84 // typedefs
85 public:
86 typedef void SeqUserprocCallback(u16 procId,
88 void *callbackData);
89
90 // methods
91 public:
92 // cdtors
93 SeqPlayer();
94 virtual ~SeqPlayer();
95
96 // virtual function ordering
97 // vtable BasicPlayer
98 virtual bool Start();
99 virtual void Stop();
100 virtual void Pause(bool flag);
101 virtual bool IsActive() const { return mActiveFlag; }
102 virtual bool IsStarted() const { return mStartedFlag; }
103 virtual bool IsPause() const { return mPauseFlag; }
104
105 // vtable DisposeCallback
106 virtual void InvalidateData(void const *start, void const *end);
107 virtual void InvalidateWaveData(void const *, void const *) {}
108
109 // vtable SeqPlayer
110 /* WARNING: must come before SoundThread::PlayerCallback virtual
111 * functions
112 */
113 virtual void ChannelCallback(Channel *channel ATTR_UNUSED) {}
114
115 // vtable SoundThread::PlayerCallback
116 virtual void OnUpdateFrameSoundThread() { Update(); }
117 virtual void OnShutdownSoundThread() { Stop(); }
118
119 // methods
120 SetupResult Setup(SeqTrackAllocator *trackAllocator, ulong allocTracks,
121 int voiceOutCount, NoteOnCallback *callback);
122 void Update();
123 void Skip(OffsetType offsetType, int offset);
124 void Shutdown();
125
126 bool IsReleasePriorityFix() const { return mReleasePriorityFixFlag; }
127 f32 GetPanRange() const { return mPanRange; }
128 int GetVoiceOutCount() const { return mVoiceOutCount; }
129 ParserPlayerParam &GetParserPlayerParam() { return mParserParam; }
130 SeqTrack *GetPlayerTrack(int trackNo);
131 s16 volatile *GetVariablePtr(int varNo);
132
133 s16 GetLocalVariable(int varNo) const;
134 void SetLocalVariable(int varNo, s16 value);
135 static void SetGlobalVariable(int varNo, s16 value);
136
137 void SetTempoRatio(f32 tempo);
138 void SetReleasePriorityFix(bool fix);
139 void SetChannelPriority(int priority);
140 void SetSeqUserprocCallback(SeqUserprocCallback *callback, void *arg);
141 void SetPlayerTrack(int trackNo, SeqTrack *track);
142
143 f32 CalcTickPerMsec() const
144 {
145 return CalcTickPerMinute() / (60 * 1000);
146 }
147 f32 CalcTickPerMinute() const
148 {
149 return mParserParam.timebase * mParserParam.tempo * mTempoRatio;
150 }
151
152 ulong GetTickCounter() const {
153 return mTickCounter;
154 }
155
156 void SetSeqData(void const *seqBase, s32 seqOffset);
157
158 void CallSeqUserprocCallback(u16 procId, SeqTrack *track);
159 Channel *NoteOn(int bankNo, NoteOnInfo const &noteOnInfo);
160
161 void SetTrackMute(ulong trackFlags, SeqMute mute);
162 void SetTrackSilence(ulong trackFlags, bool silence, int fadeFrames);
163 void SetTrackVolume(ulong trackFlags, f32 volume);
164
165 static void InitSeqPlayer();
166
167 private:
168 void InitParam(int voiceOutCount, NoteOnCallback *callback);
169
170 void UpdateChannelParam();
171
172 void CloseTrack(int trackNo);
173 void FinishPlayer();
174
175 int ParseNextTick(bool doNoteOn); // meant to be bool?
176 void UpdateTick(int msec);
177 void SkipTick();
178
179 template <typename T>
180 void SetTrackParam(ulong trackFlags, void (SeqTrack::*pSetter)(T), T param) {
181 ut::AutoInterruptLock lock;
182
183 for (int i = 0; i < TRACK_NUM && trackFlags != 0;
184 trackFlags >>= 1, i++) {
185
186 if (trackFlags & 1) {
187 SeqTrack* pTrack = GetPlayerTrack(i);
188
189 if (pTrack != NULL) {
190 (pTrack->*pSetter)(param);
191 }
192 }
193 }
194 }
195
196 template <typename T, typename U>
197 void SetTrackParam(ulong trackFlags, void (SeqTrack::*pSetter)(T, U), T param, U param2) {
198 ut::AutoInterruptLock lock;
199
200 for (int i = 0; i < TRACK_NUM && trackFlags != 0;
201 trackFlags >>= 1, i++) {
202
203 if (trackFlags & 1) {
204 SeqTrack* pTrack = GetPlayerTrack(i);
205
206 if (pTrack != NULL) {
207 (pTrack->*pSetter)(param, param2);
208 }
209 }
210 }
211 }
212
213 // static members
214 public:
215 static int const MAX_SKIP_TICK_PER_FRAME = 768;
216 static int const DEFAULT_TEMPO = 120;
217 static int const DEFAULT_TIMEBASE = 48;
218 static int const VARIABLE_DEFAULT_VALUE = -1;
219 static int const TRACK_NUM_PER_PLAYER = 16;
220 static int const GLOBAL_VARIABLE_NUM = 16;
221 static int const PLAYER_VARIABLE_NUM = 16;
222
223 static const int TRACK_NUM = 16;
224
225 private:
226 static s16 mGlobalVariable[GLOBAL_VARIABLE_NUM];
227
228 // members
229 private:
230 /* base BasicPlayer */ // size 0x0a4, offset 0x000
231 /* base DisposeCallback */ // size 0x00c, offset 0x0a4
232 /* base SoundThread::PlayerCallback */ // size 0x00c, offset 0x0b0
233 bool mActiveFlag; // size 0x001, offset 0x0ec
234 bool mStartedFlag; // size 0x001, offset 0x0ed
235 bool mPauseFlag; // size 0x001, offset 0x0ee
236 bool mReleasePriorityFixFlag; // size 0x001, offset 0x0ef
237 f32 mPanRange; // size 0x004, offset 0x0f0
238 f32 mTempoRatio; // size 0x004, offset 0x0f4
239 f32 mTickFraction; // size 0x004, offset 0x0f8
240 ulong mSkipTickCounter; // size 0x004, offset 0x0fc
241 f32 mSkipTimeCounter; // size 0x004, offset 0x100
242 s32 mVoiceOutCount; // size 0x004, offset 0x104
243 ParserPlayerParam mParserParam; // size 0x00c, offset 0x108
244 SeqTrackAllocator *mSeqTrackAllocator; // size 0x004, offset 0x114
245 SeqUserprocCallback *mSeqUserprocCallback; // size 0x004, offset 0x118
246 void *mSeqUserprocCallbackArg; // size 0x004, offset 0x11c
247 SeqTrack *mTracks[TRACK_NUM_PER_PLAYER]; // size 0x040, offset 0x120
248 s16 volatile mLocalVariable[PLAYER_VARIABLE_NUM]; // size 0x020, offset 0x160
249 ulong mTickCounter; // size 0x004, offset 0x180
250 }; // size 0x184
251}}} // namespace nw4r::snd::detail
252
253#endif // NW4R_SND_SEQ_PLAYER_H