Nearly match CARAMManager

Former-commit-id: e70cf7d4b3c97c15deaac6e0af4051476d301f39
This commit is contained in:
Phillip Stephens 2023-10-12 04:10:49 -07:00
parent 5e47494749
commit 9843b74547
6 changed files with 272 additions and 27 deletions

View File

@ -14513,7 +14513,7 @@ FindFreeBlocks__12CARAMManagerFUiUiUi = .text:0x80344B98; // type:function size:
Alloc__12CARAMManagerFUi = .text:0x80344C28; // type:function size:0x9C scope:global
Shutdown__12CARAMManagerFv = .text:0x80344CC4; // type:function size:0x50 scope:global
Initialize__12CARAMManagerFUi = .text:0x80344D14; // type:function size:0x170 scope:global
fn_80344E84 = .text:0x80344E84; // type:function size:0x7C
do_erase__Q24rstl67list<PQ212CARAMManager15SAramDMARequest,Q24rstl17rmemory_allocator>FPQ34rstl67list<PQ212CARAMManager15SAramDMARequest,Q24rstl17rmemory_allocator>4node = .text:0x80344E84; // type:function size:0x7C
__sinit_CARAMManager_cpp = .text:0x80344F00; // type:function size:0x54 scope:local
__dt__Q24rstl67list<PQ212CARAMManager15SAramDMARequest,Q24rstl17rmemory_allocator>Fv = .text:0x80344F54; // type:function size:0x78 scope:global
PointInFrustumPlanes__14CFrustumPlanesCFRC9CVector3f = .text:0x80344FCC; // type:function size:0x60 scope:global
@ -17857,7 +17857,7 @@ cplext = .rodata:0x803D7CFC; // type:object size:0x7C scope:local
cpdist = .rodata:0x803D7D78; // type:object size:0x78 scope:local
cpdext = .rodata:0x803D7DF0; // type:object size:0x78 scope:local
@stringBase0 = .rodata:0x803D7E68; // type:object size:0xE5 scope:local data:string_table
lbl_803D7F50 = .rodata:0x803D7F50; // type:object size:0x8
@stringBase0 = .rodata:0x803D7F50; // type:object size:0x8 data:string_table
lbl_803D7F58 = .rodata:0x803D7F58; // type:object size:0xF0
lbl_803D8048 = .rodata:0x803D8048; // type:object size:0x30 data:4byte
lbl_803D8078 = .rodata:0x803D8078; // type:object size:0x30
@ -19239,7 +19239,7 @@ lbl_804BFF00 = .bss:0x804BFF00; // type:object size:0x10
lbl_804BFF10 = .bss:0x804BFF10; // type:object size:0xC
lbl_804BFF1C = .bss:0x804BFF1C; // type:object size:0x14
lbl_804BFF30 = .bss:0x804BFF30; // type:object size:0x10
lbl_804BFF40 = .bss:0x804BFF40; // type:object size:0x10
@52 = .bss:0x804BFF40; // type:object size:0x10
sPlayerPosition = .bss:0x804BFF50; // type:object size:0xC scope:local data:float
sTextureProjectionTransform = .bss:0x804BFF5C; // type:object size:0x34 scope:local data:float
lbl_804BFF90 = .bss:0x804BFF90; // type:object size:0x10
@ -21307,7 +21307,7 @@ lbl_805A8911 = .sdata:0x805A8911; // type:object size:0x1 data:byte
lbl_805A8912 = .sdata:0x805A8912; // type:object size:0x6 data:byte
fixed_bl = .sdata:0x805A8918; // type:object size:0x4 scope:local data:4byte
fixed_bd = .sdata:0x805A891C; // type:object size:0x4 scope:local data:4byte
mPreInitializeAlloc__12CARAMManager = .sdata:0x805A8920; // type:object size:0x8 scope:global data:4byte
mPreInitializeAlloc__12CARAMManager = .sdata:0x805A8920; // type:object size:0x4 scope:global data:4byte
lbl_805A8928 = .sdata:0x805A8928; // type:object size:0x4 data:4byte
lbl_805A892C = .sdata:0x805A892C; // type:object size:0x4 data:float
lbl_805A8930 = .sdata:0x805A8930; // type:object size:0x4 data:float
@ -21992,7 +21992,7 @@ mChunkSize__12CARAMManager = .sbss:0x805A9528; // type:object size:0x4 scope:glo
mNumChunks__12CARAMManager = .sbss:0x805A952C; // type:object size:0x4 scope:global data:4byte
mpBookKeepingMemory__12CARAMManager = .sbss:0x805A9530; // type:object size:0x4 scope:global data:4byte
mDMAUniqueID__12CARAMManager = .sbss:0x805A9534; // type:object size:0x4 scope:global data:4byte
mChunksAllocated__12CARAMManager = .sbss:0x805A9538; // type:object size:0x8 scope:global data:4byte
mChunksAllocated__12CARAMManager = .sbss:0x805A9538; // type:object size:0x4 scope:global data:4byte
sMaterialCachedState = .sbss:0x805A9540; // type:object size:0x4 scope:global data:4byte
sLastModelCached__13CCubeMaterial = .sbss:0x805A9544; // type:object size:0x4 scope:global data:4byte
sRenderingModel__13CCubeMaterial = .sbss:0x805A9548; // type:object size:0x4 scope:global data:4byte

View File

@ -14528,7 +14528,7 @@ FindFreeBlocks__12CARAMManagerFUiUiUi = .text:0x80344C78; // type:function size:
Alloc__12CARAMManagerFUi = .text:0x80344D08; // type:function size:0x9C scope:global
Shutdown__12CARAMManagerFv = .text:0x80344DA4; // type:function size:0x50 scope:global
Initialize__12CARAMManagerFUi = .text:0x80344DF4; // type:function size:0x170 scope:global
fn_80344E84__Fv = .text:0x80344F64; // type:function size:0x7C scope:global
do_erase__Q24rstl67list<PQ212CARAMManager15SAramDMARequest,Q24rstl17rmemory_allocator>FPQ34rstl67list<PQ212CARAMManager15SAramDMARequest,Q24rstl17rmemory_allocator>4node__Fv = .text:0x80344F64; // type:function size:0x7C scope:global
__sinit_CARAMManager_cpp = .text:0x80344FE0; // type:function size:0x54 scope:global
__dt__Q24rstl67list<PQ212CARAMManager15SAramDMARequest,Q24rstl17rmemory_allocator>Fv = .text:0x80345034; // type:function size:0x78 scope:global
PointInFrustumPlanes__14CFrustumPlanesCFRC9CVector3f = .text:0x803450AC; // type:function size:0x60 scope:global
@ -17911,7 +17911,7 @@ cplext = .rodata:0x803D7EDC; // type:object size:0x7C scope:local
cpdist = .rodata:0x803D7F58; // type:object size:0x78 scope:local
cpdext = .rodata:0x803D7FD0; // type:object size:0x78 scope:local
@stringBase0 = .rodata:0x803D8048; // type:object size:0xE5 scope:local data:string_table
lbl_803D7F50 = .rodata:0x803D8130; // type:object size:0x8 scope:global
@stringBase0 = .rodata:0x803D8130; // type:object size:0x8 scope:global
lbl_803D7F58 = .rodata:0x803D8138; // type:object size:0xF0 scope:global
lbl_803D8048 = .rodata:0x803D8228; // type:object size:0x30 scope:global data:4byte
lbl_803D8078 = .rodata:0x803D8258; // type:object size:0x30 scope:global
@ -19268,7 +19268,7 @@ lbl_804BFF00 = .bss:0x804C00E0; // type:object size:0x10 scope:local
lbl_804BFF10 = .bss:0x804C00F0; // type:object size:0xC scope:local
lbl_804BFF1C = .bss:0x804C00FC; // type:object size:0x14 scope:local
lbl_804BFF30 = .bss:0x804C0110; // type:object size:0x10 scope:local
lbl_804BFF40 = .bss:0x804C0120; // type:object size:0x10 scope:local
@52 = .bss:0x804C0120; // type:object size:0x10 scope:local
sPlayerPosition = .bss:0x804C0130; // type:object size:0xC scope:local data:float
sTextureProjectionTransform = .bss:0x804C013C; // type:object size:0x34 scope:local data:float
lbl_804BFF90 = .bss:0x804C0170; // type:object size:0x10 scope:local

View File

@ -137,7 +137,8 @@ config.ldflags = [
"-fp hardware",
"-nodefaults",
]
config.progress_all = False
config.progress_all = True
config.build_rels = False
# Base flags, common to most GC/Wii games.
# Generally leave untouched, with overrides added below.

View File

@ -3,6 +3,10 @@
#include "types.h"
#include <dolphin/arq.h>
#include <rstl/list.hpp>
class CARAMManager {
public:
enum EDMAPriority {
@ -15,22 +19,49 @@ public:
kDMAPrio_Six,
};
static bool Initialize(uint);
static void Shutdown();
static void CollectGarbage();
static void PreInitializeAlloc(uint size) { mPreInitializeAlloc += size; }
static void Initialize(uint);
static void* Alloc(uint len);
static uint FindFreeBlocks(uint, uint, uint);
static bool Free(const void* ptr);
static uint DMAToARAM(void*, void*, uint, EDMAPriority);
static int DMAToMRAM(void*, void*, uint, EDMAPriority);
static bool IsDMACompleted(uint handle);
static void WaitForDMACompletion(uint handle);
static void WaitForAllDMAsToComplete();
static bool CancelDMA(uint);
static void AramManagerDMACallback(u32 result);
static void RefreshActiveDMAList();
static void CollectGarbage();
static void PreInitializeAlloc(uint size) { mPreInitializeAlloc += size; }
static const void* GetInvalidAlloc() { return (const void*)kInvalidAlloc; }
static const uint GetInvalidDMAHandle() { return kInvalidHandle; }
static bool CancelDMA(uint);
static void WaitForDMACompletion(uint);
static bool IsDMACompleted(uint handle);
static void* Alloc(uint len);
static void Free(const void* ptr);
static int DMAToARAM(void*, void*, uint, EDMAPriority);
static int DMAToMRAM(void*, void*, uint, EDMAPriority);
static uint GetAndIncrementUniqueID() {
mDMAUniqueID++;
if (mDMAUniqueID == GetInvalidDMAHandle()) {
mDMAUniqueID++;
}
return mDMAUniqueID;
}
private:
struct SAramDMARequest {
ARQRequest mRequest;
uint mUniqueID;
bool mComplete;
};
static bool mbInitialized;
static u32 mpARAMStart;
static uint mChunkSize;
static uint mNumChunks;
static uint* mpBookKeepingMemory;
static uint mPreInitializeAlloc;
static uint mDMAUniqueID;
static uint mChunksAllocated;
static rstl::list< SAramDMARequest* > mActiveDMAs;
static const int kInvalidAlloc;
static const int kInvalidHandle;
};

209
src/Kyoto/CARAMManager.cpp Normal file
View File

@ -0,0 +1,209 @@
#include "Kyoto/CARAMManager.hpp"
#include <dolphin/ar.h>
#include <dolphin/os.h>
bool CARAMManager::mbInitialized = false;
u32 CARAMManager::mpARAMStart = 0;
uint CARAMManager::mChunkSize = 0;
uint CARAMManager::mNumChunks = 0;
uint* CARAMManager::mpBookKeepingMemory;
uint CARAMManager::mPreInitializeAlloc = 16 * 1024;
uint CARAMManager::mDMAUniqueID;
uint CARAMManager::mChunksAllocated;
const int CARAMManager::kInvalidAlloc = -1;
const int CARAMManager::kInvalidHandle = -1;
rstl::list< CARAMManager::SAramDMARequest* > CARAMManager::mActiveDMAs;
bool CARAMManager::Initialize(uint chunkSize) {
uint numChunks = (ARGetSize() - mPreInitializeAlloc) / chunkSize;
mChunkSize = chunkSize;
mNumChunks = numChunks;
mpARAMStart = ARAlloc(chunkSize * numChunks);
mpBookKeepingMemory = (uint*)CMemory::Alloc(numChunks * 4, IAllocator::kHI_None,
IAllocator::kSC_Unk1, IAllocator::kTP_Heap,
CCallStack(-1, "??(??)", CCallStack::kUnknownType));
CMemory::OffsetFakeStatics(mNumChunks * 4);
for (uint i = 0; i < numChunks; ++i) {
mpBookKeepingMemory[i] = 0;
}
mDMAUniqueID = 0;
mbInitialized = true;
return true;
}
void CARAMManager::Shutdown() {
WaitForAllDMAsToComplete();
CMemory::Free(mpBookKeepingMemory);
u32 unk = 0;
CMemory::OffsetFakeStatics(-mNumChunks * 4);
ARFree(&unk);
mbInitialized = false;
}
void* CARAMManager::Alloc(const uint len) {
uint chunkCount = (mChunkSize - 1 + len) / mChunkSize;
uint block = FindFreeBlocks(0, mNumChunks, chunkCount);
if (block == -1) {
return (void*)-1;
}
mChunksAllocated += chunkCount;
uint blockOffset = mpARAMStart + block * mChunkSize;
mpBookKeepingMemory[block] = chunkCount;
while (--chunkCount != 0) {
++block;
mpBookKeepingMemory[block] = -1;
}
return (void*)blockOffset;
}
uint CARAMManager::FindFreeBlocks(uint arg0, uint arg1, uint arg2) {
while (arg0 < arg1) {
if (mpBookKeepingMemory[arg0] == 0) {
if (arg2 == 1) {
return arg0;
}
++arg0;
int r8 = 1;
while (arg0 < arg1) {
uint tmp = mpBookKeepingMemory[arg0];
if (tmp != 0) {
arg0 += tmp;
break;
}
r8++;
if (r8 == arg2) {
return arg0 - (arg2 - 1);
}
++arg0;
}
} else {
arg0 += mpBookKeepingMemory[arg0];
}
}
return -1;
}
bool CARAMManager::Free(const void* ptr) {
if (GetInvalidAlloc() == ptr) {
return false;
}
uint blockStart = ((u32)ptr - mpARAMStart) / mChunkSize;
uint blockCount = mpBookKeepingMemory[blockStart];
mChunksAllocated -= blockCount;
while (blockCount--) {
mpBookKeepingMemory[blockStart++] = 0;
}
return true;
}
uint CARAMManager::DMAToARAM(void* src, void* dest, uint len, EDMAPriority priority) {
DCStoreRange(src, len);
SAramDMARequest* req = new SAramDMARequest();
req->mComplete = false;
req->mUniqueID = mDMAUniqueID;
mActiveDMAs.push_back(req);
ARQPostRequest(&req->mRequest, req->mUniqueID, ARQ_TYPE_MRAM_TO_ARAM,
(priority == kDMAPrio_One) ? ARQ_PRIORITY_HIGH : ARQ_PRIORITY_LOW, (u32)src,
(u32)dest, len, AramManagerDMACallback);
GetAndIncrementUniqueID();
return req->mUniqueID;
}
int CARAMManager::DMAToMRAM(void* src, void* dest, uint len, EDMAPriority priority) {
DCInvalidateRange(dest, len);
SAramDMARequest* req = new SAramDMARequest();
req->mComplete = false;
req->mUniqueID = mDMAUniqueID;
mActiveDMAs.push_back(req);
ARQPostRequest(&req->mRequest, req->mUniqueID, ARQ_TYPE_ARAM_TO_MRAM,
(priority == kDMAPrio_One) ? ARQ_PRIORITY_HIGH : ARQ_PRIORITY_LOW, (u32)src,
(u32)dest, len, AramManagerDMACallback);
GetAndIncrementUniqueID();
return req->mUniqueID;
}
bool CARAMManager::IsDMACompleted(uint handle) {
rstl::list< SAramDMARequest* >::iterator it = mActiveDMAs.begin();
for (; it != mActiveDMAs.end(); ++it) {
uint uniqueId = (*it)->mUniqueID;
if (uniqueId == handle) {
if ((*it)->mComplete) {
delete (*it);
mActiveDMAs.erase(it);
return true;
}
return false;
}
}
return true;
}
void CARAMManager::WaitForDMACompletion(uint handle) {
rstl::list< SAramDMARequest* >::iterator it = mActiveDMAs.begin();
for (; it != mActiveDMAs.end(); ++it) {
uint uniqueId = (*it)->mUniqueID;
if (uniqueId == handle) {
// Spin until complete!
while (!(*it)->mComplete)
;
delete (*it);
mActiveDMAs.erase(it);
return;
}
}
}
void CARAMManager::WaitForAllDMAsToComplete() {
while ((int)mActiveDMAs.size() > 0) {
RefreshActiveDMAList();
}
}
bool CARAMManager::CancelDMA(uint handle) {
rstl::list< SAramDMARequest* >::iterator it = mActiveDMAs.begin();
for (; it != mActiveDMAs.end(); ++it) {
uint uniqueId = (*it)->mUniqueID;
if (uniqueId == handle) {
return (*it)->mComplete != false;
}
}
return true;
}
void CARAMManager::AramManagerDMACallback(u32 result) {
SAramDMARequest* req = reinterpret_cast< SAramDMARequest* >(result);
req->mComplete = true;
if (req->mRequest.type == ARQ_TYPE_ARAM_TO_MRAM) {
DCInvalidateRange(reinterpret_cast< void* >(req->mRequest.dest), req->mRequest.length);
}
}
void CARAMManager::RefreshActiveDMAList() {
rstl::list< SAramDMARequest* >::iterator it = mActiveDMAs.begin();
while (it != mActiveDMAs.end()) {
if ((*it)->mComplete) {
delete (*it);
it = mActiveDMAs.erase(it);
continue;
}
++it;
}
}
void CARAMManager::CollectGarbage() {
RefreshActiveDMAList();
}

View File

@ -17,7 +17,10 @@ import re
script_dir = os.path.dirname(os.path.realpath(__file__))
root_dir = os.path.abspath(os.path.join(script_dir, ".."))
src_dir = os.path.join(root_dir, "src")
include_dir = os.path.join(root_dir, "include")
include_dirs = [
os.path.join(root_dir, "include"),
os.path.join(root_dir, "libc"),
]
include_pattern = re.compile(r'^#include\s*[<"](.+?)[>"]$')
guard_pattern = re.compile(r'^#ifndef\s+(.*)$')
@ -26,14 +29,15 @@ defines = set()
def import_h_file(in_file: str, r_path: str) -> str:
rel_path = os.path.join(root_dir, r_path, in_file)
inc_path = os.path.join(include_dir, in_file)
if os.path.exists(rel_path):
return import_c_file(rel_path)
elif os.path.exists(inc_path):
return import_c_file(inc_path)
return import_c_file(rel_path)
for include_dir in include_dirs:
inc_path = os.path.join(include_dir, in_file)
if os.path.exists(inc_path):
return import_c_file(inc_path)
else:
print("Failed to locate", in_file)
exit(1)
print("Failed to locate", in_file)
return ""
def import_c_file(in_file) -> str:
in_file = os.path.relpath(in_file, root_dir)
@ -84,4 +88,4 @@ def main():
if __name__ == "__main__":
main()
main()