From 84e37e1fb119e2367b59f1c5ff0f3ae69743a354 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Fri, 26 Apr 2024 21:52:07 -0400 Subject: [PATCH] Implement & link PreRender Co-authored by: Prakxo --- config/rel_slices.yml | 9 +- include/PreRender.h | 244 ++++++++++++++++++++++++++++++++++--- include/sys_ucode.h | 6 +- src/PreRender.c | 276 ++++++++++++++++++++++++++++++++++++++++++ src/m_play.c | 4 +- 5 files changed, 513 insertions(+), 26 deletions(-) create mode 100644 src/PreRender.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index a5dc12fb..9d0709b4 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -323,6 +323,9 @@ m_vibctl.c: .text: [0x8040387C, 0x804040F0] .rodata: [0x80643550, 0x806436C8] .bss: [0x812F3098, 0x812F31B8] +PreRender.c: + .text: [0x804040F0, 0x80404AE0] + .rodata: [0x806436C8, 0x806436E8] THA_GA.c: .text: [0x80404AE0, 0x80404B40] TwoHeadArena.c: @@ -357,14 +360,14 @@ main.c: .text: [0x80407AE8, 0x80407CF4] .data: [0x8065F110, 0x8065F138] .bss: [0x812F4CC0, 0x812F5038] +sys_math.c: + .text: [0x80408940, 0x80408A44] + .rodata: [0x806437C0, 0x806437D0] sys_math3d.c: .text: [0x80408A44, 0x8040C06C] .rodata: [0x806437D0, 0x80643810] .data: [0x8065F150, 0x8065F168] .bss: [0x812F54A0, 0x812F5668] -sys_math.c: - .text: [0x80408940, 0x80408A44] - .rodata: [0x806437C0, 0x806437D0] sys_math_atan.c: .text: [0x8040C06C, 0x8040C284] .rodata: [0x80643810, 0x80643828] diff --git a/include/PreRender.h b/include/PreRender.h index 899ffebd..c330b573 100644 --- a/include/PreRender.h +++ b/include/PreRender.h @@ -2,35 +2,241 @@ #define PRERENDER_H #include "types.h" +#include "libforest/gbi_extensions.h" #ifdef __cplusplus extern "C" { #endif +#define G_OBJ_RECTANGLE_R 0xDA +#define G_OBJ_MOVEMEM 0xDC +#define G_RDPHALF_0 0xE4 +#define G_OBJ_RECTANGLE 0x01 +#define G_OBJ_SPRITE 0x02 +#define G_SELECT_DL 0x04 +#define G_OBJ_LOADTXTR 0x05 +#define G_OBJ_LDTX_SPRITE 0x06 +#define G_OBJ_LDTX_RECT 0x07 +#define G_OBJ_LDTX_RECT_R 0x08 +#define G_BG_1CYC 0x09 +#define G_BG_COPY 0x0A +#define G_OBJ_RENDERMODE 0x0B + +#define G_OBJRM_NOTXCLAMP 0x01 +#define G_OBJRM_XLU 0x02 /* Ignored */ +#define G_OBJRM_ANTIALIAS 0x04 /* Ignored */ +#define G_OBJRM_BILERP 0x08 +#define G_OBJRM_SHRINKSIZE_1 0x10 +#define G_OBJRM_SHRINKSIZE_2 0x20 +#define G_OBJRM_WIDEN 0x40 + +/*---------------------------------------------------------------------------* + * Background wrapped screen + *---------------------------------------------------------------------------*/ +#define gSPBgRectangle(pkt, m, mptr) gDma0p((pkt), (m), (mptr), 0) +#define gsSPBgRectangle(m, mptr) gsDma0p((m), (mptr), 0) +#define gSPBgRectCopy(pkt, mptr) gSPBgRectangle((pkt), G_BG_COPY, (mptr)) +#define gsSPBgRectCopy(mptr) gsSPBgRectangle(G_BG_COPY, (mptr)) +#define gSPBgRect1Cyc(pkt, mptr) gSPBgRectangle((pkt), G_BG_1CYC, (mptr)) +#define gsSPBgRect1Cyc(mptr) gsSPBgRectangle(G_BG_1CYC, (mptr)) + +/*---------------------------------------------------------------------------* + * 2D Objects + *---------------------------------------------------------------------------*/ +#define gSPObjSprite(pkt, mptr) gDma0p((pkt), G_OBJ_SPRITE, (mptr), 0) +#define gsSPObjSprite(mptr) gsDma0p(G_OBJ_SPRITE, (mptr), 0) +#define gSPObjRectangle(pkt, mptr) gDma0p((pkt), G_OBJ_RECTANGLE, (mptr), 0) +#define gsSPObjRectangle(mptr) gsDma0p(G_OBJ_RECTANGLE, (mptr), 0) +#define gSPObjRectangleR(pkt, mptr) gDma0p((pkt), G_OBJ_RECTANGLE_R, (mptr), 0) +#define gsSPObjRectangleR(mptr) gsDma0p(G_OBJ_RECTANGLE_R, (mptr), 0) + +/*---------------------------------------------------------------------------* + * 2D Matrix + *---------------------------------------------------------------------------*/ +#define gSPObjMatrix(pkt, mptr) gDma1p((pkt), G_OBJ_MOVEMEM, (mptr), 0, 23) +#define gsSPObjMatrix(mptr) gsDma1p(G_OBJ_MOVEMEM, (mptr), 0, 23) +#define gSPObjSubMatrix(pkt, mptr) gDma1p((pkt), G_OBJ_MOVEMEM, (mptr), 2, 7) +#define gsSPObjSubMatrix(mptr) gsDma1p(G_OBJ_MOVEMEM, (mptr), 2, 7) + +/*---------------------------------------------------------------------------* + * Loading into TMEM + *---------------------------------------------------------------------------*/ +#define gSPObjLoadTxtr(pkt, tptr) gDma0p((pkt), G_OBJ_LOADTXTR, (tptr), 23) +#define gsSPObjLoadTxtr(tptr) gsDma0p(G_OBJ_LOADTXTR, (tptr), 23) +#define gSPObjLoadTxSprite(pkt, tptr) gDma0p((pkt), G_OBJ_LDTX_SPRITE, (tptr), 47) +#define gsSPObjLoadTxSprite(tptr) gsDma0p(G_OBJ_LDTX_SPRITE, (tptr), 47) +#define gSPObjLoadTxRect(pkt, tptr) gDma0p((pkt), G_OBJ_LDTX_RECT, (tptr), 47) +#define gsSPObjLoadTxRect(tptr) gsDma0p(G_OBJ_LDTX_RECT, (tptr), 47) +#define gSPObjLoadTxRectR(pkt, tptr) gDma0p((pkt), G_OBJ_LDTX_RECT_R, (tptr), 47) +#define gsSPObjLoadTxRectR(tptr) gsDma0p(G_OBJ_LDTX_RECT_R, (tptr), 47) + +/*---------------------------------------------------------------------------* + * Select Display List + *---------------------------------------------------------------------------*/ +#define gSPSelectDL(pkt, mptr, sid, flag, mask) \ + { \ + gDma1p((pkt), G_RDPHALF_0, (flag), (u32)(mptr) & 0xFFFF, (sid)); \ + gDma1p((pkt), G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_PUSH); \ + } +#define gsSPSelectDL(mptr, sid, flag, mask) \ + { \ + gsDma1p(G_RDPHALF_0, (flag), (u32)(mptr) & 0xFFFF, (sid)); \ + gsDma1p(G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_PUSH); \ + } +#define gSPSelectBranchDL(pkt, mptr, sid, flag, mask) \ + { \ + gDma1p((pkt), G_RDPHALF_0, (flag), (u32)(mptr) & 0xFFFF, (sid)); \ + gDma1p((pkt), G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_NOPUSH); \ + } +#define gsSPSelectBranchDL(mptr, sid, flag, mask) \ + { \ + gsDma1p(G_RDPHALF_0, (flag), (u32)(mptr) & 0xFFFF, (sid)); \ + gsDma1p(G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_NOPUSH); \ + } + +#define G_OBJRM_NOTXCLAMP 0x01 +#define G_OBJRM_XLU 0x02 /* Ignored */ +#define G_OBJRM_ANTIALIAS 0x04 /* Ignored */ +#define G_OBJRM_BILERP 0x08 +#define G_OBJRM_SHRINKSIZE_1 0x10 +#define G_OBJRM_SHRINKSIZE_2 0x20 +#define G_OBJRM_WIDEN 0x40 + +#define gSPObjRenderMode(pkt, mode) gImmp1((pkt), G_OBJ_RENDERMODE, (mode)) +#define gsSPObjRenderMode(mode) gsImmp1(G_OBJ_RENDERMODE, (mode)) + +#define G_BGLT_LOADBLOCK 0x0033 +#define G_BGLT_LOADTILE 0xFFF4 + +#define BG2D_FLAGS_1 (1 << 0) +#define BG2D_FLAGS_2 (1 << 1) +#define BG2D_FLAGS_AC_THRESHOLD (1 << 2) +#define BG2D_FLAGS_LOAD_S2DEX2 (1 << 3) +#define BG2D_FLAGS_COPY (1 << 4) + typedef struct prerender_s { - u16 width; - u16 height; - - u16 width_bak; - u16 height_bak; - - u8 _08[8]; - - void* framebuffer; - void* framebuffer_bak; - - void* _18; - - int _1C; - int _20; - - u8 _24[0x24]; + /* 0x00 */ u16 width; + /* 0x02 */ u16 height; + /* 0x04 */ u16 width_bak; + /* 0x06 */ u16 height_bak; + /* 0x08 */ u16 unk8; + /* 0x0A */ u16 unkA; + /* 0x0C */ u8 unkC; + /* 0x0D */ u8 unkD; + /* 0x0E */ u16 unkE; /* inferred */ + /* 0x10 */ u16* framebuffer; + /* 0x14 */ u16* framebuffer_bak; + /* 0x18 */ u8* cvg_bak; + /* 0x1C */ u16* zbuffer; + /* 0x20 */ u16* zbuffer_bak; + /* 0x24 */ u16 ulx_bak; + /* 0x26 */ u16 uly_bak; + /* 0x28 */ u16 lrx_bak; + /* 0x2A */ u16 lry_bak; + /* 0x2C */ u16 ulx; + /* 0x2E */ u16 uly; + /* 0x30 */ u16 lrx; + /* 0x32 */ u16 lry; + /* 0x34 */ u8 _34[0x14]; } PreRender; -extern void PreRender_setup_savebuf(PreRender* render, int arg1, int arg2, int arg3, int arg4, int arg5); +typedef struct { + /* 0x00 */ void* timg; + /* 0x04 */ void* tlut; + /* 0x08 */ u16 width; + /* 0x0A */ u16 height; + /* 0x0C */ u8 fmt; + /* 0x0D */ u8 siz; + /* 0x0E */ u16 tt; + /* 0x10 */ u16 tlutCount; + /* 0x14 */ f32 x; + /* 0x18 */ f32 y; + /* 0x1C */ f32 xScale; + /* 0x20 */ f32 yScale; + /* 0x24 */ u32 flags; +} PreRenderBackground2DParams; // size = 0x28 + +/* Non scalable background plane */ +typedef struct { + u16 imageX; /* x-coordinate of upper-left position of texture (u10.5) */ + u16 imageW; /* width of the texture (u10.2) */ + s16 frameX; /* upper-left position of transferred frame (s10.2) */ + u16 frameW; /* width of transferred frame (u10.2) */ + + u16 imageY; /* y-coordinate of upper-left position of texture (u10.5) */ + u16 imageH; /* height of the texture (u10.2) */ + s16 frameY; /* upper-left position of transferred frame (s10.2) */ + u16 frameH; /* height of transferred frame (u10.2) */ + + u64* imagePtr; /* texture source address on DRAM */ + u16 imageLoad; /* which to use, LoadBlock or LoadTile */ + u8 imageFmt; /* format of texel - G_IM_FMT_* */ + u8 imageSiz; /* size of texel - G_IM_SIZ_* */ + u16 imagePal; /* pallet number */ + u16 imageFlip; /* right & left image inversion (Inverted by G_BG_FLAG_FLIPS) */ + + /* The following is set in the initialization routine guS2DInitBg(). There is no need for the user to set it. */ + u16 tmemW; /* TMEM width and Word size of frame 1 line. + At LoadBlock, GS_PIX2TMEM(imageW/4,imageSiz) + At LoadTile GS_PIX2TMEM(frameW/4,imageSiz)+1 */ + u16 tmemH; /* height of TMEM loadable at a time (s13.2) 4 times value + When the normal texture, 512/tmemW*4 + When the CI texture, 256/tmemW*4 */ + u16 tmemLoadSH; /* SH value + At LoadBlock, tmemSize/2-1 + At LoadTile, tmemW*16-1 */ + u16 tmemLoadTH; /* TH value or Stride value + At LoadBlock, GS_CALC_DXT(tmemW) + At LoadTile, tmemH-1 */ + u16 tmemSizeW; /* skip value of imagePtr for image 1-line + At LoadBlock, tmemW*2 + At LoadTile, GS_PIX2TMEM(imageW/4,imageSiz)*2 */ + u16 tmemSize; /* skip value of imagePtr for 1-loading + = tmemSizeW*tmemH */ +} uObjBg_t; /* 40 bytes */ + +/* Scalable background plane */ +typedef struct { + u16 imageX; /* x-coordinate of upper-left position of texture (u10.5) */ + u16 imageW; /* width of texture (u10.2) */ + s16 frameX; /* upper-left position of transferred frame (s10.2) */ + u16 frameW; /* width of transferred frame (u10.2) */ + + u16 imageY; /* y-coordinate of upper-left position of texture (u10.5) */ + u16 imageH; /* height of texture (u10.2) */ + s16 frameY; /* upper-left position of transferred frame (s10.2) */ + u16 frameH; /* height of transferred frame (u10.2) */ + + u64* imagePtr; /* texture source address on DRAM */ + u16 imageLoad; /* Which to use, LoadBlock or LoadTile? */ + u8 imageFmt; /* format of texel - G_IM_FMT_* */ + u8 imageSiz; /* size of texel - G_IM_SIZ_* */ + u16 imagePal; /* pallet number */ + u16 imageFlip; /* right & left image inversion (Inverted by G_BG_FLAG_FLIPS) */ + + u16 scaleW; /* scale value of X-direction (u5.10) */ + u16 scaleH; /* scale value of Y-direction (u5.10) */ + s32 imageYorig; /* start point of drawing on image (s20.5) */ + + u8 padding[4]; + +} uObjScaleBg_t; /* 40 bytes */ + +typedef union { + uObjBg_t b; + uObjScaleBg_t s; + long long int force_structure_alignment; +} uObjBg; + +extern void wallpaper_draw1(PreRenderBackground2DParams* bg2D, Gfx** gfxp); +extern void wallpaper_draw(Gfx** const gfxp, u16* const timg, u16* const tlut, const u16 width, const u16 height, + const u8 fmt, const u8 siz, const u16 tt, const u16 tlutCount, f32 x, const f32 y, + const f32 xScale, const f32 yScale, const u32 flags); +extern void PreRender_setup_savebuf(PreRender* render, u32 width, u32 height, void* fbuf, void* zbuf, void* cvg); extern void PreRender_init(PreRender* render); -extern void PreRender_setup_renderbuf(PreRender* render, int arg1, int arg2, void* arg3, void* arg4); +extern void PreRender_setup_renderbuf(PreRender* render, u32 width, u32 height, void* fbuf, void* zbuf); extern void PreRender_cleanup(PreRender* render); +extern void PreRender_CopyRGBC(PreRender* render, Gfx** gfxp, int width, int height); #ifdef __cplusplus } diff --git a/include/sys_ucode.h b/include/sys_ucode.h index 4bc34ffb..6f67ff50 100644 --- a/include/sys_ucode.h +++ b/include/sys_ucode.h @@ -9,8 +9,8 @@ extern "C" { #endif typedef struct ucode_info_s { - int type; - void* ucode_p; + int type; + void* ucode_p; } ucode_info; #define UCODE_TYPE_NONE 0 @@ -19,6 +19,8 @@ typedef struct ucode_info_s { #define UCODE_TYPE_SPRITE_TEXT 3 #define UCODE_TYPE_SPRITE_DATA 4 +#define SP_UCODE_DATA_SIZE 0x800 + extern long long int gspF3DZEX2_NoN_PosLight_fifoDataStart[]; extern long long int gspF3DZEX2_NoN_PosLight_fifoTextStart[]; diff --git a/src/PreRender.c b/src/PreRender.c new file mode 100644 index 00000000..83336ddc --- /dev/null +++ b/src/PreRender.c @@ -0,0 +1,276 @@ +#include "PreRender.h" + +#include "libultra/libultra.h" +#include "gfxalloc.h" +#include "sys_ucode.h" +#include "libforest/gbi_extensions.h" + +extern void wallpaper_draw1(PreRenderBackground2DParams* bg2D, Gfx** gfxp) { + Gfx* gfx; + uObjBg* bg; + int alphaCompare; + Gfx* gfxTemp; + int loadS2DEX2; + + loadS2DEX2 = (bg2D->flags & BG2D_FLAGS_LOAD_S2DEX2) != 0; + alphaCompare = (bg2D->flags & BG2D_FLAGS_AC_THRESHOLD) ? G_AC_THRESHOLD : G_AC_NONE; + + gfxTemp = *gfxp; + bg = (uObjBg*)gfxalloc(&gfxTemp, sizeof(uObjBg)); + gfx = gfxTemp; + + bg->b.imageX = 0; + bg->b.imageW = (bg2D->width * (1 << 2)) + 1; + bg->b.frameX = bg2D->x * (1 << 2); + + bg->b.imageY = 0; + bg->b.imageH = (bg2D->height * (1 << 2)) + 1; + bg->b.frameY = bg2D->y * (1 << 2); + + bg->b.imagePtr = bg2D->timg; + bg->b.imageLoad = G_BGLT_LOADTILE; + bg->b.imageFmt = bg2D->fmt; + bg->b.imageSiz = bg2D->siz; + bg->b.imagePal = 0; + bg->b.imageFlip = 0; + + if (loadS2DEX2 != 0) { + gSPLoadUcode(gfx++, ucode_GetSpriteTextStart(), ucode_GetSpriteDataStart()); + } + + if ((bg2D->fmt == G_IM_FMT_CI) && (bg2D->tlut != NULL)) { + gDPLoadTLUT(gfx++, bg2D->tlutCount, 256, bg2D->tlut); + } else { + gDPPipeSync(gfx++); + } + + if (bg2D->flags & BG2D_FLAGS_COPY) { + bg->b.frameW = bg2D->width * (1 << 2); + bg->b.frameH = bg2D->height * (1 << 2); + + if (!(bg2D->flags & BG2D_FLAGS_1)) { + gDPSetOtherMode(gfx++, bg2D->tt | G_CYC_COPY, alphaCompare); + } + + gSPBgRectCopy(gfx++, bg); + } else { + bg->b.frameW = ((u32)bg2D->width << 2) * bg2D->xScale; + bg->b.frameH = ((u32)bg2D->height << 2) * bg2D->yScale; + bg->b.tmemW = (1 << 10) / bg2D->xScale; + bg->b.tmemH = (1 << 10) / bg2D->yScale; + bg->s.imageYorig = bg->b.imageY; + + if (!(bg2D->flags & BG2D_FLAGS_1)) { + gDPSetOtherMode(gfx++, bg2D->tt | G_AD_DISABLE | G_CD_DISABLE | G_TC_FILT, + AA_EN | CVG_X_ALPHA | ALPHA_CVG_SEL | + GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_BL, G_BL_1MA) | + GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_BL, G_BL_1MA) | alphaCompare); + } + + if (!(bg2D->flags & BG2D_FLAGS_2)) { + gDPSetCombineLERP(gfx++, 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1); + } + + gSPObjRenderMode(gfx++, G_OBJRM_ANTIALIAS | G_OBJRM_BILERP); + gSPBgRect1Cyc(gfx++, bg); + } + + gDPPipeSync(gfx++); + + if (loadS2DEX2) { + gSPLoadUcode(gfx++, ucode_GetPolyTextStart(), ucode_GetPolyDataStart()); + } + + *gfxp = gfx; +} + +extern void wallpaper_draw(Gfx** const gfxp, u16* const timg, u16* const tlut, const u16 width, const u16 height, + const u8 fmt, const u8 siz, const u16 tt, const u16 tlutCount, f32 x, const f32 y, + const f32 xScale, const f32 yScale, const u32 flags) { + + PreRenderBackground2DParams bg2D; + + bg2D.timg = timg; + bg2D.tlut = tlut; + bg2D.width = width; + bg2D.height = height; + bg2D.fmt = fmt; + bg2D.siz = siz; + bg2D.tt = tt; + bg2D.tlutCount = tlutCount; + bg2D.x = x; + bg2D.y = y; + bg2D.xScale = xScale; + bg2D.yScale = yScale; + bg2D.flags = flags; + + wallpaper_draw1(&bg2D, gfxp); +} + +static Gfx* gfx_SetUpCFB(Gfx* gfx, void* ptr, u32 width, u32 heiht) { + + gDPPipeSync(gfx + 0); + gDPSetColorImage(gfx + 1, G_IM_FMT_RGBA, G_IM_SIZ_16b, width, ptr); + gDPSetScissor(gfx + 2, G_SC_NON_INTERLACE, 0, 0, width, heiht); + + return gfx + 3; +} + +extern void PreRender_setup_savebuf(PreRender* render, u32 width, u32 height, void* fbuf, void* zbuf, void* cvg) { + render->width_bak = width; + render->height_bak = height; + + render->framebuffer_bak = fbuf; + render->cvg_bak = cvg; + + render->zbuffer_bak = zbuf; + + render->ulx_bak = 0; + render->uly_bak = 0; + render->lrx_bak = width - 1; + render->lry_bak = height - 1; +} + +extern void PreRender_init(PreRender* render) { + bzero(render, sizeof(PreRender)); +} + +extern void PreRender_setup_renderbuf(PreRender* render, u32 width, u32 height, void* fbuf, void* zbuf) { + render->width = width; + render->height = height; + + render->framebuffer = fbuf; + render->zbuffer = zbuf; + + render->ulx = 0; + render->uly = 0; + render->lrx = width - 1; + render->lry = height - 1; +} + +extern void PreRender_cleanup(PreRender* render) { + // nothing +} + +static void PreRender_ShowCoveredge(Gfx** gfxp, u16 ulx, u16 uly, u16 lrx, u16 lry) { + Gfx* gfx = *gfxp; + + gDPPipeSync(gfx++); + + gDPSetBlendColor(gfx++, 255, 255, 255, 8); + gDPSetPrimDepth(gfx++, -1, -1); + + gDPSetOtherMode(gfx++, + G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PRIM | G_RM_VISCVG | G_RM_VISCVG2); + + gDPFillRectangle(gfx++, ulx, uly, lrx, lry); + + gDPPipeSync(gfx++); + + *gfxp = gfx; +} + +extern void PreRender_CopyRGBC(PreRender* render, Gfx** gfxp, int width, int height) { + Gfx* gfx = *gfxp; + + u32 remain; + u32 term; + + u32 uls; + u32 ult; + u32 lrs; + u32 lrt; + + u32 w; + u32 h; + u32 lrs_max; + u32 lrt_max; + + if ((render->width_bak + width) <= 0 || (render->height_bak + height) <= 0) { + return; + } + + gDPPipeSync(gfx++); + + gfx = gfx_SetUpCFB(gfx, render->framebuffer, render->width, render->height); + + gDPSetOtherMode(gfx++, + G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2); + gDPSetCombineLERP(gfx++, 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1); + + wallpaper_draw(&gfx, render->framebuffer_bak, 0, render->width_bak, render->height_bak, 0, 2, 0, 0, width, height, + 1.0f, 1.0f, 11); + + gfx = gfx_SetUpCFB(gfx, render->framebuffer_bak, render->width_bak, render->height_bak); + + PreRender_ShowCoveredge(&gfx, 0, 0, render->width_bak, render->height_bak); + + gfx = gfx_SetUpCFB(gfx, render->framebuffer, render->width, render->height); + + gDPSetOtherMode(gfx++, + G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_2CYCLE | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PRIM | AA_EN | IM_RD | CVG_DST_WRAP | ZMODE_OPA | CVG_X_ALPHA | ALPHA_CVG_SEL | + FORCE_BL | G_RM_PASS | GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_1)); + + gDPSetCombineLERP(gfx++, 0, 0, 0, 0, 1, 0, TEXEL0, ENVIRONMENT, 0, 0, 0, COMBINED, 0, 0, 0, COMBINED); + + gDPSetEnvColor(gfx++, 255, 255, 255, 32); + + remain = (1 << 12) / (u32)((u16)render->width_bak << 1); + term = render->width_bak; + + if (width < 0) { + uls = -width; + lrs = 0; + } else { + uls = 0; + lrs = width; + } + + if (height < 0) { + ult = -height; + lrt = 0; + term = render->height_bak + height; + } else { + term = render->height_bak; + lrt = height; + ult = 0; + } + + w = (render->width_bak + width); + lrs_max = (u32)render->width_bak; + + while (term > 0) { + if (remain > term) { + remain = term; + } + + lrt_max = ult + remain; + if (lrt_max > render->width_bak) { + lrt_max = render->width_bak; + remain = render->width_bak - ult; + } + + h = lrt + remain; + + gDPLoadTextureTile(gfx++, render->framebuffer_bak, G_IM_FMT_I, G_IM_SIZ_8b, (render->width_bak << 1), + (render->height_bak << 1), (uls * 2), ult, ((lrs_max * 2) - 1), /* this has issues */ + (lrt_max - 1), 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); + + gSPTextureRectangle(gfx++, ((u32)lrs) * 4, ((u32)lrt) << G_TEXTURE_IMAGE_FRAC, ((u32)w) << G_TEXTURE_IMAGE_FRAC, + ((u32)h) << G_TEXTURE_IMAGE_FRAC, G_TX_RENDERTILE, (uls * 2) << 5, ult << 5, (1 << 1) << 10, + 1 << 10); + + term -= remain; + ult += remain; + lrt += remain; + } + gDPPipeSync(gfx++); + *gfxp = gfx; +} diff --git a/src/m_play.c b/src/m_play.c index 70b41ef9..4cd21dbb 100644 --- a/src/m_play.c +++ b/src/m_play.c @@ -444,8 +444,8 @@ void play_init(GAME* game) { play->submenu.mode = 0; PreRender_init(&play->prerender); - PreRender_setup_savebuf(&play->prerender, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2, 0, 0, 0); - PreRender_setup_renderbuf(&play->prerender, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2, 0, 0); + PreRender_setup_savebuf(&play->prerender, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2, NULL, NULL, NULL); + PreRender_setup_renderbuf(&play->prerender, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2, NULL, NULL); play->fb_mode = 0; type = 1;