added new GBI command: G_COPYMEM

exclusively for copying lights around for now; required for my retarded model color implementation
This commit is contained in:
fgsfds 2021-04-06 00:18:04 +03:00
parent d4cdd89683
commit 798389b527
2 changed files with 54 additions and 1 deletions

View file

@ -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)

View file

@ -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));