diff --git a/src/RDP.h b/src/RDP.h index da90f03d..d773ec1d 100644 --- a/src/RDP.h +++ b/src/RDP.h @@ -16,6 +16,7 @@ extern RDPInfo RDP; void RDP_Init(); void RDP_Half_1(u32 _c); +void RDP_TexRect(u32 w0, u32 w1); void RDP_ProcessRDPList(); void RDP_RepeatLastLoadBlock(); void RDP_SetScissor(u32 w0, u32 w1); diff --git a/src/S2DEX.cpp b/src/S2DEX.cpp index d873840d..e38579b6 100644 --- a/src/S2DEX.cpp +++ b/src/S2DEX.cpp @@ -1,3 +1,4 @@ +#include #include "OpenGL.h" #include "S2DEX.h" #include "F3D.h" @@ -6,6 +7,7 @@ #include "gSP.h" #include "gDP.h" #include "RSP.h" +#include "RDP.h" #include "Types.h" #include "Log.h" @@ -57,9 +59,41 @@ void S2DEX_MoveWord( u32 w0, u32 w1 ) } } +void S2DEX_RDPHalf_0( u32 w0, u32 w1 ) { + if (RSP.nextCmd == G_SELECT_DL) { + gSP.selectDL.addr = _SHIFTR(w0, 0, 16); + gSP.selectDL.sid = _SHIFTR(w0, 18, 8); + gSP.selectDL.flag = w1; + return; + } + if (RSP.nextCmd == G_RDPHALF_1) { + RDP_TexRect(w0, w1); + return; + } + assert(false); +} + void S2DEX_Select_DL( u32 w0, u32 w1 ) { - LOG(LOG_WARNING, "S2DEX_Select_DL unimplemented\n"); + gSP.selectDL.addr |= (_SHIFTR(w0, 0, 16)) << 16; + const u8 sid = gSP.selectDL.sid; + const u32 flag = gSP.selectDL.flag; + const u32 mask = w1; + if ((gSP.status[sid] & mask) == flag) + // Do nothing; + return; + + gSP.status[sid] = (gSP.status[sid] & ~mask) | (flag & mask); + + switch (_SHIFTR( w0, 16, 8 )) + { + case G_DL_PUSH: + gSPDisplayList( gSP.selectDL.addr ); + break; + case G_DL_NOPUSH: + gSPBranchList( gSP.selectDL.addr ); + break; + } } void S2DEX_Obj_RenderMode( u32 w0, u32 w1 ) @@ -119,6 +153,7 @@ void S2DEX_Init() GBI_SetGBI( G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, F3D_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, F3D_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3D_ENDDL, F3D_EndDL ); + GBI_SetGBI( G_RDPHALF_0, S2DEX_RDPHALF_0, S2DEX_RDPHalf_0 ); GBI_SetGBI( G_RDPHALF_1, F3D_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3D_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_LOAD_UCODE, S2DEX_LOAD_UCODE, F3DEX_Load_uCode ); diff --git a/src/S2DEX.h b/src/S2DEX.h index a608e132..f98a4a43 100644 --- a/src/S2DEX.h +++ b/src/S2DEX.h @@ -173,6 +173,7 @@ void S2DEX_BG_Copy( u32 w0, u32 w1 ); void S2DEX_Obj_Rectangle( u32 w0, u32 w1 ); void S2DEX_Obj_Sprite( u32 w0, u32 w1 ); void S2DEX_Obj_MoveMem( u32 w0, u32 w1 ); +void S2DEX_RDPHalf_0( u32 w0, u32 w1 ); void S2DEX_Select_DL( u32 w0, u32 w1 ); void S2DEX_Obj_RenderMode( u32 w0, u32 w1 ); void S2DEX_Obj_Rectangle_R( u32 w0, u32 w1 ); diff --git a/src/S2DEX2.cpp b/src/S2DEX2.cpp index 51c30646..7dd1431f 100644 --- a/src/S2DEX2.cpp +++ b/src/S2DEX2.cpp @@ -50,6 +50,7 @@ void S2DEX2_Init() GBI_SetGBI( G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, F3DEX2_SetOtherMode_H ); GBI_SetGBI( G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, F3DEX2_SetOtherMode_L ); GBI_SetGBI( G_ENDDL, F3DEX2_ENDDL, F3D_EndDL ); + GBI_SetGBI( G_RDPHALF_0, S2DEX2_RDPHALF_0, S2DEX_RDPHalf_0 ); GBI_SetGBI( G_RDPHALF_1, F3DEX2_RDPHALF_1, F3D_RDPHalf_1 ); GBI_SetGBI( G_RDPHALF_2, F3DEX2_RDPHALF_2, F3D_RDPHalf_2 ); GBI_SetGBI( G_LOAD_UCODE, F3DEX2_LOAD_UCODE, F3DEX_Load_uCode ); diff --git a/src/gSP.cpp b/src/gSP.cpp index a23e27d2..d7258e1d 100644 --- a/src/gSP.cpp +++ b/src/gSP.cpp @@ -1791,6 +1791,7 @@ void gSPLineW3D( s32 v0, s32 v1, s32 wd, s32 flag ) void gSPSetStatus(u32 sid, u32 val) { + assert(sid <= 12); gSP.status[sid>>2] = val; } diff --git a/src/gSP.h b/src/gSP.h index ca8032e1..273d580c 100644 --- a/src/gSP.h +++ b/src/gSP.h @@ -119,6 +119,11 @@ struct gSPInfo u32 changed; + struct { + u8 sid; + u32 flag; + u32 addr; + } selectDL; u32 status[4]; struct