daedalus/Source/HLEGraphics/uCodes/Ucode_DKR.h
2025-03-17 07:31:55 +11:00

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 glm::vec4 & t = gRenderer->GetTransformedVtxPos( idx );
const glm::vec4 & 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_