mirror of
https://github.com/DaedalusX64/daedalus.git
synced 2025-04-02 10:21:48 -04:00
*Properly trigger DP interrupt, some games are very sensitive when we ignore it. Blast Corps no longer hangs after the Rare logo. Also ensure to trigger the interrupt when frameskip its enabled to avoid stalls *Added bound checks for DLinMem and DLCount *Disabled invalid address bound checks for the PSP. With the recent changes, now its safer to disable it
304 lines
8.7 KiB
C
304 lines
8.7 KiB
C
/*
|
|
Copyright (C) 2009 StrmnNrmn
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
#ifndef HLEGRAPHICS_UCODES_UCODE_DKR_H_
|
|
#define HLEGRAPHICS_UCODES_UCODE_DKR_H_
|
|
|
|
u32 gDKRMatrixAddr = 0;
|
|
u32 gDKRVtxCount = 0;
|
|
bool gDKRBillBoard = false;
|
|
|
|
// DKR verts are 10 bytes
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_DumpVtxInfoDKR(u32 address, u32 v0_idx, u32 num_verts)
|
|
{
|
|
if (DLDebug_IsActive())
|
|
{
|
|
uintptr_t psSrc = (uintptr_t)(g_pu8RamBase + address);
|
|
|
|
for ( u32 idx = v0_idx; idx < v0_idx + num_verts; idx++ )
|
|
{
|
|
f32 x = *(s16*)((psSrc + 0) ^ 2);
|
|
f32 y = *(s16*)((psSrc + 2) ^ 2);
|
|
f32 z = *(s16*)((psSrc + 4) ^ 2);
|
|
|
|
//u16 wFlags = gRenderer->GetVtxFlags( idx ); //(u16)psSrc[3^0x1];
|
|
|
|
u8 a = *(u8*)((psSrc + 6) ^ 3); //R
|
|
u8 b = *(u8*)((psSrc + 7) ^ 3); //G
|
|
u8 c = *(u8*)((psSrc + 8) ^ 3); //B
|
|
u8 d = *(u8*)((psSrc + 9) ^ 3); //A
|
|
|
|
const v4 & t = gRenderer->GetTransformedVtxPos( idx );
|
|
const v4 & p = gRenderer->GetProjectedVtxPos( idx );
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DL_PF(" #%02d Pos:{% 0.1f,% 0.1f,% 0.1f}->{% 0.1f,% 0.1f,% 0.1f} Proj:{% 6f,% 6f,% 6f,% 6f} RGBA:{%02x%02x%02x%02x}",
|
|
idx, x, y, z, t.x, t.y, t.z, p.x/p.w, p.y/p.w, p.z/p.w, p.w, a, b, c, d );
|
|
#endif
|
|
|
|
psSrc+=10;
|
|
}
|
|
|
|
/*
|
|
u16 * pwSrc = (u16 *)(g_pu8RamBase + address);
|
|
i = 0;
|
|
for( u32 idx = v0_idx; idx < v0_idx + num_verts; idx++ )
|
|
{
|
|
DL_PF(" #%02d %04x %04x %04x %04x %04x",
|
|
idx, pwSrc[(i + 0) ^ 1],
|
|
pwSrc[(i + 1) ^ 1],
|
|
pwSrc[(i + 2) ^ 1],
|
|
pwSrc[(i + 3) ^ 1],
|
|
pwSrc[(i + 4) ^ 1]);
|
|
|
|
i += 5;
|
|
}
|
|
*/
|
|
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI0_Vtx_DKR( MicroCodeCommand command )
|
|
{
|
|
u32 address = RDPSegAddr(command.inst.cmd1) + gAuxAddr;
|
|
|
|
if( command.inst.cmd0 & 0x00010000 )
|
|
{
|
|
if( gDKRBillBoard )
|
|
gDKRVtxCount = 1;
|
|
}
|
|
else
|
|
{
|
|
gDKRVtxCount = 0;
|
|
}
|
|
|
|
u32 v0 = ((command.inst.cmd0 >> 9) & 0x1F) + gDKRVtxCount;
|
|
u32 n = ((command.inst.cmd0 >> 19) & 0x1F);
|
|
|
|
// Increase by one num verts for DKR
|
|
if( g_ROM.GameHacks == DKR ) n++;
|
|
|
|
|
|
DL_PF(" Address[0x%08x] v0[%d] Num[%d]", address, v0, n);
|
|
if (IsVertexInfoValid(address, 10, v0, n))
|
|
{
|
|
gRenderer->SetNewVertexInfoDKR(address, v0, n, gDKRBillBoard);
|
|
gDKRVtxCount += n;
|
|
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
gNumVertices += n;
|
|
DLParser_DumpVtxInfoDKR(address, v0, n);
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_DLInMem( MicroCodeCommand command )
|
|
{
|
|
u32 address = RDPSegAddr(command.inst.cmd1);
|
|
if (address == 0 || !IsAddressValid(address, 8, "DLInMem"))
|
|
return;
|
|
|
|
gDlistStackPointer++;
|
|
gDlistStack.address[gDlistStackPointer] = address;
|
|
gDlistStack.limit = (command.inst.cmd0 >> 16) & 0xFF;
|
|
|
|
DL_PF(" DLInMem: Push -> DisplayList 0x%08x", address);
|
|
DL_PF(" \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/");
|
|
DL_PF(" ############################################");
|
|
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_Mtx_DKR( MicroCodeCommand command )
|
|
{
|
|
u32 address = RDPSegAddr(command.inst.cmd1) + gDKRMatrixAddr;
|
|
u32 index = (command.inst.cmd0 >> 16) & 0xF;
|
|
bool mul = false;
|
|
|
|
if (index == 0)
|
|
{
|
|
//DKR : no mult
|
|
index = (command.inst.cmd0 >> 22) & 0x3;
|
|
}
|
|
else
|
|
{
|
|
//JFG : mult but only if bit is set
|
|
mul = ((command.inst.cmd0 >> 23) & 0x1);
|
|
}
|
|
|
|
// Load matrix from address
|
|
gRenderer->SetDKRMat(address, mul, index);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_MoveWord_DKR( MicroCodeCommand command )
|
|
{
|
|
switch( command.inst.cmd0 & 0xFF )
|
|
{
|
|
case G_MW_NUMLIGHT:
|
|
{
|
|
gDKRBillBoard = command.inst.cmd1 & 0x1;
|
|
DL_PF(" DKR BillBoard: %d", gDKRBillBoard);
|
|
}
|
|
break;
|
|
|
|
case G_MW_LIGHTCOL:
|
|
{
|
|
u32 idx = (command.inst.cmd1 >> 6) & 0x3;
|
|
DL_PF(" DKR MtxIdx: %d", idx);
|
|
gRenderer->DKRMtxChanged( idx );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DLParser_GBI1_MoveWord( command );
|
|
break;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_Set_Addr_DKR( MicroCodeCommand command )
|
|
{
|
|
gDKRMatrixAddr = command.inst.cmd0 & 0x00FFFFFF;
|
|
gAuxAddr = command.inst.cmd1 & 0x00FFFFFF;
|
|
gDKRVtxCount = 0;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_DMA_Tri_DKR( MicroCodeCommand command )
|
|
{
|
|
u32 address = RDPSegAddr(command.inst.cmd1);
|
|
u32 count = (command.inst.cmd0 >> 4) & 0x1F; //Count should never exceed 16
|
|
|
|
if( !IsAddressValid(address, (count * 16), "DMA_Tri_DKR") )
|
|
return;
|
|
|
|
const TriDKR *tri = (const TriDKR*)(g_pu8RamBase + address);
|
|
bool tris_added = false;
|
|
|
|
for (u32 i = 0; i < count; i++)
|
|
{
|
|
u32 v0_idx = tri->v0;
|
|
u32 v1_idx = tri->v1;
|
|
u32 v2_idx = tri->v2;
|
|
|
|
gRenderer->SetCullMode( !(tri->flag & 0x40), true );
|
|
|
|
//if( info & 0x40000000 )
|
|
//{ // no cull
|
|
// gRenderer->SetCullMode( false, false );
|
|
//}
|
|
//else
|
|
//{
|
|
// // back culling
|
|
// gRenderer->SetCullMode( true, true );
|
|
|
|
// //if (RDP_View_Scales_X < 0)
|
|
// //{ // back culling
|
|
// // gRenderer->SetCullMode( true, true );
|
|
// //}
|
|
// //else
|
|
// //{ // front cull
|
|
// // gRenderer->SetCullMode( true, false );
|
|
// //}
|
|
//}
|
|
DL_PF(" Index[%d %d %d] Cull[%s] uv_TexCoord[%0.2f|%0.2f] [%0.2f|%0.2f] [%0.2f|%0.2f]",
|
|
v0_idx, v1_idx, v2_idx, !(tri->flag & 0x40)? "On":"Off",
|
|
(f32)tri->s0/32.0f, (f32)tri->t0/32.0f,
|
|
(f32)tri->s1/32.0f, (f32)tri->t1/32.0f,
|
|
(f32)tri->s2/32.0f, (f32)tri->t2/32.0f);
|
|
|
|
#if 1 //1->Fixes texture scaling, 0->Render as is and get some texture scaling errors
|
|
//
|
|
// This will create problem since some verts will get re-used and over-write new texture coords before previous has been rendered
|
|
// To fix it we copy all verts to a new location where we can have individual texture coordinates for each triangle//Corn
|
|
const u32 new_v0_idx = i * 3 + 32;
|
|
const u32 new_v1_idx = i * 3 + 33;
|
|
const u32 new_v2_idx = i * 3 + 34;
|
|
|
|
gRenderer->CopyVtx( v0_idx, new_v0_idx);
|
|
gRenderer->CopyVtx( v1_idx, new_v1_idx);
|
|
gRenderer->CopyVtx( v2_idx, new_v2_idx);
|
|
|
|
if( gRenderer->AddTri(new_v0_idx, new_v1_idx, new_v2_idx) )
|
|
{
|
|
tris_added = true;
|
|
// Generate texture coordinates...
|
|
gRenderer->SetVtxTextureCoord( new_v0_idx, tri->s0, tri->t0 );
|
|
gRenderer->SetVtxTextureCoord( new_v1_idx, tri->s1, tri->t1 );
|
|
gRenderer->SetVtxTextureCoord( new_v2_idx, tri->s2, tri->t2 );
|
|
}
|
|
#else
|
|
if( gRenderer->AddTri(v0_idx, v1_idx, v2_idx) )
|
|
{
|
|
tris_added = true;
|
|
// Generate texture coordinates...
|
|
gRenderer->SetVtxTextureCoord( v0_idx, tri->s0, tri->t0 );
|
|
gRenderer->SetVtxTextureCoord( v1_idx, tri->s1, tri->t1 );
|
|
gRenderer->SetVtxTextureCoord( v2_idx, tri->s2, tri->t2 );
|
|
}
|
|
#endif
|
|
tri++;
|
|
}
|
|
|
|
if(tris_added)
|
|
{
|
|
gRenderer->FlushTris();
|
|
}
|
|
|
|
gDKRVtxCount = 0;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI1_Texture_DKR( MicroCodeCommand command )
|
|
{
|
|
DL_PF(" Texture its enabled: Level[%d] Tile[%d]", command.texture.level, command.texture.tile);
|
|
|
|
// Force enable texture in DKR Ucode, fixes static texture bug etc
|
|
gRenderer->SetTextureEnable( true );
|
|
gRenderer->SetTextureTile( command.texture.tile );
|
|
|
|
f32 scale_s = f32(command.texture.scaleS) / (65536.0f * 32.0f);
|
|
f32 scale_t = f32(command.texture.scaleT) / (65536.0f * 32.0f);
|
|
|
|
DL_PF(" ScaleS[%0.4f], ScaleT[%0.4f]", scale_s*32.0f, scale_t*32.0f);
|
|
gRenderer->SetTextureScale( scale_s, scale_t );
|
|
}
|
|
|
|
#endif // HLEGRAPHICS_UCODES_UCODE_DKR_H_
|