Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions include/constants/sjis_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,21 @@

// [Translation: 2D resource heap (d2d::ResAccMultLoader_c::create)]
#define D2D_HEAP_NAME "�Q�c���\�[�X�p�q�[�v(d2d::ResAccMultLoader_c::create)"

// [Translation: General-purpose file reading heap (mHeap::archiveHeap)]
#define ARCHIVE_HEAP_NAME "�ėp�t�@�C���ǂݍ��ݗp�q�[�v(mHeap::archiveHeap)"

// [Translation: DVD read command heap (mHeap::commandHeap)]
#define COMMAND_HEAP_NAME "DVD�ǂݍ��݃R�}���h�p�q�[�v(mHeap::commandHeap)"

// [Translation: Dynamic linking heap (mHeap::dylinkHeap)]
#define DYLINK_HEAP_NAME "�_�C�i�~�b�N�����N�p�q�[�v(mHeap::dylinkHeap)"

// [Translation: General-purpose heap for games 1(mHeap::gameHeaps[1])]
#define GAME_HEAP_1_NAME "�Q�[���p�ėp�q�[�v1(mHeap::gameHeaps[1])"

// [Translation: General-purpose heap for games 2(mHeap::gameHeaps[2])]
#define GAME_HEAP_2_NAME "�Q�[���p�ėp�q�[�v2(mHeap::gameHeaps[2])"

// [Translation: Assert Heap (mHeap::assertHeap)]
#define ASSERT_HEAP_NAME "�A�T�[�g�q�[�v(mHeap::assertHeap)"
6 changes: 3 additions & 3 deletions include/game/mLib/m_allocator_dummy_heap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ class mAllocatorDummyHeap_c : public EGG::Heap {
virtual void free(void *ptr);

virtual void destroy();
virtual void *resizeForMBlock(void *ptr, size_t newSize);
virtual size_t resizeForMBlock(void *ptr, size_t newSize);

virtual u32 getTotalFreeSize();
virtual u32 getAllocatableSize(long alignment);
virtual bool adjust();
virtual size_t getAllocatableSize(long alignment);
virtual size_t adjust();

static void *AllocatorAllocForDummyHeap(MEMAllocator *, size_t);
static void AllocatorFreeForDummyHeap(MEMAllocator *, void *);
Expand Down
178 changes: 164 additions & 14 deletions include/game/mLib/m_heap.hpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,175 @@
#pragma once
#include <types.h>
#include <lib/egg/core/eggAssertHeap.h>
#include <lib/egg/core/eggFrmHeap.h>
#include <lib/egg/core/eggExpHeap.h>
#include <nw4r/ut.h>
#include <lib/egg/core/eggUnitHeap.h>

/**
* @brief Provides high-level heap management utilities built on top of the @ref EGG heap system.
* @details The mHeap namespace wraps and extends the functionality of the EGG heap framework, providing
* helper functions for creating and managing different heap types used by the game.
*
* It supports:
* - @ref EGG::ExpHeap "Expandable heaps".
* - @ref EGG::FrmHeap "Frame heaps".
* - @ref EGG::UnitHeap "Unit heaps".
*
* It also manages various game-specific heaps:
* - The @ref g_gameHeaps "game heaps", used for most game-related content. One game heap is created in MEM1 and one in MEM2.
* - The @ref g_archiveHeap "archive heap", used for loading resource files.
* - The @ref g_commandHeap "command heap", used for @ref mDvd_command_c "DVD commands".
* - The @ref g_dylinkHeap "dylink heap", used for loading and linking the game's REL files.
* - The @ref g_assertHeap "assert heap".
*/
namespace mHeap {

/// @brief Bit flags controlling heap allocation behavior.
/// These flags are translated into internal MEM heap flags via GetOptFlag().
enum AllocOptBit_t {
OPT_NONE = 0,
OPT_THREAD_SAFE = BIT_FLAG(2)
OPT_NONE = 0, ///< No special allocation options.
OPT_CLEAR_ALLOC = BIT_FLAG(0), ///< Memory blocks are cleared upon allocation.
OPT_DEBUG_FILL = BIT_FLAG(1), ///< Memory blocks are filled with different values depending on the heap status.
OPT_THREAD_SAFE = BIT_FLAG(2) ///< Enables thread-safe memory block de/allocation.
};

void restoreCurrentHeap();
EGG::Heap *setCurrentHeap(EGG::Heap *);
size_t frmHeapCost(size_t, size_t);
void destroyFrmHeap(EGG::FrmHeap *);
unsigned long adjustFrmHeap(EGG::FrmHeap *);
/// @brief The identifiers for the predefined game heaps.
/// @unofficial
enum GAME_HEAP_e {
GAME_HEAP_DEFAULT, ///< The default game heap (alias of MEM1 or MEM2).
GAME_HEAP_MEM1, ///< The game heap allocated in MEM1.
GAME_HEAP_MEM2, ///< The game heap allocated in MEM2.
GAME_HEAP_COUNT, ///< The total number of game heaps.
};

/// @brief Converts the allocation option bits to internal MEM heap flags.
/// @param opt The allocation option bits.
/// @return The corresponding MEM heap flag mask.
u16 GetOptFlag(AllocOptBit_t opt);

/// @brief Sets the specified heap as the current heap.
/// @param heap The heap to become current.
/// @return The previously current heap.
EGG::Heap *setCurrentHeap(EGG::Heap *heap);

/// @brief Saves the currently active heap.
/// The saved heap can later be restored using restoreCurrentHeap().
void saveCurrentHeap();
void restoreCurrentHeap(); ///< Restores the previously saved heap as current.

/// @brief Calculates the total required size for an @ref EGG::ExpHeap "expandable heap", including internal overhead.
/// @param size The requested usable size.
/// @param align The lignment requirement.
/// @return The total allocation size required.
size_t expHeapCost(size_t size, ulong align);

/// @brief Calculates the total required size for a @ref EGG::FrmHeap "frame heap", including internal overhead.
/// @param size The requested usable size.
/// @param align The lignment requirement.
/// @return The total allocation size required.
size_t frmHeapCost(size_t size, ulong align);

/**
* @brief Calculates the total required size for an @ref EGG::UnitHeap "unit heap", including internal overhead.
* @param size The requested usable size.
* @param count The number of units.
* @param align The lignment requirement.
* @return The total allocation size required.
*/
size_t untHeapCost(size_t size, ulong count, ulong align);

/// @brief Destroys a frame heap.
/// @param heap The frame heap to destroy, or @p nullptr .
void destroyFrmHeap(EGG::FrmHeap *heap);

/// @brief Adjusts a frame heap to release unused memory.
/// @param heap The frame heap to adjust, or @p nullptr .
/// @return The total available space in the heap, or @p 0 if the adjust operation failed.
size_t adjustFrmHeap(EGG::FrmHeap *heap);

/**
* @brief Creates an expandable heap.
* @param size The size of the heap, or -1 to use all space available.
* @param parent The parent heap.
* @param name The heap name, or @p nullptr .
* @param align The heap alignment (minimum 0x20).
* @param opt The allocation options.
* @return A pointer to the created heap, or @p nullptr on failure.
*/
EGG::ExpHeap *createExpHeap(size_t size, EGG::Heap *parent, const char *name, ulong align, AllocOptBit_t opt);

/**
* @brief Creates a frame heap and sets it as current.
* @param size The size of the heap, or -1 to use all space available.
* @param parent The parent heap.
* @param name The heap name, or @p nullptr .
* @param align The heap alignment (minimum 0x20).
* @param opt The allocation options.
* @return A pointer to the created heap, or @p nullptr on failure.
*/
EGG::FrmHeap *createFrmHeapToCurrent(size_t size, EGG::Heap *parent, const char *name, ulong align, AllocOptBit_t opt);

/**
* @brief Creates a frame heap.
* @param size The size of the heap, or -1 to use all space available.
* @param parent The parent heap.
* @param name The heap name, or @p nullptr .
* @param align The heap alignment (minimum 0x20).
* @param opt The allocation options.
* @return A pointer to the created heap, or @p nullptr on failure.
*/
EGG::FrmHeap *createFrmHeap(size_t size, EGG::Heap *parent, const char *name, ulong align, AllocOptBit_t opt);

/**
* @brief Creates a unit heap.
* @param size The size of the heap, or -1 to use all space available.
* @param count The number of units.
* @param parent The parent heap.
* @param name The heap name, or @p nullptr .
* @param align The heap alignment (minimum 0x20).
* @param opt The allocation options.
* @return A pointer to the created heap, or @p nullptr on failure.
*/
EGG::UnitHeap *createUntHeap(size_t size, ulong count, EGG::Heap *parent, const char *name, ulong align, AllocOptBit_t opt);

inline bool isValidGameHeapId(u32 idx) {
return GAME_HEAP_MEM1 <= idx && idx <= GAME_HEAP_MEM2;
}

/**
* @brief Creates a generic expandable heap, with @ref MEM_EXP_HEAP_ALLOC_FAST "fast allocation mode" and @ref OPT_THREAD_SAFE "thread-safe de/allocation".
* @param size The heap size.
* @param parent The parent heap.
* @param name The heap name, or @p nullptr .
* @return A pointer to the created heap, or @p nullptr on failure.
*/
EGG::Heap *createHeap(size_t size, EGG::Heap *parent, const char *name);

/**
* @brief Creates a game heap.
* @param idx The game heap index.
* @param size The heap size.
* @param parent The parent heap.
* @return A pointer to the created heap, or @p nullptr if invalid index.
*/
EGG::Heap *createGameHeap(int idx, size_t size, EGG::Heap* parent);
EGG::Heap *createGameHeap1(size_t size, EGG::Heap *parent); ///< Creates the MEM1 game heap. See createGameHeap().
EGG::Heap *createGameHeap2(size_t size, EGG::Heap *parent); ///< Creates the MEM2 game heap. See createGameHeap().
EGG::Heap *createArchiveHeap(size_t size, EGG::Heap *parent); ///< Creates the archive heap. See createHeap().
EGG::Heap *createCommandHeap(size_t size, EGG::Heap *parent); ///< Creates the DVD command heap. See createHeap().
EGG::Heap *createDylinkHeap(size_t size, EGG::Heap *parent); ///< Creates the REL linking heap. See createHeap().

/// @brief Creates the assert heap.
/// @details The size is determined automatically using EGG::AssertHeap::getMinSizeForCreate().
EGG::Heap *createAssertHeap(EGG::Heap *parent);

extern u8 g_DefaultGameHeapId; ///< The default game heap to be used if one isn't specified.
extern const char * const s_GameHeapNames[GAME_HEAP_COUNT]; ///< The game heap names.

EGG::ExpHeap *createExpHeap(size_t, EGG::Heap *, const char *, size_t, mHeap::AllocOptBit_t);
EGG::FrmHeap *createFrmHeapToCurrent(unsigned long size, EGG::Heap *parent, const char *name, ulong align, mHeap::AllocOptBit_t opt);
EGG::FrmHeap *createFrmHeap(unsigned long size, EGG::Heap *parent, const char *name, ulong align, mHeap::AllocOptBit_t opt);
extern EGG::Heap *s_SavedCurrentHeap; ///< The saved current heap.
extern EGG::Heap *g_gameHeaps[GAME_HEAP_COUNT]; ///< The game heaps.
extern EGG::Heap *g_archiveHeap; ///< The archive resource heap.
extern EGG::Heap *g_commandHeap; ///< The DVD command heap.
extern EGG::Heap *g_dylinkHeap; ///< The REL linking heap.
extern EGG::Heap *g_assertHeap; ///< The assert heap.

extern EGG::Heap *g_gameHeaps[3];
};
}; // namespace mHeap
12 changes: 12 additions & 0 deletions include/lib/egg/core/eggAssertHeap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once
#include <lib/egg/core/eggHeap.h>

namespace EGG {

class AssertHeap : public Heap {
public:
static AssertHeap *create(size_t size, Heap *parent);
static size_t getMinSizeForCreate();
};

} // namespace EGG
17 changes: 10 additions & 7 deletions include/lib/egg/core/eggExpHeap.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#pragma once

#include <lib/egg/core/eggHeap.h>

namespace EGG {

// [TODO: extend this]
class ExpHeap : public Heap {
public:
void setAllocMode(u16 mode);

namespace EGG {
class ExpHeap : public Heap {
public:
static EGG::ExpHeap *create(size_t, EGG::Heap *, u16);
};
}
static EGG::ExpHeap *create(void *buffer, size_t size, u16 flags);
static EGG::ExpHeap *create(size_t, EGG::Heap *, u16);
};

} // namespace EGG
16 changes: 9 additions & 7 deletions include/lib/egg/core/eggFrmHeap.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#pragma once

#include <lib/egg/core/eggHeap.h>
#include <revolution/MEM.h>

namespace EGG {

// [TODO: extend this]
class FrmHeap : public Heap {
public:
void free(long);

namespace EGG {
class FrmHeap : public Heap {
public:
void free(long);
};
}
static FrmHeap *create(void *buffer, size_t size, u16 flags);
};

} // namespace EGG
7 changes: 7 additions & 0 deletions include/lib/egg/core/eggHeap.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,18 @@ class Heap : Disposer {
virtual void *alloc(size_t, long) = 0;
virtual void free(void *) = 0;
virtual void destroy() = 0;
virtual size_t resizeForMBlock(void* block, size_t size) = 0;
virtual u32 getTotalFreeSize();
virtual size_t getAllocatableSize(long align) = 0;
virtual size_t adjust() = 0;

void dump();

static void *alloc(size_t, int, EGG::Heap *);
static void free(void *, EGG::Heap *);

static Heap *findContainHeap(const void *);
Heap *becomeCurrentHeap();

void appendDisposer(Disposer *disposer) { nw4r::ut::List_Append(&mChildren, disposer); }
void removeDisposer(Disposer *disposer) { nw4r::ut::List_Remove(&mChildren, disposer); }
Expand Down
13 changes: 13 additions & 0 deletions include/lib/egg/core/eggUnitHeap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once
#include <revolution/MEM/mem_unitHeap.h>
#include <lib/egg/core/eggHeap.h>

namespace EGG {

class UnitHeap : public Heap, MEMiUntHeapHead {
public:
static UnitHeap* create(void* block, size_t size, size_t unitSize, long align, u16 flag);
static size_t calcHeapSize(size_t unitSize, ulong count, long align);
};

} // namespace EGG
2 changes: 1 addition & 1 deletion include/lib/nw4r/ut/ut_algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ inline int ComparePtr(const void* pPtr1, const void* pPtr2) {
*
******************************************************************************/
template <typename T> inline T RoundUp(T t, unsigned int alignment) {
return (alignment + t - 1) & ~(alignment - 1);
return (t + (alignment - 1)) & ~(alignment - 1);
}

template <typename T> inline void* RoundUp(T* pPtr, unsigned int alignment) {
Expand Down
5 changes: 2 additions & 3 deletions include/lib/revolution/MEM/mem_expHeap.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
extern "C" {
#endif

#define MEM_EXP_HEAP_MIN_SIZE \
(sizeof(MEMiHeapHead) + sizeof(MEMiExpHeapHead) + \
sizeof(MEMiExpHeapMBlock) + 4)
#define MEM_EXP_HEAP_HEAD_SIZE (sizeof(MEMiHeapHead) + sizeof(MEMiExpHeapHead))
#define MEM_EXP_HEAP_MIN_SIZE (MEM_EXP_HEAP_HEAD_SIZE + sizeof(MEMiExpHeapMBlock) + 4)

// Forward declarations
typedef struct MEMiHeapHead MEMiHeapHead;
Expand Down
3 changes: 2 additions & 1 deletion include/lib/revolution/MEM/mem_frameHeap.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
extern "C" {
#endif

#define MEM_FRM_HEAP_MIN_SIZE (sizeof(MEMiHeapHead) + sizeof(MEMiFrmHeapHead))
#define MEM_FRM_HEAP_HEAD_SIZE (sizeof(MEMiHeapHead) + sizeof(MEMiFrmHeapHead))
#define MEM_FRM_HEAP_MIN_SIZE MEM_FRM_HEAP_HEAD_SIZE

// Forward declarations
typedef struct MEMiHeapHead MEMiHeapHead;
Expand Down
20 changes: 20 additions & 0 deletions include/lib/revolution/MEM/mem_unitHeap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once
#include <types.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct MEMiUntHeapMBlockHead MEMiUntHeapMBlockHead;
struct MEMiUntHeapMBlockHead {
MEMiUntHeapMBlockHead* succ;
};

typedef struct MEMiUntHeapHead {
MEMiUntHeapMBlockHead* free_list;
u32 unit_size;
} MEMiUntHeapHead;

#ifdef __cplusplus
}
#endif
11 changes: 11 additions & 0 deletions slices/wiimj2d.json
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,17 @@
".data": "0x2b780-0x2b7a8"
}
},
{
"source": "dol/mLib/m_heap.cpp",
"memoryRanges": {
".text": "0x167e70-0x168560",
".rodata": "0x7d60-0x7d70",
".data": "0x2b7a8-0x2b8c0",
".bss": "0x265c8-0x265d8",
".sdata": "0x1e08-0x1e10",
".sbss": "0x888-0x8a0"
}
},
{
"source": "dol/mLib/m_mtx.cpp",
"memoryRanges": {
Expand Down
Loading