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

@ -1,492 +1,493 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <cassert> #include <cassert>
#include <new> #include <new>
#include "rwbase.h" #include "rwbase.h"
#include "rwplugin.h" #include "rwplugin.h"
#include "rwpipeline.h" #include "rwpipeline.h"
#include "rwobjects.h" #include "rwobjects.h"
using namespace std; using namespace std;
namespace rw { namespace rw {
// //
// TexDictionary // TexDictionary
// //
TexDictionary *currentTexDictionary; TexDictionary *currentTexDictionary;
TexDictionary::TexDictionary(void) TexDictionary::TexDictionary(void)
{ {
this->first = NULL; this->first = NULL;
} }
void void
TexDictionary::add(Texture *tex) TexDictionary::add(Texture *tex)
{ {
tex->next = this->first; tex->next = this->first;
this->first = tex; this->first = tex;
} }
Texture* Texture*
TexDictionary::find(const char *name) TexDictionary::find(const char *name)
{ {
for(Texture *tex = this->first; tex; tex = tex->next) for(Texture *tex = this->first; tex; tex = tex->next)
if(strncmp(tex->name, name, 32) == 0) if(strncmp(tex->name, name, 32) == 0)
return tex; return tex;
return NULL; return NULL;
} }
// //
// Texture // Texture
// //
Texture::Texture(void) Texture::Texture(void)
{ {
memset(this->name, 0, 32); memset(this->name, 0, 32);
memset(this->mask, 0, 32); memset(this->mask, 0, 32);
this->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST; this->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST;
this->raster = NULL; this->raster = NULL;
this->refCount = 1; this->refCount = 1;
this->next = NULL; this->next = NULL;
this->constructPlugins(); this->constructPlugins();
} }
Texture::~Texture(void) Texture::~Texture(void)
{ {
this->destructPlugins(); this->destructPlugins();
} }
void void
Texture::decRef(void) Texture::decRef(void)
{ {
this->refCount--; this->refCount--;
if(this->refCount) if(this->refCount)
delete this; delete this;
} }
// TODO: do this properly, pretty ugly right now // TODO: do this properly, pretty ugly right now
Texture* Texture*
Texture::read(const char *name, const char *mask) Texture::read(const char *name, const char *mask)
{ {
(void)mask; (void)mask;
Raster *raster = NULL; Raster *raster = NULL;
Texture *tex; Texture *tex;
if(currentTexDictionary && (tex = currentTexDictionary->find(name))) if(currentTexDictionary && (tex = currentTexDictionary->find(name)))
return tex; return tex;
tex = new Texture; tex = new Texture;
strncpy(tex->name, name, 32); strncpy(tex->name, name, 32);
strncpy(tex->mask, mask, 32); strncpy(tex->mask, mask, 32);
char *n = (char*)malloc(strlen(name) + 5); char *n = (char*)malloc(strlen(name) + 5);
strcpy(n, name); strcpy(n, name);
strcat(n, ".tga"); strcat(n, ".tga");
Image *img = readTGA(n); Image *img = readTGA(n);
free(n); free(n);
if(img){ if(img){
raster = Raster::createFromImage(img); raster = Raster::createFromImage(img);
delete img; delete img;
} }
tex->raster = raster; tex->raster = raster;
if(currentTexDictionary) if(currentTexDictionary)
currentTexDictionary->add(tex); currentTexDictionary->add(tex);
return tex; return tex;
} }
Texture* Texture*
Texture::streamRead(Stream *stream) Texture::streamRead(Stream *stream)
{ {
uint32 length; uint32 length;
char name[32], mask[32]; char name[32], mask[32];
assert(findChunk(stream, ID_STRUCT, NULL, NULL)); assert(findChunk(stream, ID_STRUCT, NULL, NULL));
uint32 filterAddressing = stream->readU16(); uint32 filterAddressing = stream->readU16();
// TODO: what is this? (mipmap? i think) // TODO: what is this? (mipmap? i think)
stream->seek(2); stream->seek(2);
assert(findChunk(stream, ID_STRING, &length, NULL)); assert(findChunk(stream, ID_STRING, &length, NULL));
stream->read(name, length); stream->read(name, length);
assert(findChunk(stream, ID_STRING, &length, NULL)); assert(findChunk(stream, ID_STRING, &length, NULL));
stream->read(mask, length); stream->read(mask, length);
Texture *tex = Texture::read(name, mask); Texture *tex = Texture::read(name, mask);
tex->refCount++; tex->refCount++;
tex->filterAddressing = filterAddressing; tex->filterAddressing = filterAddressing;
tex->streamReadPlugins(stream); tex->streamReadPlugins(stream);
return tex; return tex;
} }
bool bool
Texture::streamWrite(Stream *stream) Texture::streamWrite(Stream *stream)
{ {
int size; int size;
writeChunkHeader(stream, ID_TEXTURE, this->streamGetSize()); writeChunkHeader(stream, ID_TEXTURE, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, 4); writeChunkHeader(stream, ID_STRUCT, 4);
stream->writeU32(this->filterAddressing); stream->writeU32(this->filterAddressing);
// TODO: length can't be > 32 // TODO: length can't be > 32
size = strlen(this->name)+4 & ~3; size = strlen(this->name)+4 & ~3;
writeChunkHeader(stream, ID_STRING, size); writeChunkHeader(stream, ID_STRING, size);
stream->write(this->name, size); stream->write(this->name, size);
size = strlen(this->mask)+4 & ~3; size = strlen(this->mask)+4 & ~3;
writeChunkHeader(stream, ID_STRING, size); writeChunkHeader(stream, ID_STRING, size);
stream->write(this->mask, size); stream->write(this->mask, size);
this->streamWritePlugins(stream); this->streamWritePlugins(stream);
return true; return true;
} }
uint32 uint32
Texture::streamGetSize(void) Texture::streamGetSize(void)
{ {
uint32 size = 0; uint32 size = 0;
size += 12 + 4; size += 12 + 4;
size += 12 + 12; size += 12 + 12;
size += strlen(this->name)+4 & ~3; size += strlen(this->name)+4 & ~3;
size += strlen(this->mask)+4 & ~3; size += strlen(this->mask)+4 & ~3;
size += 12 + this->streamGetPluginSize(); size += 12 + this->streamGetPluginSize();
return size; return size;
} }
// //
// Image // Image
// //
Image::Image(int32 width, int32 height, int32 depth) Image::Image(int32 width, int32 height, int32 depth)
{ {
this->flags = 0; this->flags = 0;
this->width = width; this->width = width;
this->height = height; this->height = height;
this->depth = depth; this->depth = depth;
this->stride = 0; this->stride = 0;
this->pixels = NULL; this->pixels = NULL;
this->palette = NULL; this->palette = NULL;
} }
Image::~Image(void) Image::~Image(void)
{ {
this->free(); this->free();
} }
void void
Image::allocate(void) Image::allocate(void)
{ {
if(this->pixels == NULL){ if(this->pixels == NULL){
this->stride = this->width*(this->depth==4 ? 1 : this->depth/8); this->stride = this->width*(this->depth==4 ? 1 : this->depth/8);
this->pixels = new uint8[this->stride*this->height]; this->pixels = new uint8[this->stride*this->height];
this->flags |= 1; this->flags |= 1;
} }
if(this->palette == NULL){ if(this->palette == NULL){
if(this->depth == 4 || this->depth == 8) if(this->depth == 4 || this->depth == 8)
this->palette = new uint8[(this->depth==4? 16 : 256)*4]; this->palette = new uint8[(this->depth==4? 16 : 256)*4];
this->flags |= 2; this->flags |= 2;
} }
} }
void void
Image::free(void) Image::free(void)
{ {
if(this->flags&1) if(this->flags&1)
delete[] this->pixels; delete[] this->pixels;
if(this->flags&2) if(this->flags&2)
delete[] this->palette; delete[] this->palette;
} }
void void
Image::setPixels(uint8 *pixels) Image::setPixels(uint8 *pixels)
{ {
this->pixels = pixels; this->pixels = pixels;
this->flags |= 1; this->flags |= 1;
} }
void void
Image::setPalette(uint8 *palette) Image::setPalette(uint8 *palette)
{ {
this->palette = palette; this->palette = palette;
this->flags |= 2; this->flags |= 2;
} }
static char *searchPaths = NULL; static char *searchPaths = NULL;
int numSearchPaths = 0; int numSearchPaths = 0;
void void
Image::setSearchPath(const char *path) Image::setSearchPath(const char *path)
{ {
char *p, *end; char *p, *end;
::free(searchPaths); ::free(searchPaths);
numSearchPaths = 0; numSearchPaths = 0;
if(path) if(path)
searchPaths = p = strdup(path); searchPaths = p = strdup(path);
else{ else{
searchPaths = NULL; searchPaths = NULL;
return; return;
} }
while(p && *p){ while(p && *p){
end = strchr(p, ';'); end = strchr(p, ';');
if(end) if(end)
*end++ = '\0'; *end++ = '\0';
numSearchPaths++; numSearchPaths++;
p = end; p = end;
} }
} }
void void
Image::printSearchPath(void) Image::printSearchPath(void)
{ {
char *p = searchPaths; char *p = searchPaths;
for(int i = 0; i < numSearchPaths; i++){ for(int i = 0; i < numSearchPaths; i++){
printf("%s\n", p); printf("%s\n", p);
p += strlen(p) + 1; p += strlen(p) + 1;
} }
} }
char* char*
Image::getFilename(const char *name) Image::getFilename(const char *name)
{ {
FILE *f; FILE *f;
char *s, *p = searchPaths; char *s, *p = searchPaths;
int len = strlen(name)+1; int len = strlen(name)+1;
if(numSearchPaths == 0){ if(numSearchPaths == 0){
f = fopen(name, "r"); f = fopen(name, "r");
if(f){ if(f){
fclose(f); fclose(f);
printf("found %s\n", name); printf("found %s\n", name);
return strdup(name); return strdup(name);
} }
return NULL; return NULL;
}else }else
for(int i = 0; i < numSearchPaths; i++){ for(int i = 0; i < numSearchPaths; i++){
s = (char*)malloc(strlen(p)+len); s = (char*)malloc(strlen(p)+len);
strcpy(s, p); strcpy(s, p);
strcat(s, name); strcat(s, name);
f = fopen(s, "r"); f = fopen(s, "r");
if(f){ if(f){
fclose(f); fclose(f);
printf("found %s\n", name); printf("found %s\n", name);
return s; return s;
} }
::free(s); ::free(s);
p += strlen(p) + 1; p += strlen(p) + 1;
} }
return NULL; return NULL;
} }
// //
// TGA I/O // TGA I/O
// //
#ifndef RW_PS2 // TODO: fuck pakced structs
#pragma pack(push) #ifndef RW_PS2
#pragma pack(1) #pragma pack(push)
#define PACKED_STRUCT #pragma pack(1)
#else #define PACKED_STRUCT
#define PACKED_STRUCT __attribute__((__packed__)) #else
#endif #define PACKED_STRUCT __attribute__((__packed__))
struct PACKED_STRUCT TGAHeader #endif
{ struct PACKED_STRUCT TGAHeader
int8 IDlen; {
int8 colorMapType; int8 IDlen;
int8 imageType; int8 colorMapType;
int16 colorMapOrigin; int8 imageType;
int16 colorMapLength; int16 colorMapOrigin;
int8 colorMapDepth; int16 colorMapLength;
int16 xOrigin, yOrigin; int8 colorMapDepth;
int16 width, height; int16 xOrigin, yOrigin;
uint8 depth; int16 width, height;
uint8 descriptor; uint8 depth;
}; uint8 descriptor;
#ifndef RW_PS2 };
#pragma pack(push) #ifndef RW_PS2
#endif #pragma pack(push)
#endif
Image*
readTGA(const char *afilename) Image*
{ readTGA(const char *afilename)
TGAHeader header; {
Image *image; TGAHeader header;
char *filename; Image *image;
int depth = 0, palDepth = 0; char *filename;
filename = Image::getFilename(afilename); int depth = 0, palDepth = 0;
if(filename == NULL) filename = Image::getFilename(afilename);
return NULL; if(filename == NULL)
uint32 length; return NULL;
uint8 *data = getFileContents(filename, &length); uint32 length;
assert(data != NULL); uint8 *data = getFileContents(filename, &length);
free(filename); assert(data != NULL);
StreamMemory file; free(filename);
file.open(data, length); StreamMemory file;
file.read(&header, sizeof(header)); file.open(data, length);
file.read(&header, sizeof(header));
assert(header.imageType == 1 || header.imageType == 2);
file.seek(header.IDlen); assert(header.imageType == 1 || header.imageType == 2);
if(header.colorMapType){ file.seek(header.IDlen);
assert(header.colorMapOrigin == 0); if(header.colorMapType){
depth = (header.colorMapLength <= 16) ? 4 : 8; assert(header.colorMapOrigin == 0);
palDepth = header.colorMapDepth; depth = (header.colorMapLength <= 16) ? 4 : 8;
assert(palDepth == 24 || palDepth == 32); palDepth = header.colorMapDepth;
}else{ assert(palDepth == 24 || palDepth == 32);
depth = header.depth; }else{
assert(depth == 24 || depth == 32); depth = header.depth;
} assert(depth == 24 || depth == 32);
}
image = new Image(header.width, header.height, depth);
image->allocate(); image = new Image(header.width, header.height, depth);
uint8 *palette = header.colorMapType ? image->palette : NULL; image->allocate();
uint8 (*color)[4] = NULL; uint8 *palette = header.colorMapType ? image->palette : NULL;
if(palette){ uint8 (*color)[4] = NULL;
int maxlen = depth == 4 ? 16 : 256; if(palette){
color = (uint8(*)[4])palette; int maxlen = depth == 4 ? 16 : 256;
int i; color = (uint8(*)[4])palette;
for(i = 0; i < header.colorMapLength; i++){ int i;
color[i][2] = file.readU8(); for(i = 0; i < header.colorMapLength; i++){
color[i][1] = file.readU8(); color[i][2] = file.readU8();
color[i][0] = file.readU8(); color[i][1] = file.readU8();
color[i][3] = 0xFF; color[i][0] = file.readU8();
if(palDepth == 32) color[i][3] = 0xFF;
color[i][3] = file.readU8(); if(palDepth == 32)
} color[i][3] = file.readU8();
for(; i < maxlen; i++){ }
color[i][0] = color[i][1] = color[i][2] = 0; for(; i < maxlen; i++){
color[i][3] = 0xFF; color[i][0] = color[i][1] = color[i][2] = 0;
} color[i][3] = 0xFF;
} }
}
uint8 *pixels = image->pixels;
if(!(header.descriptor & 0x20)) uint8 *pixels = image->pixels;
pixels += (image->height-1)*image->stride; if(!(header.descriptor & 0x20))
for(int y = 0; y < image->height; y++){ pixels += (image->height-1)*image->stride;
uint8 *line = pixels; for(int y = 0; y < image->height; y++){
for(int x = 0; x < image->width; x++){ uint8 *line = pixels;
if(palette) for(int x = 0; x < image->width; x++){
*line++ = file.readU8(); if(palette)
else{ *line++ = file.readU8();
line[2] = file.readU8(); else{
line[1] = file.readU8(); line[2] = file.readU8();
line[0] = file.readU8(); line[1] = file.readU8();
line += 3; line[0] = file.readU8();
if(depth == 32) line += 3;
*line++ = file.readU8(); if(depth == 32)
} *line++ = file.readU8();
} }
pixels += (header.descriptor&0x20) ? }
image->stride : -image->stride; pixels += (header.descriptor&0x20) ?
} image->stride : -image->stride;
}
file.close();
delete[] data; file.close();
return image; delete[] data;
} return image;
}
void
writeTGA(Image *image, const char *filename) void
{ writeTGA(Image *image, const char *filename)
TGAHeader header; {
StreamFile file; TGAHeader header;
assert(file.open(filename, "wb")); StreamFile file;
header.IDlen = 0; assert(file.open(filename, "wb"));
header.imageType = image->palette != NULL ? 1 : 2; header.IDlen = 0;
header.colorMapType = image->palette != NULL; header.imageType = image->palette != NULL ? 1 : 2;
header.colorMapOrigin = 0; header.colorMapType = image->palette != NULL;
header.colorMapLength = image->depth == 4 ? 16 : header.colorMapOrigin = 0;
image->depth == 8 ? 256 : 0; header.colorMapLength = image->depth == 4 ? 16 :
header.colorMapDepth = image->palette ? 32 : 0; image->depth == 8 ? 256 : 0;
header.xOrigin = 0; header.colorMapDepth = image->palette ? 32 : 0;
header.yOrigin = 0; header.xOrigin = 0;
header.width = image->width; header.yOrigin = 0;
header.height = image->height; header.width = image->width;
header.depth = image->depth == 4 ? 8 : image->depth; header.height = image->height;
header.descriptor = 0x20 | (image->depth == 32 ? 8 : 0); header.depth = image->depth == 4 ? 8 : image->depth;
file.write(&header, sizeof(header)); 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 *pixels = image->pixels;
uint8 (*color)[4] = (uint8(*)[4])palette;; uint8 *palette = header.colorMapType ? image->palette : NULL;
if(palette) uint8 (*color)[4] = (uint8(*)[4])palette;;
for(int i = 0; i < header.colorMapLength; i++){ if(palette)
file.writeU8(color[i][2]); for(int i = 0; i < header.colorMapLength; i++){
file.writeU8(color[i][1]); file.writeU8(color[i][2]);
file.writeU8(color[i][0]); file.writeU8(color[i][1]);
file.writeU8(color[i][3]); file.writeU8(color[i][0]);
} file.writeU8(color[i][3]);
}
for(int y = 0; y < image->height; y++){
uint8 *line = pixels; for(int y = 0; y < image->height; y++){
for(int x = 0; x < image->width; x++){ uint8 *line = pixels;
if(palette) for(int x = 0; x < image->width; x++){
file.writeU8(*line++); if(palette)
else{ file.writeU8(*line++);
file.writeU8(line[2]); else{
file.writeU8(line[1]); file.writeU8(line[2]);
file.writeU8(line[0]); file.writeU8(line[1]);
line += 3; file.writeU8(line[0]);
if(image->depth == 32) line += 3;
file.writeU8(*line++); if(image->depth == 32)
} file.writeU8(*line++);
} }
pixels += image->stride; }
} pixels += image->stride;
file.close(); }
} file.close();
}
//
// Raster //
// // Raster
//
Raster::Raster(void)
{ Raster::Raster(void)
this->type = 0; {
this->width = this->height = this->depth = this->stride = 0; this->type = 0;
this->format = 0; this->width = this->height = this->depth = this->stride = 0;
this->texels = this->palette = NULL; this->format = 0;
this->constructPlugins(); this->texels = this->palette = NULL;
} this->constructPlugins();
}
Raster::~Raster(void)
{ Raster::~Raster(void)
this->destructPlugins(); {
delete[] this->texels; this->destructPlugins();
delete[] this->palette; delete[] this->texels;
} delete[] this->palette;
}
Raster*
Raster::createFromImage(Image *image) Raster*
{ Raster::createFromImage(Image *image)
Raster *raster = new Raster; {
raster->type = 4; Raster *raster = new Raster;
raster->width = image->width; raster->type = 4;
raster->stride = image->stride; raster->width = image->width;
raster->height = image->height; raster->stride = image->stride;
raster->depth = image->depth; raster->height = image->height;
raster->texels = raster->palette = NULL; raster->depth = image->depth;
if(raster->depth == 32) raster->texels = raster->palette = NULL;
raster->format = Raster::C8888; if(raster->depth == 32)
else if(raster->depth == 24) raster->format = Raster::C8888;
raster->format = Raster::C888; else if(raster->depth == 24)
else if(raster->depth == 16) raster->format = Raster::C888;
raster->format = Raster::C1555; else if(raster->depth == 16)
else if(raster->depth == 8) raster->format = Raster::C1555;
raster->format = Raster::PAL8 | Raster::C8888; else if(raster->depth == 8)
else if(raster->depth == 4) raster->format = Raster::PAL8 | Raster::C8888;
raster->format = Raster::PAL4 | Raster::C8888; else if(raster->depth == 4)
else{ raster->format = Raster::PAL4 | Raster::C8888;
delete raster; else{
return NULL; delete raster;
} return NULL;
raster->texels = new uint8[raster->stride*raster->height]; }
memcpy(raster->texels, image->pixels, raster->stride*raster->height); raster->texels = new uint8[raster->stride*raster->height];
if(image->palette){ memcpy(raster->texels, image->pixels, raster->stride*raster->height);
int size = raster->depth == 4 ? 16 : 256; if(image->palette){
raster->palette = new uint8[size*4]; int size = raster->depth == 4 ? 16 : 256;
memcpy(raster->palette, image->palette, size*4); raster->palette = new uint8[size*4];
} memcpy(raster->palette, image->palette, size*4);
return raster; }
} return raster;
}
}
}

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);