#include "global.h" s32 gFramerateDivisor = 1; f32 gFramerateDivisorF = 1.0f; f32 gFramerateDivisorHalf = 1.0f / 2.0f; f32 gFramerateDivisorThird = 1.0f / 3.0f; void Game_UpdateFramerateVariables(s32 divisor) { gFramerateDivisor = divisor; gFramerateDivisorF = (f32)divisor; gFramerateDivisorHalf = (f32)(divisor * 0.5f); gFramerateDivisorThird = (f32)(divisor / 3.0f); } void Game_SetFramerateDivisor(GameState* gameState, s32 divisor) { R_UPDATE_RATE = (s16)divisor; gameState->framerateDivisor = divisor; Game_UpdateFramerateVariables(divisor); } void GameState_SetFBFilter(Gfx** gfx, u32 arg1) { Gfx* dlist = *gfx; if ((R_FB_FILTER_TYPE > 0) && (R_FB_FILTER_TYPE < 5)) { D_801F8010.type = R_FB_FILTER_TYPE; D_801F8010.color.r = R_FB_FILTER_PRIM_COLOR(0); D_801F8010.color.g = R_FB_FILTER_PRIM_COLOR(1); D_801F8010.color.b = R_FB_FILTER_PRIM_COLOR(2); D_801F8010.color.a = R_FB_FILTER_A; func_80140D10(&D_801F8010, &dlist, arg1); } else { if ((R_FB_FILTER_TYPE == 5) || (R_FB_FILTER_TYPE == 6)) { D_801F8020.useRgba = (R_FB_FILTER_TYPE == 6); D_801F8020.primColor.r = R_FB_FILTER_PRIM_COLOR(0); D_801F8020.primColor.g = R_FB_FILTER_PRIM_COLOR(1); D_801F8020.primColor.b = R_FB_FILTER_PRIM_COLOR(2); D_801F8020.primColor.a = R_FB_FILTER_A; D_801F8020.envColor.r = R_FB_FILTER_ENV_COLOR(0); D_801F8020.envColor.g = R_FB_FILTER_ENV_COLOR(1); D_801F8020.envColor.b = R_FB_FILTER_ENV_COLOR(2); D_801F8020.envColor.a = R_FB_FILTER_A; func_80142100(&D_801F8020, &dlist, arg1); } else { if (R_FB_FILTER_TYPE == 7) { sMonoColors.unk_00 = 0; sMonoColors.primColor.r = R_FB_FILTER_PRIM_COLOR(0); sMonoColors.primColor.g = R_FB_FILTER_PRIM_COLOR(1); sMonoColors.primColor.b = R_FB_FILTER_PRIM_COLOR(2); sMonoColors.primColor.a = R_FB_FILTER_A; sMonoColors.envColor.r = R_FB_FILTER_ENV_COLOR(0); sMonoColors.envColor.g = R_FB_FILTER_ENV_COLOR(1); sMonoColors.envColor.b = R_FB_FILTER_ENV_COLOR(2); sMonoColors.envColor.a = R_FB_FILTER_A; VisMono_Draw(&sMonoColors, &dlist, arg1); } } } *gfx = dlist; } void Game_Nop80173534(GameState* gameState) { } void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx) { Gfx* nextDisplayList; Gfx* polyOpa; OPEN_DISPS(gfxCtx); nextDisplayList = Graph_GfxPlusOne(polyOpa = POLY_OPA_DISP); gSPDisplayList(OVERLAY_DISP++, nextDisplayList); if (R_FB_FILTER_TYPE && R_FB_FILTER_ENV_COLOR(3) == 0) { GameState_SetFBFilter(&nextDisplayList, (u32)gfxCtx->zbuffer); } if (R_ENABLE_ARENA_DBG < 0) { R_ENABLE_ARENA_DBG = 0; } gSPEndDisplayList(nextDisplayList++); Graph_BranchDlist(polyOpa, nextDisplayList); POLY_OPA_DISP = nextDisplayList; // Block prevents reordering, if(1) around the above block don't seem to help unlike in OoT { s32 requiredScopeTemp; func_800E9F78(gfxCtx); } if (R_ENABLE_ARENA_DBG != 0) { SpeedMeter_DrawTimeEntries(&D_801F7FF0, gfxCtx); SpeedMeter_DrawAllocEntries(&D_801F7FF0, gfxCtx, gameState); } CLOSE_DISPS(gfxCtx); } void GameState_SetFrameBuffer(GraphicsContext* gfxCtx) { OPEN_DISPS(gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x00, NULL); gSPSegment(POLY_OPA_DISP++, 0x0F, gfxCtx->curFrameBuffer); gSPSegment(POLY_XLU_DISP++, 0x00, NULL); gSPSegment(POLY_XLU_DISP++, 0x0F, gfxCtx->curFrameBuffer); gSPSegment(OVERLAY_DISP++, 0x00, NULL); gSPSegment(OVERLAY_DISP++, 0x0F, gfxCtx->curFrameBuffer); CLOSE_DISPS(gfxCtx); } void func_801736DC(GraphicsContext* gfxCtx) { Gfx* nextDisplayList; Gfx* polyOpa; OPEN_DISPS(gfxCtx); nextDisplayList = Graph_GfxPlusOne(polyOpa = gfxCtx->polyOpa.p); gSPDisplayList(OVERLAY_DISP++, nextDisplayList); gSPEndDisplayList(nextDisplayList++); Graph_BranchDlist(polyOpa, nextDisplayList); POLY_OPA_DISP = nextDisplayList; CLOSE_DISPS(gfxCtx); } void Game_UpdateInput(GameState* gameState) { Padmgr_GetInput(gameState->input, 1); } void Game_Update(GameState* gameState) { GraphicsContext* gfxCtx = gameState->gfxCtx; GameState_SetFrameBuffer(gameState->gfxCtx); gameState->main(gameState); if (R_PAUSE_MENU_MODE != 2) { GameState_Draw(gameState, gfxCtx); func_801736DC(gfxCtx); } } void Game_IncrementFrameCount(GameState* gameState) { Game_Nop80173534(gameState); gameState->frames++; } void GameState_InitArena(GameState* gameState, size_t size) { GameAlloc* alloc = &gameState->alloc; void* buf = GameAlloc_Malloc(alloc, size); if (buf) { THA_Ct(&gameState->heap, buf, size); return; } THA_Ct(&gameState->heap, NULL, 0); __assert("../game.c", 1035); } void GameState_Realloc(GameState* gameState, size_t size) { GameAlloc* alloc; void* gameArena; size_t systemMaxFree; size_t bytesFree; size_t bytesAllocated; void* heapStart; heapStart = gameState->heap.bufp; alloc = &gameState->alloc; THA_Dt(&gameState->heap); GameAlloc_Free(alloc, heapStart); SystemArena_AnalyzeArena(&systemMaxFree, &bytesFree, &bytesAllocated); size = ((systemMaxFree - (sizeof(ArenaNode))) < size) ? (0) : (size); if (size == 0) { size = systemMaxFree - (sizeof(ArenaNode)); } if ((gameArena = GameAlloc_Malloc(alloc, size)) != NULL) { THA_Ct(&gameState->heap, gameArena, size); } else { THA_Ct(&gameState->heap, 0, 0); __assert("../game.c", 1074); } } void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* gfxCtx) { gameState->gfxCtx = gfxCtx; gameState->frames = 0U; gameState->main = NULL; gameState->destroy = NULL; gameState->running = 1; gfxCtx->viMode = D_801FBB88; gfxCtx->viConfigFeatures = gViConfigFeatures; gfxCtx->xScale = gViConfigXScale; gfxCtx->yScale = gViConfigYScale; gameState->nextGameStateInit = NULL; gameState->nextGameStateSize = 0U; { s32 requiredScopeTemp; GameAlloc_Init(&gameState->alloc); GameState_InitArena(gameState, 0x100000); Game_SetFramerateDivisor(gameState, 3); init(gameState); func_80140CE0(&D_801F8010); func_801420C0(&D_801F8020); func_801418B0(&sMonoColors); func_80140898(&D_801F8048); func_801773A0(&D_801F7FF0); func_8013ED9C(); osSendMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK); } } void GameState_Destroy(GameState* gameState) { func_80172BC0(); func_8019E014(); osRecvMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK); if (gameState->destroy != NULL) { gameState->destroy(gameState); } func_8013EDD0(); func_801773C4(&D_801F7FF0); func_80140D04(&D_801F8010); func_801420F4(&D_801F8020); func_80141900(&sMonoColors); func_80140900(&D_801F8048); THA_Dt(&gameState->heap); GameAlloc_Cleanup(&gameState->alloc); } GameStateFunc GameState_GetNextStateInit(GameState* gameState) { return gameState->nextGameStateInit; } size_t GameState_GetNextStateSize(GameState* gameState) { return gameState->nextGameStateSize; } u32 GameState_IsRunning(GameState* gameState) { return gameState->running; } s32 GameState_GetArenaSize(GameState* gameState) { return THA_GetSize(&gameState->heap); } s32 func_80173B48(GameState* gameState) { s32 result = OS_CYCLES_TO_NSEC(gameState->framerateDivisor * sIrqMgrRetraceTime) - OS_CYCLES_TO_NSEC(D_801FBAF0); return result; }