Skip to content

Commit

Permalink
Several improvements to S2DEX and Sprite2D ucodes.
Browse files Browse the repository at this point in the history
Thanks to Salvy.
  • Loading branch information
Rinnegatamante committed Aug 5, 2020
1 parent a27921b commit 5ce03e6
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 171 deletions.
1 change: 1 addition & 0 deletions Source/Core/ROM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ void SpecificGameHacks( const ROMHeader & id )
case 0x4441: g_ROM.GameHacks = WORMS_ARMAGEDDON; break;
case 0x4F50: g_ROM.GameHacks = POKEMON_STADIUM; break;
case 0x3350: g_ROM.GameHacks = POKEMON_STADIUM; break; // Pokemon Stadium 2
case 0x3357: g_ROM.GameHacks = WCW_NITRO; break;
case 0x4B51: // Quake 64
g_ROM.GameHacks = QUAKE;
g_ROM.KEEP_MODE_H_HACK = true;
Expand Down
1 change: 1 addition & 0 deletions Source/Core/ROM.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ enum EGameHacks
BANJO_TOOIE,
POKEMON_STADIUM,
QUAKE,
WCW_NITRO,
MAX_HACK_NAMES //DONT CHANGE THIS! AND SHOULD BE LAST ENTRY
};

Expand Down
12 changes: 1 addition & 11 deletions Source/HLEGraphics/BaseRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,22 +374,14 @@ class BaseRenderer
answ.x = roundf( LightN64ToScreenX( roundf( n64_coords.x ) ) );
answ.y = roundf( LightN64ToScreenY( roundf( n64_coords.y ) ) );
}
#ifdef DAEDALUS_VITA
virtual void RenderTriangles( uint32_t *colors, u32 num_vertices, bool disable_zbuffer ) = 0;
#else
virtual void RenderTriangles( DaedalusVtx * p_vertices, u32 num_vertices, bool disable_zbuffer ) = 0;
#endif
void TestVFPUVerts( u32 v0, u32 num, const FiddledVtx * verts, const Matrix4x4 & mat_world );
template< bool FogEnable, int TextureMode >
void ProcessVerts( u32 v0, u32 num, const FiddledVtx * verts, const Matrix4x4 & mat_world );


void PrepareTrisClipped( TempVerts * temp_verts ) const;
#ifdef DAEDALUS_VITA
uint32_t PrepareTrisUnclipped( uint32_t **clr );
#else
void PrepareTrisUnclipped( TempVerts * temp_verts ) const;
#endif
v3 LightVert( const v3 & norm ) const;
v3 LightPointVert( const v4 & w ) const;

Expand Down Expand Up @@ -465,9 +457,7 @@ class BaseRenderer
u32 mDAMTexScale;
u32 mTextureScaleX, mTextureScaleY;

#if defined(DAEDALUS_GL) || defined(DAEDALUS_VITA)
Matrix4x4 mScreenToDevice; // Used by OSX renderer - scales screen coords (0..640 etc) to device coords (-1..+1)
#endif
Matrix4x4 mScreenToDevice;

static const u32 kMaxIndices = 320; // We need at least 80 verts * 3 = 240? But Flying Dragon uses more than 256 //Corn
u16 mIndexBuffer[kMaxIndices];
Expand Down
2 changes: 0 additions & 2 deletions Source/HLEGraphics/uCodes/Ucode_FB.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

static float fb_ratio;

#if !defined(DAEDALUS_PSP)
static inline CRefPtr<CNativeTexture> LoadFrameBuffer(u32 origin)
{
u32 width = Memory_VI_GetRegister( VI_WIDTH_REG );
Expand Down Expand Up @@ -76,5 +75,4 @@ void RenderFrameBuffer(u32 origin)
CGraphicsContext::Get()->UpdateFrame( false );
}

#endif // !DAEDALUS_PSP
#endif // HLEGRAPHICS_UCODES_UCODE_FB_H_
133 changes: 61 additions & 72 deletions Source/HLEGraphics/uCodes/Ucode_S2DEX.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ static inline CRefPtr<CNativeTexture> Load_ObjSprite( const uObjSprite *sprite,
TextureInfo ti;

// When txtr is NULL, it means TLUT was loaded from ObjLoadTxtr ucode
if( txtr == NULL )
if( txtr == nullptr )
{
// Get ti info from TextureDescriptor since there's no txtr for tile or block (txtr = NULL)
ti = gRDPStateManager.GetUpdatedTextureDescriptor( gRenderer->GetTextureTile() );
Expand All @@ -264,6 +264,10 @@ static inline CRefPtr<CNativeTexture> Load_ObjSprite( const uObjSprite *sprite,
ti.SetSize (sprite->imageSiz);
ti.SetLoadAddress (RDPSegAddr(txtr->block.image) + (sprite->imageAdrs<<3) );
//ti.SetLine (0); // Ensure line is 0?
ti.SetSwapped (0);
ti.SetPalette (sprite->imagePal);
ti.SetTlutAddress (gTlutLoadAddresses[0]);
ti.SetTLutFormat (kTT_RGBA16);

switch( txtr->block.type )
{
Expand All @@ -286,10 +290,6 @@ static inline CRefPtr<CNativeTexture> Load_ObjSprite( const uObjSprite *sprite,
return NULL;
}

ti.SetSwapped (0);
ti.SetPalette (sprite->imagePal);
ti.SetTlutAddress (gTlutLoadAddresses[0]);
ti.SetTLutFormat (kTT_RGBA16);
}

return gRenderer->LoadTextureDirectly(ti);
Expand All @@ -298,7 +298,8 @@ static inline CRefPtr<CNativeTexture> Load_ObjSprite( const uObjSprite *sprite,
//*****************************************************************************
//
//*****************************************************************************
static inline void Draw_ObjSprite( const uObjSprite *sprite, ESpriteMode mode, const CNativeTexture * texture )
template< ESpriteMode mode >
static void Draw_ObjSprite( const uObjSprite *sprite, const CNativeTexture * texture )
{
f32 imageW = sprite->imageW / 32.0f;
f32 imageH = sprite->imageH / 32.0f;
Expand All @@ -325,10 +326,7 @@ static inline void Draw_ObjSprite( const uObjSprite *sprite, ESpriteMode mode, c
y1 = mat2D.C*objW + mat2D.D*objY + mat2D.Y;
x3 = mat2D.A*objX + mat2D.B*objH + mat2D.X;
y3 = mat2D.C*objX + mat2D.D*objH + mat2D.Y;
#ifdef DAEDALUS_ENABLE_ASSERTS
DAEDALUS_ASSERT((sprite->imageFlags & 1) == 0, "Need to flip X" );
DAEDALUS_ASSERT((sprite->imageFlags & 0x10) == 0, "Need to flip Y" );
#endif

gRenderer->Draw2DTextureR(x0, y0, x1, y1, x2, y2, x3, y3, imageW, imageH, texture);
break;

Expand Down Expand Up @@ -365,10 +363,10 @@ static inline void Draw_ObjSprite( const uObjSprite *sprite, ESpriteMode mode, c
// Bomberman : Second Atatck uses this
void DLParser_S2DEX_ObjSprite( MicroCodeCommand command )
{
uObjSprite *sprite = (uObjSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));
const uObjSprite *sprite = (const uObjSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));

CRefPtr<CNativeTexture> texture = Load_ObjSprite( sprite, NULL );
Draw_ObjSprite( sprite, FULL_ROTATION, texture );
Draw_ObjSprite< FULL_ROTATION >( sprite, texture );
}

//*****************************************************************************
Expand All @@ -378,24 +376,24 @@ void DLParser_S2DEX_ObjSprite( MicroCodeCommand command )
// Note : This cmd loads textures from both ObjTxtr and LoadBlock/LoadTile!!
void DLParser_S2DEX_ObjRectangle( MicroCodeCommand command )
{
uObjSprite *sprite = (uObjSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));
const uObjSprite *sprite = (const uObjSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));

CRefPtr<CNativeTexture> texture = Load_ObjSprite( sprite, gObjTxtr );
Draw_ObjSprite( sprite, NO_ROTATION, texture );
Draw_ObjSprite< NO_ROTATION >( sprite, texture );
}

//*****************************************************************************
//
//*****************************************************************************
void DLParser_S2DEX_ObjRectangleR( MicroCodeCommand command )
{
uObjSprite *sprite = (uObjSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));
const uObjSprite *sprite = (const uObjSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));

if (sprite->imageFmt == G_IM_FMT_YUV)
DLParser_OB_YUV(sprite);

CRefPtr<CNativeTexture> texture = Load_ObjSprite( sprite, gObjTxtr );
Draw_ObjSprite( sprite, PARTIAL_ROTATION, texture );
Draw_ObjSprite< PARTIAL_ROTATION >( sprite, texture );
}

//*****************************************************************************
Expand All @@ -404,10 +402,10 @@ void DLParser_S2DEX_ObjRectangleR( MicroCodeCommand command )
// Nintendo logo, shade, items, enemies & foes, sun, and pretty much everything in Yoshi
void DLParser_S2DEX_ObjLdtxSprite( MicroCodeCommand command )
{
uObjTxSprite *sprite = (uObjTxSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));
const uObjTxSprite *sprite = (const uObjTxSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));

CRefPtr<CNativeTexture> texture = Load_ObjSprite( &sprite->sprite, &sprite->txtr );
Draw_ObjSprite( &sprite->sprite, FULL_ROTATION, texture );
Draw_ObjSprite< FULL_ROTATION >( &sprite->sprite, texture );
}

//*****************************************************************************
Expand All @@ -416,10 +414,10 @@ void DLParser_S2DEX_ObjLdtxSprite( MicroCodeCommand command )
// No Rotation. Intro logo, Awesome command screens and HUD in game :)
void DLParser_S2DEX_ObjLdtxRect( MicroCodeCommand command )
{
uObjTxSprite *sprite = (uObjTxSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));
const uObjTxSprite *sprite = (const uObjTxSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));

CRefPtr<CNativeTexture> texture = Load_ObjSprite( &sprite->sprite, &sprite->txtr );
Draw_ObjSprite( &sprite->sprite, NO_ROTATION, texture );
Draw_ObjSprite< NO_ROTATION >( &sprite->sprite, texture );
}

//*****************************************************************************
Expand All @@ -428,10 +426,10 @@ void DLParser_S2DEX_ObjLdtxRect( MicroCodeCommand command )
// With Rotation. Text, smoke, and items in Yoshi
void DLParser_S2DEX_ObjLdtxRectR( MicroCodeCommand command )
{
uObjTxSprite *sprite = (uObjTxSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));
const uObjTxSprite *sprite = (const uObjTxSprite*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));

CRefPtr<CNativeTexture> texture = Load_ObjSprite( &sprite->sprite, &sprite->txtr );
Draw_ObjSprite( &sprite->sprite, PARTIAL_ROTATION, texture );
Draw_ObjSprite< PARTIAL_ROTATION >( &sprite->sprite, texture );
}

//*****************************************************************************
Expand All @@ -445,7 +443,7 @@ void DLParser_S2DEX_ObjMoveMem( MicroCodeCommand command )

if( index == 0 ) // Mtx
{
uObjMtx* mtx = (uObjMtx *)(addr+g_pu8RamBase);
const uObjMtx* mtx = (const uObjMtx *)(addr+g_pu8RamBase);
mat2D.A = mtx->A/65536.0f;
mat2D.B = mtx->B/65536.0f;
mat2D.C = mtx->C/65536.0f;
Expand All @@ -457,7 +455,7 @@ void DLParser_S2DEX_ObjMoveMem( MicroCodeCommand command )
}
else if( index == 2 ) // Sub Mtx
{
uObjSubMtx* sub = (uObjSubMtx*)(addr+g_pu8RamBase);
const uObjSubMtx* sub = (const uObjSubMtx*)(addr+g_pu8RamBase);
mat2D.X = f32(sub->X>>2);
mat2D.Y = f32(sub->Y>>2);
mat2D.BaseScaleX = sub->BaseScaleX/1024.0f;
Expand All @@ -471,7 +469,7 @@ void DLParser_S2DEX_ObjMoveMem( MicroCodeCommand command )
// Kirby uses this for proper palette loading
void DLParser_S2DEX_ObjLoadTxtr( MicroCodeCommand command )
{
uObjTxtr* ObjTxtr = (uObjTxtr*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));
const uObjTxtr* ObjTxtr = (const uObjTxtr*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));

g_TI.Format = G_IM_FMT_RGBA;
g_TI.Size = G_IM_SIZ_16b;
Expand Down Expand Up @@ -526,9 +524,7 @@ inline void DLParser_Yoshi_MemRect( MicroCodeCommand command )

if (y1 > scissors.bottom)
y1 = scissors.bottom;
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
DL_PF (" MemRect->Addr[0x%08x] (%d, %d -> %d, %d) Width[%d]", tile_addr, x0, y0, mem_rect.x1, y1, g_CI.Width);
#endif

#if 1 //1->Optimized, 0->Generic
// This assumes Yoshi always copy 16 bytes per line and dst is aligned and we force alignment on src!!! //Corn
u32 tex_width = rdp_tile.line << 3;
Expand Down Expand Up @@ -562,6 +558,9 @@ inline void DLParser_Yoshi_MemRect( MicroCodeCommand command )

}

//*****************************************************************************
//
//*****************************************************************************
//Ogre Battle needs to copy YUV texture to frame buffer
void DLParser_OB_YUV(const uObjSprite *sprite)
{
Expand Down Expand Up @@ -590,7 +589,7 @@ void DLParser_OB_YUV(const uObjSprite *sprite)
if (lr_x > ci_width) width = ci_width - ul_x;
if (lr_y > ci_height) height = ci_height - ul_y;

u32 *mb = (u32*)(g_pu8RamBase + g_TI.Address); //pointer to the first macro block
const u32 *mb = (const u32*)(g_pu8RamBase + g_TI.Address); //pointer to the first macro block
u16 *dst = (u16*)(g_pu8RamBase + g_CI.Address);
dst += ul_x + ul_y * ci_width;

Expand Down Expand Up @@ -636,30 +635,37 @@ void DLParser_S2DEX_RDPHalf_0( MicroCodeCommand command )
//*****************************************************************************
void DLParser_S2DEX_ObjRendermode( MicroCodeCommand command )
{
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
DL_PF( " S2DEX_ObjRendermode (Ignored)" );
#endif
}

//*****************************************************************************
//
//*****************************************************************************
void DLParser_S2DEX_SelectDl( MicroCodeCommand command )
{
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
DL_PF( " S2DEX_SelectDl (Ignored)" );
#endif
}

//*****************************************************************************
//
//*****************************************************************************
void DLParser_S2DEX_BgCopy( MicroCodeCommand command )
{
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
DL_PF(" DLParser_S2DEX_BgCopy");
#endif
uObjBg *objBg = (uObjBg*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));
const uObjBg *objBg = (const uObjBg*)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));

TextureInfo ti;

ti.SetFormat(objBg->imageFmt);
ti.SetSize(objBg->imageSiz);

ti.SetLoadAddress(RDPSegAddr(objBg->imagePtr));
ti.SetWidth(objBg->imageW >> 2);
ti.SetHeight(objBg->imageH >> 2);
ti.SetPitch(((((objBg->imageW >> 2) << objBg->imageSiz) >> 1)>>3)<<3); //force 8-bit alignment

ti.SetSwapped(false);

ti.SetPalette(objBg->imagePal);
ti.SetTlutAddress(gTlutLoadAddresses[0]);
ti.SetTLutFormat(kTT_RGBA16);

u16 imageX = objBg->imageX >> 5;
u16 imageY = objBg->imageY >> 5;
Expand All @@ -672,22 +678,6 @@ void DLParser_S2DEX_BgCopy( MicroCodeCommand command )
u16 frameW = (objBg->frameW >> 2) + frameX;
u16 frameH = (objBg->frameH >> 2) + frameY;

TextureInfo ti;

ti.SetFormat (objBg->imageFmt);
ti.SetSize (objBg->imageSiz);

ti.SetLoadAddress (RDPSegAddr(objBg->imagePtr));
ti.SetWidth (imageW);
ti.SetHeight (imageH);
ti.SetPitch ((((imageW << objBg->imageSiz) >> 1)>>3)<<3); //force 8-bit alignment

ti.SetSwapped (false);

ti.SetPalette (objBg->imagePal);
ti.SetTlutAddress (gTlutLoadAddresses[0]);
ti.SetTLutFormat (kTT_RGBA16);

CRefPtr<CNativeTexture> texture = gRenderer->LoadTextureDirectly(ti);
gRenderer->Draw2DTexture( (float)frameX, (float)frameY, (float)frameW, (float)frameH,
(float)imageX, (float)imageY, (float)imageW, (float)imageH,
Expand All @@ -702,8 +692,23 @@ void DLParser_S2DEX_Bg1cyc( MicroCodeCommand command )
if( g_ROM.GameHacks == ZELDA_MM )
return;

uObjScaleBg *objBg = (uObjScaleBg *)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));
const uObjScaleBg *objBg = (const uObjScaleBg *)(g_pu8RamBase + RDPSegAddr(command.inst.cmd1));

TextureInfo ti;
ti.SetFormat(objBg->imageFmt);
ti.SetSize(objBg->imageSiz);

ti.SetLoadAddress(RDPSegAddr(objBg->imagePtr));
ti.SetWidth(objBg->imageW / 4);
ti.SetHeight(objBg->imageH / 4);
ti.SetPitch(((((objBg->imageW / 4) << ti.GetSize()) >> 1)>>3)<<3); //force 8-bit alignment, this what sets our correct viewport.

ti.SetSwapped(false);

ti.SetPalette(objBg->imagePal);
ti.SetTlutAddress(gTlutLoadAddresses[0]);
ti.SetTLutFormat(kTT_RGBA16);

f32 frameX = objBg->frameX / 4.0f;
f32 frameY = objBg->frameY / 4.0f;

Expand All @@ -719,22 +724,6 @@ void DLParser_S2DEX_Bg1cyc( MicroCodeCommand command )
f32 imageW = objBg->imageW/4.0f;
f32 imageH = objBg->imageH/4.0f;

TextureInfo ti;

ti.SetFormat (objBg->imageFmt);
ti.SetSize (objBg->imageSiz);

ti.SetLoadAddress (RDPSegAddr(objBg->imagePtr));
ti.SetWidth (objBg->imageW/4);
ti.SetHeight (objBg->imageH/4);
ti.SetPitch ((((objBg->imageW/4 << ti.GetSize()) >> 1)>>3)<<3); //force 8-bit alignment, this what sets our correct viewport.

ti.SetSwapped (false);

ti.SetPalette (objBg->imagePal);
ti.SetTlutAddress (gTlutLoadAddresses[0]);
ti.SetTLutFormat (kTT_RGBA16);

CRefPtr<CNativeTexture> texture = gRenderer->LoadTextureDirectly(ti);

if (g_ROM.GameHacks != YOSHI)
Expand Down
Loading

0 comments on commit 5ce03e6

Please sign in to comment.