perfect_dark/src/game/gfxmemory.c

191 lines
5.0 KiB
C

#include <ultra64.h>
#include "constants.h"
#include "game/gfxmemory.h"
#include "game/stubs/game_175f50.h"
#include "bss.h"
#include "lib/rzip.h"
#include "lib/dma.h"
#include "lib/memp.h"
#include "lib/rng.h"
#include "data.h"
#include "types.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 and -mgfxtra
* arguments. 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];
u32 var800aa58c;
u8 *g_VtxBuffers[3];
u8 *g_GfxMemPos;
u8 g_GfxActiveBufferIndex;
u32 g_GfxRequestedDisplayList;
u32 g_GfxSizesByPlayerCount[] = {
0x00010000,
0x00018000,
0x00020000,
0x00028000,
};
u32 g_VtxSizesByPlayerCount[] = {
0x00010000,
0x00018000,
0x00020000,
0x00028000,
};
s32 g_GfxNumSwapsPerBuffer[2] = {0, 1};
u32 g_GfxNumSwaps = 0x00000002;
/**
* Allocate graphics memory from the heap. Presumably called on stage load.
*
* Comments in this function are strings that appear in an XBLA debug build.
* They were likely in the N64 version but ifdeffed out.
*/
void gfxReset(void)
{
s32 stack;
if (argFindByPrefix(1, "-mgfx")) {
// Argument specified master_dl_size\n
s32 gfx;
s32 gfxtra = 0;
gfx = strtol(argFindByPrefix(1, "-mgfx"), NULL, 0) * 1024;
if (argFindByPrefix(1, "-mgfxtra")) {
// ******** Extra specified but are we in the correct game mode I wonder???\n
if ((g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) && PLAYERCOUNT() == 2) {
// ******** Extra Display List Memeory Required\n
// ******** Shall steal from video buffer\n
// ******** If you try and run hi-res then\n
// ******** you're gonna shafted up the arse\n
// ******** so don't blame me\n
gfxtra = strtol(argFindByPrefix(1, "-mgfxtra"), NULL, 0) * 1024;
} else {
// ******** No we're not so there\n
}
}
// ******** Original Amount required = %dK ber buffer\n
// ******** Extra Amount required = %dK ber buffer\n
// ******** Total of %dK (Double Buffered)\n
g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1] = gfx + gfxtra;
}
if (argFindByPrefix(1, "-mvtx")) {
// Argument specified mtxvtx_size\n
g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] = strtol(argFindByPrefix(1, "-mvtx"), NULL, 0) * 1024;
}
// %d Players : Allocating %d bytes for master dl's\n
g_GfxBuffers[0] = mempAlloc(g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1] * 2, MEMPOOL_STAGE);
g_GfxBuffers[1] = g_GfxBuffers[0] + g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1];
g_GfxBuffers[2] = g_GfxBuffers[1] + g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1];
// Allocating %d bytes for mtxvtx space\n
g_VtxBuffers[0] = mempAlloc(g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] * 2, MEMPOOL_STAGE);
g_VtxBuffers[1] = g_VtxBuffers[0] + g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1];
g_VtxBuffers[2] = g_VtxBuffers[1] + g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1];
g_GfxActiveBufferIndex = 0;
g_GfxRequestedDisplayList = false;
g_GfxMemPos = g_VtxBuffers[0];
}
Gfx *gfxGetMasterDisplayList(void)
{
g_GfxRequestedDisplayList = true;
return (Gfx *)g_GfxBuffers[g_GfxActiveBufferIndex];
}
struct gfxvtx *gfxAllocateVertices(s32 count)
{
void *ptr = g_GfxMemPos;
g_GfxMemPos += count * sizeof(struct gfxvtx);
g_GfxMemPos = (u8 *)ALIGN16((u32)g_GfxMemPos);
return ptr;
}
void *gfxAllocateMatrix(void)
{
void *ptr = g_GfxMemPos;
g_GfxMemPos += sizeof(Mtx);
return ptr;
}
void *gfxAllocateLookAt(s32 count)
{
void *ptr = g_GfxMemPos;
g_GfxMemPos += count * 0x10;
return ptr;
}
void *gfxAllocateColours(s32 count)
{
void *ptr = g_GfxMemPos;
count = ALIGN16(count * sizeof(u32));
g_GfxMemPos += count;
return ptr;
}
void *gfxAllocate(u32 size)
{
void *ptr = g_GfxMemPos;
size = ALIGN16(size);
g_GfxMemPos += size;
return ptr;
}
extern s32 g_GfxNumSwapsPerBuffer[2];
void gfxSwapBuffers(void)
{
g_GfxActiveBufferIndex ^= 1;
g_GfxRequestedDisplayList = false;
g_GfxMemPos = g_VtxBuffers[g_GfxActiveBufferIndex];
g_GfxNumSwapsPerBuffer[g_GfxActiveBufferIndex] = g_GfxNumSwaps;
g_GfxNumSwaps++;
if (g_GfxNumSwaps == -1) {
g_GfxNumSwaps = 2;
}
}
s32 gfxGetFreeGfx(Gfx *gdl)
{
return (Gfx *)g_GfxBuffers[g_GfxActiveBufferIndex + 1] - gdl;
}
u32 gfxGetFreeVtx(void)
{
return g_VtxBuffers[g_GfxActiveBufferIndex + 1] - g_GfxMemPos;
}