#include "common.h" #include "nu/nusys.h" #include "include_asset.h" #define INTEGER_LOG2(x) ((x) <= 1 ? 0 : (x) <= 2 ? 1 : (x) <= 4 ? 2 : (x) <= 8 ? 3 : (x) <= 16 ? 4 : (x) <= 32 ? 5 : (x) <= 64 ? 6 : (x) <= 128 ? 7 : (x) <= 256 ? 8 : (x) <= 512 ? 9 : 10) typedef struct DefaultWindowStyle { /* 0x00 */ u8 bgIndex; /* 0x01 */ u8 cornersIndex; /* 0x02 */ u8 combineModeIndex; /* 0x03 */ Color_RGBA8 color1; /* 0x07 */ Color_RGBA8 color2; } DefaultWindowStyle; // size = 0x0B #define BOX_QUAD_BUFFER_NUM 21 BSS Vtx gBoxQuadBuffer[BOX_QUAD_BUFFER_NUM][16]; DefaultWindowStyle gBoxDefaultStyles[] = { { .bgIndex = 1, .cornersIndex = 0, .combineModeIndex = 0, .color1 = { .r = 200, .g = 191, .b = 164, .a = 255 }, .color2 = { .r = 128, .g = 128, .b = 128, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 1, .combineModeIndex = 1, .color1 = { .r = 255, .g = 200, .b = 128, .a = 255 }, .color2 = { .r = 128, .g = 128, .b = 128, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 2, .combineModeIndex = 1, .color1 = { .r = 232, .g = 196, .b = 77, .a = 255 }, .color2 = { .r = 163, .g = 123, .b = 0, .a = 255 } }, { .bgIndex = 0, .cornersIndex = 3, .combineModeIndex = 1, .color1 = { .r = 226, .g = 225, .b = 216, .a = 255 }, .color2 = { .r = 217, .g = 208, .b = 201, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 4, .combineModeIndex = 1, .color1 = { .r = 61, .g = 74, .b = 188, .a = 255 }, .color2 = { .r = 0, .g = 25, .b = 28, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 5, .combineModeIndex = 1, .color1 = { .r = 235, .g = 230, .b = 119, .a = 255 }, .color2 = { .r = 142, .g = 90, .b = 37, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 6, .combineModeIndex = 1, .color1 = { .r = 235, .g = 230, .b = 119, .a = 255 }, .color2 = { .r = 142, .g = 99, .b = 37, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 4, .combineModeIndex = 1, .color1 = { .r = 215, .g = 191, .b = 116, .a = 255 }, .color2 = { .r = 132, .g = 70, .b = 50, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 4, .combineModeIndex = 1, .color1 = { .r = 215, .g = 191, .b = 116, .a = 255 }, .color2 = { .r = 132, .g = 70, .b = 50, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 4, .combineModeIndex = 1, .color1 = { .r = 141, .g = 143, .b = 255, .a = 255 }, .color2 = { .r = 43, .g = 69, .b = 102, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 8, .combineModeIndex = 1, .color1 = { .r = 141, .g = 143, .b = 255, .a = 255 }, .color2 = { .r = 43, .g = 69, .b = 102, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 4, .combineModeIndex = 1, .color1 = { .r = 170, .g = 208, .b = 128, .a = 255 }, .color2 = { .r = 71, .g = 123, .b = 83, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 8, .combineModeIndex = 1, .color1 = { .r = 170, .g = 208, .b = 128, .a = 255 }, .color2 = { .r = 71, .g = 123, .b = 83, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 4, .combineModeIndex = 1, .color1 = { .r = 200, .g = 200, .b = 90, .a = 255 }, .color2 = { .r = 140, .g = 140, .b = 0, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 8, .combineModeIndex = 1, .color1 = { .r = 200, .g = 200, .b = 90, .a = 255 }, .color2 = { .r = 140, .g = 140, .b = 0, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 4, .combineModeIndex = 1, .color1 = { .r = 235, .g = 230, .b = 119, .a = 255 }, .color2 = { .r = 142, .g = 90, .b = 37, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 4, .combineModeIndex = 1, .color1 = { .r = 142, .g = 212, .b = 236, .a = 255 }, .color2 = { .r = 67, .g = 98, .b = 69, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 4, .combineModeIndex = 1, .color1 = { .r = 167, .g = 151, .b = 119, .a = 255 }, .color2 = { .r = 98, .g = 55, .b = 154, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 7, .combineModeIndex = 1, .color1 = { .r = 17, .g = 151, .b = 29, .a = 255 }, .color2 = { .r = 8, .g = 55, .b = 14, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 7, .combineModeIndex = 1, .color1 = { .r = 110, .g = 110, .b = 200, .a = 255 }, .color2 = { .r = 10, .g = 10, .b = 100, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 4, .combineModeIndex = 1, .color1 = { .r = 181, .g = 60, .b = 60, .a = 255 }, .color2 = { .r = 76, .g = 10, .b = 0, .a = 255 } }, { .bgIndex = 1, .cornersIndex = 4, .combineModeIndex = 1, .color1 = { .r = 174, .g = 227, .b = 235, .a = 255 }, .color2 = { .r = 76, .g = 110, .b = 60, .a = 255 } }, { .bgIndex = 0, .cornersIndex = 3, .combineModeIndex = 1, .color1 = { .r = 126, .g = 125, .b = 216, .a = 255 }, .color2 = { .r = 217, .g = 108, .b = 201, .a = 255 } } }; INCLUDE_IMG("ui/box/corners9.png", ui_box_corners9_png); INCLUDE_IMG("ui/box/corners8.png", ui_box_corners8_png); INCLUDE_IMG("ui/box/corners6.png", ui_box_corners6_png); INCLUDE_IMG("ui/box/corners7.png", ui_box_corners7_png); INCLUDE_IMG("ui/box/corners3.png", ui_box_corners3_png); INCLUDE_IMG("ui/box/corners5.png", ui_box_corners5_png); INCLUDE_IMG("ui/box/corners4.png", ui_box_corners4_png); INCLUDE_IMG("ui/box/bg_tile.png", ui_box_bg_tile_png); INCLUDE_IMG("ui/box/corners1.png", ui_box_corners1_png); INCLUDE_IMG("ui/box/corners2.png", ui_box_corners2_png); INCLUDE_IMG("ui/box/bg_flat.png", ui_box_bg_flat_png); WindowBackground gBoxBackground[] = { { .imgData = ui_box_bg_tile_png, .fmt = G_IM_FMT_I, .bitDepth = G_IM_SIZ_4b, .width = 16, .height = 16, .unk_07 = { 0, 0, 0, 0}, .size = 128 }, { .imgData = ui_box_bg_flat_png, .fmt = G_IM_FMT_I, .bitDepth = G_IM_SIZ_4b, .width = 16, .height = 1, .unk_07 = { 0, 0, 0, 0}, .size = 8 } }; WindowCorners gBoxCorners[] = { { .imgData = ui_box_corners1_png, .fmt = G_IM_FMT_IA, .bitDepth = G_IM_SIZ_8b, .size1 = { 16, 16}, .size2 = { 16, 16}, .size3 = { 16, 16}, .size4 = { 16, 16}, .unk_0D = { 0, 0, 0} }, { .imgData = ui_box_corners2_png, .fmt = G_IM_FMT_I, .bitDepth = G_IM_SIZ_4b, .size1 = { 16, 16}, .size2 = { 16, 16}, .size3 = { 16, 16}, .size4 = { 16, 16}, .unk_0D = { 0, 0, 0} }, { .imgData = ui_box_corners3_png, .fmt = G_IM_FMT_IA, .bitDepth = G_IM_SIZ_8b, .size1 = { 16, 32}, .size2 = { 16, 32}, .size3 = { 16, 16}, .size4 = { 16, 16}, .unk_0D = { 0, 0, 0} }, { .imgData = ui_box_corners4_png, .fmt = G_IM_FMT_IA, .bitDepth = G_IM_SIZ_8b, .size1 = { 8, 8}, .size2 = { 8, 8}, .size3 = { 8, 8}, .size4 = { 8, 8}, .unk_0D = { 0, 0, 0} }, { .imgData = ui_box_corners5_png, .fmt = G_IM_FMT_IA, .bitDepth = G_IM_SIZ_8b, .size1 = { 16, 8}, .size2 = { 16, 8}, .size3 = { 16, 8}, .size4 = { 16, 8}, .unk_0D = { 0, 0, 0} }, { .imgData = ui_box_corners6_png, .fmt = G_IM_FMT_IA, .bitDepth = G_IM_SIZ_8b, .size1 = { 16, 8}, .size2 = { 16, 8}, .size3 = { 16, 8}, .size4 = { 16, 16}, .unk_0D = { 0, 0, 0} }, { .imgData = ui_box_corners7_png, .fmt = G_IM_FMT_IA, .bitDepth = G_IM_SIZ_8b, .size1 = { 16, 8}, .size2 = { 16, 8}, .size3 = { 16, 8}, .size4 = { 16, 8}, .unk_0D = { 0, 0, 0} }, { .imgData = ui_box_corners8_png, .fmt = G_IM_FMT_IA, .bitDepth = G_IM_SIZ_8b, .size1 = { 24, 24}, .size2 = { 24, 24}, .size3 = { 24, 24}, .size4 = { 24, 24}, .unk_0D = { 0, 0, 0} }, { .imgData = ui_box_corners9_png, .fmt = G_IM_FMT_IA, .bitDepth = G_IM_SIZ_8b, .size1 = { 16, 16}, .size2 = { 16, 16}, .size3 = { 16, 16}, .size4 = { 16, 16}, .unk_0D = { 0, 0, 0} } }; Gfx gBoxCombineModes[] = { gsDPSetCombineMode(PM_CC_BOX1_OPAQUE, PM_CC_BOX1_CYC2), gsDPSetCombineMode(PM_CC_BOX2_OPAQUE, PM_CC_BOX2_CYC2), gsDPSetCombineMode(PM_CC_BOX1_TRANSPARENT, PM_CC_BOX1_CYC2), gsDPSetCombineMode(PM_CC_BOX2_TRANSPARENT, PM_CC_BOX2_CYC2) }; s32 gBoxQuadIndex = 0; Vp gBoxViewport = { .vp = { .vscale = { 640, 480, 511, 0 }, .vtrans = { 640, 480, 511, 0 } } }; #include "vtx/drawbox1.vtx.inc.c" Mtx gBoxMatrix = RDP_MATRIX( 0.000000, 0.000000, 0.000000, -6.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 ); // @bug there's an issue with the way the "quads" temp below is used, sometimes going out of bounds. // In vanilla, this results in some data being written to an unused struct field inside gPartnerStatus, which doesn't // cause any issues. In shiftable builds, there's no telling where quads might be, so we make some adjustments to // prevent the overflow s32 draw_box(s32 flags, WindowStyle windowStyle, s32 posX, s32 posY, s32 posZ, s32 width, s32 height, u8 opacity, u8 darkening, f32 scaleX, f32 scaleY, f32 rotX, f32 rotY, f32 rotZ, void (*fpDrawContents)(s32, s32, s32, s32, s32, s32, s32), void* drawContentsArg0, Matrix4f rotScaleMtx, s32 translateX, s32 translateY, Matrix4f outMtx) { Matrix4f mtx1, mtx2, mtx3; u8 primR, primG, primB, primA, envR, envG, envB, envA; DefaultWindowStyle* defaultStyle = NULL; WindowStyleCustom* customStyle = NULL; WindowCorners* corners; WindowBackground* background; u32 bgWidth, bgHeight; u32 cornerWidth, cornerHeight; s32 masks, maskt; Vtx* quads; s32 idx; s32 i, j; s32 tmem = 0x100; u32 bgScrollOffsetX, bgScrollOffsetY; s32 foo; s32 alpha = foo * opacity / 255; if (windowStyle.defaultStyleID <= WINDOW_STYLE_MAX && windowStyle.defaultStyleID >= 0) { defaultStyle = &gBoxDefaultStyles[windowStyle.defaultStyleID]; primR = defaultStyle->color1.r; primG = defaultStyle->color1.g; primB = defaultStyle->color1.b; primA = defaultStyle->color1.a * opacity / 255; envR = defaultStyle->color2.r; envG = defaultStyle->color2.g; envB = defaultStyle->color2.b; envA = defaultStyle->color2.a; background = &gBoxBackground[defaultStyle->bgIndex]; corners = &gBoxCorners[defaultStyle->cornersIndex]; } else { primR = windowStyle.customStyle->color1.r; primG = windowStyle.customStyle->color1.g; primB = windowStyle.customStyle->color1.b; primA = windowStyle.customStyle->color1.a * opacity / 255; envR = windowStyle.customStyle->color2.r; envG = windowStyle.customStyle->color2.g; envB = windowStyle.customStyle->color2.b; envA = windowStyle.customStyle->color2.a; customStyle = windowStyle.customStyle; background = &windowStyle.customStyle->background; corners = &windowStyle.customStyle->corners; } { u8* bgImage; u8* cornersImage; s32 bgFmt; s32 bgMasks; s32 bgMaskt; Vec2bu* cornersSizes; u32 cornersFmt; u32 cornersBitDepth; Mtx* sp154; bgFmt = background->fmt; cornersImage = corners->imgData; do {} while (0); bgWidth = background->width; bgImage = background->imgData; bgHeight = background->height; bgMasks = INTEGER_LOG2(bgWidth); bgMaskt = INTEGER_LOG2(bgHeight); quads = NULL; sp154 = NULL; cornersSizes = (Vec2bu*)&corners->size1; cornersFmt = corners->fmt; cornersBitDepth = corners->bitDepth; if (width <= 0 || height <= 0 || opacity == 0 || posX <= -768 || posY <= -768) { return TRUE; } if (posX >= SCREEN_WIDTH || posY >= SCREEN_HEIGHT) { return TRUE; } if (posX + width >= 768 || posY + height >= 768 || posX + width <= 0 || posY + height <= 0) { return TRUE; } if (flags & DRAW_FLAG_ROTSCALE) { quads = gBoxQuadBuffer[gBoxQuadIndex++]; if (gBoxQuadIndex > BOX_QUAD_BUFFER_NUM - 1) { gBoxQuadIndex = 0; } } gDPPipeSync(gMainGfxPos++); gDPSetCycleType(gMainGfxPos++, G_CYC_2CYCLE); gDPSetBlendColor(gMainGfxPos++, 0, 0, 0, 0); gDPSetFogColor(gMainGfxPos++, 0, 0, 0, darkening); gDPSetRenderMode(gMainGfxPos++, PM_RM_SHROUD, G_RM_XLU_SURF2); if (!(flags & DRAW_FLAG_NO_CLIP)) { gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); } if (defaultStyle != NULL) { Gfx* gfxPos = gMainGfxPos; *gfxPos = gBoxCombineModes[defaultStyle->combineModeIndex + (primA != 255 ? 2 : 0)]; } else { Gfx* gfxPos = gMainGfxPos; if (primA != 255) { *gfxPos = customStyle->transparentCombineMode; } else { *gfxPos = customStyle->opaqueCombineMode; } } gMainGfxPos++; gDPSetTextureFilter(gMainGfxPos++, G_TF_POINT); if (quads != NULL) { gSPViewport(gMainGfxPos++, &gBoxViewport); guFrustumF(mtx1, -80.0f, 80.0f, 60.0f, -60.0f, 160.0f, 480.0f, 1.0f); guMtxF2L(mtx1, &gDisplayContext->matrixStack[gMatrixListPos]); sp154 = &gDisplayContext->matrixStack[gMatrixListPos]; gSPMatrix(gMainGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); guPositionF(mtx1, rotX, rotY, rotZ, 1.0f, posX + width / 2, posY + height / 2, posZ); if (scaleX != 1.0f || scaleY != 1.0f) { guScaleF(mtx2, scaleX, scaleY, 1.0f); guMtxCatF(mtx2, mtx1, mtx1); } if (rotScaleMtx != 0) { guTranslateF(mtx2, -translateX / 2, -translateY / 2, 0.0f); guMtxCatF(mtx1, mtx2, mtx2); guMtxCatF(mtx2, rotScaleMtx, mtx1); } if (outMtx) { for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { outMtx[i][j] = mtx1[i][j]; } } } guTranslateF(mtx2, -160.0f, -120.0f, -320.0f); guMtxCatF(mtx1, mtx2, mtx1); gSPClearGeometryMode(gMainGfxPos++, G_CULL_BOTH | G_LIGHTING); if (flags & DRAW_FLAG_CULL_BACK) { gSPSetGeometryMode(gMainGfxPos++, G_CULL_BACK); } guMtxF2L(mtx1, &gDisplayContext->matrixStack[gMatrixListPos]); gSPMatrix(gMainGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gDPSetTexturePersp(gMainGfxPos++, G_TP_PERSP); gSPPerspNormalize(gMainGfxPos++, 20); } else { gDPSetTexturePersp(gMainGfxPos++, G_TP_NONE); } gSPTexture(gMainGfxPos++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); gDPSetTextureLUT(gMainGfxPos++, G_TT_NONE); gDPSetTextureDetail(gMainGfxPos++, G_TD_CLAMP); gDPSetTextureLOD(gMainGfxPos++, G_TL_TILE); gDPSetPrimColor(gMainGfxPos++, 0, 0, primR, primG, primB, primA); gDPSetEnvColor(gMainGfxPos++, envR, envG, envB, envA); if (bgImage != NULL) { switch (background->bitDepth) { case G_IM_SIZ_4b: gDPLoadTextureTile_4b(gMainGfxPos++, bgImage, bgFmt, bgWidth, bgHeight, 0, 0, bgWidth - 1, bgHeight - 1, 0, G_TX_WRAP, G_TX_WRAP, bgMasks, bgMaskt, G_TX_NOLOD, G_TX_NOLOD); break; case G_IM_SIZ_8b: gDPLoadTextureTile(gMainGfxPos++, bgImage, bgFmt, G_IM_SIZ_8b, bgWidth, bgHeight, 0, 0, bgWidth - 1, bgHeight - 1, 0, G_TX_WRAP, G_TX_WRAP, bgMasks, bgMaskt, G_TX_NOLOD, G_TX_NOLOD); break; case G_IM_SIZ_16b: gDPLoadTextureTile(gMainGfxPos++, bgImage, bgFmt, G_IM_SIZ_16b, bgWidth, bgHeight, 0, 0, bgWidth - 1, bgHeight - 1, 0, G_TX_WRAP, G_TX_WRAP, bgMasks, bgMaskt, G_TX_NOLOD, G_TX_NOLOD); break; case G_IM_SIZ_32b: gDPLoadTextureTile(gMainGfxPos++, bgImage, bgFmt, G_IM_SIZ_32b, bgWidth, bgHeight, 0, 0, bgWidth - 1, bgHeight - 1, 0, G_TX_WRAP, G_TX_WRAP, bgMasks, bgMaskt, G_TX_NOLOD, G_TX_NOLOD); break; } if (flags & DRAW_FLAG_ANIMATED_BACKGROUND) { bgScrollOffsetY = (gGameStatusPtr->frameCounter * 4) & 0x1FF; bgScrollOffsetX = 511 - bgScrollOffsetY; gDPSetTileSize(gMainGfxPos++, G_TX_RENDERTILE, width / 2 * 4 + bgScrollOffsetX, height / 2 * 4 + bgScrollOffsetY, (width / 2 + bgWidth - 1) * 4 + bgScrollOffsetX, (height / 2 + bgHeight - 1) * 4 + bgScrollOffsetY); } else { gDPSetTileSize(gMainGfxPos++, G_TX_RENDERTILE, width / 2 * 4, height / 2 * 4, (width / 2 + bgWidth - 1) * 4, (height / 2 + bgHeight - 1)* 4); } } if (cornersImage != NULL) { for (idx = 0; idx < 4; idx++) { cornerWidth = cornersSizes[idx].x; cornerHeight = cornersSizes[idx].y; masks = INTEGER_LOG2(cornerWidth); maskt = INTEGER_LOG2(cornerHeight); switch (cornersBitDepth) { case G_IM_SIZ_4b: gDPLoadMultiTile_4b(gMainGfxPos++, cornersImage, tmem, 1, cornersFmt, cornerWidth, cornerHeight, 0, 0, cornerWidth - 1, cornerHeight - 1, 0, G_TX_CLAMP, G_TX_CLAMP, masks, maskt, G_TX_NOLOD, G_TX_NOLOD); cornersImage += cornerWidth * cornerHeight / 2; break; case G_IM_SIZ_8b: gDPLoadMultiTile(gMainGfxPos++, cornersImage, tmem, 1, cornersFmt, G_IM_SIZ_8b, cornerWidth, cornerHeight, 0, 0, cornerWidth - 1, cornerHeight - 1, 0, G_TX_CLAMP, G_TX_CLAMP, masks, maskt, G_TX_NOLOD, G_TX_NOLOD); cornersImage += cornerWidth * cornerHeight; break; case G_IM_SIZ_16b: gDPLoadMultiTile(gMainGfxPos++, cornersImage, tmem, 1, cornersFmt, G_IM_SIZ_16b, cornerWidth, cornerHeight, 0, 0, cornerWidth - 1, cornerHeight - 1, 0, G_TX_CLAMP, G_TX_CLAMP, masks, maskt, G_TX_NOLOD, G_TX_NOLOD); cornersImage += cornerWidth * cornerHeight * 2; break; case G_IM_SIZ_32b: gDPLoadMultiTile(gMainGfxPos++, cornersImage, tmem, 1, cornersFmt, G_IM_SIZ_32b, cornerWidth, cornerHeight, 0, 0, cornerWidth - 1, cornerHeight - 1, 0, G_TX_CLAMP, G_TX_CLAMP, masks, maskt, G_TX_NOLOD, G_TX_NOLOD); cornersImage += cornerWidth * cornerHeight * 4; break; } switch(idx) { case 1: gDPSetTileSize(gMainGfxPos++, 1, (width - cornerWidth) * 4, 0, (width - 1) * 4, (cornerHeight - 1) * 4); break; case 2: gDPSetTileSize(gMainGfxPos++, 1, 0, (height - cornerHeight) * 4, (cornerWidth - 1) * 4, (height - 1) * 4); break; case 3: gDPSetTileSize(gMainGfxPos++, 1, (width - cornerWidth) * 4, (height - cornerHeight) * 4, (width - 1) * 4, (height - 1) * 4); break; } if (quads != NULL) { switch(idx) { case 0: quads[0].v.ob[0] = -width / 2; quads[0].v.ob[1] = -height / 2; quads[0].v.ob[2] = 0; quads[1].v.ob[0] = 0; quads[1].v.ob[1] = -height / 2; quads[1].v.ob[2] = 0; quads[2].v.ob[0] = -width / 2; quads[2].v.ob[1] = 0; quads[2].v.ob[2] = 0; quads[3].v.ob[0] = 0; quads[3].v.ob[1] = 0; quads[3].v.ob[2] = 0; quads[0].v.tc[0] = 0; quads[0].v.tc[1] = 0; quads[1].v.tc[0] = (width / 2) * 32; quads[1].v.tc[1] = 0; quads[2].v.tc[0] = 0; quads[2].v.tc[1] = (height / 2) * 32; quads[3].v.tc[0] = (width / 2) * 32; quads[3].v.tc[1] = (height / 2) * 32; break; case 1: quads[4].v.ob[0] = 0; quads[4].v.ob[1] = -height / 2; quads[4].v.ob[2] = 0; quads[5].v.ob[0] = (-width / 2) + width; quads[5].v.ob[1] = -height / 2; quads[5].v.ob[2] = 0; quads[6].v.ob[0] = 0; quads[6].v.ob[1] = 0; quads[6].v.ob[2] = 0; quads[7].v.ob[0] = (-width / 2) + width; quads[7].v.ob[1] = 0; quads[7].v.ob[2] = 0; quads[4].v.tc[0] = (width / 2) * 32; quads[4].v.tc[1] = 0; quads[5].v.tc[0] = width * 32; quads[5].v.tc[1] = 0; quads[6].v.tc[0] = (width / 2) * 32; quads[6].v.tc[1] = (height / 2) * 32; quads[7].v.tc[0] = width * 32; quads[7].v.tc[1] = (height / 2) * 32; #ifndef SHIFT quads += 4; #endif break; case 2: quads[8].v.ob[0] = -width / 2; quads[8].v.ob[1] = 0; quads[8].v.ob[2] = 0; quads[9].v.ob[0] = 0; quads[9].v.ob[1] = 0; quads[9].v.ob[2] = 0; quads[10].v.ob[0] = -width / 2; quads[10].v.ob[1] = height / 2; quads[10].v.ob[2] = 0; quads[11].v.ob[0] = 0; quads[11].v.ob[1] = height / 2; quads[11].v.ob[2] = 0; quads[8].v.tc[0] = 0; quads[8].v.tc[1] = (height / 2) * 32; quads[9].v.tc[0] = (width / 2) * 32; quads[9].v.tc[1] = (height / 2) * 32; quads[10].v.tc[0] = 0; quads[10].v.tc[1] = height * 32; quads[11].v.tc[0] = (width / 2) * 32; quads[11].v.tc[1] = height * 32; #ifndef SHIFT quads += 8; #endif break; case 3: quads[12].v.ob[0] = 0; quads[12].v.ob[1] = 0; quads[12].v.ob[2] = 0; quads[13].v.ob[0] = (-width / 2) + width; quads[13].v.ob[1] = 0; quads[13].v.ob[2] = 0; quads[14].v.ob[0] = 0; quads[14].v.ob[1] = height / 2; quads[14].v.ob[2] = 0; quads[15].v.ob[0] = (-width / 2) + width; quads[15].v.ob[1] = height / 2; quads[15].v.ob[2] = 0; quads[12].v.tc[0] = (width / 2) * 32; quads[12].v.tc[1] = (height / 2) * 32; quads[13].v.tc[0] = width * 32; quads[13].v.tc[1] = (height / 2) * 32; quads[14].v.tc[0] = (width / 2) * 32; quads[14].v.tc[1] = height * 32; quads[15].v.tc[0] = width * 32; quads[15].v.tc[1] = height * 32; #ifndef SHIFT quads += 12; #endif break; } #ifdef SHIFT gSPVertex(gMainGfxPos++, &quads[idx*4], 4, 0); #else gSPVertex(gMainGfxPos++, quads, 4, 0); #endif gSP2Triangles(gMainGfxPos++, 0, 3, 1, 0, 0, 2, 3, 0); } else { switch (idx) { case 0: gSPScisTextureRectangle(gMainGfxPos++, posX * 4, posY * 4, (posX + width / 2) * 4, (posY + height / 2) * 4, G_TX_RENDERTILE, 0, 0, 0x400, 0x400); break; case 1: gSPScisTextureRectangle(gMainGfxPos++, (posX + width / 2) * 4, posY * 4, (posX + width) * 4, (posY + height / 2) * 4, G_TX_RENDERTILE, (width / 2) * 32, 0, 0x400, 0x400); break; case 2: gSPScisTextureRectangle(gMainGfxPos++, posX * 4, (posY + height / 2) * 4, (posX + width / 2) * 4, (posY + height) * 4, G_TX_RENDERTILE, 0, (height / 2) * 32, 0x400, 0x400); break; case 3: gSPScisTextureRectangle(gMainGfxPos++, (posX + width / 2) * 4, (posY + height / 2) * 4, (posX + width) * 4, (posY + height) * 4, G_TX_RENDERTILE, (width / 2) * 32, (height / 2) * 32, 0x400, 0x400); break; } } gDPPipeSync(gMainGfxPos++); } } else if (bgImage != NULL) { if (quads != NULL) { quads[0].v.ob[0] = -width / 2; quads[0].v.ob[1] = -height / 2; quads[0].v.ob[2] = 0; quads[1].v.ob[0] = (-width / 2) + width; quads[1].v.ob[1] = -height / 2; quads[1].v.ob[2] = 0; quads[2].v.ob[0] = -width / 2; quads[2].v.ob[1] = height / 2; quads[2].v.ob[2] = 0; quads[3].v.ob[0] = (-width / 2) + width; quads[3].v.ob[1] = height / 2; quads[3].v.ob[2] = 0; quads[0].v.tc[0] = 0; quads[0].v.tc[1] = 0; quads[1].v.tc[1] = 0; quads[1].v.tc[0] = width * 32; quads[2].v.tc[0] = 0; quads[2].v.tc[1] = height * 32; quads[3].v.tc[0] = width * 32; quads[3].v.tc[1] = height * 32; gSPVertex(gMainGfxPos++, &quads[0], 4, 0); gSP2Triangles(gMainGfxPos++, 0, 3, 1, 0, 0, 2, 3, 0); } else { gSPScisTextureRectangle(gMainGfxPos++, posX * 4, posY * 4, (posX + width) * 4, (posY + height) * 4, G_TX_RENDERTILE, 0, 0, 0x0400, 0x0400); } gDPPipeSync(gMainGfxPos++); } gDPSetTexturePersp(gMainGfxPos++, G_TP_NONE); gDPSetCycleType(gMainGfxPos++, G_CYC_1CYCLE); if(fpDrawContents != NULL) { if (quads != NULL) { void* mdl_address = mdl_get_next_texture_address(width * height * 2); if(mdl_address != 0) { gDPSetColorImage(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, OS_K0_TO_PHYSICAL(mdl_address)); gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, 0, 0, width, height); gDPSetCycleType(gMainGfxPos++, G_CYC_FILL); gDPSetFillColor(gMainGfxPos++, PACK_FILL_COLOR(primR, primG, primB, 0)); gDPSetRenderMode(gMainGfxPos++, G_RM_NOOP, G_RM_NOOP2); gDPFillRectangle(gMainGfxPos++, 0, 0, width - 1, height - 1); gDPPipeSync(gMainGfxPos++); gDPSetScissorFrac(gMainGfxPos++, G_SC_NON_INTERLACE, 4, 4, (width - 1) * 4.0f, (height - 1) * 4.0f); gDPSetCycleType(gMainGfxPos++, G_CYC_1CYCLE); fpDrawContents((s32)drawContentsArg0, 0, 0, width, height, opacity, darkening); gDPPipeSync(gMainGfxPos++); gDPSetColorImage(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, OS_K0_TO_PHYSICAL(nuGfxCfb_ptr)); gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE, 0, 0, 320, 240); gSPViewport(gMainGfxPos++, &gBoxViewport); gSPMatrix(gMainGfxPos++, sp154, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); gSPTexture(gMainGfxPos++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); gDPSetCycleType(gMainGfxPos++, G_CYC_1CYCLE); gDPSetTextureLUT(gMainGfxPos++, G_TT_NONE); gDPSetCombineMode(gMainGfxPos++, G_CC_DECALRGBA, G_CC_DECALRGBA); gDPSetRenderMode(gMainGfxPos++, G_RM_CLD_SURF, G_RM_NOOP2); gDPSetTexturePersp(gMainGfxPos++, G_TP_PERSP); gDPSetTextureFilter(gMainGfxPos++, G_TF_BILERP); guTranslateF(mtx3, 0.0f, 6.0f, 0.0f); guMtxF2L(mtx3, &gBoxMatrix); guTranslateF(mtx3, 0.0f, -height / 2, 0.0f); guMtxF2L(mtx3, &gDisplayContext->matrixStack[gMatrixListPos]); gSPMatrix(gMainGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); for (idx = 0; idx < height / 6; idx++) { s32 extraHeight, lineHeight; if (idx == height / 6 - 1) { extraHeight = 0; if (height % 6 != 0) { extraHeight = 1; } } else { extraHeight = 1; } lineHeight = extraHeight + 5; gDPLoadTextureTile(gMainGfxPos++, OS_K0_TO_PHYSICAL(mdl_address), G_IM_FMT_RGBA, G_IM_SIZ_16b, width, 0, 0, idx * 6, width - 1, idx * 6 + lineHeight, 0, G_TX_CLAMP, G_TX_CLAMP, 9, 3, G_TX_NOLOD, G_TX_NOLOD); gDPSetTileSize(gMainGfxPos++, G_TX_RENDERTILE, (160 - width / 2) * 4, 0, ((160 - width / 2) + width - 1) * 4, lineHeight * 4); gSPVertex(gMainGfxPos++, &vtx_drawbox1, 4, 0); gSP2Triangles(gMainGfxPos++, 0, 3, 1, 0, 0, 2, 3, 0); gDPPipeSync(gMainGfxPos++); gSPMatrix(gMainGfxPos++, &gBoxMatrix, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); } } } else { fpDrawContents((s32)drawContentsArg0, posX, posY, width, height, opacity, darkening); } } if (quads != NULL) { gSPPopMatrix(gMainGfxPos++, G_MTX_MODELVIEW); gDPSetTexturePersp(gMainGfxPos++, G_TP_NONE); gDPPipeSync(gMainGfxPos++); } return FALSE; } }