From fd017a69ef8ca221d12de8cce73e8d78c4c90450 Mon Sep 17 00:00:00 2001 From: Angelo Papenhoff Date: Sat, 27 Dec 2014 23:18:10 +0100 Subject: [PATCH] Added experimental PS2 target. Implemented a Stream class. --- Makefile.ps2 | 29 ++++++++++ dffwrite.cpp | 21 ++++--- src/clump.cpp | 51 +++++++++-------- src/geometry.cpp | 85 ++++++++++++++-------------- src/image.cpp | 24 ++++++-- src/ogl.cpp | 22 ++++---- src/plugins.cpp | 67 +++++++++++----------- src/ps2.cpp | 19 +++---- src/rwbase.cpp | 143 +++++++++++++++++++++++++++++++---------------- src/rwbase.h | 58 +++++++++++++------ src/rwobjects.h | 28 +++++----- src/rwogl.h | 4 +- src/rwplugin.h | 14 ++--- src/rwps2.h | 4 +- 14 files changed, 345 insertions(+), 224 deletions(-) create mode 100644 Makefile.ps2 diff --git a/Makefile.ps2 b/Makefile.ps2 new file mode 100644 index 0000000..328211b --- /dev/null +++ b/Makefile.ps2 @@ -0,0 +1,29 @@ +CXX=ee-g++ +# null, opengl +BUILD=ps2 + +# e.g. null -> -DRW_NULL +BUILDDEF:=$(shell echo $(BUILD) | tr a-z A-Z | sed 's/^/-DRW_/') +BUILDDIR=build-$(BUILD) +SRCDIR=src +SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, rwbase.cpp clump.cpp\ + geometry.cpp plugins.cpp ps2.cpp\ + ogl.cpp image.cpp) +OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC)) +DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(SRC)) +CFLAGS=-Wall -g $(BUILDDEF) #-Wno-parentheses #-Wconversion +LIB=librw-$(BUILD).a + +$(LIB): $(OBJ) + ar scr $@ $(OBJ) + +$(BUILDDIR)/%.o: $(SRCDIR)/%.cpp + $(CXX) $(CFLAGS) -c $< -o $@ + +$(BUILDDIR)/%.d: $(SRCDIR)/%.cpp + $(CXX) -MM -MT '$(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$<)' $(CFLAGS) $< > $@ + +clean: + rm -f $(BUILDDIR)/*.[od] + +-include $(DEP) diff --git a/dffwrite.cpp b/dffwrite.cpp index 39074cf..496daac 100644 --- a/dffwrite.cpp +++ b/dffwrite.cpp @@ -3,9 +3,10 @@ #include #include -#include -#include -#include +//#include +//#include +//#include +#include #include "rw.h" @@ -23,9 +24,11 @@ main(int argc, char *argv[]) registerMeshPlugin(); Rw::Clump *c; - ifstream in(argv[1], ios::binary); - Rw::FindChunk(in, Rw::ID_CLUMP, NULL, NULL); - c = Rw::Clump::streamRead(in); +// ifstream in(argv[1], ios::binary); + Rw::StreamFile in; + in.open(argv[1], "rb"); + Rw::FindChunk(&in, Rw::ID_CLUMP, NULL, NULL); + c = Rw::Clump::streamRead(&in); assert(c != NULL); in.close(); @@ -36,8 +39,10 @@ main(int argc, char *argv[]) // for(Rw::int32 i = 0; i < c->numAtomics; i++) // Rw::Gl::Instance(c->atomicList[i]); - ofstream out(argv[2], ios::binary); - c->streamWrite(out); +// ofstream out(argv[2], ios::binary); + Rw::StreamFile out; + out.open(argv[2], "wb"); + c->streamWrite(&out); out.close(); delete c; diff --git a/src/clump.cpp b/src/clump.cpp index 56ed30f..62d2375 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -3,8 +3,7 @@ #include #include -#include -#include +#include #include "rwbase.h" #include "rwplugin.h" @@ -145,14 +144,15 @@ Clump::~Clump(void) } Clump* -Clump::streamRead(istream &stream) +Clump::streamRead(Stream *stream) { uint32 length, version; int32 buf[3]; Clump *clump; +printf("- before chunk: %X\n", stream->tell()); assert(FindChunk(stream, ID_STRUCT, &length, &version)); clump = new Clump; - stream.read((char*)buf, length); + stream->read(buf, length); clump->numAtomics = buf[0]; clump->numLights = 0; clump->numCameras = 0; @@ -161,17 +161,19 @@ Clump::streamRead(istream &stream) clump->numCameras = buf[2]; } +printf("- frame list: %X\n", stream->tell()); // Frame list Frame **frameList; int32 numFrames; clump->frameListStreamRead(stream, &frameList, &numFrames); clump->parent = (void*)frameList[0]; +printf("- geometry list: %X\n", stream->tell()); // Geometry list int32 numGeometries = 0; assert(FindChunk(stream, ID_GEOMETRYLIST, NULL, NULL)); assert(FindChunk(stream, ID_STRUCT, NULL, NULL)); - numGeometries = readInt32(stream); + numGeometries = stream->readI32(); Geometry **geometryList = 0; if(numGeometries) geometryList = new Geometry*[numGeometries]; @@ -180,6 +182,7 @@ Clump::streamRead(istream &stream) geometryList[i] = Geometry::streamRead(stream); } +printf("- atomics: %X\n", stream->tell()); // Atomics if(clump->numAtomics) clump->atomicList = new Atomic*[clump->numAtomics]; @@ -196,7 +199,7 @@ Clump::streamRead(istream &stream) for(int32 i = 0; i < clump->numLights; i++){ int32 frm; assert(FindChunk(stream, ID_STRUCT, NULL, NULL)); - frm = readInt32(stream); + frm = stream->readI32(); assert(FindChunk(stream, ID_LIGHT, NULL, NULL)); clump->lightList[i] = Light::streamRead(stream); clump->lightList[i]->frame = frameList[frm]; @@ -210,14 +213,14 @@ Clump::streamRead(istream &stream) } bool -Clump::streamWrite(ostream &stream) +Clump::streamWrite(Stream *stream) { int size = this->streamGetSize(); WriteChunkHeader(stream, ID_CLUMP, size); int buf[3] = { this->numAtomics, this->numLights, this->numCameras }; size = Version >= 0x33000 ? 12 : 4; WriteChunkHeader(stream, ID_STRUCT, size); - stream.write((char*)buf, size); + stream->write(buf, size); int32 numFrames = ((Frame*)this->parent)->count(); Frame **flist = new Frame*[numFrames]; @@ -230,7 +233,7 @@ Clump::streamWrite(ostream &stream) size += 12 + this->atomicList[i]->geometry->streamGetSize(); WriteChunkHeader(stream, ID_GEOMETRYLIST, size); WriteChunkHeader(stream, ID_STRUCT, 4); - writeInt32(this->numAtomics, stream); // same as numGeometries + stream->writeI32(this->numAtomics); // same as numGeometries for(int32 i = 0; i < this->numAtomics; i++) this->atomicList[i]->geometry->streamWrite(stream); @@ -243,7 +246,7 @@ Clump::streamWrite(ostream &stream) if(frm < 0) return false; WriteChunkHeader(stream, ID_STRUCT, 4); - writeInt32(frm, stream); + stream->writeI32(frm); l->streamWrite(stream); } @@ -294,18 +297,18 @@ Clump::streamGetSize(void) void -Clump::frameListStreamRead(istream &stream, Frame ***flp, int32 *nf) +Clump::frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf) { FrameStreamData buf; int32 numFrames = 0; assert(FindChunk(stream, ID_FRAMELIST, NULL, NULL)); assert(FindChunk(stream, ID_STRUCT, NULL, NULL)); - numFrames = readInt32(stream); + numFrames = stream->readI32(); Frame **frameList = new Frame*[numFrames]; for(int32 i = 0; i < numFrames; i++){ Frame *f; frameList[i] = f = new Frame; - stream.read((char*)&buf, sizeof(buf)); + stream->read(&buf, sizeof(buf)); f->matrix[0] = buf.mat[0]; f->matrix[1] = buf.mat[1]; f->matrix[2] = buf.mat[2]; @@ -333,7 +336,7 @@ Clump::frameListStreamRead(istream &stream, Frame ***flp, int32 *nf) } void -Clump::frameListStreamWrite(ostream &stream, Frame **frameList, int32 numFrames) +Clump::frameListStreamWrite(Stream *stream, Frame **frameList, int32 numFrames) { FrameStreamData buf; @@ -345,7 +348,7 @@ Clump::frameListStreamWrite(ostream &stream, Frame **frameList, int32 numFrames) WriteChunkHeader(stream, ID_FRAMELIST, size); WriteChunkHeader(stream, ID_STRUCT, structsize); - writeUInt32(numFrames, stream); + stream->writeU32(numFrames); for(int32 i = 0; i < numFrames; i++){ Frame *f = frameList[i]; buf.mat[0] = f->matrix[0]; @@ -362,7 +365,7 @@ Clump::frameListStreamWrite(ostream &stream, Frame **frameList, int32 numFrames) buf.pos[2] = f->matrix[14]; buf.parent = findPointer((void*)f, (void**)frameList,numFrames); buf.matflag = f->matflag; - stream.write((char*)&buf, sizeof(buf)); + stream->write(&buf, sizeof(buf)); } for(int32 i = 0; i < numFrames; i++) frameList[i]->streamWritePlugins(stream); @@ -389,12 +392,12 @@ Atomic::~Atomic(void) } Atomic* -Atomic::streamReadClump(istream &stream, +Atomic::streamReadClump(Stream *stream, Frame **frameList, Geometry **geometryList) { int32 buf[4]; assert(FindChunk(stream, ID_STRUCT, NULL, NULL)); - stream.read((char*)buf, 16); + stream->read(buf, 16); Atomic *atomic = new Atomic; atomic->frame = frameList[buf[0]]; atomic->geometry = geometryList[buf[1]]; @@ -403,7 +406,7 @@ Atomic::streamReadClump(istream &stream, } bool -Atomic::streamWriteClump(ostream &stream, Frame **frameList, int32 numFrames) +Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames) { int32 buf[4] = { 0, 0, 5, 0 }; Clump *c = this->clump; @@ -420,7 +423,7 @@ Atomic::streamWriteClump(ostream &stream, Frame **frameList, int32 numFrames) return false; foundgeo: - stream.write((char*)buf, sizeof(buf)); + stream->write(buf, sizeof(buf)); this->streamWritePlugins(stream); return true; } @@ -459,12 +462,12 @@ struct LightChunkData }; Light* -Light::streamRead(istream &stream) +Light::streamRead(Stream *stream) { LightChunkData buf; assert(FindChunk(stream, ID_STRUCT, NULL, NULL)); Light *light = new Light; - stream.read((char*)&buf, sizeof(LightChunkData)); + stream->read(&buf, sizeof(LightChunkData)); light->radius = buf.radius; light->color[0] = buf.red; light->color[1] = buf.green; @@ -479,7 +482,7 @@ Light::streamRead(istream &stream) } bool -Light::streamWrite(ostream &stream) +Light::streamWrite(Stream *stream) { LightChunkData buf; WriteChunkHeader(stream, ID_LIGHT, this->streamGetSize()); @@ -491,7 +494,7 @@ Light::streamWrite(ostream &stream) buf.minusCosAngle = this->minusCosAngle; buf.flags = this->flags; buf.type = this->subType; - stream.write((char*)&buf, sizeof(LightChunkData)); + stream->write(&buf, sizeof(LightChunkData)); this->streamWritePlugins(stream); return true; diff --git a/src/geometry.cpp b/src/geometry.cpp index 4416d36..d4d3525 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -3,8 +3,7 @@ #include #include -#include -#include +#include #include "rwbase.h" #include "rwplugin.h" @@ -99,44 +98,44 @@ struct GeoStreamData }; Geometry* -Geometry::streamRead(istream &stream) +Geometry::streamRead(Stream *stream) { uint32 version; GeoStreamData buf; assert(FindChunk(stream, ID_STRUCT, NULL, &version)); - stream.read((char*)&buf, sizeof(buf)); + stream->read(&buf, sizeof(buf)); Geometry *geo = new Geometry(buf.numVertices, buf.numTriangles, buf.flags); geo->addMorphTargets(buf.numMorphTargets-1); // skip surface properties if(version < 0x34000) - stream.seekg(12, ios::cur); + stream->seek(12); if(!(geo->geoflags & NATIVE)){ if(geo->geoflags & PRELIT) - stream.read((char*)geo->colors, 4*geo->numVertices); + stream->read(geo->colors, 4*geo->numVertices); for(int32 i = 0; i < geo->numTexCoordSets; i++) - stream.read((char*)geo->texCoords[i], + stream->read(geo->texCoords[i], 2*geo->numVertices*4); - stream.read((char*)geo->triangles, 4*geo->numTriangles*2); + stream->read(geo->triangles, 4*geo->numTriangles*2); } for(int32 i = 0; i < geo->numMorphTargets; i++){ MorphTarget *m = &geo->morphTargets[i]; - stream.read((char*)m->boundingSphere, 4*4); - int32 hasVertices = readInt32(stream); - int32 hasNormals = readInt32(stream); + stream->read(m->boundingSphere, 4*4); + int32 hasVertices = stream->readI32(); + int32 hasNormals = stream->readI32(); if(hasVertices) - stream.read((char*)m->vertices, 3*geo->numVertices*4); + stream->read(m->vertices, 3*geo->numVertices*4); if(hasNormals) - stream.read((char*)m->normals, 3*geo->numVertices*4); + stream->read(m->normals, 3*geo->numVertices*4); } assert(FindChunk(stream, ID_MATLIST, NULL, NULL)); assert(FindChunk(stream, ID_STRUCT, NULL, NULL)); - geo->numMaterials = readInt32(stream); + geo->numMaterials = stream->readI32(); geo->materialList = new Material*[geo->numMaterials]; - stream.seekg(geo->numMaterials*4, ios::cur); // unused (-1) + stream->seek(geo->numMaterials*4); // unused (-1) for(int32 i = 0; i < geo->numMaterials; i++){ assert(FindChunk(stream, ID_MATERIAL, NULL, NULL)); geo->materialList[i] = Material::streamRead(stream); @@ -175,7 +174,7 @@ geoStructSize(Geometry *geo) } bool -Geometry::streamWrite(ostream &stream) +Geometry::streamWrite(Stream *stream) { GeoStreamData buf; uint32 size; @@ -188,34 +187,34 @@ Geometry::streamWrite(ostream &stream) buf.numTriangles = this->numTriangles; buf.numVertices = this->numVertices; buf.numMorphTargets = this->numMorphTargets; - stream.write((char*)&buf, sizeof(buf)); + stream->write(&buf, sizeof(buf)); if(Version < 0x34000) - stream.write((char*)fbuf, sizeof(fbuf)); + stream->write(fbuf, sizeof(fbuf)); if(!(this->geoflags & NATIVE)){ if(this->geoflags & PRELIT) - stream.write((char*)this->colors, 4*this->numVertices); + stream->write(this->colors, 4*this->numVertices); for(int32 i = 0; i < this->numTexCoordSets; i++) - stream.write((char*)this->texCoords[i], + stream->write(this->texCoords[i], 2*this->numVertices*4); - stream.write((char*)this->triangles, 4*this->numTriangles*2); + stream->write(this->triangles, 4*this->numTriangles*2); } for(int32 i = 0; i < this->numMorphTargets; i++){ MorphTarget *m = &this->morphTargets[i]; - stream.write((char*)m->boundingSphere, 4*4); + stream->write(m->boundingSphere, 4*4); if(!(this->geoflags & NATIVE)){ - writeInt32(m->vertices != NULL, stream); - writeInt32(m->normals != NULL, stream); + stream->writeI32(m->vertices != NULL); + stream->writeI32(m->normals != NULL); if(m->vertices) - stream.write((char*)m->vertices, + stream->write(m->vertices, 3*this->numVertices*4); if(m->normals) - stream.write((char*)m->normals, + stream->write(m->normals, 3*this->numVertices*4); }else{ - writeInt32(0, stream); - writeInt32(0, stream); + stream->writeI32(0); + stream->writeI32(0); } } @@ -224,9 +223,9 @@ Geometry::streamWrite(ostream &stream) size += 4 + 12 + this->materialList[i]->streamGetSize(); WriteChunkHeader(stream, ID_MATLIST, size); WriteChunkHeader(stream, ID_STRUCT, 4 + this->numMaterials*4); - writeInt32(this->numMaterials, stream); + stream->writeI32(this->numMaterials); for(int32 i = 0; i < this->numMaterials; i++) - writeInt32(-1, stream); + stream->writeI32(-1); for(int32 i = 0; i < this->numMaterials; i++) this->materialList[i]->streamWrite(stream); @@ -321,12 +320,12 @@ struct MatStreamData }; Material* -Material::streamRead(istream &stream) +Material::streamRead(Stream *stream) { uint32 length; MatStreamData buf; assert(FindChunk(stream, ID_STRUCT, NULL, NULL)); - stream.read((char*)&buf, sizeof(buf)); + stream->read(&buf, sizeof(buf)); Material *mat = new Material; mat->color[0] = buf.color[0]; mat->color[1] = buf.color[1]; @@ -347,7 +346,7 @@ Material::streamRead(istream &stream) } bool -Material::streamWrite(ostream &stream) +Material::streamWrite(Stream *stream) { MatStreamData buf; @@ -364,7 +363,7 @@ Material::streamWrite(ostream &stream) buf.flags = 0; buf.unused = 0; buf.textured = this->texture != NULL; - stream.write((char*)&buf, sizeof(buf)); + stream->write(&buf, sizeof(buf)); if(this->texture) this->texture->streamWrite(stream); @@ -409,19 +408,19 @@ Texture::decRef(void) } Texture* -Texture::streamRead(istream &stream) +Texture::streamRead(Stream *stream) { uint32 length; assert(FindChunk(stream, ID_STRUCT, NULL, NULL)); Texture *tex = new Texture; - tex->filterAddressing = readUInt16(stream); - stream.seekg(2, ios::cur); + tex->filterAddressing = stream->readU16(); + stream->seek(2); assert(FindChunk(stream, ID_STRING, &length, NULL)); - stream.read(tex->name, length); + stream->read(tex->name, length); assert(FindChunk(stream, ID_STRING, &length, NULL)); - stream.read(tex->mask, length); + stream->read(tex->mask, length); tex->streamReadPlugins(stream); @@ -429,25 +428,25 @@ Texture::streamRead(istream &stream) } bool -Texture::streamWrite(ostream &stream) +Texture::streamWrite(Stream *stream) { int size; WriteChunkHeader(stream, ID_TEXTURE, this->streamGetSize()); WriteChunkHeader(stream, ID_STRUCT, 4); - writeUInt32(this->filterAddressing, stream); + stream->writeU32(this->filterAddressing); // TODO: length can't be > 32 size = strlen(this->name)+3 & ~3; if(size < 4) size = 4; WriteChunkHeader(stream, ID_STRING, size); - stream.write(this->name, size); + stream->write(this->name, size); size = strlen(this->mask)+3 & ~3; if(size < 4) size = 4; WriteChunkHeader(stream, ID_STRING, size); - stream.write(this->mask, size); + stream->write(this->mask, size); this->streamWritePlugins(stream); return true; diff --git a/src/image.cpp b/src/image.cpp index 31c4457..63e2a5b 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -14,6 +14,22 @@ using namespace std; namespace Rw { +uint8 +readUInt8(istream &rw) +{ + uint8 tmp; + rw.read((char*)&tmp, sizeof(uint8)); + return tmp; +} + +uint32 +writeUInt8(uint8 tmp, ostream &rw) +{ + rw.write((char*)&tmp, sizeof(uint8)); + return sizeof(uint8); +} + + Image::Image(int32 width, int32 height, int32 depth) { this->flags = 0; @@ -72,9 +88,9 @@ Image::setPalette(uint8 *palette) // TGA I/O // -#pragma pack(push) -#pragma pack(1) -struct TGAHeader +//#pragma pack(push) +//#pragma pack(1) +struct __attribute__((__packed__)) TGAHeader { int8 IDlen; int8 colorMapType; @@ -87,7 +103,7 @@ struct TGAHeader uint8 depth; uint8 descriptor; }; -#pragma pack(push) +//#pragma pack(push) Image* readTGA(const char *filename) diff --git a/src/ogl.cpp b/src/ogl.cpp index 74bcb7b..b6e22a9 100644 --- a/src/ogl.cpp +++ b/src/ogl.cpp @@ -3,15 +3,16 @@ #include #include -#include -#include +#include #include "rwbase.h" #include "rwplugin.h" #include "rwobjects.h" #include "rwogl.h" +#ifdef RW_OPENGL #include +#endif using namespace std; @@ -66,7 +67,7 @@ DestroyNativeData(void *object, int32, int32) } void -ReadNativeData(istream &stream, int32, void *object, int32, int32) +ReadNativeData(Stream *stream, int32, void *object, int32, int32) { Geometry *geometry = (Geometry*)object; InstanceDataHeader *header = new InstanceDataHeader; @@ -74,26 +75,25 @@ ReadNativeData(istream &stream, int32, void *object, int32, int32) header->platform = PLATFORM_OGL; header->vbo = 0; header->ibo = 0; - header->numAttribs = readUInt32(stream); + header->numAttribs = stream->readU32(); header->attribs = new AttribDesc[header->numAttribs]; - stream.read((char*)header->attribs, + stream->read(header->attribs, header->numAttribs*sizeof(AttribDesc)); header->dataSize = header->attribs[0].stride*geometry->numVertices; header->data = new uint8[header->dataSize]; - stream.read((char*)header->data, header->dataSize); + stream->read(header->data, header->dataSize); } void -WriteNativeData(ostream &stream, int32, void *object, int32, int32) +WriteNativeData(Stream *stream, int32, void *object, int32, int32) { Geometry *geometry = (Geometry*)object; assert(geometry->instData->platform == PLATFORM_OGL); InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - writeUInt32(header->numAttribs, stream); - stream.write((char*)header->attribs, - header->numAttribs*sizeof(AttribDesc)); - stream.write((char*)header->data, header->dataSize); + stream->writeU32(header->numAttribs); + stream->write(header->attribs, header->numAttribs*sizeof(AttribDesc)); + stream->write(header->data, header->dataSize); } int32 diff --git a/src/plugins.cpp b/src/plugins.cpp index de66520..5f47e55 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -3,8 +3,9 @@ #include #include -#include -#include +//#include +//#include +#include #include "rwbase.h" #include "rwplugin.h" @@ -45,18 +46,18 @@ destroyNodeName(void *object, int32, int32) } static void -readNodeName(istream &stream, int32 len, void *object, int32 offset, int32) +readNodeName(Stream *stream, int32 len, void *object, int32 offset, int32) { char *name = PLUGINOFFSET(char, object, offset); - stream.read(name, len); + stream->read(name, len); name[len] = '\0'; } static void -writeNodeName(ostream &stream, int32 len, void *object, int32 offset, int32) +writeNodeName(Stream *stream, int32 len, void *object, int32 offset, int32) { char *name = PLUGINOFFSET(char, object, offset); - stream.write(name, len); + stream->write(name, len); } static int32 @@ -86,12 +87,12 @@ registerNodeNamePlugin(void) // Mesh static void -readMesh(istream &stream, int32 len, void *object, int32, int32) +readMesh(Stream *stream, int32 len, void *object, int32, int32) { Geometry *geo = (Geometry*)object; int32 indbuf[256]; uint32 buf[3]; - stream.read((char*)buf, 12); + stream->read(buf, 12); geo->meshHeader = new MeshHeader; geo->meshHeader->flags = buf[0]; geo->meshHeader->numMeshes = buf[1]; @@ -100,7 +101,7 @@ readMesh(istream &stream, int32 len, void *object, int32, int32) Mesh *mesh = geo->meshHeader->mesh; bool hasData = len > 12+geo->meshHeader->numMeshes*8; for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){ - stream.read((char*)buf, 8); + stream->read(buf, 8); mesh->numIndices = buf[0]; mesh->material = geo->materialList[buf[1]]; mesh->indices = NULL; @@ -108,7 +109,7 @@ readMesh(istream &stream, int32 len, void *object, int32, int32) // OpenGL stores uint16 indices here if(hasData){ mesh->indices = new uint16[mesh->numIndices]; - stream.read((char*)mesh->indices, + stream->read(mesh->indices, mesh->numIndices*2); } }else{ @@ -117,7 +118,7 @@ readMesh(istream &stream, int32 len, void *object, int32, int32) int32 numIndices = mesh->numIndices; for(; numIndices > 0; numIndices -= 256){ int32 n = numIndices < 256 ? numIndices : 256; - stream.read((char*)indbuf, n*4); + stream->read(indbuf, n*4); for(int32 j = 0; j < n; j++) ind[j] = indbuf[j]; ind += n; @@ -128,7 +129,7 @@ readMesh(istream &stream, int32 len, void *object, int32, int32) } static void -writeMesh(ostream &stream, int32, void *object, int32, int32) +writeMesh(Stream *stream, int32, void *object, int32, int32) { Geometry *geo = (Geometry*)object; int32 indbuf[256]; @@ -136,18 +137,18 @@ writeMesh(ostream &stream, int32, void *object, int32, int32) buf[0] = geo->meshHeader->flags; buf[1] = geo->meshHeader->numMeshes; buf[2] = geo->meshHeader->totalIndices; - stream.write((char*)buf, 12); + stream->write(buf, 12); Mesh *mesh = geo->meshHeader->mesh; for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){ buf[0] = mesh->numIndices; buf[1] = findPointer((void*)mesh->material, (void**)geo->materialList, geo->numMaterials); - stream.write((char*)buf, 8); + stream->write(buf, 8); if(geo->geoflags & Geometry::NATIVE){ assert(geo->instData != NULL); if(geo->instData->platform == PLATFORM_OGL) - stream.write((char*)mesh->indices, + stream->write(mesh->indices, mesh->numIndices*2); }else{ uint16 *ind = mesh->indices; @@ -156,7 +157,7 @@ writeMesh(ostream &stream, int32, void *object, int32, int32) int32 n = numIndices < 256 ? numIndices : 256; for(int32 j = 0; j < n; j++) indbuf[j] = ind[j]; - stream.write((char*)indbuf, n*4); + stream->write(indbuf, n*4); ind += n; } } @@ -207,32 +208,32 @@ destroyNativeData(void *object, int32 offset, int32 size) } static void -readNativeData(istream &stream, int32 len, void *object, int32 o, int32 s) +readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s) { ChunkHeaderInfo header; uint32 libid; uint32 platform; // ugly hack to find out platform - stream.seekg(-4, ios::cur); - libid = readUInt32(stream); + stream->seek(-4); + libid = stream->readU32(); ReadChunkHeaderInfo(stream, &header); if(header.type == ID_STRUCT && LibraryIDPack(header.version, header.build) == libid){ // must be PS2 or Xbox - platform = readUInt32(stream); - stream.seekg(-16, ios::cur); + platform = stream->readU32(); + stream->seek(-16); if(platform == PLATFORM_PS2) ReadNativeDataPS2(stream, len, object, o, s); else if(platform == PLATFORM_XBOX) - stream.seekg(len, ios::cur); + stream->seek(len); }else{ - stream.seekg(-12, ios::cur); + stream->seek(-12); Gl::ReadNativeData(stream, len, object, o, s); } } static void -writeNativeData(ostream &stream, int32 len, void *object, int32 o, int32 s) +writeNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s) { Geometry *geometry = (Geometry*)object; if(geometry->instData == NULL) @@ -298,13 +299,13 @@ destroyBreakableModel(void *object, int32 offset, int32) } static void -readBreakableModel(istream &stream, int32, void *object, int32 o, int32) +readBreakableModel(Stream *stream, int32, void *object, int32 o, int32) { uint32 header[13]; - uint32 hasBreakable = readUInt32(stream); + uint32 hasBreakable = stream->readU32(); if(hasBreakable == 0) return; - stream.read((char*)header, 13*4); + stream->read(header, 13*4); uint32 size = header[1]*(12+8+4) + header[5]*(6+2) + header[8]*(32+32+12); uint8 *p = new uint8[sizeof(Breakable)+size]; @@ -315,7 +316,7 @@ readBreakableModel(istream &stream, int32, void *object, int32 o, int32) breakable->numFaces = header[5]; breakable->numMaterials = header[8]; p += sizeof(Breakable); - stream.read((char*)p, size); + stream->read(p, size); breakable->vertices = (float*)p; p += breakable->numVertices*12; breakable->texCoords = (float*)p; @@ -334,24 +335,24 @@ readBreakableModel(istream &stream, int32, void *object, int32 o, int32) } static void -writeBreakableModel(ostream &stream, int32, void *object, int32 o, int32) +writeBreakableModel(Stream *stream, int32, void *object, int32 o, int32) { uint32 header[13]; Breakable *breakable = *PLUGINOFFSET(Breakable*, object, o); uint8 *p = (uint8*)breakable; if(breakable == NULL){ - writeUInt32(0, stream); + stream->writeU32(0); return; } - writeUInt32(1, stream); + stream->writeU32(1); memset((char*)header, 0, 13*4); header[0] = breakable->position; header[1] = breakable->numVertices; header[5] = breakable->numFaces; header[8] = breakable->numMaterials; - stream.write((char*)header, 13*4); + stream->write(header, 13*4); p += sizeof(Breakable); - stream.write((char*)p, breakable->numVertices*(12+8+4) + + stream->write(p, breakable->numVertices*(12+8+4) + breakable->numFaces*(6+2) + breakable->numMaterials*(32+32+12)); } diff --git a/src/ps2.cpp b/src/ps2.cpp index f3617d8..c485508 100644 --- a/src/ps2.cpp +++ b/src/ps2.cpp @@ -3,8 +3,7 @@ #include #include -#include -#include +#include #include "rwbase.h" #include "rwplugin.h" @@ -30,11 +29,11 @@ DestroyNativeDataPS2(void *object, int32, int32) } void -ReadNativeDataPS2(istream &stream, int32, void *object, int32, int32) +ReadNativeDataPS2(Stream *stream, int32, void *object, int32, int32) { Geometry *geometry = (Geometry*)object; assert(FindChunk(stream, ID_STRUCT, NULL, NULL)); - assert(readUInt32(stream) == PLATFORM_PS2); + assert(stream->readU32() == PLATFORM_PS2); PS2InstanceDataHeader *header = new PS2InstanceDataHeader; geometry->instData = header; header->platform = PLATFORM_PS2; @@ -44,21 +43,21 @@ ReadNativeDataPS2(istream &stream, int32, void *object, int32, int32) for(uint32 i = 0; i < header->numMeshes; i++){ PS2InstanceData *instance = &header->instanceMeshes[i]; uint32 buf[2]; - stream.read((char*)buf, 8); + stream->read(buf, 8); instance->dataSize = buf[0]; instance->noRefChain = buf[1]; instance->data = new uint8[instance->dataSize]; - stream.read((char*)instance->data, instance->dataSize); + stream->read(instance->data, instance->dataSize); } } void -WriteNativeDataPS2(ostream &stream, int32 len, void *object, int32, int32) +WriteNativeDataPS2(Stream *stream, int32 len, void *object, int32, int32) { Geometry *geometry = (Geometry*)object; WriteChunkHeader(stream, ID_STRUCT, len-12); assert(geometry->instData->platform == PLATFORM_PS2); - writeUInt32(PLATFORM_PS2, stream); + stream->writeU32(PLATFORM_PS2); assert(geometry->instData != NULL); PS2InstanceDataHeader *header = (PS2InstanceDataHeader*)geometry->instData; @@ -67,8 +66,8 @@ WriteNativeDataPS2(ostream &stream, int32 len, void *object, int32, int32) uint32 buf[2]; buf[0] = instance->dataSize; buf[1] = instance->noRefChain; - stream.write((char*)buf, 8); - stream.write((char*)instance->data, instance->dataSize); + stream->write(buf, 8); + stream->write(instance->data, instance->dataSize); } } diff --git a/src/rwbase.cpp b/src/rwbase.cpp index 2fd5c2d..5c21f7a 100644 --- a/src/rwbase.cpp +++ b/src/rwbase.cpp @@ -2,8 +2,7 @@ #include #include -#include -#include +#include #include "rwbase.h" #include "rwplugin.h" @@ -15,123 +14,169 @@ namespace Rw { int Version = 0x36003; int Build = 0xFFFF; -uint32 -writeInt8(int8 tmp, ostream &rw) +int32 +Stream::writeI8(int8 val) { - rw.write((char*)&tmp, sizeof(int8)); - return sizeof(int8); + return write(&val, sizeof(int8)); } -uint32 -writeUInt8(uint8 tmp, ostream &rw) +int32 +Stream::writeU8(uint8 val) { - rw.write((char*)&tmp, sizeof(uint8)); - return sizeof(uint8); + return write(&val, sizeof(uint8)); } -uint32 -writeInt16(int16 tmp, ostream &rw) +int32 +Stream::writeI16(int16 val) { - rw.write((char*)&tmp, sizeof(int16)); - return sizeof(int16); + return write(&val, sizeof(int16)); } -uint32 -writeUInt16(uint16 tmp, ostream &rw) +int32 +Stream::writeU16(uint16 val) { - rw.write((char*)&tmp, sizeof(uint16)); - return sizeof(uint16); + return write(&val, sizeof(uint16)); } -uint32 -writeInt32(int32 tmp, ostream &rw) +int32 +Stream::writeI32(int32 val) { - rw.write((char*)&tmp, sizeof(int32)); - return sizeof(int32); + return write(&val, sizeof(int32)); } -uint32 -writeUInt32(uint32 tmp, ostream &rw) +int32 +Stream::writeU32(uint32 val) { - rw.write((char*)&tmp, sizeof(uint32)); - return sizeof(uint32); + return write(&val, sizeof(uint32)); } -uint32 -writeFloat32(float32 tmp, ostream &rw) +int32 +Stream::writeF32(float32 val) { - rw.write((char*)&tmp, sizeof(float32)); - return sizeof(float32); + return write(&val, sizeof(float32)); +} + +int8 +Stream::readI8(void) +{ + int8 tmp; + read(&tmp, sizeof(int8)); + return tmp; } uint8 -readUInt8(istream &rw) +Stream::readU8(void) { uint8 tmp; - rw.read((char*)&tmp, sizeof(uint8)); + read(&tmp, sizeof(uint8)); return tmp; } int16 -readInt16(istream &rw) +Stream::readI16(void) { int16 tmp; - rw.read((char*)&tmp, sizeof(int16)); + read(&tmp, sizeof(int16)); return tmp; } uint16 -readUInt16(istream &rw) +Stream::readU16(void) { uint16 tmp; - rw.read((char*)&tmp, sizeof(uint16)); + read(&tmp, sizeof(uint16)); return tmp; } int32 -readInt32(istream &rw) +Stream::readI32(void) { int32 tmp; - rw.read((char*)&tmp, sizeof(int32)); + read(&tmp, sizeof(int32)); return tmp; } uint32 -readUInt32(istream &rw) +Stream::readU32(void) { uint32 tmp; - rw.read((char*)&tmp, sizeof(uint32)); + read(&tmp, sizeof(uint32)); return tmp; } float32 -readFloat32(istream &rw) +Stream::readF32(void) { float32 tmp; - rw.read((char*)&tmp, sizeof(float32)); + read(&tmp, sizeof(float32)); return tmp; } + +StreamFile* +StreamFile::open(const char *path, const char *mode) +{ + this->file = fopen(path, mode); + return this->file ? this : NULL; +} + +void +StreamFile::close(void) +{ + fclose(this->file); +} + +uint32 +StreamFile::write(const void *data, uint32 length) +{ + return fwrite(data, length, 1, this->file); +} + +uint32 +StreamFile::read(void *data, uint32 length) +{ + printf("read %d bytes @ %x\n", length, this->tell()); + return fread(data, length, 1, this->file); +} + +void +StreamFile::seek(int32 offset, int32 whence) +{ + fseek(this->file, offset, whence); +} + +uint32 +StreamFile::tell(void) +{ + return ftell(this->file); +} + bool -WriteChunkHeader(ostream &s, int32 type, int32 size) +StreamFile::eof(void) +{ + return feof(this->file); +} + +bool +WriteChunkHeader(Stream *s, int32 type, int32 size) { struct { int32 type, size; uint32 id; } buf = { type, size, LibraryIDPack(Version, Build) }; - s.write((char*)&buf, 12); + s->write(&buf, 12); return true; } bool -ReadChunkHeaderInfo(istream &s, ChunkHeaderInfo *header) +ReadChunkHeaderInfo(Stream *s, ChunkHeaderInfo *header) { struct { int32 type, size; uint32 id; } buf; - s.read((char*)&buf, 12); - if(s.eof()) + s->read(&buf, 12); + if(s->eof()) return false; assert(header != NULL); header->type = buf.type; @@ -142,7 +187,7 @@ ReadChunkHeaderInfo(istream &s, ChunkHeaderInfo *header) } bool -FindChunk(istream &s, uint32 type, uint32 *length, uint32 *version) +FindChunk(Stream *s, uint32 type, uint32 *length, uint32 *version) { ChunkHeaderInfo header; while(ReadChunkHeaderInfo(s, &header)){ @@ -155,7 +200,7 @@ FindChunk(istream &s, uint32 type, uint32 *length, uint32 *version) *version = header.version; return true; } - s.seekg(header.length, ios::cur); + s->seek(header.length); } return false; } diff --git a/src/rwbase.h b/src/rwbase.h index a3b924e..d45bb5b 100644 --- a/src/rwbase.h +++ b/src/rwbase.h @@ -13,20 +13,43 @@ typedef int32 bool32; typedef uint8 byte; typedef uint32 uint; -uint32 writeInt8(int8 tmp, std::ostream &rw); -uint32 writeUInt8(uint8 tmp, std::ostream &rw); -uint32 writeInt16(int16 tmp, std::ostream &rw); -uint32 writeUInt16(uint16 tmp, std::ostream &rw); -uint32 writeInt32(int32 tmp, std::ostream &rw); -uint32 writeUInt32(uint32 tmp, std::ostream &rw); -uint32 writeFloat32(float32 tmp, std::ostream &rw); -int8 readInt8(std::istream &rw); -uint8 readUInt8(std::istream &rw); -int16 readInt16(std::istream &rw); -uint16 readUInt16(std::istream &rw); -int32 readInt32(std::istream &rw); -uint32 readUInt32(std::istream &rw); -float32 readFloat32(std::istream &rw); +class Stream +{ +public: + virtual void close(void) = 0; + virtual uint32 write(const void *data, uint32 length) = 0; + virtual uint32 read(void *data, uint32 length) = 0; + virtual void seek(int32 offset, int32 whence = 1) = 0; + virtual uint32 tell(void) = 0; + virtual bool eof(void) = 0; + int32 writeI8(int8 val); + int32 writeU8(uint8 val); + int32 writeI16(int16 val); + int32 writeU16(uint16 val); + int32 writeI32(int32 val); + int32 writeU32(uint32 val); + int32 writeF32(float32 val); + int8 readI8(void); + uint8 readU8(void); + int16 readI16(void); + uint16 readU16(void); + int32 readI32(void); + uint32 readU32(void); + float32 readF32(void); +}; + +class StreamFile : public Stream +{ + FILE *file; +public: + void close(void); + uint32 write(const void *data, uint32 length); + uint32 read(void *data, uint32 length); + void seek(int32 offset, int32 whence); + uint32 tell(void); + bool eof(void); + StreamFile *open(const char *path, const char *mode); +}; enum Platform { @@ -72,6 +95,7 @@ extern int Build; inline uint32 LibraryIDPack(int version, int build) { + // TODO: check version in if statement if(build){ version -= 0x30000; return (version&0xFFC0) << 14 | (version&0x3F) << 16 | @@ -108,9 +132,9 @@ struct ChunkHeaderInfo }; // TODO?: make these methods of ChunkHeaderInfo? -bool WriteChunkHeader(std::ostream &s, int32 type, int32 size); -bool ReadChunkHeaderInfo(std::istream &s, ChunkHeaderInfo *header); -bool FindChunk(std::istream &s, uint32 type, uint32 *length, uint32 *version); +bool WriteChunkHeader(Stream *s, int32 type, int32 size); +bool ReadChunkHeaderInfo(Stream *s, ChunkHeaderInfo *header); +bool FindChunk(Stream *s, uint32 type, uint32 *length, uint32 *version); int32 findPointer(void *p, void **list, int32 num); } diff --git a/src/rwobjects.h b/src/rwobjects.h index d91503e..016317e 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -38,8 +38,8 @@ struct Texture : PluginBase Texture(void); ~Texture(void); void decRef(void); - static Texture *streamRead(std::istream &stream); - bool streamWrite(std::ostream &stream); + static Texture *streamRead(Stream *stream); + bool streamWrite(Stream *stream); uint32 streamGetSize(void); enum FilterMode { @@ -69,8 +69,8 @@ struct Material : PluginBase Material(Material *m); void decRef(void); ~Material(void); - static Material *streamRead(std::istream &stream); - bool streamWrite(std::ostream &stream); + static Material *streamRead(Stream *stream); + bool streamWrite(Stream *stream); uint32 streamGetSize(void); }; @@ -128,8 +128,8 @@ struct Geometry : PluginBase, Object Geometry(int32 numVerts, int32 numTris, uint32 flags); void decRef(void); ~Geometry(void); - static Geometry *streamRead(std::istream &stream); - bool streamWrite(std::ostream &stream); + static Geometry *streamRead(Stream *stream); + bool streamWrite(Stream *stream); uint32 streamGetSize(void); void addMorphTargets(int32 n); @@ -183,8 +183,8 @@ struct Light : PluginBase, Object Light(void); Light(Light *l); ~Light(void); - static Light *streamRead(std::istream &stream); - bool streamWrite(std::ostream &stream); + static Light *streamRead(Stream *stream); + bool streamWrite(Stream *stream); uint32 streamGetSize(void); }; @@ -197,9 +197,9 @@ struct Atomic : PluginBase, Object Atomic(void); Atomic(Atomic *a); ~Atomic(void); - static Atomic *streamReadClump(std::istream &stream, + static Atomic *streamReadClump(Stream *stream, Frame **frameList, Geometry **geometryList); - bool streamWriteClump(std::ostream &stream, + bool streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames); uint32 streamGetSize(void); }; @@ -216,13 +216,13 @@ struct Clump : PluginBase, Object Clump(void); Clump(Clump *c); ~Clump(void); - static Clump *streamRead(std::istream &stream); - bool streamWrite(std::ostream &stream); + static Clump *streamRead(Stream *stream); + bool streamWrite(Stream *stream); uint32 streamGetSize(void); private: - void frameListStreamRead(std::istream &stream, Frame ***flp, int32 *nf); - void frameListStreamWrite(std::ostream &stream, Frame **flp, int32 nf); + void frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf); + void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf); }; } diff --git a/src/rwogl.h b/src/rwogl.h index 9b0918e..4b5a905 100644 --- a/src/rwogl.h +++ b/src/rwogl.h @@ -27,8 +27,8 @@ struct InstanceDataHeader : Rw::InstanceDataHeader }; void *DestroyNativeData(void *object, int32, int32); -void ReadNativeData(std::istream &stream, int32 len, void *object, int32, int32); -void WriteNativeData(std::ostream &stream, int32 len, void *object, int32, int32); +void ReadNativeData(Stream *stream, int32 len, void *object, int32, int32); +void WriteNativeData(Stream *stream, int32 len, void *object, int32, int32); int32 GetSizeNativeData(void *object, int32, int32); void Instance(Atomic *atomic); diff --git a/src/rwplugin.h b/src/rwplugin.h index 9831285..1605f94 100644 --- a/src/rwplugin.h +++ b/src/rwplugin.h @@ -6,8 +6,8 @@ namespace Rw { typedef void *(*Constructor)(void *object, int32 offset, int32 size); typedef void *(*Destructor)(void *object, int32 offset, int32 size); typedef void *(*CopyConstructor)(void *dst, void *src, int32 offset, int32 size); -typedef void (*StreamRead)(std::istream &stream, int32 length, void *object, int32 offset, int32 size); -typedef void (*StreamWrite)(std::ostream &stream, int32 length, void *object, int32 offset, int32 size); +typedef void (*StreamRead)(Stream *stream, int32 length, void *object, int32 offset, int32 size); +typedef void (*StreamWrite)(Stream *stream, int32 length, void *object, int32 offset, int32 size); typedef int32 (*StreamGetSize)(void *object, int32 offset, int32 size); struct Plugin @@ -34,8 +34,8 @@ struct PluginBase void constructPlugins(void); void destructPlugins(void); void copyPlugins(T *t); - void streamReadPlugins(std::istream &stream); - void streamWritePlugins(std::ostream &stream); + void streamReadPlugins(Stream *stream); + void streamWritePlugins(Stream *stream); int streamGetPluginSize(void); static int registerPlugin(int size, uint id, @@ -78,7 +78,7 @@ PluginBase::copyPlugins(T *t) } template void -PluginBase::streamReadPlugins(std::istream &stream) +PluginBase::streamReadPlugins(Stream *stream) { int32 length; Rw::ChunkHeaderInfo header; @@ -93,14 +93,14 @@ PluginBase::streamReadPlugins(std::istream &stream) (void*)this, p->offset, p->size); goto cont; } - stream.seekg(header.length, std::ios::cur); + stream->seek(header.length); cont: length -= header.length; } } template void -PluginBase::streamWritePlugins(std::ostream &stream) +PluginBase::streamWritePlugins(Stream *stream) { int size = this->streamGetPluginSize(); Rw::WriteChunkHeader(stream, Rw::ID_EXTENSION, size); diff --git a/src/rwps2.h b/src/rwps2.h index e3b2b8b..90543ea 100644 --- a/src/rwps2.h +++ b/src/rwps2.h @@ -15,8 +15,8 @@ struct PS2InstanceDataHeader : InstanceDataHeader }; void *DestroyNativeDataPS2(void *object, int32, int32); -void ReadNativeDataPS2(std::istream &stream, int32 len, void *object, int32, int32); -void WriteNativeDataPS2(std::ostream &stream, int32 len, void *object, int32, int32); +void ReadNativeDataPS2(Stream *stream, int32 len, void *object, int32, int32); +void WriteNativeDataPS2(Stream *stream, int32 len, void *object, int32, int32); int32 GetSizeNativeDataPS2(void *object, int32, int32); }