mirror of https://github.com/aap/librw.git
some work on ps2 pipelines, d3d rasters
This commit is contained in:
parent
91291709d8
commit
a6a7b0e89c
|
@ -198,6 +198,7 @@
|
|||
<ClCompile Include="src\geometry.cpp" />
|
||||
<ClCompile Include="src\image.cpp" />
|
||||
<ClCompile Include="src\ogl.cpp" />
|
||||
<ClCompile Include="src\pds.cpp" />
|
||||
<ClCompile Include="src\pipeline.cpp" />
|
||||
<ClCompile Include="src\plugins.cpp" />
|
||||
<ClCompile Include="src\ps2.cpp" />
|
||||
|
|
27
src/d3d.cpp
27
src/d3d.cpp
|
@ -420,18 +420,25 @@ void
|
|||
D3dRaster::fromImage(Raster *raster, Image *image)
|
||||
{
|
||||
int32 format;
|
||||
if(image->depth == 32)
|
||||
format = Raster::C8888;
|
||||
else if(image->depth == 24)
|
||||
switch(image->depth){
|
||||
case 32:
|
||||
format = image->hasAlpha() ? Raster::C8888 : Raster::C888;
|
||||
break;
|
||||
case 24:
|
||||
format = Raster::C888;
|
||||
else if(image->depth == 16)
|
||||
break;
|
||||
case 16:
|
||||
format = Raster::C1555;
|
||||
else if(image->depth == 8)
|
||||
break;
|
||||
case 8:
|
||||
format = Raster::PAL8 | Raster::C8888;
|
||||
else if(image->depth == 4)
|
||||
break;
|
||||
case 4:
|
||||
format = Raster::PAL4 | Raster::C8888;
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
format |= 4;
|
||||
|
||||
raster->type = format & 0x7;
|
||||
|
@ -458,11 +465,13 @@ D3dRaster::fromImage(Raster *raster, Image *image)
|
|||
}
|
||||
}
|
||||
|
||||
int32 inc = image->depth/8;
|
||||
in = image->pixels;
|
||||
out = raster->lock(0);
|
||||
if(pallength)
|
||||
memcpy(out, in, raster->width*raster->height);
|
||||
else
|
||||
// TODO: stride
|
||||
for(int32 y = 0; y < image->height; y++)
|
||||
for(int32 x = 0; x < image->width; x++)
|
||||
switch(raster->format & 0xF00){
|
||||
|
@ -471,7 +480,7 @@ D3dRaster::fromImage(Raster *raster, Image *image)
|
|||
out[1] = in[1];
|
||||
out[2] = in[0];
|
||||
out[3] = in[3];
|
||||
in += 4;
|
||||
in += inc;
|
||||
out += 4;
|
||||
break;
|
||||
case Raster::C888:
|
||||
|
@ -479,7 +488,7 @@ D3dRaster::fromImage(Raster *raster, Image *image)
|
|||
out[1] = in[1];
|
||||
out[2] = in[0];
|
||||
out[3] = 0xFF;
|
||||
in += 3;
|
||||
in += inc;
|
||||
out += 4;
|
||||
break;
|
||||
case Raster::C1555:
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -379,6 +379,27 @@ Image::setPalette(uint8 *palette)
|
|||
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;
|
||||
int numSearchPaths = 0;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
330
src/ps2.cpp
330
src/ps2.cpp
|
@ -191,6 +191,11 @@ PipeAttribute attribXYZ = {
|
|||
AT_V3_32
|
||||
};
|
||||
|
||||
PipeAttribute attribXYZW = {
|
||||
"XYZW",
|
||||
AT_V4_32
|
||||
};
|
||||
|
||||
PipeAttribute attribUV = {
|
||||
"UV",
|
||||
AT_V2_32
|
||||
|
@ -256,6 +261,23 @@ instanceXYZ(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
|
|||
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*
|
||||
instanceUV(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
|
||||
{
|
||||
|
@ -393,7 +415,55 @@ brokenout:
|
|||
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
|
||||
{
|
||||
|
@ -401,7 +471,9 @@ struct InstMeshInfo
|
|||
uint32 batchVertCount, lastBatchVertCount;
|
||||
uint32 numBatches;
|
||||
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];
|
||||
};
|
||||
|
||||
|
@ -412,16 +484,15 @@ getInstMeshInfo(MatPipeline *pipe, Geometry *g, Mesh *m)
|
|||
InstMeshInfo im;
|
||||
im.numAttribs = 0;
|
||||
im.numBrokenAttribs = 0;
|
||||
im.stride = 0;
|
||||
im.vertexSize = 0;
|
||||
for(uint i = 0; i < nelem(pipe->attribs); i++)
|
||||
if(a = pipe->attribs[i])
|
||||
if(a->attrib & AT_RW)
|
||||
im.numBrokenAttribs++;
|
||||
else{
|
||||
im.stride += attribSize(a->attrib);
|
||||
im.vertexSize += attribSize(a->attrib);
|
||||
im.numAttribs++;
|
||||
}
|
||||
uint32 totalVerts = 0;
|
||||
if(g->meshHeader->flags == MeshHeader::TRISTRIP){
|
||||
im.numBatches = (m->numIndices-2) / (pipe->triStripCount-2);
|
||||
im.batchVertCount = pipe->triStripCount;
|
||||
|
@ -430,7 +501,7 @@ getInstMeshInfo(MatPipeline *pipe, Geometry *g, Mesh *m)
|
|||
im.numBatches++;
|
||||
im.lastBatchVertCount += 2;
|
||||
}
|
||||
}else{
|
||||
}else{ // TRILIST; nothing else supported yet
|
||||
im.numBatches = (m->numIndices+pipe->triListCount-1) /
|
||||
pipe->triListCount;
|
||||
im.batchVertCount = pipe->triListCount;
|
||||
|
@ -441,7 +512,6 @@ getInstMeshInfo(MatPipeline *pipe, Geometry *g, Mesh *m)
|
|||
|
||||
im.batchSize = getBatchSize(pipe, im.batchVertCount);
|
||||
im.lastBatchSize = getBatchSize(pipe, im.lastBatchVertCount);
|
||||
im.size = 0;
|
||||
if(im.numBrokenAttribs == 0)
|
||||
im.size = 1 + im.batchSize*(im.numBatches-1) + im.lastBatchSize;
|
||||
else
|
||||
|
@ -477,13 +547,16 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
|
|||
if((a = this->attribs[i]) && a->attrib & AT_RW)
|
||||
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 *p = (uint32*)inst->data;
|
||||
if(im.numBrokenAttribs == 0){
|
||||
*p++ = 0x60000000 | im.size-1;
|
||||
*p++ = DMAret | im.size-1;
|
||||
*p++ = 0;
|
||||
*p++ = 0x11000000; // FLUSH
|
||||
*p++ = 0x06000000; // MSKPATH3; SA: FLUSH
|
||||
*p++ = VIF_FLUSH;
|
||||
*p++ = msk_flush;
|
||||
}
|
||||
for(uint32 j = 0; j < im.numBatches; j++){
|
||||
uint32 nverts, bsize;
|
||||
|
@ -497,44 +570,46 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
|
|||
for(uint i = 0; i < nelem(this->attribs); i++)
|
||||
if((a = this->attribs[i]) && a->attrib & AT_RW){
|
||||
uint32 atsz = attribSize(a->attrib);
|
||||
*p++ = 0x30000000 | QWC(nverts*atsz);
|
||||
*p++ = DMAref | QWC(nverts*atsz);
|
||||
*p++ = im.attribPos[i];
|
||||
*p++ = 0x01000100 |
|
||||
this->inputStride; // STCYCL
|
||||
*p++ = VIF_STCYCL | this->inputStride;
|
||||
// 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)
|
||||
| 0x8000 | (QWC(nverts*atsz)<<4)/atsz << 16 | i; // UNPACK
|
||||
|
||||
*p++ = 0x10000000;
|
||||
*p++ = 0x0;
|
||||
*p++ = 0x0;
|
||||
*p++ = DMAcnt;
|
||||
*p++ = 0x0;
|
||||
*p++ = VIF_NOP;
|
||||
*p++ = VIF_NOP;
|
||||
|
||||
im.attribPos[i] += g->meshHeader->flags == 1 ?
|
||||
QWC((im.batchVertCount-2)*atsz) :
|
||||
QWC(im.batchVertCount*atsz);
|
||||
}
|
||||
if(im.numBrokenAttribs){
|
||||
*p++ = (j < im.numBatches-1 ? 0x10000000 : 0x60000000) |
|
||||
bsize;
|
||||
*p++ = 0x0;
|
||||
*p++ = 0x0;
|
||||
*p++ = (j < im.numBatches-1 ? DMAcnt : DMAret) | bsize;
|
||||
*p++ = 0x0;
|
||||
*p++ = VIF_NOP;
|
||||
*p++ = VIF_NOP;
|
||||
}
|
||||
|
||||
for(uint i = 0; i < nelem(this->attribs); i++)
|
||||
if((a = this->attribs[i]) && (a->attrib & AT_RW) == 0){
|
||||
*p++ = 0x07000000 | markcnt++; // MARK (SA: NOP)
|
||||
*p++ = 0x05000000; // STMOD
|
||||
*p++ = 0x01000100 |
|
||||
this->inputStride; // STCYCL
|
||||
if(rw::version >= 0x35000)
|
||||
*p++ = VIF_NOP;
|
||||
else
|
||||
*p++ = VIF_MARK | markcnt++;
|
||||
*p++ = VIF_STMOD;
|
||||
*p++ = VIF_STCYCL | this->inputStride;
|
||||
*p++ = (a->attrib&0xFF004000)
|
||||
| 0x8000 | nverts << 16 | i; // UNPACK
|
||||
|
||||
if(a == &attribXYZ)
|
||||
p = instanceXYZ(p, g, m, idx, nverts);
|
||||
else if(a == &attribXYZW)
|
||||
p = instanceXYZW(p, g, m, idx, nverts);
|
||||
else if(a == &attribUV)
|
||||
p = instanceUV(p, g, m, idx, nverts);
|
||||
else if(a == &attribUV2)
|
||||
|
@ -547,14 +622,14 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
|
|||
idx += g->meshHeader->flags == 1
|
||||
? im.batchVertCount-2 : im.batchVertCount;
|
||||
|
||||
*p++ = 0x04000000 | nverts; // ITOP
|
||||
*p++ = j == 0 ? 0x15000000 : 0x17000000;
|
||||
*p++ = VIF_ITOP | nverts;
|
||||
*p++ = j == 0 ? VIF_MSCALF : VIF_MSCNT;
|
||||
if(j < im.numBatches-1){
|
||||
*p++ = 0x0;
|
||||
*p++ = 0x0;
|
||||
*p++ = VIF_NOP;
|
||||
*p++ = VIF_NOP;
|
||||
}else{
|
||||
*p++ = 0x11000000; // FLUSH
|
||||
*p++ = 0x06000000; // MSKPATH3; SA: FLUSH
|
||||
*p++ = VIF_FLUSH;
|
||||
*p++ = msk_flush;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -568,7 +643,8 @@ MatPipeline::collectData(Geometry *g, InstanceData *inst, Mesh *m, uint8 *data[]
|
|||
PipeAttribute *a;
|
||||
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;
|
||||
for(uint i = 0; i < nelem(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);
|
||||
}
|
||||
|
||||
int8 *bits = NULL;
|
||||
if(adcOffset){
|
||||
ADCData *adc = PLUGINOFFSET(ADCData, geo, adcOffset);
|
||||
if(adc->adcFormatted)
|
||||
bits = adc->adcBits;
|
||||
}
|
||||
int8 *bits = getADCbits(geo);
|
||||
geo->generateTriangles(bits);
|
||||
delete[] flags;
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
|
||||
{
|
||||
|
@ -872,9 +955,6 @@ makeDefaultPipeline(void)
|
|||
return defaultObjPipe;
|
||||
}
|
||||
|
||||
static void skinInstanceCB(MatPipeline*, Geometry*, Mesh*, uint8**);
|
||||
static void skinUninstanceCB(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**);
|
||||
|
||||
ObjPipeline*
|
||||
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)
|
||||
{
|
||||
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[])
|
||||
{
|
||||
float32 *verts = (float32*)data[AT_XYZ];
|
||||
|
@ -1171,6 +1251,30 @@ skinPostCB(MatPipeline*, Geometry *geo)
|
|||
|
||||
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
|
||||
void
|
||||
convertADC(Geometry*)
|
||||
|
@ -1324,130 +1428,6 @@ registerADCPlugin(void)
|
|||
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
|
||||
|
||||
void
|
||||
|
@ -1456,20 +1436,17 @@ printDMA(InstanceData *inst)
|
|||
uint32 *tag = (uint32*)inst->data;
|
||||
for(;;){
|
||||
switch(tag[0]&0x70000000){
|
||||
// DMAcnt
|
||||
case 0x10000000:
|
||||
case DMAcnt:
|
||||
printf("%08x %08x\n", tag[0], tag[1]);
|
||||
tag += (1+(tag[0]&0xFFFF))*4;
|
||||
break;
|
||||
|
||||
// DMAref
|
||||
case 0x30000000:
|
||||
case DMAref:
|
||||
printf("%08x %08x\n", tag[0], tag[1]);
|
||||
tag += 4;
|
||||
break;
|
||||
|
||||
// DMAret
|
||||
case 0x60000000:
|
||||
case DMAret:
|
||||
printf("%08x %08x\n", tag[0], tag[1]);
|
||||
return;
|
||||
}
|
||||
|
@ -1486,19 +1463,16 @@ sizedebug(InstanceData *inst)
|
|||
uint32 *last = NULL;
|
||||
for(;;){
|
||||
switch(tag[0]&0x70000000){
|
||||
// DMAcnt
|
||||
case 0x10000000:
|
||||
case DMAcnt:
|
||||
tag += (1+(tag[0]&0xFFFF))*4;
|
||||
break;
|
||||
|
||||
// DMAref
|
||||
case 0x30000000:
|
||||
case DMAref:
|
||||
last = base + tag[1]*4 + (tag[0]&0xFFFF)*4;
|
||||
tag += 4;
|
||||
break;
|
||||
|
||||
// DMAret
|
||||
case 0x60000000:
|
||||
case DMAret:
|
||||
tag += (1+(tag[0]&0xFFFF))*4;
|
||||
uint32 diff;
|
||||
if(!last)
|
||||
|
|
|
@ -168,7 +168,7 @@ Matrix3::makeRotation(const Quat &q)
|
|||
res.at.z = q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Matrix3::setIdentity(void)
|
||||
{
|
||||
|
|
|
@ -218,6 +218,7 @@ struct Image
|
|||
void free(void);
|
||||
void setPixels(uint8 *pixels);
|
||||
void setPalette(uint8 *palette);
|
||||
bool32 hasAlpha(void);
|
||||
|
||||
static void setSearchPath(const char*);
|
||||
static void printSearchPath(void);
|
||||
|
@ -507,6 +508,7 @@ struct Geometry : PluginBase<Geometry>
|
|||
void allocateData(void);
|
||||
void generateTriangles(int8 *adc = NULL);
|
||||
void buildMeshes(void);
|
||||
void removeUnusedMaterials(void);
|
||||
|
||||
enum Flags
|
||||
{
|
||||
|
|
15
src/rwps2.h
15
src/rwps2.h
|
@ -38,6 +38,7 @@ enum PS2Attribs {
|
|||
AT_RW = 0x6
|
||||
};
|
||||
|
||||
// Not really types as in RW but offsets
|
||||
enum PS2AttibTypes {
|
||||
AT_XYZ = 0,
|
||||
AT_UV = 1,
|
||||
|
@ -65,6 +66,14 @@ struct PipeAttribute
|
|||
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
|
||||
{
|
||||
public:
|
||||
|
@ -122,6 +131,10 @@ void insertVertex(Geometry *geo, int32 i, uint32 mask, Vertex *v);
|
|||
extern ObjPipeline *defaultObjPipe;
|
||||
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 *makeSkinPipeline(void);
|
||||
ObjPipeline *makeMatFXPipeline(void);
|
||||
|
@ -164,6 +177,8 @@ struct ADCData
|
|||
extern int32 adcOffset;
|
||||
void registerADCPlugin(void);
|
||||
|
||||
int8 *getADCbits(Geometry *geo);
|
||||
int8 *getADCbitsForMesh(Geometry *geo, Mesh *mesh);
|
||||
void convertADC(Geometry *g);
|
||||
void unconvertADC(Geometry *geo);
|
||||
void allocateADC(Geometry *geo);
|
||||
|
|
Loading…
Reference in New Issue