mirror of
https://github.com/aap/librw.git
synced 2025-04-29 13:03:20 +01:00
implemented PDS plugin and uninstancing in SA pipes
This commit is contained in:
parent
305f93f738
commit
32dfcf0fd2
@ -289,33 +289,36 @@ Geometry::allocateData(void)
|
|||||||
static int
|
static int
|
||||||
isDegenerate(uint16 *idx)
|
isDegenerate(uint16 *idx)
|
||||||
{
|
{
|
||||||
// TODO: maybe check position instead of index?
|
|
||||||
return idx[0] == idx[1] ||
|
return idx[0] == idx[1] ||
|
||||||
idx[0] == idx[2] ||
|
idx[0] == idx[2] ||
|
||||||
idx[1] == idx[2];
|
idx[1] == idx[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Geometry::generateTriangles(void)
|
Geometry::generateTriangles(int8 *adc)
|
||||||
{
|
{
|
||||||
MeshHeader *header = this->meshHeader;
|
MeshHeader *header = this->meshHeader;
|
||||||
assert(header != NULL);
|
assert(header != NULL);
|
||||||
|
|
||||||
this->numTriangles = 0;
|
this->numTriangles = 0;
|
||||||
Mesh *m = header->mesh;
|
Mesh *m = header->mesh;
|
||||||
|
int8 *adcbits = adc;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
if(m->numIndices < 3){
|
if(m->numIndices < 3){
|
||||||
// shouldn't happen but it does
|
// shouldn't happen but it does
|
||||||
|
adcbits += m->numIndices;
|
||||||
m++;
|
m++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(header->flags == 1){ // tristrip
|
if(header->flags == 1){ // tristrip
|
||||||
for(uint32 j = 0; j < m->numIndices-2; j++){
|
for(uint32 j = 0; j < m->numIndices-2; j++){
|
||||||
if(!isDegenerate(&m->indices[j]))
|
if(!(adc && adcbits[j+2]) &&
|
||||||
|
!isDegenerate(&m->indices[j]))
|
||||||
this->numTriangles++;
|
this->numTriangles++;
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
this->numTriangles += m->numIndices/3;
|
this->numTriangles += m->numIndices/3;
|
||||||
|
adcbits += m->numIndices;
|
||||||
m++;
|
m++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,8 +327,10 @@ Geometry::generateTriangles(void)
|
|||||||
|
|
||||||
uint16 *f = this->triangles;
|
uint16 *f = this->triangles;
|
||||||
m = header->mesh;
|
m = header->mesh;
|
||||||
|
adcbits = adc;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
if(m->numIndices < 3){
|
if(m->numIndices < 3){
|
||||||
|
adcbits += m->numIndices;
|
||||||
m++;
|
m++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -334,7 +339,8 @@ Geometry::generateTriangles(void)
|
|||||||
this->numMaterials);
|
this->numMaterials);
|
||||||
if(header->flags == 1) // tristrip
|
if(header->flags == 1) // tristrip
|
||||||
for(uint32 j = 0; j < m->numIndices-2; j++){
|
for(uint32 j = 0; j < m->numIndices-2; j++){
|
||||||
if(isDegenerate(&m->indices[j]))
|
if(adc && adcbits[j+2] ||
|
||||||
|
isDegenerate(&m->indices[j]))
|
||||||
continue;
|
continue;
|
||||||
*f++ = m->indices[j+1 + (j%2)];
|
*f++ = m->indices[j+1 + (j%2)];
|
||||||
*f++ = m->indices[j+0];
|
*f++ = m->indices[j+0];
|
||||||
@ -348,6 +354,7 @@ Geometry::generateTriangles(void)
|
|||||||
*f++ = matid;
|
*f++ = matid;
|
||||||
*f++ = m->indices[j+2];
|
*f++ = m->indices[j+2];
|
||||||
}
|
}
|
||||||
|
adcbits += m->numIndices;
|
||||||
m++;
|
m++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
431
src/gtaplg.cpp
431
src/gtaplg.cpp
@ -21,7 +21,8 @@ namespace gta {
|
|||||||
void
|
void
|
||||||
attachPlugins(void)
|
attachPlugins(void)
|
||||||
{
|
{
|
||||||
rw::ps2::registerPDSPlugin();
|
rw::ps2::registerPDSPlugin(12);
|
||||||
|
gta::registerPDSPipes();
|
||||||
|
|
||||||
rw::ps2::registerNativeRaster();
|
rw::ps2::registerNativeRaster();
|
||||||
rw::xbox::registerNativeRaster();
|
rw::xbox::registerNativeRaster();
|
||||||
@ -36,12 +37,12 @@ attachPlugins(void)
|
|||||||
rw::registerHAnimPlugin();
|
rw::registerHAnimPlugin();
|
||||||
gta::registerNodeNamePlugin();
|
gta::registerNodeNamePlugin();
|
||||||
rw::registerMatFXPlugin();
|
rw::registerMatFXPlugin();
|
||||||
// rw::registerUVAnimPlugin();
|
rw::registerUVAnimPlugin();
|
||||||
rw::ps2::registerADCPlugin();
|
rw::ps2::registerADCPlugin();
|
||||||
gta::registerExtraNormalsPlugin();
|
gta::registerExtraNormalsPlugin();
|
||||||
gta::registerExtraVertColorPlugin();
|
gta::registerExtraVertColorPlugin();
|
||||||
gta::registerEnvSpecPlugin();
|
gta::registerEnvSpecPlugin();
|
||||||
// gta::registerBreakableModelPlugin();
|
gta::registerBreakableModelPlugin();
|
||||||
gta::registerCollisionPlugin();
|
gta::registerCollisionPlugin();
|
||||||
gta::register2dEffectPlugin();
|
gta::register2dEffectPlugin();
|
||||||
gta::registerPipelinePlugin();
|
gta::registerPipelinePlugin();
|
||||||
@ -300,6 +301,16 @@ registerExtraNormalsPlugin(void)
|
|||||||
|
|
||||||
int32 extraVertColorOffset;
|
int32 extraVertColorOffset;
|
||||||
|
|
||||||
|
void
|
||||||
|
allocateExtraVertColors(Geometry *g)
|
||||||
|
{
|
||||||
|
ExtraVertColors *colordata =
|
||||||
|
PLUGINOFFSET(ExtraVertColors, g, extraVertColorOffset);
|
||||||
|
colordata->nightColors = new uint8[g->numVertices*4];
|
||||||
|
colordata->dayColors = new uint8[g->numVertices*4];
|
||||||
|
colordata->balance = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
createExtraVertColors(void *object, int32 offset, int32)
|
createExtraVertColors(void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
@ -759,4 +770,418 @@ registerCollisionPlugin(void)
|
|||||||
writeCollision, getSizeCollision);
|
writeCollision, getSizeCollision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PS2
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace ps2;
|
||||||
|
|
||||||
|
PipeAttribute saXYZADC = {
|
||||||
|
"saXYZADC",
|
||||||
|
AT_V4_16 | AT_RW
|
||||||
|
};
|
||||||
|
|
||||||
|
PipeAttribute saUV = {
|
||||||
|
"saUV",
|
||||||
|
AT_V2_16 | AT_RW
|
||||||
|
};
|
||||||
|
|
||||||
|
PipeAttribute saUV2 = {
|
||||||
|
"saUV2",
|
||||||
|
AT_V4_16 | AT_RW
|
||||||
|
};
|
||||||
|
|
||||||
|
PipeAttribute saRGBA = {
|
||||||
|
"saRGBA",
|
||||||
|
AT_V4_8 | AT_UNSGN | AT_RW
|
||||||
|
};
|
||||||
|
|
||||||
|
PipeAttribute saRGBA2 = {
|
||||||
|
"saRGBA2",
|
||||||
|
AT_V4_16 | AT_UNSGN | AT_RW
|
||||||
|
};
|
||||||
|
|
||||||
|
PipeAttribute saNormal = {
|
||||||
|
"saNormal",
|
||||||
|
AT_V4_8 | AT_RW
|
||||||
|
};
|
||||||
|
|
||||||
|
PipeAttribute saWeights = {
|
||||||
|
"saWeights",
|
||||||
|
AT_V4_32 | AT_RW
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool hasTex2(uint32 id)
|
||||||
|
{
|
||||||
|
return id == 0x53f2008b;
|
||||||
|
}
|
||||||
|
static bool hasNormals(uint32 id)
|
||||||
|
{
|
||||||
|
return id == 0x53f20085 || id == 0x53f20087 || id == 0x53f20089 ||
|
||||||
|
id == 0x53f2008b || id == 0x53f2008d || id == 0x53f2008f;
|
||||||
|
}
|
||||||
|
static bool hasColors(uint32 id)
|
||||||
|
{
|
||||||
|
return id == 0x53f20081 || id == 0x53f20083 || id == 0x53f2008d || id == 0x53f2008f;
|
||||||
|
}
|
||||||
|
static bool hasColors2(uint32 id)
|
||||||
|
{
|
||||||
|
return id == 0x53f20083 || id == 0x53f2008f;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SaVert {
|
||||||
|
float32 p[3];
|
||||||
|
float32 n[3];
|
||||||
|
float32 t0[2];
|
||||||
|
float32 t1[2];
|
||||||
|
uint8 c0[4];
|
||||||
|
uint8 c1[4];
|
||||||
|
float32 w[4];
|
||||||
|
uint8 i[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
saPreCB(MatPipeline *p, Geometry *geo)
|
||||||
|
{
|
||||||
|
// allocate ADC, extra colors, skin
|
||||||
|
allocateADC(geo);
|
||||||
|
if(hasColors2(p->pluginData) && extraVertColorOffset)
|
||||||
|
allocateExtraVertColors(geo);
|
||||||
|
if(p->pluginData == 0x53f20089)
|
||||||
|
skinPreCB(p, geo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
saPostCB(MatPipeline *p, Geometry *geo)
|
||||||
|
{
|
||||||
|
skinPostCB(p, geo);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
findSAVertex(Geometry *g, uint32 flags[], uint32 mask, SaVert *v)
|
||||||
|
{
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
||||||
|
float32 *wghts = NULL;
|
||||||
|
uint8 *inds = NULL;
|
||||||
|
if(skin){
|
||||||
|
wghts = skin->weights;
|
||||||
|
inds = skin->indices;
|
||||||
|
}
|
||||||
|
float32 *verts = g->morphTargets[0].vertices;
|
||||||
|
float32 *tex0 = g->texCoords[0];
|
||||||
|
float32 *tex1 = g->texCoords[1];
|
||||||
|
float32 *norms = g->morphTargets[0].normals;
|
||||||
|
uint8 *cols0 = g->colors;
|
||||||
|
uint8 *cols1 = NULL;
|
||||||
|
if(extraVertColorOffset)
|
||||||
|
cols1 = PLUGINOFFSET(ExtraVertColors, g, extraVertColorOffset)->nightColors;
|
||||||
|
|
||||||
|
for(int32 i = 0; i < g->numVertices; i++){
|
||||||
|
if(mask & flags[i] & 0x1 &&
|
||||||
|
!(verts[0] == v->p[0] && verts[1] == v->p[1] && verts[2] == v->p[2]))
|
||||||
|
goto cont;
|
||||||
|
if(mask & flags[i] & 0x10 &&
|
||||||
|
!(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2]))
|
||||||
|
goto cont;
|
||||||
|
if(mask & flags[i] & 0x100 &&
|
||||||
|
!(cols0[0] == v->c0[0] && cols0[1] == v->c0[1] &&
|
||||||
|
cols0[2] == v->c0[2] && cols0[3] == v->c0[3]))
|
||||||
|
goto cont;
|
||||||
|
if(mask & flags[i] & 0x200 &&
|
||||||
|
!(cols1[0] == v->c1[0] && cols1[1] == v->c1[1] &&
|
||||||
|
cols1[2] == v->c1[2] && cols1[3] == v->c1[3]))
|
||||||
|
goto cont;
|
||||||
|
if(mask & flags[i] & 0x1000 &&
|
||||||
|
!(tex0[0] == v->t0[0] && tex0[1] == v->t0[1]))
|
||||||
|
goto cont;
|
||||||
|
if(mask & flags[i] & 0x2000 &&
|
||||||
|
!(tex1[0] == v->t1[0] && tex1[1] == v->t1[1]))
|
||||||
|
goto cont;
|
||||||
|
if(mask & flags[i] & 0x10000 &&
|
||||||
|
!(wghts[0] == v->w[0] && wghts[1] == v->w[1] &&
|
||||||
|
wghts[2] == v->w[2] && wghts[3] == v->w[3] &&
|
||||||
|
inds[0] == v->i[0] && inds[1] == v->i[1] &&
|
||||||
|
inds[2] == v->i[2] && inds[3] == v->i[3]))
|
||||||
|
goto cont;
|
||||||
|
return i;
|
||||||
|
cont:
|
||||||
|
verts += 3;
|
||||||
|
tex0 += 2;
|
||||||
|
tex1 += 2;
|
||||||
|
norms += 3;
|
||||||
|
cols0 += 4;
|
||||||
|
cols1 += 4;
|
||||||
|
wghts += 4;
|
||||||
|
inds += 4;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
insertSAVertex(Geometry *geo, int32 i, uint32 mask, SaVert *v)
|
||||||
|
{
|
||||||
|
insertVertex(geo, i, mask, v->p, v->t0, v->t1, v->c0, v->n);
|
||||||
|
if(mask & 0x200 && extraVertColorOffset){
|
||||||
|
uint8 *cols1 =
|
||||||
|
&PLUGINOFFSET(ExtraVertColors, geo, extraVertColorOffset)->nightColors[i*4];
|
||||||
|
cols1[0] = v->c1[0];
|
||||||
|
cols1[1] = v->c1[1];
|
||||||
|
cols1[2] = v->c1[2];
|
||||||
|
cols1[3] = v->c1[3];
|
||||||
|
}
|
||||||
|
if(mask & 0x10000 && skinGlobals.offset){
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
||||||
|
memcpy(&skin->weights[i*4], v->w, 16);
|
||||||
|
memcpy(&skin->indices[i*4], v->i, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
saUninstanceCB(ps2::MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
|
||||||
|
{
|
||||||
|
uint32 id = pipe->pluginData;
|
||||||
|
int16 *verts = (int16*)data[0];
|
||||||
|
int16 *texcoords = (int16*)data[1];
|
||||||
|
uint8 *colors = (uint8*)data[2];
|
||||||
|
int8 *norms = (int8*)data[id == 0x53f20089 ? 2 : 3];
|
||||||
|
uint32 *wghts = (uint32*)data[3];
|
||||||
|
float vertScale = 1.0f/128.0f;
|
||||||
|
if(id == 0x53f20085 || id == 0x53f20087 ||
|
||||||
|
id == 0x53f20089 || id == 0x53f2008b)
|
||||||
|
vertScale = 1.0f/1024.0f;
|
||||||
|
uint32 mask = 0x1; // vertices
|
||||||
|
int cinc = 4;
|
||||||
|
int tinc = 2;
|
||||||
|
if((geo->geoflags & Geometry::NORMALS) && hasNormals(id))
|
||||||
|
mask |= 0x10;
|
||||||
|
if((geo->geoflags & Geometry::PRELIT) && hasColors(id))
|
||||||
|
mask |= 0x100;
|
||||||
|
if(hasColors2(id)){
|
||||||
|
mask |= 0x200;
|
||||||
|
cinc *= 2;
|
||||||
|
}
|
||||||
|
if(geo->numTexCoordSets > 0)
|
||||||
|
mask |= 0x1000;
|
||||||
|
if(geo->numTexCoordSets > 0 && hasTex2(id)){
|
||||||
|
mask |= 0x2000;
|
||||||
|
tinc *= 2;
|
||||||
|
}
|
||||||
|
if(id == 0x53f20089)
|
||||||
|
mask |= 0x10000;
|
||||||
|
SaVert v;
|
||||||
|
int32 idxstart = 0;
|
||||||
|
for(Mesh *m = geo->meshHeader->mesh; m < mesh; m++)
|
||||||
|
idxstart += m->numIndices;
|
||||||
|
int8 *adc = PLUGINOFFSET(ADCData, geo, adcOffset)->adcBits;
|
||||||
|
for(uint32 i = 0; i < mesh->numIndices; i++){
|
||||||
|
v.p[0] = verts[0]*vertScale;
|
||||||
|
v.p[1] = verts[1]*vertScale;
|
||||||
|
v.p[2] = verts[2]*vertScale;
|
||||||
|
if(mask & 0x10){
|
||||||
|
v.n[0] = norms[0]/127.0f;
|
||||||
|
v.n[1] = norms[1]/127.0f;
|
||||||
|
v.n[2] = norms[2]/127.0f;
|
||||||
|
}
|
||||||
|
if(mask & 0x200){
|
||||||
|
v.c0[0] = colors[0];
|
||||||
|
v.c0[1] = colors[2];
|
||||||
|
v.c0[2] = colors[4];
|
||||||
|
v.c0[3] = colors[6];
|
||||||
|
v.c1[0] = colors[1];
|
||||||
|
v.c1[1] = colors[3];
|
||||||
|
v.c1[2] = colors[5];
|
||||||
|
v.c1[3] = colors[7];
|
||||||
|
}else if(mask & 0x100){
|
||||||
|
v.c0[0] = colors[0];
|
||||||
|
v.c0[1] = colors[1];
|
||||||
|
v.c0[2] = colors[2];
|
||||||
|
v.c0[3] = colors[3];
|
||||||
|
}
|
||||||
|
if(mask & 0x1000){
|
||||||
|
v.t0[0] = texcoords[0]/4096.0f;
|
||||||
|
v.t0[1] = texcoords[1]/4096.0f;
|
||||||
|
}
|
||||||
|
if(mask & 0x2000){
|
||||||
|
v.t1[0] = texcoords[2]/4096.0f;
|
||||||
|
v.t1[1] = texcoords[3]/4096.0f;
|
||||||
|
}
|
||||||
|
if(mask & 0x10000){
|
||||||
|
for(int j = 0; j < 4; j++){
|
||||||
|
((uint32*)v.w)[j] = wghts[j] & ~0x3FF;
|
||||||
|
v.i[j] = (wghts[j] & 0x3FF) >> 2;
|
||||||
|
if(v.i[j]) v.i[j]--;
|
||||||
|
if(v.w[j] == 0.0f) v.i[j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int32 idx = findSAVertex(geo, flags, mask, &v);
|
||||||
|
if(idx < 0)
|
||||||
|
idx = geo->numVertices++;
|
||||||
|
mesh->indices[i] = idx;
|
||||||
|
adc[idxstart+i] = !!verts[3];
|
||||||
|
flags[idx] = mask;
|
||||||
|
insertSAVertex(geo, idx, mask, &v);
|
||||||
|
|
||||||
|
verts += 4;
|
||||||
|
texcoords += tinc;
|
||||||
|
colors += cinc;
|
||||||
|
norms += 4;
|
||||||
|
wghts += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
saInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data, int32 n)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
registerPDSPipes(void)
|
||||||
|
{
|
||||||
|
Pipeline *pipe;
|
||||||
|
MatPipeline *mpipe;
|
||||||
|
|
||||||
|
// Atomic pipes
|
||||||
|
|
||||||
|
pipe = new ps2::ObjPipeline(PLATFORM_PS2);
|
||||||
|
pipe->pluginID = ID_PDS;
|
||||||
|
pipe->pluginData = 0x53f20080;
|
||||||
|
ps2::registerPDSPipe(pipe);
|
||||||
|
|
||||||
|
pipe = new ps2::ObjPipeline(PLATFORM_PS2);
|
||||||
|
pipe->pluginID = ID_PDS;
|
||||||
|
pipe->pluginData = 0x53f20082;
|
||||||
|
ps2::registerPDSPipe(pipe);
|
||||||
|
|
||||||
|
pipe = new ps2::ObjPipeline(PLATFORM_PS2);
|
||||||
|
pipe->pluginID = ID_PDS;
|
||||||
|
pipe->pluginData = 0x53f20084;
|
||||||
|
ps2::registerPDSPipe(pipe);
|
||||||
|
|
||||||
|
pipe = new ps2::ObjPipeline(PLATFORM_PS2);
|
||||||
|
pipe->pluginID = ID_PDS;
|
||||||
|
pipe->pluginData = 0x53f20088;
|
||||||
|
ps2::registerPDSPipe(pipe);
|
||||||
|
|
||||||
|
// Material pipes
|
||||||
|
|
||||||
|
mpipe = new MatPipeline(PLATFORM_PS2);
|
||||||
|
mpipe->pluginID = ID_PDS;
|
||||||
|
mpipe->pluginData = 0x53f20081;
|
||||||
|
mpipe->attribs[0] = &saXYZADC;
|
||||||
|
mpipe->attribs[1] = &saUV;
|
||||||
|
mpipe->attribs[2] = &saRGBA;
|
||||||
|
uint32 vertCount = MatPipeline::getVertCount(VU_Lights, 3, 3, 2);
|
||||||
|
mpipe->setTriBufferSizes(3, vertCount);
|
||||||
|
mpipe->vifOffset = mpipe->inputStride*vertCount;
|
||||||
|
mpipe->instanceCB = saInstanceCB;
|
||||||
|
mpipe->preUninstCB = saPreCB;
|
||||||
|
mpipe->uninstanceCB = saUninstanceCB;
|
||||||
|
ps2::registerPDSPipe(mpipe);
|
||||||
|
|
||||||
|
mpipe = new MatPipeline(PLATFORM_PS2);
|
||||||
|
mpipe->pluginID = ID_PDS;
|
||||||
|
mpipe->pluginData = 0x53f20083;
|
||||||
|
mpipe->attribs[0] = &saXYZADC;
|
||||||
|
mpipe->attribs[1] = &saUV;
|
||||||
|
mpipe->attribs[2] = &saRGBA2;
|
||||||
|
vertCount = MatPipeline::getVertCount(VU_Lights, 3, 3, 2);
|
||||||
|
mpipe->setTriBufferSizes(3, vertCount);
|
||||||
|
mpipe->vifOffset = mpipe->inputStride*vertCount;
|
||||||
|
mpipe->instanceCB = saInstanceCB;
|
||||||
|
mpipe->preUninstCB = saPreCB;
|
||||||
|
mpipe->uninstanceCB = saUninstanceCB;
|
||||||
|
ps2::registerPDSPipe(mpipe);
|
||||||
|
|
||||||
|
mpipe = new MatPipeline(PLATFORM_PS2);
|
||||||
|
mpipe->pluginID = ID_PDS;
|
||||||
|
mpipe->pluginData = 0x53f20085;
|
||||||
|
mpipe->attribs[0] = &saXYZADC;
|
||||||
|
mpipe->attribs[1] = &saUV;
|
||||||
|
mpipe->attribs[3] = &saNormal;
|
||||||
|
vertCount = MatPipeline::getVertCount(VU_Lights, 4, 3, 2);
|
||||||
|
mpipe->setTriBufferSizes(4, vertCount);
|
||||||
|
mpipe->vifOffset = mpipe->inputStride*vertCount;
|
||||||
|
mpipe->instanceCB = saInstanceCB;
|
||||||
|
mpipe->preUninstCB = saPreCB;
|
||||||
|
mpipe->uninstanceCB = saUninstanceCB;
|
||||||
|
ps2::registerPDSPipe(mpipe);
|
||||||
|
|
||||||
|
mpipe = new MatPipeline(PLATFORM_PS2);
|
||||||
|
mpipe->pluginID = ID_PDS;
|
||||||
|
mpipe->pluginData = 0x53f20087;
|
||||||
|
mpipe->attribs[0] = &saXYZADC;
|
||||||
|
mpipe->attribs[1] = &saUV;
|
||||||
|
mpipe->attribs[3] = &saNormal;
|
||||||
|
vertCount = MatPipeline::getVertCount(0x3BD, 4, 3, 3);
|
||||||
|
mpipe->setTriBufferSizes(4, vertCount);
|
||||||
|
mpipe->vifOffset = mpipe->inputStride*vertCount;
|
||||||
|
mpipe->instanceCB = saInstanceCB;
|
||||||
|
mpipe->preUninstCB = saPreCB;
|
||||||
|
mpipe->uninstanceCB = saUninstanceCB;
|
||||||
|
ps2::registerPDSPipe(mpipe);
|
||||||
|
|
||||||
|
mpipe = new MatPipeline(PLATFORM_PS2);
|
||||||
|
mpipe->pluginID = ID_PDS;
|
||||||
|
mpipe->pluginData = 0x53f20089;
|
||||||
|
mpipe->attribs[0] = &saXYZADC;
|
||||||
|
mpipe->attribs[1] = &saUV;
|
||||||
|
mpipe->attribs[2] = &saNormal;
|
||||||
|
mpipe->attribs[3] = &saWeights;
|
||||||
|
// these values give vertCount = 0x33 :/
|
||||||
|
// vertCount = MatPipeline::getVertCount(0x2D0, 4, 3, 2);
|
||||||
|
vertCount = 0x30;
|
||||||
|
mpipe->setTriBufferSizes(4, vertCount);
|
||||||
|
mpipe->vifOffset = mpipe->inputStride*vertCount;
|
||||||
|
mpipe->instanceCB = saInstanceCB;
|
||||||
|
mpipe->preUninstCB = saPreCB;
|
||||||
|
mpipe->uninstanceCB = saUninstanceCB;
|
||||||
|
mpipe->postUninstCB = saPostCB;
|
||||||
|
ps2::registerPDSPipe(mpipe);
|
||||||
|
|
||||||
|
mpipe = new MatPipeline(PLATFORM_PS2);
|
||||||
|
mpipe->pluginID = ID_PDS;
|
||||||
|
mpipe->pluginData = 0x53f2008b;
|
||||||
|
mpipe->attribs[0] = &saXYZADC;
|
||||||
|
mpipe->attribs[1] = &saUV2;
|
||||||
|
mpipe->attribs[3] = &saNormal;
|
||||||
|
vertCount = MatPipeline::getVertCount(0x3BD, 4, 3, 3);
|
||||||
|
mpipe->setTriBufferSizes(4, vertCount);
|
||||||
|
mpipe->vifOffset = mpipe->inputStride*vertCount;
|
||||||
|
mpipe->instanceCB = saInstanceCB;
|
||||||
|
mpipe->preUninstCB = saPreCB;
|
||||||
|
mpipe->uninstanceCB = saUninstanceCB;
|
||||||
|
ps2::registerPDSPipe(mpipe);
|
||||||
|
|
||||||
|
mpipe = new MatPipeline(PLATFORM_PS2);
|
||||||
|
mpipe->pluginID = ID_PDS;
|
||||||
|
mpipe->pluginData = 0x53f2008d;
|
||||||
|
mpipe->attribs[0] = &saXYZADC;
|
||||||
|
mpipe->attribs[1] = &saUV;
|
||||||
|
mpipe->attribs[2] = &saRGBA;
|
||||||
|
mpipe->attribs[3] = &saNormal;
|
||||||
|
vertCount = MatPipeline::getVertCount(0x3BD, 4, 3, 3);
|
||||||
|
mpipe->setTriBufferSizes(4, vertCount);
|
||||||
|
mpipe->vifOffset = mpipe->inputStride*vertCount;
|
||||||
|
mpipe->instanceCB = saInstanceCB;
|
||||||
|
mpipe->preUninstCB = saPreCB;
|
||||||
|
mpipe->uninstanceCB = saUninstanceCB;
|
||||||
|
ps2::registerPDSPipe(mpipe);
|
||||||
|
|
||||||
|
mpipe = new MatPipeline(PLATFORM_PS2);
|
||||||
|
mpipe->pluginID = ID_PDS;
|
||||||
|
mpipe->pluginData = 0x53f2008f;
|
||||||
|
mpipe->attribs[0] = &saXYZADC;
|
||||||
|
mpipe->attribs[1] = &saUV;
|
||||||
|
mpipe->attribs[2] = &saRGBA2;
|
||||||
|
mpipe->attribs[3] = &saNormal;
|
||||||
|
vertCount = MatPipeline::getVertCount(0x3BD, 4, 3, 3);
|
||||||
|
mpipe->setTriBufferSizes(4, vertCount);
|
||||||
|
mpipe->vifOffset = mpipe->inputStride*vertCount;
|
||||||
|
mpipe->instanceCB = saInstanceCB;
|
||||||
|
mpipe->preUninstCB = saPreCB;
|
||||||
|
mpipe->uninstanceCB = saUninstanceCB;
|
||||||
|
ps2::registerPDSPipe(mpipe);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -116,4 +116,8 @@ extern int32 collisionOffset;
|
|||||||
|
|
||||||
void registerCollisionPlugin(void);
|
void registerCollisionPlugin(void);
|
||||||
|
|
||||||
|
// PDS pipes
|
||||||
|
|
||||||
|
void registerPDSPipes(void);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
191
src/ps2.cpp
191
src/ps2.cpp
@ -58,6 +58,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
|||||||
assert(a % 0x10 == 0);
|
assert(a % 0x10 == 0);
|
||||||
#endif
|
#endif
|
||||||
stream->read(instance->data, instance->dataSize);
|
stream->read(instance->data, instance->dataSize);
|
||||||
|
instance->material = geometry->meshHeader->mesh[i].material;
|
||||||
// sizedebug(instance);
|
// sizedebug(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,28 +190,6 @@ unfixDmaOffsets(InstanceData *inst)
|
|||||||
|
|
||||||
// Pipeline
|
// Pipeline
|
||||||
|
|
||||||
enum PS2Attribs {
|
|
||||||
AT_V2_32 = 0x64000000,
|
|
||||||
AT_V2_16 = 0x65000000,
|
|
||||||
AT_V2_8 = 0x66000000,
|
|
||||||
AT_V3_32 = 0x68000000,
|
|
||||||
AT_V3_16 = 0x69000000,
|
|
||||||
AT_V3_8 = 0x6A000000,
|
|
||||||
AT_V4_32 = 0x6C000000,
|
|
||||||
AT_V4_16 = 0x6D000000,
|
|
||||||
AT_V4_8 = 0x6E000000,
|
|
||||||
AT_UNSGN = 0x00004000,
|
|
||||||
|
|
||||||
AT_RW = 0x6
|
|
||||||
};
|
|
||||||
|
|
||||||
enum PS2AttibTypes {
|
|
||||||
AT_XYZ = 0,
|
|
||||||
AT_UV = 1,
|
|
||||||
AT_RGBA = 2,
|
|
||||||
AT_NORMAL = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
PipeAttribute attribXYZ = {
|
PipeAttribute attribXYZ = {
|
||||||
"XYZ",
|
"XYZ",
|
||||||
AT_V3_32
|
AT_V3_32
|
||||||
@ -254,10 +233,10 @@ static uint32
|
|||||||
getBatchSize(MatPipeline *pipe, uint32 vertCount)
|
getBatchSize(MatPipeline *pipe, uint32 vertCount)
|
||||||
{
|
{
|
||||||
PipeAttribute *a;
|
PipeAttribute *a;
|
||||||
uint32 size = 1;
|
uint32 size = 1; // ITOP &c. at the end
|
||||||
for(uint i = 0; i < nelem(pipe->attribs); i++)
|
for(uint i = 0; i < nelem(pipe->attribs); i++)
|
||||||
if((a = pipe->attribs[i]) && (a->attrib & AT_RW) == 0){
|
if((a = pipe->attribs[i]) && (a->attrib & AT_RW) == 0){
|
||||||
size++;
|
size++; // UNPACK &c.
|
||||||
size += QWC(vertCount*attribSize(a->attrib));
|
size += QWC(vertCount*attribSize(a->attrib));
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
@ -345,7 +324,7 @@ instanceNormal(uint32 *wp, Geometry *g, Mesh *m, uint32 idx, uint32 n)
|
|||||||
|
|
||||||
MatPipeline::MatPipeline(uint32 platform)
|
MatPipeline::MatPipeline(uint32 platform)
|
||||||
: rw::Pipeline(platform), instanceCB(NULL), uninstanceCB(NULL),
|
: rw::Pipeline(platform), instanceCB(NULL), uninstanceCB(NULL),
|
||||||
allocateCB(NULL), finishCB(NULL)
|
preUninstCB(NULL), postUninstCB(NULL)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 10; i++)
|
for(int i = 0; i < 10; i++)
|
||||||
this->attribs[i] = NULL;
|
this->attribs[i] = NULL;
|
||||||
@ -436,7 +415,7 @@ getInstMeshInfo(MatPipeline *pipe, Geometry *g, Mesh *m)
|
|||||||
if(im.numBrokenAttribs == 0)
|
if(im.numBrokenAttribs == 0)
|
||||||
im.size = 1 + im.batchSize*(im.numBatches-1) + im.lastBatchSize;
|
im.size = 1 + im.batchSize*(im.numBatches-1) + im.lastBatchSize;
|
||||||
else
|
else
|
||||||
im.size = 2*im.numBatches +
|
im.size = 2*im.numBrokenAttribs*im.numBatches +
|
||||||
(1+im.batchSize)*(im.numBatches-1) + 1+im.lastBatchSize;
|
(1+im.batchSize)*(im.numBatches-1) + 1+im.lastBatchSize;
|
||||||
|
|
||||||
/* figure out size and addresses of broken out sections */
|
/* figure out size and addresses of broken out sections */
|
||||||
@ -492,8 +471,11 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
|
|||||||
*p++ = im.attribPos[i];
|
*p++ = im.attribPos[i];
|
||||||
*p++ = 0x01000100 |
|
*p++ = 0x01000100 |
|
||||||
this->inputStride; // STCYCL
|
this->inputStride; // STCYCL
|
||||||
|
// Round up nverts so UNPACK will fit exactly into the DMA packet
|
||||||
|
// (can't pad with zeroes in broken out sections).
|
||||||
|
// TODO: check for clash with vifOffset somewhere
|
||||||
*p++ = (a->attrib&0xFF004000)
|
*p++ = (a->attrib&0xFF004000)
|
||||||
| 0x8000 | nverts << 16 | i; // UNPACK
|
| 0x8000 | (QWC(nverts*atsz)<<4)/atsz << 16 | i; // UNPACK
|
||||||
|
|
||||||
*p++ = 0x10000000;
|
*p++ = 0x10000000;
|
||||||
*p++ = 0x0;
|
*p++ = 0x0;
|
||||||
@ -572,10 +554,7 @@ MatPipeline::collectData(Geometry *g, InstanceData *inst, Mesh *m, uint8 *data[]
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8 *datap[nelem(this->attribs)];
|
uint8 *datap[nelem(this->attribs)];
|
||||||
for(uint i = 0; i < nelem(this->attribs); i++){
|
memcpy(datap, data, sizeof(datap));
|
||||||
datap[i] = data[i];
|
|
||||||
//printf("%p %x, %x\n", datap[i], datap[i]-datap[0], im.attribPos[i]*0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 overlap = g->meshHeader->flags == 1 ? 2 : 0;
|
uint32 overlap = g->meshHeader->flags == 1 ? 2 : 0;
|
||||||
uint32 *p = (uint32*)inst->data;
|
uint32 *p = (uint32*)inst->data;
|
||||||
@ -630,6 +609,7 @@ ObjPipeline::instance(Atomic *atomic)
|
|||||||
if(m == NULL)
|
if(m == NULL)
|
||||||
m = defaultMatPipe;
|
m = defaultMatPipe;
|
||||||
m->instance(geo, instance, mesh);
|
m->instance(geo, instance, mesh);
|
||||||
|
instance->material = mesh->material;
|
||||||
}
|
}
|
||||||
geo->geoflags |= Geometry::NATIVE;
|
geo->geoflags |= Geometry::NATIVE;
|
||||||
}
|
}
|
||||||
@ -638,6 +618,9 @@ void
|
|||||||
printVertCounts(InstanceData *inst, int flag)
|
printVertCounts(InstanceData *inst, int flag)
|
||||||
{
|
{
|
||||||
uint32 *d = (uint32*)inst->data;
|
uint32 *d = (uint32*)inst->data;
|
||||||
|
uint32 id = 0;
|
||||||
|
if(inst->material->pipeline)
|
||||||
|
id = inst->material->pipeline->pluginData;
|
||||||
int stride;
|
int stride;
|
||||||
if(inst->arePointersFixed){
|
if(inst->arePointersFixed){
|
||||||
d += 4;
|
d += 4;
|
||||||
@ -646,15 +629,16 @@ printVertCounts(InstanceData *inst, int flag)
|
|||||||
d += 4 + 4*QWC(attribSize(d[3])*((d[3]>>16)&0xFF));
|
d += 4 + 4*QWC(attribSize(d[3])*((d[3]>>16)&0xFF));
|
||||||
}
|
}
|
||||||
if(d[2] == 0)
|
if(d[2] == 0)
|
||||||
printf("ITOP %x %d (%d)\n", *d, stride, flag);
|
printf("ITOP %x %d (%d) %x\n", *d, stride, flag, id);
|
||||||
}else{
|
}else{
|
||||||
while((*d&0x70000000) == 0x30000000){
|
while((*d&0x70000000) == 0x30000000){
|
||||||
stride = d[2]&0xFF;
|
stride = d[2]&0xFF;
|
||||||
|
printf("UNPACK %x %d (%d) %x\n", d[3], stride, flag, id);
|
||||||
d += 8;
|
d += 8;
|
||||||
}
|
}
|
||||||
if((*d&0x70000000) == 0x10000000){
|
if((*d&0x70000000) == 0x10000000){
|
||||||
d += (*d&0xFFFF)*4;
|
d += (*d&0xFFFF)*4;
|
||||||
printf("ITOP %x %d (%d)\n", *d, stride, flag);
|
printf("ITOP %x %d (%d) %x\n", *d, stride, flag, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -667,6 +651,7 @@ ObjPipeline::uninstance(Atomic *atomic)
|
|||||||
return;
|
return;
|
||||||
assert(geo->instData != NULL);
|
assert(geo->instData != NULL);
|
||||||
assert(geo->instData->platform == PLATFORM_PS2);
|
assert(geo->instData->platform == PLATFORM_PS2);
|
||||||
|
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
||||||
// highest possible number of vertices
|
// highest possible number of vertices
|
||||||
geo->numVertices = geo->meshHeader->totalIndices;
|
geo->numVertices = geo->meshHeader->totalIndices;
|
||||||
geo->geoflags &= ~Geometry::NATIVE;
|
geo->geoflags &= ~Geometry::NATIVE;
|
||||||
@ -675,18 +660,24 @@ ObjPipeline::uninstance(Atomic *atomic)
|
|||||||
uint32 *flags = new uint32[geo->numVertices];
|
uint32 *flags = new uint32[geo->numVertices];
|
||||||
memset(flags, 0, 4*geo->numVertices);
|
memset(flags, 0, 4*geo->numVertices);
|
||||||
memset(geo->meshHeader->mesh[0].indices, 0, 2*geo->meshHeader->totalIndices);
|
memset(geo->meshHeader->mesh[0].indices, 0, 2*geo->meshHeader->totalIndices);
|
||||||
geo->numVertices = 0;
|
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
Mesh *mesh = &geo->meshHeader->mesh[i];
|
Mesh *mesh = &geo->meshHeader->mesh[i];
|
||||||
InstanceData *instance = &header->instanceMeshes[i];
|
|
||||||
|
|
||||||
MatPipeline *m;
|
MatPipeline *m;
|
||||||
m = this->groupPipeline ?
|
m = this->groupPipeline ?
|
||||||
this->groupPipeline :
|
this->groupPipeline :
|
||||||
(MatPipeline*)mesh->material->pipeline;
|
(MatPipeline*)mesh->material->pipeline;
|
||||||
if(m == NULL) m = defaultMatPipe;
|
if(m == NULL) m = defaultMatPipe;
|
||||||
if(m->allocateCB) m->allocateCB(m, geo);
|
if(m->preUninstCB) m->preUninstCB(m, geo);
|
||||||
|
}
|
||||||
|
geo->numVertices = 0;
|
||||||
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
|
Mesh *mesh = &geo->meshHeader->mesh[i];
|
||||||
|
InstanceData *instance = &header->instanceMeshes[i];
|
||||||
|
MatPipeline *m;
|
||||||
|
m = this->groupPipeline ?
|
||||||
|
this->groupPipeline :
|
||||||
|
(MatPipeline*)mesh->material->pipeline;
|
||||||
|
if(m == NULL) m = defaultMatPipe;
|
||||||
|
|
||||||
uint8 *data[nelem(m->attribs)] = { NULL };
|
uint8 *data[nelem(m->attribs)] = { NULL };
|
||||||
uint8 *raw = m->collectData(geo, instance, mesh, data);
|
uint8 *raw = m->collectData(geo, instance, mesh, data);
|
||||||
@ -701,21 +692,28 @@ ObjPipeline::uninstance(Atomic *atomic)
|
|||||||
this->groupPipeline :
|
this->groupPipeline :
|
||||||
(MatPipeline*)mesh->material->pipeline;
|
(MatPipeline*)mesh->material->pipeline;
|
||||||
if(m == NULL) m = defaultMatPipe;
|
if(m == NULL) m = defaultMatPipe;
|
||||||
if(m->finishCB) m->finishCB(m, geo);
|
if(m->postUninstCB) m->postUninstCB(m, geo);
|
||||||
}
|
}
|
||||||
|
|
||||||
geo->generateTriangles();
|
int8 *bits = NULL;
|
||||||
|
if(adcOffset){
|
||||||
|
ADCData *adc = PLUGINOFFSET(ADCData, geo, adcOffset);
|
||||||
|
if(adc->adcFormatted)
|
||||||
|
bits = adc->adcBits;
|
||||||
|
}
|
||||||
|
geo->generateTriangles(bits);
|
||||||
delete[] flags;
|
delete[] flags;
|
||||||
destroyNativeData(geo, 0, 0);
|
destroyNativeData(geo, 0, 0);
|
||||||
geo->instData = NULL;
|
geo->instData = NULL;
|
||||||
|
/*
|
||||||
/* for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
Mesh *mesh = &geometry->meshHeader->mesh[i];
|
Mesh *mesh = &geo->meshHeader->mesh[i];
|
||||||
InstanceData *instance = &header->instanceMeshes[i];
|
InstanceData *instance = &header->instanceMeshes[i];
|
||||||
// printf("numIndices: %d\n", mesh->numIndices);
|
// printf("numIndices: %d\n", mesh->numIndices);
|
||||||
// printDMA(instance);
|
// printDMA(instance);
|
||||||
printVertCounts(instance, geometry->meshHeader->flags);
|
printVertCounts(instance, geo->meshHeader->flags);
|
||||||
}*/
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
@ -832,8 +830,6 @@ makeDefaultPipeline(void)
|
|||||||
|
|
||||||
static void skinInstanceCB(MatPipeline*, Geometry*, Mesh*, uint8**, int32);
|
static void skinInstanceCB(MatPipeline*, Geometry*, Mesh*, uint8**, int32);
|
||||||
static void skinUninstanceCB(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**);
|
static void skinUninstanceCB(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**);
|
||||||
static void skinAllocateCB(MatPipeline*, Geometry*);
|
|
||||||
static void skinFinishCB(MatPipeline*, Geometry*);
|
|
||||||
|
|
||||||
ObjPipeline*
|
ObjPipeline*
|
||||||
makeSkinPipeline(void)
|
makeSkinPipeline(void)
|
||||||
@ -851,8 +847,8 @@ makeSkinPipeline(void)
|
|||||||
pipe->vifOffset = pipe->inputStride*vertCount;
|
pipe->vifOffset = pipe->inputStride*vertCount;
|
||||||
pipe->instanceCB = skinInstanceCB;
|
pipe->instanceCB = skinInstanceCB;
|
||||||
pipe->uninstanceCB = skinUninstanceCB;
|
pipe->uninstanceCB = skinUninstanceCB;
|
||||||
pipe->allocateCB = skinAllocateCB;
|
pipe->preUninstCB = skinPreCB;
|
||||||
pipe->finishCB = skinFinishCB;
|
pipe->postUninstCB = skinPostCB;
|
||||||
|
|
||||||
ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
|
ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
|
||||||
opipe->pluginID = ID_SKIN;
|
opipe->pluginID = ID_SKIN;
|
||||||
@ -1108,15 +1104,12 @@ skinUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, u
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
skinAllocateCB(MatPipeline*, Geometry *geo)
|
skinPreCB(MatPipeline*, Geometry *geo)
|
||||||
{
|
{
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
||||||
// If weight/index data is allocated don't do it again as this function
|
if(skin == NULL)
|
||||||
// can be called multiple times per geometry.
|
|
||||||
if(skin == NULL || skin->weights)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint8 *data = skin->data;
|
uint8 *data = skin->data;
|
||||||
float *invMats = skin->inverseMatrices;
|
float *invMats = skin->inverseMatrices;
|
||||||
// meshHeader->totalIndices is highest possible number of vertices again
|
// meshHeader->totalIndices is highest possible number of vertices again
|
||||||
@ -1125,8 +1118,8 @@ skinAllocateCB(MatPipeline*, Geometry *geo)
|
|||||||
delete[] data;
|
delete[] data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
skinFinishCB(MatPipeline*, Geometry *geo)
|
skinPostCB(MatPipeline*, Geometry *geo)
|
||||||
{
|
{
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
||||||
skin->findNumWeights(geo->numVertices);
|
skin->findNumWeights(geo->numVertices);
|
||||||
@ -1135,6 +1128,8 @@ skinFinishCB(MatPipeline*, Geometry *geo)
|
|||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
|
|
||||||
|
int32 adcOffset;
|
||||||
|
|
||||||
// TODO: look at PC SA rccam.dff bloodrb.dff, Xbox csbigbear.dff
|
// TODO: look at PC SA rccam.dff bloodrb.dff, Xbox csbigbear.dff
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1217,6 +1212,17 @@ debugadc(Geometry *g, MeshHeader *mh, ADCData *adc)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
allocateADC(Geometry *geo)
|
||||||
|
{
|
||||||
|
ADCData *adc = PLUGINOFFSET(ADCData, geo, adcOffset);
|
||||||
|
adc->adcFormatted = 1;
|
||||||
|
adc->numBits = geo->meshHeader->totalIndices;
|
||||||
|
int32 size = adc->numBits+3 & ~3;
|
||||||
|
adc->adcBits = new int8[size];
|
||||||
|
memset(adc->adcBits, 0, size);
|
||||||
|
}
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
createADC(void *object, int32 offset, int32)
|
createADC(void *object, int32 offset, int32)
|
||||||
{
|
{
|
||||||
@ -1311,7 +1317,7 @@ getSizeADC(void *object, int32 offset, int32)
|
|||||||
void
|
void
|
||||||
registerADCPlugin(void)
|
registerADCPlugin(void)
|
||||||
{
|
{
|
||||||
Geometry::registerPlugin(sizeof(ADCData), ID_ADC,
|
adcOffset = Geometry::registerPlugin(sizeof(ADCData), ID_ADC,
|
||||||
createADC, destroyADC, copyADC);
|
createADC, destroyADC, copyADC);
|
||||||
Geometry::registerPluginStream(ID_ADC,
|
Geometry::registerPluginStream(ID_ADC,
|
||||||
readADC,
|
readADC,
|
||||||
@ -1322,29 +1328,50 @@ registerADCPlugin(void)
|
|||||||
|
|
||||||
// PDS plugin
|
// PDS plugin
|
||||||
|
|
||||||
|
struct PdsGlobals
|
||||||
|
{
|
||||||
|
Pipeline **pipes;
|
||||||
|
int32 maxPipes;
|
||||||
|
int32 numPipes;
|
||||||
|
};
|
||||||
|
PdsGlobals pdsGlobals;
|
||||||
|
|
||||||
|
Pipeline*
|
||||||
|
getPDSPipe(uint32 data)
|
||||||
|
{
|
||||||
|
for(int32 i = 0; i < pdsGlobals.numPipes; i++)
|
||||||
|
if(pdsGlobals.pipes[i]->pluginData == data)
|
||||||
|
return pdsGlobals.pipes[i];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
registerPDSPipe(Pipeline *pipe)
|
||||||
|
{
|
||||||
|
assert(pdsGlobals.numPipes < pdsGlobals.maxPipes);
|
||||||
|
pdsGlobals.pipes[pdsGlobals.numPipes++] = pipe;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
atomicPDSRights(void *object, int32, int32, uint32 data)
|
atomicPDSRights(void *object, int32, int32, uint32 data)
|
||||||
{
|
{
|
||||||
Atomic *a = (Atomic*)object;
|
Atomic *a = (Atomic*)object;
|
||||||
// TODO: lookup pipeline by data
|
a->pipeline = (ObjPipeline*)getPDSPipe(data);
|
||||||
a->pipeline = new ObjPipeline(PLATFORM_PS2);
|
|
||||||
a->pipeline->pluginID = ID_PDS;
|
|
||||||
a->pipeline->pluginData = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
materialPDSRights(void *object, int32, int32, uint32 data)
|
materialPDSRights(void *object, int32, int32, uint32 data)
|
||||||
{
|
{
|
||||||
Material *m = (Material*)object;
|
Material *m = (Material*)object;
|
||||||
// TODO: lookup pipeline by data
|
m->pipeline = (ObjPipeline*)getPDSPipe(data);
|
||||||
m->pipeline = new Pipeline(PLATFORM_PS2);
|
|
||||||
m->pipeline->pluginID = ID_PDS;
|
|
||||||
m->pipeline->pluginData = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
registerPDSPlugin(void)
|
registerPDSPlugin(int32 n)
|
||||||
{
|
{
|
||||||
|
pdsGlobals.maxPipes = n;
|
||||||
|
pdsGlobals.numPipes = 0;
|
||||||
|
pdsGlobals.pipes = new Pipeline*[n];
|
||||||
Atomic::registerPlugin(0, ID_PDS, NULL, NULL, NULL);
|
Atomic::registerPlugin(0, ID_PDS, NULL, NULL, NULL);
|
||||||
Atomic::setStreamRightsCallback(ID_PDS, atomicPDSRights);
|
Atomic::setStreamRightsCallback(ID_PDS, atomicPDSRights);
|
||||||
|
|
||||||
@ -1381,36 +1408,6 @@ printDMA(InstanceData *inst)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function to specifically walk geometry chains */
|
|
||||||
void
|
|
||||||
walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size))
|
|
||||||
{
|
|
||||||
if(inst->arePointersFixed == 2)
|
|
||||||
return;
|
|
||||||
uint32 *base = (uint32*)inst->data;
|
|
||||||
uint32 *tag = (uint32*)inst->data;
|
|
||||||
for(;;){
|
|
||||||
switch(tag[0]&0x70000000){
|
|
||||||
// DMAcnt
|
|
||||||
case 0x10000000:
|
|
||||||
f(tag+2, 2+(tag[0]&0xFFFF)*4);
|
|
||||||
tag += (1+(tag[0]&0xFFFF))*4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// DMAref
|
|
||||||
case 0x30000000:
|
|
||||||
f(base + tag[1]*4, (tag[0]&0xFFFF)*4);
|
|
||||||
tag += 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// DMAret
|
|
||||||
case 0x60000000:
|
|
||||||
f(tag+2, 2+(tag[0]&0xFFFF)*4);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sizedebug(InstanceData *inst)
|
sizedebug(InstanceData *inst)
|
||||||
{
|
{
|
||||||
|
@ -333,7 +333,7 @@ struct Geometry : PluginBase<Geometry>, Object
|
|||||||
uint32 streamGetSize(void);
|
uint32 streamGetSize(void);
|
||||||
void addMorphTargets(int32 n);
|
void addMorphTargets(int32 n);
|
||||||
void allocateData(void);
|
void allocateData(void);
|
||||||
void generateTriangles(void);
|
void generateTriangles(int8 *adc = NULL);
|
||||||
|
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
|
41
src/rwps2.h
41
src/rwps2.h
@ -23,6 +23,28 @@ enum {
|
|||||||
VU_Lights = 0x3d0
|
VU_Lights = 0x3d0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PS2Attribs {
|
||||||
|
AT_V2_32 = 0x64000000,
|
||||||
|
AT_V2_16 = 0x65000000,
|
||||||
|
AT_V2_8 = 0x66000000,
|
||||||
|
AT_V3_32 = 0x68000000,
|
||||||
|
AT_V3_16 = 0x69000000,
|
||||||
|
AT_V3_8 = 0x6A000000,
|
||||||
|
AT_V4_32 = 0x6C000000,
|
||||||
|
AT_V4_16 = 0x6D000000,
|
||||||
|
AT_V4_8 = 0x6E000000,
|
||||||
|
AT_UNSGN = 0x00004000,
|
||||||
|
|
||||||
|
AT_RW = 0x6
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PS2AttibTypes {
|
||||||
|
AT_XYZ = 0,
|
||||||
|
AT_UV = 1,
|
||||||
|
AT_RGBA = 2,
|
||||||
|
AT_NORMAL = 3
|
||||||
|
};
|
||||||
|
|
||||||
void *destroyNativeData(void *object, int32, int32);
|
void *destroyNativeData(void *object, int32, int32);
|
||||||
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||||
void writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
void writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||||
@ -30,7 +52,6 @@ int32 getSizeNativeData(void *object, int32, int32);
|
|||||||
void registerNativeDataPlugin(void);
|
void registerNativeDataPlugin(void);
|
||||||
|
|
||||||
void printDMA(InstanceData *inst);
|
void printDMA(InstanceData *inst);
|
||||||
void walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size));
|
|
||||||
void sizedebug(InstanceData *inst);
|
void sizedebug(InstanceData *inst);
|
||||||
|
|
||||||
// only RW_PS2
|
// only RW_PS2
|
||||||
@ -47,8 +68,8 @@ public:
|
|||||||
PipeAttribute *attribs[10];
|
PipeAttribute *attribs[10];
|
||||||
void (*instanceCB)(MatPipeline*, Geometry*, Mesh*, uint8**, int32);
|
void (*instanceCB)(MatPipeline*, Geometry*, Mesh*, uint8**, int32);
|
||||||
void (*uninstanceCB)(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**);
|
void (*uninstanceCB)(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**);
|
||||||
void (*allocateCB)(MatPipeline*, Geometry*);
|
void (*preUninstCB)(MatPipeline*, Geometry*);
|
||||||
void (*finishCB)(MatPipeline*, Geometry*);
|
void (*postUninstCB)(MatPipeline*, Geometry*);
|
||||||
|
|
||||||
static uint32 getVertCount(uint32 top, uint32 inAttribs,
|
static uint32 getVertCount(uint32 top, uint32 inAttribs,
|
||||||
uint32 outAttribs, uint32 outBufs) {
|
uint32 outAttribs, uint32 outBufs) {
|
||||||
@ -72,6 +93,8 @@ public:
|
|||||||
virtual void uninstance(Atomic *atomic);
|
virtual void uninstance(Atomic *atomic);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void insertVertex(Geometry *geo, int32 i, uint32 mask, float *v, float *t0, float *t1, uint8 *c, float *n);
|
||||||
|
|
||||||
extern ObjPipeline *defaultObjPipe;
|
extern ObjPipeline *defaultObjPipe;
|
||||||
extern MatPipeline *defaultMatPipe;
|
extern MatPipeline *defaultMatPipe;
|
||||||
|
|
||||||
@ -86,6 +109,9 @@ void readNativeSkin(Stream *stream, int32, void *object, int32 offset);
|
|||||||
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
||||||
int32 getSizeNativeSkin(void *object, int32 offset);
|
int32 getSizeNativeSkin(void *object, int32 offset);
|
||||||
|
|
||||||
|
void skinPreCB(MatPipeline*, Geometry*);
|
||||||
|
void skinPostCB(MatPipeline*, Geometry*);
|
||||||
|
|
||||||
// ADC plugin
|
// ADC plugin
|
||||||
|
|
||||||
// Each element in adcBits corresponds to an index in Mesh->indices,
|
// Each element in adcBits corresponds to an index in Mesh->indices,
|
||||||
@ -101,9 +127,11 @@ struct ADCData
|
|||||||
int8 *adcBits;
|
int8 *adcBits;
|
||||||
int32 numBits;
|
int32 numBits;
|
||||||
};
|
};
|
||||||
|
extern int32 adcOffset;
|
||||||
void registerADCPlugin(void);
|
void registerADCPlugin(void);
|
||||||
|
|
||||||
|
void allocateADC(Geometry *geo);
|
||||||
|
|
||||||
// PDS plugin
|
// PDS plugin
|
||||||
|
|
||||||
// IDs used by SA
|
// IDs used by SA
|
||||||
@ -117,8 +145,9 @@ void registerADCPlugin(void);
|
|||||||
// 4640 53f20084 53f2008b // vehicles
|
// 4640 53f20084 53f2008b // vehicles
|
||||||
// 418 53f20088 53f20089 // peds
|
// 418 53f20088 53f20089 // peds
|
||||||
|
|
||||||
|
Pipeline *getPDSPipe(uint32 data);
|
||||||
void registerPDSPlugin(void);
|
void registerPDSPipe(Pipeline *pipe);
|
||||||
|
void registerPDSPlugin(int32 n);
|
||||||
|
|
||||||
// Native Texture and Raster
|
// Native Texture and Raster
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user