// Yoshi's Story uses this - 0x03
void RSP_S2DEX_OBJ_RECTANGLE(Gfx *gfx)
{
    uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
    uObjSprite *ptr = (uObjSprite*)(g_pRDRAMu8+dwAddr);

    uObjTxSprite objtx;
    memcpy(&objtx.sprite,ptr,sizeof(uObjSprite));

    if( g_TxtLoadBy == CMD_LOAD_OBJ_TXTR )
    {
        memcpy(&(objtx.txtr.block),&(gObjTxtr->block),sizeof(uObjTxtr));
        CRender::g_pRender->LoadObjSprite(objtx, true);
    }
    else
    {
        PrepareTextures();
    }
    CRender::g_pRender->DrawSprite(objtx, false);

#ifdef DEBUGGER
    if( (pauseAtNext && (eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI)) || logTextures )
    {
        if( debuggerPauseCount > 0 ) 
            debuggerPauseCount--; 
        if( debuggerPauseCount == 0 )
        {
            eventToPause = false;
            debuggerPause = true;
            TRACE3("Paused at RSP_S2DEX_OBJ_RECTANGLE\nptr=%08X, img=%08X, TMEM=%08X",
                dwAddr,objtx.txtr.block.image, ptr->imageAdrs);
            CGraphicsContext::g_pGraphicsContext->UpdateFrame(false);
        }
    }
#endif
}
// Yoshi's Story uses this - 0x04
void RSP_S2DEX_OBJ_SPRITE(Gfx *gfx)
{
    uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
    uObjSprite *info = (uObjSprite*)(g_pRDRAMu8+dwAddr);

    uint32 dwTile   = gRSP.curTile;
    status.bAllowLoadFromTMEM = false;  // Because we need to use TLUT loaded by ObjTlut cmd
    PrepareTextures();
    status.bAllowLoadFromTMEM = true;

    uObjTxSprite drawinfo;
    memcpy( &(drawinfo.sprite), info, sizeof(uObjSprite));
    CRender::g_pRender->DrawSpriteR(drawinfo, false, dwTile, 0, 0, drawinfo.sprite.imageW/32, drawinfo.sprite.imageH/32);


    /*
    static BOOL bWarned = FALSE;
    //if (!bWarned)
    {
        RSP_RDP_NOIMPL("RDP: RSP_S2DEX_OBJ_SPRITE (0x%08x 0x%08x)", (gfx->words.w0), (gfx->words.w1));
        bWarned = TRUE;
    }
    */

#ifdef DEBUGGER
    if( (pauseAtNext && (eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI)) || logTextures )
    {   
        eventToPause = false;
        debuggerPause = true;
        TRACE0("Paused at RSP_S2DEX_OBJ_SPRITE");
        CGraphicsContext::Get()->UpdateFrame();
    }
#endif
}
// Yoshi's Story uses this - 0x02
void RSP_S2DEX_BG_COPY(Gfx *gfx)
{
    SP_Timing(DP_Minimal16);
    DP_Timing(DP_Minimal16);

    uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
    uObjBg *sbgPtr = (uObjBg*)(g_pRDRAMu8+dwAddr);
    CRender::g_pRender->LoadObjBGCopy(*sbgPtr);
    CRender::g_pRender->DrawObjBGCopy(*sbgPtr);
}
// Yoshi's Story uses this - 0x04
void RSP_S2DEX_OBJ_SPRITE(Gfx *gfx)
{
    uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
    uObjSprite *info = (uObjSprite*)(g_pRDRAMu8+dwAddr);

    uint32 dwTile   = gRSP.curTile;
    status.bAllowLoadFromTMEM = false;  // Because we need to use TLUT loaded by the ObjTlut command
    PrepareTextures();
    status.bAllowLoadFromTMEM = true;

    uObjTxSprite drawinfo;
    memcpy( &(drawinfo.sprite), info, sizeof(uObjSprite));
    CRender::g_pRender->DrawSpriteR(drawinfo, false, dwTile, 0, 0, drawinfo.sprite.imageW/32, drawinfo.sprite.imageH/32);

#ifdef DEBUGGER
    if( (pauseAtNext && (eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI)) || logTextures )
    {   
        eventToPause = false;
        debuggerPause = true;
        TRACE0("Paused at RSP_S2DEX_OBJ_SPRITE");
        CGraphicsContext::g_pGraphicsContext->UpdateFrame(false);
    }
#endif
}
Example #5
0
 //#define SUPPORT_ZBUFFER_IMG		//Doesn't work good enough, still need lockable zbuffer
//#define SUPPORT_LOCKABLE_ZBUFFER
void D3DRender::DrawObjBGCopy(uObjBg &info)
{
	if( IsUsedAsDI(g_CI.dwAddr) )
	{
#ifndef SUPPORT_LOCKABLE_ZBUFFER
#ifndef SUPPORT_ZBUFFER_IMG
		g_pD3DDev->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0);	//Check me
		LOG_UCODE("    Clearing ZBuffer by using ZeldaBG");
#else
		if( g_CI.dwWidth == 0x200 && info.imageFmt == g_CI.dwFormat && info.imageSiz == g_CI.dwSize &&
				info.frameW == 0x800 )
		{
			InitCombinerBlenderForSimpleTextureDraw();
			ZBufferEnable( TRUE );
			gD3DDevWrapper.SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TFACTOR );
			gD3DDevWrapper.SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR );
			SetTextureFactor(0);
			//SetTextureFactor(0x80808080);
			//gD3DDevWrapper.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
			//gD3DDevWrapper.SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
			
			// Resident Evil2
			uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
			uint32 height = (info.frameW/4*info.frameH/4)/width;
			uint32 pitch = width;

			//LoadObjBGCopy(info);

			// We don't support lockable Zbuffer, but we can simular it by splitting the image
			// to small pieces and render the piece with depth from the depth image

			uint16 *Base = (uint16*)(g_pu8RamBase+RSPSegmentAddr(info.imagePtr));
			float depth;

			const uint32 inc=10;

			for( uint32 i=0; i<height; i+=inc )
			{
				uint16 *pSrc = Base + i * pitch;
				depth = (*pSrc + 1.0f ) / 0x10000;
				for( uint32 j=0; j<width; j+=inc)
				{
					DrawSimpleRect(j, i, j+inc, i+inc, gRDP.primitiveColor, depth, 1/depth);

#ifdef _DEBUG
					if( pauseAtNext && eventToPause == NEXT_TRIANGLE )
					{
						debuggerPause = true;
						TRACE0("Pause after drawing a rect for Z buffer");
						DebuggerPause();
					}
#endif
				}
			}
		}
#endif
#else
		if( g_pLockableBackBuffer == NULL && status.bHandleN64RenderTexture == false )
		{
			if( IsResultGood(g_pD3DDev->CreateDepthStencilSurface(windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, D3DFMT_D16_LOCKABLE, D3DMULTISAMPLE_NONE, &g_pLockableBackBuffer)) && g_pLockableBackBuffer )
			{
				g_pD3DDev->SetRenderTarget(NULL, g_pLockableBackBuffer);
				TRACE0("Created and use lockable depth buffer");
			}
			else
			{
				if( g_pLockableBackBuffer )
				{
					g_pLockableBackBuffer->Release();
					g_pLockableBackBuffer = NULL;
				}
				TRACE0("Can not create lockable depth buffer");
			}
		}

		DEBUGGER_IF_DUMP((pauseAtNext&& (eventToPause==NEXT_OBJ_TXT_CMD||eventToPause==NEXT_OBJ_BG)), 
		{TRACE0("Using BG to update Z buffer has not been implemented yet");});