marioparty4/src/dolphin/demo/DEMOInit.c
2024-11-12 03:51:15 +01:00

251 lines
7.5 KiB
C

#include <dolphin.h>
#include <dolphin/demo.h>
#include <dolphin/gx.h>
#include <dolphin/pad.h>
#include <dolphin/vi.h>
#include "game/init.h"
#include <dolphin/demoPriv.h>
extern unsigned char DemoStatEnable; // size: 0x1, address: 0x0
// .bss
static struct _GXRenderModeObj rmodeobj; // size: 0x3C, address: 0x0
// .sdata
static unsigned char DemoFirstFrame = 1; // size: 0x1, address: 0x0
// .sbss
static void *DefaultFifo = NULL; // size: 0x4, address: 0x0
static GXFifoObj *DefaultFifoObj = NULL; // size: 0x4, address: 0x4
static struct _GXRenderModeObj *rmode; // size: 0x4, address: 0x8
static int BypassWorkaround; // size: 0x4, address: 0xC
static unsigned long FrameCount; // size: 0x4, address: 0x10
static unsigned long FrameMissThreshold; // size: 0x4, address: 0x14
// functions
static void __DEMOInitRenderMode(struct _GXRenderModeObj *mode);
static void __DEMOInitMem();
static void __DEMOInitGX();
static void __DEMOInitVI();
static void __DEMOInitForEmu();
static void __BypassRetraceCallback();
static void LoadMemInfo();
void DEMOInit(struct _GXRenderModeObj *mode)
{
OSInit();
DVDInit();
VIInit();
DEMOPadInit();
__DEMOInitRenderMode(mode);
__DEMOInitMem();
VIConfigure(rmode);
DefaultFifo = OSAllocFromHeap(__OSCurrHeap, 0x40000);
DefaultFifoObj = GXInit(DefaultFifo, 0x40000);
__DEMOInitGX();
__DEMOInitVI();
}
static void __DEMOInitRenderMode(struct _GXRenderModeObj *mode)
{
if (mode != NULL) {
rmode = mode;
return;
}
switch (VIGetTvFormat()) {
case VI_NTSC:
rmode = &GXNtsc480IntDf;
break;
case VI_PAL:
rmode = &GXPal528IntDf;
break;
case VI_MPAL:
rmode = &GXMpal480IntDf;
break;
default:
OSPanic(__FILE__, 0x1A6, "DEMOInit: invalid TV format\n");
break;
}
GXAdjustForOverscan(rmode, &rmodeobj, 0, 0x10);
rmode = &rmodeobj;
}
static void __DEMOInitMem()
{
void *arenaLo = OSGetArenaLo();
void *arenaHi = OSGetArenaHi();
unsigned long fbSize = ((u16)(rmode->fbWidth + 15) & 0xFFF0) * rmode->xfbHeight * 2;
DemoFrameBuffer1 = (void *)(((u32)arenaLo + 0x1F) & 0xFFFFFFE0);
DemoFrameBuffer2 = (void *)(((u32)DemoFrameBuffer1 + fbSize + 0x1F) & 0xFFFFFFE0);
DemoCurrentBuffer = DemoFrameBuffer2;
arenaLo = (void *)(((u32)DemoFrameBuffer2 + fbSize + 0x1F) & 0xFFFFFFE0);
OSSetArenaLo(arenaLo);
if (((OSGetConsoleType() + 0xF0000000) == 4U) && ((OSGetPhysicalMemSize() + 0xFFC00000) != 0U)
&& (OSGetConsoleSimulatedMemSize() < 0x01800000U)) {
LoadMemInfo();
return;
}
arenaLo = OSGetArenaLo();
arenaHi = OSGetArenaHi();
arenaLo = OSInitAlloc(arenaLo, arenaHi, 1);
OSSetArenaLo(arenaLo);
arenaLo = (void *)(((u32)arenaLo + 0x1F) & 0xFFFFFFE0);
arenaHi = (void *)((u32)arenaHi & 0xFFFFFFE0);
OSSetCurrentHeap(OSCreateHeap((void *)(((u32)arenaLo)), arenaHi));
OSSetArenaLo((arenaLo = arenaHi));
}
static void __DEMOInitGX()
{
GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->xfbHeight, 0.0f, 1.0f);
GXSetScissor(0, 0, rmode->fbWidth, rmode->efbHeight);
GXSetDispCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight);
GXSetDispCopyDst(rmode->fbWidth, rmode->xfbHeight);
GXSetDispCopyYScale(((f32)rmode->xfbHeight / (f32)rmode->efbHeight));
GXSetCopyFilter(rmode->aa, rmode->sample_pattern, 1, rmode->vfilter);
if (rmode->aa != 0) {
GXSetPixelFmt(2, 0);
}
else {
GXSetPixelFmt(0, 0);
}
GXCopyDisp(DemoCurrentBuffer, 1);
GXSetDispCopyGamma(0);
}
static void __DEMOInitVI()
{
unsigned long nin;
VISetNextFrameBuffer(DemoFrameBuffer1);
DemoCurrentBuffer = DemoFrameBuffer2;
VIFlush();
VIWaitForRetrace();
nin = rmode->viTVmode & 1;
if (nin != 0) {
VIWaitForRetrace();
}
}
static void __DEMOInitForEmu() { }
void DEMOBeforeRender()
{
if (BypassWorkaround != 0) {
GXSetDrawSync(0xFEEB);
}
if (rmode->field_rendering != 0) {
GXSetViewportJitter(0.0f, 0.0f, rmode->fbWidth, rmode->xfbHeight, 0.0f, 1.0f, VIGetNextField());
}
else {
GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->xfbHeight, 0.0f, 1.0f);
}
GXInvalidateVtxCache();
GXInvalidateTexAll();
}
void DEMOSwapBuffers()
{
VISetNextFrameBuffer(DemoCurrentBuffer);
if (DemoFirstFrame != 0) {
VISetBlack(0);
DemoFirstFrame = 0;
}
VIFlush();
VIWaitForRetrace();
if ((u32)DemoCurrentBuffer == (u32)DemoFrameBuffer1) {
DemoCurrentBuffer = DemoFrameBuffer2;
return;
}
DemoCurrentBuffer = DemoFrameBuffer1;
}
struct _GXRenderModeObj *DEMOGetRenderModeObj()
{
return rmode;
}
u32 DEMOGetCurrentBuffer(void)
{
return (u32)DemoCurrentBuffer;
}
void DEMOEnableBypassWorkaround(unsigned long timeoutFrames)
{
BypassWorkaround = 1;
FrameMissThreshold = timeoutFrames;
VISetPreRetraceCallback(__BypassRetraceCallback);
}
static void __BypassRetraceCallback()
{
FrameCount += 1;
}
static void LoadMemInfo()
{
void *arenaHiOld;
void *arenaLo;
void *arenaHi;
void *simMemEnd;
struct DVDFileInfo fileInfo;
unsigned long length;
unsigned long transferLength;
long offset;
unsigned long i;
unsigned long indexMax;
char *buf[63];
struct {
void *start;
void *end;
} *memEntry;
OSReport("\nNow, try to find memory info file...\n\n");
if (!DVDOpen("/meminfo.bin", &fileInfo)) {
OSReport("\nCan't find memory info file. Use /XXX toolname/ to maximize available\n");
OSReport("memory space. For now, we only use the first %dMB.\n", OSGetConsoleSimulatedMemSize() >> 0x14);
arenaLo = OSGetArenaLo();
arenaHi = OSGetArenaHi();
arenaLo = OSInitAlloc(arenaLo, arenaHi, 1);
OSSetArenaLo(arenaLo);
arenaLo = (void *)(((u32)arenaLo + 0x1F) & 0xFFFFFFE0);
arenaHi = (void *)((u32)arenaHi & 0xFFFFFFE0);
OSSetCurrentHeap(OSCreateHeap((void *)(((u32)arenaLo)), arenaHi));
OSSetArenaLo((arenaLo = arenaHi));
return;
}
memEntry = (void *)((u32)buf + 0x1F & 0xFFFFFFE0);
arenaHiOld = OSGetArenaHi();
simMemEnd = OSPhysicalToCached(OSGetConsoleSimulatedMemSize());
OSSetArenaHi(OSPhysicalToCached(OSGetPhysicalMemSize()));
arenaLo = OSGetArenaLo();
arenaHi = OSGetArenaHi();
arenaLo = OSInitAlloc(arenaLo, arenaHi, 1);
OSSetArenaLo(arenaLo);
arenaLo = (void *)(((u32)arenaLo + 0x1F) & 0xFFFFFFE0);
arenaHi = (void *)((u32)arenaHi & 0xFFFFFFE0);
OSSetCurrentHeap(OSCreateHeap((void *)(arenaLo), arenaHi));
OSSetArenaLo((arenaLo = arenaHi));
OSAllocFixed(&arenaHiOld, &simMemEnd);
length = fileInfo.length;
offset = 0;
while (length) {
OSReport("loop\n");
transferLength = (length < 0x20) ? length : 0x20;
if (DVDReadPrio(&fileInfo, memEntry, (transferLength + 0x1F) & 0xFFFFFFE0, offset, 2) < 0) {
OSPanic(__FILE__, 0x49F, "An error occurred when issuing read to /meminfo.bin\n");
}
indexMax = (transferLength / 8);
for (i = 0; i < indexMax; i++) {
OSReport("start: 0x%08x, end: 0x%08x\n", memEntry[i].start, memEntry[i].end);
OSAllocFixed(&memEntry[i].start, &memEntry[i].end);
OSReport("Removed 0x%08x - 0x%08x from the current heap\n", memEntry[i].start, (char *)memEntry[i].end - 1);
}
length -= transferLength;
offset += transferLength;
}
DVDClose(&fileInfo);
OSDumpHeap(__OSCurrHeap);
}