[jak3] Set up ckernel (#3308)

This sets up the C Kernel for Jak 3, and makes it possible to build and
load code built with `goalc --jak3`.

There's not too much interesting here, other than they switched to a
system where symbol IDs (unique numbers less than 2^14) are generated at
compile time, and those get included in the object file itself.

This is kind of annoying, since it means all tools that produce a GOAL
object file need to work together to assign unique symbol IDs. And since
the symbol IDs can't conflict, and are only a number between 0 and 2^14,
you can't just hash and hope for no collisions.

We work around this by ignoring the IDs and re-assigning our own. I
think this is very similar to what the C Kernel did on early builds of
Jak 3 which supported loading old format level files, which didn't have
the IDs included.

As far as I can tell, this shouldn't cause any problems. It defeats all
of their fancy tricks to save memory by not storing the symbol string,
but we don't care.
This commit is contained in:
water111
2024-01-16 19:24:02 -05:00
committed by GitHub
parent ed6639ee60
commit 4f537d4a71
88 changed files with 7364 additions and 653 deletions
+29
View File
@@ -12,11 +12,25 @@
// global and debug kernel heaps
Ptr<kheapinfo> kglobalheap;
Ptr<kheapinfo> kdebugheap;
// if we should count the number of strings and types allocated on the global heap.
bool kheaplogging = false;
enum MemItemsCategory {
STRING = 0,
TYPE = 1,
NUM_CATEGORIES = 2,
};
int MemItemsCount[NUM_CATEGORIES] = {0, 0};
int MemItemsSize[NUM_CATEGORIES] = {0, 0};
void kmalloc_init_globals_common() {
// _globalheap and _debugheap
kglobalheap.offset = GLOBAL_HEAP_INFO_ADDR;
kdebugheap.offset = DEBUG_HEAP_INFO_ADDR;
kheaplogging = false;
for (auto& x : MemItemsCount)
x = 0;
for (auto& x : MemItemsSize)
x = 0;
}
/*!
@@ -75,6 +89,10 @@ Ptr<kheapinfo> kheapstatus(Ptr<kheapinfo> heap) {
Msg(6, "\t %d bytes before stack\n", GLOBAL_HEAP_END - heap->current.offset);
}
for (int i = 0; i < NUM_CATEGORIES; i++) {
printf(" %d: %d %d\n", i, MemItemsCount[i], MemItemsSize[i]);
}
// might not have returned heap in jak 1
return heap;
}
@@ -171,6 +189,17 @@ Ptr<u8> kmalloc(Ptr<kheapinfo> heap, s32 size, u32 flags, char const* name) {
if (flags & KMALLOC_MEMSET)
std::memset(Ptr<u8>(memstart).c(), 0, (size_t)size);
// this logging was added in Jak 3, but we port it back to all games:
if ((heap == kglobalheap) && (kheaplogging != 0)) {
if (strcmp(name, "string") == 0) {
MemItemsCount[STRING]++;
MemItemsSize[STRING] += size;
} else if (strcmp(name, "type") == 0) {
MemItemsCount[TYPE]++;
MemItemsSize[TYPE] += size;
}
}
return Ptr<u8>(memstart);
}
}