summaryrefslogtreecommitdiff
path: root/libs/revolution/src/homebuttonLib/nw4hbm/snd/FrameHeap.h
blob: 1184a3284e0568818404e686cfbb4c658486c9ce (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
#ifndef NW4HBM_SND_FRAME_HEAP_H
#define NW4HBM_SND_FRAME_HEAP_H

#include <revolution/types.h>

#include "../ut/LinkList.h"

#include <revolution/mem.h>

namespace nw4hbm {
    namespace snd {
        namespace detail {
            class FrameHeap {
            public:
                typedef void (*FreeCallback)(void* buffer, u32 size, void* callbackArg);

                FrameHeap();
                ~FrameHeap();

                bool Create(void* base, u32 size);
                void Destroy();
                void Clear();
                void* Alloc(u32 size, FreeCallback callback, void* callbackArg);

                int SaveState();
                void LoadState(int id);

                int GetCurrentLevel() const;
                u32 GetFreeSize() const;

                bool IsValid() const { return mHandle != NULL; }

            private:
                typedef struct Block {
                    /* 0x00 */ ut::LinkListNode mLink;
                    /* 0x08 */ u32 mSize;
                    /* 0x0C */ FreeCallback mCallback;
                    /* 0x10 */ void* mCallbackArg;

                    Block(u32 size, FreeCallback callback, void* callbackArg)
                        : mSize(size), mCallback(callback), mCallbackArg(callbackArg) {}

                    ~Block() {
                        if (mCallback != NULL) {
                            mCallback(GetBufferAddr(), mSize, mCallbackArg);
                        }
                    }

                    void* GetBufferAddr() { return ut::AddOffsetToPtr(this, BLOCK_BUFFER_SIZE); }
                } Block;
                typedef ut::LinkList<Block, offsetof(Block, mLink)> BlockList;

                typedef struct Section {
                    /* 0x00 */ ut::LinkListNode mLink;
                    /* 0x08 */ BlockList mBlockList;

                    ~Section();
                    void AppendBlock(Block* block) { mBlockList.PushBack(block); }
                } Section;
                typedef ut::LinkList<Section, offsetof(Section, mLink)> SectionList;

                bool NewSection();
                void ClearSection();

                static const int BLOCK_BUFFER_SIZE = OSRoundUp32B(sizeof(Block));
                static const int HEAP_ALIGN = 32;

                /* 0x00 */ MEMHeapHandle mHandle;
                /* 0x04 */ SectionList mSectionList;
            };
        }  // namespace detail
    }  // namespace snd
}  // namespace nw4hbm

#endif