From d832570142c39533a7a7b773531c7e1833d96a75 Mon Sep 17 00:00:00 2001 From: aap Date: Sun, 12 Jul 2015 22:57:05 +0200 Subject: [PATCH] basic PS2 instancing --- dumprwtree.cpp | 139 +++++++ insttest.cpp | 100 +++++ src/image.cpp | 985 +++++++++++++++++++++++---------------------- src/pipeline.cpp | 54 +++ src/plugins.cpp | 5 +- src/ps2.cpp | 352 +++++++++++++++- src/rwbase.cpp | 2 +- src/rwpipeline.h | 27 ++ src/rwps2.h | 5 + tests/ps2/main.cpp | 21 +- 10 files changed, 1186 insertions(+), 504 deletions(-) create mode 100644 dumprwtree.cpp create mode 100644 insttest.cpp create mode 100644 src/pipeline.cpp create mode 100644 src/rwpipeline.h diff --git a/dumprwtree.cpp b/dumprwtree.cpp new file mode 100644 index 0000000..6b6cc87 --- /dev/null +++ b/dumprwtree.cpp @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include + +#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; +} diff --git a/insttest.cpp b/insttest.cpp new file mode 100644 index 0000000..2bfa21d --- /dev/null +++ b/insttest.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include + +#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; +} diff --git a/src/image.cpp b/src/image.cpp index ed32458..1a59e57 100755 --- a/src/image.cpp +++ b/src/image.cpp @@ -1,492 +1,493 @@ -#include -#include -#include -#include - -#include - -#include "rwbase.h" -#include "rwplugin.h" -#include "rwpipeline.h" -#include "rwobjects.h" - -using namespace std; - -namespace rw { - -// -// TexDictionary -// - -TexDictionary *currentTexDictionary; - -TexDictionary::TexDictionary(void) -{ - this->first = NULL; -} - -void -TexDictionary::add(Texture *tex) -{ - tex->next = this->first; - this->first = tex; -} - -Texture* -TexDictionary::find(const char *name) -{ - for(Texture *tex = this->first; tex; tex = tex->next) - if(strncmp(tex->name, name, 32) == 0) - return tex; - return NULL; -} - -// -// Texture -// - -Texture::Texture(void) -{ - memset(this->name, 0, 32); - memset(this->mask, 0, 32); - this->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST; - this->raster = NULL; - this->refCount = 1; - this->next = NULL; - this->constructPlugins(); -} - -Texture::~Texture(void) -{ - this->destructPlugins(); -} - -void -Texture::decRef(void) -{ - this->refCount--; - if(this->refCount) - delete this; -} - -// TODO: do this properly, pretty ugly right now -Texture* -Texture::read(const char *name, const char *mask) -{ - (void)mask; - Raster *raster = NULL; - Texture *tex; - - if(currentTexDictionary && (tex = currentTexDictionary->find(name))) - return tex; - tex = new Texture; - strncpy(tex->name, name, 32); - strncpy(tex->mask, mask, 32); - char *n = (char*)malloc(strlen(name) + 5); - strcpy(n, name); - strcat(n, ".tga"); - Image *img = readTGA(n); - free(n); - if(img){ - raster = Raster::createFromImage(img); - delete img; - } - tex->raster = raster; - if(currentTexDictionary) - currentTexDictionary->add(tex); - return tex; -} - -Texture* -Texture::streamRead(Stream *stream) -{ - uint32 length; - char name[32], mask[32]; - assert(findChunk(stream, ID_STRUCT, NULL, NULL)); - uint32 filterAddressing = stream->readU16(); - // TODO: what is this? (mipmap? i think) - stream->seek(2); - - assert(findChunk(stream, ID_STRING, &length, NULL)); - stream->read(name, length); - - assert(findChunk(stream, ID_STRING, &length, NULL)); - stream->read(mask, length); - - Texture *tex = Texture::read(name, mask); - tex->refCount++; - tex->filterAddressing = filterAddressing; - - tex->streamReadPlugins(stream); - - return tex; -} - -bool -Texture::streamWrite(Stream *stream) -{ - int size; - writeChunkHeader(stream, ID_TEXTURE, this->streamGetSize()); - writeChunkHeader(stream, ID_STRUCT, 4); - stream->writeU32(this->filterAddressing); - - // TODO: length can't be > 32 - size = strlen(this->name)+4 & ~3; - writeChunkHeader(stream, ID_STRING, size); - stream->write(this->name, size); - - size = strlen(this->mask)+4 & ~3; - writeChunkHeader(stream, ID_STRING, size); - stream->write(this->mask, size); - - this->streamWritePlugins(stream); - return true; -} - -uint32 -Texture::streamGetSize(void) -{ - uint32 size = 0; - size += 12 + 4; - size += 12 + 12; - size += strlen(this->name)+4 & ~3; - size += strlen(this->mask)+4 & ~3; - size += 12 + this->streamGetPluginSize(); - return size; -} - -// -// Image -// - -Image::Image(int32 width, int32 height, int32 depth) -{ - this->flags = 0; - this->width = width; - this->height = height; - this->depth = depth; - this->stride = 0; - this->pixels = NULL; - this->palette = NULL; -} - -Image::~Image(void) -{ - this->free(); -} - -void -Image::allocate(void) -{ - if(this->pixels == NULL){ - this->stride = this->width*(this->depth==4 ? 1 : this->depth/8); - this->pixels = new uint8[this->stride*this->height]; - this->flags |= 1; - } - if(this->palette == NULL){ - if(this->depth == 4 || this->depth == 8) - this->palette = new uint8[(this->depth==4? 16 : 256)*4]; - this->flags |= 2; - } -} - -void -Image::free(void) -{ - if(this->flags&1) - delete[] this->pixels; - if(this->flags&2) - delete[] this->palette; -} - -void -Image::setPixels(uint8 *pixels) -{ - this->pixels = pixels; - this->flags |= 1; -} - -void -Image::setPalette(uint8 *palette) -{ - this->palette = palette; - this->flags |= 2; -} - -static char *searchPaths = NULL; -int numSearchPaths = 0; - -void -Image::setSearchPath(const char *path) -{ - char *p, *end; - ::free(searchPaths); - numSearchPaths = 0; - if(path) - searchPaths = p = strdup(path); - else{ - searchPaths = NULL; - return; - } - while(p && *p){ - end = strchr(p, ';'); - if(end) - *end++ = '\0'; - numSearchPaths++; - p = end; - } -} - -void -Image::printSearchPath(void) -{ - char *p = searchPaths; - for(int i = 0; i < numSearchPaths; i++){ - printf("%s\n", p); - p += strlen(p) + 1; - } -} - -char* -Image::getFilename(const char *name) -{ - FILE *f; - char *s, *p = searchPaths; - int len = strlen(name)+1; - if(numSearchPaths == 0){ - f = fopen(name, "r"); - if(f){ - fclose(f); - printf("found %s\n", name); - return strdup(name); - } - return NULL; - }else - for(int i = 0; i < numSearchPaths; i++){ - s = (char*)malloc(strlen(p)+len); - strcpy(s, p); - strcat(s, name); - f = fopen(s, "r"); - if(f){ - fclose(f); - printf("found %s\n", name); - return s; - } - ::free(s); - p += strlen(p) + 1; - } - return NULL; -} - -// -// TGA I/O -// - -#ifndef RW_PS2 -#pragma pack(push) -#pragma pack(1) -#define PACKED_STRUCT -#else -#define PACKED_STRUCT __attribute__((__packed__)) -#endif -struct PACKED_STRUCT TGAHeader -{ - int8 IDlen; - int8 colorMapType; - int8 imageType; - int16 colorMapOrigin; - int16 colorMapLength; - int8 colorMapDepth; - int16 xOrigin, yOrigin; - int16 width, height; - uint8 depth; - uint8 descriptor; -}; -#ifndef RW_PS2 -#pragma pack(push) -#endif - -Image* -readTGA(const char *afilename) -{ - TGAHeader header; - Image *image; - char *filename; - int depth = 0, palDepth = 0; - filename = Image::getFilename(afilename); - if(filename == NULL) - return NULL; - uint32 length; - uint8 *data = getFileContents(filename, &length); - assert(data != NULL); - free(filename); - StreamMemory file; - file.open(data, length); - file.read(&header, sizeof(header)); - - assert(header.imageType == 1 || header.imageType == 2); - file.seek(header.IDlen); - if(header.colorMapType){ - assert(header.colorMapOrigin == 0); - depth = (header.colorMapLength <= 16) ? 4 : 8; - palDepth = header.colorMapDepth; - assert(palDepth == 24 || palDepth == 32); - }else{ - depth = header.depth; - assert(depth == 24 || depth == 32); - } - - image = new Image(header.width, header.height, depth); - image->allocate(); - uint8 *palette = header.colorMapType ? image->palette : NULL; - uint8 (*color)[4] = NULL; - if(palette){ - int maxlen = depth == 4 ? 16 : 256; - color = (uint8(*)[4])palette; - int i; - for(i = 0; i < header.colorMapLength; i++){ - color[i][2] = file.readU8(); - color[i][1] = file.readU8(); - color[i][0] = file.readU8(); - color[i][3] = 0xFF; - if(palDepth == 32) - color[i][3] = file.readU8(); - } - for(; i < maxlen; i++){ - color[i][0] = color[i][1] = color[i][2] = 0; - color[i][3] = 0xFF; - } - } - - uint8 *pixels = image->pixels; - if(!(header.descriptor & 0x20)) - pixels += (image->height-1)*image->stride; - for(int y = 0; y < image->height; y++){ - uint8 *line = pixels; - for(int x = 0; x < image->width; x++){ - if(palette) - *line++ = file.readU8(); - else{ - line[2] = file.readU8(); - line[1] = file.readU8(); - line[0] = file.readU8(); - line += 3; - if(depth == 32) - *line++ = file.readU8(); - } - } - pixels += (header.descriptor&0x20) ? - image->stride : -image->stride; - } - - file.close(); - delete[] data; - return image; -} - -void -writeTGA(Image *image, const char *filename) -{ - TGAHeader header; - StreamFile file; - assert(file.open(filename, "wb")); - header.IDlen = 0; - header.imageType = image->palette != NULL ? 1 : 2; - header.colorMapType = image->palette != NULL; - header.colorMapOrigin = 0; - header.colorMapLength = image->depth == 4 ? 16 : - image->depth == 8 ? 256 : 0; - header.colorMapDepth = image->palette ? 32 : 0; - header.xOrigin = 0; - header.yOrigin = 0; - header.width = image->width; - header.height = image->height; - header.depth = image->depth == 4 ? 8 : image->depth; - header.descriptor = 0x20 | (image->depth == 32 ? 8 : 0); - file.write(&header, sizeof(header)); - - uint8 *pixels = image->pixels; - uint8 *palette = header.colorMapType ? image->palette : NULL; - uint8 (*color)[4] = (uint8(*)[4])palette;; - if(palette) - for(int i = 0; i < header.colorMapLength; i++){ - file.writeU8(color[i][2]); - file.writeU8(color[i][1]); - file.writeU8(color[i][0]); - file.writeU8(color[i][3]); - } - - for(int y = 0; y < image->height; y++){ - uint8 *line = pixels; - for(int x = 0; x < image->width; x++){ - if(palette) - file.writeU8(*line++); - else{ - file.writeU8(line[2]); - file.writeU8(line[1]); - file.writeU8(line[0]); - line += 3; - if(image->depth == 32) - file.writeU8(*line++); - } - } - pixels += image->stride; - } - file.close(); -} - -// -// Raster -// - -Raster::Raster(void) -{ - this->type = 0; - this->width = this->height = this->depth = this->stride = 0; - this->format = 0; - this->texels = this->palette = NULL; - this->constructPlugins(); -} - -Raster::~Raster(void) -{ - this->destructPlugins(); - delete[] this->texels; - delete[] this->palette; -} - -Raster* -Raster::createFromImage(Image *image) -{ - Raster *raster = new Raster; - raster->type = 4; - raster->width = image->width; - raster->stride = image->stride; - raster->height = image->height; - raster->depth = image->depth; - raster->texels = raster->palette = NULL; - if(raster->depth == 32) - raster->format = Raster::C8888; - else if(raster->depth == 24) - raster->format = Raster::C888; - else if(raster->depth == 16) - raster->format = Raster::C1555; - else if(raster->depth == 8) - raster->format = Raster::PAL8 | Raster::C8888; - else if(raster->depth == 4) - raster->format = Raster::PAL4 | Raster::C8888; - else{ - delete raster; - return NULL; - } - raster->texels = new uint8[raster->stride*raster->height]; - memcpy(raster->texels, image->pixels, raster->stride*raster->height); - if(image->palette){ - int size = raster->depth == 4 ? 16 : 256; - raster->palette = new uint8[size*4]; - memcpy(raster->palette, image->palette, size*4); - } - return raster; -} - -} +#include +#include +#include +#include + +#include + +#include "rwbase.h" +#include "rwplugin.h" +#include "rwpipeline.h" +#include "rwobjects.h" + +using namespace std; + +namespace rw { + +// +// TexDictionary +// + +TexDictionary *currentTexDictionary; + +TexDictionary::TexDictionary(void) +{ + this->first = NULL; +} + +void +TexDictionary::add(Texture *tex) +{ + tex->next = this->first; + this->first = tex; +} + +Texture* +TexDictionary::find(const char *name) +{ + for(Texture *tex = this->first; tex; tex = tex->next) + if(strncmp(tex->name, name, 32) == 0) + return tex; + return NULL; +} + +// +// Texture +// + +Texture::Texture(void) +{ + memset(this->name, 0, 32); + memset(this->mask, 0, 32); + this->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST; + this->raster = NULL; + this->refCount = 1; + this->next = NULL; + this->constructPlugins(); +} + +Texture::~Texture(void) +{ + this->destructPlugins(); +} + +void +Texture::decRef(void) +{ + this->refCount--; + if(this->refCount) + delete this; +} + +// TODO: do this properly, pretty ugly right now +Texture* +Texture::read(const char *name, const char *mask) +{ + (void)mask; + Raster *raster = NULL; + Texture *tex; + + if(currentTexDictionary && (tex = currentTexDictionary->find(name))) + return tex; + tex = new Texture; + strncpy(tex->name, name, 32); + strncpy(tex->mask, mask, 32); + char *n = (char*)malloc(strlen(name) + 5); + strcpy(n, name); + strcat(n, ".tga"); + Image *img = readTGA(n); + free(n); + if(img){ + raster = Raster::createFromImage(img); + delete img; + } + tex->raster = raster; + if(currentTexDictionary) + currentTexDictionary->add(tex); + return tex; +} + +Texture* +Texture::streamRead(Stream *stream) +{ + uint32 length; + char name[32], mask[32]; + assert(findChunk(stream, ID_STRUCT, NULL, NULL)); + uint32 filterAddressing = stream->readU16(); + // TODO: what is this? (mipmap? i think) + stream->seek(2); + + assert(findChunk(stream, ID_STRING, &length, NULL)); + stream->read(name, length); + + assert(findChunk(stream, ID_STRING, &length, NULL)); + stream->read(mask, length); + + Texture *tex = Texture::read(name, mask); + tex->refCount++; + tex->filterAddressing = filterAddressing; + + tex->streamReadPlugins(stream); + + return tex; +} + +bool +Texture::streamWrite(Stream *stream) +{ + int size; + writeChunkHeader(stream, ID_TEXTURE, this->streamGetSize()); + writeChunkHeader(stream, ID_STRUCT, 4); + stream->writeU32(this->filterAddressing); + + // TODO: length can't be > 32 + size = strlen(this->name)+4 & ~3; + writeChunkHeader(stream, ID_STRING, size); + stream->write(this->name, size); + + size = strlen(this->mask)+4 & ~3; + writeChunkHeader(stream, ID_STRING, size); + stream->write(this->mask, size); + + this->streamWritePlugins(stream); + return true; +} + +uint32 +Texture::streamGetSize(void) +{ + uint32 size = 0; + size += 12 + 4; + size += 12 + 12; + size += strlen(this->name)+4 & ~3; + size += strlen(this->mask)+4 & ~3; + size += 12 + this->streamGetPluginSize(); + return size; +} + +// +// Image +// + +Image::Image(int32 width, int32 height, int32 depth) +{ + this->flags = 0; + this->width = width; + this->height = height; + this->depth = depth; + this->stride = 0; + this->pixels = NULL; + this->palette = NULL; +} + +Image::~Image(void) +{ + this->free(); +} + +void +Image::allocate(void) +{ + if(this->pixels == NULL){ + this->stride = this->width*(this->depth==4 ? 1 : this->depth/8); + this->pixels = new uint8[this->stride*this->height]; + this->flags |= 1; + } + if(this->palette == NULL){ + if(this->depth == 4 || this->depth == 8) + this->palette = new uint8[(this->depth==4? 16 : 256)*4]; + this->flags |= 2; + } +} + +void +Image::free(void) +{ + if(this->flags&1) + delete[] this->pixels; + if(this->flags&2) + delete[] this->palette; +} + +void +Image::setPixels(uint8 *pixels) +{ + this->pixels = pixels; + this->flags |= 1; +} + +void +Image::setPalette(uint8 *palette) +{ + this->palette = palette; + this->flags |= 2; +} + +static char *searchPaths = NULL; +int numSearchPaths = 0; + +void +Image::setSearchPath(const char *path) +{ + char *p, *end; + ::free(searchPaths); + numSearchPaths = 0; + if(path) + searchPaths = p = strdup(path); + else{ + searchPaths = NULL; + return; + } + while(p && *p){ + end = strchr(p, ';'); + if(end) + *end++ = '\0'; + numSearchPaths++; + p = end; + } +} + +void +Image::printSearchPath(void) +{ + char *p = searchPaths; + for(int i = 0; i < numSearchPaths; i++){ + printf("%s\n", p); + p += strlen(p) + 1; + } +} + +char* +Image::getFilename(const char *name) +{ + FILE *f; + char *s, *p = searchPaths; + int len = strlen(name)+1; + if(numSearchPaths == 0){ + f = fopen(name, "r"); + if(f){ + fclose(f); + printf("found %s\n", name); + return strdup(name); + } + return NULL; + }else + for(int i = 0; i < numSearchPaths; i++){ + s = (char*)malloc(strlen(p)+len); + strcpy(s, p); + strcat(s, name); + f = fopen(s, "r"); + if(f){ + fclose(f); + printf("found %s\n", name); + return s; + } + ::free(s); + p += strlen(p) + 1; + } + return NULL; +} + +// +// TGA I/O +// + +// TODO: fuck pakced structs +#ifndef RW_PS2 +#pragma pack(push) +#pragma pack(1) +#define PACKED_STRUCT +#else +#define PACKED_STRUCT __attribute__((__packed__)) +#endif +struct PACKED_STRUCT TGAHeader +{ + int8 IDlen; + int8 colorMapType; + int8 imageType; + int16 colorMapOrigin; + int16 colorMapLength; + int8 colorMapDepth; + int16 xOrigin, yOrigin; + int16 width, height; + uint8 depth; + uint8 descriptor; +}; +#ifndef RW_PS2 +#pragma pack(push) +#endif + +Image* +readTGA(const char *afilename) +{ + TGAHeader header; + Image *image; + char *filename; + int depth = 0, palDepth = 0; + filename = Image::getFilename(afilename); + if(filename == NULL) + return NULL; + uint32 length; + uint8 *data = getFileContents(filename, &length); + assert(data != NULL); + free(filename); + StreamMemory file; + file.open(data, length); + file.read(&header, sizeof(header)); + + assert(header.imageType == 1 || header.imageType == 2); + file.seek(header.IDlen); + if(header.colorMapType){ + assert(header.colorMapOrigin == 0); + depth = (header.colorMapLength <= 16) ? 4 : 8; + palDepth = header.colorMapDepth; + assert(palDepth == 24 || palDepth == 32); + }else{ + depth = header.depth; + assert(depth == 24 || depth == 32); + } + + image = new Image(header.width, header.height, depth); + image->allocate(); + uint8 *palette = header.colorMapType ? image->palette : NULL; + uint8 (*color)[4] = NULL; + if(palette){ + int maxlen = depth == 4 ? 16 : 256; + color = (uint8(*)[4])palette; + int i; + for(i = 0; i < header.colorMapLength; i++){ + color[i][2] = file.readU8(); + color[i][1] = file.readU8(); + color[i][0] = file.readU8(); + color[i][3] = 0xFF; + if(palDepth == 32) + color[i][3] = file.readU8(); + } + for(; i < maxlen; i++){ + color[i][0] = color[i][1] = color[i][2] = 0; + color[i][3] = 0xFF; + } + } + + uint8 *pixels = image->pixels; + if(!(header.descriptor & 0x20)) + pixels += (image->height-1)*image->stride; + for(int y = 0; y < image->height; y++){ + uint8 *line = pixels; + for(int x = 0; x < image->width; x++){ + if(palette) + *line++ = file.readU8(); + else{ + line[2] = file.readU8(); + line[1] = file.readU8(); + line[0] = file.readU8(); + line += 3; + if(depth == 32) + *line++ = file.readU8(); + } + } + pixels += (header.descriptor&0x20) ? + image->stride : -image->stride; + } + + file.close(); + delete[] data; + return image; +} + +void +writeTGA(Image *image, const char *filename) +{ + TGAHeader header; + StreamFile file; + assert(file.open(filename, "wb")); + header.IDlen = 0; + header.imageType = image->palette != NULL ? 1 : 2; + header.colorMapType = image->palette != NULL; + header.colorMapOrigin = 0; + header.colorMapLength = image->depth == 4 ? 16 : + image->depth == 8 ? 256 : 0; + header.colorMapDepth = image->palette ? 32 : 0; + header.xOrigin = 0; + header.yOrigin = 0; + header.width = image->width; + header.height = image->height; + header.depth = image->depth == 4 ? 8 : image->depth; + header.descriptor = 0x20 | (image->depth == 32 ? 8 : 0); + file.write(&header, sizeof(header)); + + uint8 *pixels = image->pixels; + uint8 *palette = header.colorMapType ? image->palette : NULL; + uint8 (*color)[4] = (uint8(*)[4])palette;; + if(palette) + for(int i = 0; i < header.colorMapLength; i++){ + file.writeU8(color[i][2]); + file.writeU8(color[i][1]); + file.writeU8(color[i][0]); + file.writeU8(color[i][3]); + } + + for(int y = 0; y < image->height; y++){ + uint8 *line = pixels; + for(int x = 0; x < image->width; x++){ + if(palette) + file.writeU8(*line++); + else{ + file.writeU8(line[2]); + file.writeU8(line[1]); + file.writeU8(line[0]); + line += 3; + if(image->depth == 32) + file.writeU8(*line++); + } + } + pixels += image->stride; + } + file.close(); +} + +// +// Raster +// + +Raster::Raster(void) +{ + this->type = 0; + this->width = this->height = this->depth = this->stride = 0; + this->format = 0; + this->texels = this->palette = NULL; + this->constructPlugins(); +} + +Raster::~Raster(void) +{ + this->destructPlugins(); + delete[] this->texels; + delete[] this->palette; +} + +Raster* +Raster::createFromImage(Image *image) +{ + Raster *raster = new Raster; + raster->type = 4; + raster->width = image->width; + raster->stride = image->stride; + raster->height = image->height; + raster->depth = image->depth; + raster->texels = raster->palette = NULL; + if(raster->depth == 32) + raster->format = Raster::C8888; + else if(raster->depth == 24) + raster->format = Raster::C888; + else if(raster->depth == 16) + raster->format = Raster::C1555; + else if(raster->depth == 8) + raster->format = Raster::PAL8 | Raster::C8888; + else if(raster->depth == 4) + raster->format = Raster::PAL4 | Raster::C8888; + else{ + delete raster; + return NULL; + } + raster->texels = new uint8[raster->stride*raster->height]; + memcpy(raster->texels, image->pixels, raster->stride*raster->height); + if(image->palette){ + int size = raster->depth == 4 ? 16 : 256; + raster->palette = new uint8[size*4]; + memcpy(raster->palette, image->palette, size*4); + } + return raster; +} + +} diff --git a/src/pipeline.cpp b/src/pipeline.cpp new file mode 100644 index 0000000..5e61987 --- /dev/null +++ b/src/pipeline.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +#include + +#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"); +} + +} diff --git a/src/plugins.cpp b/src/plugins.cpp index f3cad01..44c2b2f 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -554,7 +554,8 @@ registerSkinPlugin(void) defpipe->pluginData = 1; for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++) skinGlobals.pipelines[i] = defpipe; - + skinGlobals.pipelines[platformIdx[PLATFORM_PS2]] = + ps2::makeSkinPipeline(); skinGlobals.offset = Geometry::registerPlugin(sizeof(Skin*), ID_SKIN, createSkin, @@ -883,6 +884,8 @@ registerMatFXPlugin(void) defpipe->pluginData = 0; for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++) matFXGlobals.pipelines[i] = defpipe; + matFXGlobals.pipelines[platformIdx[PLATFORM_PS2]] = + ps2::makeMatFXPipeline(); matFXGlobals.atomicOffset = Atomic::registerPlugin(sizeof(int32), ID_MATFX, diff --git a/src/ps2.cpp b/src/ps2.cpp index 2ef1ee0..567d71f 100644 --- a/src/ps2.cpp +++ b/src/ps2.cpp @@ -126,7 +126,7 @@ fixDmaOffsets(InstanceData *inst) // DMAref case 0x30000000: // fix address and jump to next - tag[1] = base + tag[1]*0x10; + tag[1] = base + tag[1]<<4; tag += 4; break; @@ -165,7 +165,7 @@ unfixDmaOffsets(InstanceData *inst) // DMAref case 0x30000000: // unfix address and jump to next - tag[1] = (tag[1] - base)/0x10; + tag[1] = (tag[1] - base)>>4; tag += 4; break; @@ -203,9 +203,8 @@ enum PS2Attribs { enum PS2AttibTypes { AT_XYZ = 0, AT_UV = 1, - AT_UV2 = 2, - AT_RGBA = 3, - AT_NORMAL = 4 + AT_RGBA = 2, + AT_NORMAL = 3 }; PipeAttribute attribXYZ = { @@ -241,6 +240,301 @@ PipeAttribute attribWeights = { Pipeline::Pipeline(uint32 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 Pipeline::setTriBufferSizes(uint32 inputStride, uint32 stripCount, uint32 listCount) @@ -277,6 +571,8 @@ Pipeline* makeSkinPipeline(void) { Pipeline *pipe = new Pipeline(PLATFORM_PS2); + pipe->pluginID = ID_SKIN; + pipe->pluginData = 1; pipe->attribs[AT_XYZ] = &attribXYZ; pipe->attribs[AT_UV] = &attribUV; pipe->attribs[AT_RGBA] = &attribRGBA; @@ -288,6 +584,24 @@ makeSkinPipeline(void) 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 dumpPipeline(rw::Pipeline *rwpipe) { @@ -454,6 +768,32 @@ registerADCPlugin(void) // 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 */ void walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size)) @@ -471,7 +811,7 @@ walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size)) break; // DMAref - case 0x3000000: + case 0x30000000: f(base + tag[1]*4, (tag[0]&0xFFFF)*4); tag += 4; break; diff --git a/src/rwbase.cpp b/src/rwbase.cpp index 17cc742..a99bece 100644 --- a/src/rwbase.cpp +++ b/src/rwbase.cpp @@ -18,7 +18,7 @@ int version = 0x36003; int build = 0xFFFF; #ifdef RW_PS2 int platform = PLATFORM_PS2; -#elseif RW_OPENGL +#elif RW_OPENGL int platform = PLATFORM_OPENGL; #else int platform = PLATFORM_NULL; diff --git a/src/rwpipeline.h b/src/rwpipeline.h new file mode 100644 index 0000000..96bb4b3 --- /dev/null +++ b/src/rwpipeline.h @@ -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); +}; + +} diff --git a/src/rwps2.h b/src/rwps2.h index 3a633b7..a1e1732 100644 --- a/src/rwps2.h +++ b/src/rwps2.h @@ -29,6 +29,7 @@ void writeNativeData(Stream *stream, int32 len, void *object, int32, int32); int32 getSizeNativeData(void *object, int32, int32); void registerNativeDataPlugin(void); +void printDMA(InstanceData *inst); void walkDMA(InstanceData *inst, void (*f)(uint32 *data, int32 size)); void sizedebug(InstanceData *inst); @@ -49,12 +50,16 @@ struct Pipeline : rw::Pipeline } Pipeline(uint32 platform); + virtual void instance(Atomic *atomic); + virtual void uninstance(Atomic *atomic); +// virtual void render(Atomic *atomic); void setTriBufferSizes(uint32 inputStride, uint32 stripCount, uint32 listCount); }; Pipeline *makeDefaultPipeline(void); Pipeline *makeSkinPipeline(void); +Pipeline *makeMatFXPipeline(void); void dumpPipeline(rw::Pipeline *pipe); // Skin plugin diff --git a/tests/ps2/main.cpp b/tests/ps2/main.cpp index c2e2307..524a9d3 100755 --- a/tests/ps2/main.cpp +++ b/tests/ps2/main.cpp @@ -109,10 +109,18 @@ dumpRasterPacket(int n) printf("\n"); } +rw::Pipeline *defpipe; + void drawAtomic(rw::Atomic *atomic) { 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); rw::ps2::InstanceDataHeader *instData = (rw::ps2::InstanceDataHeader*)geo->instData; @@ -178,10 +186,10 @@ draw(void) gsClear(); 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, -8.0f); -// matTranslate(viewMat, 0.0f, 0.0f, -4.0f); + matTranslate(viewMat, 0.0f, 0.0f, -4.0f); matRotateX(viewMat, rot); matRotateY(viewMat, rot); matRotateZ(viewMat, rot); @@ -199,7 +207,7 @@ draw(void) matCopy(vuMat, m); } - rot += 0.01f; + rot += 0.001f; if(rot > 2*M_PI) rot -= 2*M_PI; } @@ -233,9 +241,14 @@ main() // rw::ps2::registerNativeDataPlugin(); rw::registerMeshPlugin(); + defpipe = rw::ps2::makeDefaultPipeline(); + + printf("platform: %d\n", rw::platform); + rw::uint32 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::StreamMemory in; in.open(data, len);