some work on ps2 pipelines, d3d rasters

This commit is contained in:
aap 2016-02-23 10:07:04 +01:00
parent 91291709d8
commit a6a7b0e89c
9 changed files with 454 additions and 188 deletions

View File

@ -198,6 +198,7 @@
<ClCompile Include="src\geometry.cpp" /> <ClCompile Include="src\geometry.cpp" />
<ClCompile Include="src\image.cpp" /> <ClCompile Include="src\image.cpp" />
<ClCompile Include="src\ogl.cpp" /> <ClCompile Include="src\ogl.cpp" />
<ClCompile Include="src\pds.cpp" />
<ClCompile Include="src\pipeline.cpp" /> <ClCompile Include="src\pipeline.cpp" />
<ClCompile Include="src\plugins.cpp" /> <ClCompile Include="src\plugins.cpp" />
<ClCompile Include="src\ps2.cpp" /> <ClCompile Include="src\ps2.cpp" />

View File

@ -420,18 +420,25 @@ void
D3dRaster::fromImage(Raster *raster, Image *image) D3dRaster::fromImage(Raster *raster, Image *image)
{ {
int32 format; int32 format;
if(image->depth == 32) switch(image->depth){
format = Raster::C8888; case 32:
else if(image->depth == 24) format = image->hasAlpha() ? Raster::C8888 : Raster::C888;
break;
case 24:
format = Raster::C888; format = Raster::C888;
else if(image->depth == 16) break;
case 16:
format = Raster::C1555; format = Raster::C1555;
else if(image->depth == 8) break;
case 8:
format = Raster::PAL8 | Raster::C8888; format = Raster::PAL8 | Raster::C8888;
else if(image->depth == 4) break;
case 4:
format = Raster::PAL4 | Raster::C8888; format = Raster::PAL4 | Raster::C8888;
else break;
default:
return; return;
}
format |= 4; format |= 4;
raster->type = format & 0x7; raster->type = format & 0x7;
@ -458,11 +465,13 @@ D3dRaster::fromImage(Raster *raster, Image *image)
} }
} }
int32 inc = image->depth/8;
in = image->pixels; in = image->pixels;
out = raster->lock(0); out = raster->lock(0);
if(pallength) if(pallength)
memcpy(out, in, raster->width*raster->height); memcpy(out, in, raster->width*raster->height);
else else
// TODO: stride
for(int32 y = 0; y < image->height; y++) for(int32 y = 0; y < image->height; y++)
for(int32 x = 0; x < image->width; x++) for(int32 x = 0; x < image->width; x++)
switch(raster->format & 0xF00){ switch(raster->format & 0xF00){
@ -471,7 +480,7 @@ D3dRaster::fromImage(Raster *raster, Image *image)
out[1] = in[1]; out[1] = in[1];
out[2] = in[0]; out[2] = in[0];
out[3] = in[3]; out[3] = in[3];
in += 4; in += inc;
out += 4; out += 4;
break; break;
case Raster::C888: case Raster::C888:
@ -479,7 +488,7 @@ D3dRaster::fromImage(Raster *raster, Image *image)
out[1] = in[1]; out[1] = in[1];
out[2] = in[0]; out[2] = in[0];
out[3] = 0xFF; out[3] = 0xFF;
in += 3; in += inc;
out += 4; out += 4;
break; break;
case Raster::C1555: case Raster::C1555:

View File

@ -447,6 +447,65 @@ Geometry::buildMeshes(void)
} }
} }
// HAS to be called with an existing mesh
void
Geometry::removeUnusedMaterials(void)
{
if(this->meshHeader == NULL)
return;
MeshHeader *mh = this->meshHeader;
int32 *map = new int32[this->numMaterials];
Material **matlist = new Material*[this->numMaterials];
int32 numMaterials = 0;
/* Build new material list and map */
for(uint32 i = 0; i < mh->numMeshes; i++){
Mesh *m = &mh->mesh[i];
if(m->numIndices <= 0)
continue;
matlist[numMaterials] = m->material;
int32 oldid = findPointer((void*)m->material,
(void**)this->materialList,
this->numMaterials);
map[oldid] = numMaterials;
numMaterials++;
}
delete[] this->materialList;
this->materialList = matlist;
this->numMaterials = numMaterials;
/* Build new meshes */
MeshHeader *newmh = new MeshHeader;
newmh->flags = mh->flags;
newmh->numMeshes = numMaterials;
newmh->mesh = new Mesh[newmh->numMeshes];
newmh->totalIndices = mh->totalIndices;
Mesh *newm = newmh->mesh;
for(uint32 i = 0; i < mh->numMeshes; i++){
Mesh *oldm = &mh->mesh[i];
if(oldm->numIndices <= 0)
continue;
newm->numIndices = oldm->numIndices;
newm->material = oldm->material;
newm++;
}
newmh->allocateIndices();
/* Copy indices */
newm = newmh->mesh;
for(uint32 i = 0; i < mh->numMeshes; i++){
Mesh *oldm = &mh->mesh[i];
if(oldm->numIndices <= 0)
continue;
memcpy(newm->indices, oldm->indices,
oldm->numIndices*sizeof(*oldm->indices));
newm++;
}
delete this->meshHeader;
this->meshHeader = newmh;
/* Remap triangle material IDs */
for(int32 i = 0; i < this->numTriangles; i++)
this->triangles[i].matId = map[this->triangles[i].matId];
delete[] map;
}
// //
// Material // Material
// //

View File

@ -379,6 +379,27 @@ Image::setPalette(uint8 *palette)
this->flags |= 2; this->flags |= 2;
} }
bool32
Image::hasAlpha(void)
{
uint8 ret = 0xFF;
uint8 *pixels = this->pixels;
if(this->depth == 24)
return 0;
// TODO: palettized textures
if(this->depth == 32){
for(int y = 0; y < this->height; y++){
uint8 *line = pixels;
for(int x = 0; x < this->width; x++){
ret &= line[3];
line += 4;
}
pixels += this->stride;
}
}
return ret != 0xFF;
}
static char *searchPaths = NULL; static char *searchPaths = NULL;
int numSearchPaths = 0; int numSearchPaths = 0;

185
src/pds.cpp Normal file
View File

@ -0,0 +1,185 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwps2.h"
namespace rw {
namespace ps2 {
struct PdsGlobals
{
Pipeline **pipes;
int32 maxPipes;
int32 numPipes;
};
static 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
atomicPDSRights(void *object, int32, int32, uint32 data)
{
Atomic *a = (Atomic*)object;
//printf("atm pds: %x\n", data);
a->pipeline = (ObjPipeline*)getPDSPipe(data);
}
static void
materialPDSRights(void *object, int32, int32, uint32 data)
{
Material *m = (Material*)object;
//printf("mat pds: %x\n", data);
m->pipeline = (ObjPipeline*)getPDSPipe(data);
}
void
registerPDSPlugin(int32 n)
{
pdsGlobals.maxPipes = n;
pdsGlobals.numPipes = 0;
pdsGlobals.pipes = new Pipeline*[n];
Atomic::registerPlugin(0, ID_PDS, NULL, NULL, NULL);
Atomic::setStreamRightsCallback(ID_PDS, atomicPDSRights);
Material::registerPlugin(0, ID_PDS, NULL, NULL, NULL);
Material::setStreamRightsCallback(ID_PDS, materialPDSRights);
}
void
registerPluginPDSPipes(void)
{
// rwPDS_G3_Skin_GrpMatPipeID
MatPipeline *pipe = new MatPipeline(PLATFORM_PS2);
pipe->pluginID = ID_PDS;
pipe->pluginData = 0x11001;
pipe->attribs[AT_XYZ] = &attribXYZ;
pipe->attribs[AT_UV] = &attribUV;
pipe->attribs[AT_RGBA] = &attribRGBA;
pipe->attribs[AT_NORMAL] = &attribNormal;
pipe->attribs[AT_NORMAL+1] = &attribWeights;
uint32 vertCount = MatPipeline::getVertCount(VU_Lights-0x100, 5, 3, 2);
pipe->setTriBufferSizes(5, vertCount);
pipe->vifOffset = pipe->inputStride*vertCount;
pipe->instanceCB = skinInstanceCB;
pipe->uninstanceCB = skinUninstanceCB;
pipe->preUninstCB = skinPreCB;
pipe->postUninstCB = skinPostCB;
registerPDSPipe(pipe);
// rwPDS_G3_Skin_GrpAtmPipeID
ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
opipe->pluginID = ID_PDS;
opipe->pluginData = 0x11002;
opipe->groupPipeline = pipe;
registerPDSPipe(opipe);
// rwPDS_G3_MatfxUV1_GrpMatPipeID
pipe = new MatPipeline(PLATFORM_PS2);
pipe->pluginID = ID_PDS;
pipe->pluginData = 0x1100b;
pipe->attribs[AT_XYZ] = &attribXYZ;
pipe->attribs[AT_UV] = &attribUV;
pipe->attribs[AT_RGBA] = &attribRGBA;
pipe->attribs[AT_NORMAL] = &attribNormal;
vertCount = MatPipeline::getVertCount(0x3C5, 4, 3, 3);
pipe->setTriBufferSizes(4, vertCount);
pipe->vifOffset = pipe->inputStride*vertCount;
pipe->uninstanceCB = defaultUninstanceCB;
registerPDSPipe(pipe);
// rwPDS_G3_MatfxUV1_GrpAtmPipeID
opipe = new ObjPipeline(PLATFORM_PS2);
opipe->pluginID = ID_PDS;
opipe->pluginData = 0x1100d;
opipe->groupPipeline = pipe;
registerPDSPipe(opipe);
// rwPDS_G3_MatfxUV2_GrpMatPipeID
pipe = new MatPipeline(PLATFORM_PS2);
pipe->pluginID = ID_PDS;
pipe->pluginData = 0x1100c;
pipe->attribs[AT_XYZ] = &attribXYZ;
pipe->attribs[AT_UV] = &attribUV2;
pipe->attribs[AT_RGBA] = &attribRGBA;
pipe->attribs[AT_NORMAL] = &attribNormal;
vertCount = MatPipeline::getVertCount(0x3C5, 4, 3, 3);
pipe->setTriBufferSizes(4, vertCount);
pipe->vifOffset = pipe->inputStride*vertCount;
pipe->uninstanceCB = defaultUninstanceCB;
registerPDSPipe(pipe);
// rwPDS_G3_MatfxUV2_GrpAtmPipeID
opipe = new ObjPipeline(PLATFORM_PS2);
opipe->pluginID = ID_PDS;
opipe->pluginData = 0x1100e;
opipe->groupPipeline = pipe;
registerPDSPipe(opipe);
// RW World plugin
// rwPDS_G3x_Generic_AtmPipeID
opipe = new ObjPipeline(PLATFORM_PS2);
opipe->pluginID = ID_PDS;
opipe->pluginData = 0x50001;
opipe->groupPipeline = pipe;
registerPDSPipe(opipe);
// rwPDS_G3x_Skin_AtmPipeID
opipe = new ObjPipeline(PLATFORM_PS2);
opipe->pluginID = ID_PDS;
opipe->pluginData = 0x5000b;
opipe->groupPipeline = pipe;
registerPDSPipe(opipe);
// rwPDS_G3xd_A4D_MatPipeID
pipe = new MatPipeline(PLATFORM_PS2);
pipe->pluginID = ID_PDS;
pipe->pluginData = 0x5002f;
pipe->attribs[0] = &attribXYZW;
pipe->attribs[1] = &attribUV;
pipe->attribs[2] = &attribNormal;
vertCount = 0x50;
pipe->setTriBufferSizes(3, vertCount);
pipe->vifOffset = pipe->inputStride*vertCount;
// TODO:
//pipe->uninstanceCB = defaultUninstanceCB;
registerPDSPipe(pipe);
// rwPDS_G3xd_A4DSkin_MatPipeID
pipe = new MatPipeline(PLATFORM_PS2);
pipe->pluginID = ID_PDS;
pipe->pluginData = 0x5003e;
pipe->attribs[0] = &attribXYZW;
pipe->attribs[1] = &attribUV;
pipe->attribs[2] = &attribNormal;
pipe->attribs[3] = &attribWeights;
vertCount = 0x30;
pipe->setTriBufferSizes(4, vertCount);
pipe->vifOffset = pipe->inputStride*vertCount;
// TODO:
//pipe->uninstanceCB = skinUninstanceCB;
registerPDSPipe(pipe);
}
}
}

View File

@ -191,6 +191,11 @@ PipeAttribute attribXYZ = {
AT_V3_32 AT_V3_32
}; };
PipeAttribute attribXYZW = {
"XYZW",
AT_V4_32
};
PipeAttribute attribUV = { PipeAttribute attribUV = {
"UV", "UV",
AT_V2_32 AT_V2_32
@ -256,6 +261,23 @@ instanceXYZ(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
return p; return p;
} }
uint32*
instanceXYZW(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
{
uint16 j;
uint32 *d = (uint32*)g->morphTargets[0].vertices;
int8 *adcbits = getADCbitsForMesh(g, m);
for(uint32 i = idx; i < idx+n; i++){
j = m->indices[i];
*p++ = d[j*3+0];
*p++ = d[j*3+1];
*p++ = d[j*3+2];
*p++ = adcbits && adcbits[i] ? 0x8000 : 0;
}
// don't need to pad
return p;
}
uint32* uint32*
instanceUV(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n) instanceUV(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
{ {
@ -393,7 +415,55 @@ brokenout:
this->triStripCount = (stripCount-2)/4*4+2; this->triStripCount = (stripCount-2)/4*4+2;
} }
uint32 markcnt = 0xf790; // Instance format:
// no broken out clusters
// ======================
// DMAret [FLUSH; MSKPATH3 || FLUSH; FLUSH] {
// foreach batch {
// foreach cluster {
// MARK/0; STMOD; STCYCL; UNPACK
// unpack-data
// }
// ITOP; MSCALF/MSCNT; // if first/not-first
// 0/FLUSH; 0/MSKPATH3 || 0/FLUSH; 0/FLUSH // if not-last/last
// }
// }
//
// broken out clusters
// ===================
// foreach batch {
// foreach broken out cluster {
// DMAref [STCYCL; UNPACK] -> pointer into unpack-data
// DMAcnt (empty)
// }
// DMAcnt/ret {
// foreach cluster {
// MARK/0; STMOD; STCYCL; UNPACK
// unpack-data
// }
// ITOP; MSCALF/MSCNT; // if first/not-first
// 0/FLUSH; 0/MSKPATH3 || 0/FLUSH; 0/FLUSH // if not-last/last
// }
// }
// unpack-data for broken out clusters
uint32 markcnt = 0;
enum {
DMAcnt = 0x10000000,
DMAref = 0x30000000,
DMAret = 0x60000000,
VIF_NOP = 0,
VIF_STCYCL = 0x01000100, // WL = 1
VIF_ITOP = 0x04000000,
VIF_STMOD = 0x05000000,
VIF_MSKPATH3 = 0x06000000,
VIF_MARK = 0x07000000,
VIF_FLUSH = 0x11000000,
VIF_MSCALF = 0x15000000,
VIF_MSCNT = 0x17000000,
};
struct InstMeshInfo struct InstMeshInfo
{ {
@ -401,7 +471,9 @@ struct InstMeshInfo
uint32 batchVertCount, lastBatchVertCount; uint32 batchVertCount, lastBatchVertCount;
uint32 numBatches; uint32 numBatches;
uint32 batchSize, lastBatchSize; uint32 batchSize, lastBatchSize;
uint32 size, size2, stride; uint32 size; // size of DMA chain without broken out data
uint32 size2; // size of broken out data
uint32 vertexSize;
uint32 attribPos[10]; uint32 attribPos[10];
}; };
@ -412,16 +484,15 @@ getInstMeshInfo(MatPipeline *pipe, Geometry *g, Mesh *m)
InstMeshInfo im; InstMeshInfo im;
im.numAttribs = 0; im.numAttribs = 0;
im.numBrokenAttribs = 0; im.numBrokenAttribs = 0;
im.stride = 0; im.vertexSize = 0;
for(uint i = 0; i < nelem(pipe->attribs); i++) for(uint i = 0; i < nelem(pipe->attribs); i++)
if(a = pipe->attribs[i]) if(a = pipe->attribs[i])
if(a->attrib & AT_RW) if(a->attrib & AT_RW)
im.numBrokenAttribs++; im.numBrokenAttribs++;
else{ else{
im.stride += attribSize(a->attrib); im.vertexSize += attribSize(a->attrib);
im.numAttribs++; im.numAttribs++;
} }
uint32 totalVerts = 0;
if(g->meshHeader->flags == MeshHeader::TRISTRIP){ if(g->meshHeader->flags == MeshHeader::TRISTRIP){
im.numBatches = (m->numIndices-2) / (pipe->triStripCount-2); im.numBatches = (m->numIndices-2) / (pipe->triStripCount-2);
im.batchVertCount = pipe->triStripCount; im.batchVertCount = pipe->triStripCount;
@ -430,7 +501,7 @@ getInstMeshInfo(MatPipeline *pipe, Geometry *g, Mesh *m)
im.numBatches++; im.numBatches++;
im.lastBatchVertCount += 2; im.lastBatchVertCount += 2;
} }
}else{ }else{ // TRILIST; nothing else supported yet
im.numBatches = (m->numIndices+pipe->triListCount-1) / im.numBatches = (m->numIndices+pipe->triListCount-1) /
pipe->triListCount; pipe->triListCount;
im.batchVertCount = pipe->triListCount; im.batchVertCount = pipe->triListCount;
@ -441,7 +512,6 @@ getInstMeshInfo(MatPipeline *pipe, Geometry *g, Mesh *m)
im.batchSize = getBatchSize(pipe, im.batchVertCount); im.batchSize = getBatchSize(pipe, im.batchVertCount);
im.lastBatchSize = getBatchSize(pipe, im.lastBatchVertCount); im.lastBatchSize = getBatchSize(pipe, im.lastBatchVertCount);
im.size = 0;
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
@ -477,13 +547,16 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
if((a = this->attribs[i]) && a->attrib & AT_RW) if((a = this->attribs[i]) && a->attrib & AT_RW)
dp[i] = inst->data + im.attribPos[i]*0x10; dp[i] = inst->data + im.attribPos[i]*0x10;
// TODO: not sure if this is correct
uint32 msk_flush = rw::version >= 0x35000 ? VIF_FLUSH : VIF_MSKPATH3;
uint32 idx = 0; uint32 idx = 0;
uint32 *p = (uint32*)inst->data; uint32 *p = (uint32*)inst->data;
if(im.numBrokenAttribs == 0){ if(im.numBrokenAttribs == 0){
*p++ = 0x60000000 | im.size-1; *p++ = DMAret | im.size-1;
*p++ = 0; *p++ = 0;
*p++ = 0x11000000; // FLUSH *p++ = VIF_FLUSH;
*p++ = 0x06000000; // MSKPATH3; SA: FLUSH *p++ = msk_flush;
} }
for(uint32 j = 0; j < im.numBatches; j++){ for(uint32 j = 0; j < im.numBatches; j++){
uint32 nverts, bsize; uint32 nverts, bsize;
@ -497,44 +570,46 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
for(uint i = 0; i < nelem(this->attribs); i++) for(uint i = 0; i < nelem(this->attribs); i++)
if((a = this->attribs[i]) && a->attrib & AT_RW){ if((a = this->attribs[i]) && a->attrib & AT_RW){
uint32 atsz = attribSize(a->attrib); uint32 atsz = attribSize(a->attrib);
*p++ = 0x30000000 | QWC(nverts*atsz); *p++ = DMAref | QWC(nverts*atsz);
*p++ = im.attribPos[i]; *p++ = im.attribPos[i];
*p++ = 0x01000100 | *p++ = VIF_STCYCL | this->inputStride;
this->inputStride; // STCYCL
// Round up nverts so UNPACK will fit exactly into the DMA packet // Round up nverts so UNPACK will fit exactly into the DMA packet
// (can't pad with zeroes in broken out sections). // (can't pad with zeroes in broken out sections).
// TODO: check for clash with vifOffset somewhere // TODO: check for clash with vifOffset somewhere
*p++ = (a->attrib&0xFF004000) *p++ = (a->attrib&0xFF004000)
| 0x8000 | (QWC(nverts*atsz)<<4)/atsz << 16 | i; // UNPACK | 0x8000 | (QWC(nverts*atsz)<<4)/atsz << 16 | i; // UNPACK
*p++ = 0x10000000; *p++ = DMAcnt;
*p++ = 0x0;
*p++ = 0x0;
*p++ = 0x0; *p++ = 0x0;
*p++ = VIF_NOP;
*p++ = VIF_NOP;
im.attribPos[i] += g->meshHeader->flags == 1 ? im.attribPos[i] += g->meshHeader->flags == 1 ?
QWC((im.batchVertCount-2)*atsz) : QWC((im.batchVertCount-2)*atsz) :
QWC(im.batchVertCount*atsz); QWC(im.batchVertCount*atsz);
} }
if(im.numBrokenAttribs){ if(im.numBrokenAttribs){
*p++ = (j < im.numBatches-1 ? 0x10000000 : 0x60000000) | *p++ = (j < im.numBatches-1 ? DMAcnt : DMAret) | bsize;
bsize;
*p++ = 0x0;
*p++ = 0x0;
*p++ = 0x0; *p++ = 0x0;
*p++ = VIF_NOP;
*p++ = VIF_NOP;
} }
for(uint i = 0; i < nelem(this->attribs); i++) for(uint i = 0; i < nelem(this->attribs); i++)
if((a = this->attribs[i]) && (a->attrib & AT_RW) == 0){ if((a = this->attribs[i]) && (a->attrib & AT_RW) == 0){
*p++ = 0x07000000 | markcnt++; // MARK (SA: NOP) if(rw::version >= 0x35000)
*p++ = 0x05000000; // STMOD *p++ = VIF_NOP;
*p++ = 0x01000100 | else
this->inputStride; // STCYCL *p++ = VIF_MARK | markcnt++;
*p++ = VIF_STMOD;
*p++ = VIF_STCYCL | this->inputStride;
*p++ = (a->attrib&0xFF004000) *p++ = (a->attrib&0xFF004000)
| 0x8000 | nverts << 16 | i; // UNPACK | 0x8000 | nverts << 16 | i; // UNPACK
if(a == &attribXYZ) if(a == &attribXYZ)
p = instanceXYZ(p, g, m, idx, nverts); p = instanceXYZ(p, g, m, idx, nverts);
else if(a == &attribXYZW)
p = instanceXYZW(p, g, m, idx, nverts);
else if(a == &attribUV) else if(a == &attribUV)
p = instanceUV(p, g, m, idx, nverts); p = instanceUV(p, g, m, idx, nverts);
else if(a == &attribUV2) else if(a == &attribUV2)
@ -547,14 +622,14 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
idx += g->meshHeader->flags == 1 idx += g->meshHeader->flags == 1
? im.batchVertCount-2 : im.batchVertCount; ? im.batchVertCount-2 : im.batchVertCount;
*p++ = 0x04000000 | nverts; // ITOP *p++ = VIF_ITOP | nverts;
*p++ = j == 0 ? 0x15000000 : 0x17000000; *p++ = j == 0 ? VIF_MSCALF : VIF_MSCNT;
if(j < im.numBatches-1){ if(j < im.numBatches-1){
*p++ = 0x0; *p++ = VIF_NOP;
*p++ = 0x0; *p++ = VIF_NOP;
}else{ }else{
*p++ = 0x11000000; // FLUSH *p++ = VIF_FLUSH;
*p++ = 0x06000000; // MSKPATH3; SA: FLUSH *p++ = msk_flush;
} }
} }
@ -568,7 +643,8 @@ MatPipeline::collectData(Geometry *g, InstanceData *inst, Mesh *m, uint8 *data[]
PipeAttribute *a; PipeAttribute *a;
InstMeshInfo im = getInstMeshInfo(this, g, m); InstMeshInfo im = getInstMeshInfo(this, g, m);
uint8 *raw = im.stride*m->numIndices ? new uint8[im.stride*m->numIndices] : NULL; uint8 *raw = im.vertexSize*m->numIndices ?
new uint8[im.vertexSize*m->numIndices] : NULL;
uint8 *dp = raw; uint8 *dp = raw;
for(uint i = 0; i < nelem(this->attribs); i++) for(uint i = 0; i < nelem(this->attribs); i++)
if(a = this->attribs[i]) if(a = this->attribs[i])
@ -722,12 +798,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
if(m->postUninstCB) m->postUninstCB(m, geo); if(m->postUninstCB) m->postUninstCB(m, geo);
} }
int8 *bits = NULL; int8 *bits = getADCbits(geo);
if(adcOffset){
ADCData *adc = PLUGINOFFSET(ADCData, geo, adcOffset);
if(adc->adcFormatted)
bits = adc->adcBits;
}
geo->generateTriangles(bits); geo->generateTriangles(bits);
delete[] flags; delete[] flags;
destroyNativeData(geo, 0, 0); destroyNativeData(geo, 0, 0);
@ -802,6 +873,18 @@ insertVertex(Geometry *geo, int32 i, uint32 mask, Vertex *v)
memcpy(&geo->texCoords[1][i*2], v->t1, 8); memcpy(&geo->texCoords[1][i*2], v->t1, 8);
} }
void
genericUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
{
//extern PipeAttribute attribXYZ;
//extern PipeAttribute attribXYZW;
//extern PipeAttribute attribUV;
//extern PipeAttribute attribUV2;
//extern PipeAttribute attribRGBA;
//extern PipeAttribute attribNormal;
//extern PipeAttribute attribWeights;
}
void void
defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[]) defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
{ {
@ -872,9 +955,6 @@ makeDefaultPipeline(void)
return defaultObjPipe; return defaultObjPipe;
} }
static void skinInstanceCB(MatPipeline*, Geometry*, Mesh*, uint8**);
static void skinUninstanceCB(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**);
ObjPipeline* ObjPipeline*
makeSkinPipeline(void) makeSkinPipeline(void)
{ {
@ -1026,7 +1106,7 @@ instanceSkinData(Geometry*, Mesh *m, Skin *skin, uint32 *data)
} }
} }
static void void
skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data) skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data)
{ {
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset); Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
@ -1095,7 +1175,7 @@ insertVertexSkin(Geometry *geo, int32 i, uint32 mask, SkinVertex *v)
} }
} }
static void void
skinUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[]) skinUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
{ {
float32 *verts = (float32*)data[AT_XYZ]; float32 *verts = (float32*)data[AT_XYZ];
@ -1171,6 +1251,30 @@ skinPostCB(MatPipeline*, Geometry *geo)
int32 adcOffset; int32 adcOffset;
int8*
getADCbits(Geometry *geo)
{
int8 *bits = NULL;
if(adcOffset){
ADCData *adc = PLUGINOFFSET(ADCData, geo, adcOffset);
if(adc->adcFormatted)
bits = adc->adcBits;
}
return bits;
}
int8*
getADCbitsForMesh(Geometry *geo, Mesh *mesh)
{
int8 *bits = getADCbits(geo);
if(bits == NULL)
return NULL;
int32 n = mesh - geo->meshHeader->mesh;
for(int32 i = 0; i < n; i++)
bits += geo->meshHeader->mesh[i].numIndices;
return bits;
}
// TODO // TODO
void void
convertADC(Geometry*) convertADC(Geometry*)
@ -1324,130 +1428,6 @@ registerADCPlugin(void)
getSizeADC); getSizeADC);
} }
// 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
atomicPDSRights(void *object, int32, int32, uint32 data)
{
Atomic *a = (Atomic*)object;
//printf("atm pds: %x\n", data);
a->pipeline = (ObjPipeline*)getPDSPipe(data);
}
static void
materialPDSRights(void *object, int32, int32, uint32 data)
{
Material *m = (Material*)object;
//printf("mat pds: %x\n", data);
m->pipeline = (ObjPipeline*)getPDSPipe(data);
}
void
registerPDSPlugin(int32 n)
{
pdsGlobals.maxPipes = n;
pdsGlobals.numPipes = 0;
pdsGlobals.pipes = new Pipeline*[n];
Atomic::registerPlugin(0, ID_PDS, NULL, NULL, NULL);
Atomic::setStreamRightsCallback(ID_PDS, atomicPDSRights);
Material::registerPlugin(0, ID_PDS, NULL, NULL, NULL);
Material::setStreamRightsCallback(ID_PDS, materialPDSRights);
}
void
registerPluginPDSPipes(void)
{
// Skin
MatPipeline *pipe = new MatPipeline(PLATFORM_PS2);
pipe->pluginID = ID_PDS;
pipe->pluginData = 0x11001; // rwPDS_G3_Generic_GrpMatPipeID
pipe->attribs[AT_XYZ] = &attribXYZ;
pipe->attribs[AT_UV] = &attribUV;
pipe->attribs[AT_RGBA] = &attribRGBA;
pipe->attribs[AT_NORMAL] = &attribNormal;
pipe->attribs[AT_NORMAL+1] = &attribWeights;
uint32 vertCount = MatPipeline::getVertCount(VU_Lights-0x100, 5, 3, 2);
pipe->setTriBufferSizes(5, vertCount);
pipe->vifOffset = pipe->inputStride*vertCount;
pipe->instanceCB = skinInstanceCB;
pipe->uninstanceCB = skinUninstanceCB;
pipe->preUninstCB = skinPreCB;
pipe->postUninstCB = skinPostCB;
registerPDSPipe(pipe);
ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
opipe->pluginID = ID_PDS;
opipe->pluginData = 0x11002; // rwPDS_G3_Skin_GrpAtmPipeID
opipe->groupPipeline = pipe;
registerPDSPipe(opipe);
// MatFX UV1
pipe = new MatPipeline(PLATFORM_PS2);
pipe->pluginID = ID_PDS;
pipe->pluginData = 0x1100b; // rwPDS_G3_MatfxUV1_GrpMatPipeID
pipe->attribs[AT_XYZ] = &attribXYZ;
pipe->attribs[AT_UV] = &attribUV;
pipe->attribs[AT_RGBA] = &attribRGBA;
pipe->attribs[AT_NORMAL] = &attribNormal;
vertCount = MatPipeline::getVertCount(0x3C5, 4, 3, 3);
pipe->setTriBufferSizes(4, vertCount);
pipe->vifOffset = pipe->inputStride*vertCount;
pipe->uninstanceCB = defaultUninstanceCB;
registerPDSPipe(pipe);
opipe = new ObjPipeline(PLATFORM_PS2);
opipe->pluginID = ID_PDS;
opipe->pluginData = 0x1100d; // rwPDS_G3_MatfxUV1_GrpAtmPipeID
opipe->groupPipeline = pipe;
registerPDSPipe(opipe);
// MatFX UV2
pipe = new MatPipeline(PLATFORM_PS2);
pipe->pluginID = ID_PDS;
pipe->pluginData = 0x1100c; // rwPDS_G3_MatfxUV2_GrpMatPipeID
pipe->attribs[AT_XYZ] = &attribXYZ;
pipe->attribs[AT_UV] = &attribUV2;
pipe->attribs[AT_RGBA] = &attribRGBA;
pipe->attribs[AT_NORMAL] = &attribNormal;
vertCount = MatPipeline::getVertCount(0x3C5, 4, 3, 3);
pipe->setTriBufferSizes(4, vertCount);
pipe->vifOffset = pipe->inputStride*vertCount;
pipe->uninstanceCB = defaultUninstanceCB;
registerPDSPipe(pipe);
opipe = new ObjPipeline(PLATFORM_PS2);
opipe->pluginID = ID_PDS;
opipe->pluginData = 0x1100e; // rwPDS_G3_MatfxUV2_GrpAtmPipeID
opipe->groupPipeline = pipe;
registerPDSPipe(opipe);
}
// misc stuff // misc stuff
void void
@ -1456,20 +1436,17 @@ printDMA(InstanceData *inst)
uint32 *tag = (uint32*)inst->data; uint32 *tag = (uint32*)inst->data;
for(;;){ for(;;){
switch(tag[0]&0x70000000){ switch(tag[0]&0x70000000){
// DMAcnt case DMAcnt:
case 0x10000000:
printf("%08x %08x\n", tag[0], tag[1]); printf("%08x %08x\n", tag[0], tag[1]);
tag += (1+(tag[0]&0xFFFF))*4; tag += (1+(tag[0]&0xFFFF))*4;
break; break;
// DMAref case DMAref:
case 0x30000000:
printf("%08x %08x\n", tag[0], tag[1]); printf("%08x %08x\n", tag[0], tag[1]);
tag += 4; tag += 4;
break; break;
// DMAret case DMAret:
case 0x60000000:
printf("%08x %08x\n", tag[0], tag[1]); printf("%08x %08x\n", tag[0], tag[1]);
return; return;
} }
@ -1486,19 +1463,16 @@ sizedebug(InstanceData *inst)
uint32 *last = NULL; uint32 *last = NULL;
for(;;){ for(;;){
switch(tag[0]&0x70000000){ switch(tag[0]&0x70000000){
// DMAcnt case DMAcnt:
case 0x10000000:
tag += (1+(tag[0]&0xFFFF))*4; tag += (1+(tag[0]&0xFFFF))*4;
break; break;
// DMAref case DMAref:
case 0x30000000:
last = base + tag[1]*4 + (tag[0]&0xFFFF)*4; last = base + tag[1]*4 + (tag[0]&0xFFFF)*4;
tag += 4; tag += 4;
break; break;
// DMAret case DMAret:
case 0x60000000:
tag += (1+(tag[0]&0xFFFF))*4; tag += (1+(tag[0]&0xFFFF))*4;
uint32 diff; uint32 diff;
if(!last) if(!last)

View File

@ -218,6 +218,7 @@ struct Image
void free(void); void free(void);
void setPixels(uint8 *pixels); void setPixels(uint8 *pixels);
void setPalette(uint8 *palette); void setPalette(uint8 *palette);
bool32 hasAlpha(void);
static void setSearchPath(const char*); static void setSearchPath(const char*);
static void printSearchPath(void); static void printSearchPath(void);
@ -507,6 +508,7 @@ struct Geometry : PluginBase<Geometry>
void allocateData(void); void allocateData(void);
void generateTriangles(int8 *adc = NULL); void generateTriangles(int8 *adc = NULL);
void buildMeshes(void); void buildMeshes(void);
void removeUnusedMaterials(void);
enum Flags enum Flags
{ {

View File

@ -38,6 +38,7 @@ enum PS2Attribs {
AT_RW = 0x6 AT_RW = 0x6
}; };
// Not really types as in RW but offsets
enum PS2AttibTypes { enum PS2AttibTypes {
AT_XYZ = 0, AT_XYZ = 0,
AT_UV = 1, AT_UV = 1,
@ -65,6 +66,14 @@ struct PipeAttribute
uint32 attrib; uint32 attrib;
}; };
extern PipeAttribute attribXYZ;
extern PipeAttribute attribXYZW;
extern PipeAttribute attribUV;
extern PipeAttribute attribUV2;
extern PipeAttribute attribRGBA;
extern PipeAttribute attribNormal;
extern PipeAttribute attribWeights;
class MatPipeline : public rw::Pipeline class MatPipeline : public rw::Pipeline
{ {
public: public:
@ -122,6 +131,10 @@ void insertVertex(Geometry *geo, int32 i, uint32 mask, Vertex *v);
extern ObjPipeline *defaultObjPipe; extern ObjPipeline *defaultObjPipe;
extern MatPipeline *defaultMatPipe; extern MatPipeline *defaultMatPipe;
void defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[]);
void skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data);
void skinUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[]);
ObjPipeline *makeDefaultPipeline(void); ObjPipeline *makeDefaultPipeline(void);
ObjPipeline *makeSkinPipeline(void); ObjPipeline *makeSkinPipeline(void);
ObjPipeline *makeMatFXPipeline(void); ObjPipeline *makeMatFXPipeline(void);
@ -164,6 +177,8 @@ struct ADCData
extern int32 adcOffset; extern int32 adcOffset;
void registerADCPlugin(void); void registerADCPlugin(void);
int8 *getADCbits(Geometry *geo);
int8 *getADCbitsForMesh(Geometry *geo, Mesh *mesh);
void convertADC(Geometry *g); void convertADC(Geometry *g);
void unconvertADC(Geometry *geo); void unconvertADC(Geometry *geo);
void allocateADC(Geometry *geo); void allocateADC(Geometry *geo);