From 66c11d93296677e1da14de491199f4b98312cc84 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Tue, 6 Apr 2021 00:18:04 +0300 Subject: [PATCH] added new GBI command: G_COPYMEM exclusively for copying lights around for now; required for my retarded model color implementation --- include/PR/gbi.h | 32 ++++++++++++++++++++++++++++++++ src/pc/gfx/gfx_pc.c | 23 ++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/include/PR/gbi.h b/include/PR/gbi.h index bd981be8..dd1bb440 100644 --- a/include/PR/gbi.h +++ b/include/PR/gbi.h @@ -118,6 +118,11 @@ #define G_SPECIAL_2 0xd4 #define G_SPECIAL_3 0xd3 +#ifdef F3DEX_GBI_2E +/* extended commands */ +#define G_COPYMEM 0xd2 +#endif + #define G_VTX 0x01 #define G_MODIFYVTX 0x02 #define G_CULLDL 0x03 @@ -1790,6 +1795,22 @@ typedef union { (uintptr_t)(adrs) \ }} +#ifdef F3DEX_GBI_2E +#define gCopyMemEXT(pkt, c, idx, dst, src, len) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + _g->words.w0 = (_SHIFTL((c),24,8)|_SHIFTL((src)/8,16,8)| \ + _SHIFTL((dst)/8,8,8)|_SHIFTL((idx),0,8)); \ + _g->words.w1 = (uintptr_t)(((len)-1)/8); \ +} +#define gsCopyMemEXT(c, idx, dst, src, len) \ +{{ \ + (_SHIFTL((c),24,8)|_SHIFTL((src)/8,16,8)| \ + _SHIFTL((dst)/8,8,8)|_SHIFTL((idx),0,8)), \ + (uintptr_t)(((len)-1)/8) \ +}} +#endif + #define gSPNoOp(pkt) gDma0p(pkt, G_SPNOOP, 0, 0) #define gsSPNoOp() gsDma0p(G_SPNOOP, 0, 0) @@ -2541,6 +2562,17 @@ typedef union { gsDma1p( G_MOVEMEM, l, sizeof(Light),((n)-1)*2+G_MV_L0) #endif /* F3DEX_GBI_2 */ +/* + * EXTENDED COMMAND + * Copy one light's parameters to the other. + */ +#ifdef F3DEX_GBI_2E +# define gSPCopyLightEXT(pkt, dst, src) \ + gCopyMemEXT((pkt),G_COPYMEM,G_MV_LIGHT,(dst)*24+24,(src)*24+24,sizeof(Light)) +# define gsSPCopyLightEXT(dst, src) \ + gsCopyMemEXT( G_COPYMEM,G_MV_LIGHT,(dst)*24+24,(src)*24+24,sizeof(Light)) +#endif + /* * gSPLightColor changes color of light without recalculating light direction * col is a 32 bit word with r,g,b,a (alpha is ignored) diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index a78f2ffd..876d9f54 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -47,7 +47,7 @@ #define RATIO_Y (gfx_current_dimensions.height / (2.0f * HALF_SCREEN_HEIGHT)) #define MAX_BUFFERED 256 -#define MAX_LIGHTS 2 +#define MAX_LIGHTS 8 #define MAX_VERTICES 64 #ifdef EXTERNAL_DATA @@ -1123,6 +1123,10 @@ static void gfx_sp_movemem(uint8_t index, uint8_t offset, const void* data) { case G_MV_L0: case G_MV_L1: case G_MV_L2: + case G_MV_L3: + case G_MV_L4: + case G_MV_L5: + case G_MV_L6: // NOTE: reads out of bounds if it is an ambient light memcpy(rsp.current_lights + (index - G_MV_L0) / 2, data, sizeof(Light_t)); break; @@ -1130,6 +1134,18 @@ static void gfx_sp_movemem(uint8_t index, uint8_t offset, const void* data) { } } +#ifdef F3DEX_GBI_2E +static void gfx_sp_copymem(uint8_t idx, uint8_t dstofs, uint8_t srcofs, uint8_t words) { + if (idx == G_MV_LIGHT) { + const int srcidx = srcofs / 24 - 2; + const int dstidx = dstofs / 24 - 2; + if (srcidx <= MAX_LIGHTS && dstidx <= MAX_LIGHTS) { + memcpy(rsp.current_lights + dstidx, rsp.current_lights + srcidx, sizeof(Light_t)); + } + } +} +#endif + static void gfx_sp_moveword(uint8_t index, uint16_t offset, uint32_t data) { switch (index) { case G_MW_NUMLIGHT: @@ -1538,6 +1554,11 @@ static void gfx_run_dl(Gfx* cmd) { gfx_sp_moveword(C0(0, 8), C0(8, 16), cmd->words.w1); #endif break; +#ifdef F3DEX_GBI_2E + case (uint8_t)G_COPYMEM: + gfx_sp_copymem(C0(0, 8), C0(8, 8) * 8, C0(16, 8) * 8, C1(0, 8)); + break; +#endif case (uint8_t)G_TEXTURE: #ifdef F3DEX_GBI_2 gfx_sp_texture(C1(16, 16), C1(0, 16), C0(11, 3), C0(8, 3), C0(1, 7));