mirror of
https://gitlab.com/kholdfuzion/goldeneye_src
synced 2026-09-02 17:42:56 -04:00
160 lines
5.3 KiB
C
160 lines
5.3 KiB
C
#include "ultra64.h"
|
|
#include "game/dyn.h"
|
|
#include "token.h"
|
|
#include "str.h"
|
|
#include "memp.h"
|
|
|
|
/**
|
|
* This file handles memory usage for graphics related tasks.
|
|
*
|
|
* There are two pools, "gfx" and "vtx", which are used to store different data.
|
|
*
|
|
* The gfx pool (g_GfxBuffers) is sized based on the stage's -mgfx
|
|
* argument. It contains only the master display list's GBI bytecode.
|
|
* The master gdl is passed through all rendering functions in the game engine,
|
|
* where each appends to the display list.
|
|
*
|
|
* The vtx pool (g_VtxBuffers) is sized based on the stage's -mvtx argument.
|
|
* It is used for auxiliary graphics data such as vertex arrays, matrices and
|
|
* colours.
|
|
*
|
|
* Both the gfx and vtx pools are split into two buffers of equal size.
|
|
* Only one buffer is active at a time - the other is being drawn to the screen
|
|
* while the active one is being built. Each time a frame is finished the active
|
|
* buffer index is swapped to the other one.
|
|
*
|
|
* Both the gfx and vtx pools have a third element in them, but this is just a
|
|
* marker for the end of the second element's allocation.
|
|
*/
|
|
|
|
u8 *g_GfxBuffers[3];
|
|
u8 *g_VtxBuffers[3];
|
|
u8 *g_GfxMemPos;
|
|
u8 g_GfxActiveBufferIndex;
|
|
s32 g_GfxRequestedDisplayList;
|
|
s32 D_800482E0 = 0;
|
|
s32 g_GfxSizesByPlayerCount[] = {0x10000, 0x18000, 0x20000, 0x28000};
|
|
s32 g_VtxSizesByPlayerCount[] = {0x10000, 0x18000, 0x20000, 0x28000};
|
|
|
|
char membars_string1[] = ">>>>>>>>>>>>>>>>>>>>>>>>>";
|
|
char membars_string2[] = "=========================";
|
|
char membars_string3[] = "-------------------------";
|
|
|
|
void dynInitDebugNoticeList(void) {
|
|
debTryAdd(&D_800482E0, "dyn_c_debug");
|
|
}
|
|
|
|
void dynInitMemory(void) {
|
|
if (tokenFind(1, "-mgfx")) {
|
|
g_GfxSizesByPlayerCount[getPlayerCount() - 1] = strtol(tokenFind(1, "-mgfx"), NULL, 0) * 1024;
|
|
}
|
|
if (tokenFind(1, "-mvtx")) {
|
|
g_VtxSizesByPlayerCount[getPlayerCount() - 1] = strtol(tokenFind(1, "-mvtx"), NULL, 0) * 1024;
|
|
}
|
|
|
|
g_GfxBuffers[0] = mempAllocBytesInBank(g_GfxSizesByPlayerCount[getPlayerCount() - 1] * 2, 4);
|
|
g_GfxBuffers[1] = (g_GfxBuffers[0] + g_GfxSizesByPlayerCount[getPlayerCount() - 1]);
|
|
g_GfxBuffers[2] = (g_GfxBuffers[1] + g_GfxSizesByPlayerCount[getPlayerCount() - 1]);
|
|
|
|
g_VtxBuffers[0] = mempAllocBytesInBank(g_VtxSizesByPlayerCount[getPlayerCount() - 1] * 2, 4);
|
|
g_VtxBuffers[1] = (g_VtxBuffers[0] + g_VtxSizesByPlayerCount[getPlayerCount() - 1]);
|
|
g_VtxBuffers[2] = (g_VtxBuffers[1] + g_VtxSizesByPlayerCount[getPlayerCount() - 1]);
|
|
|
|
g_GfxActiveBufferIndex = 0;
|
|
g_GfxRequestedDisplayList = FALSE;
|
|
g_GfxMemPos = g_VtxBuffers[0];
|
|
}
|
|
|
|
Gfx *dynGetMasterDisplayList(void) {
|
|
g_GfxRequestedDisplayList = TRUE;
|
|
|
|
return (Gfx*)g_GfxBuffers[g_GfxActiveBufferIndex];
|
|
}
|
|
|
|
s32 dynGetFreeGfx2(Gfx *gdl) {
|
|
return (Gfx*)g_GfxBuffers[g_GfxActiveBufferIndex + 1] - gdl;
|
|
}
|
|
|
|
void/*Vtx?*/ *dynAllocate7F0BD6C4(s32 count) {
|
|
void *ptr = g_GfxMemPos;
|
|
g_GfxMemPos += count * 0x10/*sizeof(Vtx)?*/;
|
|
return ptr;
|
|
}
|
|
|
|
Mtx *dynAllocateMatrix(void)
|
|
{
|
|
void *ptr = g_GfxMemPos;
|
|
g_GfxMemPos += sizeof(Mtx);
|
|
return ptr;
|
|
}
|
|
|
|
void/*Light?*/ *dynAllocate7F0BD6F8(s32 count) {
|
|
void *ptr = g_GfxMemPos;
|
|
g_GfxMemPos += count * 0x10/*sizeof(Light)?*/;
|
|
return ptr;
|
|
}
|
|
|
|
void *dynAllocate(s32 size) {
|
|
void *ptr = g_GfxMemPos;
|
|
size = ALIGN16_a(size);
|
|
g_GfxMemPos += size;
|
|
return ptr;
|
|
}
|
|
|
|
void dynSwapBuffers(void) {
|
|
g_GfxActiveBufferIndex = (g_GfxActiveBufferIndex ^ 1);
|
|
g_GfxRequestedDisplayList = FALSE;
|
|
g_GfxMemPos = g_VtxBuffers[g_GfxActiveBufferIndex];
|
|
}
|
|
|
|
void dynRemovedFunc(Gfx *gdl) {
|
|
}
|
|
|
|
s32 dynGetFreeGfx(Gfx *gdl) {
|
|
return (Gfx*)g_GfxBuffers[g_GfxActiveBufferIndex + 1] - gdl;
|
|
}
|
|
|
|
s32 dynGetFreeVtx(void) {
|
|
return g_VtxBuffers[g_GfxActiveBufferIndex + 1] - g_GfxMemPos;
|
|
}
|
|
|
|
#ifdef NONMATCHING
|
|
// $f2 is used for 0.0f instead of $f0
|
|
f32 dynCalculateMembarLength(const char* arg0, f32 arg1, f32 arg2) {
|
|
strlen(arg0);
|
|
arg1 /= arg2;
|
|
if (arg1 < 0.0f) {
|
|
return 0.0f;
|
|
}
|
|
}
|
|
#else
|
|
f32 dynCalculateMembarLength(const char* arg0, f32 arg1, f32 arg2);
|
|
GLOBAL_ASM(
|
|
.text
|
|
glabel dynCalculateMembarLength
|
|
/* 0F22FC 7F0BD7CC 44856000 */ mtc1 $a1, $f12
|
|
/* 0F2300 7F0BD7D0 27BDFFE8 */ addiu $sp, $sp, -0x18
|
|
/* 0F2304 7F0BD7D4 AFBF0014 */ sw $ra, 0x14($sp)
|
|
/* 0F2308 7F0BD7D8 AFA60020 */ sw $a2, 0x20($sp)
|
|
/* 0F230C 7F0BD7DC 0C004E1F */ jal strlen
|
|
/* 0F2310 7F0BD7E0 E7AC001C */ swc1 $f12, 0x1c($sp)
|
|
/* 0F2314 7F0BD7E4 C7AC001C */ lwc1 $f12, 0x1c($sp)
|
|
/* 0F2318 7F0BD7E8 C7A40020 */ lwc1 $f4, 0x20($sp)
|
|
/* 0F231C 7F0BD7EC 44800000 */ mtc1 $zero, $f0
|
|
/* 0F2320 7F0BD7F0 8FBF0014 */ lw $ra, 0x14($sp)
|
|
/* 0F2324 7F0BD7F4 46046303 */ div.s $f12, $f12, $f4
|
|
/* 0F2328 7F0BD7F8 4600603C */ c.lt.s $f12, $f0
|
|
/* 0F232C 7F0BD7FC 00000000 */ nop
|
|
/* 0F2330 7F0BD800 45000001 */ bc1f .L7F0BD808
|
|
/* 0F2334 7F0BD804 00000000 */ nop
|
|
.L7F0BD808:
|
|
/* 0F2338 7F0BD808 03E00008 */ jr $ra
|
|
/* 0F233C 7F0BD80C 27BD0018 */ addiu $sp, $sp, 0x18
|
|
)
|
|
#endif
|
|
|
|
void dynDrawMembars(Gfx *gdl) {
|
|
dynCalculateMembarLength(membars_string2, ((Gfx*)g_GfxBuffers[g_GfxActiveBufferIndex + 1] - gdl), ((Gfx*)g_GfxBuffers[g_GfxActiveBufferIndex + 1] - (Gfx*)g_GfxBuffers[g_GfxActiveBufferIndex]));
|
|
dynCalculateMembarLength(membars_string2, (g_VtxBuffers[g_GfxActiveBufferIndex + 1] - g_GfxMemPos), (g_VtxBuffers[g_GfxActiveBufferIndex + 1] - g_VtxBuffers[g_GfxActiveBufferIndex]));
|
|
}
|