mirror of
				https://github.com/aap/librw.git
				synced 2025-11-04 00:41:59 +00:00 
			
		
		
		
	some changes
This commit is contained in:
		
							parent
							
								
									56e48f4d76
								
							
						
					
					
						commit
						d20a6c3d04
					
				@ -85,6 +85,7 @@ Global
 | 
				
			|||||||
		{2592ED29-F258-4949-AB45-7B873BF697F7}.Release|Win32.ActiveCfg = Release|Win32
 | 
							{2592ED29-F258-4949-AB45-7B873BF697F7}.Release|Win32.ActiveCfg = Release|Win32
 | 
				
			||||||
		{2592ED29-F258-4949-AB45-7B873BF697F7}.Release|Win32.Build.0 = Release|Win32
 | 
							{2592ED29-F258-4949-AB45-7B873BF697F7}.Release|Win32.Build.0 = Release|Win32
 | 
				
			||||||
		{2592ED29-F258-4949-AB45-7B873BF697F7}.Release|x64.ActiveCfg = Release|x64
 | 
							{2592ED29-F258-4949-AB45-7B873BF697F7}.Release|x64.ActiveCfg = Release|x64
 | 
				
			||||||
 | 
							{2592ED29-F258-4949-AB45-7B873BF697F7}.Release|x64.Build.0 = Release|x64
 | 
				
			||||||
		{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
 | 
							{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
 | 
				
			||||||
		{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug - null|x64.ActiveCfg = Debug - null|x64
 | 
							{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug - null|x64.ActiveCfg = Debug - null|x64
 | 
				
			||||||
		{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug|Win32.ActiveCfg = Debug|Win32
 | 
							{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug|Win32.ActiveCfg = Debug|Win32
 | 
				
			||||||
 | 
				
			|||||||
@ -149,6 +149,7 @@
 | 
				
			|||||||
      <Optimization>Disabled</Optimization>
 | 
					      <Optimization>Disabled</Optimization>
 | 
				
			||||||
      <SDLCheck>true</SDLCheck>
 | 
					      <SDLCheck>true</SDLCheck>
 | 
				
			||||||
      <PreprocessorDefinitions>_USING_V110_SDK71_;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
					      <PreprocessorDefinitions>_USING_V110_SDK71_;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
				
			||||||
 | 
					      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
 | 
				
			||||||
    </ClCompile>
 | 
					    </ClCompile>
 | 
				
			||||||
    <Link>
 | 
					    <Link>
 | 
				
			||||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
					      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
				
			||||||
 | 
				
			|||||||
@ -301,11 +301,6 @@ registerUVAnimInterpolator(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int32 uvAnimOffset;
 | 
					int32 uvAnimOffset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct UVAnim
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	AnimInterpolator *interp[8];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void*
 | 
					static void*
 | 
				
			||||||
createUVAnim(void *object, int32 offset, int32)
 | 
					createUVAnim(void *object, int32 offset, int32)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -367,7 +362,7 @@ makeDummyAnimation(const char *name)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
readUVAnim(Stream *stream, int32, void *object, int32 offset, int32)
 | 
					readUVAnim(Stream *stream, int32, void *object, int32 offset, int32)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	UVAnim *uvanim = PLUGINOFFSET(UVAnim, object, offset);	
 | 
						UVAnim *uvanim = PLUGINOFFSET(UVAnim, object, offset);
 | 
				
			||||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
						assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
				
			||||||
	char name[32];
 | 
						char name[32];
 | 
				
			||||||
	uint32 mask = stream->readI32();
 | 
						uint32 mask = stream->readI32();
 | 
				
			||||||
 | 
				
			|||||||
@ -88,16 +88,21 @@ Frame::destroyHierarchy(void)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Frame*
 | 
					Frame*
 | 
				
			||||||
Frame::addChild(Frame *child)
 | 
					Frame::addChild(Frame *child, bool32 append)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if(this->child == NULL)
 | 
						if(append){
 | 
				
			||||||
 | 
							if(this->child == NULL)
 | 
				
			||||||
 | 
								this->child = child;
 | 
				
			||||||
 | 
							else{
 | 
				
			||||||
 | 
								Frame *f;
 | 
				
			||||||
 | 
								for(f = this->child; f->next; f = f->next);
 | 
				
			||||||
 | 
								f->next = child;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							child->next = NULL;
 | 
				
			||||||
 | 
						}else{
 | 
				
			||||||
 | 
							child->next = this->child;
 | 
				
			||||||
		this->child = child;
 | 
							this->child = child;
 | 
				
			||||||
	else{
 | 
					 | 
				
			||||||
		Frame *f;
 | 
					 | 
				
			||||||
		for(f = this->child; f->next; f = f->next);
 | 
					 | 
				
			||||||
		f->next = child;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	child->next = NULL;
 | 
					 | 
				
			||||||
	child->object.parent = this;
 | 
						child->object.parent = this;
 | 
				
			||||||
	child->root = this->root;
 | 
						child->root = this->root;
 | 
				
			||||||
	return this;
 | 
						return this;
 | 
				
			||||||
@ -364,7 +369,8 @@ Clump::streamWrite(Stream *stream)
 | 
				
			|||||||
	writeChunkHeader(stream, ID_CLUMP, size);
 | 
						writeChunkHeader(stream, ID_CLUMP, size);
 | 
				
			||||||
	int32 numAtomics = this->countAtomics();
 | 
						int32 numAtomics = this->countAtomics();
 | 
				
			||||||
	int32 numLights = this->countLights();
 | 
						int32 numLights = this->countLights();
 | 
				
			||||||
	int buf[3] = { numAtomics, numLights, 0 };
 | 
						int32 numCameras = this->countCameras();
 | 
				
			||||||
 | 
						int buf[3] = { numAtomics, numLights, numCameras };
 | 
				
			||||||
	size = version > 0x33000 ? 12 : 4;
 | 
						size = version > 0x33000 ? 12 : 4;
 | 
				
			||||||
	writeChunkHeader(stream, ID_STRUCT, size);
 | 
						writeChunkHeader(stream, ID_STRUCT, size);
 | 
				
			||||||
	stream->write(buf, size);
 | 
						stream->write(buf, size);
 | 
				
			||||||
@ -372,7 +378,6 @@ Clump::streamWrite(Stream *stream)
 | 
				
			|||||||
	int32 numFrames = this->getFrame()->count();
 | 
						int32 numFrames = this->getFrame()->count();
 | 
				
			||||||
	Frame **flist = new Frame*[numFrames];
 | 
						Frame **flist = new Frame*[numFrames];
 | 
				
			||||||
	makeFrameList(this->getFrame(), flist);
 | 
						makeFrameList(this->getFrame(), flist);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	this->frameListStreamWrite(stream, flist, numFrames);
 | 
						this->frameListStreamWrite(stream, flist, numFrames);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(rw::version >= 0x30400){
 | 
						if(rw::version >= 0x30400){
 | 
				
			||||||
@ -550,6 +555,18 @@ Atomic::create(void)
 | 
				
			|||||||
	atomic->geometry = NULL;
 | 
						atomic->geometry = NULL;
 | 
				
			||||||
	atomic->pipeline = NULL;
 | 
						atomic->pipeline = NULL;
 | 
				
			||||||
	atomic->constructPlugins();
 | 
						atomic->constructPlugins();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// flags:
 | 
				
			||||||
 | 
						// rpATOMICCOLLISIONTEST = 0x01, /**<A generic collision flag to indicate
 | 
				
			||||||
 | 
						// 			* that the atomic should be considered
 | 
				
			||||||
 | 
						// 			* in collision tests.
 | 
				
			||||||
 | 
						// 			*/
 | 
				
			||||||
 | 
						// rpATOMICRENDER = 0x04,      /**<The atomic is rendered if it is
 | 
				
			||||||
 | 
						// 			* in the view frustum.
 | 
				
			||||||
 | 
						// 			*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// private flags:
 | 
				
			||||||
 | 
						// rpATOMICPRIVATEWORLDBOUNDDIRTY = 0x01
 | 
				
			||||||
	return atomic;
 | 
						return atomic;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -41,7 +41,7 @@ Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
 | 
				
			|||||||
			for(int32 i = 0; i < geo->numTexCoordSets; i++)
 | 
								for(int32 i = 0; i < geo->numTexCoordSets; i++)
 | 
				
			||||||
				geo->texCoords[i] =
 | 
									geo->texCoords[i] =
 | 
				
			||||||
					new float32[2*geo->numVertices];
 | 
										new float32[2*geo->numVertices];
 | 
				
			||||||
		geo->triangles = new uint16[4*geo->numTriangles];
 | 
							geo->triangles = new Triangle[geo->numTriangles];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	geo->morphTargets = new MorphTarget[1];
 | 
						geo->morphTargets = new MorphTarget[1];
 | 
				
			||||||
	MorphTarget *m = geo->morphTargets;
 | 
						MorphTarget *m = geo->morphTargets;
 | 
				
			||||||
@ -77,7 +77,7 @@ Geometry::destroy(void)
 | 
				
			|||||||
		for(int32 i = 0; i < this->numTexCoordSets; i++)
 | 
							for(int32 i = 0; i < this->numTexCoordSets; i++)
 | 
				
			||||||
			delete[] this->texCoords[i];
 | 
								delete[] this->texCoords[i];
 | 
				
			||||||
		delete[] this->triangles;
 | 
							delete[] this->triangles;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		for(int32 i = 0; i < this->numMorphTargets; i++){
 | 
							for(int32 i = 0; i < this->numMorphTargets; i++){
 | 
				
			||||||
			MorphTarget *m = &this->morphTargets[i];
 | 
								MorphTarget *m = &this->morphTargets[i];
 | 
				
			||||||
			delete[] m->vertices;
 | 
								delete[] m->vertices;
 | 
				
			||||||
@ -120,7 +120,14 @@ Geometry::streamRead(Stream *stream)
 | 
				
			|||||||
		for(int32 i = 0; i < geo->numTexCoordSets; i++)
 | 
							for(int32 i = 0; i < geo->numTexCoordSets; i++)
 | 
				
			||||||
			stream->read(geo->texCoords[i],
 | 
								stream->read(geo->texCoords[i],
 | 
				
			||||||
				    2*geo->numVertices*4);
 | 
									    2*geo->numVertices*4);
 | 
				
			||||||
		stream->read(geo->triangles, 4*geo->numTriangles*2);
 | 
							for(int32 i = 0; i < geo->numTriangles; i++){
 | 
				
			||||||
 | 
								uint32 tribuf[2];
 | 
				
			||||||
 | 
								stream->read(tribuf, 8);
 | 
				
			||||||
 | 
								geo->triangles[i].v[0]  = tribuf[0] >> 16;
 | 
				
			||||||
 | 
								geo->triangles[i].v[1]  = tribuf[0];
 | 
				
			||||||
 | 
								geo->triangles[i].v[2]  = tribuf[1] >> 16;
 | 
				
			||||||
 | 
								geo->triangles[i].matId = tribuf[1];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for(int32 i = 0; i < geo->numMorphTargets; i++){
 | 
						for(int32 i = 0; i < geo->numMorphTargets; i++){
 | 
				
			||||||
@ -200,7 +207,14 @@ Geometry::streamWrite(Stream *stream)
 | 
				
			|||||||
		for(int32 i = 0; i < this->numTexCoordSets; i++)
 | 
							for(int32 i = 0; i < this->numTexCoordSets; i++)
 | 
				
			||||||
			stream->write(this->texCoords[i],
 | 
								stream->write(this->texCoords[i],
 | 
				
			||||||
				    2*this->numVertices*4);
 | 
									    2*this->numVertices*4);
 | 
				
			||||||
		stream->write(this->triangles, 4*this->numTriangles*2);
 | 
							for(int32 i = 0; i < this->numTriangles; i++){
 | 
				
			||||||
 | 
								uint32 tribuf[2];
 | 
				
			||||||
 | 
								tribuf[0] = this->triangles[i].v[0] << 16 |
 | 
				
			||||||
 | 
								            this->triangles[i].v[1];
 | 
				
			||||||
 | 
								tribuf[1] = this->triangles[i].v[2] << 16 |
 | 
				
			||||||
 | 
								            this->triangles[i].matId;
 | 
				
			||||||
 | 
								stream->write(tribuf, 8);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for(int32 i = 0; i < this->numMorphTargets; i++){
 | 
						for(int32 i = 0; i < this->numMorphTargets; i++){
 | 
				
			||||||
@ -363,9 +377,9 @@ Geometry::generateTriangles(int8 *adc)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	delete[] this->triangles;
 | 
						delete[] this->triangles;
 | 
				
			||||||
	this->triangles = new uint16[4*this->numTriangles];
 | 
						this->triangles = new Triangle[this->numTriangles];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint16 *f = this->triangles;
 | 
						Triangle *tri = this->triangles;
 | 
				
			||||||
	m = header->mesh;
 | 
						m = header->mesh;
 | 
				
			||||||
	adcbits = adc;
 | 
						adcbits = adc;
 | 
				
			||||||
	for(uint32 i = 0; i < header->numMeshes; i++){
 | 
						for(uint32 i = 0; i < header->numMeshes; i++){
 | 
				
			||||||
@ -382,23 +396,65 @@ Geometry::generateTriangles(int8 *adc)
 | 
				
			|||||||
				if(adc && adcbits[j+2] ||
 | 
									if(adc && adcbits[j+2] ||
 | 
				
			||||||
				   isDegenerate(&m->indices[j]))
 | 
									   isDegenerate(&m->indices[j]))
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
				*f++ = m->indices[j+1 + (j%2)];
 | 
									tri->v[0] = m->indices[j+0];
 | 
				
			||||||
				*f++ = m->indices[j+0];
 | 
									tri->v[1] = m->indices[j+1 + (j%2)];
 | 
				
			||||||
				*f++ = matid;
 | 
									tri->v[2] = m->indices[j+2 - (j%2)];
 | 
				
			||||||
				*f++ = m->indices[j+2 - (j%2)];
 | 
									tri->matId = matid;
 | 
				
			||||||
 | 
									tri++;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			for(uint32 j = 0; j < m->numIndices-2; j+=3){
 | 
								for(uint32 j = 0; j < m->numIndices-2; j+=3){
 | 
				
			||||||
				*f++ = m->indices[j+1];
 | 
									tri->v[0] = m->indices[j+0];
 | 
				
			||||||
				*f++ = m->indices[j+0];
 | 
									tri->v[1] = m->indices[j+1];
 | 
				
			||||||
				*f++ = matid;
 | 
									tri->v[2] = m->indices[j+2];
 | 
				
			||||||
				*f++ = m->indices[j+2];
 | 
									tri->matId = matid;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		adcbits += m->numIndices;
 | 
							adcbits += m->numIndices;
 | 
				
			||||||
		m++;
 | 
							m++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					Geometry::buildMeshes(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						delete this->meshHeader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Triangle *tri;
 | 
				
			||||||
 | 
						MeshHeader *h = new MeshHeader;
 | 
				
			||||||
 | 
						this->meshHeader = h;
 | 
				
			||||||
 | 
						if((this->geoflags & Geometry::TRISTRIP) == 0){
 | 
				
			||||||
 | 
							h->flags = 0;
 | 
				
			||||||
 | 
							h->totalIndices = this->numTriangles*3;
 | 
				
			||||||
 | 
							h->numMeshes = this->numMaterials;
 | 
				
			||||||
 | 
							h->mesh = new Mesh[h->numMeshes];
 | 
				
			||||||
 | 
							for(uint32 i = 0; i < h->numMeshes; i++){
 | 
				
			||||||
 | 
								h->mesh[i].material = this->materialList[i];
 | 
				
			||||||
 | 
								h->mesh[i].numIndices = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// count indices per mesh
 | 
				
			||||||
 | 
							tri = this->triangles;
 | 
				
			||||||
 | 
							for(int32 i = 0; i < this->numTriangles; i++){
 | 
				
			||||||
 | 
								h->mesh[tri->matId].numIndices += 3;
 | 
				
			||||||
 | 
								tri++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							h->allocateIndices();
 | 
				
			||||||
 | 
							for(uint32 i = 0; i < h->numMeshes; i++)
 | 
				
			||||||
 | 
								h->mesh[i].numIndices = 0;
 | 
				
			||||||
 | 
							// same as above but fill with indices
 | 
				
			||||||
 | 
							tri = this->triangles;
 | 
				
			||||||
 | 
							for(int32 i = 0; i < this->numTriangles; i++){
 | 
				
			||||||
 | 
								uint32 idx = h->mesh[tri->matId].numIndices;
 | 
				
			||||||
 | 
								h->mesh[tri->matId].indices[idx++] = tri->v[0];
 | 
				
			||||||
 | 
								h->mesh[tri->matId].indices[idx++] = tri->v[1];
 | 
				
			||||||
 | 
								h->mesh[tri->matId].indices[idx++] = tri->v[2];
 | 
				
			||||||
 | 
								h->mesh[tri->matId].numIndices = idx;
 | 
				
			||||||
 | 
								tri++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}else{
 | 
				
			||||||
 | 
							assert(0 && "can't tristrip\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Material
 | 
					// Material
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
				
			|||||||
@ -61,6 +61,9 @@ attachPlugins(void)
 | 
				
			|||||||
	rw::ps2::registerNativeRaster();
 | 
						rw::ps2::registerNativeRaster();
 | 
				
			||||||
	rw::xbox::registerNativeRaster();
 | 
						rw::xbox::registerNativeRaster();
 | 
				
			||||||
	rw::d3d::registerNativeRaster();
 | 
						rw::d3d::registerNativeRaster();
 | 
				
			||||||
 | 
						int32 nativeRasterOffset = Raster::registerPlugin(sizeof(NativeRaster),
 | 
				
			||||||
 | 
							0x12340000 | PLATFORM_NULL, NULL, NULL, NULL);
 | 
				
			||||||
 | 
						Raster::nativeOffsets[PLATFORM_NULL] = nativeRasterOffset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rw::registerMeshPlugin();
 | 
						rw::registerMeshPlugin();
 | 
				
			||||||
	rw::registerNativeDataPlugin();
 | 
						rw::registerNativeDataPlugin();
 | 
				
			||||||
@ -873,13 +876,6 @@ static bool hasColors2(uint32 id)
 | 
				
			|||||||
	return id == 0x53f20083 || id == 0x53f2008f;
 | 
						return id == 0x53f20083 || id == 0x53f2008f;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct SaVert : ps2::Vertex {
 | 
					 | 
				
			||||||
	float32 w[4];
 | 
					 | 
				
			||||||
	uint8   i[4];
 | 
					 | 
				
			||||||
	float32 t1[2];
 | 
					 | 
				
			||||||
	uint8   c1[4];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
saPreCB(MatPipeline *p, Geometry *geo)
 | 
					saPreCB(MatPipeline *p, Geometry *geo)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -916,27 +912,28 @@ findSAVertex(Geometry *g, uint32 flags[], uint32 mask, SaVert *v)
 | 
				
			|||||||
		cols1 = PLUGINOFFSET(ExtraVertColors, g, extraVertColorOffset)->nightColors;
 | 
							cols1 = PLUGINOFFSET(ExtraVertColors, g, extraVertColorOffset)->nightColors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for(int32 i = 0; i < g->numVertices; i++){
 | 
						for(int32 i = 0; i < g->numVertices; i++){
 | 
				
			||||||
		if(mask & flags[i] & 0x1 &&
 | 
							uint32 flag = flags ? flags[i] : ~0;
 | 
				
			||||||
 | 
							if(mask & flag & 0x1 &&
 | 
				
			||||||
		   !(verts[0] == v->p[0] && verts[1] == v->p[1] && verts[2] == v->p[2]))
 | 
							   !(verts[0] == v->p[0] && verts[1] == v->p[1] && verts[2] == v->p[2]))
 | 
				
			||||||
			goto cont;
 | 
								goto cont;
 | 
				
			||||||
		if(mask & flags[i] & 0x10 &&
 | 
							if(mask & flag & 0x10 &&
 | 
				
			||||||
		   !(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2]))
 | 
							   !(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2]))
 | 
				
			||||||
			goto cont;
 | 
								goto cont;
 | 
				
			||||||
		if(mask & flags[i] & 0x100 &&
 | 
							if(mask & flag & 0x100 &&
 | 
				
			||||||
		   !(cols0[0] == v->c[0] && cols0[1] == v->c[1] &&
 | 
							   !(cols0[0] == v->c[0] && cols0[1] == v->c[1] &&
 | 
				
			||||||
		     cols0[2] == v->c[2] && cols0[3] == v->c[3]))
 | 
							     cols0[2] == v->c[2] && cols0[3] == v->c[3]))
 | 
				
			||||||
			goto cont;
 | 
								goto cont;
 | 
				
			||||||
		if(mask & flags[i] & 0x200 &&
 | 
							if(mask & flag & 0x200 &&
 | 
				
			||||||
		   !(cols1[0] == v->c1[0] && cols1[1] == v->c1[1] &&
 | 
							   !(cols1[0] == v->c1[0] && cols1[1] == v->c1[1] &&
 | 
				
			||||||
		     cols1[2] == v->c1[2] && cols1[3] == v->c1[3]))
 | 
							     cols1[2] == v->c1[2] && cols1[3] == v->c1[3]))
 | 
				
			||||||
			goto cont;
 | 
								goto cont;
 | 
				
			||||||
		if(mask & flags[i] & 0x1000 &&
 | 
							if(mask & flag & 0x1000 &&
 | 
				
			||||||
		   !(tex0[0] == v->t[0] && tex0[1] == v->t[1]))
 | 
							   !(tex0[0] == v->t[0] && tex0[1] == v->t[1]))
 | 
				
			||||||
			goto cont;
 | 
								goto cont;
 | 
				
			||||||
		if(mask & flags[i] & 0x2000 &&
 | 
							if(mask & flag & 0x2000 &&
 | 
				
			||||||
		   !(tex1[0] == v->t1[0] && tex1[1] == v->t1[1]))
 | 
							   !(tex1[0] == v->t1[0] && tex1[1] == v->t1[1]))
 | 
				
			||||||
			goto cont;
 | 
								goto cont;
 | 
				
			||||||
		if(mask & flags[i] & 0x10000 &&
 | 
							if(mask & flag & 0x10000 &&
 | 
				
			||||||
		   !(wghts[0] == v->w[0] && wghts[1] == v->w[1] &&
 | 
							   !(wghts[0] == v->w[0] && wghts[1] == v->w[1] &&
 | 
				
			||||||
		     wghts[2] == v->w[2] && wghts[3] == v->w[3] &&
 | 
							     wghts[2] == v->w[2] && wghts[3] == v->w[3] &&
 | 
				
			||||||
		     inds[0] == v->i[0] && inds[1] == v->i[1] &&
 | 
							     inds[0] == v->i[0] && inds[1] == v->i[1] &&
 | 
				
			||||||
 | 
				
			|||||||
@ -124,6 +124,15 @@ void registerCollisionPlugin(void);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// PDS pipes
 | 
					// PDS pipes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct SaVert : ps2::Vertex {
 | 
				
			||||||
 | 
						float32 w[4];
 | 
				
			||||||
 | 
						uint8   i[4];
 | 
				
			||||||
 | 
						float32 t1[2];
 | 
				
			||||||
 | 
						uint8   c1[4];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					void insertSAVertex(Geometry *geo, int32 i, uint32 mask, SaVert *v);
 | 
				
			||||||
 | 
					int32 findSAVertex(Geometry *g, uint32 flags[], uint32 mask, SaVert *v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void registerPDSPipes(void);
 | 
					void registerPDSPipes(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -170,7 +170,7 @@ Texture*
 | 
				
			|||||||
Texture::streamRead(Stream *stream)
 | 
					Texture::streamRead(Stream *stream)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32 length;
 | 
						uint32 length;
 | 
				
			||||||
	char name[32], mask[32];
 | 
						char name[128], mask[128];
 | 
				
			||||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
						assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
				
			||||||
	uint32 filterAddressing = stream->readU32();
 | 
						uint32 filterAddressing = stream->readU32();
 | 
				
			||||||
	// TODO: if V addressing is 0, copy U
 | 
						// TODO: if V addressing is 0, copy U
 | 
				
			||||||
@ -197,18 +197,22 @@ bool
 | 
				
			|||||||
Texture::streamWrite(Stream *stream)
 | 
					Texture::streamWrite(Stream *stream)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int size;
 | 
						int size;
 | 
				
			||||||
 | 
						char buf[36];
 | 
				
			||||||
	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
 | 
						memset(buf, 0, 36);
 | 
				
			||||||
	size = strlen(this->name)+4 & ~3;
 | 
						strncpy(buf, this->name, 32);
 | 
				
			||||||
 | 
						size = strlen(buf)+4 & ~3;
 | 
				
			||||||
	writeChunkHeader(stream, ID_STRING, size);
 | 
						writeChunkHeader(stream, ID_STRING, size);
 | 
				
			||||||
	stream->write(this->name, size);
 | 
						stream->write(buf, size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size = strlen(this->mask)+4 & ~3;
 | 
						memset(buf, 0, 36);
 | 
				
			||||||
 | 
						strncpy(buf, this->mask, 32);
 | 
				
			||||||
 | 
						size = strlen(buf)+4 & ~3;
 | 
				
			||||||
	writeChunkHeader(stream, ID_STRING, size);
 | 
						writeChunkHeader(stream, ID_STRING, size);
 | 
				
			||||||
	stream->write(this->mask, size);
 | 
						stream->write(buf, size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->streamWritePlugins(stream);
 | 
						this->streamWritePlugins(stream);
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
@ -640,7 +644,7 @@ Raster::calculateNumLevels(int32 width, int32 height)
 | 
				
			|||||||
Raster*
 | 
					Raster*
 | 
				
			||||||
Raster::createFromImage(Image *image)
 | 
					Raster::createFromImage(Image *image)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	assert(0 && "unsupported atm");
 | 
						assert(0 && "cannot create raster from image");
 | 
				
			||||||
	int32 format;
 | 
						int32 format;
 | 
				
			||||||
	// TODO: make that into a function
 | 
						// TODO: make that into a function
 | 
				
			||||||
	if(image->depth == 32)
 | 
						if(image->depth == 32)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										216
									
								
								src/plugins.cpp
									
									
									
									
									
								
							
							
						
						
									
										216
									
								
								src/plugins.cpp
									
									
									
									
									
								
							@ -24,6 +24,101 @@ namespace rw {
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int32 hAnimOffset;
 | 
					int32 hAnimOffset;
 | 
				
			||||||
 | 
					bool32 hAnimDoStream = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HAnimHierarchy*
 | 
				
			||||||
 | 
					HAnimHierarchy::create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs, int32 flags, int32 maxKeySize)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						HAnimHierarchy *hier = (HAnimHierarchy*)malloc(sizeof(*hier));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hier->numNodes = numNodes;
 | 
				
			||||||
 | 
						hier->flags = flags;
 | 
				
			||||||
 | 
						hier->maxInterpKeyFrameSize = maxKeySize;
 | 
				
			||||||
 | 
						hier->parentFrame = NULL;
 | 
				
			||||||
 | 
						hier->parentHierarchy = hier;
 | 
				
			||||||
 | 
						if(hier->flags & 2)
 | 
				
			||||||
 | 
							hier->matrices = hier->matricesUnaligned = NULL;
 | 
				
			||||||
 | 
						else{
 | 
				
			||||||
 | 
							hier->matricesUnaligned =
 | 
				
			||||||
 | 
							  (float*) new uint8[hier->numNodes*64 + 15];
 | 
				
			||||||
 | 
							hier->matrices =
 | 
				
			||||||
 | 
							  (float*)((uintptr)hier->matricesUnaligned & ~0xF);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hier->nodeInfo = new HAnimNodeInfo[hier->numNodes];
 | 
				
			||||||
 | 
						for(int32 i = 0; i < hier->numNodes; i++){
 | 
				
			||||||
 | 
							hier->nodeInfo[i].id = nodeIDs[i];
 | 
				
			||||||
 | 
							hier->nodeInfo[i].index = i;
 | 
				
			||||||
 | 
							hier->nodeInfo[i].flags = nodeFlags[i];
 | 
				
			||||||
 | 
							hier->nodeInfo[i].frame = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return hier;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					HAnimHierarchy::destroy(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						delete[] (uint8*)this->matricesUnaligned;
 | 
				
			||||||
 | 
						delete[] this->nodeInfo;
 | 
				
			||||||
 | 
						free(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Frame*
 | 
				
			||||||
 | 
					findById(Frame *f, int32 id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if(f == NULL) return NULL;
 | 
				
			||||||
 | 
						HAnimData *hanim = HAnimData::get(f);
 | 
				
			||||||
 | 
						if(hanim->id >= 0 && hanim->id == id) return f;
 | 
				
			||||||
 | 
						Frame *ff = findById(f->next, id);
 | 
				
			||||||
 | 
						if(ff) return ff;
 | 
				
			||||||
 | 
						return findById(f->child, id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					HAnimHierarchy::attachByIndex(int32 idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int32 id = this->nodeInfo[idx].id;
 | 
				
			||||||
 | 
						Frame *f = findById(this->parentFrame, id);
 | 
				
			||||||
 | 
						this->nodeInfo[idx].frame = f;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					HAnimHierarchy::attach(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for(int32 i = 0; i < this->numNodes; i++)
 | 
				
			||||||
 | 
							this->attachByIndex(i);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32
 | 
				
			||||||
 | 
					HAnimHierarchy::getIndex(int32 id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for(int32 i = 0; i < this->numNodes; i++)
 | 
				
			||||||
 | 
							if(this->nodeInfo[i].id == id)
 | 
				
			||||||
 | 
								return i;
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HAnimHierarchy*
 | 
				
			||||||
 | 
					HAnimHierarchy::get(Frame *f)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return HAnimData::get(f)->hierarchy;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HAnimHierarchy*
 | 
				
			||||||
 | 
					HAnimHierarchy::find(Frame *f)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if(f == NULL) return NULL;
 | 
				
			||||||
 | 
						HAnimHierarchy *hier = HAnimHierarchy::get(f);
 | 
				
			||||||
 | 
						if(hier) return hier;
 | 
				
			||||||
 | 
						hier = HAnimHierarchy::find(f->next);
 | 
				
			||||||
 | 
						if(hier) return hier;
 | 
				
			||||||
 | 
						return HAnimHierarchy::find(f->child);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HAnimData*
 | 
				
			||||||
 | 
					HAnimData::get(Frame *f)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return PLUGINOFFSET(HAnimData, f, hAnimOffset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void*
 | 
					static void*
 | 
				
			||||||
createHAnim(void *object, int32 offset, int32)
 | 
					createHAnim(void *object, int32 offset, int32)
 | 
				
			||||||
@ -38,12 +133,8 @@ static void*
 | 
				
			|||||||
destroyHAnim(void *object, int32 offset, int32)
 | 
					destroyHAnim(void *object, int32 offset, int32)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
 | 
						HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
 | 
				
			||||||
	if(hanim->hierarchy){
 | 
						if(hanim->hierarchy)
 | 
				
			||||||
		HAnimHierarchy *hier = hanim->hierarchy;
 | 
							hanim->hierarchy->destroy();
 | 
				
			||||||
		delete[] (uint8*)hier->matricesUnaligned;
 | 
					 | 
				
			||||||
		delete[] hier->nodeInfo;
 | 
					 | 
				
			||||||
		delete hier;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	hanim->id = -1;
 | 
						hanim->id = -1;
 | 
				
			||||||
	hanim->hierarchy = NULL;
 | 
						hanim->hierarchy = NULL;
 | 
				
			||||||
	return object;
 | 
						return object;
 | 
				
			||||||
@ -70,28 +161,20 @@ readHAnim(Stream *stream, int32, void *object, int32 offset, int32)
 | 
				
			|||||||
	hanim->id = stream->readI32();
 | 
						hanim->id = stream->readI32();
 | 
				
			||||||
	numNodes = stream->readI32();
 | 
						numNodes = stream->readI32();
 | 
				
			||||||
	if(numNodes != 0){
 | 
						if(numNodes != 0){
 | 
				
			||||||
		HAnimHierarchy *hier = new HAnimHierarchy;
 | 
							int32 flags = stream->readI32();
 | 
				
			||||||
		hanim->hierarchy = hier;
 | 
							int32 maxKeySize = stream->readI32();
 | 
				
			||||||
		hier->numNodes = numNodes;
 | 
							int32 *nodeFlags = new int32[numNodes];
 | 
				
			||||||
		hier->flags = stream->readI32();
 | 
							int32 *nodeIDs = new int32[numNodes];
 | 
				
			||||||
		hier->maxInterpKeyFrameSize = stream->readI32();
 | 
							for(int32 i = 0; i < numNodes; i++){
 | 
				
			||||||
		hier->parentFrame = (Frame*)object;
 | 
								nodeIDs[i] = stream->readI32();
 | 
				
			||||||
		hier->parentHierarchy = hier;
 | 
								stream->readI32();	// index...unused
 | 
				
			||||||
		if(hier->flags & 2)
 | 
								nodeFlags[i] = stream->readI32();
 | 
				
			||||||
			hier->matrices = hier->matricesUnaligned = NULL;
 | 
					 | 
				
			||||||
		else{
 | 
					 | 
				
			||||||
			hier->matricesUnaligned =
 | 
					 | 
				
			||||||
			  (float*) new uint8[hier->numNodes*64 + 15];
 | 
					 | 
				
			||||||
			hier->matrices =
 | 
					 | 
				
			||||||
			  (float*)((uintptr)hier->matricesUnaligned & ~0xF);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		hier->nodeInfo = new HAnimNodeInfo[hier->numNodes];
 | 
					 | 
				
			||||||
		for(int32 i = 0; i < hier->numNodes; i++){
 | 
					 | 
				
			||||||
			hier->nodeInfo[i].id = stream->readI32();
 | 
					 | 
				
			||||||
			hier->nodeInfo[i].index = stream->readI32();
 | 
					 | 
				
			||||||
			hier->nodeInfo[i].flags = stream->readI32();
 | 
					 | 
				
			||||||
			hier->nodeInfo[i].frame = NULL;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							hanim->hierarchy = HAnimHierarchy::create(numNodes,
 | 
				
			||||||
 | 
								nodeFlags, nodeIDs, flags, maxKeySize);
 | 
				
			||||||
 | 
							hanim->hierarchy->parentFrame = (Frame*)object;
 | 
				
			||||||
 | 
							delete[] nodeFlags;
 | 
				
			||||||
 | 
							delete[] nodeIDs;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -121,8 +204,9 @@ getSizeHAnim(void *object, int32 offset, int32)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
 | 
						HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
 | 
				
			||||||
	// TODO: version correct?
 | 
						// TODO: version correct?
 | 
				
			||||||
	if(version >= 0x35000 && hanim->id == -1 && hanim->hierarchy == NULL)
 | 
						if(!hAnimDoStream ||
 | 
				
			||||||
		return -1;
 | 
						   version >= 0x35000 && hanim->id == -1 && hanim->hierarchy == NULL)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
	if(hanim->hierarchy)
 | 
						if(hanim->hierarchy)
 | 
				
			||||||
		return 12 + 8 + hanim->hierarchy->numNodes*12;
 | 
							return 12 + 8 + hanim->hierarchy->numNodes*12;
 | 
				
			||||||
	return 12;
 | 
						return 12;
 | 
				
			||||||
@ -605,7 +689,7 @@ getSizeSkin(void *object, int32 offset, int32)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
skinRights(void *object, int32, int32, uint32)
 | 
					skinRights(void *object, int32, int32, uint32)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	((Atomic*)object)->pipeline = skinGlobals.pipelines[rw::platform];
 | 
						Skin::setPipeline((Atomic*)object, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
@ -712,6 +796,13 @@ Skin::findUsedBones(int32 numVertices)
 | 
				
			|||||||
			this->usedBones[this->numUsedBones++] = i;
 | 
								this->usedBones[this->numUsedBones++] = i;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					Skin::setPipeline(Atomic *a, int32 type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						(void)type;
 | 
				
			||||||
 | 
						a->pipeline = skinGlobals.pipelines[rw::platform];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// MatFX
 | 
					// MatFX
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@ -728,28 +819,22 @@ createAtomicMatFX(void *object, int32 offset, int32)
 | 
				
			|||||||
static void*
 | 
					static void*
 | 
				
			||||||
copyAtomicMatFX(void *dst, void *src, int32 offset, int32)
 | 
					copyAtomicMatFX(void *dst, void *src, int32 offset, int32)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	*PLUGINOFFSET(int32, dst, offset) = *PLUGINOFFSET(int32, src, offset);
 | 
						if(*PLUGINOFFSET(int32, src, offset))
 | 
				
			||||||
 | 
							MatFX::enableEffects((Atomic*)dst);
 | 
				
			||||||
	return dst;
 | 
						return dst;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
readAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
					readAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int32 flag;
 | 
						if(stream->readI32())
 | 
				
			||||||
	stream->read(&flag, 4);
 | 
							MatFX::enableEffects((Atomic*)object);
 | 
				
			||||||
//	printf("matfx: %d\n", flag);
 | 
					 | 
				
			||||||
	*PLUGINOFFSET(int32, object, offset) = flag;
 | 
					 | 
				
			||||||
	if(flag)
 | 
					 | 
				
			||||||
		((Atomic*)object)->pipeline =
 | 
					 | 
				
			||||||
			matFXGlobals.pipelines[rw::platform];
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
writeAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
					writeAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int32 flag;
 | 
						stream->writeI32(*PLUGINOFFSET(int32, object, offset));
 | 
				
			||||||
	flag = *PLUGINOFFSET(int32, object, offset);
 | 
					 | 
				
			||||||
	stream->writeI32(flag);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int32
 | 
					static int32
 | 
				
			||||||
@ -826,6 +911,22 @@ MatFX::getEffectIndex(uint32 type)
 | 
				
			|||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					MatFX::setBumpTexture(Texture *t)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int32 i = this->getEffectIndex(BUMPMAP);
 | 
				
			||||||
 | 
						if(i >= 0)
 | 
				
			||||||
 | 
							this->fx[i].bump.tex = t;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					MatFX::setBumpCoefficient(float32 coef)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int32 i = this->getEffectIndex(BUMPMAP);
 | 
				
			||||||
 | 
						if(i >= 0)
 | 
				
			||||||
 | 
							this->fx[i].bump.coefficient = coef;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
MatFX::setEnvTexture(Texture *t)
 | 
					MatFX::setEnvTexture(Texture *t)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -842,6 +943,30 @@ MatFX::setEnvCoefficient(float32 coef)
 | 
				
			|||||||
		this->fx[i].env.coefficient = coef;
 | 
							this->fx[i].env.coefficient = coef;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					MatFX::setDualTexture(Texture *t)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int32 i = this->getEffectIndex(DUAL);
 | 
				
			||||||
 | 
						if(i >= 0)
 | 
				
			||||||
 | 
							this->fx[i].dual.tex = t;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					MatFX::setDualSrcBlend(int32 blend)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int32 i = this->getEffectIndex(DUAL);
 | 
				
			||||||
 | 
						if(i >= 0)
 | 
				
			||||||
 | 
							this->fx[i].dual.srcBlend = blend;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					MatFX::setDualDestBlend(int32 blend)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int32 i = this->getEffectIndex(DUAL);
 | 
				
			||||||
 | 
						if(i >= 0)
 | 
				
			||||||
 | 
							this->fx[i].dual.dstBlend = blend;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void*
 | 
					static void*
 | 
				
			||||||
createMaterialMatFX(void *object, int32 offset, int32)
 | 
					createMaterialMatFX(void *object, int32 offset, int32)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -1038,11 +1163,18 @@ getSizeMaterialMatFX(void *object, int32 offset, int32)
 | 
				
			|||||||
	return size;
 | 
						return size;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					MatFX::enableEffects(Atomic *atomic)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						*PLUGINOFFSET(int32, atomic, matFXGlobals.atomicOffset) = 1;
 | 
				
			||||||
 | 
						atomic->pipeline = matFXGlobals.pipelines[rw::platform];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
registerMatFXPlugin(void)
 | 
					registerMatFXPlugin(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
 | 
						ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
 | 
				
			||||||
	defpipe->pluginID = ID_MATFX;
 | 
						defpipe->pluginID = 0; //ID_MATFX;
 | 
				
			||||||
	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;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										27
									
								
								src/ps2.cpp
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/ps2.cpp
									
									
									
									
									
								
							@ -233,6 +233,8 @@ static uint32
 | 
				
			|||||||
getBatchSize(MatPipeline *pipe, uint32 vertCount)
 | 
					getBatchSize(MatPipeline *pipe, uint32 vertCount)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PipeAttribute *a;
 | 
						PipeAttribute *a;
 | 
				
			||||||
 | 
						if(vertCount == 0)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
	uint32 size = 1;	// ITOP &c. at the end
 | 
						uint32 size = 1;	// ITOP &c. at the end
 | 
				
			||||||
	for(uint i = 0; i < nelem(pipe->attribs); i++)
 | 
						for(uint i = 0; i < nelem(pipe->attribs); i++)
 | 
				
			||||||
		if((a = pipe->attribs[i]) && (a->attrib & AT_RW) == 0){
 | 
							if((a = pipe->attribs[i]) && (a->attrib & AT_RW) == 0){
 | 
				
			||||||
@ -393,21 +395,22 @@ getInstMeshInfo(MatPipeline *pipe, Geometry *g, Mesh *m)
 | 
				
			|||||||
				im.numAttribs++;
 | 
									im.numAttribs++;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
	uint32 totalVerts = 0;
 | 
						uint32 totalVerts = 0;
 | 
				
			||||||
	if(g->meshHeader->flags == 1){	// tristrip
 | 
						if(g->meshHeader->flags == MeshHeader::TRISTRIP){
 | 
				
			||||||
		im.numBatches = 0;
 | 
							im.numBatches = (m->numIndices-2) / (pipe->triStripCount-2);
 | 
				
			||||||
		for(uint i = 0; i < m->numIndices; i += pipe->triStripCount-2){
 | 
					 | 
				
			||||||
			im.numBatches++;
 | 
					 | 
				
			||||||
			totalVerts += m->numIndices-i < pipe->triStripCount ?
 | 
					 | 
				
			||||||
			              m->numIndices-i : pipe->triStripCount;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		im.batchVertCount = pipe->triStripCount;
 | 
							im.batchVertCount = pipe->triStripCount;
 | 
				
			||||||
		im.lastBatchVertCount = totalVerts % pipe->triStripCount;
 | 
							im.lastBatchVertCount = (m->numIndices-2) % (pipe->triStripCount-2);
 | 
				
			||||||
	}else{				// trilist
 | 
							if(im.lastBatchVertCount){
 | 
				
			||||||
 | 
								im.numBatches++;
 | 
				
			||||||
 | 
								im.lastBatchVertCount += 2;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}else{
 | 
				
			||||||
		im.numBatches = (m->numIndices+pipe->triListCount-1) /
 | 
							im.numBatches = (m->numIndices+pipe->triListCount-1) /
 | 
				
			||||||
		                 pipe->triListCount;
 | 
							                 pipe->triListCount;
 | 
				
			||||||
		im.batchVertCount = pipe->triListCount;
 | 
							im.batchVertCount = pipe->triListCount;
 | 
				
			||||||
		im.lastBatchVertCount = m->numIndices % pipe->triListCount;
 | 
							im.lastBatchVertCount = m->numIndices % pipe->triListCount;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if(im.lastBatchVertCount == 0)
 | 
				
			||||||
 | 
							im.lastBatchVertCount = im.batchVertCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	im.batchSize = getBatchSize(pipe, im.batchVertCount);
 | 
						im.batchSize = getBatchSize(pipe, im.batchVertCount);
 | 
				
			||||||
	im.lastBatchSize = getBatchSize(pipe, im.lastBatchVertCount);
 | 
						im.lastBatchSize = getBatchSize(pipe, im.lastBatchVertCount);
 | 
				
			||||||
@ -572,8 +575,10 @@ MatPipeline::collectData(Geometry *g, InstanceData *inst, Mesh *m, uint8 *data[]
 | 
				
			|||||||
			if((a = this->attribs[i]) && (a->attrib & AT_RW) == 0){
 | 
								if((a = this->attribs[i]) && (a->attrib & AT_RW) == 0){
 | 
				
			||||||
				uint32 asz = attribSize(a->attrib);
 | 
									uint32 asz = attribSize(a->attrib);
 | 
				
			||||||
				p += 4;
 | 
									p += 4;
 | 
				
			||||||
				if((p[-1] & 0xff004000) != a->attrib)
 | 
									if((p[-1] & 0xff004000) != a->attrib){
 | 
				
			||||||
					printf("unexpected unpack: %08x %08x\n", p[-1], a->attrib);
 | 
										fprintf(stderr, "unexpected unpack xx: %08x %08x\n", p[-1], a->attrib);
 | 
				
			||||||
 | 
										assert(0 && "unexpected unpack\n");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				memcpy(datap[i], p, asz*nverts);
 | 
									memcpy(datap[i], p, asz*nverts);
 | 
				
			||||||
				datap[i] += asz*(nverts-overlap);
 | 
									datap[i] += asz*(nverts-overlap);
 | 
				
			||||||
				p += QWC(asz*nverts)*4;
 | 
									p += QWC(asz*nverts)*4;
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,16 @@ int32 build = 0xFFFF;
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
char *debugFile = NULL;
 | 
					char *debugFile = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					matrixIdentify(float32 *mat)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						memset(mat, 0, 64);
 | 
				
			||||||
 | 
						mat[0] = 1.0f;
 | 
				
			||||||
 | 
						mat[5] = 1.0f;
 | 
				
			||||||
 | 
						mat[10] = 1.0f;
 | 
				
			||||||
 | 
						mat[16] = 1.0f;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
matrixMult(float32 *out, float32 *a, float32 *b)
 | 
					matrixMult(float32 *out, float32 *a, float32 *b)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -32,17 +42,41 @@ matrixMult(float32 *out, float32 *a, float32 *b)
 | 
				
			|||||||
	#define L(i,j) out[i*4+j]
 | 
						#define L(i,j) out[i*4+j]
 | 
				
			||||||
	#define A(i,j) a[i*4+j]
 | 
						#define A(i,j) a[i*4+j]
 | 
				
			||||||
	#define B(i,j) b[i*4+j]
 | 
						#define B(i,j) b[i*4+j]
 | 
				
			||||||
			for(int i = 0; i < 4; i++)
 | 
						for(int i = 0; i < 4; i++)
 | 
				
			||||||
				for(int j = 0; j < 4; j++)
 | 
							for(int j = 0; j < 4; j++)
 | 
				
			||||||
					L(i,j) = A(0,j)*B(i,0)
 | 
								L(i,j) = A(0,j)*B(i,0)
 | 
				
			||||||
					       + A(1,j)*B(i,1)
 | 
								       + A(1,j)*B(i,1)
 | 
				
			||||||
					       + A(2,j)*B(i,2)
 | 
								       + A(2,j)*B(i,2)
 | 
				
			||||||
					       + A(3,j)*B(i,3);
 | 
								       + A(3,j)*B(i,3);
 | 
				
			||||||
	#undef L
 | 
						#undef L
 | 
				
			||||||
	#undef A
 | 
						#undef A
 | 
				
			||||||
	#undef B
 | 
						#undef B
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					vecTrans(float32 *out, float32 *mat, float32 *vec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#define M(i,j) mat[i*4+j]
 | 
				
			||||||
 | 
						for(int i = 0; i < 4; i++)
 | 
				
			||||||
 | 
							out[i] = M(0,i)*vec[0]
 | 
				
			||||||
 | 
							       + M(1,i)*vec[1]
 | 
				
			||||||
 | 
							       + M(2,i)*vec[2]
 | 
				
			||||||
 | 
							       + M(3,i)*vec[3];
 | 
				
			||||||
 | 
						#undef M
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					matrixTranspose(float32 *out, float32 *in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#define OUT(i,j) out[i*4+j]
 | 
				
			||||||
 | 
						#define IN(i,j) in[i*4+j]
 | 
				
			||||||
 | 
						for(int i = 0; i < 4; i++)
 | 
				
			||||||
 | 
							for(int j = 0; j < 4; j++)
 | 
				
			||||||
 | 
								OUT(i,j) = IN(j,i);
 | 
				
			||||||
 | 
						#undef IN
 | 
				
			||||||
 | 
						#undef OUT
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
matrixInvert(float32 *out, float32 *m)
 | 
					matrixInvert(float32 *out, float32 *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -153,7 +153,10 @@ extern int build;
 | 
				
			|||||||
extern int platform;
 | 
					extern int platform;
 | 
				
			||||||
extern char *debugFile;
 | 
					extern char *debugFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void matrixIdentify(float32 *mat);
 | 
				
			||||||
void matrixMult(float32 *out, float32 *a, float32 *b);
 | 
					void matrixMult(float32 *out, float32 *a, float32 *b);
 | 
				
			||||||
 | 
					void vecTrans(float32 *out, float32 *mat, float32 *vec);
 | 
				
			||||||
 | 
					void matrixTranspose(float32 *out, float32 *in);
 | 
				
			||||||
void matrixInvert(float32 *out, float32 *in);
 | 
					void matrixInvert(float32 *out, float32 *in);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 0x04000000	3.1
 | 
					// 0x04000000	3.1
 | 
				
			||||||
 | 
				
			|||||||
@ -132,7 +132,7 @@ struct Frame : PluginBase<Frame>
 | 
				
			|||||||
	Frame *cloneHierarchy(void);
 | 
						Frame *cloneHierarchy(void);
 | 
				
			||||||
	void destroy(void);
 | 
						void destroy(void);
 | 
				
			||||||
	void destroyHierarchy(void);
 | 
						void destroyHierarchy(void);
 | 
				
			||||||
	Frame *addChild(Frame *f);
 | 
						Frame *addChild(Frame *f, bool32 append = 0);
 | 
				
			||||||
	Frame *removeChild(void);
 | 
						Frame *removeChild(void);
 | 
				
			||||||
	Frame *forAllChildren(Callback cb, void *data);
 | 
						Frame *forAllChildren(Callback cb, void *data);
 | 
				
			||||||
	Frame *getParent(void){
 | 
						Frame *getParent(void){
 | 
				
			||||||
@ -144,6 +144,13 @@ struct Frame : PluginBase<Frame>
 | 
				
			|||||||
	void setHierarchyRoot(Frame *root);
 | 
						void setHierarchyRoot(Frame *root);
 | 
				
			||||||
	Frame *cloneAndLink(Frame *clonedroot);
 | 
						Frame *cloneAndLink(Frame *clonedroot);
 | 
				
			||||||
	void purgeClone(void);
 | 
						void purgeClone(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// private flags:
 | 
				
			||||||
 | 
						// #define rwFRAMEPRIVATEHIERARCHYSYNCLTM  0x01
 | 
				
			||||||
 | 
						// #define rwFRAMEPRIVATEHIERARCHYSYNCOBJ  0x02
 | 
				
			||||||
 | 
						// #define rwFRAMEPRIVATESUBTREESYNCLTM    0x04
 | 
				
			||||||
 | 
						// #define rwFRAMEPRIVATESUBTREESYNCOBJ    0x08
 | 
				
			||||||
 | 
						// #define rwFRAMEPRIVATESTATIC            0x10
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Frame **makeFrameList(Frame *frame, Frame **flist);
 | 
					Frame **makeFrameList(Frame *frame, Frame **flist);
 | 
				
			||||||
@ -191,15 +198,32 @@ struct HAnimHierarchy
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// temporary
 | 
						// temporary
 | 
				
			||||||
	int32 maxInterpKeyFrameSize;
 | 
						int32 maxInterpKeyFrameSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static HAnimHierarchy *create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs, int32 flags, int32 maxKeySize);
 | 
				
			||||||
 | 
						void destroy(void);
 | 
				
			||||||
 | 
						void attachByIndex(int32 id);
 | 
				
			||||||
 | 
						void attach(void);
 | 
				
			||||||
 | 
						int32 getIndex(int32 id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static HAnimHierarchy *get(Frame *f);
 | 
				
			||||||
 | 
						static HAnimHierarchy *find(Frame *f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum NodeFlag {
 | 
				
			||||||
 | 
							POP = 1,
 | 
				
			||||||
 | 
							PUSH
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct HAnimData
 | 
					struct HAnimData
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int32 id;
 | 
						int32 id;
 | 
				
			||||||
	HAnimHierarchy *hierarchy;
 | 
						HAnimHierarchy *hierarchy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static HAnimData *get(Frame *f);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int32 hAnimOffset;
 | 
					extern int32 hAnimOffset;
 | 
				
			||||||
 | 
					extern bool32 hAnimDoStream;
 | 
				
			||||||
void registerHAnimPlugin(void);
 | 
					void registerHAnimPlugin(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Image
 | 
					struct Image
 | 
				
			||||||
@ -362,7 +386,7 @@ struct MatFX
 | 
				
			|||||||
		NOTHING = 0,
 | 
							NOTHING = 0,
 | 
				
			||||||
		BUMPMAP,
 | 
							BUMPMAP,
 | 
				
			||||||
		ENVMAP,
 | 
							ENVMAP,
 | 
				
			||||||
		BUMPENVMAP,
 | 
							BUMPENVMAP,	// BUMP | ENV
 | 
				
			||||||
		DUAL,
 | 
							DUAL,
 | 
				
			||||||
		UVTRANSFORM,
 | 
							UVTRANSFORM,
 | 
				
			||||||
		DUALUVTRANSFORM
 | 
							DUALUVTRANSFORM
 | 
				
			||||||
@ -401,8 +425,15 @@ struct MatFX
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	void setEffects(uint32 flags);
 | 
						void setEffects(uint32 flags);
 | 
				
			||||||
	int32 getEffectIndex(uint32 type);
 | 
						int32 getEffectIndex(uint32 type);
 | 
				
			||||||
 | 
						void setBumpTexture(Texture *t);
 | 
				
			||||||
 | 
						void setBumpCoefficient(float32 coef);
 | 
				
			||||||
	void setEnvTexture(Texture *t);
 | 
						void setEnvTexture(Texture *t);
 | 
				
			||||||
	void setEnvCoefficient(float32 coef);
 | 
						void setEnvCoefficient(float32 coef);
 | 
				
			||||||
 | 
						void setDualTexture(Texture *t);
 | 
				
			||||||
 | 
						void setDualSrcBlend(int32 blend);
 | 
				
			||||||
 | 
						void setDualDestBlend(int32 blend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static void enableEffects(Atomic *atomic);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct MatFXGlobals
 | 
					struct MatFXGlobals
 | 
				
			||||||
@ -423,6 +454,9 @@ struct Mesh
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct MeshHeader
 | 
					struct MeshHeader
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						enum {
 | 
				
			||||||
 | 
							TRISTRIP = 1
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
	uint32 flags;
 | 
						uint32 flags;
 | 
				
			||||||
	uint16 numMeshes;
 | 
						uint16 numMeshes;
 | 
				
			||||||
	// RW has uint16 serialNum here
 | 
						// RW has uint16 serialNum here
 | 
				
			||||||
@ -445,6 +479,12 @@ struct InstanceDataHeader
 | 
				
			|||||||
	uint32 platform;
 | 
						uint32 platform;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Triangle
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint16 v[3];
 | 
				
			||||||
 | 
						uint16 matId;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Geometry : PluginBase<Geometry>
 | 
					struct Geometry : PluginBase<Geometry>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	enum { ID = 8 };
 | 
						enum { ID = 8 };
 | 
				
			||||||
@ -455,7 +495,7 @@ struct Geometry : PluginBase<Geometry>
 | 
				
			|||||||
	int32 numMorphTargets;
 | 
						int32 numMorphTargets;
 | 
				
			||||||
	int32 numTexCoordSets;
 | 
						int32 numTexCoordSets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint16 *triangles;
 | 
						Triangle *triangles;
 | 
				
			||||||
	uint8 *colors;
 | 
						uint8 *colors;
 | 
				
			||||||
	float32 *texCoords[8];
 | 
						float32 *texCoords[8];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -481,6 +521,7 @@ struct Geometry : PluginBase<Geometry>
 | 
				
			|||||||
	bool32 hasColoredMaterial(void);
 | 
						bool32 hasColoredMaterial(void);
 | 
				
			||||||
	void allocateData(void);
 | 
						void allocateData(void);
 | 
				
			||||||
	void generateTriangles(int8 *adc = NULL);
 | 
						void generateTriangles(int8 *adc = NULL);
 | 
				
			||||||
 | 
						void buildMeshes(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum Flags
 | 
						enum Flags
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -515,6 +556,7 @@ struct Skin
 | 
				
			|||||||
	void init(int32 numBones, int32 numUsedBones, int32 numVertices);
 | 
						void init(int32 numBones, int32 numUsedBones, int32 numVertices);
 | 
				
			||||||
	void findNumWeights(int32 numVertices);
 | 
						void findNumWeights(int32 numVertices);
 | 
				
			||||||
	void findUsedBones(int32 numVertices);
 | 
						void findUsedBones(int32 numVertices);
 | 
				
			||||||
 | 
						static void setPipeline(Atomic *a, int32 type);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct SkinGlobals
 | 
					struct SkinGlobals
 | 
				
			||||||
@ -769,6 +811,11 @@ struct UVAnimDictionary
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern UVAnimDictionary *currentUVAnimDictionary;
 | 
					extern UVAnimDictionary *currentUVAnimDictionary;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct UVAnim
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						AnimInterpolator *interp[8];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int32 uvAnimOffset;
 | 
					extern int32 uvAnimOffset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void registerUVAnimPlugin(void);
 | 
					void registerUVAnimPlugin(void);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										14
									
								
								src/rwps2.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/rwps2.h
									
									
									
									
									
								
							@ -172,13 +172,13 @@ void registerPDSPlugin(int32 n);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct Ps2Raster : NativeRaster
 | 
					struct Ps2Raster : NativeRaster
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32 tex0[2];
 | 
						uint32 tex0[2];
 | 
				
			||||||
	uint32 tex1[2];
 | 
						uint32 tex1[2];
 | 
				
			||||||
	uint32 miptbp1[2];
 | 
						uint32 miptbp1[2];
 | 
				
			||||||
	uint32 miptbp2[2];
 | 
						uint32 miptbp2[2];
 | 
				
			||||||
	uint32 texelSize;
 | 
						uint32 texelSize;
 | 
				
			||||||
	uint32 paletteSize;
 | 
						uint32 paletteSize;
 | 
				
			||||||
	uint32 gsSize;
 | 
						uint32 gsSize;
 | 
				
			||||||
	int8 flags;
 | 
						int8 flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8 *data;	//tmp
 | 
						uint8 *data;	//tmp
 | 
				
			||||||
 | 
				
			|||||||
@ -36,6 +36,42 @@ usage(void)
 | 
				
			|||||||
	exit(1);
 | 
						exit(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					dumpUVAnim(Animation *anim)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						UVAnimCustomData *cust = (UVAnimCustomData*)anim->customData;
 | 
				
			||||||
 | 
						printf(" %s", cust->name);
 | 
				
			||||||
 | 
						for(int i = 0; i < 8; i++)
 | 
				
			||||||
 | 
							printf(" %d", cust->nodeToUVChannel[i]);
 | 
				
			||||||
 | 
						printf("\n %d %x\n", anim->numFrames, anim->interpInfo->id);
 | 
				
			||||||
 | 
						UVAnimKeyFrame *kf = (UVAnimKeyFrame*)anim->keyframes;
 | 
				
			||||||
 | 
						for(int i = 0; i < anim->numFrames; i++){
 | 
				
			||||||
 | 
							printf(" %f\n", kf->time);
 | 
				
			||||||
 | 
							printf("  %f %f %f %f %f %f\n", kf->uv[0], kf->uv[1], kf->uv[2], kf->uv[3], kf->uv[4], kf->uv[5]);
 | 
				
			||||||
 | 
							kf++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					dumpFrameHier(Frame *frame, int ind = 0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for(int i = 0; i < ind; i++)
 | 
				
			||||||
 | 
							printf("  ");
 | 
				
			||||||
 | 
						char *name = gta::getNodeName(frame);
 | 
				
			||||||
 | 
						HAnimData *hanim = HAnimData::get(frame);
 | 
				
			||||||
 | 
						printf("*%s %d %d %s\n", name[0] ? name : "---", frame->objectList.count(), hanim->id, hanim->hierarchy ? "HIERARCHY" : "");
 | 
				
			||||||
 | 
						if(hanim->hierarchy){
 | 
				
			||||||
 | 
							HAnimHierarchy *h = hanim->hierarchy;
 | 
				
			||||||
 | 
							for(int i = 0; i < h->numNodes; i++){
 | 
				
			||||||
 | 
								name = h->nodeInfo[i].frame ? gta::getNodeName(h->nodeInfo[i].frame) : "";
 | 
				
			||||||
 | 
								printf("\t\t%d %d\t%p %s\n", h->nodeInfo[i].id, h->nodeInfo[i].flags, h->nodeInfo[i].frame, name);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for(Frame *child = frame->child;
 | 
				
			||||||
 | 
						    child; child = child->next)
 | 
				
			||||||
 | 
							dumpFrameHier(child, ind+1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
main(int argc, char *argv[])
 | 
					main(int argc, char *argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -106,7 +142,10 @@ main(int argc, char *argv[])
 | 
				
			|||||||
		currentUVAnimDictionary = dict;
 | 
							currentUVAnimDictionary = dict;
 | 
				
			||||||
		readChunkHeaderInfo(&in, &header);
 | 
							readChunkHeaderInfo(&in, &header);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	assert(header.type == ID_CLUMP);
 | 
						if(header.type != ID_CLUMP){
 | 
				
			||||||
 | 
							in.close();
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	debugFile = argv[0];
 | 
						debugFile = argv[0];
 | 
				
			||||||
	c = Clump::streamRead(&in);
 | 
						c = Clump::streamRead(&in);
 | 
				
			||||||
	assert(c != NULL);
 | 
						assert(c != NULL);
 | 
				
			||||||
@ -132,6 +171,19 @@ main(int argc, char *argv[])
 | 
				
			|||||||
	//	printf("%d %f %f %f\n", l->getType(), l->color.red, l->color.green, l->color.blue);
 | 
						//	printf("%d %f %f %f\n", l->getType(), l->color.red, l->color.green, l->color.blue);
 | 
				
			||||||
	//}
 | 
						//}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HAnimHierarchy *hier = HAnimHierarchy::find(c->getFrame());
 | 
				
			||||||
 | 
						if(hier)
 | 
				
			||||||
 | 
							hier->attach();
 | 
				
			||||||
 | 
						dumpFrameHier(c->getFrame());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//if(currentUVAnimDictionary){
 | 
				
			||||||
 | 
						//	FORLIST(lnk, currentUVAnimDictionary->animations){
 | 
				
			||||||
 | 
						//		UVAnimDictEntry *de = UVAnimDictEntry::fromDict(lnk);
 | 
				
			||||||
 | 
						//		Animation *anim = de->anim;
 | 
				
			||||||
 | 
						//		dumpUVAnim(anim);
 | 
				
			||||||
 | 
						//	}
 | 
				
			||||||
 | 
						//}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int32 platform = findPlatform(c);
 | 
						int32 platform = findPlatform(c);
 | 
				
			||||||
	if(platform){
 | 
						if(platform){
 | 
				
			||||||
		rw::platform = platform;
 | 
							rw::platform = platform;
 | 
				
			||||||
@ -192,10 +244,10 @@ main(int argc, char *argv[])
 | 
				
			|||||||
//	out.close();
 | 
					//	out.close();
 | 
				
			||||||
//	delete[] data;
 | 
					//	delete[] data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c->destroy();
 | 
				
			||||||
	if(currentUVAnimDictionary)
 | 
						if(currentUVAnimDictionary)
 | 
				
			||||||
		currentUVAnimDictionary->destroy();
 | 
							currentUVAnimDictionary->destroy();
 | 
				
			||||||
	//currentTexDictionary->destroy();
 | 
						currentTexDictionary->destroy();
 | 
				
			||||||
	c->destroy();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -113,7 +113,7 @@
 | 
				
			|||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
 | 
					  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
 | 
				
			||||||
    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)</IncludePath>
 | 
					    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)</IncludePath>
 | 
				
			||||||
    <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(SolutionDir)$(Configuration)</LibraryPath>
 | 
					    <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)$(Platform)\$(Configuration)</LibraryPath>
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
 | 
					  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
 | 
				
			||||||
    <ClCompile>
 | 
					    <ClCompile>
 | 
				
			||||||
@ -202,6 +202,9 @@
 | 
				
			|||||||
      <OptimizeReferences>true</OptimizeReferences>
 | 
					      <OptimizeReferences>true</OptimizeReferences>
 | 
				
			||||||
      <AdditionalDependencies>librw.lib;%(AdditionalDependencies)</AdditionalDependencies>
 | 
					      <AdditionalDependencies>librw.lib;%(AdditionalDependencies)</AdditionalDependencies>
 | 
				
			||||||
    </Link>
 | 
					    </Link>
 | 
				
			||||||
 | 
					    <PostBuildEvent>
 | 
				
			||||||
 | 
					      <Command>copy /y "$(TargetPath)" "C:\Users\aap\bin\"</Command>
 | 
				
			||||||
 | 
					    </PostBuildEvent>
 | 
				
			||||||
  </ItemDefinitionGroup>
 | 
					  </ItemDefinitionGroup>
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
    <ClCompile Include="insttest.cpp" />
 | 
					    <ClCompile Include="insttest.cpp" />
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@ using namespace rw;
 | 
				
			|||||||
#include "rsl.h"
 | 
					#include "rsl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *argv0;
 | 
					char *argv0;
 | 
				
			||||||
 | 
					int32 atmOffset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
RslStream::relocate(void)
 | 
					RslStream::relocate(void)
 | 
				
			||||||
@ -68,6 +69,33 @@ mapID(int32 id)
 | 
				
			|||||||
	return id;
 | 
						return id;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static RslFrame*
 | 
				
			||||||
 | 
					findFrame(RslFrame *f, int32 id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if(f == NULL) return NULL;
 | 
				
			||||||
 | 
						if((f->nodeId & 0xFF) == (id & 0xFF))
 | 
				
			||||||
 | 
							return f;
 | 
				
			||||||
 | 
						RslFrame *ff = findFrame(f->next, id);
 | 
				
			||||||
 | 
						if(ff) return ff;
 | 
				
			||||||
 | 
						return findFrame(f->child, id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static RslFrame*
 | 
				
			||||||
 | 
					findChild(RslFrame *f)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for(RslFrame *c = f->child; c; c = c->next)
 | 
				
			||||||
 | 
							if(c->nodeId < 0)
 | 
				
			||||||
 | 
								return c;
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32 nextId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Node {
 | 
				
			||||||
 | 
						int32 id;
 | 
				
			||||||
 | 
						int32 parent;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Frame*
 | 
					Frame*
 | 
				
			||||||
convertFrame(RslFrame *f)
 | 
					convertFrame(RslFrame *f)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -91,20 +119,46 @@ convertFrame(RslFrame *f)
 | 
				
			|||||||
	HAnimData *hanim = PLUGINOFFSET(HAnimData, rwf, hAnimOffset);
 | 
						HAnimData *hanim = PLUGINOFFSET(HAnimData, rwf, hAnimOffset);
 | 
				
			||||||
	hanim->id = f->nodeId;
 | 
						hanim->id = f->nodeId;
 | 
				
			||||||
	if(f->hier){
 | 
						if(f->hier){
 | 
				
			||||||
		HAnimHierarchy *hier;
 | 
							int32 numNodes = f->hier->numNodes;
 | 
				
			||||||
		hanim->hierarchy = hier = new HAnimHierarchy;
 | 
							int32 *nodeFlags = new int32[numNodes];
 | 
				
			||||||
		hier->numNodes = f->hier->numNodes;
 | 
							int32 *nodeIDs = new int32[numNodes];
 | 
				
			||||||
		hier->flags = f->hier->flags;
 | 
					
 | 
				
			||||||
		hier->maxInterpKeyFrameSize = f->hier->maxKeyFrameSize;
 | 
							nextId = 2000;
 | 
				
			||||||
		hier->parentFrame = rwf;
 | 
							Node *nodehier = new Node[numNodes];
 | 
				
			||||||
		hier->parentHierarchy = hier;
 | 
							int32 stack[100];
 | 
				
			||||||
		hier->nodeInfo = new HAnimNodeInfo[hier->numNodes];
 | 
							int32 sp = 0;
 | 
				
			||||||
		for(int32 i = 0; i < hier->numNodes; i++){
 | 
							stack[sp] = -1;
 | 
				
			||||||
			hier->nodeInfo[i].id = mapID((uint8)f->hier->pNodeInfo[i].id);
 | 
							// Match up nodes with frames to fix and assign IDs
 | 
				
			||||||
			hier->nodeInfo[i].index = f->hier->pNodeInfo[i].index;
 | 
							// NOTE: assignment can only work reliably when not more
 | 
				
			||||||
			hier->nodeInfo[i].flags = f->hier->pNodeInfo[i].flags;
 | 
							//       than one child node needs an ID
 | 
				
			||||||
			hier->nodeInfo[i].frame = NULL;
 | 
							for(int32 i = 0; i < numNodes; i++){
 | 
				
			||||||
 | 
								RslHAnimNodeInfo *ni = &f->hier->pNodeInfo[i];
 | 
				
			||||||
 | 
								Node *n = &nodehier[i];
 | 
				
			||||||
 | 
								n->parent = stack[sp];
 | 
				
			||||||
 | 
								if(ni->flags & HAnimHierarchy::PUSH)
 | 
				
			||||||
 | 
									sp++;
 | 
				
			||||||
 | 
								stack[sp] = i;
 | 
				
			||||||
 | 
								RslFrame *ff = findFrame(f, (uint8)ni->id);
 | 
				
			||||||
 | 
								n->id = ff->nodeId;
 | 
				
			||||||
 | 
								if(n->id < 0){
 | 
				
			||||||
 | 
									ff = findFrame(f, nodehier[n->parent].id);
 | 
				
			||||||
 | 
									ff = findChild(ff);
 | 
				
			||||||
 | 
									n->id = ff->nodeId = nextId++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								//printf("%d %s %d %d\n", i, ff->name, n->id, n->parent);
 | 
				
			||||||
 | 
								if(ni->flags & HAnimHierarchy::POP)
 | 
				
			||||||
 | 
									sp--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								nodeFlags[i] = ni->flags;
 | 
				
			||||||
 | 
								nodeIDs[i] = n->id;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							HAnimHierarchy *hier = HAnimHierarchy::create(numNodes, nodeFlags, nodeIDs, f->hier->flags, f->hier->maxKeyFrameSize);
 | 
				
			||||||
 | 
							hanim->hierarchy = hier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							delete[] nodeFlags;
 | 
				
			||||||
 | 
							delete[] nodeIDs;
 | 
				
			||||||
 | 
							delete[] nodehier;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return rwf;
 | 
						return rwf;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -302,6 +356,8 @@ convertAtomic(RslAtomic *atomic)
 | 
				
			|||||||
	Geometry *rwg = Geometry::create(0, 0, 0);
 | 
						Geometry *rwg = Geometry::create(0, 0, 0);
 | 
				
			||||||
	rwa->geometry = rwg;
 | 
						rwa->geometry = rwg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*PLUGINOFFSET(RslAtomic*, rwa, atmOffset) = atomic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rwg->numMaterials = g->matList.numMaterials;
 | 
						rwg->numMaterials = g->matList.numMaterials;
 | 
				
			||||||
	rwg->materialList = new Material*[rwg->numMaterials];
 | 
						rwg->materialList = new Material*[rwg->numMaterials];
 | 
				
			||||||
	for(int32 i = 0; i < rwg->numMaterials; i++)
 | 
						for(int32 i = 0; i < rwg->numMaterials; i++)
 | 
				
			||||||
@ -447,6 +503,41 @@ makeTextures(RslAtomic *atomic, void*)
 | 
				
			|||||||
	return atomic;
 | 
						return atomic;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					moveAtomics(Frame *f)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static char *names[] = { "", "hi_ok", "hi_dam" };
 | 
				
			||||||
 | 
						if(f == NULL) return;
 | 
				
			||||||
 | 
						int n = f->objectList.count();
 | 
				
			||||||
 | 
						if(n > 1){
 | 
				
			||||||
 | 
							char *oldname = gta::getNodeName(f);
 | 
				
			||||||
 | 
							ObjectWithFrame **objs = new ObjectWithFrame*[n];
 | 
				
			||||||
 | 
							int i = 0;
 | 
				
			||||||
 | 
							FORLIST(lnk, f->objectList){
 | 
				
			||||||
 | 
								ObjectWithFrame *obj = ObjectWithFrame::fromFrame(lnk);
 | 
				
			||||||
 | 
								assert(obj->type == Atomic::ID);
 | 
				
			||||||
 | 
								objs[i] = obj;
 | 
				
			||||||
 | 
								obj->setFrame(NULL);
 | 
				
			||||||
 | 
								i++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for(i = 0; i < n; i++){
 | 
				
			||||||
 | 
								Frame *ff = Frame::create();
 | 
				
			||||||
 | 
								RslAtomic *rsla = *PLUGINOFFSET(RslAtomic*, objs[i], atmOffset);
 | 
				
			||||||
 | 
								char *name = gta::getNodeName(ff);
 | 
				
			||||||
 | 
								strncpy(name, oldname, 24);
 | 
				
			||||||
 | 
								char *end = strrchr(name, '_');
 | 
				
			||||||
 | 
								if(end){
 | 
				
			||||||
 | 
									*(++end) = '\0';
 | 
				
			||||||
 | 
									strcat(end, names[rsla->unk3&3]);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								f->addChild(ff);
 | 
				
			||||||
 | 
								objs[i]->setFrame(ff);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							delete[] objs;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						moveAtomics(f->next);
 | 
				
			||||||
 | 
						moveAtomics(f->child);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -751,6 +842,7 @@ usage(void)
 | 
				
			|||||||
	fprintf(stderr, "\t-v RW version, e.g. 33004 for 3.3.0.4\n");
 | 
						fprintf(stderr, "\t-v RW version, e.g. 33004 for 3.3.0.4\n");
 | 
				
			||||||
	fprintf(stderr, "\t-x extract textures to tga\n");
 | 
						fprintf(stderr, "\t-x extract textures to tga\n");
 | 
				
			||||||
	fprintf(stderr, "\t-s don't unswizzle textures\n");
 | 
						fprintf(stderr, "\t-s don't unswizzle textures\n");
 | 
				
			||||||
 | 
						fprintf(stderr, "\t-a fix Atomics placement inside hierarchy (mdl files)\n");
 | 
				
			||||||
	exit(1);
 | 
						exit(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -758,11 +850,13 @@ int
 | 
				
			|||||||
main(int argc, char *argv[])
 | 
					main(int argc, char *argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	gta::attachPlugins();
 | 
						gta::attachPlugins();
 | 
				
			||||||
 | 
						atmOffset = Atomic::registerPlugin(sizeof(void*), 0x1000000, NULL, NULL, NULL);
 | 
				
			||||||
	rw::version = 0x34003;
 | 
						rw::version = 0x34003;
 | 
				
			||||||
	rw::platform = PLATFORM_D3D8;
 | 
						rw::platform = PLATFORM_D3D8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert(sizeof(void*) == 4);
 | 
						assert(sizeof(void*) == 4);
 | 
				
			||||||
	int extract = 0;
 | 
						int extract = 0;
 | 
				
			||||||
 | 
						int fixAtomics = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ARGBEGIN{
 | 
						ARGBEGIN{
 | 
				
			||||||
	case 'v':
 | 
						case 'v':
 | 
				
			||||||
@ -774,6 +868,9 @@ main(int argc, char *argv[])
 | 
				
			|||||||
	case 'x':
 | 
						case 'x':
 | 
				
			||||||
		extract++;
 | 
							extract++;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case 'a':
 | 
				
			||||||
 | 
							fixAtomics++;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		usage();
 | 
							usage();
 | 
				
			||||||
	}ARGEND;
 | 
						}ARGEND;
 | 
				
			||||||
@ -906,6 +1003,8 @@ main(int argc, char *argv[])
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	writeDff:
 | 
						writeDff:
 | 
				
			||||||
		rwc = convertClump(clump);
 | 
							rwc = convertClump(clump);
 | 
				
			||||||
 | 
							if(fixAtomics)
 | 
				
			||||||
 | 
								moveAtomics(rwc->getFrame());
 | 
				
			||||||
		if(argc > 1)
 | 
							if(argc > 1)
 | 
				
			||||||
			assert(stream.open(argv[1], "wb"));
 | 
								assert(stream.open(argv[1], "wb"));
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user