basic PS2 instancing

This commit is contained in:
aap 2015-07-12 22:57:05 +02:00
parent e9f638db05
commit d832570142
10 changed files with 1186 additions and 504 deletions

139
dumprwtree.cpp Normal file
View File

@ -0,0 +1,139 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <new>
#include "rw.h"
using namespace std;
using namespace rw;
const char *chunks[] = { "None", "Struct", "String", "Extension", "Unknown",
"Camera", "Texture", "Material", "Material List", "Atomic Section",
"Plane Section", "World", "Spline", "Matrix", "Frame List",
"Geometry", "Clump", "Unknown", "Light", "Unicode String", "Atomic",
"Texture Native", "Texture Dictionary", "Animation Database",
"Image", "Skin Animation", "Geometry List", "Anim Animation",
"Team", "Crowd", "Delta Morph Animation", "Right To Render",
"MultiTexture Effect Native", "MultiTexture Effect Dictionary",
"Team Dictionary", "Platform Independet Texture Dictionary",
"Table of Contents", "Particle Standard Global Data", "AltPipe",
"Platform Independet Peds", "Patch Mesh", "Chunk Group Start",
"Chunk Group End", "UV Animation Dictionary", "Coll Tree"
};
/* From 0x0101 through 0x0135 */
const char *toolkitchunks0[] = { "Metrics PLG", "Spline PLG", "Stereo PLG",
"VRML PLG", "Morph PLG", "PVS PLG", "Memory Leak PLG", "Animation PLG",
"Gloss PLG", "Logo PLG", "Memory Info PLG", "Random PLG",
"PNG Image PLG", "Bone PLG", "VRML Anim PLG", "Sky Mipmap Val",
"MRM PLG", "LOD Atomic PLG", "ME PLG", "Lightmap PLG",
"Refine PLG", "Skin PLG", "Label PLG", "Particles PLG", "GeomTX PLG",
"Synth Core PLG", "STQPP PLG",
"Part PP PLG", "Collision PLG", "HAnim PLG", "User Data PLG",
"Material Effects PLG", "Particle System PLG", "Delta Morph PLG",
"Patch PLG", "Team PLG", "Crowd PP PLG", "Mip Split PLG",
"Anisotrophy PLG", "Not used", "GCN Material PLG", "Geometric PVS PLG",
"XBOX Material PLG", "Multi Texture PLG", "Chain PLG", "Toon PLG",
"PTank PLG", "Particle Standard PLG", "PDS PLG", "PrtAdv PLG",
"Normal Map PLG", "ADC PLG", "UV Animation PLG"
};
/* From 0x0180 through 0x01c1 */
const char *toolkitchunks1[] = {
"Character Set PLG", "NOHS World PLG", "Import Util PLG",
"Slerp PLG", "Optim PLG", "TL World PLG", "Database PLG",
"Raytrace PLG", "Ray PLG", "Library PLG",
"Not used", "Not used", "Not used", "Not used", "Not used", "Not used",
"2D PLG", "Tile Render PLG", "JPEG Image PLG", "TGA Image PLG",
"GIF Image PLG", "Quat PLG", "Spline PVS PLG", "Mipmap PLG",
"MipmapK PLG", "2D Font", "Intersection PLG", "TIFF Image PLG",
"Pick PLG", "BMP Image PLG", "RAS Image PLG", "Skin FX PLG",
"VCAT PLG", "2D Path", "2D Brush", "2D Object", "2D Shape", "2D Scene",
"2D Pick Region", "2D Object String", "2D Animation PLG",
"2D Animation",
"Not used", "Not used", "Not used", "Not used", "Not used", "Not used",
"2D Keyframe", "2D Maestro", "Barycentric",
"Platform Independent Texture Dictionary TK", "TOC TK", "TPL TK",
"AltPipe TK", "Animation TK", "Skin Split Tookit", "Compressed Key TK",
"Geometry Conditioning PLG", "Wing PLG", "Generic Pipeline TK",
"Lightmap Conversion TK", "Filesystem PLG", "Dictionary TK",
"UV Animation Linear", "UV Animation Parameter"
};
const char *RSchunks[] = { "Unused 1", "Unused 2", "Unused 3",
"Pipeline Set", "Unused 5", "Unused 6", "Specular Material",
"Unused 8", "2dfx", "Night Vertex Colors", "Collision Model",
"Unused 12", "Reflection Material", "Mesh Extension", "Frame",
"Unused 16"
};
const char*
getChunkName(uint32 id)
{
switch(id){
case 0x50E:
return "Bin Mesh PLG";
case 0x510:
return "Native Data PLG";
case 0xF21E:
return "ZModeler Lock";
}
if(id <= 45)
return chunks[id];
else if(id <= 0x0253F2FF && id >= 0x0253F2F0)
return RSchunks[id-0x0253F2F0];
else if(id <= 0x0135 && id >= 0x0101)
return toolkitchunks0[id-0x0101];
else if(id <= 0x01C0 && id >= 0x0181)
return toolkitchunks1[id-0x0181];
else
return "Unknown";
}
void
readchunk(StreamFile *s, ChunkHeaderInfo *h, int level)
{
for(int i = 0; i < level; i++)
printf(" ");
const char *name = getChunkName(h->type);
printf("%s (%x bytes @ 0x%x/0x%x) - [0x%x]\n",
name, h->length, s->tell()-12, s->tell(), h->type);
uint32 end = s->tell() + h->length;
while(s->tell() < end){
ChunkHeaderInfo nh;
readChunkHeaderInfo(s, &nh);
if(nh.version == h->version && nh.build == h->build){
readchunk(s, &nh, level+1);
if(h->type == 0x510)
s->seek(end, 0);
}else{
s->seek(h->length-12);
break;
}
}
}
int
main(int argc, char *argv[])
{
if(argc < 2){
fprintf(stderr, "usage: %s rwStreamFile\n", argv[0]);
return 0;
}
StreamFile s;
s.open(argv[1], "rb");
ChunkHeaderInfo header;
readChunkHeaderInfo(&s, &header);
readchunk(&s, &header, 0);
printf("%x %x %x\n", header.version, header.build,
libraryIDPack(header.version, header.build));
s.close();
return 0;
}

100
insttest.cpp Normal file
View File

@ -0,0 +1,100 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <new>
#include "rw.h"
#include "src/gtaplg.h"
using namespace std;
using namespace rw;
int
main(int argc, char *argv[])
{
rw::version = 0x33002;
gta::registerEnvSpecPlugin();
rw::registerMatFXPlugin();
rw::registerMaterialRightsPlugin();
rw::registerAtomicRightsPlugin();
rw::registerHAnimPlugin();
gta::registerNodeNamePlugin();
gta::registerBreakableModelPlugin();
gta::registerExtraVertColorPlugin();
rw::ps2::registerADCPlugin();
rw::registerSkinPlugin();
rw::registerNativeDataPlugin();
rw::registerMeshPlugin();
rw::platform = rw::PLATFORM_PS2;
rw::Pipeline *defpipe = rw::ps2::makeDefaultPipeline();
rw::Pipeline *skinpipe = rw::ps2::makeSkinPipeline();
// rw::ps2::dumpPipeline(defpipe);
// rw::ps2::dumpPipeline(skinpipe);
int uninstance = 0;
int arg = 1;
if(argc < 2){
printf("usage: %s [-u] ps2.dff\n", argv[0]);
return 0;
}
if(strcmp(argv[arg], "-u") == 0){
uninstance++;
arg++;
if(argc < 3){
printf("usage: %s [-u] ps2.dff\n", argv[0]);
return 0;
}
}
Clump *c;
uint32 len;
uint8 *data = getFileContents(argv[arg], &len);
assert(data != NULL);
StreamMemory in;
in.open(data, len);
findChunk(&in, ID_CLUMP, NULL, NULL);
debugFile = argv[arg];
c = Clump::streamRead(&in);
assert(c != NULL);
for(int32 i = 0; i < c->numAtomics; i++){
Atomic *a = c->atomicList[i];
if(a->pipeline){
printf("has pipeline %x %x %x\n",
a->pipeline->pluginID,
a->pipeline->pluginData,
a->pipeline->platform);
if(uninstance)
a->pipeline->uninstance(a);
else
a->pipeline->instance(a);
}else{
printf("default pipeline\n");
if(uninstance)
defpipe->uninstance(a);
else
defpipe->instance(a);
}
}
data = new rw::uint8[256*1024];
rw::StreamMemory out;
out.open(data, 0, 256*1024);
c->streamWrite(&out);
FILE *cf = fopen("out.dff", "wb");
assert(cf != NULL);
fwrite(data, out.getLength(), 1, cf);
fclose(cf);
out.close();
delete[] data;
delete c;
return 0;
}

View File

@ -282,6 +282,7 @@ Image::getFilename(const char *name)
// TGA I/O // TGA I/O
// //
// TODO: fuck pakced structs
#ifndef RW_PS2 #ifndef RW_PS2
#pragma pack(push) #pragma pack(push)
#pragma pack(1) #pragma pack(1)

54
src/pipeline.cpp Normal file
View File

@ -0,0 +1,54 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <new>
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwps2.h"
using namespace std;
namespace rw {
Pipeline::Pipeline(uint32 platform)
{
this->pluginID = 0;
this->pluginData = 0;
this->platform = platform;
for(int i = 0; i < 10; i++)
this->attribs[i] = NULL;
}
Pipeline::Pipeline(Pipeline *)
{
assert(0 && "Can't copy pipeline");
}
Pipeline::~Pipeline(void)
{
}
void
Pipeline::instance(Atomic *atomic)
{
fprintf(stderr, "This pipeline can't instance\n");
}
void
Pipeline::uninstance(Atomic *atomic)
{
fprintf(stderr, "This pipeline can't uninstance\n");
}
void
Pipeline::render(Atomic *atomic)
{
fprintf(stderr, "This pipeline can't render\n");
}
}

View File

@ -554,7 +554,8 @@ registerSkinPlugin(void)
defpipe->pluginData = 1; defpipe->pluginData = 1;
for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++) for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++)
skinGlobals.pipelines[i] = defpipe; skinGlobals.pipelines[i] = defpipe;
skinGlobals.pipelines[platformIdx[PLATFORM_PS2]] =
ps2::makeSkinPipeline();
skinGlobals.offset = Geometry::registerPlugin(sizeof(Skin*), ID_SKIN, skinGlobals.offset = Geometry::registerPlugin(sizeof(Skin*), ID_SKIN,
createSkin, createSkin,
@ -883,6 +884,8 @@ registerMatFXPlugin(void)
defpipe->pluginData = 0; defpipe->pluginData = 0;
for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++) for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++)
matFXGlobals.pipelines[i] = defpipe; matFXGlobals.pipelines[i] = defpipe;
matFXGlobals.pipelines[platformIdx[PLATFORM_PS2]] =
ps2::makeMatFXPipeline();
matFXGlobals.atomicOffset = matFXGlobals.atomicOffset =
Atomic::registerPlugin(sizeof(int32), ID_MATFX, Atomic::registerPlugin(sizeof(int32), ID_MATFX,

View File

@ -126,7 +126,7 @@ fixDmaOffsets(InstanceData *inst)
// DMAref // DMAref
case 0x30000000: case 0x30000000:
// fix address and jump to next // fix address and jump to next
tag[1] = base + tag[1]*0x10; tag[1] = base + tag[1]<<4;
tag += 4; tag += 4;
break; break;
@ -165,7 +165,7 @@ unfixDmaOffsets(InstanceData *inst)
// DMAref // DMAref
case 0x30000000: case 0x30000000:
// unfix address and jump to next // unfix address and jump to next
tag[1] = (tag[1] - base)/0x10; tag[1] = (tag[1] - base)>>4;
tag += 4; tag += 4;
break; break;
@ -203,9 +203,8 @@ enum PS2Attribs {
enum PS2AttibTypes { enum PS2AttibTypes {
AT_XYZ = 0, AT_XYZ = 0,
AT_UV = 1, AT_UV = 1,
AT_UV2 = 2, AT_RGBA = 2,
AT_RGBA = 3, AT_NORMAL = 3
AT_NORMAL = 4
}; };
PipeAttribute attribXYZ = { PipeAttribute attribXYZ = {
@ -241,6 +240,301 @@ PipeAttribute attribWeights = {
Pipeline::Pipeline(uint32 platform) Pipeline::Pipeline(uint32 platform)
: rw::Pipeline(platform) { } : rw::Pipeline(platform) { }
static uint32
attribSize(uint32 unpack)
{
static uint32 size[] = { 32, 16, 8, 16 };
return ((unpack>>26 & 3)+1)*size[unpack>>24 & 3]/8;
}
#define QWC(x) (((x)+0xF)>>4)
static uint32
getBatchSize(Pipeline *pipe, uint32 vertCount)
{
PipeAttribute *a;
uint32 size = 1;
for(uint i = 0; i < nelem(pipe->attribs); i++)
if((a = pipe->attribs[i]) && (a->attrib & AT_RW) == 0){
size++;
size += QWC(vertCount*attribSize(a->attrib));
}
return size;
}
uint32*
instanceXYZ(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
{
uint16 j;
uint32 *d = (uint32*)g->morphTargets[0].vertices;
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];
}
while((uintptr)p % 0x10)
*p++ = 0;
return p;
}
uint32*
instanceUV(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
{
uint16 j;
uint32 *d = (uint32*)g->texCoords[0];
if((g->geoflags & Geometry::TEXTURED) ||
(g->geoflags & Geometry::TEXTURED2))
for(uint32 i = idx; i < idx+n; i++){
j = m->indices[i];
*p++ = d[j*2+0];
*p++ = d[j*2+1];
}
else
for(uint32 i = idx; i < idx+n; i++){
*p++ = 0;
*p++ = 0;
}
while((uintptr)p % 0x10)
*p++ = 0;
return p;
}
uint32*
instanceRGBA(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
{
uint16 j;
uint32 *d = (uint32*)g->colors;
if((g->geoflags & Geometry::PRELIT))
for(uint32 i = idx; i < idx+n; i++){
j = m->indices[i];
*p++ = d[j];
}
else
for(uint32 i = idx; i < idx+n; i++)
*p++ = 0xFF000000;
while((uintptr)p % 0x10)
*p++ = 0;
return p;
}
uint32*
instanceNormal(uint32 *wp, Geometry *g, Mesh *m, uint32 idx, uint32 n)
{
uint16 j;
float *d = g->morphTargets[0].normals;
uint8 *p = (uint8*)wp;
if((g->geoflags & Geometry::NORMALS))
for(uint32 i = idx; i < idx+n; i++){
j = m->indices[i];
*p++ = d[j*3+0]*127.0f;
*p++ = d[j*3+1]*127.0f;
*p++ = d[j*3+2]*127.0f;
}
else
for(uint32 i = idx; i < idx+n; i++){
*p++ = 0;
*p++ = 0;
*p++ = 0;
}
while((uintptr)p % 0x10)
*p++ = 0;
return (uint32*)p;
}
uint32 markcnt = 0xf790;
static void
instanceMat(Pipeline *pipe, Geometry *g, InstanceData *inst, Mesh *m)
{
PipeAttribute *a;
uint32 numAttribs = 0;
uint32 numBrokenAttribs = 0;
for(uint i = 0; i < nelem(pipe->attribs); i++)
if(a = pipe->attribs[i])
if(a->attrib & AT_RW)
numBrokenAttribs++;
else
numAttribs++;
uint32 numBatches = 0;
uint32 totalVerts = 0;
uint32 batchVertCount, lastBatchVertCount;
if(g->meshHeader->flags == 1){ // tristrip
for(uint i = 0; i < m->numIndices; i += pipe->triStripCount-2){
numBatches++;
totalVerts += m->numIndices-i < pipe->triStripCount ?
m->numIndices-i : pipe->triStripCount;
}
batchVertCount = pipe->triStripCount;
lastBatchVertCount = totalVerts%pipe->triStripCount;
}else{ // trilist
numBatches = (m->numIndices+pipe->triListCount-1) /
pipe->triListCount;
totalVerts = m->numIndices;
batchVertCount = pipe->triListCount;
lastBatchVertCount = totalVerts%pipe->triListCount;
}
uint32 batchSize = getBatchSize(pipe, batchVertCount);
uint32 lastBatchSize = getBatchSize(pipe, lastBatchVertCount);
uint32 size = 0;
if(numBrokenAttribs == 0)
size = 1 + batchSize*(numBatches-1) + lastBatchSize;
else
size = 2*numBatches +
(1+batchSize)*(numBatches-1) + 1+lastBatchSize;
/* figure out size and addresses of broken out sections */
uint32 attribPos[nelem(pipe->attribs)];
uint32 size2 = 0;
for(uint i = 0; i < nelem(pipe->attribs); i++)
if((a = pipe->attribs[i]) && a->attrib & AT_RW){
attribPos[i] = size2 + size;
size2 += QWC(m->numIndices*attribSize(a->attrib));
}
/*
printf("attribs: %d %d\n", numAttribs, numBrokenAttribs);
printf("numIndices: %d\n", m->numIndices);
printf("%d %d, %x %x\n", numBatches, totalVerts,
batchVertCount, lastBatchVertCount);
printf("%x %x\n", batchSize, lastBatchSize);
printf("size: %x, %x\n", size, size2);
*/
inst->dataSize = (size+size2)<<4;
inst->arePointersFixed = numBrokenAttribs == 0;
// TODO: force alignment
inst->data = new uint8[inst->dataSize];
uint32 idx = 0;
uint32 *p = (uint32*)inst->data;
if(numBrokenAttribs == 0){
*p++ = 0x60000000 | size-1;
*p++ = 0;
*p++ = 0x11000000; // FLUSH
*p++ = 0x06000000; // MSKPATH3; SA: FLUSH
}
for(uint32 j = 0; j < numBatches; j++){
uint32 nverts, bsize;
if(j < numBatches-1){
bsize = batchSize;
nverts = batchVertCount;
}else{
bsize = lastBatchSize;
nverts = lastBatchVertCount;
}
for(uint i = 0; i < nelem(pipe->attribs); i++)
if((a = pipe->attribs[i]) && a->attrib & AT_RW){
uint32 atsz = attribSize(a->attrib);
*p++ = 0x30000000 | QWC(nverts*atsz);
*p++ = attribPos[i];
*p++ = 0x01000100 |
pipe->inputStride; // STCYCL
*p++ = (a->attrib&0xFF004000)
| 0x8000 | nverts << 16 | i; // UNPACK
*p++ = 0x10000000;
*p++ = 0x0;
*p++ = 0x0;
*p++ = 0x0;
attribPos[i] += g->meshHeader->flags == 1 ?
QWC((batchVertCount-2)*atsz) :
QWC(batchVertCount*atsz);
}
if(numBrokenAttribs){
*p++ = (j < numBatches-1 ? 0x10000000 : 0x60000000) |
bsize;
*p++ = 0x0;
*p++ = 0x0;
*p++ = 0x0;
}
for(uint i = 0; i < nelem(pipe->attribs); i++)
if((a = pipe->attribs[i]) && (a->attrib & AT_RW) == 0){
*p++ = 0x07000000 | markcnt++; // MARK (SA: NOP)
*p++ = 0x05000000; // STMOD
*p++ = 0x01000100 |
pipe->inputStride; // STCYCL
*p++ = (a->attrib&0xFF004000)
| 0x8000 | nverts << 16 | i; // UNPACK
// TODO: instance
switch(i){
case 0:
p = instanceXYZ(p, g, m, idx, nverts);
break;
case 1:
p = instanceUV(p, g, m, idx, nverts);
break;
case 2:
p = instanceRGBA(p, g, m, idx, nverts);
break;
case 3:
p = instanceNormal(p,g, m, idx, nverts);
break;
}
}
idx += g->meshHeader->flags == 1
? batchVertCount-2 : batchVertCount;
*p++ = 0x04000000 | nverts; // ITOP
*p++ = j == 0 ? 0x15000000 : 0x17000000;
if(j < numBatches-1){
*p++ = 0x0;
*p++ = 0x0;
}else{
*p++ = 0x11000000; // FLUSH
*p++ = 0x06000000; // MSKPATH3; SA: FLUSH
}
}
/*
FILE *f = fopen("out.bin", "w");
fwrite(inst->data, inst->dataSize, 1, f);
fclose(f);
*/
}
#undef QWC
void
Pipeline::instance(Atomic *atomic)
{
Geometry *geometry = atomic->geometry;
InstanceDataHeader *header = new InstanceDataHeader;
geometry->instData = header;
header->platform = PLATFORM_PS2;
assert(geometry->meshHeader != NULL);
header->numMeshes = geometry->meshHeader->numMeshes;
header->instanceMeshes = new InstanceData[header->numMeshes];
for(uint32 i = 0; i < header->numMeshes; i++){
Mesh *mesh = &geometry->meshHeader->mesh[i];
InstanceData *instance = &header->instanceMeshes[i];
// TODO: should depend on material pipeline
instanceMat(this, geometry, instance, mesh);
//printf("\n");
}
geometry->geoflags |= Geometry::NATIVE;
}
// Only a dummy right now
void
Pipeline::uninstance(Atomic *atomic)
{
Geometry *geometry = atomic->geometry;
assert(geometry->instData->platform == PLATFORM_PS2);
assert(geometry->instData != NULL);
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
for(uint32 i = 0; i < header->numMeshes; i++){
Mesh *mesh = &geometry->meshHeader->mesh[i];
InstanceData *instance = &header->instanceMeshes[i];
printf("numIndices: %d\n", mesh->numIndices);
printDMA(instance);
}
}
void void
Pipeline::setTriBufferSizes(uint32 inputStride, Pipeline::setTriBufferSizes(uint32 inputStride,
uint32 stripCount, uint32 listCount) uint32 stripCount, uint32 listCount)
@ -277,6 +571,8 @@ Pipeline*
makeSkinPipeline(void) makeSkinPipeline(void)
{ {
Pipeline *pipe = new Pipeline(PLATFORM_PS2); Pipeline *pipe = new Pipeline(PLATFORM_PS2);
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
pipe->attribs[AT_XYZ] = &attribXYZ; pipe->attribs[AT_XYZ] = &attribXYZ;
pipe->attribs[AT_UV] = &attribUV; pipe->attribs[AT_UV] = &attribUV;
pipe->attribs[AT_RGBA] = &attribRGBA; pipe->attribs[AT_RGBA] = &attribRGBA;
@ -288,6 +584,24 @@ makeSkinPipeline(void)
return pipe; return pipe;
} }
Pipeline*
makeMatFXPipeline(void)
{
Pipeline *pipe = new Pipeline(PLATFORM_PS2);
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
pipe->attribs[AT_XYZ] = &attribXYZ;
pipe->attribs[AT_UV] = &attribUV;
pipe->attribs[AT_RGBA] = &attribRGBA;
pipe->attribs[AT_NORMAL] = &attribNormal;
// TODO: not correct
uint32 vertCount = Pipeline::getVertCount(VU_Lights, 4, 3, 2);
pipe->setTriBufferSizes(4, vertCount, vertCount/3);
pipe->triStripCount = 0x38;
pipe->vifOffset = pipe->inputStride*vertCount;
return pipe;
}
void void
dumpPipeline(rw::Pipeline *rwpipe) dumpPipeline(rw::Pipeline *rwpipe)
{ {
@ -454,6 +768,32 @@ registerADCPlugin(void)
// misc stuff // misc stuff
void
printDMA(InstanceData *inst)
{
uint32 *tag = (uint32*)inst->data;
for(;;){
switch(tag[0]&0x70000000){
// DMAcnt
case 0x10000000:
printf("%08x %08x\n", tag[0], tag[1]);
tag += (1+(tag[0]&0xFFFF))*4;
break;
// DMAref
case 0x30000000:
printf("%08x %08x\n", tag[0], tag[1]);
tag += 4;
break;
// DMAret
case 0x60000000:
printf("%08x %08x\n", tag[0], tag[1]);
return;
}
}
}
/* Function to specifically walk geometry chains */ /* Function to specifically walk geometry chains */
void void
walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size)) walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size))
@ -471,7 +811,7 @@ walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size))
break; break;
// DMAref // DMAref
case 0x3000000: case 0x30000000:
f(base + tag[1]*4, (tag[0]&0xFFFF)*4); f(base + tag[1]*4, (tag[0]&0xFFFF)*4);
tag += 4; tag += 4;
break; break;

View File

@ -18,7 +18,7 @@ int version = 0x36003;
int build = 0xFFFF; int build = 0xFFFF;
#ifdef RW_PS2 #ifdef RW_PS2
int platform = PLATFORM_PS2; int platform = PLATFORM_PS2;
#elseif RW_OPENGL #elif RW_OPENGL
int platform = PLATFORM_OPENGL; int platform = PLATFORM_OPENGL;
#else #else
int platform = PLATFORM_NULL; int platform = PLATFORM_NULL;

27
src/rwpipeline.h Normal file
View File

@ -0,0 +1,27 @@
namespace rw {
struct PipeAttribute
{
const char *name;
uint32 attrib;
};
struct Atomic;
struct Pipeline
{
uint32 pluginID;
uint32 pluginData;
uint32 platform;
PipeAttribute *attribs[10];
Pipeline(uint32 platform);
Pipeline(Pipeline *p);
~Pipeline(void);
virtual void instance(Atomic *atomic);
virtual void uninstance(Atomic *atomic);
virtual void render(Atomic *atomic);
};
}

View File

@ -29,6 +29,7 @@ void writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
int32 getSizeNativeData(void *object, int32, int32); int32 getSizeNativeData(void *object, int32, int32);
void registerNativeDataPlugin(void); void registerNativeDataPlugin(void);
void printDMA(InstanceData *inst);
void walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size)); void walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size));
void sizedebug(InstanceData *inst); void sizedebug(InstanceData *inst);
@ -49,12 +50,16 @@ struct Pipeline : rw::Pipeline
} }
Pipeline(uint32 platform); Pipeline(uint32 platform);
virtual void instance(Atomic *atomic);
virtual void uninstance(Atomic *atomic);
// virtual void render(Atomic *atomic);
void setTriBufferSizes(uint32 inputStride, void setTriBufferSizes(uint32 inputStride,
uint32 stripCount, uint32 listCount); uint32 stripCount, uint32 listCount);
}; };
Pipeline *makeDefaultPipeline(void); Pipeline *makeDefaultPipeline(void);
Pipeline *makeSkinPipeline(void); Pipeline *makeSkinPipeline(void);
Pipeline *makeMatFXPipeline(void);
void dumpPipeline(rw::Pipeline *pipe); void dumpPipeline(rw::Pipeline *pipe);
// Skin plugin // Skin plugin

View File

@ -109,10 +109,18 @@ dumpRasterPacket(int n)
printf("\n"); printf("\n");
} }
rw::Pipeline *defpipe;
void void
drawAtomic(rw::Atomic *atomic) drawAtomic(rw::Atomic *atomic)
{ {
rw::Geometry *geo = atomic->geometry; rw::Geometry *geo = atomic->geometry;
if(!(geo->geoflags & rw::Geometry::NATIVE)){
if(atomic->pipeline)
atomic->pipeline->instance(atomic);
else
defpipe->instance(atomic);
}
assert(geo->instData != NULL); assert(geo->instData != NULL);
rw::ps2::InstanceDataHeader *instData = rw::ps2::InstanceDataHeader *instData =
(rw::ps2::InstanceDataHeader*)geo->instData; (rw::ps2::InstanceDataHeader*)geo->instData;
@ -178,10 +186,10 @@ draw(void)
gsClear(); gsClear();
matMakeIdentity(viewMat); matMakeIdentity(viewMat);
matTranslate(viewMat, 0.0f, 0.0f, -34.0f); // matTranslate(viewMat, 0.0f, 0.0f, -34.0f);
// matTranslate(viewMat, 0.0f, 0.0f, -10.0f); // matTranslate(viewMat, 0.0f, 0.0f, -10.0f);
// matTranslate(viewMat, 0.0f, 0.0f, -8.0f); // matTranslate(viewMat, 0.0f, 0.0f, -8.0f);
// matTranslate(viewMat, 0.0f, 0.0f, -4.0f); matTranslate(viewMat, 0.0f, 0.0f, -4.0f);
matRotateX(viewMat, rot); matRotateX(viewMat, rot);
matRotateY(viewMat, rot); matRotateY(viewMat, rot);
matRotateZ(viewMat, rot); matRotateZ(viewMat, rot);
@ -199,7 +207,7 @@ draw(void)
matCopy(vuMat, m); matCopy(vuMat, m);
} }
rot += 0.01f; rot += 0.001f;
if(rot > 2*M_PI) if(rot > 2*M_PI)
rot -= 2*M_PI; rot -= 2*M_PI;
} }
@ -233,9 +241,14 @@ main()
// rw::ps2::registerNativeDataPlugin(); // rw::ps2::registerNativeDataPlugin();
rw::registerMeshPlugin(); rw::registerMeshPlugin();
defpipe = rw::ps2::makeDefaultPipeline();
printf("platform: %d\n", rw::platform);
rw::uint32 len; rw::uint32 len;
// rw::uint8 *data = rw::getFileContents("host:player-vc-ps2.dff", &len); // rw::uint8 *data = rw::getFileContents("host:player-vc-ps2.dff", &len);
rw::uint8 *data = rw::getFileContents("host:od_newscafe_dy-ps2.dff", &len); rw::uint8 *data = rw::getFileContents("host:player_pc.dff", &len);
// rw::uint8 *data = rw::getFileContents("host:od_newscafe_dy-ps2.dff", &len);
// rw::uint8 *data = rw::getFileContents("host:admiral-ps2.dff", &len); // rw::uint8 *data = rw::getFileContents("host:admiral-ps2.dff", &len);
rw::StreamMemory in; rw::StreamMemory in;
in.open(data, len); in.open(data, len);