summaryrefslogtreecommitdiff
path: root/include/d/snd/d_snd_state_mgr.h
blob: ce3058ef6b21184a8c5feabf1650e36ec37c571e (plain)
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#ifndef D_SND_STATE_MGR_H
#define D_SND_STATE_MGR_H

#include "common.h"
#include "d/snd/d_snd_event.h"
#include "d/snd/d_snd_util.h"
#include "nw4r/snd/snd_FxReverbStdDpl2.h"
#include "nw4r/snd/snd_SoundHandle.h"
#include "sized_string.h"

SND_DISPOSER_FORWARD_DECL(dSndStateMgr_c);

// Previous Ghidra name: EnemySoundMgr
class dSndStateMgr_c {
public:
    SND_DISPOSER_MEMBERS(dSndStateMgr_c);

public:
    typedef void (*OnEventStartCallback)(s32 soundEventId, u32 flags);
    typedef void (*OnFlagsChangeCallback)(u32 newFlags, u32 oldFlags);

    enum StageFlags_e {
        STAGE_FIELD = 0x1,
        STAGE_DUNGEON = 0x2,
        STAGE_BOSS = 0x4,
        STAGE_SILENT_REALM = 0x8,

        STAGE_ROOM = 0x10, // only for sky

        STAGE_SKY = 0x20,
        STAGE_FOREST = 0x40,
        STAGE_MOUNTAIN = 0x80,
        STAGE_DESERT = 0x100,
        STAGE_SILENT_GROUNDS = 0x200,
    };

    enum Flag0x10_e {
        FLAG0x10_0x01 = 0x01,
        FLAG0x10_0x02 = 0x02,
        FLAG0x10_0x04 = 0x04,
        FLAG0x10_0x08 = 0x08,
        FLAG0x10_0x10 = 0x10,
    };

    // 0x94
    enum EventFlags_e {
        EVENT_IN_EVENT = 0x1,
        EVENT_DEMO = 0x2,
        EVENT_0x04 = 0x4,
        EVENT_MUTE_BGM_PARTIAL = 0x8,
        EVENT_MUTE_BGM_FULL = 0x10,
        EVENT_MUTE_STAGE_EFFECTS_PARTIAL = 0x20,
        EVENT_MUTE_STAGE_EFFECTS_FULL = 0x40,
        EVENT_MUTE_ENEMY_PARTIAL = 0x80,
        EVENT_MUTE_ENEMY_FULL = 0x100,
        EVENT_MUTE_OBJ_PARTIAL = 0x200,
        EVENT_MUTE_OBJ_FULL = 0x400,
        EVENT_0x800 = 0x800,
        EVENT_0x400000 = 0x400000,
    };

    dSndStateMgr_c();

    void setup(EGG::Heap *pHeap);
    void calc();
    void restoreEffects();

    static bool isInStage(const char *stageName);

    bool getField_0x064() const {
        return field_0x064;
    }

    s32 getField_0x14() const {
        return field_0x014;
    }

    s32 getStageId_0x040() const {
        return mStageId;
    }

    s32 getStageId_0x044() const {
        return field_0x044;
    }

    s32 getLayer() const {
        return mLayer;
    }

    u32 getFrameCounter() const {
        return mFrameCounter;
    }

    f32 getFxSend3D() const {
        return mFxSend3D;
    }

    void resetEventName() {
        mEventName = "EVENT_NONE";
    }

    const char *getCameraFmt() {
        return "%s_C%d_%d";
    }

    const char *getMsgWaitFmt() {
        return "%s_M%d_W%d_%d";
    }

    const char *getFrameFmt() {
        return "%s_%d";
    }

    bool checkFlag0x18(u32 mask);

    bool checkFlag0x258(u32 mask) {
        return field_0x258 & mask;
    }

    void resetFlag0x258() {
        field_0x258 = 0;
    }

    void onFlag0x258(u32 mask) {
        field_0x258 |= mask;
    }

    void offFlag0x258(u32 mask) {
        field_0x258 &= ~mask;
    }

    bool checkStageTypeFlag(u32 mask) {
        return mStageTypeFlags & mask;
    }

    bool checkFlag0x10(u32 mask) {
        return field_0x010 & mask;
    }

    void onFlag0x10(u32 mask) {
        field_0x010 |= mask;
    }

    void offFlag0x10(u32 mask) {
        field_0x010 &= ~mask;
    }

    bool checkEventFlag(u32 mask) {
        return mEventFlags & mask;
    }

    void onEventFlag(u32 mask) {
        mEventFlags |= mask;
    }

    void offEventFlag(u32 mask) {
        mEventFlags &= ~mask;
    }

    void setFlowEvent(u32 eventId);

    const char *getCurrentStageMusicDemoName() const;
    bool isInDemo() const {
        // implicit conversion required for regalloc in loadStageSound
        return getCurrentStageMusicDemoName();
    }

    void setStbEventName(const char *eventName);
    void setEvent(const char *eventName);
    // not sure, subtype is unused
    bool isActiveDemoMaybe(s32 subtype) const;
    bool isInEvent(const char *eventName);
    bool isInEvent();
    bool onSkipEvent() const;

    void onMsgStart(s32 idx);
    void onMsgEnd();

    void onMsgWaitStart();
    void onMsgWaitEnd();

    void onLinkDie();

    f32 getUserParamVolume(u32 userParam);

    void onStageOrLayerUpdate();
    void onStageLoad();
    void onRestartScene(s32 fadeFrames);
    void onGotoStage(s32 fadeFrames);
    void loadStageSound();
    void loadObjectSound();

    // TODO better names
    static const char *getStageName(s32 id);
    const char *getStageName4(s32 id);
    const char *getCurrentStageName4();

    static s32 getSndStageId(const char *stageName, s32 layer);
    static s32 getSndStageId3(const char *stageName, s32 layer);
    static s32 getSndStageId4(const char *stageName, s32 layer);

    static s32 getSndStageId2(s32 id);
    static s32 getSndStageId4(s32 id);

    static s32 getNextSndStageId(s32 id);
    static bool specialLayerVersionExists(const char *stageName, s32 layer);

    enum SoundIdLookup_e {
        LOOKUP_BGM,
        LOOKUP_BGM_MAIN,
        LOOKUP_SE_A,
    };

    u32 getSoundIdForStageAndLayer(SoundIdLookup_e lookup, const char *stageName, s32 layer, s32 stageId);

    void setFiltersIfUnderwater();
    void setBgmLpfAndFxSendIfUnderwater();
    void resetLpfAndFxSend();
    void resetBgmLpfAndFxSend();
    void setBgmAndStageEffectLpf();
    void setBgmLpf();
    void setBgmLpf(s32 fadeFrames);
    void resetBgmAndStageEffectLpf();
    void resetBgmLpf();

    void onCameraCut(s32 cutIdx);

    static void clearEventExecuteCallback();

private:
    void loadStageSound(bool force);

    void resetOverrides();
    void initializeEventCallbacks(const char *name);
    bool handleGlobalEvent(const char *name);
    bool handleStageEvent(const char *name);
    void handleDemoEvent(const char *name);

    void calcEvent();
    void calcRoomId();
    void setRoomId(s32 roomId);
    void calcTgSnd();
    void calcFilters();
    void calcFxSend3D();
    void setFxSend3DTarget();

    u32 getBgmLabelSoundId();
    void doLabelSuffix(const char *suffix);

    u32 convertSeLabelToSoundId(const char *label);
    u32 convertBgmLabelToSoundId(const char *label);
    u32 convertCmdLabelToSoundId(const char *label);

    void doBgm(const char *label);
    void doSe(const char *label);
    void doCmd(const char *label);

    u32 getSeCameraId();
    u32 getSeMsgWaitId();
    u32 getSeFrameCountId();

    u32 getBgmCameraId();
    u32 getBgmMsgWaitId();
    u32 getBgmFrameCountId();

    u32 getCmdCameraId();
    u32 getCmdMsgWaitId();
    u32 getCmdFrameCountId();

    void calcSe();
    bool calcBgm();
    void calcCmd();

    bool playSe(u32 soundId);
    bool playFanOrBgm(u32 soundId);
    bool playCmd(u32 soundId);

    void handleFan();
    void handleSe();
    void handleCmd();
    void handleSeLv();

    /** Called when no event is running anymore */
    void endEvent(bool skipped);
    /** Called when an event stops */
    bool finalizeEvent(bool skipped);

    void resetEventVars();

    // Callbacks start
    static void cbUnkNoop();

    // Callbacks end

    u32 getStageTypeFlags(const char *stageName) const;
    // ET, FS, or corresponding Sky Keep rooms
    static bool isVolcanicDungeon(u32 stageId);
    // Checks if the given stage + layer is the stage you're transported
    // to when viewing hint movies.
    static bool isSeekerStoneStage(const char *stageName, s32 layer);
    bool isSomeSkyloftRoom() const;

    void setCallbacksForStage();

    u32 getStageId(const char *name, s32 layer);
    static u32 getStageUnk2(u32 stageId);

    static SndEventCallback sEventExecuteCallback;

    /* 0x010 */ u32 field_0x010;
    /* 0x014 */ UNKWORD field_0x014;
    /* 0x018 */ UNKWORD field_0x018;
    /* 0x01C */ SizedString<32> mStageName;
    /* 0x03C */ s32 field_0x03C;
    /* 0x040 */ s32 mStageId;
    /* 0x044 */ UNKWORD field_0x044;
    /* 0x048 */ u8 _0x048[0x050 - 0x048];
    /* 0x050 */ s32 mPreviousStageId;
    /* 0x054 */ u32 mStageTypeFlags;
    /* 0x058 */ s32 mLayer;
    /* 0x05C */ s32 mRoomId;
    /* 0x060 */ s32 mCheckRoomIdCooldown;
    /* 0x064 */ bool field_0x064;
    /* 0x065 */ bool field_0x065;
    /* 0x066 */ bool mHasChangedTgSndAreaFlags;
    /* 0x067 */ bool mHasChangedTgSndAreaMgFlags;
    /* 0x068 */ u32 mSavedTgSndAreaFlags;
    /* 0x06C */ u32 mSavedTgSndAreaMgFlags;
    /* 0x070 */ void (*mpUnkCallback)();
    /* 0x074 */ UNKWORD field_0x074;
    /* 0x078 */ OnEventStartCallback mpOnEventStartCallback;
    /* 0x07C */ UNKWORD field_0x07C;
    /* 0x080 */ OnFlagsChangeCallback mpTgSndAreaFlagsChangeCallback;
    /* 0x084 */ OnFlagsChangeCallback mpTgSndAreaMgFlagsChangeCallback;
    /* 0x088 */ UNKWORD field_0x088;
    /* 0x08C */ s32 mSoundEventId;
    /* 0x090 */ s32 mCameraCutCounter;
    /* 0x094 */ u32 mEventFlags;
    /* 0x098 */ SizedString<64> mEventName;
    /* 0x0D8 */ SizedString<64> mPrevEventName;
    /* 0x118 */ const char *mpStbEventName;
    /* 0x11C */ u32 mFrameCounter;
    /* 0x120 */ u32 mCameraCutFrameCounter;
    /* 0x124 */ u32 mMsgFrameCounter;
    /* 0x128 */ u32 mSeLvSoundId;
    /* 0x12C */ SizedString<64> mSeName;
    /* 0x16C */ SizedString<64> mBgmName;
    /* 0x1AC */ SizedString<64> mFanName;
    /* 0x1EC */ SizedString<64> mCmdName;
    /* 0x22C */ UNKWORD field_0x22C;
    /* 0x230 */ nw4r::snd::SoundHandle mSeLvSoundHandle;
    /* 0x234 */ const SndEventDef *mpSoundEventDef;
    /* 0x238 */ u32 field_0x238;
    /* 0x23C */ u8 field_0x23C;
    /* 0x23D */ u8 field_0x23D;
    /* 0x240 */ UNKWORD field_0x240;
    /* 0x244 */ UNKWORD field_0x244;
    /* 0x248 */ UNKWORD field_0x248;
    /* 0x24C */ s32 mMsgCounter;
    /* 0x250 */ s32 mMsgWaitSelectCounter;
    /* 0x254 */ u8 field_0x254;
    /* 0x258 */ u32 field_0x258;
    /* 0x25C */ nw4r::snd::FxReverbStdDpl2 mFx;
    /* 0x48C */ UNKWORD field_0x48C;
    /* 0x490 */ f32 mFxSend3DDefault;
    /* 0x494 */ f32 mFxSend3DOverride;
    /* 0x498 */ f32 mFxSend3DNext;
    /* 0x49C */ f32 mFxSend3D;
    /* 0x4A0 */ f32 mFxSend3DTarget;
    /* 0x4A4 */ u32 mPrevStageGroup;
    /* 0x4A8 */ u8 field_0x4A8;
    /* 0x4A9 */ bool mNeedsGroupsReload;
};

#endif