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
620 lines
18 KiB
C
620 lines
18 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_GBI2_H_
|
|
#define HLEGRAPHICS_UCODES_UCODE_GBI2_H_
|
|
|
|
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_Vtx( MicroCodeCommand command )
|
|
{
|
|
u32 address = RDPSegAddr(command.vtx2.addr);
|
|
|
|
u32 vend = command.vtx2.vend >> 1;
|
|
u32 n = command.vtx2.n;
|
|
u32 v0 = vend - n;
|
|
|
|
DL_PF( " Address[0x%08x] vEnd[%d] v0[%d] Num[%d]", address, vend, v0, n );
|
|
if (IsVertexInfoValid(address, 16, v0, n))
|
|
{
|
|
gRenderer->SetNewVertexInfo( address, v0, n );
|
|
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
gNumVertices += n;
|
|
DLParser_DumpVtxInfo( address, v0, n );
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_Mtx( MicroCodeCommand command )
|
|
{
|
|
u32 address = RDPSegAddr(command.mtx2.addr);
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DL_PF(" Command: %s %s %s Length %d Address 0x%08x",
|
|
command.mtx2.projection ? "Projection" : "ModelView",
|
|
command.mtx2.load ? "Load" : "Mul",
|
|
command.mtx2.nopush == 0 ? "Push" : "No Push",
|
|
command.mtx2.len, address);
|
|
#endif
|
|
// Load matrix from address
|
|
if (command.mtx2.projection)
|
|
{
|
|
gRenderer->SetProjection(address, command.mtx2.load);
|
|
}
|
|
else
|
|
{
|
|
gRenderer->SetWorldView(address, command.mtx2.nopush==0, command.mtx2.load);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_PopMtx( MicroCodeCommand command )
|
|
{
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DL_PF(" Command: (%s)", command.inst.cmd1 ? "Projection" : "ModelView");
|
|
#endif
|
|
// Banjo Tooie, pops more than one matrix
|
|
u32 num = command.inst.cmd1>>6;
|
|
|
|
// Just pop the worldview matrix
|
|
gRenderer->PopWorldView(num);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
//0016A710: DB020000 00000018 CMD Zelda_MOVEWORD Mem[2][00]=00000018 Lightnum=0
|
|
//001889F0: DB020000 00000030 CMD Zelda_MOVEWORD Mem[2][00]=00000030 Lightnum=2
|
|
void DLParser_GBI2_MoveWord( MicroCodeCommand command )
|
|
{
|
|
|
|
switch (command.mw2.type)
|
|
{
|
|
case G_MW_MATRIX:
|
|
{
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DL_PF(" G_MW_MATRIX(2)");
|
|
#endif
|
|
gRenderer->InsertMatrix(command.inst.cmd0, command.inst.cmd1);
|
|
}
|
|
break;
|
|
|
|
case G_MW_NUMLIGHT:
|
|
{
|
|
// Lightnum
|
|
// command->cmd1:
|
|
// 0x18 = 24 = 0 lights
|
|
// 0x30 = 48 = 2 lights
|
|
|
|
u32 num_lights = command.mw2.value / 24;
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DL_PF(" G_MW_NUMLIGHT: %d", num_lights);
|
|
#endif
|
|
gRenderer->SetNumLights(num_lights);
|
|
}
|
|
break;
|
|
/*
|
|
case G_MW_CLIP: // Seems to be unused?
|
|
{
|
|
DL_PF(" G_MW_CLIP");
|
|
}
|
|
break;
|
|
*/
|
|
case G_MW_SEGMENT:
|
|
{
|
|
u32 segment = command.mw2.offset >> 2;
|
|
u32 address = command.mw2.value & 0x00FFFFFF;
|
|
|
|
DL_PF( " G_MW_SEGMENT Segment[%d] = 0x%08x", segment, address );
|
|
gSegments[segment] = address;
|
|
}
|
|
break;
|
|
|
|
case G_MW_FOG: // WIP, only works for the PSP
|
|
{
|
|
#ifdef DAEDALUS_PSP
|
|
f32 mul = (f32)(s16)(command.mw2.value >> 16); //Fog mult
|
|
f32 offs = (f32)(s16)(command.mw2.value & 0xFFFF); //Fog Offset
|
|
|
|
gRenderer->SetFogMultOffs(mul, offs);
|
|
|
|
// HW fog, only works for a few games
|
|
#if 0
|
|
f32 a = (f32)(command.mw2.value >> 16);
|
|
f32 b = (f32)(command.mw2.value & 0xFFFF);
|
|
|
|
f32 fog_near = a / 256.0f;
|
|
f32 fog_far = b / 6.0f;
|
|
|
|
gRenderer->SetFogMinMax(fog_near, fog_far);
|
|
#endif
|
|
//DL_PF(" G_MW_FOG. Mult = 0x%04x (%f), Off = 0x%04x (%f)", wMult, 255.0f * fMult, wOff, 255.0f * fOff );
|
|
//printf("1Fog %.0f | %.0f || %.0f | %.0f\n", min, max, a, b);
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case G_MW_LIGHTCOL:
|
|
{
|
|
u32 light_idx = command.mw2.offset / 0x18;
|
|
u32 field_offset = (command.mw2.offset & 0x7);
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DL_PF(" G_MW_LIGHTCOL/0x%08x: 0x%08x", command.mw2.offset, command.mw2.value);
|
|
#endif
|
|
if (field_offset == 0)
|
|
{
|
|
u8 r = ((command.mw2.value>>24)&0xFF);
|
|
u8 g = ((command.mw2.value>>16)&0xFF);
|
|
u8 b = ((command.mw2.value>>8)&0xFF);
|
|
gRenderer->SetLightCol(light_idx, r, g, b);
|
|
}
|
|
}
|
|
break;
|
|
/*
|
|
case G_MW_PERSPNORM:
|
|
DL_PF(" G_MW_PERSPNORM 0x%04x", (s16)command.inst.cmd1);
|
|
break;
|
|
|
|
case G_MW_POINTS:
|
|
DL_PF(" G_MW_POINTS : Ignored");
|
|
break;
|
|
*/
|
|
default:
|
|
{
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DL_PF(" Ignored!!");
|
|
#endif
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
/*
|
|
|
|
001889F8: DC08060A 80188708 CMD Zelda_MOVEMEM Movemem[0806] <- 80188708
|
|
!light 0 color 0.12 0.16 0.35 dir 0.01 0.00 0.00 0.00 (2 lights) [ 1E285A00 1E285A00 01000000 00000000 ]
|
|
data(00188708): 1E285A00 1E285A00 01000000 00000000
|
|
00188A00: DC08090A 80188718 CMD Zelda_MOVEMEM Movemem[0809] <- 80188718
|
|
!light 1 color 0.23 0.25 0.30 dir 0.01 0.00 0.00 0.00 (2 lights) [ 3C404E00 3C404E00 01000000 00000000 ]
|
|
data(00188718): 3C404E00 3C404E00 01000000 00000000
|
|
00188A08: DC080C0A 80188700 CMD Zelda_MOVEMEM Movemem[080C] <- 80188700
|
|
!light 2 color 0.17 0.16 0.26 dir 0.23 0.31 0.70 0.00 (2 lights) [ 2C294300 2C294300 1E285A00 1E285A00 ]
|
|
*/
|
|
/*
|
|
ZeldaMoveMem: 0xdc080008 0x801984d8
|
|
SetScissor: x0=416 y0=72 x1=563 y1=312 mode=0
|
|
// Mtx
|
|
ZeldaMoveWord:0xdb0e0000 0x00000041 Ignored
|
|
ZeldaMoveMem: 0xdc08000a 0x80198538
|
|
ZeldaMoveMem: 0xdc08030a 0x80198548
|
|
|
|
ZeldeMoveMem: Unknown Type. 0xdc08000a 0x80198518
|
|
ZeldeMoveMem: Unknown Type. 0xdc08030a 0x80198528
|
|
ZeldeMoveMem: Unknown Type. 0xdc08000a 0x80198538
|
|
ZeldeMoveMem: Unknown Type. 0xdc08030a 0x80198548
|
|
ZeldeMoveMem: Unknown Type. 0xdc08000a 0x80198518
|
|
ZeldeMoveMem: Unknown Type. 0xdc08030a 0x80198528
|
|
ZeldeMoveMem: Unknown Type. 0xdc08000a 0x80198538
|
|
ZeldeMoveMem: Unknown Type. 0xdc08030a 0x80198548
|
|
|
|
|
|
0xa4001120: <0x0c000487> JAL 0x121c Seg2Addr(t8) dram
|
|
0xa4001124: <0x332100fe> ANDI at = t9 & 0x00fe
|
|
0xa4001128: <0x937309c1> LBU s3 <- 0x09c1(k1) len
|
|
0xa400112c: <0x943402f0> LHU s4 <- 0x02f0(at) dmem
|
|
0xa4001130: <0x00191142> SRL v0 = t9 >> 0x0005
|
|
0xa4001134: <0x959f0336> LHU ra <- 0x0336(t4)
|
|
0xa4001138: <0x080007f6> J 0x1fd8 SpMemXfer
|
|
0xa400113c: <0x0282a020> ADD s4 = s4 + v0 dmem
|
|
|
|
ZeldaMoveMem: 0xdc08000a 0x8010e830 Type: 0a Len: 08 Off: 4000
|
|
ZeldaMoveMem: 0xdc08030a 0x8010e840 Type: 0a Len: 08 Off: 4018
|
|
// Light
|
|
ZeldaMoveMem: 0xdc08060a 0x800ff368 Type: 0a Len: 08 Off: 4030
|
|
ZeldaMoveMem: 0xdc08090a 0x800ff360 Type: 0a Len: 08 Off: 4048
|
|
//VP
|
|
ZeldaMoveMem: 0xdc080008 0x8010e3c0 Type: 08 Len: 08 Off: 4000
|
|
|
|
*/
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_MoveMem( MicroCodeCommand command )
|
|
{
|
|
u32 address = RDPSegAddr(command.inst.cmd1);
|
|
u32 type = (command.inst.cmd0 ) & 0xFE;
|
|
|
|
switch (type)
|
|
{
|
|
case G_GBI2_MV_VIEWPORT:
|
|
{
|
|
RDP_MoveMemViewport( address );
|
|
}
|
|
break;
|
|
|
|
case G_GBI2_MV_LIGHT:
|
|
{
|
|
u32 offset2 = (command.inst.cmd0 >> 5) & 0x7F8;
|
|
u32 light_idx = offset2 / 24;
|
|
if (light_idx < 2)
|
|
{
|
|
DL_PF(" G_MV_LOOKAT" );
|
|
return;
|
|
}
|
|
RDP_MoveMemLight< POINT_LIGHT_MM, 8 >(address, light_idx - 2);
|
|
}
|
|
break;
|
|
|
|
case G_GBI2_MV_MATRIX:
|
|
{
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DL_PF(" Force Matrix(2): addr=%08X", address);
|
|
#endif
|
|
// Rayman 2, Donald Duck, Tarzan, all wrestling games use this
|
|
gRenderer->ForceMatrix( address );
|
|
// ForceMatrix takes two cmds
|
|
gDlistStack.address[gDlistStackPointer] += 8;
|
|
}
|
|
break;
|
|
/*
|
|
case G_GBI2_MVO_L0:
|
|
case G_GBI2_MVO_L1:
|
|
case G_GBI2_MVO_L2:
|
|
case G_GBI2_MVO_L3:
|
|
case G_GBI2_MVO_L4:
|
|
case G_GBI2_MVO_L5:
|
|
case G_GBI2_MVO_L6:
|
|
case G_GBI2_MVO_L7:
|
|
DL_PF("MoveMem Light(2)");
|
|
break;
|
|
case G_GBI2_MV_POINT:
|
|
DL_PF("MoveMem Point(2)");
|
|
break;
|
|
|
|
case G_GBI2_MVO_LOOKATY:
|
|
DL_PF("MoveMem LOOKATY(2)");
|
|
break;
|
|
*/
|
|
|
|
case 0x00:
|
|
case 0x02:
|
|
{
|
|
// Ucode for Evangelion.v64
|
|
// 0 ObjMtx
|
|
// 2 SubMtx
|
|
DLParser_S2DEX_ObjMoveMem( command );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DBGConsole_Msg(0, "GBI2 MoveMem: Unknown Type. 0x%08x 0x%08x", command.inst.cmd0, command.inst.cmd1);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// Kirby 64, SSB and Cruisn' Exotica use this
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_DL_Count( MicroCodeCommand command )
|
|
{
|
|
u32 address = RDPSegAddr(command.inst.cmd1);
|
|
if (address == 0 || !IsAddressValid(address, 8, "DL_Count"))
|
|
return;
|
|
|
|
gDlistStackPointer++;
|
|
gDlistStack.address[gDlistStackPointer] = address;
|
|
gDlistStack.limit = command.inst.cmd0 & 0xFFFF;
|
|
|
|
DL_PF(" DL Count: Push -> DisplayList 0x%08x", address);
|
|
DL_PF(" \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/");
|
|
DL_PF(" ############################################");
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_GeometryMode( MicroCodeCommand command )
|
|
{
|
|
gGeometryMode._u32 &= command.inst.arg0;
|
|
gGeometryMode._u32 |= command.inst.arg1;
|
|
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DL_PF(" 0x%08x 0x%08x =(x & 0x%08x) | 0x%08x", command.inst.cmd0, command.inst.cmd1, command.inst.arg0, command.inst.arg1);
|
|
DL_PF(" ZBuffer %s", (gGeometryMode.GBI2_Zbuffer) ? "On" : "Off");
|
|
DL_PF(" Culling %s", (gGeometryMode.GBI2_CullBack) ? "Back face" : (gGeometryMode.GBI2_CullFront) ? "Front face" : "Off");
|
|
DL_PF(" Smooth Shading %s", (gGeometryMode.GBI2_ShadingSmooth) ? "On" : "Off");
|
|
DL_PF(" Lighting %s", (gGeometryMode.GBI2_Lighting) ? "On" : "Off");
|
|
DL_PF(" Texture Gen %s", (gGeometryMode.GBI2_TexGen) ? "On" : "Off");
|
|
DL_PF(" Texture Gen Linear %s", (gGeometryMode.GBI2_TexGenLin) ? "On" : "Off");
|
|
DL_PF(" Fog %s", (gGeometryMode.GBI2_Fog) ? "On" : "Off");
|
|
DL_PF(" PointLight %s", (gGeometryMode.GBI2_PointLight) ? "On" : "Off");
|
|
#endif
|
|
|
|
TnLMode TnL;
|
|
TnL._u32 = 0;
|
|
|
|
TnL.Light = gGeometryMode.GBI2_Lighting;
|
|
TnL.TexGen = gGeometryMode.GBI2_TexGen;
|
|
TnL.TexGenLin = gGeometryMode.GBI2_TexGenLin;
|
|
TnL.Fog = gGeometryMode.GBI2_Fog & gFogEnabled;// && (gRDPOtherMode.c1_m1a==3 || gRDPOtherMode.c1_m2a==3 || gRDPOtherMode.c2_m1a==3 || gRDPOtherMode.c2_m2a==3);
|
|
TnL.Shade = !(gGeometryMode.GBI2_TexGenLin/* & (g_ROM.GameHacks != TIGERS_HONEY_HUNT)*/);
|
|
TnL.Zbuffer = gGeometryMode.GBI2_Zbuffer;
|
|
TnL.TriCull = gGeometryMode.GBI2_CullFront | gGeometryMode.GBI2_CullBack;
|
|
TnL.CullBack = gGeometryMode.GBI2_CullBack;
|
|
TnL.PointLight = gGeometryMode.GBI2_PointLight;
|
|
|
|
gRenderer->SetTnLMode( TnL._u32 );
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_SetOtherModeL( MicroCodeCommand command )
|
|
{
|
|
// Mask is constructed slightly differently
|
|
const u32 mask = (u32)((s32)(0x80000000) >> command.othermode.len) >> command.othermode.sft;
|
|
|
|
gRDPOtherMode.L = (gRDPOtherMode.L & ~mask) | command.othermode.data;
|
|
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DLDebug_DumpRDPOtherModeL(mask, command.othermode.data);
|
|
#endif
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_SetOtherModeH( MicroCodeCommand command )
|
|
{
|
|
// Mask is constructed slightly differently
|
|
const u32 mask = (u32)((s32)(0x80000000) >> command.othermode.len) >> command.othermode.sft;
|
|
|
|
gRDPOtherMode.H = (gRDPOtherMode.H & ~mask) | command.othermode.data;
|
|
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
DLDebug_DumpRDPOtherModeH(mask, command.othermode.data);
|
|
#endif
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_Texture( MicroCodeCommand command )
|
|
{
|
|
bool enabled = command.texture.enable_gbi2;
|
|
if (!enabled)
|
|
{
|
|
DL_PF(" Texture its disabled -> Ignored");
|
|
gRenderer->SetTextureEnable( false );
|
|
return;
|
|
}
|
|
|
|
DL_PF(" Texture its enabled: Level[%d] Tile[%d]", command.texture.level, command.texture.tile);
|
|
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 );
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_DMA_IO( MicroCodeCommand command )
|
|
{
|
|
#ifdef DAEDALUS_DEBUG_CONSOLE
|
|
DL_UNIMPLEMENTED_ERROR( "G_DMA_IO" );
|
|
#endif
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_Quad( MicroCodeCommand command )
|
|
{
|
|
// While the next command pair is Tri2, add vertices
|
|
u32 pc = gDlistStack.address[gDlistStackPointer];
|
|
u32 * pCmdBase = (u32 *)(g_pu8RamBase + pc);
|
|
|
|
bool tris_added = false;
|
|
|
|
do
|
|
{
|
|
//DL_PF(" 0x%08x: %08x %08x %-10s", pc-8, command.inst.cmd0, command.inst.cmd1, "G_GBI2_QUAD");
|
|
|
|
// Vertex indices are multiplied by 2
|
|
u32 v0_idx = command.gbi2line3d.v0 >> 1;
|
|
u32 v1_idx = command.gbi2line3d.v1 >> 1;
|
|
u32 v2_idx = command.gbi2line3d.v2 >> 1;
|
|
|
|
tris_added |= gRenderer->AddTri(v0_idx, v1_idx, v2_idx);
|
|
|
|
u32 v3_idx = command.gbi2line3d.v3 >> 1;
|
|
u32 v4_idx = command.gbi2line3d.v4 >> 1;
|
|
u32 v5_idx = command.gbi2line3d.v5 >> 1;
|
|
|
|
tris_added |= gRenderer->AddTri(v3_idx, v4_idx, v5_idx);
|
|
|
|
//printf("Q 0x%08x: %08x %08x %d\n", pc-8, command.inst.cmd0, command.inst.cmd1, tris_added);
|
|
|
|
command.inst.cmd0 = *pCmdBase++;
|
|
command.inst.cmd1 = *pCmdBase++;
|
|
pc += 8;
|
|
} while ( command.inst.cmd == G_GBI2_QUAD );
|
|
|
|
gDlistStack.address[gDlistStackPointer] = pc-8;
|
|
|
|
if (tris_added)
|
|
{
|
|
gRenderer->FlushTris();
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
// XXX SpiderMan uses this command.DLParser_GBI2_Tri2
|
|
void DLParser_GBI2_Line3D( MicroCodeCommand command )
|
|
{
|
|
// While the next command pair is Tri2, add vertices
|
|
u32 pc = gDlistStack.address[gDlistStackPointer];
|
|
u32 * pCmdBase = (u32 *)(g_pu8RamBase + pc);
|
|
|
|
bool tris_added = false;
|
|
|
|
do
|
|
{
|
|
//DL_PF(" 0x%08x: %08x %08x %-10s", pc-8, command.inst.cmd0, command.inst.cmd1, "G_GBI2_LINE3D");
|
|
|
|
u32 v0_idx = command.gbi2line3d.v0 >> 1;
|
|
u32 v1_idx = command.gbi2line3d.v1 >> 1;
|
|
u32 v2_idx = command.gbi2line3d.v2 >> 1;
|
|
|
|
tris_added |= gRenderer->AddTri(v0_idx, v1_idx, v2_idx);
|
|
|
|
u32 v3_idx = command.gbi2line3d.v3 >> 1;
|
|
u32 v4_idx = command.gbi2line3d.v4 >> 1;
|
|
u32 v5_idx = command.gbi2line3d.v5 >> 1;
|
|
|
|
tris_added |= gRenderer->AddTri(v3_idx, v4_idx, v5_idx);
|
|
|
|
command.inst.cmd0 = *pCmdBase++;
|
|
command.inst.cmd1 = *pCmdBase++;
|
|
pc += 8;
|
|
} while ( command.inst.cmd == G_GBI2_LINE3D );
|
|
|
|
gDlistStack.address[gDlistStackPointer] = pc-8;
|
|
|
|
if (tris_added)
|
|
{
|
|
gRenderer->FlushTris();
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_Tri1( MicroCodeCommand command )
|
|
{
|
|
|
|
// While the next command pair is Tri1, add vertices
|
|
u32 pc = gDlistStack.address[gDlistStackPointer];
|
|
u32 * pCmdBase = (u32 *)(g_pu8RamBase + pc);
|
|
|
|
bool tris_added = false;
|
|
|
|
do
|
|
{
|
|
//DL_PF(" 0x%08x: %08x %08x %-10s", pc-8, command.inst.cmd0, command.inst.cmd1, "G_GBI2_TRI1");
|
|
|
|
u32 v0_idx = command.gbi2tri1.v0 >> 1;
|
|
u32 v1_idx = command.gbi2tri1.v1 >> 1;
|
|
u32 v2_idx = command.gbi2tri1.v2 >> 1;
|
|
|
|
tris_added |= gRenderer->AddTri(v0_idx, v1_idx, v2_idx);
|
|
|
|
command.inst.cmd0 = *pCmdBase++;
|
|
command.inst.cmd1 = *pCmdBase++;
|
|
pc += 8;
|
|
} while ( command.inst.cmd == G_GBI2_TRI1 );
|
|
|
|
gDlistStack.address[gDlistStackPointer] = pc-8;
|
|
|
|
if (tris_added)
|
|
{
|
|
gRenderer->FlushTris();
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
// While the next command pair is Tri2, add vertices
|
|
//*****************************************************************************
|
|
void DLParser_GBI2_Tri2( MicroCodeCommand command )
|
|
{
|
|
|
|
u32 pc = gDlistStack.address[gDlistStackPointer];
|
|
u32 * pCmdBase = (u32 *)(g_pu8RamBase + pc);
|
|
|
|
bool tris_added = false;
|
|
|
|
do
|
|
{
|
|
//DL_PF(" 0x%08x: %08x %08x %-10s", pc-8, command.inst.cmd0, command.inst.cmd1, "G_GBI2_TRI2");
|
|
|
|
// Vertex indices already divided in ucodedef
|
|
u32 v0_idx = command.gbi2tri2.v0;
|
|
u32 v1_idx = command.gbi2tri2.v1;
|
|
u32 v2_idx = command.gbi2tri2.v2;
|
|
|
|
tris_added |= gRenderer->AddTri(v0_idx, v1_idx, v2_idx);
|
|
|
|
u32 v3_idx = command.gbi2tri2.v3;
|
|
u32 v4_idx = command.gbi2tri2.v4;
|
|
u32 v5_idx = command.gbi2tri2.v5;
|
|
|
|
tris_added |= gRenderer->AddTri(v3_idx, v4_idx, v5_idx);
|
|
|
|
command.inst.cmd0 = *pCmdBase++;
|
|
command.inst.cmd1 = *pCmdBase++;
|
|
pc += 8;
|
|
} while ( command.inst.cmd == G_GBI2_TRI2 );
|
|
|
|
gDlistStack.address[gDlistStackPointer] = pc-8;
|
|
|
|
if (tris_added)
|
|
{
|
|
gRenderer->FlushTris();
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
/*
|
|
void DLParser_GBI2_0x8( MicroCodeCommand command )
|
|
{
|
|
if( (command.inst.arg0 == 0x2F && ((command.inst.cmd1)&0xFF000000) == 0x80000000 )
|
|
{
|
|
// V-Rally 64
|
|
DLParser_S2DEX_ObjLdtxRectR(command);
|
|
}
|
|
else
|
|
{
|
|
DLParser_Nothing(command);
|
|
}
|
|
}
|
|
*/
|
|
|
|
#endif // HLEGRAPHICS_UCODES_UCODE_GBI2_H_
|