diff --git a/include/pause.h b/include/pause.h index d5f348a03cf..d9d006aad82 100644 --- a/include/pause.h +++ b/include/pause.h @@ -53,9 +53,33 @@ typedef enum PauseMenuPage { #define PAUSE_EQUIP_PLAYER_FRAG_HEIGHT (TMEM_SIZE / (PAUSE_EQUIP_PLAYER_WIDTH * G_IM_SIZ_16b_BYTES)) #define PAUSE_EQUIP_PLAYER_FRAG_NUM (((PAUSE_EQUIP_PLAYER_HEIGHT - 1) / PAUSE_EQUIP_PLAYER_FRAG_HEIGHT) + 1) -#define PAUSE_EQUIP_BUFFER_SIZE sizeof(u16[PAUSE_EQUIP_PLAYER_HEIGHT][PAUSE_EQUIP_PLAYER_WIDTH]) +// The pause player segment consists of: +// PAUSE_PLAYER_RENDER_TEX_SIZE RGBA16 texture / framebuffer for rendering the player into +// PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_BUFFER_SIZE First bytes of gameplay_keep for accessing player-related data +// sizeof(link object) Link object +// sizeof(Vec3s[PLAYER_LIMB_BUF_COUNT])) Joint table + +#define PAUSE_PLAYER_SEGMENT_TEX_SIZE sizeof(u16[PAUSE_EQUIP_PLAYER_HEIGHT][PAUSE_EQUIP_PLAYER_WIDTH]) #define PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_BUFFER_SIZE 0x5000 +#define PAUSE_PLAYER_SEGMENT_TEXTURE(playerSegment) \ + (playerSegment) + +// Note that only the first chunk of gameplay_keep is loaded, the data relevant to rendering the player +// is expected to be within this first chunk. The size of this first chunk is determined by +// PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_BUFFER_SIZE. +#define PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_START(playerSegment) \ + ((playerSegment) + PAUSE_PLAYER_SEGMENT_TEX_SIZE) + +#define PAUSE_PLAYER_SEGMENT_LINK_OBJECT(playerSegment) \ + ((playerSegment) + PAUSE_PLAYER_SEGMENT_TEX_SIZE + PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_BUFFER_SIZE) + +#define PAUSE_PLAYER_SEGMENT_TOTAL_SIZE(linkObjectSize) \ + (PAUSE_PLAYER_SEGMENT_TEX_SIZE + \ + PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_BUFFER_SIZE + \ + (linkObjectSize) + \ + sizeof(Vec3s[PLAYER_LIMB_BUF_COUNT])) + typedef enum PauseState { /* 0 */ PAUSE_STATE_OFF, /* 1 */ PAUSE_STATE_WAIT_LETTERBOX, // Request no letterboxing and wait for it. diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c index d56eb841026..efa35f1cfc2 100644 --- a/src/code/z_player_lib.c +++ b/src/code/z_player_lib.c @@ -1889,25 +1889,27 @@ u32 Player_InitPauseDrawData(PlayState* play, u8* segment, SkelAnime* skelAnime) u32 size; void* ptr; + // Note that since gameplay_keep is typically a compressed segment and due to constraints in the DMA manager, + // the entire segment is loaded even when only the first bytes up to PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_BUFFER_SIZE + // are kept for later use. size = gObjectTable[OBJECT_GAMEPLAY_KEEP].vromEnd - gObjectTable[OBJECT_GAMEPLAY_KEEP].vromStart; - ptr = segment + PAUSE_EQUIP_BUFFER_SIZE; + ptr = PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_START(segment); DMA_REQUEST_SYNC(ptr, gObjectTable[OBJECT_GAMEPLAY_KEEP].vromStart, size, "../z_player_lib.c", 2982); size = gObjectTable[linkObjectId].vromEnd - gObjectTable[linkObjectId].vromStart; - ptr = segment + PAUSE_EQUIP_BUFFER_SIZE + PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_BUFFER_SIZE; + ptr = PAUSE_PLAYER_SEGMENT_LINK_OBJECT(segment); DMA_REQUEST_SYNC(ptr, gObjectTable[linkObjectId].vromStart, size, "../z_player_lib.c", 2988); + // Joint tables are placed after the link object ptr = (void*)ALIGN16((uintptr_t)ptr + size); - gSegments[4] = OS_K0_TO_PHYSICAL(segment + PAUSE_EQUIP_BUFFER_SIZE); - gSegments[6] = - OS_K0_TO_PHYSICAL(segment + PAUSE_EQUIP_BUFFER_SIZE + PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_BUFFER_SIZE); + gSegments[4] = OS_K0_TO_PHYSICAL(PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_START(segment)); + gSegments[6] = OS_K0_TO_PHYSICAL(PAUSE_PLAYER_SEGMENT_LINK_OBJECT(segment)); SkelAnime_InitLink(play, skelAnime, gPlayerSkelHeaders[(void)0, gSaveContext.save.linkAge], &gPlayerAnim_link_normal_wait, 9, ptr, ptr, PLAYER_LIMB_MAX); - return PAUSE_EQUIP_BUFFER_SIZE + PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_BUFFER_SIZE + size + - sizeof(Vec3s[PLAYER_LIMB_BUF_COUNT]); + return PAUSE_PLAYER_SEGMENT_TOTAL_SIZE(size); } u8 sPauseModelGroupBySword[] = { @@ -2077,9 +2079,8 @@ void Player_DrawPause(PlayState* play, u8* segment, SkelAnime* skelAnime, Vec3f* Vec3s* srcTable; s32 i; - gSegments[4] = OS_K0_TO_PHYSICAL(segment + PAUSE_EQUIP_BUFFER_SIZE); - gSegments[6] = - OS_K0_TO_PHYSICAL(segment + PAUSE_EQUIP_BUFFER_SIZE + PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_BUFFER_SIZE); + gSegments[4] = OS_K0_TO_PHYSICAL(PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_START(segment)); + gSegments[6] = OS_K0_TO_PHYSICAL(PAUSE_PLAYER_SEGMENT_LINK_OBJECT(segment)); if (!LINK_IS_ADULT) { if (shield == PLAYER_SHIELD_DEKU) { @@ -2103,9 +2104,9 @@ void Player_DrawPause(PlayState* play, u8* segment, SkelAnime* skelAnime, Vec3f* *destTable++ = *srcTable++; } - Player_DrawPauseImpl(play, segment + PAUSE_EQUIP_BUFFER_SIZE, - segment + PAUSE_EQUIP_BUFFER_SIZE + PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_BUFFER_SIZE, skelAnime, - pos, rot, scale, sword, tunic, shield, boots, PAUSE_EQUIP_PLAYER_WIDTH, - PAUSE_EQUIP_PLAYER_HEIGHT, &eye, &at, 60.0f, play->state.gfxCtx->curFrameBuffer, + Player_DrawPauseImpl(play, PAUSE_PLAYER_SEGMENT_GAMEPLAY_KEEP_START(segment), + PAUSE_PLAYER_SEGMENT_LINK_OBJECT(segment), skelAnime, pos, rot, scale, sword, tunic, shield, + boots, PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT, &eye, &at, 60.0f, + play->state.gfxCtx->curFrameBuffer, play->state.gfxCtx->curFrameBuffer + (PAUSE_EQUIP_PLAYER_WIDTH * PAUSE_EQUIP_PLAYER_HEIGHT)); } diff --git a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c index 1ac32371251..3d8dcfbd8c2 100644 --- a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c +++ b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c @@ -70,7 +70,7 @@ static u8 sEquipmentItemOffsets[] = { ITEM_BOOTS_HOVER - ITEM_SWORD_KOKIRI, // EQUIP_VALUE_BOOTS_HOVER }; -void KaleidoScope_DrawEquipmentImage(PlayState* play, void* source, u32 width, u32 height) { +void KaleidoScope_DrawEquipmentImage(PlayState* play, void* texture, u32 width, u32 height) { PauseContext* pauseCtx = &play->pauseCtx; u8* curTexture; s32 vtxIndex; @@ -88,7 +88,7 @@ void KaleidoScope_DrawEquipmentImage(PlayState* play, void* source, u32 width, u gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_POINT); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha); - curTexture = source; + curTexture = texture; remainingSize = width * height * G_IM_SIZ_16b_BYTES; textureHeight = TMEM_SIZE / (width * G_IM_SIZ_16b_BYTES); textureSize = width * textureHeight * G_IM_SIZ_16b_BYTES; @@ -697,7 +697,7 @@ void KaleidoScope_DrawEquipment(PlayState* play) { #endif } - gSPSegment(POLY_OPA_DISP++, 0x07, pauseCtx->playerSegment); + gSPSegment(POLY_OPA_DISP++, 0x07, PAUSE_PLAYER_SEGMENT_TEXTURE(pauseCtx->playerSegment)); gSPSegment(POLY_OPA_DISP++, 0x08, pauseCtx->iconItemSegment); gSPSegment(POLY_OPA_DISP++, 0x09, pauseCtx->iconItem24Segment); gSPSegment(POLY_OPA_DISP++, 0x0A, pauseCtx->nameSegment); @@ -707,7 +707,8 @@ void KaleidoScope_DrawEquipment(PlayState* play) { // Draw player prerender onto the equip page Gfx_SetupDL_42Opa(play->state.gfxCtx); - KaleidoScope_DrawEquipmentImage(play, pauseCtx->playerSegment, PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT); + KaleidoScope_DrawEquipmentImage(play, PAUSE_PLAYER_SEGMENT_TEXTURE(pauseCtx->playerSegment), + PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT); CLOSE_DISPS(play->state.gfxCtx, "../z_kaleido_equipment.c", 609); } diff --git a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.c b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.c index f43b3d627cd..b3016562623 100644 --- a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.c +++ b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.c @@ -3431,7 +3431,7 @@ void KaleidoScope_Draw(PlayState* play) { pauseCtx->stickAdjY = input->rel.stick_y; gSPSegment(POLY_OPA_DISP++, 0x02, interfaceCtx->parameterSegment); - gSPSegment(POLY_OPA_DISP++, 0x07, pauseCtx->playerSegment); + gSPSegment(POLY_OPA_DISP++, 0x07, PAUSE_PLAYER_SEGMENT_TEXTURE(pauseCtx->playerSegment)); gSPSegment(POLY_OPA_DISP++, 0x08, pauseCtx->iconItemSegment); gSPSegment(POLY_OPA_DISP++, 0x09, pauseCtx->iconItem24Segment); gSPSegment(POLY_OPA_DISP++, 0x0A, pauseCtx->nameSegment); @@ -3881,7 +3881,7 @@ void KaleidoScope_Update(PlayState* play) { PreRender_Init(&sPlayerPreRender); PreRender_SetValuesSave(&sPlayerPreRender, PAUSE_EQUIP_PLAYER_WIDTH, PAUSE_EQUIP_PLAYER_HEIGHT, - pauseCtx->playerSegment, NULL, sPreRenderCvg); + PAUSE_PLAYER_SEGMENT_TEXTURE(pauseCtx->playerSegment), NULL, sPreRenderCvg); KaleidoScope_DrawPlayerWork(play); KaleidoScope_SetupPlayerPreRender(play);