mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2024-11-07 15:15:05 +01:00
1524 lines
70 KiB
C
1524 lines
70 KiB
C
#include "patches.h"
|
|
#include "buffers.h"
|
|
#include "sys_cfb.h"
|
|
#include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h"
|
|
|
|
// This moves elements towards the screen edges when increased
|
|
s32 margin_reduction = 8;
|
|
|
|
// Modified to enable RT64 extended GBI mode
|
|
void Graph_SetNextGfxPool(GraphicsContext* gfxCtx) {
|
|
GfxPool* pool = &gGfxPools[gfxCtx->gfxPoolIdx % 2];
|
|
|
|
gGfxMasterDL = &pool->master;
|
|
gSegments[0x0E] = (uintptr_t)gGfxMasterDL;
|
|
|
|
pool->headMagic = GFXPOOL_HEAD_MAGIC;
|
|
pool->tailMagic = GFXPOOL_TAIL_MAGIC;
|
|
|
|
Graph_InitTHGA(&gfxCtx->polyOpa, pool->polyOpaBuffer, sizeof(pool->polyOpaBuffer));
|
|
Graph_InitTHGA(&gfxCtx->polyXlu, pool->polyXluBuffer, sizeof(pool->polyXluBuffer));
|
|
Graph_InitTHGA(&gfxCtx->overlay, pool->overlayBuffer, sizeof(pool->overlayBuffer));
|
|
Graph_InitTHGA(&gfxCtx->work, pool->workBuffer, sizeof(pool->workBuffer));
|
|
Graph_InitTHGA(&gfxCtx->debug, pool->debugBuffer, sizeof(pool->debugBuffer));
|
|
|
|
gfxCtx->polyOpaBuffer = pool->polyOpaBuffer;
|
|
gfxCtx->polyXluBuffer = pool->polyXluBuffer;
|
|
gfxCtx->overlayBuffer = pool->overlayBuffer;
|
|
gfxCtx->workBuffer = pool->workBuffer;
|
|
gfxCtx->debugBuffer = pool->debugBuffer;
|
|
|
|
gfxCtx->curFrameBuffer = SysCfb_GetFramebuffer(gfxCtx->framebufferIndex % 2);
|
|
gSegments[0x0F] = (uintptr_t)gfxCtx->curFrameBuffer;
|
|
|
|
gfxCtx->zbuffer = SysCfb_GetZBuffer();
|
|
|
|
gSPBranchList(&gGfxMasterDL->disps[0], pool->polyOpaBuffer);
|
|
gSPBranchList(&gGfxMasterDL->disps[1], pool->polyXluBuffer);
|
|
gSPBranchList(&gGfxMasterDL->disps[2], pool->overlayBuffer);
|
|
gSPBranchList(&gGfxMasterDL->disps[3], pool->workBuffer);
|
|
gSPEndDisplayList(&gGfxMasterDL->disps[4]);
|
|
gSPBranchList(&gGfxMasterDL->debugDisp[0], pool->debugBuffer);
|
|
|
|
// Enable RT64 extended GBI mode
|
|
OPEN_DISPS(gfxCtx);
|
|
gEXEnable(POLY_OPA_DISP++);
|
|
// gEXPrint(POLY_OPA_DISP++);
|
|
CLOSE_DISPS(gfxCtx);
|
|
}
|
|
|
|
// Adjusts an x-coordinate to the relative to be given origin
|
|
s16 adjust_x(s16 xPos, u32 origin) {
|
|
switch (origin) {
|
|
default:
|
|
return xPos - margin_reduction;
|
|
case G_EX_ORIGIN_RIGHT:
|
|
return xPos - SCREEN_WIDTH + margin_reduction;
|
|
case G_EX_ORIGIN_CENTER:
|
|
return xPos - (SCREEN_WIDTH / 2);
|
|
}
|
|
}
|
|
|
|
// Adjusts an x-coordinate with 2 fractional bits to be relative to the given origin
|
|
s16 adjust_x_fractional(s16 xPos, u32 origin) {
|
|
switch (origin) {
|
|
default:
|
|
return xPos - (margin_reduction << 2);
|
|
case G_EX_ORIGIN_RIGHT:
|
|
return xPos - (SCREEN_WIDTH << 2) + (margin_reduction << 2);
|
|
case G_EX_ORIGIN_CENTER:
|
|
return xPos - ((SCREEN_WIDTH / 2) << 2);
|
|
}
|
|
}
|
|
|
|
typedef enum {
|
|
Y_ORIGIN_TOP,
|
|
Y_ORIGIN_CENTER,
|
|
Y_ORIGIN_BOTTOM
|
|
} YOrigin;
|
|
|
|
// Adjusts a top y-coordinate to be relative to the given origin
|
|
s16 adjust_y(s16 yPos, YOrigin origin) {
|
|
switch (origin) {
|
|
default:
|
|
return yPos - margin_reduction;
|
|
case Y_ORIGIN_CENTER:
|
|
return yPos;
|
|
case Y_ORIGIN_BOTTOM:
|
|
return yPos + margin_reduction;
|
|
}
|
|
}
|
|
|
|
// Adjusts a y-coordinate with 2 fractional bits to be relative to the given origin
|
|
s16 adjust_y_fractional(s16 yPos, YOrigin origin) {
|
|
switch (origin) {
|
|
default:
|
|
return yPos - (margin_reduction << 2);
|
|
case Y_ORIGIN_CENTER:
|
|
return yPos;
|
|
case Y_ORIGIN_BOTTOM:
|
|
return yPos + (margin_reduction << 2);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draw an IA8 texture on a rectangle with a shadow slightly offset to the bottom-right
|
|
*
|
|
* @param gfx the display list pointer
|
|
* @param texture
|
|
* @param textureWidth texture image width in texels
|
|
* @param textureHeight texture image height in texels
|
|
* @param rectLeft the x-coordinate of upper-left corner of rectangle
|
|
* @param rectTop the y-coordinate of upper-left corner of rectangle
|
|
* @param rectWidth rectangle width in texels
|
|
* @param rectHeight rectangle height in texels
|
|
* @param dsdx the change in s for each change in x (s5.10)
|
|
* @param dtdy the change in t for each change in y (s5.10)
|
|
* @param r texture red
|
|
* @param g texture green
|
|
* @param b texture blue
|
|
* @param a texture alpha
|
|
* @return Gfx* the display list pointer
|
|
*/
|
|
Gfx* GfxEx_DrawTexRectIA8_DropShadow(Gfx* gfx, TexturePtr texture, s16 textureWidth, s16 textureHeight, s16 rectLeft,
|
|
s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy, s16 r, s16 g, s16 b,
|
|
s16 a, u32 origin_x, u32 origin_y) {
|
|
s16 dropShadowAlpha = a;
|
|
|
|
if (a > 100) {
|
|
dropShadowAlpha = 100;
|
|
}
|
|
|
|
rectLeft = adjust_x(rectLeft, origin_x);
|
|
rectTop = adjust_x(rectTop, origin_y);
|
|
|
|
gDPPipeSync(gfx++);
|
|
gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, dropShadowAlpha);
|
|
|
|
gDPLoadTextureBlock(gfx++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, textureWidth, textureHeight, 0,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
|
G_TX_NOLOD);
|
|
|
|
gEXTextureRectangle(gfx++, origin_x, origin_x, (rectLeft + 2) * 4, (rectTop + 2) * 4, (rectLeft + rectWidth + 2) * 4,
|
|
(rectTop + rectHeight + 2) * 4, G_TX_RENDERTILE, 0, 0, dsdx, dtdy);
|
|
|
|
gDPPipeSync(gfx++);
|
|
gDPSetPrimColor(gfx++, 0, 0, r, g, b, a);
|
|
|
|
gEXTextureRectangle(gfx++, origin_x, origin_x, rectLeft * 4, rectTop * 4, (rectLeft + rectWidth) * 4, (rectTop + rectHeight) * 4,
|
|
G_TX_RENDERTILE, 0, 0, dsdx, dtdy);
|
|
|
|
return gfx;
|
|
}
|
|
|
|
/**
|
|
* Draw a colored rectangle with a shadow slightly offset to the bottom-right
|
|
*
|
|
* @param gfx the display list pointer
|
|
* @param rectLeft the x-coordinate of upper-left corner of rectangle
|
|
* @param rectTop the y-coordinate of upper-left corner of rectangle
|
|
* @param rectWidth rectangle width in texels
|
|
* @param rectHeight rectangle height in texels
|
|
* @param dsdx the change in s for each change in x (s5.10)
|
|
* @param dtdy the change in t for each change in y (s5.10)
|
|
* @param r // rectangle red
|
|
* @param g // rectangle green
|
|
* @param b // rectangle blue
|
|
* @param a // rectangle alpha
|
|
* @return Gfx* the display list pointer
|
|
*/
|
|
Gfx* GfxEx_DrawRect_DropShadow(Gfx* gfx, s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy,
|
|
s16 r, s16 g, s16 b, s16 a, u32 origin_x, u32 origin_y) {
|
|
s16 dropShadowAlpha = a;
|
|
|
|
if (a > 100) {
|
|
dropShadowAlpha = 100;
|
|
}
|
|
|
|
rectLeft = adjust_x(rectLeft, origin_x);
|
|
rectTop = adjust_x(rectTop, origin_y);
|
|
|
|
gDPPipeSync(gfx++);
|
|
gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, dropShadowAlpha);
|
|
gEXTextureRectangle(gfx++, origin_x, origin_x, (rectLeft + 2) * 4, (rectTop + 2) * 4, (rectLeft + rectWidth + 2) * 4,
|
|
(rectTop + rectHeight + 2) * 4, G_TX_RENDERTILE, 0, 0, dsdx, dtdy);
|
|
|
|
gDPPipeSync(gfx++);
|
|
gDPSetPrimColor(gfx++, 0, 0, r, g, b, a);
|
|
|
|
gEXTextureRectangle(gfx++, origin_x, origin_x, rectLeft * 4, rectTop * 4, (rectLeft + rectWidth) * 4, (rectTop + rectHeight) * 4,
|
|
G_TX_RENDERTILE, 0, 0, dsdx, dtdy);
|
|
|
|
return gfx;
|
|
}
|
|
|
|
|
|
/**
|
|
* Draw an IA8 texture on a rectangle with a shadow slightly offset to the bottom-right with additional texture offsets
|
|
*
|
|
* @param gfx the display list pointer
|
|
* @param texture
|
|
* @param textureWidth texture image width in texels
|
|
* @param textureHeight texture image height in texels
|
|
* @param rectLeft the x-coordinate of upper-left corner of rectangle
|
|
* @param rectTop the y-coordinate of upper-left corner of rectangle
|
|
* @param rectWidth rectangle width in texels
|
|
* @param rectHeight rectangle height in texels
|
|
* @param dsdx the change in s for each change in x (s5.10)
|
|
* @param dtdy the change in t for each change in y (s5.10)
|
|
* @param r // texture red
|
|
* @param g // texture green
|
|
* @param b // texture blue
|
|
* @param a // texture alpha
|
|
* @param masks specify the mask for the s axis
|
|
* @param rects the texture coordinate s of upper-left corner of rectangle (s10.5)
|
|
* @return Gfx* the display list pointer
|
|
*/
|
|
Gfx* GfxEx_DrawTexRectIA8_DropShadowOffset(Gfx* gfx, TexturePtr texture, s16 textureWidth, s16 textureHeight,
|
|
s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy,
|
|
s16 r, s16 g, s16 b, s16 a, s32 masks, s32 rects, u32 origin_x, u32 origin_y) {
|
|
s16 dropShadowAlpha = a;
|
|
|
|
if (a > 100) {
|
|
dropShadowAlpha = 100;
|
|
}
|
|
|
|
rectLeft = adjust_x(rectLeft, origin_x);
|
|
rectTop = adjust_x(rectTop, origin_y);
|
|
|
|
gDPPipeSync(gfx++);
|
|
gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, dropShadowAlpha);
|
|
|
|
gDPLoadTextureBlock(gfx++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, textureWidth, textureHeight, 0,
|
|
G_TX_MIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, masks, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
|
|
|
gEXTextureRectangle(gfx++, origin_x, origin_x, (rectLeft + 2) * 4, (rectTop + 2) * 4, (rectLeft + rectWidth + 2) * 4,
|
|
(rectTop + rectHeight + 2) * 4, G_TX_RENDERTILE, rects, 0, dsdx, dtdy);
|
|
|
|
gDPPipeSync(gfx++);
|
|
gDPSetPrimColor(gfx++, 0, 0, r, g, b, a);
|
|
|
|
gEXTextureRectangle(gfx++, origin_x, origin_x, rectLeft * 4, rectTop * 4, (rectLeft + rectWidth) * 4, (rectTop + rectHeight) * 4,
|
|
G_TX_RENDERTILE, rects, 0, dsdx, dtdy);
|
|
|
|
return gfx;
|
|
}
|
|
|
|
/**
|
|
* Draw an IA8 texture on a rectangle
|
|
*
|
|
* @param gfx the display list pointer
|
|
* @param texture
|
|
* @param textureWidth texture image width in texels
|
|
* @param textureHeight texture image height in texels
|
|
* @param rectLeft the x-coordinate of upper-left corner of rectangle
|
|
* @param rectTop the y-coordinate of upper-left corner of rectangle
|
|
* @param rectWidth rectangle width in texels
|
|
* @param rectHeight rectangle height in texels
|
|
* @param dsdx the change in s for each change in x (s5.10)
|
|
* @param dtdy the change in t for each change in y (s5.10)
|
|
* @return Gfx* the display list pointer
|
|
*/
|
|
Gfx* GfxEx_DrawTexRectIA8(Gfx* gfx, TexturePtr texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop,
|
|
s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy, u32 origin_x, u32 origin_y) {
|
|
gDPLoadTextureBlock(gfx++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, textureWidth, textureHeight, 0,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
|
G_TX_NOLOD);
|
|
|
|
rectLeft = adjust_x(rectLeft, origin_x);
|
|
rectTop = adjust_y(rectTop, origin_y);
|
|
|
|
gEXTextureRectangle(gfx++, origin_x, origin_x, rectLeft << 2, rectTop << 2, (rectLeft + rectWidth) << 2, (rectTop + rectHeight) << 2,
|
|
G_TX_RENDERTILE, 0, 0, dsdx, dtdy);
|
|
|
|
return gfx;
|
|
}
|
|
|
|
/**
|
|
* Draw an I8 texture on a rectangle
|
|
*
|
|
* @param gfx the display list pointer
|
|
* @param texture
|
|
* @param textureWidth texture image width in texels
|
|
* @param textureHeight texture image height in texels
|
|
* @param rectLeft the x-coordinate of upper-left corner of rectangle
|
|
* @param rectTop the y-coordinate of upper-left corner of rectangle
|
|
* @param rectWidth rectangle width in texels
|
|
* @param rectHeight rectangle height in texels
|
|
* @param dsdx the change in s for each change in x (s5.10)
|
|
* @param dtdy the change in t for each change in y (s5.10)
|
|
* @return Gfx* the display list pointer
|
|
*/
|
|
Gfx* GfxEx_DrawTexRectI8(Gfx* gfx, TexturePtr texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop,
|
|
s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy, u32 origin_x, u32 origin_y) {
|
|
gDPLoadTextureBlock(gfx++, texture, G_IM_FMT_I, G_IM_SIZ_8b, textureWidth, textureHeight, 0,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
|
G_TX_NOLOD);
|
|
|
|
rectLeft = adjust_x(rectLeft, origin_x);
|
|
rectTop = adjust_y(rectTop, origin_y);
|
|
|
|
gEXTextureRectangle(gfx++, origin_x, origin_x, rectLeft << 2, rectTop << 2, (rectLeft + rectWidth) << 2, (rectTop + rectHeight) << 2,
|
|
G_TX_RENDERTILE, 0, 0, dsdx, dtdy);
|
|
|
|
return gfx;
|
|
}
|
|
|
|
extern u8 gTatlCUpENGTex[];
|
|
extern u8 gTatlCUpGERTex[];
|
|
extern u8 gTatlCUpFRATex[];
|
|
extern u8 gTatlCUpESPTex[];
|
|
extern u8 gButtonBackgroundTex[];
|
|
extern s16 D_801BF9D4[];
|
|
extern s16 D_801BF9DC[];
|
|
extern s16 D_801BF9E4[];
|
|
extern s16 D_801BF9BC[];
|
|
extern u8 gAmmoDigit0Tex[];
|
|
|
|
typedef enum {
|
|
/* 0 */ PICTO_BOX_STATE_OFF, // Not using the pictograph
|
|
/* 1 */ PICTO_BOX_STATE_LENS, // Looking through the lens of the pictograph
|
|
/* 2 */ PICTO_BOX_STATE_SETUP_PHOTO, // Looking at the photo currently taken
|
|
/* 3 */ PICTO_BOX_STATE_PHOTO
|
|
} PictoBoxState;
|
|
|
|
extern s16 sPictoState;
|
|
extern u16 sCUpInvisible;
|
|
extern u16 sCUpTimer;
|
|
|
|
#define DO_ACTION_TEX_WIDTH 48
|
|
#define DO_ACTION_TEX_HEIGHT 16
|
|
#define DO_ACTION_TEX_SIZE ((DO_ACTION_TEX_WIDTH * DO_ACTION_TEX_HEIGHT) / 2)
|
|
|
|
// Modify item button drawing to use the extended GBI texture rectangles for widescreen support
|
|
void Interface_DrawItemButtons(PlayState* play) {
|
|
static TexturePtr cUpLabelTextures[] = {
|
|
gTatlCUpENGTex, gTatlCUpENGTex, gTatlCUpGERTex, gTatlCUpFRATex, gTatlCUpESPTex,
|
|
};
|
|
static s16 startButtonLeftPos[] = {
|
|
// Remnant of OoT
|
|
130, 136, 136, 136, 136,
|
|
};
|
|
static s16 D_801BFAF4[] = {
|
|
0x1D, // EQUIP_SLOT_B
|
|
0x1B, // EQUIP_SLOT_C_LEFT
|
|
0x1B, // EQUIP_SLOT_C_DOWN
|
|
0x1B, // EQUIP_SLOT_C_RIGHT
|
|
};
|
|
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
|
Player* player = GET_PLAYER(play);
|
|
PauseContext* pauseCtx = &play->pauseCtx;
|
|
MessageContext* msgCtx = &play->msgCtx;
|
|
s16 temp; // Used as both an alpha value and a button index
|
|
s32 pad;
|
|
|
|
OPEN_DISPS(play->state.gfxCtx);
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
|
|
|
// B Button Color & Texture
|
|
OVERLAY_DISP = GfxEx_DrawTexRectIA8_DropShadow(
|
|
OVERLAY_DISP, gButtonBackgroundTex, 0x20, 0x20, D_801BF9D4[EQUIP_SLOT_B], D_801BF9DC[EQUIP_SLOT_B],
|
|
D_801BFAF4[EQUIP_SLOT_B], D_801BFAF4[EQUIP_SLOT_B], D_801BF9E4[EQUIP_SLOT_B] * 2, D_801BF9E4[EQUIP_SLOT_B] * 2,
|
|
100, 255, 120, interfaceCtx->bAlpha, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
|
|
// C-Left Button Color & Texture
|
|
OVERLAY_DISP = GfxEx_DrawRect_DropShadow(OVERLAY_DISP, D_801BF9D4[EQUIP_SLOT_C_LEFT], D_801BF9DC[EQUIP_SLOT_C_LEFT],
|
|
D_801BFAF4[EQUIP_SLOT_C_LEFT], D_801BFAF4[EQUIP_SLOT_C_LEFT],
|
|
D_801BF9E4[EQUIP_SLOT_C_LEFT] * 2, D_801BF9E4[EQUIP_SLOT_C_LEFT] * 2, 255,
|
|
240, 0, interfaceCtx->cLeftAlpha, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
// C-Down Button Color & Texture
|
|
OVERLAY_DISP = GfxEx_DrawRect_DropShadow(OVERLAY_DISP, D_801BF9D4[EQUIP_SLOT_C_DOWN], D_801BF9DC[EQUIP_SLOT_C_DOWN],
|
|
D_801BFAF4[EQUIP_SLOT_C_DOWN], D_801BFAF4[EQUIP_SLOT_C_DOWN],
|
|
D_801BF9E4[EQUIP_SLOT_C_DOWN] * 2, D_801BF9E4[EQUIP_SLOT_C_DOWN] * 2, 255,
|
|
240, 0, interfaceCtx->cDownAlpha, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
// C-Right Button Color & Texture
|
|
OVERLAY_DISP = GfxEx_DrawRect_DropShadow(OVERLAY_DISP, D_801BF9D4[EQUIP_SLOT_C_RIGHT], D_801BF9DC[EQUIP_SLOT_C_RIGHT],
|
|
D_801BFAF4[EQUIP_SLOT_C_RIGHT], D_801BFAF4[EQUIP_SLOT_C_RIGHT],
|
|
D_801BF9E4[EQUIP_SLOT_C_RIGHT] * 2, D_801BF9E4[EQUIP_SLOT_C_RIGHT] * 2, 255,
|
|
240, 0, interfaceCtx->cRightAlpha, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
|
|
if (!IS_PAUSE_STATE_GAMEOVER) {
|
|
if ((play->pauseCtx.state != PAUSE_STATE_OFF) || (play->pauseCtx.debugEditor != DEBUG_EDITOR_NONE)) {
|
|
OVERLAY_DISP = GfxEx_DrawRect_DropShadow(OVERLAY_DISP, 0x88, 0x11, 0x16, 0x16, 0x5B6, 0x5B6, 0xFF, 0x82, 0x3C,
|
|
interfaceCtx->startAlpha, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
// Start Button Texture, Color & Label
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->startAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 0);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0,
|
|
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
|
|
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE * 2, G_IM_FMT_IA,
|
|
DO_ACTION_TEX_WIDTH, DO_ACTION_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_RIGHT, G_EX_ORIGIN_RIGHT,
|
|
adjust_x(126, G_EX_ORIGIN_RIGHT) * 4, adjust_y(21, Y_ORIGIN_TOP) * 4,
|
|
adjust_x(181, G_EX_ORIGIN_RIGHT) * 4, adjust_y(39, Y_ORIGIN_TOP) * 4,
|
|
G_TX_RENDERTILE, 0, 0, 0x04A6, 0x04A6);
|
|
}
|
|
}
|
|
|
|
if (interfaceCtx->tatlCalling && (play->pauseCtx.state == PAUSE_STATE_OFF) &&
|
|
(play->pauseCtx.debugEditor == DEBUG_EDITOR_NONE) && (play->csCtx.state == CS_STATE_IDLE) &&
|
|
(sPictoState == PICTO_BOX_STATE_OFF)) {
|
|
if (sCUpInvisible == 0) {
|
|
// C-Up Button Texture, Color & Label (Tatl Text)
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
|
|
if ((gSaveContext.hudVisibility == HUD_VISIBILITY_NONE) ||
|
|
(gSaveContext.hudVisibility == HUD_VISIBILITY_NONE_ALT) ||
|
|
(gSaveContext.hudVisibility == HUD_VISIBILITY_A_HEARTS_MAGIC_WITH_OVERWRITE) ||
|
|
(msgCtx->msgMode != MSGMODE_NONE)) {
|
|
temp = 0;
|
|
} else if (player->stateFlags1 & PLAYER_STATE1_200000) {
|
|
temp = 70;
|
|
} else {
|
|
temp = interfaceCtx->aAlpha;
|
|
}
|
|
|
|
OVERLAY_DISP =
|
|
GfxEx_DrawRect_DropShadow(OVERLAY_DISP, 0xFE, 0x10, 0x10, 0x10, 0x800, 0x800, 0xFF, 0xF0, 0, temp, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, temp);
|
|
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 0);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0,
|
|
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
|
|
gDPLoadTextureBlock_4b(OVERLAY_DISP++, cUpLabelTextures[gSaveContext.options.language], G_IM_FMT_IA, 32, 12,
|
|
0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
|
G_TX_NOLOD, G_TX_NOLOD);
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_RIGHT, G_EX_ORIGIN_RIGHT,
|
|
adjust_x(247, G_EX_ORIGIN_RIGHT) * 4, adjust_y(18, Y_ORIGIN_TOP) * 4,
|
|
adjust_x(279, G_EX_ORIGIN_RIGHT) * 4, adjust_y(30, Y_ORIGIN_TOP) * 4, G_TX_RENDERTILE, 0, 0, 1 << 10,
|
|
1 << 10);
|
|
}
|
|
|
|
sCUpTimer--;
|
|
if (sCUpTimer == 0) {
|
|
sCUpInvisible ^= 1;
|
|
sCUpTimer = 10;
|
|
}
|
|
}
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
|
|
// Empty C Button Arrows
|
|
for (temp = EQUIP_SLOT_C_LEFT; temp <= EQUIP_SLOT_C_RIGHT; temp++) {
|
|
if (GET_CUR_FORM_BTN_ITEM(temp) > 0xF0) {
|
|
if (temp == EQUIP_SLOT_C_LEFT) {
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 240, 0, interfaceCtx->cLeftAlpha);
|
|
} else if (temp == EQUIP_SLOT_C_DOWN) {
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 240, 0, interfaceCtx->cDownAlpha);
|
|
} else { // EQUIP_SLOT_C_RIGHT
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 240, 0, interfaceCtx->cRightAlpha);
|
|
}
|
|
OVERLAY_DISP = GfxEx_DrawTexRectIA8(OVERLAY_DISP, ((u8*)gButtonBackgroundTex + ((32 * 32) * (temp + 1))),
|
|
0x20, 0x20, D_801BF9D4[temp], D_801BF9DC[temp], D_801BFAF4[temp],
|
|
D_801BFAF4[temp], D_801BF9E4[temp] * 2, D_801BF9E4[temp] * 2, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
}
|
|
}
|
|
|
|
CLOSE_DISPS(play->state.gfxCtx);
|
|
}
|
|
|
|
// Modify item icon drawing to use the extended GBI texture rectangles for widescreen support
|
|
void Interface_DrawItemIconTexture(PlayState* play, TexturePtr texture, s16 button) {
|
|
static s16 D_801BFAFC[] = { 30, 24, 24, 24 };
|
|
|
|
OPEN_DISPS(play->state.gfxCtx);
|
|
|
|
gDPLoadTextureBlock(OVERLAY_DISP++, texture, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
|
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_RIGHT, G_EX_ORIGIN_RIGHT,
|
|
adjust_x(D_801BF9D4[button], G_EX_ORIGIN_RIGHT) * 4, adjust_y(D_801BF9DC[button], Y_ORIGIN_TOP) * 4,
|
|
adjust_x(D_801BF9D4[button] + D_801BFAFC[button], G_EX_ORIGIN_RIGHT) * 4, adjust_y(D_801BF9DC[button] + D_801BFAFC[button], Y_ORIGIN_TOP) * 4,
|
|
G_TX_RENDERTILE, 0, 0, D_801BF9BC[button] << 1, D_801BF9BC[button] << 1);
|
|
|
|
CLOSE_DISPS(play->state.gfxCtx);
|
|
}
|
|
|
|
// Modify drawing A button for widescreen
|
|
extern f32 D_801BF9CC[];
|
|
|
|
void Interface_SetPerspectiveView(PlayState* play, s32 topY, s32 bottomY, s32 leftX, s32 rightX);
|
|
void View_ViewportToVp(Vp* dest, Viewport* src);
|
|
|
|
void ViewEx_SetScissor(Gfx** gfx, s32 ulx, s32 uly, s32 lrx, s32 lry, u32 lorigin, u32 rorigin) {
|
|
Gfx* gfxp = *gfx;
|
|
|
|
ulx = adjust_x(ulx, lorigin);
|
|
lrx = adjust_x(lrx, rorigin);
|
|
|
|
gEXSetScissor(gfxp++, G_SC_NON_INTERLACE, lorigin, rorigin, ulx, uly, lrx, lry);
|
|
|
|
*gfx = gfxp;
|
|
}
|
|
|
|
|
|
void View_SetScissor(Gfx** gfx, s32 ulx, s32 uly, s32 lrx, s32 lry);
|
|
|
|
/**
|
|
* Apply scissor, viewport, view and projection (perspective) to OVERLAY_DISP.
|
|
*/
|
|
s32 ViewEx_ApplyPerspectiveToOverlay(View* view, u32 origin_x, u32 origin_y) {
|
|
f32 aspect;
|
|
s32 width;
|
|
s32 height;
|
|
Vp* vp;
|
|
Mtx* projection;
|
|
Mtx* viewing;
|
|
GraphicsContext* gfxCtx;
|
|
s32 pad;
|
|
|
|
gfxCtx = view->gfxCtx;
|
|
|
|
OPEN_DISPS(gfxCtx);
|
|
|
|
vp = GRAPH_ALLOC(gfxCtx, sizeof(Vp));
|
|
View_ViewportToVp(vp, &view->viewport);
|
|
view->vp = *vp;
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
{
|
|
s32 pad;
|
|
Gfx* overlay;
|
|
|
|
overlay = OVERLAY_DISP;
|
|
ViewEx_SetScissor(&overlay, view->viewport.leftX, view->viewport.topY, view->viewport.rightX,
|
|
view->viewport.bottomY, origin_x, origin_x);
|
|
OVERLAY_DISP = overlay;
|
|
}
|
|
|
|
vp->vp.vtrans[0] = adjust_x_fractional(vp->vp.vtrans[0], origin_x);
|
|
vp->vp.vtrans[1] = adjust_y_fractional(vp->vp.vtrans[1], origin_y);
|
|
|
|
gEXViewport(OVERLAY_DISP++, origin_x, vp);
|
|
projection = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
|
view->projectionPtr = projection;
|
|
|
|
width = view->viewport.rightX - view->viewport.leftX;
|
|
height = view->viewport.bottomY - view->viewport.topY;
|
|
aspect = (f32)width / (f32)height;
|
|
|
|
guPerspective(projection, &view->perspNorm, view->fovy, aspect, view->zNear, view->zFar, view->scale);
|
|
|
|
view->projection = *projection;
|
|
|
|
gSPPerspNormalize(OVERLAY_DISP++, view->perspNorm);
|
|
gSPMatrix(OVERLAY_DISP++, projection, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
|
|
|
viewing = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
|
view->viewingPtr = viewing;
|
|
|
|
// This check avoids a divide-by-zero in guLookAt if eye == at
|
|
if (view->eye.x == view->at.x && view->eye.y == view->at.y && view->eye.z == view->at.z) {
|
|
view->eye.z += 2.0f;
|
|
}
|
|
|
|
guLookAt(viewing, view->eye.x, view->eye.y, view->eye.z, view->at.x, view->at.y, view->at.z, view->up.x, view->up.y,
|
|
view->up.z);
|
|
|
|
view->viewing = *viewing;
|
|
|
|
gSPMatrix(OVERLAY_DISP++, viewing, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_PROJECTION);
|
|
|
|
CLOSE_DISPS(gfxCtx);
|
|
|
|
return 1;
|
|
}
|
|
|
|
void InterfaceEx_SetPerspectiveView(PlayState* play, s32 topY, s32 bottomY, s32 leftX, s32 rightX, u32 origin_x, u32 origin_y) {
|
|
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
|
Vec3f eye;
|
|
Vec3f at;
|
|
Vec3f up;
|
|
|
|
eye.x = eye.y = eye.z = 0.0f;
|
|
at.x = at.y = 0.0f;
|
|
at.z = -1.0f;
|
|
up.x = up.z = 0.0f;
|
|
up.y = 1.0f;
|
|
|
|
View_LookAt(&interfaceCtx->view, &eye, &at, &up);
|
|
|
|
interfaceCtx->viewport.topY = topY;
|
|
interfaceCtx->viewport.bottomY = bottomY;
|
|
interfaceCtx->viewport.leftX = leftX;
|
|
interfaceCtx->viewport.rightX = rightX;
|
|
View_SetViewport(&interfaceCtx->view, &interfaceCtx->viewport);
|
|
|
|
View_SetPerspective(&interfaceCtx->view, 60.0f, 10.0f, 60.0f);
|
|
ViewEx_ApplyPerspectiveToOverlay(&interfaceCtx->view, origin_x, origin_y);
|
|
}
|
|
|
|
void Interface_DrawAButton(PlayState* play) {
|
|
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
|
s16 aAlpha;
|
|
|
|
OPEN_DISPS(play->state.gfxCtx);
|
|
|
|
aAlpha = interfaceCtx->aAlpha;
|
|
|
|
if (aAlpha > 100) {
|
|
aAlpha = 100;
|
|
}
|
|
|
|
Gfx_SetupDL42_Overlay(play->state.gfxCtx);
|
|
|
|
InterfaceEx_SetPerspectiveView(play, 25 + R_A_BTN_Y_OFFSET, 70 + R_A_BTN_Y_OFFSET, 192, 237, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
|
|
gSPClearGeometryMode(OVERLAY_DISP++, G_CULL_BOTH);
|
|
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
|
gDPSetAlphaCompare(OVERLAY_DISP++, G_AC_THRESHOLD);
|
|
|
|
Matrix_Translate(0.0f, 0.0f, -38.0f, MTXMODE_NEW);
|
|
Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
|
|
Matrix_RotateXFApply(interfaceCtx->aButtonRoll / 10000.0f);
|
|
|
|
// Draw A button Shadow
|
|
gSPMatrix(OVERLAY_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gSPVertex(OVERLAY_DISP++, &interfaceCtx->actionVtx[4], 4, 0);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, aAlpha);
|
|
|
|
OVERLAY_DISP = Gfx_DrawTexQuadIA8(OVERLAY_DISP, gButtonBackgroundTex, 32, 32, 0);
|
|
|
|
// Draw A Button Colored
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
InterfaceEx_SetPerspectiveView(play, 23 + R_A_BTN_Y_OFFSET, 68 + R_A_BTN_Y_OFFSET, 190, 235, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
gSPVertex(OVERLAY_DISP++, &interfaceCtx->actionVtx[0], 4, 0);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 100, 200, 255, interfaceCtx->aAlpha);
|
|
gSP1Quadrangle(OVERLAY_DISP++, 0, 2, 3, 1, 0);
|
|
|
|
// Draw A Button Do-Action
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
InterfaceEx_SetPerspectiveView(play, 23 + R_A_BTN_Y_OFFSET, 68 + R_A_BTN_Y_OFFSET, 190, 235, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
gSPSetGeometryMode(OVERLAY_DISP++, G_CULL_BACK);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE,
|
|
ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->aAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 0);
|
|
|
|
Matrix_Translate(0.0f, 0.0f, D_801BF9CC[gSaveContext.options.language] / 10.0f, MTXMODE_NEW);
|
|
Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
|
|
Matrix_RotateXFApply(interfaceCtx->aButtonRoll / 10000.0f);
|
|
gSPMatrix(OVERLAY_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPVertex(OVERLAY_DISP++, &interfaceCtx->actionVtx[8], 4, 0);
|
|
|
|
// Draw Action Label
|
|
if (((interfaceCtx->aButtonState <= A_BTN_STATE_1) || (interfaceCtx->aButtonState == A_BTN_STATE_3))) {
|
|
OVERLAY_DISP = Gfx_DrawTexQuad4b(OVERLAY_DISP, interfaceCtx->doActionSegment, 3, DO_ACTION_TEX_WIDTH,
|
|
DO_ACTION_TEX_HEIGHT, 0);
|
|
} else {
|
|
OVERLAY_DISP = Gfx_DrawTexQuad4b(OVERLAY_DISP, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE, 3,
|
|
DO_ACTION_TEX_WIDTH, DO_ACTION_TEX_HEIGHT, 0);
|
|
}
|
|
|
|
CLOSE_DISPS(play->state.gfxCtx);
|
|
}
|
|
|
|
extern s16 D_801BFB04[];
|
|
extern s16 D_801BFB0C[];
|
|
|
|
// Modify item ammo count drawing to use the extended GBI texture rectangles for widescreen support
|
|
void Interface_DrawAmmoCount(PlayState* play, s16 button, s16 alpha) {
|
|
u8 i;
|
|
u16 ammo;
|
|
|
|
OPEN_DISPS(play->state.gfxCtx);
|
|
|
|
i = ((void)0, GET_CUR_FORM_BTN_ITEM(button));
|
|
|
|
if ((i == ITEM_DEKU_STICK) || (i == ITEM_DEKU_NUT) || (i == ITEM_BOMB) || (i == ITEM_BOW) ||
|
|
((i >= ITEM_BOW_FIRE) && (i <= ITEM_BOW_LIGHT)) || (i == ITEM_BOMBCHU) || (i == ITEM_POWDER_KEG) ||
|
|
(i == ITEM_MAGIC_BEANS) || (i == ITEM_PICTOGRAPH_BOX)) {
|
|
|
|
if ((i >= ITEM_BOW_FIRE) && (i <= ITEM_BOW_LIGHT)) {
|
|
i = ITEM_BOW;
|
|
}
|
|
|
|
ammo = AMMO(i);
|
|
|
|
if (i == ITEM_PICTOGRAPH_BOX) {
|
|
if (!CHECK_QUEST_ITEM(QUEST_PICTOGRAPH)) {
|
|
ammo = 0;
|
|
} else {
|
|
ammo = 1;
|
|
}
|
|
}
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
|
|
if ((button == EQUIP_SLOT_B) && (gSaveContext.minigameStatus == MINIGAME_STATUS_ACTIVE)) {
|
|
ammo = play->interfaceCtx.minigameAmmo;
|
|
} else if ((button == EQUIP_SLOT_B) && (play->unk_1887C > 1)) {
|
|
ammo = play->unk_1887C - 1;
|
|
} else if (((i == ITEM_BOW) && (AMMO(i) == CUR_CAPACITY(UPG_QUIVER))) ||
|
|
((i == ITEM_BOMB) && (AMMO(i) == CUR_CAPACITY(UPG_BOMB_BAG))) ||
|
|
((i == ITEM_DEKU_STICK) && (AMMO(i) == CUR_CAPACITY(UPG_DEKU_STICKS))) ||
|
|
((i == ITEM_DEKU_NUT) && (AMMO(i) == CUR_CAPACITY(UPG_DEKU_NUTS))) ||
|
|
((i == ITEM_BOMBCHU) && (AMMO(i) == CUR_CAPACITY(UPG_BOMB_BAG))) ||
|
|
((i == ITEM_POWDER_KEG) && (ammo == 1)) || ((i == ITEM_PICTOGRAPH_BOX) && (ammo == 1)) ||
|
|
((i == ITEM_MAGIC_BEANS) && (ammo == 20))) {
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 120, 255, 0, alpha);
|
|
}
|
|
|
|
if ((u32)ammo == 0) {
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 100, 100, 100, alpha);
|
|
}
|
|
|
|
for (i = 0; ammo >= 10; i++) {
|
|
ammo -= 10;
|
|
}
|
|
|
|
// Draw upper digit (tens)
|
|
if ((u32)i != 0) {
|
|
OVERLAY_DISP = GfxEx_DrawTexRectIA8(OVERLAY_DISP, ((u8*)gAmmoDigit0Tex + ((8 * 8) * i)), 8, 8,
|
|
D_801BFB04[button], D_801BFB0C[button], 8, 8, 1 << 10, 1 << 10, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
}
|
|
|
|
// Draw lower digit (ones)
|
|
OVERLAY_DISP = GfxEx_DrawTexRectIA8(OVERLAY_DISP, ((u8*)gAmmoDigit0Tex + ((8 * 8) * ammo)), 8, 8,
|
|
D_801BFB04[button] + 6, D_801BFB0C[button], 8, 8, 1 << 10, 1 << 10, G_EX_ORIGIN_RIGHT, Y_ORIGIN_TOP);
|
|
}
|
|
|
|
CLOSE_DISPS(play->state.gfxCtx);
|
|
}
|
|
|
|
// Modify magic meter drawing
|
|
extern u8 gMagicMeterEndTex[];
|
|
extern u8 gMagicMeterFillTex[];
|
|
extern u8 gMagicMeterMidTex[];
|
|
|
|
extern s16 sMagicMeterOutlinePrimBlue;
|
|
extern s16 sMagicMeterOutlinePrimGreen;
|
|
extern s16 sMagicMeterOutlinePrimRed;
|
|
|
|
void Magic_DrawMeter(PlayState* play) {
|
|
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
|
s16 magicBarY;
|
|
|
|
OPEN_DISPS(play->state.gfxCtx);
|
|
|
|
if (gSaveContext.save.saveInfo.playerData.magicLevel != 0) {
|
|
if (gSaveContext.save.saveInfo.playerData.healthCapacity > 0xA0) {
|
|
magicBarY = 42; // two rows of hearts
|
|
} else {
|
|
magicBarY = 34; // one row of hearts
|
|
}
|
|
|
|
Gfx_SetupDL39_Overlay(play->state.gfxCtx);
|
|
|
|
gDPSetEnvColor(OVERLAY_DISP++, 100, 50, 50, 255);
|
|
|
|
OVERLAY_DISP = GfxEx_DrawTexRectIA8_DropShadow(
|
|
OVERLAY_DISP, gMagicMeterEndTex, 8, 16, 18, magicBarY, 8, 16, 1 << 10, 1 << 10, sMagicMeterOutlinePrimRed,
|
|
sMagicMeterOutlinePrimGreen, sMagicMeterOutlinePrimBlue, interfaceCtx->magicAlpha, G_EX_ORIGIN_LEFT, Y_ORIGIN_TOP);
|
|
OVERLAY_DISP = GfxEx_DrawTexRectIA8_DropShadow(OVERLAY_DISP, gMagicMeterMidTex, 24, 16, 26, magicBarY,
|
|
((void)0, gSaveContext.magicCapacity), 16, 1 << 10, 1 << 10,
|
|
sMagicMeterOutlinePrimRed, sMagicMeterOutlinePrimGreen,
|
|
sMagicMeterOutlinePrimBlue, interfaceCtx->magicAlpha, G_EX_ORIGIN_LEFT, Y_ORIGIN_TOP);
|
|
OVERLAY_DISP = GfxEx_DrawTexRectIA8_DropShadowOffset(
|
|
OVERLAY_DISP, gMagicMeterEndTex, 8, 16, ((void)0, gSaveContext.magicCapacity) + 26, magicBarY, 8, 16,
|
|
1 << 10, 1 << 10, sMagicMeterOutlinePrimRed, sMagicMeterOutlinePrimGreen, sMagicMeterOutlinePrimBlue,
|
|
interfaceCtx->magicAlpha, 3, 0x100, G_EX_ORIGIN_LEFT, Y_ORIGIN_TOP);
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, PRIMITIVE, PRIMITIVE,
|
|
ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, PRIMITIVE);
|
|
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255);
|
|
|
|
if (gSaveContext.magicState == MAGIC_STATE_METER_FLASH_2) {
|
|
// Yellow part of the meter indicating the amount of magic to be subtracted
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 250, 250, 0, interfaceCtx->magicAlpha);
|
|
gDPLoadTextureBlock_4b(OVERLAY_DISP++, gMagicMeterFillTex, G_IM_FMT_I, 16, 16, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT,
|
|
adjust_x(26, G_EX_ORIGIN_LEFT) * 4, adjust_y(magicBarY + 3, Y_ORIGIN_TOP) << 2,
|
|
adjust_x(gSaveContext.save.saveInfo.playerData.magic + 26, G_EX_ORIGIN_LEFT) * 4, adjust_y(magicBarY + 10, Y_ORIGIN_TOP) << 2,
|
|
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
|
|
// Fill the rest of the meter with the normal magic color
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_DRANK_CHATEAU_ROMANI)) {
|
|
// Blue magic
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 200, interfaceCtx->magicAlpha);
|
|
} else {
|
|
// Green magic (default)
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 200, 0, interfaceCtx->magicAlpha);
|
|
}
|
|
|
|
gEXTextureRectangle(
|
|
OVERLAY_DISP++, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT,
|
|
adjust_x(26, G_EX_ORIGIN_LEFT) * 4, adjust_y(magicBarY + 3, Y_ORIGIN_TOP) << 2,
|
|
adjust_x(gSaveContext.save.saveInfo.playerData.magic - gSaveContext.magicToConsume + 26, G_EX_ORIGIN_LEFT) * 4, adjust_y(magicBarY + 10, Y_ORIGIN_TOP) << 2,
|
|
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
} else {
|
|
// Fill the whole meter with the normal magic color
|
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_DRANK_CHATEAU_ROMANI)) {
|
|
// Blue magic
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 200, interfaceCtx->magicAlpha);
|
|
} else {
|
|
// Green magic (default)
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 200, 0, interfaceCtx->magicAlpha);
|
|
}
|
|
|
|
gDPLoadTextureBlock_4b(OVERLAY_DISP++, gMagicMeterFillTex, G_IM_FMT_I, 16, 16, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT,
|
|
adjust_x(26, G_EX_ORIGIN_LEFT) * 4, adjust_y(magicBarY + 3, Y_ORIGIN_TOP) << 2,
|
|
adjust_x(gSaveContext.save.saveInfo.playerData.magic + 26, G_EX_ORIGIN_LEFT) * 4, adjust_y(magicBarY + 10, Y_ORIGIN_TOP) << 2,
|
|
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
}
|
|
}
|
|
|
|
CLOSE_DISPS(play->state.gfxCtx);
|
|
}
|
|
|
|
// Modify life meter drawing
|
|
extern u8 gHeartEmptyTex[];
|
|
extern u8 gHeartFullTex[];
|
|
extern u8 gHeartHalfTex[];
|
|
extern u8 gHeartQuarterTex[];
|
|
extern u8 gHeartShapeTex[];
|
|
extern u8 gHeartThreeQuarterTex[];
|
|
|
|
static TexturePtr sHeartTextures[] = {
|
|
gHeartFullTex, gHeartQuarterTex, gHeartQuarterTex, gHeartQuarterTex,
|
|
gHeartQuarterTex, gHeartQuarterTex, gHeartHalfTex, gHeartHalfTex,
|
|
gHeartHalfTex, gHeartHalfTex, gHeartHalfTex, gHeartThreeQuarterTex,
|
|
gHeartThreeQuarterTex, gHeartThreeQuarterTex, gHeartThreeQuarterTex, gHeartThreeQuarterTex,
|
|
};
|
|
|
|
extern u8 gDefenseHeartEmptyTex[];
|
|
extern u8 gDefenseHeartFullTex[];
|
|
extern u8 gDefenseHeartHalfTex[];
|
|
extern u8 gDefenseHeartQuarterTex[];
|
|
extern u8 gDefenseHeartThreeQuarterTex[];
|
|
|
|
static TexturePtr sHeartDDTextures[] = {
|
|
gDefenseHeartFullTex, gDefenseHeartQuarterTex, gDefenseHeartQuarterTex,
|
|
gDefenseHeartQuarterTex, gDefenseHeartQuarterTex, gDefenseHeartQuarterTex,
|
|
gDefenseHeartHalfTex, gDefenseHeartHalfTex, gDefenseHeartHalfTex,
|
|
gDefenseHeartHalfTex, gDefenseHeartHalfTex, gDefenseHeartThreeQuarterTex,
|
|
gDefenseHeartThreeQuarterTex, gDefenseHeartThreeQuarterTex, gDefenseHeartThreeQuarterTex,
|
|
gDefenseHeartThreeQuarterTex,
|
|
};
|
|
|
|
extern s16 sBeatingHeartsDDPrim[3];
|
|
extern s16 sBeatingHeartsDDEnv[3];
|
|
extern s16 sHeartsDDPrim[2][3];
|
|
extern s16 sHeartsDDEnv[2][3];
|
|
|
|
void LifeMeter_Draw(PlayState* play) {
|
|
s32 pad[5];
|
|
TexturePtr heartTex;
|
|
s32 curColorSet;
|
|
f32 offsetX;
|
|
f32 offsetY;
|
|
s32 i;
|
|
f32 posY;
|
|
f32 posX;
|
|
f32 halfTexSize;
|
|
f32 temp_f4;
|
|
GraphicsContext* gfxCtx = play->state.gfxCtx;
|
|
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
|
Vtx* beatingHeartVtx = interfaceCtx->beatingHeartVtx;
|
|
s32 fractionHeartCount = gSaveContext.save.saveInfo.playerData.health % 0x10;
|
|
s16 healthCapacity = gSaveContext.save.saveInfo.playerData.healthCapacity / 0x10;
|
|
s16 fullHeartCount = gSaveContext.save.saveInfo.playerData.health / 0x10;
|
|
s32 pad2;
|
|
f32 lifesize = interfaceCtx->lifeSizeChange * 0.1f;
|
|
u32 curCombineModeSet = 0;
|
|
TexturePtr temp = NULL;
|
|
s32 ddCount = gSaveContext.save.saveInfo.inventory.defenseHearts - 1;
|
|
|
|
OPEN_DISPS(gfxCtx);
|
|
|
|
if ((gSaveContext.save.saveInfo.playerData.health % 0x10) == 0) {
|
|
fullHeartCount--;
|
|
}
|
|
|
|
offsetY = 0.0f;
|
|
offsetX = 0.0f;
|
|
curColorSet = -1;
|
|
|
|
for (i = 0; i < healthCapacity; i++) {
|
|
if ((ddCount < 0) || (ddCount < i)) {
|
|
if (i < fullHeartCount) {
|
|
if (curColorSet != 0) {
|
|
curColorSet = 0;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, interfaceCtx->heartsPrimR[0], interfaceCtx->heartsPrimG[0],
|
|
interfaceCtx->heartsPrimB[0], interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, interfaceCtx->heartsEnvR[0], interfaceCtx->heartsEnvG[0],
|
|
interfaceCtx->heartsEnvB[0], 255);
|
|
}
|
|
} else if (i == fullHeartCount) {
|
|
if (curColorSet != 1) {
|
|
curColorSet = 1;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, interfaceCtx->beatingHeartPrim[0],
|
|
interfaceCtx->beatingHeartPrim[1], interfaceCtx->beatingHeartPrim[2],
|
|
interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, interfaceCtx->beatingHeartEnv[0], interfaceCtx->beatingHeartEnv[1],
|
|
interfaceCtx->beatingHeartEnv[2], 255);
|
|
}
|
|
} else if (fullHeartCount < i) {
|
|
if (curColorSet != 2) {
|
|
curColorSet = 2;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, interfaceCtx->heartsPrimR[0], interfaceCtx->heartsPrimG[0],
|
|
interfaceCtx->heartsPrimB[0], interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, interfaceCtx->heartsEnvR[0], interfaceCtx->heartsEnvG[0],
|
|
interfaceCtx->heartsEnvB[0], 255);
|
|
}
|
|
} else {
|
|
if (curColorSet != 3) {
|
|
curColorSet = 3;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, interfaceCtx->heartsPrimR[1], interfaceCtx->heartsPrimG[1],
|
|
interfaceCtx->heartsPrimB[1], interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, interfaceCtx->heartsEnvR[1], interfaceCtx->heartsEnvG[1],
|
|
interfaceCtx->heartsEnvB[1], 255);
|
|
}
|
|
}
|
|
|
|
if (i < fullHeartCount) {
|
|
heartTex = gHeartFullTex;
|
|
} else if (i == fullHeartCount) {
|
|
heartTex = sHeartTextures[fractionHeartCount];
|
|
} else {
|
|
heartTex = gHeartEmptyTex;
|
|
}
|
|
} else {
|
|
if (i < fullHeartCount) {
|
|
if (curColorSet != 4) {
|
|
curColorSet = 4;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sHeartsDDPrim[0][0], sHeartsDDPrim[0][1], sHeartsDDPrim[0][2],
|
|
interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, sHeartsDDEnv[0][0], sHeartsDDEnv[0][1], sHeartsDDEnv[0][2], 255);
|
|
}
|
|
} else if (i == fullHeartCount) {
|
|
if (curColorSet != 5) {
|
|
curColorSet = 5;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sBeatingHeartsDDPrim[0], sBeatingHeartsDDPrim[1],
|
|
sBeatingHeartsDDPrim[2], interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, sBeatingHeartsDDEnv[0], sBeatingHeartsDDEnv[1],
|
|
sBeatingHeartsDDEnv[2], 255);
|
|
}
|
|
} else if (i > fullHeartCount) {
|
|
if (curColorSet != 6) {
|
|
curColorSet = 6;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sHeartsDDPrim[0][0], sHeartsDDPrim[0][1], sHeartsDDPrim[0][2],
|
|
interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, sHeartsDDEnv[0][0], sHeartsDDEnv[0][1], sHeartsDDEnv[0][2], 255);
|
|
}
|
|
} else if (curColorSet != 7) {
|
|
curColorSet = 7;
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sHeartsDDPrim[1][0], sHeartsDDPrim[1][1], sHeartsDDPrim[1][2],
|
|
interfaceCtx->healthAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, sHeartsDDEnv[1][0], sHeartsDDEnv[1][1], sHeartsDDEnv[1][2], 255);
|
|
}
|
|
if (i < fullHeartCount) {
|
|
heartTex = gDefenseHeartFullTex;
|
|
} else if (i == fullHeartCount) {
|
|
heartTex = sHeartDDTextures[fractionHeartCount];
|
|
} else {
|
|
heartTex = gDefenseHeartEmptyTex;
|
|
}
|
|
}
|
|
|
|
if (temp != heartTex) {
|
|
temp = heartTex;
|
|
gDPLoadTextureBlock(OVERLAY_DISP++, heartTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, 0,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
|
G_TX_NOLOD, G_TX_NOLOD);
|
|
}
|
|
|
|
if (i != fullHeartCount) {
|
|
if ((ddCount < 0) || (i > ddCount)) {
|
|
if (curCombineModeSet != 1) {
|
|
curCombineModeSet = 1;
|
|
Gfx_SetupDL39_Overlay(gfxCtx);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE,
|
|
0, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
|
|
}
|
|
} else if (curCombineModeSet != 3) {
|
|
curCombineModeSet = 3;
|
|
Gfx_SetupDL39_Overlay(gfxCtx);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0,
|
|
ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0);
|
|
}
|
|
posY = 26.0f + offsetY;
|
|
posX = 30.0f + offsetX;
|
|
temp_f4 = 1.0f;
|
|
temp_f4 /= 0.68f;
|
|
temp_f4 *= 1 << 10;
|
|
halfTexSize = 8.0f;
|
|
halfTexSize *= 0.68f;
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT,
|
|
adjust_x(posX - halfTexSize, G_EX_ORIGIN_LEFT) * 4, adjust_y(posY - halfTexSize, Y_ORIGIN_TOP) * 4,
|
|
adjust_x(posX + halfTexSize, G_EX_ORIGIN_LEFT) * 4, adjust_y(posY + halfTexSize, Y_ORIGIN_TOP) * 4,
|
|
G_TX_RENDERTILE, 0, 0, (s32)temp_f4, (s32)temp_f4);
|
|
} else {
|
|
Mtx* mtx;
|
|
|
|
if ((ddCount < 0) || (ddCount < i)) {
|
|
if (curCombineModeSet != 2) {
|
|
curCombineModeSet = 2;
|
|
Gfx_SetupDL42_Overlay(gfxCtx);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE,
|
|
0, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
|
|
gDPSetAlphaCompare(OVERLAY_DISP++, G_AC_THRESHOLD);
|
|
}
|
|
} else {
|
|
if (curCombineModeSet != 4) {
|
|
curCombineModeSet = 4;
|
|
Gfx_SetupDL42_Overlay(gfxCtx);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, PRIMITIVE,
|
|
0, ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0);
|
|
gDPSetAlphaCompare(OVERLAY_DISP++, G_AC_THRESHOLD);
|
|
}
|
|
}
|
|
mtx = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
|
Vp* vp = GRAPH_ALLOC(gfxCtx, sizeof(Vp));
|
|
View_ViewportToVp(vp, &play->view.viewport);
|
|
|
|
vp->vp.vtrans[0] = adjust_x_fractional(vp->vp.vtrans[0], G_EX_ORIGIN_LEFT);
|
|
vp->vp.vtrans[1] = adjust_y_fractional(vp->vp.vtrans[1], Y_ORIGIN_TOP);
|
|
|
|
gEXViewport(OVERLAY_DISP++, G_EX_ORIGIN_LEFT, vp);
|
|
|
|
Mtx_SetTranslateScaleMtx(mtx, 1.0f - (0.32f * lifesize), 1.0f - (0.32f * lifesize),
|
|
1.0f - (0.32f * lifesize), -130.0f + offsetX, 94.5f - offsetY, 0.0f);
|
|
gSPMatrix(OVERLAY_DISP++, mtx, G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPVertex(OVERLAY_DISP++, beatingHeartVtx, 4, 0);
|
|
gSP1Quadrangle(OVERLAY_DISP++, 0, 2, 3, 1, 0);
|
|
|
|
// Restore the old viewport
|
|
Vp* old_vp = GRAPH_ALLOC(gfxCtx, sizeof(Vp));
|
|
View_ViewportToVp(old_vp, &play->view.viewport);
|
|
gSPViewport(OVERLAY_DISP++, old_vp);
|
|
}
|
|
|
|
offsetX += 10.0f;
|
|
if (i == 9) {
|
|
offsetY += 10.0f;
|
|
offsetX = 0.0f;
|
|
}
|
|
}
|
|
CLOSE_DISPS(gfxCtx);
|
|
}
|
|
|
|
// Modify interface drawing (rupees, key counter, etc.)
|
|
extern TexturePtr sStoryTextures[];
|
|
extern TexturePtr sStoryTLUTs[];
|
|
|
|
extern Color_RGB16 sRupeeCounterIconPrimColors[];
|
|
extern Color_RGB16 sRupeeCounterIconEnvColors[];
|
|
extern u8 gRupeeCounterIconTex[];
|
|
extern s16 sRupeeDigitsFirst[];
|
|
extern s16 sRupeeDigitsCount[];
|
|
|
|
extern u8 gSmallKeyCounterIconTex[];
|
|
extern u8 gCounterDigit0Tex[];
|
|
extern u8 gGoldSkulltulaCounterIconTex[];
|
|
|
|
extern Color_RGB16 sMinigameCountdownPrimColors[];
|
|
extern TexturePtr sMinigameCountdownTextures[];
|
|
extern s16 sMinigameCountdownTexWidths[];
|
|
|
|
extern u8 gPictoBoxFocusBorderTex[];
|
|
extern u8 gPictoBoxFocusIconTex[];
|
|
extern u8 gPictoBoxFocusTextTex[];
|
|
|
|
static Gfx sScreenFillSetupDL[] = {
|
|
gsDPPipeSync(),
|
|
gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN |
|
|
G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
|
|
gsDPSetOtherMode(G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE |
|
|
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_1PRIMITIVE,
|
|
G_AC_NONE | G_ZS_PIXEL | G_RM_CLD_SURF | G_RM_CLD_SURF2),
|
|
gsDPSetCombineMode(G_CC_PRIMITIVE, G_CC_PRIMITIVE),
|
|
gsSPEndDisplayList(),
|
|
};
|
|
|
|
void Interface_DrawBButtonIcons(PlayState* play);
|
|
void Interface_DrawCButtonIcons(PlayState* play);
|
|
void Interface_DrawClock(PlayState* play);
|
|
void Interface_DrawMinigameIcons(PlayState* play);
|
|
void Interface_DrawPauseMenuEquippingIcons(PlayState* play);
|
|
void Interface_DrawPerfectLetters(PlayState* play);
|
|
void Interface_DrawTimers(PlayState* play);
|
|
void Interface_SetOrthoView(InterfaceContext* interfaceCtx);
|
|
void Interface_SetVertices(PlayState* play);
|
|
|
|
void Interface_Draw(PlayState* play) {
|
|
s32 pad;
|
|
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
|
Player* player = GET_PLAYER(play);
|
|
Gfx* gfx;
|
|
s16 sp2CE;
|
|
s16 sp2CC;
|
|
s16 sp2CA;
|
|
s16 sp2C8;
|
|
PauseContext* pauseCtx = &play->pauseCtx;
|
|
f32 minigameCountdownScale;
|
|
s16 counterDigits[4];
|
|
s16 magicAlpha;
|
|
|
|
OPEN_DISPS(play->state.gfxCtx);
|
|
|
|
gSPSegment(OVERLAY_DISP++, 0x02, interfaceCtx->parameterSegment);
|
|
gSPSegment(OVERLAY_DISP++, 0x09, interfaceCtx->doActionSegment);
|
|
gSPSegment(OVERLAY_DISP++, 0x08, interfaceCtx->iconItemSegment);
|
|
gSPSegment(OVERLAY_DISP++, 0x0B, interfaceCtx->mapSegment);
|
|
|
|
if (pauseCtx->debugEditor == DEBUG_EDITOR_NONE) {
|
|
Interface_SetVertices(play);
|
|
Interface_SetOrthoView(interfaceCtx);
|
|
|
|
// Draw Grandma's Story
|
|
if (interfaceCtx->storyDmaStatus == STORY_DMA_DONE) {
|
|
gSPSegment(OVERLAY_DISP++, 0x07, interfaceCtx->storySegment);
|
|
Gfx_SetupDL39_Opa(play->state.gfxCtx);
|
|
|
|
gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_POINT);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha);
|
|
|
|
// Load in Grandma's Story
|
|
gSPLoadUcodeL(OVERLAY_DISP++, gspS2DEX2_fifo);
|
|
gfx = OVERLAY_DISP;
|
|
Prerender_DrawBackground2D(&gfx, sStoryTextures[interfaceCtx->storyType],
|
|
sStoryTLUTs[interfaceCtx->storyType], SCREEN_WIDTH, SCREEN_HEIGHT, 2, 1, 0x8000,
|
|
0x100, 0.0f, 0.0f, 1.0f, 1.0f, 0);
|
|
OVERLAY_DISP = gfx;
|
|
gSPLoadUcode(OVERLAY_DISP++, SysUcode_GetUCode(), SysUcode_GetUCodeData());
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
|
|
// Fill the screen with a black rectangle
|
|
gDPSetRenderMode(OVERLAY_DISP++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
|
|
gDPSetCombineMode(OVERLAY_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, R_STORY_FILL_SCREEN_ALPHA);
|
|
gDPFillRectangle(OVERLAY_DISP++, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
}
|
|
|
|
gEXSetScissor(OVERLAY_DISP++, G_SC_NON_INTERLACE, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_RIGHT, 0, 0, 0, SCREEN_HEIGHT);
|
|
LifeMeter_Draw(play);
|
|
|
|
Gfx_SetupDL39_Overlay(play->state.gfxCtx);
|
|
|
|
// Draw Rupee Icon
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sRupeeCounterIconPrimColors[CUR_UPG_VALUE(UPG_WALLET)].r,
|
|
sRupeeCounterIconPrimColors[CUR_UPG_VALUE(UPG_WALLET)].g,
|
|
sRupeeCounterIconPrimColors[CUR_UPG_VALUE(UPG_WALLET)].b, interfaceCtx->magicAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, sRupeeCounterIconEnvColors[CUR_UPG_VALUE(UPG_WALLET)].r,
|
|
sRupeeCounterIconEnvColors[CUR_UPG_VALUE(UPG_WALLET)].g,
|
|
sRupeeCounterIconEnvColors[CUR_UPG_VALUE(UPG_WALLET)].b, 255);
|
|
OVERLAY_DISP =
|
|
GfxEx_DrawTexRectIA8(OVERLAY_DISP, gRupeeCounterIconTex, 16, 16, 26, 206, 16, 16, 1 << 10, 1 << 10, G_EX_ORIGIN_LEFT, Y_ORIGIN_BOTTOM);
|
|
|
|
switch (play->sceneId) {
|
|
case SCENE_INISIE_N:
|
|
case SCENE_INISIE_R:
|
|
case SCENE_MITURIN:
|
|
case SCENE_HAKUGIN:
|
|
case SCENE_SEA:
|
|
if (DUNGEON_KEY_COUNT(gSaveContext.mapIndex) >= 0) {
|
|
// Small Key Icon
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 200, 230, 255, interfaceCtx->magicAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 20, 255);
|
|
OVERLAY_DISP = GfxEx_DrawTexRectIA8(OVERLAY_DISP, gSmallKeyCounterIconTex, 16, 16, 26, 190, 16, 16,
|
|
1 << 10, 1 << 10, G_EX_ORIGIN_LEFT, Y_ORIGIN_BOTTOM);
|
|
|
|
// Small Key Counter
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE,
|
|
TEXEL0, 0, PRIMITIVE, 0);
|
|
|
|
counterDigits[2] = 0;
|
|
counterDigits[3] = DUNGEON_KEY_COUNT(gSaveContext.mapIndex);
|
|
|
|
while (counterDigits[3] >= 10) {
|
|
counterDigits[2]++;
|
|
counterDigits[3] -= 10;
|
|
}
|
|
|
|
sp2CA = 42;
|
|
|
|
if (counterDigits[2] != 0) {
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, interfaceCtx->magicAlpha);
|
|
|
|
OVERLAY_DISP =
|
|
GfxEx_DrawTexRectI8(OVERLAY_DISP, (u8*)gCounterDigit0Tex + (8 * 16 * counterDigits[2]), 8, 16,
|
|
43, 191, 8, 16, 1 << 10, 1 << 10, G_EX_ORIGIN_LEFT, Y_ORIGIN_BOTTOM);
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->magicAlpha);
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT,
|
|
adjust_x(42, G_EX_ORIGIN_LEFT) * 4, adjust_y(190, Y_ORIGIN_BOTTOM) * 4,
|
|
adjust_x(50, G_EX_ORIGIN_LEFT) * 4, adjust_y(206, Y_ORIGIN_BOTTOM) * 4,
|
|
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
|
|
sp2CA += 8;
|
|
}
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, interfaceCtx->magicAlpha);
|
|
|
|
OVERLAY_DISP = GfxEx_DrawTexRectI8(OVERLAY_DISP, (u8*)gCounterDigit0Tex + (8 * 16 * counterDigits[3]),
|
|
8, 16, sp2CA + 1, 191, 8, 16, 1 << 10, 1 << 10, G_EX_ORIGIN_LEFT, Y_ORIGIN_BOTTOM);
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->magicAlpha);
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT,
|
|
adjust_x(sp2CA, G_EX_ORIGIN_LEFT) * 4, adjust_y(190, Y_ORIGIN_BOTTOM) * 4,
|
|
adjust_x(sp2CA + 8, G_EX_ORIGIN_LEFT) * 4, adjust_y(206, Y_ORIGIN_BOTTOM) * 4,
|
|
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
}
|
|
break;
|
|
|
|
case SCENE_KINSTA1:
|
|
case SCENE_KINDAN2:
|
|
// Gold Skulltula Icon
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->magicAlpha);
|
|
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255);
|
|
gDPLoadTextureBlock(OVERLAY_DISP++, gGoldSkulltulaCounterIconTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 24, 24,
|
|
0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
|
G_TX_NOLOD, G_TX_NOLOD);
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT,
|
|
adjust_x(20, G_EX_ORIGIN_LEFT), adjust_y(187, Y_ORIGIN_BOTTOM) * 4,
|
|
adjust_x(44, G_EX_ORIGIN_LEFT), adjust_y(205, Y_ORIGIN_BOTTOM) * 4,
|
|
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
|
|
// Gold Skulluta Counter
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE,
|
|
TEXEL0, 0, PRIMITIVE, 0);
|
|
|
|
counterDigits[2] = 0;
|
|
counterDigits[3] = Inventory_GetSkullTokenCount(play->sceneId);
|
|
|
|
while (counterDigits[3] >= 10) {
|
|
counterDigits[2]++;
|
|
counterDigits[3] -= 10;
|
|
}
|
|
|
|
sp2CA = 42;
|
|
|
|
if (counterDigits[2] != 0) {
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, interfaceCtx->magicAlpha);
|
|
|
|
OVERLAY_DISP = GfxEx_DrawTexRectI8(OVERLAY_DISP, (u8*)gCounterDigit0Tex + (8 * 16 * counterDigits[2]),
|
|
8, 16, 43, 191, 8, 16, 1 << 10, 1 << 10, G_EX_ORIGIN_LEFT, Y_ORIGIN_BOTTOM);
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->magicAlpha);
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT,
|
|
adjust_x(42, G_EX_ORIGIN_LEFT), adjust_y(190, Y_ORIGIN_BOTTOM) * 4,
|
|
adjust_x(50, G_EX_ORIGIN_LEFT), adjust_y(206, Y_ORIGIN_BOTTOM) * 4,
|
|
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
|
|
sp2CA += 8;
|
|
}
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, interfaceCtx->magicAlpha);
|
|
|
|
OVERLAY_DISP = GfxEx_DrawTexRectI8(OVERLAY_DISP, (u8*)gCounterDigit0Tex + (8 * 16 * counterDigits[3]), 8,
|
|
16, sp2CA + 1, 191, 8, 16, 1 << 10, 1 << 10, G_EX_ORIGIN_LEFT, Y_ORIGIN_BOTTOM);
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->magicAlpha);
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT,
|
|
adjust_x(sp2CA, G_EX_ORIGIN_LEFT) * 4, adjust_y(190, Y_ORIGIN_BOTTOM) * 4,
|
|
adjust_x(sp2CA + 8, G_EX_ORIGIN_LEFT) * 4, adjust_y(206, Y_ORIGIN_BOTTOM) * 4,
|
|
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Rupee Counter
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetCombineLERP(OVERLAY_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0,
|
|
PRIMITIVE, 0);
|
|
|
|
counterDigits[0] = counterDigits[1] = 0;
|
|
counterDigits[2] = gSaveContext.save.saveInfo.playerData.rupees;
|
|
|
|
if ((counterDigits[2] > 9999) || (counterDigits[2] < 0)) {
|
|
counterDigits[2] &= 0xDDD;
|
|
}
|
|
|
|
while (counterDigits[2] >= 100) {
|
|
counterDigits[0]++;
|
|
counterDigits[2] -= 100;
|
|
}
|
|
|
|
while (counterDigits[2] >= 10) {
|
|
counterDigits[1]++;
|
|
counterDigits[2] -= 10;
|
|
}
|
|
|
|
sp2CC = sRupeeDigitsFirst[CUR_UPG_VALUE(UPG_WALLET)];
|
|
sp2C8 = sRupeeDigitsCount[CUR_UPG_VALUE(UPG_WALLET)];
|
|
|
|
magicAlpha = interfaceCtx->magicAlpha;
|
|
if (magicAlpha > 180) {
|
|
magicAlpha = 180;
|
|
}
|
|
|
|
for (sp2CE = 0, sp2CA = 42; sp2CE < sp2C8; sp2CE++, sp2CC++, sp2CA += 8) {
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, magicAlpha);
|
|
|
|
OVERLAY_DISP = GfxEx_DrawTexRectI8(OVERLAY_DISP, (u8*)gCounterDigit0Tex + (8 * 16 * counterDigits[sp2CC]), 8,
|
|
16, sp2CA + 1, 207, 8, 16, 1 << 10, 1 << 10, G_EX_ORIGIN_LEFT, Y_ORIGIN_BOTTOM);
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
|
|
if (gSaveContext.save.saveInfo.playerData.rupees == CUR_CAPACITY(UPG_WALLET)) {
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 120, 255, 0, interfaceCtx->magicAlpha);
|
|
} else if (gSaveContext.save.saveInfo.playerData.rupees != 0) {
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->magicAlpha);
|
|
} else {
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 100, 100, 100, interfaceCtx->magicAlpha);
|
|
}
|
|
|
|
gEXTextureRectangle(OVERLAY_DISP++, G_EX_ORIGIN_LEFT, G_EX_ORIGIN_LEFT,
|
|
adjust_x(sp2CA, G_EX_ORIGIN_LEFT) * 4, adjust_y(206, Y_ORIGIN_BOTTOM) * 4,
|
|
adjust_x(sp2CA + 8, G_EX_ORIGIN_LEFT) * 4, adjust_y(222, Y_ORIGIN_BOTTOM) * 4,
|
|
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
}
|
|
|
|
Magic_DrawMeter(play);
|
|
Minimap_Draw(play);
|
|
|
|
if ((R_PAUSE_BG_PRERENDER_STATE != 2) && (R_PAUSE_BG_PRERENDER_STATE != 3)) {
|
|
Target_Draw(&play->actorCtx.targetCtx, play);
|
|
}
|
|
|
|
Gfx_SetupDL39_Overlay(play->state.gfxCtx);
|
|
|
|
Interface_DrawItemButtons(play);
|
|
|
|
if (player->transformation == GET_PLAYER_FORM) {
|
|
Interface_DrawBButtonIcons(play);
|
|
}
|
|
Interface_DrawCButtonIcons(play);
|
|
|
|
Interface_DrawAButton(play);
|
|
|
|
Interface_DrawPauseMenuEquippingIcons(play);
|
|
|
|
// Draw either the minigame countdown or the three-day clock
|
|
if ((play->pauseCtx.state == PAUSE_STATE_OFF) && (play->pauseCtx.debugEditor == DEBUG_EDITOR_NONE)) {
|
|
if ((interfaceCtx->minigameState != MINIGAME_STATE_NONE) &&
|
|
(interfaceCtx->minigameState < MINIGAME_STATE_NO_COUNTDOWN_SETUP)) {
|
|
// Minigame Countdown
|
|
if (((u32)interfaceCtx->minigameState % 2) == 0) {
|
|
|
|
sp2CE = (interfaceCtx->minigameState >> 1) - 1;
|
|
minigameCountdownScale = interfaceCtx->minigameCountdownScale / 100.0f;
|
|
|
|
if (sp2CE == 3) {
|
|
interfaceCtx->actionVtx[40 + 0].v.ob[0] = interfaceCtx->actionVtx[40 + 2].v.ob[0] = -20;
|
|
interfaceCtx->actionVtx[40 + 1].v.ob[0] = interfaceCtx->actionVtx[40 + 3].v.ob[0] =
|
|
interfaceCtx->actionVtx[40 + 0].v.ob[0] + 40;
|
|
interfaceCtx->actionVtx[40 + 1].v.tc[0] = interfaceCtx->actionVtx[40 + 3].v.tc[0] = 40 << 5;
|
|
}
|
|
|
|
interfaceCtx->actionVtx[40 + 2].v.tc[1] = interfaceCtx->actionVtx[40 + 3].v.tc[1] = 32 << 5;
|
|
|
|
Gfx_SetupDL42_Overlay(play->state.gfxCtx);
|
|
|
|
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
|
gDPSetAlphaCompare(OVERLAY_DISP++, G_AC_THRESHOLD);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sMinigameCountdownPrimColors[sp2CE].r,
|
|
sMinigameCountdownPrimColors[sp2CE].g, sMinigameCountdownPrimColors[sp2CE].b,
|
|
interfaceCtx->minigameCountdownAlpha);
|
|
|
|
Matrix_Translate(0.0f, -40.0f, 0.0f, MTXMODE_NEW);
|
|
Matrix_Scale(minigameCountdownScale, minigameCountdownScale, 0.0f, MTXMODE_APPLY);
|
|
|
|
gSPMatrix(OVERLAY_DISP++, Matrix_NewMtx(play->state.gfxCtx),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPVertex(OVERLAY_DISP++, &interfaceCtx->actionVtx[40], 4, 0);
|
|
|
|
OVERLAY_DISP = Gfx_DrawTexQuadIA8(OVERLAY_DISP, sMinigameCountdownTextures[sp2CE],
|
|
sMinigameCountdownTexWidths[sp2CE], 32, 0);
|
|
}
|
|
} else {
|
|
Interface_DrawClock(play);
|
|
}
|
|
}
|
|
|
|
// Draw the letters of minigame perfect
|
|
if (interfaceCtx->perfectLettersOn) {
|
|
Interface_DrawPerfectLetters(play);
|
|
}
|
|
|
|
Interface_DrawMinigameIcons(play);
|
|
Interface_DrawTimers(play);
|
|
}
|
|
|
|
// Draw pictograph focus icons
|
|
if (sPictoState == PICTO_BOX_STATE_LENS) {
|
|
|
|
Gfx_SetupDL39_Overlay(play->state.gfxCtx);
|
|
|
|
gDPSetAlphaCompare(OVERLAY_DISP++, G_AC_THRESHOLD);
|
|
gDPSetRenderMode(OVERLAY_DISP++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
|
|
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 155, 255);
|
|
gDPLoadTextureBlock_4b(OVERLAY_DISP++, gPictoBoxFocusBorderTex, G_IM_FMT_IA, 16, 16, 0, G_TX_MIRROR | G_TX_WRAP,
|
|
G_TX_MIRROR | G_TX_WRAP, 4, 4, G_TX_NOLOD, G_TX_NOLOD);
|
|
|
|
gSPTextureRectangle(OVERLAY_DISP++, R_PICTO_FOCUS_BORDER_TOPLEFT_X << 2, R_PICTO_FOCUS_BORDER_TOPLEFT_Y << 2,
|
|
(R_PICTO_FOCUS_BORDER_TOPLEFT_X << 2) + (16 << 2),
|
|
(R_PICTO_FOCUS_BORDER_TOPLEFT_Y << 2) + (16 << 2), G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
gSPTextureRectangle(OVERLAY_DISP++, R_PICTO_FOCUS_BORDER_TOPRIGHT_X << 2, R_PICTO_FOCUS_BORDER_TOPRIGHT_Y << 2,
|
|
(R_PICTO_FOCUS_BORDER_TOPRIGHT_X << 2) + (16 << 2),
|
|
(R_PICTO_FOCUS_BORDER_TOPRIGHT_Y << 2) + (16 << 2), G_TX_RENDERTILE, 512, 0, 1 << 10,
|
|
1 << 10);
|
|
gSPTextureRectangle(
|
|
OVERLAY_DISP++, R_PICTO_FOCUS_BORDER_BOTTOMLEFT_X << 2, R_PICTO_FOCUS_BORDER_BOTTOMLEFT_Y << 2,
|
|
(R_PICTO_FOCUS_BORDER_BOTTOMLEFT_X << 2) + (16 << 2), (R_PICTO_FOCUS_BORDER_BOTTOMLEFT_Y << 2) + (16 << 2),
|
|
G_TX_RENDERTILE, 0, 512, 1 << 10, 1 << 10);
|
|
gSPTextureRectangle(
|
|
OVERLAY_DISP++, R_PICTO_FOCUS_BORDER_BOTTOMRIGHT_X << 2, R_PICTO_FOCUS_BORDER_BOTTOMRIGHT_Y << 2,
|
|
(R_PICTO_FOCUS_BORDER_BOTTOMRIGHT_X << 2) + (16 << 2),
|
|
(R_PICTO_FOCUS_BORDER_BOTTOMRIGHT_Y << 2) + (16 << 2), G_TX_RENDERTILE, 512, 512, 1 << 10, 1 << 10);
|
|
|
|
gDPLoadTextureBlock_4b(OVERLAY_DISP++, gPictoBoxFocusIconTex, G_IM_FMT_I, 32, 16, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
|
|
|
gSPTextureRectangle(OVERLAY_DISP++, R_PICTO_FOCUS_ICON_X << 2, R_PICTO_FOCUS_ICON_Y << 2,
|
|
(R_PICTO_FOCUS_ICON_X << 2) + 0x80, (R_PICTO_FOCUS_ICON_Y << 2) + (16 << 2),
|
|
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
|
|
gDPLoadTextureBlock_4b(OVERLAY_DISP++, gPictoBoxFocusTextTex, G_IM_FMT_I, 32, 8, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
|
|
|
gSPTextureRectangle(OVERLAY_DISP++, R_PICTO_FOCUS_TEXT_X << 2, R_PICTO_FOCUS_TEXT_Y << 2,
|
|
(R_PICTO_FOCUS_TEXT_X << 2) + 0x80, (R_PICTO_FOCUS_TEXT_Y << 2) + 0x20, G_TX_RENDERTILE, 0,
|
|
0, 1 << 10, 1 << 10);
|
|
}
|
|
|
|
// Draw pictograph photo
|
|
if (sPictoState >= PICTO_BOX_STATE_SETUP_PHOTO) {
|
|
if (!(play->actorCtx.flags & ACTORCTX_FLAG_PICTO_BOX_ON)) {
|
|
Play_CompressI8ToI5((play->pictoPhotoI8 != NULL) ? play->pictoPhotoI8 : gWorkBuffer,
|
|
(u8*)gSaveContext.pictoPhotoI5, PICTO_PHOTO_WIDTH * PICTO_PHOTO_HEIGHT);
|
|
|
|
interfaceCtx->unk_222 = interfaceCtx->unk_224 = 0;
|
|
|
|
sPictoState = PICTO_BOX_STATE_OFF;
|
|
gSaveContext.hudVisibility = HUD_VISIBILITY_IDLE;
|
|
Interface_SetHudVisibility(HUD_VISIBILITY_ALL);
|
|
} else {
|
|
s16 pictoRectTop;
|
|
s16 pictoRectLeft;
|
|
|
|
if (sPictoState == PICTO_BOX_STATE_SETUP_PHOTO) {
|
|
sPictoState = PICTO_BOX_STATE_PHOTO;
|
|
Message_StartTextbox(play, 0xF8, NULL);
|
|
Interface_SetHudVisibility(HUD_VISIBILITY_NONE);
|
|
player->stateFlags1 |= PLAYER_STATE1_200;
|
|
}
|
|
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gDPSetRenderMode(OVERLAY_DISP++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
|
|
gDPSetCombineMode(OVERLAY_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 200, 200, 200, 250);
|
|
gDPFillRectangle(OVERLAY_DISP++, 70, 22, 251, 151);
|
|
|
|
Gfx_SetupDL39_Overlay(play->state.gfxCtx);
|
|
|
|
gDPSetRenderMode(OVERLAY_DISP++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
|
|
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEI_PRIM, G_CC_MODULATEI_PRIM);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 250, 160, 160, 255);
|
|
|
|
// Picture is offset up by 33 pixels to give room for the message box at the bottom
|
|
pictoRectTop = PICTO_PHOTO_TOPLEFT_Y - 33;
|
|
for (sp2CC = 0; sp2CC < (PICTO_PHOTO_HEIGHT / 8); sp2CC++, pictoRectTop += 8) {
|
|
pictoRectLeft = PICTO_PHOTO_TOPLEFT_X;
|
|
gDPLoadTextureBlock(OVERLAY_DISP++,
|
|
(u8*)((play->pictoPhotoI8 != NULL) ? play->pictoPhotoI8 : gWorkBuffer) +
|
|
(0x500 * sp2CC),
|
|
G_IM_FMT_I, G_IM_SIZ_8b, PICTO_PHOTO_WIDTH, 8, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
|
|
|
gSPTextureRectangle(OVERLAY_DISP++, pictoRectLeft << 2, pictoRectTop << 2,
|
|
(pictoRectLeft + PICTO_PHOTO_WIDTH) << 2, (pictoRectTop << 2) + (8 << 2),
|
|
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Draw over the entire screen (used in gameover)
|
|
if (interfaceCtx->screenFillAlpha != 0) {
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
gSPDisplayList(OVERLAY_DISP++, sScreenFillSetupDL);
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, interfaceCtx->screenFillAlpha);
|
|
gSPDisplayList(OVERLAY_DISP++, D_0E000000.fillRect);
|
|
}
|
|
|
|
CLOSE_DISPS(play->state.gfxCtx);
|
|
} |