bool PrepareTriangle(uint32_t dwV0, uint32_t dwV1, uint32_t dwV2) { SP_Timing(SP_Each_Triangle); bool textureFlag = (CRender::g_pRender->IsTextureEnabled() || gRSP.ucode == 6 ); InitVertex(dwV0, gRSP.numVertices, textureFlag); InitVertex(dwV1, gRSP.numVertices+1, textureFlag); InitVertex(dwV2, gRSP.numVertices+2, textureFlag); if(gRSP.numVertices == 0 && g_curRomInfo.bEnableTxtLOD && gRDP.otherMode.text_lod) { if( CRender::g_pRender->IsTexel1Enable() && CRender::g_pRender->m_pColorCombiner->m_pDecodedMux->IsUsed(MUX_LODFRAC, MUX_MASK) ) { ComputeLOD(); } else { gRDP.LODFrac = 0; } } gRSP.numVertices += 3; status.dwNumTrisRendered++; return true; }
// 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); }
void ProcessVertexDataNoSSE(uint32_t dwAddr, uint32_t dwV0, uint32_t dwNum) { UpdateCombinedMatrix(); // This function is called upon SPvertex // - do vertex matrix transform // - do vertex lighting // - do texture coordinate transform if needed // - calculate normal vector // Output: - g_vecProjected[i] -> transformed vertex x,y,z // - g_vecProjected[i].w -> saved vertex 1/w // - g_dwVtxFlags[i] -> flags // - g_dwVtxDifColor[i] -> vertex color // - g_fVtxTxtCoords[i] -> vertex texture coordinates uint8_t *rdram_u8 = (uint8_t*)gfx_info.RDRAM; FiddledVtx * pVtxBase = (FiddledVtx*)(rdram_u8 + dwAddr); g_pVtxBase = pVtxBase; for (uint32_t i = dwV0; i < dwV0 + dwNum; i++) { SP_Timing(RSP_GBI0_Vtx); FiddledVtx & vert = pVtxBase[i - dwV0]; g_vtxNonTransformed[i].x = (float)vert.x; g_vtxNonTransformed[i].y = (float)vert.y; g_vtxNonTransformed[i].z = (float)vert.z; Vec3Transform(&g_vtxTransformed[i], (XVECTOR3*)&g_vtxNonTransformed[i], &gRSPworldProject); // Convert to w=1 g_vecProjected[i].w = 1.0f / g_vtxTransformed[i].w; g_vecProjected[i].x = g_vtxTransformed[i].x * g_vecProjected[i].w; g_vecProjected[i].y = g_vtxTransformed[i].y * g_vecProjected[i].w; if ((g_curRomInfo.bPrimaryDepthHack || options.enableHackForGames == HACK_FOR_NASCAR ) && gRDP.otherMode.depth_source ) { g_vecProjected[i].z = gRDP.fPrimitiveDepth; g_vtxTransformed[i].z = gRDP.fPrimitiveDepth*g_vtxTransformed[i].w; } else { g_vecProjected[i].z = g_vtxTransformed[i].z * g_vecProjected[i].w; } if( gRSP.bFogEnabled ) { g_fFogCoord[i] = g_vecProjected[i].z; if( g_vecProjected[i].w < 0 || g_vecProjected[i].z < 0 || g_fFogCoord[i] < gRSPfFogMin ) g_fFogCoord[i] = gRSPfFogMin; } RSP_Vtx_Clipping(i); if( gRSP.bLightingEnable ) { g_normal.x = (float)vert.norma.nx; g_normal.y = (float)vert.norma.ny; g_normal.z = (float)vert.norma.nz; Vec3TransformNormal(g_normal, gRSPmodelViewTop); g_dwVtxDifColor[i] = LightVert(g_normal, i); *(((uint8_t*)&(g_dwVtxDifColor[i]))+3) = vert.rgba.a; // still use alpha from the vertex } else { if( (gRDP.geometryMode & G_SHADE) == 0 && gRSP.ucode < 5 ) //Shade is disabled { //FLAT shade g_dwVtxDifColor[i] = gRDP.primitiveColor; } else { register IColor &color = *(IColor*)&g_dwVtxDifColor[i]; color.b = vert.rgba.r; color.g = vert.rgba.g; color.r = vert.rgba.b; color.a = vert.rgba.a; } } if( options.bWinFrameMode ) { g_dwVtxDifColor[i] = COLOR_RGBA(vert.rgba.r, vert.rgba.g, vert.rgba.b, vert.rgba.a); } ReplaceAlphaWithFogFactor(i); // Update texture coords n.b. need to divide tu/tv by bogus scale on addition to buffer // If the vertex is already lit, then there is no normal (and hence we // can't generate tex coord) if (gRSP.bTextureGen && gRSP.bLightingEnable ) { TexGen(g_fVtxTxtCoords[i].x, g_fVtxTxtCoords[i].y); } else { g_fVtxTxtCoords[i].x = (float)vert.tu; g_fVtxTxtCoords[i].y = (float)vert.tv; } } }