summaryrefslogtreecommitdiff
path: root/include/d/snd/d_snd_source_enemy.h
blob: 4277b7c49390b3d7f6f2d453e6389245446f9ea6 (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
#ifndef D_SND_SOURCE_ENEMY_H
#define D_SND_SOURCE_ENEMY_H

#include "common.h"
#include "d/snd/d_snd_anim_sound.h"
#include "d/snd/d_snd_source.h"
#include "d/snd/d_snd_util.h"
#include "nw4r/ut/ut_list.h"

class dSndSourceEnemy_c : public dSoundSource_c {
public:
    dSndSourceEnemy_c(s32 sourceType, dAcBase_c *ac, const char *name, dSndSourceGroup_c *pOwnerGroup);
    virtual ~dSndSourceEnemy_c();

    /* 0x020 */ virtual void vt_0x020() override;
    /* 0x044 */ virtual void shutdown() override;

    /* 0x114 */ virtual void setBattleBgmRelated(UNKWORD arg) override {
        field_0x164 = arg;
    }
    /* 0x118 */ virtual UNKWORD checkBattleBgmRelated() override;

    /* 0x188 */ virtual void postSetup() override;
    /* 0x194 */ virtual u32 overrideStartSoundId(u32 soundId) override;
    /* 0x1A0 */ virtual u32 overrideHoldSoundId(u32 soundId, bool initial) override;

    /* 0x1CC */ virtual void postSetupSound(u32 playingId, u32 requestedId, dSndSeSound_c *seSound) override;

    /* 0x1E8 */ virtual u32 d_s_vt_0x1E8(u32 soundId) override {
        return specializeBgHitSoundId(soundId, mPolyAttr0, mPolyAttr1);
    }

protected:
    void unregisterEnemySource();

private:
    // Probably not a problem for weak function order since getName is emitted
    // earlier through an explicit call
    bool isName(const char *name) const {
        return streq(name, getName());
    }

    /* 0x15C */ nw4r::ut::Node mMgrEnemyLink;
    /* 0x164 */ UNKWORD field_0x164;
    /* 0x168 */ u8 field_0x168;
    /* 0x169 */ u8 field_0x169;
    /* 0x16A */ bool mIsRegisteredEnemy;
};

class dSndSourceEnemyAnimBase_c : public dSndSourceEnemy_c {
public:
    dSndSourceEnemyAnimBase_c(s32 sourceType, dAcBase_c *ac, const char *name, dSndSourceGroup_c *pOwnerGroup)
        : dSndSourceEnemy_c(sourceType, ac, name, pOwnerGroup), mAnimSound(this) {}

    /* 0x1A8 */ virtual StartResult
    SetupSound(nw4r::snd::SoundHandle *pHandle, u32 soundId, const StartInfo *pStartInfo, void *arg) override {
        return setupSoundCommon(pHandle, soundId, pStartInfo, arg);
    }

    /* 0x1D4 */ virtual dSndAnimSound_c *getAnimSound() override {
        return &mAnimSound;
    }

    /* 0x100 */ virtual bool hasAnimSound() override {
        return true;
    }
    /* 0x104 */ virtual void load(void *data, const char *name) override {
        mAnimSound.setData(data, name);
    }
    /* 0x108 */ virtual void setFrame(f32 frame) override {
        if (isInaudibleInternal()) {
            mAnimSound.resetFrame(frame);
        } else {
            mAnimSound.setFrame(frame);
        }
    }
    /* 0x10C */ virtual void setRate(f32 frame) override {
        mAnimSound.setRate(frame);
    }

protected:
    /* 0x16C */ dSndAnimSound_c mAnimSound;
};

class dSndSourceEnemyAnim_c : public dSndSourceEnemyAnimBase_c {
public:
    dSndSourceEnemyAnim_c(s32 sourceType, dAcBase_c *ac, const char *name, dSndSourceGroup_c *pOwnerGroup)
        : dSndSourceEnemyAnimBase_c(sourceType, ac, name, pOwnerGroup) {}

    /* 0x194 */ virtual u32 overrideStartSoundId(u32 soundId) override;
    /* 0x1A0 */ virtual u32 overrideHoldSoundId(u32 soundId, bool initial) override;

private:
};

class dSndSourceEnemyMultiBase_c : public dSndSourceEnemyAnimBase_c {
public:
    dSndSourceEnemyMultiBase_c(s32 sourceType, dAcBase_c *ac, const char *name, dSndSourceGroup_c *pOwnerGroup)
        : dSndSourceEnemyAnimBase_c(sourceType, ac, name, pOwnerGroup) {
            nw4r::ut::List_Init(&mSubSourceList, 0x14C);
            mAnimSound.setCallback(this);
        }

    /* 0x1A8 */ virtual StartResult
    SetupSound(nw4r::snd::SoundHandle *pHandle, u32 soundId, const StartInfo *pStartInfo, void *arg) override {
        bool bHoldFlag = *(bool*)arg;
        if (!bHoldFlag && (mAnimEventValue & 0xF) > 0) {
            dSoundSource_c *otherSource;
            s32 idx = (mAnimEventValue & 0xF) - 1;
            if (idx < 0) {
                otherSource = nullptr;
            } else if (idx >= nw4r::ut::List_GetSize(&mSubSourceList)) {
                otherSource = nullptr;
            } else {
                otherSource = getSubSourceFirst();
                while (idx > 0) {
                    otherSource = getSubSourceNext(otherSource);
                    idx--;
                }
            }
            if (otherSource != nullptr) {
                otherSource->startSound(soundId, pHandle);
                return onSetupError();
            }
        }

        return setupSoundCommon(pHandle, soundId, pStartInfo, arg);
    }

    /* 0x1D8 */ virtual void registerAdditionalSource(dSoundSource_c *other) override {
        if (other == this) {
            return;
        }

        if (other == nullptr) {
            return;
        }
        if (!hasSubSource(other)) {
            appendSubSource(other);
        }
    }
    /* 0x1DC */ virtual bool isMultiSource() const override {
        return true;
    }

private:
    // TODO: maybe created by the macro below
    bool hasSubSource(dSoundSource_c *other) {
        for (dSoundSource_c *it = getSubSourceFirst(); it != nullptr; it = getSubSourceNext(it)) {
            if (it == other) {
                return true;
            }
        }
        return false;
    }

    /* 0x210 */ LIST_MEMBER(dSoundSource_c, SubSource); // -> dSoundSource_c::mSubSourceLink
};

class dSndSourceEnemyMulti_c : public dSndSourceEnemyMultiBase_c {
public:
    dSndSourceEnemyMulti_c(s32 sourceType, dAcBase_c *ac, const char *name, dSndSourceGroup_c *pOwnerGroup)
        : dSndSourceEnemyMultiBase_c(sourceType, ac, name, pOwnerGroup) {}

    /* 0x18C */ virtual void postCalc() override;

private:

};

#endif