mirror of
				https://github.com/aap/librw.git
				synced 2025-11-04 08:50:09 +00:00 
			
		
		
		
	more error handling
This commit is contained in:
		
							parent
							
								
									1bb17b3094
								
							
						
					
					
						commit
						634a96be07
					
				
							
								
								
									
										56
									
								
								src/anim.cpp
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								src/anim.cpp
									
									
									
									
									
								
							@ -4,12 +4,13 @@
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include "rwbase.h"
 | 
			
		||||
#include "rwerror.h"
 | 
			
		||||
#include "rwplg.h"
 | 
			
		||||
#include "rwpipeline.h"
 | 
			
		||||
#include "rwobjects.h"
 | 
			
		||||
#include "rwplugins.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
#define PLUGIN_ID 2	// ?
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
 | 
			
		||||
@ -21,7 +22,7 @@ void
 | 
			
		||||
registerAnimInterpolatorInfo(AnimInterpolatorInfo *interpInfo)
 | 
			
		||||
{
 | 
			
		||||
	for(int32 i = 0; i < MAXINTERPINFO; i++)
 | 
			
		||||
		if(interpInfoList[i] == NULL){
 | 
			
		||||
		if(interpInfoList[i] == nil){
 | 
			
		||||
			interpInfoList[i] = interpInfo;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
@ -35,7 +36,7 @@ findAnimInterpolatorInfo(int32 id)
 | 
			
		||||
		if(interpInfoList[i] && interpInfoList[i]->id == id)
 | 
			
		||||
			return interpInfoList[i];
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Animation*
 | 
			
		||||
@ -65,7 +66,8 @@ Animation*
 | 
			
		||||
Animation::streamRead(Stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	Animation *anim;
 | 
			
		||||
	assert(stream->readI32() == 0x100);
 | 
			
		||||
	if(stream->readI32() != 0x100)
 | 
			
		||||
		return nil;
 | 
			
		||||
	int32 typeID = stream->readI32();
 | 
			
		||||
	AnimInterpolatorInfo *interpInfo = findAnimInterpolatorInfo(typeID);
 | 
			
		||||
	int32 numFrames = stream->readI32();
 | 
			
		||||
@ -156,7 +158,11 @@ UVAnimDictionary *currentUVAnimDictionary;
 | 
			
		||||
UVAnimDictionary*
 | 
			
		||||
UVAnimDictionary::create(void)
 | 
			
		||||
{
 | 
			
		||||
	UVAnimDictionary *dict = (UVAnimDictionary*)malloc(sizeof(*dict));
 | 
			
		||||
	UVAnimDictionary *dict = (UVAnimDictionary*)malloc(sizeof(UVAnimDictionary));
 | 
			
		||||
	if(dict == nil){
 | 
			
		||||
		RWERROR((ERR_ALLOC, sizeof(UVAnimDictionary)));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	dict->animations.init();
 | 
			
		||||
	return dict;
 | 
			
		||||
}
 | 
			
		||||
@ -177,7 +183,6 @@ void
 | 
			
		||||
UVAnimDictionary::add(Animation *anim)
 | 
			
		||||
{
 | 
			
		||||
	UVAnimDictEntry *de = new UVAnimDictEntry;
 | 
			
		||||
	UVAnimCustomData *custom = (UVAnimCustomData*)anim->customData;
 | 
			
		||||
	de->anim = anim;
 | 
			
		||||
	this->animations.append(&de->inDict);
 | 
			
		||||
}
 | 
			
		||||
@ -185,14 +190,29 @@ UVAnimDictionary::add(Animation *anim)
 | 
			
		||||
UVAnimDictionary*
 | 
			
		||||
UVAnimDictionary::streamRead(Stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	UVAnimDictionary *dict = UVAnimDictionary::create();
 | 
			
		||||
	if(dict == nil)
 | 
			
		||||
		return nil;
 | 
			
		||||
	int32 numAnims = stream->readI32();
 | 
			
		||||
	Animation *anim;
 | 
			
		||||
	for(int32 i = 0; i < numAnims; i++){
 | 
			
		||||
		assert(findChunk(stream, ID_ANIMANIMATION, NULL, NULL));
 | 
			
		||||
		dict->add(Animation::streamRead(stream));
 | 
			
		||||
		if(!findChunk(stream, ID_ANIMANIMATION, nil, nil)){
 | 
			
		||||
			RWERROR((ERR_CHUNK, "ANIMANIMATION"));
 | 
			
		||||
			goto fail;
 | 
			
		||||
		}
 | 
			
		||||
		anim = Animation::streamRead(stream);
 | 
			
		||||
		if(anim == nil)
 | 
			
		||||
			goto fail;
 | 
			
		||||
		dict->add(anim);
 | 
			
		||||
	}
 | 
			
		||||
	return dict;
 | 
			
		||||
fail:
 | 
			
		||||
	dict->destroy();
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
@ -214,7 +234,6 @@ uint32
 | 
			
		||||
UVAnimDictionary::streamGetSize(void)
 | 
			
		||||
{
 | 
			
		||||
	uint32 size = 12 + 4;
 | 
			
		||||
	int32 numAnims = this->count();
 | 
			
		||||
	FORLIST(lnk, this->animations){
 | 
			
		||||
		UVAnimDictEntry *de = UVAnimDictEntry::fromDict(lnk);
 | 
			
		||||
		size += 12 + de->anim->streamGetSize();
 | 
			
		||||
@ -231,7 +250,7 @@ UVAnimDictionary::find(const char *name)
 | 
			
		||||
		if(strncmp_ci(custom->name, name, 32) == 0)
 | 
			
		||||
			return anim;
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -358,21 +377,24 @@ makeDummyAnimation(const char *name)
 | 
			
		||||
	return anim;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
readUVAnim(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	UVAnim *uvanim = PLUGINOFFSET(UVAnim, object, offset);
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	char name[32];
 | 
			
		||||
	uint32 mask = stream->readI32();
 | 
			
		||||
	uint32 bit = 1;
 | 
			
		||||
	for(int32 i = 0; i < 8; i++){
 | 
			
		||||
		if(mask & bit){
 | 
			
		||||
			stream->read(name, 32);
 | 
			
		||||
			Animation *anim = NULL;
 | 
			
		||||
			Animation *anim = nil;
 | 
			
		||||
			if(currentUVAnimDictionary)
 | 
			
		||||
				anim = currentUVAnimDictionary->find(name);
 | 
			
		||||
			if(anim == NULL){
 | 
			
		||||
			if(anim == nil){
 | 
			
		||||
				anim = makeDummyAnimation(name);
 | 
			
		||||
				if(currentUVAnimDictionary)
 | 
			
		||||
					currentUVAnimDictionary->add(anim);
 | 
			
		||||
@ -384,9 +406,10 @@ readUVAnim(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
		}
 | 
			
		||||
		bit <<= 1;
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeUVAnim(Stream *stream, int32 size, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	UVAnim *uvanim = PLUGINOFFSET(UVAnim, object, offset);
 | 
			
		||||
@ -406,6 +429,7 @@ writeUVAnim(Stream *stream, int32 size, void *object, int32 offset, int32)
 | 
			
		||||
			stream->write(custom->name, 32);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
 | 
			
		||||
@ -6,3 +6,7 @@ ECODE(ERR_FILE,
 | 
			
		||||
      "Couldn't open file %s")
 | 
			
		||||
ECODE(ERR_CHUNK,
 | 
			
		||||
      "Couldn't find chunk %s")
 | 
			
		||||
ECODE(ERR_VERSION,
 | 
			
		||||
      "Unsupported version %X")
 | 
			
		||||
ECODE(ERR_PLATFORM,
 | 
			
		||||
      "Unsupported platform %d")
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,6 @@
 | 
			
		||||
#include "rwobjects.h"
 | 
			
		||||
#include "rwengine.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
#define PLUGIN_ID 2
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
@ -74,6 +72,8 @@ Clump::streamRead(Stream *stream)
 | 
			
		||||
	uint32 length, version;
 | 
			
		||||
	int32 buf[3];
 | 
			
		||||
	Clump *clump;
 | 
			
		||||
	int32 numGeometries;
 | 
			
		||||
	Geometry **geometryList;
 | 
			
		||||
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, &length, &version)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"));
 | 
			
		||||
@ -103,8 +103,8 @@ Clump::streamRead(Stream *stream)
 | 
			
		||||
	clump->setFrame(frmlst.frames[0]);
 | 
			
		||||
 | 
			
		||||
	// Geometry list
 | 
			
		||||
	int32 numGeometries = 0;
 | 
			
		||||
	Geometry **geometryList = nil;
 | 
			
		||||
	numGeometries = 0;
 | 
			
		||||
	geometryList = nil;
 | 
			
		||||
	if(version >= 0x30400){
 | 
			
		||||
		if(!findChunk(stream, ID_GEOMETRYLIST, nil, nil)){
 | 
			
		||||
			RWERROR((ERR_CHUNK, "GEOMETRYLIST"));
 | 
			
		||||
@ -502,13 +502,14 @@ Atomic::defaultRenderCB(Atomic *atomic)
 | 
			
		||||
 | 
			
		||||
// Atomic Rights plugin
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
readAtomicRights(Stream *stream, int32, void *, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	stream->read(atomicRights, 8);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeAtomicRights(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Atomic *atomic = (Atomic*)object;
 | 
			
		||||
@ -516,6 +517,7 @@ writeAtomicRights(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
	buffer[0] = atomic->pipeline->pluginID;
 | 
			
		||||
	buffer[1] = atomic->pipeline->pluginData;
 | 
			
		||||
	stream->write(buffer, 8);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,6 @@
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include <new>
 | 
			
		||||
 | 
			
		||||
#include "rwbase.h"
 | 
			
		||||
#include "rwplg.h"
 | 
			
		||||
#include "rwpipeline.h"
 | 
			
		||||
@ -562,7 +560,6 @@ static void*
 | 
			
		||||
createNativeRaster(void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	D3dRaster *raster = PLUGINOFFSET(D3dRaster, object, offset);
 | 
			
		||||
	new (raster) D3dRaster;
 | 
			
		||||
	raster->texture = NULL;
 | 
			
		||||
	raster->palette = NULL;
 | 
			
		||||
	raster->format = 0;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										73
									
								
								src/d3d8.cpp
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								src/d3d8.cpp
									
									
									
									
									
								
							@ -4,6 +4,7 @@
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include "rwbase.h"
 | 
			
		||||
#include "rwerror.h"
 | 
			
		||||
#include "rwplg.h"
 | 
			
		||||
#include "rwpipeline.h"
 | 
			
		||||
#include "rwobjects.h"
 | 
			
		||||
@ -11,7 +12,7 @@
 | 
			
		||||
#include "rwd3d.h"
 | 
			
		||||
#include "rwd3d8.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
#define PLUGIN_ID 2
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
namespace d3d8 {
 | 
			
		||||
@ -51,11 +52,12 @@ void*
 | 
			
		||||
destroyNativeData(void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_D3D8);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_D3D8)
 | 
			
		||||
		return object;
 | 
			
		||||
	InstanceDataHeader *header =
 | 
			
		||||
		(InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	geometry->instData = NULL;
 | 
			
		||||
	geometry->instData = nil;
 | 
			
		||||
	InstanceData *inst = header->inst;
 | 
			
		||||
	for(uint32 i = 0; i < header->numMeshes; i++){
 | 
			
		||||
		deleteObject(inst->indexBuffer);
 | 
			
		||||
@ -67,13 +69,20 @@ destroyNativeData(void *object, int32, int32)
 | 
			
		||||
	return object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	uint32 vers;
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, &vers));
 | 
			
		||||
	assert(stream->readU32() == PLATFORM_D3D8);
 | 
			
		||||
	uint32 platform;
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"))
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	platform = stream->readU32();
 | 
			
		||||
	if(platform != PLATFORM_D3D8){
 | 
			
		||||
		RWERROR((ERR_PLATFORM, platform));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	InstanceDataHeader *header = new InstanceDataHeader;
 | 
			
		||||
	geometry->instData = header;
 | 
			
		||||
	header->platform = PLATFORM_D3D8;
 | 
			
		||||
@ -96,8 +105,8 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
		inst->material = geometry->materialList[matid];
 | 
			
		||||
		inst->vertexShader = *(uint32*)p; p += 4;
 | 
			
		||||
		inst->primType = *(uint32*)p; p += 4;
 | 
			
		||||
		inst->indexBuffer = NULL; p += 4;
 | 
			
		||||
		inst->vertexBuffer = NULL; p += 4;
 | 
			
		||||
		inst->indexBuffer = nil; p += 4;
 | 
			
		||||
		inst->vertexBuffer = nil; p += 4;
 | 
			
		||||
		inst->baseIndex = 0; p += 4;
 | 
			
		||||
		inst->vertexAlpha = *p++;
 | 
			
		||||
		inst->managed = 0; p++;
 | 
			
		||||
@ -121,15 +130,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
 | 
			
		||||
		inst++;
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	writeChunkHeader(stream, ID_STRUCT, len-12);
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_D3D8);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_D3D8)
 | 
			
		||||
		return stream;
 | 
			
		||||
	stream->writeU32(PLATFORM_D3D8);
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
 | 
			
		||||
 | 
			
		||||
@ -172,14 +183,16 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
 | 
			
		||||
		unlockVertices(inst->vertexBuffer);
 | 
			
		||||
		inst++;
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32
 | 
			
		||||
getSizeNativeData(void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_D3D8);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_D3D8)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	InstanceData *inst = header->inst;
 | 
			
		||||
@ -195,7 +208,7 @@ void
 | 
			
		||||
registerNativeDataPlugin(void)
 | 
			
		||||
{
 | 
			
		||||
	Geometry::registerPlugin(0, ID_NATIVEDATA,
 | 
			
		||||
	                         NULL, destroyNativeData, NULL);
 | 
			
		||||
	                         nil, destroyNativeData, nil);
 | 
			
		||||
	Geometry::registerPluginStream(ID_NATIVEDATA,
 | 
			
		||||
	                               readNativeData,
 | 
			
		||||
	                               writeNativeData,
 | 
			
		||||
@ -229,7 +242,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
		inst->material = mesh->material;
 | 
			
		||||
		inst->vertexShader = 0;
 | 
			
		||||
		inst->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST;
 | 
			
		||||
		inst->vertexBuffer = NULL;
 | 
			
		||||
		inst->vertexBuffer = nil;
 | 
			
		||||
		inst->baseIndex = 0;	// (maybe) not used by us
 | 
			
		||||
		inst->vertexAlpha = 0;
 | 
			
		||||
		inst->managed = 0;
 | 
			
		||||
@ -257,7 +270,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
	Geometry *geo = atomic->geometry;
 | 
			
		||||
	if((geo->geoflags & Geometry::NATIVE) == 0)
 | 
			
		||||
		return;
 | 
			
		||||
	assert(geo->instData != NULL);
 | 
			
		||||
	assert(geo->instData != nil);
 | 
			
		||||
	assert(geo->instData->platform == PLATFORM_D3D8);
 | 
			
		||||
	geo->geoflags &= ~Geometry::NATIVE;
 | 
			
		||||
	geo->allocateData();
 | 
			
		||||
@ -290,7 +303,7 @@ render(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
	Geometry *geo = atomic->geometry;
 | 
			
		||||
	if((geo->geoflags & Geometry::NATIVE) == 0)
 | 
			
		||||
		pipe->instance(atomic);
 | 
			
		||||
	assert(geo->instData != NULL);
 | 
			
		||||
	assert(geo->instData != nil);
 | 
			
		||||
	assert(geo->instData->platform == PLATFORM_D3D8);
 | 
			
		||||
	if(pipe->renderCB)
 | 
			
		||||
		pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData);
 | 
			
		||||
@ -302,9 +315,9 @@ ObjPipeline::ObjPipeline(uint32 platform)
 | 
			
		||||
	this->impl.instance = d3d8::instance;
 | 
			
		||||
	this->impl.uninstance = d3d8::uninstance;
 | 
			
		||||
	this->impl.render = d3d8::render;
 | 
			
		||||
	this->instanceCB = NULL;
 | 
			
		||||
	this->uninstanceCB = NULL;
 | 
			
		||||
	this->renderCB = NULL;
 | 
			
		||||
	this->instanceCB = nil;
 | 
			
		||||
	this->uninstanceCB = nil;
 | 
			
		||||
	this->renderCB = nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -463,9 +476,19 @@ readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format
 | 
			
		||||
Texture*
 | 
			
		||||
readNativeTexture(Stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
			
		||||
	assert(stream->readU32() == PLATFORM_D3D8);
 | 
			
		||||
	Texture *tex = Texture::create(NULL);
 | 
			
		||||
	uint32 platform;
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"))
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	platform = stream->readU32();
 | 
			
		||||
	if(platform != PLATFORM_D3D8){
 | 
			
		||||
		RWERROR((ERR_PLATFORM, platform));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	Texture *tex = Texture::create(nil);
 | 
			
		||||
	if(tex == nil)
 | 
			
		||||
		return nil;
 | 
			
		||||
 | 
			
		||||
	// Texture
 | 
			
		||||
	tex->filterAddressing = stream->readU32();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										81
									
								
								src/d3d9.cpp
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								src/d3d9.cpp
									
									
									
									
									
								
							@ -4,6 +4,7 @@
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include "rwbase.h"
 | 
			
		||||
#include "rwerror.h"
 | 
			
		||||
#include "rwplg.h"
 | 
			
		||||
#include "rwpipeline.h"
 | 
			
		||||
#include "rwobjects.h"
 | 
			
		||||
@ -11,6 +12,8 @@
 | 
			
		||||
#include "rwd3d.h"
 | 
			
		||||
#include "rwd3d9.h"
 | 
			
		||||
 | 
			
		||||
#define PLUGIN_ID 2
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
namespace d3d9 {
 | 
			
		||||
using namespace d3d;
 | 
			
		||||
@ -70,11 +73,12 @@ void*
 | 
			
		||||
destroyNativeData(void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_D3D9);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_D3D9)
 | 
			
		||||
		return object;
 | 
			
		||||
	InstanceDataHeader *header =
 | 
			
		||||
		(InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	geometry->instData = NULL;
 | 
			
		||||
	geometry->instData = nil;
 | 
			
		||||
	deleteObject(header->vertexDeclaration);
 | 
			
		||||
	deleteObject(header->indexBuffer);
 | 
			
		||||
	deleteObject(header->vertexStream[0].vertexBuffer);
 | 
			
		||||
@ -84,13 +88,20 @@ destroyNativeData(void *object, int32, int32)
 | 
			
		||||
	return object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	uint32 vers;
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, &vers));
 | 
			
		||||
	assert(stream->readU32() == PLATFORM_D3D9);
 | 
			
		||||
	uint32 platform;
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"))
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	platform = stream->readU32();
 | 
			
		||||
	if(platform != PLATFORM_D3D9){
 | 
			
		||||
		RWERROR((ERR_PLATFORM, platform));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	InstanceDataHeader *header = new InstanceDataHeader;
 | 
			
		||||
	geometry->instData = header;
 | 
			
		||||
	header->platform = PLATFORM_D3D9;
 | 
			
		||||
@ -101,11 +112,11 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
	uint8 *p = data;
 | 
			
		||||
	header->serialNumber = *(uint32*)p; p += 4;
 | 
			
		||||
	header->numMeshes = *(uint32*)p; p += 4;
 | 
			
		||||
	header->indexBuffer = NULL; p += 4;
 | 
			
		||||
	header->indexBuffer = nil; p += 4;
 | 
			
		||||
	header->primType = *(uint32*)p; p += 4;
 | 
			
		||||
	p += 16*2;	// skip vertex streams, they're repeated with the vertex buffers
 | 
			
		||||
	header->useOffsets = *(bool32*)p; p += 4;
 | 
			
		||||
	header->vertexDeclaration = NULL; p += 4;
 | 
			
		||||
	header->vertexDeclaration = nil; p += 4;
 | 
			
		||||
	header->totalNumIndex = *(uint32*)p; p += 4;
 | 
			
		||||
	header->totalNumVertex = *(uint32*)p; p += 4;
 | 
			
		||||
	header->inst = new InstanceData[header->numMeshes];
 | 
			
		||||
@ -117,7 +128,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
		uint32 matid = *(uint32*)p; p += 4;
 | 
			
		||||
		inst->material = geometry->materialList[matid];
 | 
			
		||||
		inst->vertexAlpha = *(bool32*)p; p += 4;
 | 
			
		||||
		inst->vertexShader = NULL; p += 4;
 | 
			
		||||
		inst->vertexShader = nil; p += 4;
 | 
			
		||||
		inst->baseIndex = 0; p += 4;
 | 
			
		||||
		inst->numVertices = *(uint32*)p; p += 4;
 | 
			
		||||
		inst->startIndex = *(uint32*)p; p += 4;
 | 
			
		||||
@ -147,7 +158,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
		s->managed = *p++;
 | 
			
		||||
		s->dynamicLock = *p++;
 | 
			
		||||
 | 
			
		||||
		if(s->vertexBuffer == NULL)
 | 
			
		||||
		if(s->vertexBuffer == nil)
 | 
			
		||||
			continue;
 | 
			
		||||
		// TODO: unset managed flag when using morph targets.
 | 
			
		||||
		//       also uses different buffer type and locks differently
 | 
			
		||||
@ -165,15 +176,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	delete[] data;
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	writeChunkHeader(stream, ID_STRUCT, len-12);
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_D3D9);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_D3D9)
 | 
			
		||||
		return stream;
 | 
			
		||||
	stream->writeU32(PLATFORM_D3D9);
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	int32 size = 64 + geometry->meshHeader->numMeshes*36;
 | 
			
		||||
@ -228,7 +241,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
 | 
			
		||||
		*p++ = s->dynamicLock;
 | 
			
		||||
		stream->write(data, 16);
 | 
			
		||||
 | 
			
		||||
		if(s->vertexBuffer == NULL)
 | 
			
		||||
		if(s->vertexBuffer == nil)
 | 
			
		||||
			continue;
 | 
			
		||||
		uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
 | 
			
		||||
		stream->write(verts, s->stride*header->totalNumVertex);
 | 
			
		||||
@ -236,17 +249,19 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	delete[] data;
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32
 | 
			
		||||
getSizeNativeData(void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_D3D9);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_D3D9)
 | 
			
		||||
		return 0;
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	int32 size = 12 + 4 + 4 + 64 + header->numMeshes*36;
 | 
			
		||||
	uint32 numElt = getDeclaration(header->vertexDeclaration, NULL);
 | 
			
		||||
	uint32 numElt = getDeclaration(header->vertexDeclaration, nil);
 | 
			
		||||
	size += 4 + numElt*8;
 | 
			
		||||
	size += 2*header->totalNumIndex;
 | 
			
		||||
	size += 0x10 + header->vertexStream[0].stride*header->totalNumVertex;
 | 
			
		||||
@ -258,7 +273,7 @@ void
 | 
			
		||||
registerNativeDataPlugin(void)
 | 
			
		||||
{
 | 
			
		||||
	Geometry::registerPlugin(0, ID_NATIVEDATA,
 | 
			
		||||
	                         NULL, destroyNativeData, NULL);
 | 
			
		||||
	                         nil, destroyNativeData, nil);
 | 
			
		||||
	Geometry::registerPluginStream(ID_NATIVEDATA,
 | 
			
		||||
	                               readNativeData,
 | 
			
		||||
	                               writeNativeData,
 | 
			
		||||
@ -298,7 +313,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
		inst->numIndex = mesh->numIndices;
 | 
			
		||||
		inst->material = mesh->material;
 | 
			
		||||
		inst->vertexAlpha = 0;
 | 
			
		||||
		inst->vertexShader = NULL;
 | 
			
		||||
		inst->vertexShader = nil;
 | 
			
		||||
		inst->baseIndex = inst->minVert;
 | 
			
		||||
		inst->startIndex = startindex;
 | 
			
		||||
		inst->numPrimitives = header->primType == D3DPT_TRIANGLESTRIP ? inst->numIndex-2 : inst->numIndex/3;
 | 
			
		||||
@ -325,7 +340,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
	Geometry *geo = atomic->geometry;
 | 
			
		||||
	if((geo->geoflags & Geometry::NATIVE) == 0)
 | 
			
		||||
		return;
 | 
			
		||||
	assert(geo->instData != NULL);
 | 
			
		||||
	assert(geo->instData != nil);
 | 
			
		||||
	assert(geo->instData->platform == PLATFORM_D3D9);
 | 
			
		||||
	geo->geoflags &= ~Geometry::NATIVE;
 | 
			
		||||
	geo->allocateData();
 | 
			
		||||
@ -358,7 +373,7 @@ render(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
	Geometry *geo = atomic->geometry;
 | 
			
		||||
	if((geo->geoflags & Geometry::NATIVE) == 0)
 | 
			
		||||
		pipe->instance(atomic);
 | 
			
		||||
	assert(geo->instData != NULL);
 | 
			
		||||
	assert(geo->instData != nil);
 | 
			
		||||
	assert(geo->instData->platform == PLATFORM_D3D9);
 | 
			
		||||
	if(pipe->renderCB)
 | 
			
		||||
		pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData);
 | 
			
		||||
@ -370,9 +385,9 @@ ObjPipeline::ObjPipeline(uint32 platform)
 | 
			
		||||
	this->impl.instance = d3d9::instance;
 | 
			
		||||
	this->impl.uninstance = d3d9::uninstance;
 | 
			
		||||
	this->impl.render = d3d9::render;
 | 
			
		||||
	this->instanceCB = NULL;
 | 
			
		||||
	this->uninstanceCB = NULL;
 | 
			
		||||
	this->renderCB = NULL;
 | 
			
		||||
	this->instanceCB = nil;
 | 
			
		||||
	this->uninstanceCB = nil;
 | 
			
		||||
	this->renderCB = nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -571,9 +586,19 @@ makeMatFXPipeline(void)
 | 
			
		||||
Texture*
 | 
			
		||||
readNativeTexture(Stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
			
		||||
	assert(stream->readU32() == PLATFORM_D3D9);
 | 
			
		||||
	Texture *tex = Texture::create(NULL);
 | 
			
		||||
	uint32 platform;
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"))
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	platform = stream->readU32();
 | 
			
		||||
	if(platform != PLATFORM_D3D9){
 | 
			
		||||
		RWERROR((ERR_PLATFORM, platform));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	Texture *tex = Texture::create(nil);
 | 
			
		||||
	if(tex == nil)
 | 
			
		||||
		return nil;
 | 
			
		||||
 | 
			
		||||
	// Texture
 | 
			
		||||
	tex->filterAddressing = stream->readU32();
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,11 @@
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
 | 
			
		||||
#include "rwbase.h"
 | 
			
		||||
#include "rwerror.h"
 | 
			
		||||
#include "rwplg.h"
 | 
			
		||||
#include "rwpipeline.h"
 | 
			
		||||
#include "rwobjects.h"
 | 
			
		||||
#include "rwengine.h"
 | 
			
		||||
 | 
			
		||||
#define PLUGIN_ID 0
 | 
			
		||||
 | 
			
		||||
@ -260,15 +257,15 @@ FrameList_::streamRead(Stream *stream)
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	this->numFrames = stream->readI32();
 | 
			
		||||
	Frame **frameList = (Frame**)malloc(this->numFrames*sizeof(Frame*));
 | 
			
		||||
	if(frameList == nil){
 | 
			
		||||
	this->frames = (Frame**)malloc(this->numFrames*sizeof(Frame*));
 | 
			
		||||
	if(this->frames == nil){
 | 
			
		||||
		RWERROR((ERR_ALLOC, this->numFrames*sizeof(Frame*)));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	for(int32 i = 0; i < this->numFrames; i++){
 | 
			
		||||
		Frame *f;
 | 
			
		||||
		stream->read(&buf, sizeof(buf));
 | 
			
		||||
		frameList[i] = f = Frame::create();
 | 
			
		||||
		this->frames[i] = f = Frame::create();
 | 
			
		||||
		if(f == nil){
 | 
			
		||||
			// TODO: clean up frames?
 | 
			
		||||
			free(this->frames);
 | 
			
		||||
@ -284,10 +281,10 @@ FrameList_::streamRead(Stream *stream)
 | 
			
		||||
		f->matrix.posw = 1.0f;
 | 
			
		||||
		//f->matflag = buf.matflag;
 | 
			
		||||
		if(buf.parent >= 0)
 | 
			
		||||
			frameList[buf.parent]->addChild(f);
 | 
			
		||||
			this->frames[buf.parent]->addChild(f);
 | 
			
		||||
	}
 | 
			
		||||
	for(int32 i = 0; i < this->numFrames; i++)
 | 
			
		||||
		frameList[i]->streamReadPlugins(stream);
 | 
			
		||||
		this->frames[i]->streamReadPlugins(stream);
 | 
			
		||||
	return this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -334,6 +331,7 @@ FrameList_::streamGetSize(Frame *f)
 | 
			
		||||
	int32 numFrames = f->count();
 | 
			
		||||
	uint32 size = 12 + 12 + 4 + numFrames*(sizeof(FrameStreamData)+12);
 | 
			
		||||
	sizeCB(f, (void*)&size);
 | 
			
		||||
	return size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Frame**
 | 
			
		||||
 | 
			
		||||
@ -12,8 +12,6 @@
 | 
			
		||||
 | 
			
		||||
#define PLUGIN_ID 2
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
 | 
			
		||||
Geometry*
 | 
			
		||||
@ -699,14 +697,15 @@ Material::streamGetSize(void)
 | 
			
		||||
 | 
			
		||||
// Material Rights plugin
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
readMaterialRights(Stream *stream, int32, void *, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	stream->read(materialRights, 8);
 | 
			
		||||
//	printf("materialrights: %X %X\n", materialRights[0], materialRights[1]);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeMaterialRights(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Material *material = (Material*)object;
 | 
			
		||||
@ -714,6 +713,7 @@ writeMaterialRights(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
	buffer[0] = material->pipeline->pluginID;
 | 
			
		||||
	buffer[1] = material->pipeline->pluginData;
 | 
			
		||||
	stream->write(buffer, 8);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
@ -721,7 +721,7 @@ getSizeMaterialRights(void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Material *material = (Material*)object;
 | 
			
		||||
	if(material->pipeline == nil || material->pipeline->pluginID == 0)
 | 
			
		||||
		return -1;
 | 
			
		||||
		return 0;
 | 
			
		||||
	return 8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										137
									
								
								src/image.cpp
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								src/image.cpp
									
									
									
									
									
								
							@ -4,6 +4,7 @@
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include "rwbase.h"
 | 
			
		||||
#include "rwerror.h"
 | 
			
		||||
#include "rwplg.h"
 | 
			
		||||
#include "rwpipeline.h"
 | 
			
		||||
#include "rwobjects.h"
 | 
			
		||||
@ -19,7 +20,7 @@
 | 
			
		||||
#define strdup _strdup
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
#define PLUGIN_ID 0
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
 | 
			
		||||
@ -33,7 +34,10 @@ TexDictionary*
 | 
			
		||||
TexDictionary::create(void)
 | 
			
		||||
{
 | 
			
		||||
	TexDictionary *dict = (TexDictionary*)malloc(PluginBase::s_size);
 | 
			
		||||
	assert(dict != NULL);
 | 
			
		||||
	if(dict == nil){
 | 
			
		||||
		RWERROR((ERR_ALLOC, PluginBase::s_size));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	dict->object.init(TexDictionary::ID, 0);
 | 
			
		||||
	dict->textures.init();
 | 
			
		||||
	dict->constructPlugins();
 | 
			
		||||
@ -57,24 +61,38 @@ TexDictionary::find(const char *name)
 | 
			
		||||
		if(strncmp_ci(tex->name, name, 32) == 0)
 | 
			
		||||
			return tex;
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TexDictionary*
 | 
			
		||||
TexDictionary::streamRead(Stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	int32 numTex = stream->readI16();
 | 
			
		||||
	stream->readI16();	// some platform id (1 = d3d8, 2 = d3d9, 5 = opengl,
 | 
			
		||||
	                        //                   6 = ps2, 8 = xbox)
 | 
			
		||||
	TexDictionary *txd = TexDictionary::create();
 | 
			
		||||
	if(txd == nil)
 | 
			
		||||
		return nil;
 | 
			
		||||
	Texture *tex;
 | 
			
		||||
	for(int32 i = 0; i < numTex; i++){
 | 
			
		||||
		assert(findChunk(stream, ID_TEXTURENATIVE, NULL, NULL));
 | 
			
		||||
		Texture *tex = Texture::streamReadNative(stream);
 | 
			
		||||
		if(!findChunk(stream, ID_TEXTURENATIVE, nil, nil)){
 | 
			
		||||
			RWERROR((ERR_CHUNK, "TEXTURENATIVE"));
 | 
			
		||||
			goto fail;
 | 
			
		||||
		}
 | 
			
		||||
		tex = Texture::streamReadNative(stream);
 | 
			
		||||
		if(tex == nil)
 | 
			
		||||
			goto fail;
 | 
			
		||||
		txd->add(tex);
 | 
			
		||||
	}
 | 
			
		||||
	txd->streamReadPlugins(stream);
 | 
			
		||||
	return txd;
 | 
			
		||||
	if(txd->streamReadPlugins(stream))
 | 
			
		||||
		return txd;
 | 
			
		||||
fail:
 | 
			
		||||
	txd->destroy();
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -116,8 +134,11 @@ Texture*
 | 
			
		||||
Texture::create(Raster *raster)
 | 
			
		||||
{
 | 
			
		||||
	Texture *tex = (Texture*)malloc(PluginBase::s_size);
 | 
			
		||||
	assert(tex != NULL);
 | 
			
		||||
	tex->dict = NULL;
 | 
			
		||||
	if(tex == nil){
 | 
			
		||||
		RWERROR((ERR_ALLOC, PluginBase::s_size));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	tex->dict = nil;
 | 
			
		||||
	tex->inDict.init();
 | 
			
		||||
	memset(tex->name, 0, 32);
 | 
			
		||||
	memset(tex->mask, 0, 32);
 | 
			
		||||
@ -148,7 +169,7 @@ defaultFindCB(const char *name)
 | 
			
		||||
	if(currentTexDictionary)
 | 
			
		||||
		return currentTexDictionary->find(name);
 | 
			
		||||
	// TODO: RW searches *all* TXDs otherwise
 | 
			
		||||
	return NULL;
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Texture*
 | 
			
		||||
@ -169,14 +190,14 @@ defaultReadCB(const char *name, const char *mask)
 | 
			
		||||
		img->destroy();
 | 
			
		||||
		return tex;
 | 
			
		||||
	}else
 | 
			
		||||
		return NULL;
 | 
			
		||||
		return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Texture*
 | 
			
		||||
Texture::read(const char *name, const char *mask)
 | 
			
		||||
{
 | 
			
		||||
	(void)mask;
 | 
			
		||||
	Raster *raster = NULL;
 | 
			
		||||
	Raster *raster = nil;
 | 
			
		||||
	Texture *tex;
 | 
			
		||||
 | 
			
		||||
	if(tex = Texture::findCB(name)){
 | 
			
		||||
@ -185,11 +206,13 @@ Texture::read(const char *name, const char *mask)
 | 
			
		||||
	}
 | 
			
		||||
	if(loadTextures){
 | 
			
		||||
		tex = Texture::readCB(name, mask);
 | 
			
		||||
		if(tex == NULL)
 | 
			
		||||
		if(tex == nil)
 | 
			
		||||
			goto dummytex;
 | 
			
		||||
	}else{
 | 
			
		||||
	dummytex:
 | 
			
		||||
		tex = Texture::create(NULL);
 | 
			
		||||
		tex = Texture::create(nil);
 | 
			
		||||
		if(tex == nil)
 | 
			
		||||
			return nil;
 | 
			
		||||
		strncpy(tex->name, name, 32);
 | 
			
		||||
		if(mask)
 | 
			
		||||
			strncpy(tex->mask, mask, 32);
 | 
			
		||||
@ -209,26 +232,38 @@ Texture::streamRead(Stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	uint32 length;
 | 
			
		||||
	char name[128], mask[128];
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	uint32 filterAddressing = stream->readU32();
 | 
			
		||||
	// TODO: if V addressing is 0, copy U
 | 
			
		||||
	// if using mipmap filter mode, set automipmapping,
 | 
			
		||||
	// if 0x10000 is set, set mipmapping
 | 
			
		||||
 | 
			
		||||
	assert(findChunk(stream, ID_STRING, &length, NULL));
 | 
			
		||||
	if(!findChunk(stream, ID_STRING, &length, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRING"));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	stream->read(name, length);
 | 
			
		||||
 | 
			
		||||
	assert(findChunk(stream, ID_STRING, &length, NULL));
 | 
			
		||||
	if(!findChunk(stream, ID_STRING, &length, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRING"));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	stream->read(mask, length);
 | 
			
		||||
 | 
			
		||||
	Texture *tex = Texture::read(name, mask);
 | 
			
		||||
	if(tex == nil)
 | 
			
		||||
		return nil;
 | 
			
		||||
	if(tex->refCount == 1)
 | 
			
		||||
		tex->filterAddressing = filterAddressing;
 | 
			
		||||
	tex->refCount++;	// TODO: RW doesn't do this, why?
 | 
			
		||||
 | 
			
		||||
	tex->streamReadPlugins(stream);
 | 
			
		||||
 | 
			
		||||
	return tex;
 | 
			
		||||
	if(tex->streamReadPlugins(stream))
 | 
			
		||||
		return tex;
 | 
			
		||||
	tex->destroy();
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
@ -271,7 +306,10 @@ Texture::streamGetSize(void)
 | 
			
		||||
Texture*
 | 
			
		||||
Texture::streamReadNative(Stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	uint32 platform = stream->readU32();
 | 
			
		||||
	stream->seek(-16);
 | 
			
		||||
	if(platform == FOURCC_PS2)
 | 
			
		||||
@ -283,7 +321,7 @@ Texture::streamReadNative(Stream *stream)
 | 
			
		||||
	if(platform == PLATFORM_XBOX)
 | 
			
		||||
		return xbox::readNativeTexture(stream);
 | 
			
		||||
	assert(0 && "unsupported platform");
 | 
			
		||||
	return NULL;
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -323,15 +361,18 @@ Texture::streamGetSizeNative(void)
 | 
			
		||||
Image*
 | 
			
		||||
Image::create(int32 width, int32 height, int32 depth)
 | 
			
		||||
{
 | 
			
		||||
	Image *img = (Image*)malloc(sizeof(*img));
 | 
			
		||||
	assert(img != NULL);
 | 
			
		||||
	Image *img = (Image*)malloc(sizeof(Image));
 | 
			
		||||
	if(img == nil){
 | 
			
		||||
		RWERROR((ERR_ALLOC, sizeof(Image)));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	img->flags = 0;
 | 
			
		||||
	img->width = width;
 | 
			
		||||
	img->height = height;
 | 
			
		||||
	img->depth = depth;
 | 
			
		||||
	img->stride = 0;
 | 
			
		||||
	img->pixels = NULL;
 | 
			
		||||
	img->palette = NULL;
 | 
			
		||||
	img->pixels = nil;
 | 
			
		||||
	img->palette = nil;
 | 
			
		||||
	return img;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -345,12 +386,12 @@ Image::destroy(void)
 | 
			
		||||
void
 | 
			
		||||
Image::allocate(void)
 | 
			
		||||
{
 | 
			
		||||
	if(this->pixels == NULL){
 | 
			
		||||
	if(this->pixels == nil){
 | 
			
		||||
		this->stride = this->width*(this->depth==4 ? 1 : this->depth/8);
 | 
			
		||||
		this->pixels = new uint8[this->stride*this->height];
 | 
			
		||||
		this->flags |= 1;
 | 
			
		||||
	}
 | 
			
		||||
	if(this->palette == NULL){
 | 
			
		||||
	if(this->palette == nil){
 | 
			
		||||
		if(this->depth == 4 || this->depth == 8)
 | 
			
		||||
			this->palette = new uint8[(this->depth==4? 16 : 256)*4];
 | 
			
		||||
		this->flags |= 2;
 | 
			
		||||
@ -401,7 +442,7 @@ Image::hasAlpha(void)
 | 
			
		||||
	return ret != 0xFF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *searchPaths = NULL;
 | 
			
		||||
static char *searchPaths = nil;
 | 
			
		||||
int numSearchPaths = 0;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -413,7 +454,7 @@ Image::setSearchPath(const char *path)
 | 
			
		||||
	if(path)
 | 
			
		||||
		searchPaths = p = strdup(path);
 | 
			
		||||
	else{
 | 
			
		||||
		searchPaths = NULL;
 | 
			
		||||
		searchPaths = nil;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	while(p && *p){
 | 
			
		||||
@ -448,11 +489,14 @@ Image::getFilename(const char *name)
 | 
			
		||||
			printf("found %s\n", name);
 | 
			
		||||
			return strdup(name);
 | 
			
		||||
		}
 | 
			
		||||
		return NULL;
 | 
			
		||||
		return nil;
 | 
			
		||||
	}else
 | 
			
		||||
		for(int i = 0; i < numSearchPaths; i++){
 | 
			
		||||
			s = (char*)malloc(strlen(p)+len);
 | 
			
		||||
			assert(s != NULL);
 | 
			
		||||
			if(s == nil){
 | 
			
		||||
				RWERROR((ERR_ALLOC, strlen(p)+len));
 | 
			
		||||
				return nil;
 | 
			
		||||
			}
 | 
			
		||||
			strcpy(s, p);
 | 
			
		||||
			strcat(s, name);
 | 
			
		||||
			f = fopen(s, "r");
 | 
			
		||||
@ -464,7 +508,7 @@ Image::getFilename(const char *name)
 | 
			
		||||
			::free(s);
 | 
			
		||||
			p += strlen(p) + 1;
 | 
			
		||||
		}
 | 
			
		||||
	return NULL;
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
@ -504,11 +548,11 @@ readTGA(const char *afilename)
 | 
			
		||||
	char *filename;
 | 
			
		||||
	int depth = 0, palDepth = 0;
 | 
			
		||||
	filename = Image::getFilename(afilename);
 | 
			
		||||
	if(filename == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	if(filename == nil)
 | 
			
		||||
		return nil;
 | 
			
		||||
	uint32 length;
 | 
			
		||||
	uint8 *data = getFileContents(filename, &length);
 | 
			
		||||
	assert(data != NULL);
 | 
			
		||||
	assert(data != nil);
 | 
			
		||||
	free(filename);
 | 
			
		||||
	StreamMemory file;
 | 
			
		||||
	file.open(data, length);
 | 
			
		||||
@ -528,8 +572,8 @@ readTGA(const char *afilename)
 | 
			
		||||
 | 
			
		||||
	image = Image::create(header.width, header.height, depth);
 | 
			
		||||
	image->allocate();
 | 
			
		||||
	uint8 *palette = header.colorMapType ? image->palette : NULL;
 | 
			
		||||
	uint8 (*color)[4] = NULL;
 | 
			
		||||
	uint8 *palette = header.colorMapType ? image->palette : nil;
 | 
			
		||||
	uint8 (*color)[4] = nil;
 | 
			
		||||
	if(palette){
 | 
			
		||||
		int maxlen = depth == 4 ? 16 : 256;
 | 
			
		||||
		color = (uint8(*)[4])palette;
 | 
			
		||||
@ -579,10 +623,13 @@ writeTGA(Image *image, const char *filename)
 | 
			
		||||
{
 | 
			
		||||
	TGAHeader header;
 | 
			
		||||
	StreamFile file;
 | 
			
		||||
	assert(file.open(filename, "wb"));
 | 
			
		||||
	if(!file.open(filename, "wb")){
 | 
			
		||||
		RWERROR((ERR_FILE, filename));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	header.IDlen = 0;
 | 
			
		||||
	header.imageType = image->palette != NULL ? 1 : 2;
 | 
			
		||||
	header.colorMapType = image->palette != NULL;
 | 
			
		||||
	header.imageType = image->palette != nil ? 1 : 2;
 | 
			
		||||
	header.colorMapType = image->palette != nil;
 | 
			
		||||
	header.colorMapOrigin = 0;
 | 
			
		||||
	header.colorMapLength = image->depth == 4 ? 16 :
 | 
			
		||||
	                        image->depth == 8 ? 256 : 0;
 | 
			
		||||
@ -596,7 +643,7 @@ writeTGA(Image *image, const char *filename)
 | 
			
		||||
	file.write(&header, sizeof(header));
 | 
			
		||||
 | 
			
		||||
	uint8 *pixels = image->pixels;
 | 
			
		||||
	uint8 *palette = header.colorMapType ? image->palette : NULL;
 | 
			
		||||
	uint8 *palette = header.colorMapType ? image->palette : nil;
 | 
			
		||||
	uint8 (*color)[4] = (uint8(*)[4])palette;;
 | 
			
		||||
	if(palette)
 | 
			
		||||
		for(int i = 0; i < header.colorMapLength; i++){
 | 
			
		||||
@ -633,7 +680,7 @@ Raster*
 | 
			
		||||
Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform)
 | 
			
		||||
{
 | 
			
		||||
	Raster *raster = (Raster*)malloc(PluginBase::s_size);
 | 
			
		||||
	assert(raster != NULL);
 | 
			
		||||
	assert(raster != nil);
 | 
			
		||||
	raster->platform = platform ? platform : rw::platform;
 | 
			
		||||
	raster->type = format & 0x7;
 | 
			
		||||
	raster->flags = format & 0xF8;
 | 
			
		||||
@ -641,7 +688,7 @@ Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platf
 | 
			
		||||
	raster->width = width;
 | 
			
		||||
	raster->height = height;
 | 
			
		||||
	raster->depth = depth;
 | 
			
		||||
	raster->texels = raster->palette = NULL;
 | 
			
		||||
	raster->texels = raster->palette = nil;
 | 
			
		||||
	raster->constructPlugins();
 | 
			
		||||
 | 
			
		||||
	engine[raster->platform].rasterCreate(raster);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										111
									
								
								src/plugins.cpp
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								src/plugins.cpp
									
									
									
									
									
								
							@ -4,6 +4,7 @@
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include "rwbase.h"
 | 
			
		||||
#include "rwerror.h"
 | 
			
		||||
#include "rwplg.h"
 | 
			
		||||
#include "rwpipeline.h"
 | 
			
		||||
#include "rwobjects.h"
 | 
			
		||||
@ -15,7 +16,7 @@
 | 
			
		||||
#include "rwd3d9.h"
 | 
			
		||||
#include "rwwdgl.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
#define PLUGIN_ID 2
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
 | 
			
		||||
@ -151,7 +152,7 @@ copyHAnim(void *dst, void *src, int32 offset, int32)
 | 
			
		||||
	return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
readHAnim(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	int32 ver, numNodes;
 | 
			
		||||
@ -176,9 +177,10 @@ readHAnim(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
		delete[] nodeFlags;
 | 
			
		||||
		delete[] nodeIDs;
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeHAnim(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
 | 
			
		||||
@ -186,7 +188,7 @@ writeHAnim(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
	stream->writeI32(hanim->id);
 | 
			
		||||
	if(hanim->hierarchy == NULL){
 | 
			
		||||
		stream->writeI32(0);
 | 
			
		||||
		return;
 | 
			
		||||
		return stream;
 | 
			
		||||
	}
 | 
			
		||||
	HAnimHierarchy *hier = hanim->hierarchy;
 | 
			
		||||
	stream->writeI32(hier->numNodes);
 | 
			
		||||
@ -197,6 +199,7 @@ writeHAnim(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
		stream->writeI32(hier->nodeInfo[i].index);
 | 
			
		||||
		stream->writeI32(hier->nodeInfo[i].flags);
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
@ -270,7 +273,7 @@ registerHAnimPlugin(void)
 | 
			
		||||
 | 
			
		||||
// Mesh
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
readMesh(Stream *stream, int32 len, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geo = (Geometry*)object;
 | 
			
		||||
@ -315,9 +318,10 @@ readMesh(Stream *stream, int32 len, void *object, int32, int32)
 | 
			
		||||
		}
 | 
			
		||||
		mesh++;
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeMesh(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geo = (Geometry*)object;
 | 
			
		||||
@ -352,6 +356,7 @@ writeMesh(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
		}
 | 
			
		||||
		mesh++;
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
@ -418,7 +423,7 @@ destroyNativeData(void *object, int32 offset, int32 size)
 | 
			
		||||
	return object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
 | 
			
		||||
{
 | 
			
		||||
	ChunkHeaderInfo header;
 | 
			
		||||
@ -433,13 +438,13 @@ readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
 | 
			
		||||
		platform = stream->readU32();
 | 
			
		||||
		stream->seek(-16);
 | 
			
		||||
		if(platform == PLATFORM_PS2)
 | 
			
		||||
			ps2::readNativeData(stream, len, object, o, s);
 | 
			
		||||
			return ps2::readNativeData(stream, len, object, o, s);
 | 
			
		||||
		else if(platform == PLATFORM_XBOX)
 | 
			
		||||
			xbox::readNativeData(stream, len, object, o, s);
 | 
			
		||||
			return xbox::readNativeData(stream, len, object, o, s);
 | 
			
		||||
		else if(platform == PLATFORM_D3D8)
 | 
			
		||||
			d3d8::readNativeData(stream, len, object, o, s);
 | 
			
		||||
			return d3d8::readNativeData(stream, len, object, o, s);
 | 
			
		||||
		else if(platform == PLATFORM_D3D9)
 | 
			
		||||
			d3d9::readNativeData(stream, len, object, o, s);
 | 
			
		||||
			return d3d9::readNativeData(stream, len, object, o, s);
 | 
			
		||||
		else{
 | 
			
		||||
			fprintf(stderr, "unknown platform %d\n", platform);
 | 
			
		||||
			stream->seek(len);
 | 
			
		||||
@ -448,24 +453,26 @@ readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
 | 
			
		||||
		stream->seek(-12);
 | 
			
		||||
		wdgl::readNativeData(stream, len, object, o, s);
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	if(geometry->instData == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
		return stream;
 | 
			
		||||
	if(geometry->instData->platform == PLATFORM_PS2)
 | 
			
		||||
		ps2::writeNativeData(stream, len, object, o, s);
 | 
			
		||||
		return ps2::writeNativeData(stream, len, object, o, s);
 | 
			
		||||
	else if(geometry->instData->platform == PLATFORM_WDGL)
 | 
			
		||||
		wdgl::writeNativeData(stream, len, object, o, s);
 | 
			
		||||
		return wdgl::writeNativeData(stream, len, object, o, s);
 | 
			
		||||
	else if(geometry->instData->platform == PLATFORM_XBOX)
 | 
			
		||||
		xbox::writeNativeData(stream, len, object, o, s);
 | 
			
		||||
		return xbox::writeNativeData(stream, len, object, o, s);
 | 
			
		||||
	else if(geometry->instData->platform == PLATFORM_D3D8)
 | 
			
		||||
		d3d8::writeNativeData(stream, len, object, o, s);
 | 
			
		||||
		return d3d8::writeNativeData(stream, len, object, o, s);
 | 
			
		||||
	else if(geometry->instData->platform == PLATFORM_D3D9)
 | 
			
		||||
		d3d9::writeNativeData(stream, len, object, o, s);
 | 
			
		||||
		return d3d9::writeNativeData(stream, len, object, o, s);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
@ -473,7 +480,7 @@ getSizeNativeData(void *object, int32 offset, int32 size)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	if(geometry->instData == NULL)
 | 
			
		||||
		return -1;
 | 
			
		||||
		return 0;
 | 
			
		||||
	if(geometry->instData->platform == PLATFORM_PS2)
 | 
			
		||||
		return ps2::getSizeNativeData(object, offset, size);
 | 
			
		||||
	else if(geometry->instData->platform == PLATFORM_WDGL)
 | 
			
		||||
@ -484,7 +491,7 @@ getSizeNativeData(void *object, int32 offset, int32 size)
 | 
			
		||||
		return d3d8::getSizeNativeData(object, offset, size);
 | 
			
		||||
	else if(geometry->instData->platform == PLATFORM_D3D9)
 | 
			
		||||
		return d3d9::getSizeNativeData(object, offset, size);
 | 
			
		||||
	return -1;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -548,7 +555,7 @@ copySkin(void *dst, void *src, int32 offset, int32)
 | 
			
		||||
	return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	uint8 header[4];
 | 
			
		||||
@ -557,14 +564,15 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
 | 
			
		||||
	if(geometry->instData){
 | 
			
		||||
		// TODO: function pointers
 | 
			
		||||
		if(geometry->instData->platform == PLATFORM_PS2)
 | 
			
		||||
			ps2::readNativeSkin(stream, len, object, offset);
 | 
			
		||||
			return ps2::readNativeSkin(stream, len, object, offset);
 | 
			
		||||
		else if(geometry->instData->platform == PLATFORM_WDGL)
 | 
			
		||||
			wdgl::readNativeSkin(stream, len, object, offset);
 | 
			
		||||
			return wdgl::readNativeSkin(stream, len, object, offset);
 | 
			
		||||
		else if(geometry->instData->platform == PLATFORM_XBOX)
 | 
			
		||||
			xbox::readNativeSkin(stream, len, object, offset);
 | 
			
		||||
		else
 | 
			
		||||
			return xbox::readNativeSkin(stream, len, object, offset);
 | 
			
		||||
		else{
 | 
			
		||||
			assert(0 && "unsupported native skin platform");
 | 
			
		||||
		return;
 | 
			
		||||
			return nil;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stream->read(header, 4);	// numBones, numUsedBones, numWeights, unused
 | 
			
		||||
@ -614,9 +622,10 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
 | 
			
		||||
	// no split skins in GTA
 | 
			
		||||
	if(!oldFormat)
 | 
			
		||||
		stream->seek(12);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	uint8 header[4];
 | 
			
		||||
@ -629,9 +638,10 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
 | 
			
		||||
			wdgl::writeNativeSkin(stream, len, object, offset);
 | 
			
		||||
		else if(geometry->instData->platform == PLATFORM_XBOX)
 | 
			
		||||
			xbox::writeNativeSkin(stream, len, object, offset);
 | 
			
		||||
		else
 | 
			
		||||
		else{
 | 
			
		||||
			assert(0 && "unsupported native skin platform");
 | 
			
		||||
		return;
 | 
			
		||||
			return nil;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
 | 
			
		||||
@ -662,6 +672,7 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
 | 
			
		||||
		uint32 buffer[3] = { 0, 0, 0};
 | 
			
		||||
		stream->write(buffer, 12);
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
@ -835,17 +846,19 @@ copyAtomicMatFX(void *dst, void *src, int32 offset, int32)
 | 
			
		||||
	return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
readAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
static Stream*
 | 
			
		||||
readAtomicMatFX(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	if(stream->readI32())
 | 
			
		||||
		MatFX::enableEffects((Atomic*)object);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	stream->writeI32(*PLUGINOFFSET(int32, object, offset));
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
@ -1036,7 +1049,7 @@ copyMaterialMatFX(void *dst, void *src, int32 offset, int32)
 | 
			
		||||
	return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	Texture *tex, *bumpedTex;
 | 
			
		||||
@ -1057,13 +1070,19 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
			coefficient = stream->readF32();
 | 
			
		||||
			bumpedTex = tex = NULL;
 | 
			
		||||
			if(stream->readI32()){
 | 
			
		||||
				assert(findChunk(stream, ID_TEXTURE,
 | 
			
		||||
				       NULL, NULL));
 | 
			
		||||
				if(!findChunk(stream, ID_TEXTURE,
 | 
			
		||||
				              NULL, NULL)){
 | 
			
		||||
					RWERROR((ERR_CHUNK, "TEXTURE"));
 | 
			
		||||
					return nil;
 | 
			
		||||
				}
 | 
			
		||||
				bumpedTex = Texture::streamRead(stream);
 | 
			
		||||
			}
 | 
			
		||||
			if(stream->readI32()){
 | 
			
		||||
				assert(findChunk(stream, ID_TEXTURE,
 | 
			
		||||
				       NULL, NULL));
 | 
			
		||||
				if(!findChunk(stream, ID_TEXTURE,
 | 
			
		||||
				              NULL, NULL)){
 | 
			
		||||
					RWERROR((ERR_CHUNK, "TEXTURE"));
 | 
			
		||||
					return nil;
 | 
			
		||||
				}
 | 
			
		||||
				tex = Texture::streamRead(stream);
 | 
			
		||||
			}
 | 
			
		||||
			idx = matfx->getEffectIndex(type);
 | 
			
		||||
@ -1078,8 +1097,11 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
			fbAlpha = stream->readI32();
 | 
			
		||||
			tex = NULL;
 | 
			
		||||
			if(stream->readI32()){
 | 
			
		||||
				assert(findChunk(stream, ID_TEXTURE,
 | 
			
		||||
				       NULL, NULL));
 | 
			
		||||
				if(!findChunk(stream, ID_TEXTURE,
 | 
			
		||||
				              NULL, NULL)){
 | 
			
		||||
					RWERROR((ERR_CHUNK, "TEXTURE"));
 | 
			
		||||
					return nil;
 | 
			
		||||
				}
 | 
			
		||||
				tex = Texture::streamRead(stream);
 | 
			
		||||
			}
 | 
			
		||||
			idx = matfx->getEffectIndex(type);
 | 
			
		||||
@ -1094,8 +1116,11 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
			dstBlend = stream->readI32();
 | 
			
		||||
			tex = NULL;
 | 
			
		||||
			if(stream->readI32()){
 | 
			
		||||
				assert(findChunk(stream, ID_TEXTURE,
 | 
			
		||||
				       NULL, NULL));
 | 
			
		||||
				if(!findChunk(stream, ID_TEXTURE,
 | 
			
		||||
				              NULL, NULL)){
 | 
			
		||||
					RWERROR((ERR_CHUNK, "TEXTURE"));
 | 
			
		||||
					return nil;
 | 
			
		||||
				}
 | 
			
		||||
				tex = Texture::streamRead(stream);
 | 
			
		||||
			}
 | 
			
		||||
			idx = matfx->getEffectIndex(type);
 | 
			
		||||
@ -1106,9 +1131,10 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	MatFX *matfx = *PLUGINOFFSET(MatFX*, object, offset);
 | 
			
		||||
@ -1144,6 +1170,7 @@ writeMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										140
									
								
								src/ps2.cpp
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								src/ps2.cpp
									
									
									
									
									
								
							@ -4,6 +4,7 @@
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include "rwbase.h"
 | 
			
		||||
#include "rwerror.h"
 | 
			
		||||
#include "rwplg.h"
 | 
			
		||||
#include "rwpipeline.h"
 | 
			
		||||
#include "rwobjects.h"
 | 
			
		||||
@ -12,6 +13,8 @@
 | 
			
		||||
#include "rwps2.h"
 | 
			
		||||
#include "rwps2plg.h"
 | 
			
		||||
 | 
			
		||||
#define PLUGIN_ID 2
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
namespace ps2 {
 | 
			
		||||
 | 
			
		||||
@ -28,8 +31,9 @@ void*
 | 
			
		||||
destroyNativeData(void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_PS2);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_PS2)
 | 
			
		||||
		return object;
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	for(uint32 i = 0; i < header->numMeshes; i++)
 | 
			
		||||
		delete[] header->instanceMeshes[i].data;
 | 
			
		||||
@ -38,16 +42,24 @@ destroyNativeData(void *object, int32, int32)
 | 
			
		||||
	return object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
			
		||||
	assert(stream->readU32() == PLATFORM_PS2);
 | 
			
		||||
	uint32 platform;
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"))
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	platform = stream->readU32();
 | 
			
		||||
	if(platform != PLATFORM_PS2){
 | 
			
		||||
		RWERROR((ERR_PLATFORM, platform));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	InstanceDataHeader *header = new InstanceDataHeader;
 | 
			
		||||
	geometry->instData = header;
 | 
			
		||||
	header->platform = PLATFORM_PS2;
 | 
			
		||||
	assert(geometry->meshHeader != NULL);
 | 
			
		||||
	assert(geometry->meshHeader != nil);
 | 
			
		||||
	header->numMeshes = geometry->meshHeader->numMeshes;
 | 
			
		||||
	header->instanceMeshes = new InstanceData[header->numMeshes];
 | 
			
		||||
	for(uint32 i = 0; i < header->numMeshes; i++){
 | 
			
		||||
@ -66,15 +78,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
		instance->material = geometry->meshHeader->mesh[i].material;
 | 
			
		||||
//		sizedebug(instance);
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	writeChunkHeader(stream, ID_STRUCT, len-12);
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_PS2);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_PS2)
 | 
			
		||||
		return stream;
 | 
			
		||||
	stream->writeU32(PLATFORM_PS2);
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	for(uint32 i = 0; i < header->numMeshes; i++){
 | 
			
		||||
@ -87,6 +101,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
 | 
			
		||||
		stream->write(buf, 8);
 | 
			
		||||
		stream->write(instance->data, instance->dataSize);
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32
 | 
			
		||||
@ -94,8 +109,9 @@ getSizeNativeData(void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	int32 size = 16;
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_PS2);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_PS2)
 | 
			
		||||
		return 0;
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	for(uint32 i = 0; i < header->numMeshes; i++){
 | 
			
		||||
		InstanceData *instance = &header->instanceMeshes[i];
 | 
			
		||||
@ -109,7 +125,7 @@ void
 | 
			
		||||
registerNativeDataPlugin(void)
 | 
			
		||||
{
 | 
			
		||||
	Geometry::registerPlugin(0, ID_NATIVEDATA,
 | 
			
		||||
	                         NULL, destroyNativeData, NULL);
 | 
			
		||||
	                         nil, destroyNativeData, nil);
 | 
			
		||||
	Geometry::registerPluginStream(ID_NATIVEDATA,
 | 
			
		||||
	                               readNativeData,
 | 
			
		||||
	                               writeNativeData,
 | 
			
		||||
@ -380,11 +396,11 @@ instanceNormal(uint32 *wp, Geometry *g, Mesh *m, uint32 idx, uint32 n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MatPipeline::MatPipeline(uint32 platform)
 | 
			
		||||
 : rw::Pipeline(platform), instanceCB(NULL), uninstanceCB(NULL),
 | 
			
		||||
   preUninstCB(NULL), postUninstCB(NULL)
 | 
			
		||||
 : rw::Pipeline(platform), instanceCB(nil), uninstanceCB(nil),
 | 
			
		||||
   preUninstCB(nil), postUninstCB(nil)
 | 
			
		||||
{
 | 
			
		||||
	for(int i = 0; i < 10; i++)
 | 
			
		||||
		this->attribs[i] = NULL;
 | 
			
		||||
		this->attribs[i] = nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -653,7 +669,7 @@ MatPipeline::collectData(Geometry *g, InstanceData *inst, Mesh *m, uint8 *data[]
 | 
			
		||||
	InstMeshInfo im = getInstMeshInfo(this, g, m);
 | 
			
		||||
 | 
			
		||||
	uint8 *raw = im.vertexSize*m->numIndices ?
 | 
			
		||||
		new uint8[im.vertexSize*m->numIndices] : NULL;
 | 
			
		||||
		new uint8[im.vertexSize*m->numIndices] : nil;
 | 
			
		||||
	uint8 *dp = raw;
 | 
			
		||||
	for(uint i = 0; i < nelem(this->attribs); i++)
 | 
			
		||||
		if(a = this->attribs[i])
 | 
			
		||||
@ -706,7 +722,7 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
	InstanceDataHeader *header = new InstanceDataHeader;
 | 
			
		||||
	geo->instData = header;
 | 
			
		||||
	header->platform = PLATFORM_PS2;
 | 
			
		||||
	assert(geo->meshHeader != NULL);
 | 
			
		||||
	assert(geo->meshHeader != nil);
 | 
			
		||||
	header->numMeshes = geo->meshHeader->numMeshes;
 | 
			
		||||
	header->instanceMeshes = new InstanceData[header->numMeshes];
 | 
			
		||||
	for(uint32 i = 0; i < header->numMeshes; i++){
 | 
			
		||||
@ -717,7 +733,7 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
		m = pipe->groupPipeline ?
 | 
			
		||||
		    pipe->groupPipeline :
 | 
			
		||||
		    (MatPipeline*)mesh->material->pipeline;
 | 
			
		||||
		if(m == NULL)
 | 
			
		||||
		if(m == nil)
 | 
			
		||||
			m = defaultMatPipe;
 | 
			
		||||
		m->instance(geo, instance, mesh);
 | 
			
		||||
		instance->material = mesh->material;
 | 
			
		||||
@ -761,7 +777,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
	Geometry *geo = atomic->geometry;
 | 
			
		||||
	if((geo->geoflags & Geometry::NATIVE) == 0)
 | 
			
		||||
		return;
 | 
			
		||||
	assert(geo->instData != NULL);
 | 
			
		||||
	assert(geo->instData != nil);
 | 
			
		||||
	assert(geo->instData->platform == PLATFORM_PS2);
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
 | 
			
		||||
	// highest possible number of vertices
 | 
			
		||||
@ -778,7 +794,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
		m = pipe->groupPipeline ?
 | 
			
		||||
		    pipe->groupPipeline :
 | 
			
		||||
		    (MatPipeline*)mesh->material->pipeline;
 | 
			
		||||
		if(m == NULL) m = defaultMatPipe;
 | 
			
		||||
		if(m == nil) m = defaultMatPipe;
 | 
			
		||||
		if(m->preUninstCB) m->preUninstCB(m, geo);
 | 
			
		||||
	}
 | 
			
		||||
	geo->numVertices = 0;
 | 
			
		||||
@ -789,9 +805,9 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
		m = pipe->groupPipeline ?
 | 
			
		||||
		    pipe->groupPipeline :
 | 
			
		||||
		    (MatPipeline*)mesh->material->pipeline;
 | 
			
		||||
		if(m == NULL) m = defaultMatPipe;
 | 
			
		||||
		if(m == nil) m = defaultMatPipe;
 | 
			
		||||
 | 
			
		||||
		uint8 *data[nelem(m->attribs)] = { NULL };
 | 
			
		||||
		uint8 *data[nelem(m->attribs)] = { nil };
 | 
			
		||||
		uint8 *raw = m->collectData(geo, instance, mesh, data);
 | 
			
		||||
		assert(m->uninstanceCB);
 | 
			
		||||
		m->uninstanceCB(m, geo, flags, mesh, data);
 | 
			
		||||
@ -803,7 +819,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
		m = pipe->groupPipeline ?
 | 
			
		||||
		    pipe->groupPipeline :
 | 
			
		||||
		    (MatPipeline*)mesh->material->pipeline;
 | 
			
		||||
		if(m == NULL) m = defaultMatPipe;
 | 
			
		||||
		if(m == nil) m = defaultMatPipe;
 | 
			
		||||
		if(m->postUninstCB) m->postUninstCB(m, geo);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -811,7 +827,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
	geo->generateTriangles(bits);
 | 
			
		||||
	delete[] flags;
 | 
			
		||||
	destroyNativeData(geo, 0, 0);
 | 
			
		||||
	geo->instData = NULL;
 | 
			
		||||
	geo->instData = nil;
 | 
			
		||||
/*
 | 
			
		||||
	for(uint32 i = 0; i < header->numMeshes; i++){
 | 
			
		||||
		Mesh *mesh = &geo->meshHeader->mesh[i];
 | 
			
		||||
@ -826,7 +842,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
 | 
			
		||||
ObjPipeline::ObjPipeline(uint32 platform)
 | 
			
		||||
 : rw::ObjPipeline(platform)
 | 
			
		||||
{
 | 
			
		||||
	this->groupPipeline = NULL;
 | 
			
		||||
	this->groupPipeline = nil;
 | 
			
		||||
	this->impl.instance = objInstance;
 | 
			
		||||
	this->impl.uninstance = objUninstance;
 | 
			
		||||
}
 | 
			
		||||
@ -900,13 +916,13 @@ genericPreCB(MatPipeline *pipe, Geometry *geo)
 | 
			
		||||
void
 | 
			
		||||
genericUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
 | 
			
		||||
{
 | 
			
		||||
	float32 *xyz = NULL, *xyzw = NULL;
 | 
			
		||||
	float32 *uv = NULL, *uv2 = NULL;
 | 
			
		||||
	uint8 *rgba = NULL;
 | 
			
		||||
	int8 *normals = NULL;
 | 
			
		||||
	uint32 *weights = NULL;
 | 
			
		||||
	int8 *adc = NULL;
 | 
			
		||||
	Skin *skin = NULL;
 | 
			
		||||
	float32 *xyz = nil, *xyzw = nil;
 | 
			
		||||
	float32 *uv = nil, *uv2 = nil;
 | 
			
		||||
	uint8 *rgba = nil;
 | 
			
		||||
	int8 *normals = nil;
 | 
			
		||||
	uint32 *weights = nil;
 | 
			
		||||
	int8 *adc = nil;
 | 
			
		||||
	Skin *skin = nil;
 | 
			
		||||
	if(skinGlobals.offset)
 | 
			
		||||
		skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
 | 
			
		||||
 | 
			
		||||
@ -1031,7 +1047,7 @@ defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
 | 
			
		||||
ObjPipeline*
 | 
			
		||||
makeDefaultPipeline(void)
 | 
			
		||||
{
 | 
			
		||||
	if(defaultMatPipe == NULL){
 | 
			
		||||
	if(defaultMatPipe == nil){
 | 
			
		||||
		MatPipeline *pipe = new MatPipeline(PLATFORM_PS2);
 | 
			
		||||
		pipe->attribs[AT_XYZ] = &attribXYZ;
 | 
			
		||||
		pipe->attribs[AT_UV] = &attribUV;
 | 
			
		||||
@ -1044,7 +1060,7 @@ makeDefaultPipeline(void)
 | 
			
		||||
		defaultMatPipe = pipe;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(defaultObjPipe == NULL){
 | 
			
		||||
	if(defaultObjPipe == nil){
 | 
			
		||||
		ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
 | 
			
		||||
		defaultObjPipe = opipe;
 | 
			
		||||
	}
 | 
			
		||||
@ -1101,14 +1117,21 @@ makeMatFXPipeline(void)
 | 
			
		||||
 | 
			
		||||
// Skin
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
 | 
			
		||||
{
 | 
			
		||||
	uint8 header[4];
 | 
			
		||||
	uint32 vers;
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, &vers));
 | 
			
		||||
	assert(stream->readU32() == PLATFORM_PS2);
 | 
			
		||||
	uint32 platform;
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"))
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	platform = stream->readU32();
 | 
			
		||||
	if(platform != PLATFORM_PS2){
 | 
			
		||||
		RWERROR((ERR_PLATFORM, platform));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	stream->read(header, 4);
 | 
			
		||||
	Skin *skin = new Skin;
 | 
			
		||||
	*PLUGINOFFSET(Skin*, geometry, offset) = skin;
 | 
			
		||||
@ -1140,9 +1163,10 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
 | 
			
		||||
		// last 3 ints are split data as in the other formats
 | 
			
		||||
		// TODO: what are the other 4?
 | 
			
		||||
		stream->seek(7*4);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
 | 
			
		||||
{
 | 
			
		||||
	uint8 header[4];
 | 
			
		||||
@ -1170,13 +1194,14 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
 | 
			
		||||
		uint32 buffer[7] = { 0, 0, 0, 0, 0, 0, 0 };
 | 
			
		||||
		stream->write(buffer, 7*4);
 | 
			
		||||
	}
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32
 | 
			
		||||
getSizeNativeSkin(void *object, int32 offset)
 | 
			
		||||
{
 | 
			
		||||
	Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
 | 
			
		||||
	if(skin == NULL)
 | 
			
		||||
	if(skin == nil)
 | 
			
		||||
		return -1;
 | 
			
		||||
	int32 size = 12 + 4 + 4 + skin->numBones*64;
 | 
			
		||||
	// not sure which version introduced the new format
 | 
			
		||||
@ -1206,7 +1231,7 @@ void
 | 
			
		||||
skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data)
 | 
			
		||||
{
 | 
			
		||||
	Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
 | 
			
		||||
	if(skin == NULL)
 | 
			
		||||
	if(skin == nil)
 | 
			
		||||
		return;
 | 
			
		||||
	instanceSkinData(g, m, skin, (uint32*)data[4]);
 | 
			
		||||
}
 | 
			
		||||
@ -1216,8 +1241,8 @@ int32
 | 
			
		||||
findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v)
 | 
			
		||||
{
 | 
			
		||||
	Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
 | 
			
		||||
	float32 *wghts = NULL;
 | 
			
		||||
	uint8 *inds = NULL;
 | 
			
		||||
	float32 *wghts = nil;
 | 
			
		||||
	uint8 *inds = nil;
 | 
			
		||||
	if(skin){
 | 
			
		||||
		wghts = skin->weights;
 | 
			
		||||
		inds = skin->indices;
 | 
			
		||||
@ -1331,7 +1356,7 @@ void
 | 
			
		||||
skinPreCB(MatPipeline*, Geometry *geo)
 | 
			
		||||
{
 | 
			
		||||
	Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
 | 
			
		||||
	if(skin == NULL)
 | 
			
		||||
	if(skin == nil)
 | 
			
		||||
		return;
 | 
			
		||||
	uint8 *data = skin->data;
 | 
			
		||||
	float *invMats = skin->inverseMatrices;
 | 
			
		||||
@ -1358,7 +1383,7 @@ int32 adcOffset;
 | 
			
		||||
int8*
 | 
			
		||||
getADCbits(Geometry *geo)
 | 
			
		||||
{
 | 
			
		||||
	int8 *bits = NULL;
 | 
			
		||||
	int8 *bits = nil;
 | 
			
		||||
	if(adcOffset){
 | 
			
		||||
		ADCData *adc = PLUGINOFFSET(ADCData, geo, adcOffset);
 | 
			
		||||
		if(adc->adcFormatted)
 | 
			
		||||
@ -1371,8 +1396,8 @@ int8*
 | 
			
		||||
getADCbitsForMesh(Geometry *geo, Mesh *mesh)
 | 
			
		||||
{
 | 
			
		||||
	int8 *bits = getADCbits(geo);
 | 
			
		||||
	if(bits == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	if(bits == nil)
 | 
			
		||||
		return nil;
 | 
			
		||||
	int32 n = mesh - geo->meshHeader->mesh;
 | 
			
		||||
	for(int32 i = 0; i < n; i++)
 | 
			
		||||
		bits += geo->meshHeader->mesh[i].numIndices;
 | 
			
		||||
@ -1430,7 +1455,7 @@ unconvertADC(Geometry *g)
 | 
			
		||||
	g->meshHeader = h;
 | 
			
		||||
	adc->adcFormatted = 0;
 | 
			
		||||
	delete[] adc->adcBits;
 | 
			
		||||
	adc->adcBits = NULL;
 | 
			
		||||
	adc->adcBits = nil;
 | 
			
		||||
	adc->numBits = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1477,24 +1502,28 @@ destroyADC(void *object, int32 offset, int32)
 | 
			
		||||
	return object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
readADC(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
 | 
			
		||||
	assert(findChunk(stream, ID_ADC, NULL, NULL));
 | 
			
		||||
	if(!findChunk(stream, ID_ADC, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "ADC"));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	adc->numBits = stream->readI32();
 | 
			
		||||
	adc->adcFormatted = 1;
 | 
			
		||||
	if(adc->numBits == 0){
 | 
			
		||||
		adc->adcBits = NULL;
 | 
			
		||||
		adc->adcBits = nil;
 | 
			
		||||
		adc->numBits = 0;
 | 
			
		||||
		return;
 | 
			
		||||
		return stream;
 | 
			
		||||
	}
 | 
			
		||||
	int32 size = adc->numBits+3 & ~3;
 | 
			
		||||
	adc->adcBits = new int8[size];
 | 
			
		||||
	stream->read(adc->adcBits, size);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeADC(Stream *stream, int32 len, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
 | 
			
		||||
@ -1502,11 +1531,12 @@ writeADC(Stream *stream, int32 len, void *object, int32 offset, int32)
 | 
			
		||||
	writeChunkHeader(stream, ID_ADC, len-12);
 | 
			
		||||
	if(geometry->geoflags & Geometry::NATIVE){
 | 
			
		||||
		stream->writeI32(0);
 | 
			
		||||
		return;
 | 
			
		||||
		return stream;
 | 
			
		||||
	}
 | 
			
		||||
	stream->writeI32(adc->numBits);
 | 
			
		||||
	int32 size = adc->numBits+3 & ~3;
 | 
			
		||||
	stream->write(adc->adcBits, size);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
@ -1564,7 +1594,7 @@ sizedebug(InstanceData *inst)
 | 
			
		||||
		return;
 | 
			
		||||
	uint32 *base = (uint32*)inst->data;
 | 
			
		||||
	uint32 *tag = (uint32*)inst->data;
 | 
			
		||||
	uint32 *last = NULL;
 | 
			
		||||
	uint32 *last = nil;
 | 
			
		||||
	for(;;){
 | 
			
		||||
		switch(tag[0]&0x70000000){
 | 
			
		||||
		case DMAcnt:
 | 
			
		||||
 | 
			
		||||
@ -3,15 +3,16 @@
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include <new>
 | 
			
		||||
 | 
			
		||||
#include "rwbase.h"
 | 
			
		||||
#include "rwerror.h"
 | 
			
		||||
#include "rwplg.h"
 | 
			
		||||
#include "rwpipeline.h"
 | 
			
		||||
#include "rwobjects.h"
 | 
			
		||||
#include "rwengine.h"
 | 
			
		||||
#include "rwps2.h"
 | 
			
		||||
 | 
			
		||||
#define PLUGIN_ID 0
 | 
			
		||||
 | 
			
		||||
#define max(a, b) ((a) > (b) ? (a) : (b))
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
@ -385,7 +386,7 @@ rasterLock(Raster *raster, int32 level)
 | 
			
		||||
	// TODO
 | 
			
		||||
	(void)raster;
 | 
			
		||||
	(void)level;
 | 
			
		||||
	return NULL;
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -400,7 +401,7 @@ static int32
 | 
			
		||||
rasterNumLevels(Raster *raster)
 | 
			
		||||
{
 | 
			
		||||
	Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
 | 
			
		||||
	if(raster->texels == NULL) return 0;
 | 
			
		||||
	if(raster->texels == nil) return 0;
 | 
			
		||||
	if(raster->format & Raster::MIPMAP)
 | 
			
		||||
		return MAXLEVEL(ras)+1;
 | 
			
		||||
	return 1;
 | 
			
		||||
@ -410,7 +411,6 @@ static void*
 | 
			
		||||
createNativeRaster(void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, object, offset);
 | 
			
		||||
	new (raster) Ps2Raster;
 | 
			
		||||
	raster->tex0[0] = 0;
 | 
			
		||||
	raster->tex0[1] = 0;
 | 
			
		||||
	raster->tex1[0] = 0;
 | 
			
		||||
@ -426,7 +426,7 @@ createNativeRaster(void *object, int32 offset, int32)
 | 
			
		||||
	SETKL(raster, 0xFC0);
 | 
			
		||||
 | 
			
		||||
	raster->dataSize = 0;
 | 
			
		||||
	raster->data = NULL;
 | 
			
		||||
	raster->data = nil;
 | 
			
		||||
	return object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -447,24 +447,27 @@ copyNativeRaster(void *dst, void *src, int32 offset, int32)
 | 
			
		||||
	return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
readMipmap(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	uint16 val = stream->readI32();
 | 
			
		||||
	Texture *tex = (Texture*)object;
 | 
			
		||||
	if(tex->raster == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	if(tex->raster == nil)
 | 
			
		||||
		return stream;
 | 
			
		||||
	Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset);
 | 
			
		||||
	SETKL(raster, val);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeMipmap(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	Texture *tex = (Texture*)object;
 | 
			
		||||
	assert(tex->raster);
 | 
			
		||||
	if(tex->raster)
 | 
			
		||||
		return nil;
 | 
			
		||||
	Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset);
 | 
			
		||||
	stream->writeI32(raster->tex1[1]&0xFFFF);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
@ -487,7 +490,7 @@ registerNativeRaster(void)
 | 
			
		||||
	engine[PLATFORM_PS2].rasterUnlock = rasterUnlock;
 | 
			
		||||
	engine[PLATFORM_PS2].rasterNumLevels = rasterNumLevels;
 | 
			
		||||
 | 
			
		||||
	Texture::registerPlugin(0, ID_SKYMIPMAP, NULL, NULL, NULL);
 | 
			
		||||
	Texture::registerPlugin(0, ID_SKYMIPMAP, nil, nil, nil);
 | 
			
		||||
	Texture::registerPluginStream(ID_SKYMIPMAP, readMipmap, writeMipmap, getSizeMipmap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -512,24 +515,47 @@ Texture*
 | 
			
		||||
readNativeTexture(Stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	uint32 length, oldversion, version;
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
			
		||||
	assert(stream->readU32() == 0x00325350);	// 'PS2\0'
 | 
			
		||||
	Texture *tex = Texture::create(NULL);
 | 
			
		||||
	uint32 fourcc;
 | 
			
		||||
	Raster *raster;
 | 
			
		||||
	Ps2Raster *natras;
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	fourcc = stream->readU32();
 | 
			
		||||
	if(fourcc != FOURCC_PS2){
 | 
			
		||||
		RWERROR((ERR_PLATFORM, fourcc));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	Texture *tex = Texture::create(nil);
 | 
			
		||||
	if(tex == nil)
 | 
			
		||||
		return nil;
 | 
			
		||||
 | 
			
		||||
	// Texture
 | 
			
		||||
	tex->filterAddressing = stream->readU32();
 | 
			
		||||
	assert(findChunk(stream, ID_STRING, &length, NULL));
 | 
			
		||||
	if(!findChunk(stream, ID_STRING, &length, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRING"));
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
	stream->read(tex->name, length);
 | 
			
		||||
	assert(findChunk(stream, ID_STRING, &length, NULL));
 | 
			
		||||
	if(!findChunk(stream, ID_STRING, &length, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRING"));
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
	stream->read(tex->mask, length);
 | 
			
		||||
 | 
			
		||||
	// Raster
 | 
			
		||||
	StreamRasterExt streamExt;
 | 
			
		||||
	oldversion = rw::version;
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, NULL));
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, &version));
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"));
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, &version)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"));
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
	stream->read(&streamExt, 0x40);
 | 
			
		||||
	Raster *raster;
 | 
			
		||||
	noNewStyleRasters = streamExt.type < 2;
 | 
			
		||||
	rw::version = version;
 | 
			
		||||
	raster = Raster::create(streamExt.width, streamExt.height,
 | 
			
		||||
@ -538,36 +564,43 @@ readNativeTexture(Stream *stream)
 | 
			
		||||
	noNewStyleRasters = 0;
 | 
			
		||||
	rw::version = oldversion;
 | 
			
		||||
	tex->raster = raster;
 | 
			
		||||
	Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
 | 
			
		||||
	natras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
 | 
			
		||||
	//printf("%08X%08X %08X%08X %08X%08X %08X%08X\n",
 | 
			
		||||
	//       ras->tex0[1], ras->tex0[0], ras->tex1[1], ras->tex1[0],
 | 
			
		||||
	//       ras->miptbp1[0], ras->miptbp1[1], ras->miptbp2[0], ras->miptbp2[1]);
 | 
			
		||||
	ras->tex0[0] = streamExt.tex0[0];
 | 
			
		||||
	ras->tex0[1] = streamExt.tex0[1];
 | 
			
		||||
	ras->tex1[0] = streamExt.tex1[0];
 | 
			
		||||
	ras->tex1[1] = ras->tex1[1]&~0xFF0000 | streamExt.tex1[1]<<16 & 0xFF0000;
 | 
			
		||||
	ras->miptbp1[0] = streamExt.miptbp1[0];
 | 
			
		||||
	ras->miptbp1[1] = streamExt.miptbp1[1];
 | 
			
		||||
	ras->miptbp2[0] = streamExt.miptbp2[0];
 | 
			
		||||
	ras->miptbp2[1] = streamExt.miptbp2[1];
 | 
			
		||||
	ras->texelSize = streamExt.texelSize;
 | 
			
		||||
	ras->paletteSize = streamExt.paletteSize;
 | 
			
		||||
	ras->gsSize = streamExt.gsSize;
 | 
			
		||||
	SETKL(ras, streamExt.mipmapVal);
 | 
			
		||||
	natras->tex0[0] = streamExt.tex0[0];
 | 
			
		||||
	natras->tex0[1] = streamExt.tex0[1];
 | 
			
		||||
	natras->tex1[0] = streamExt.tex1[0];
 | 
			
		||||
	natras->tex1[1] = natras->tex1[1]&~0xFF0000 |
 | 
			
		||||
	                  streamExt.tex1[1]<<16 & 0xFF0000;
 | 
			
		||||
	natras->miptbp1[0] = streamExt.miptbp1[0];
 | 
			
		||||
	natras->miptbp1[1] = streamExt.miptbp1[1];
 | 
			
		||||
	natras->miptbp2[0] = streamExt.miptbp2[0];
 | 
			
		||||
	natras->miptbp2[1] = streamExt.miptbp2[1];
 | 
			
		||||
	natras->texelSize = streamExt.texelSize;
 | 
			
		||||
	natras->paletteSize = streamExt.paletteSize;
 | 
			
		||||
	natras->gsSize = streamExt.gsSize;
 | 
			
		||||
	SETKL(natras, streamExt.mipmapVal);
 | 
			
		||||
	//printf("%08X%08X %08X%08X %08X%08X %08X%08X\n",
 | 
			
		||||
	//       ras->tex0[1], ras->tex0[0], ras->tex1[1], ras->tex1[0],
 | 
			
		||||
	//       ras->miptbp1[0], ras->miptbp1[1], ras->miptbp2[0], ras->miptbp2[1]);
 | 
			
		||||
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, &length, NULL));
 | 
			
		||||
	if(!findChunk(stream, ID_STRING, &length, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRING"));
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
	if(streamExt.type < 2){
 | 
			
		||||
		stream->read(raster->texels, length);
 | 
			
		||||
	}else{
 | 
			
		||||
		stream->read(raster->texels-0x50, ras->texelSize);
 | 
			
		||||
		stream->read(raster->palette-0x50, ras->paletteSize);
 | 
			
		||||
		stream->read(raster->texels-0x50, natras->texelSize);
 | 
			
		||||
		stream->read(raster->palette-0x50, natras->paletteSize);
 | 
			
		||||
	}
 | 
			
		||||
	if(tex->streamReadPlugins(stream))
 | 
			
		||||
		return tex;
 | 
			
		||||
 | 
			
		||||
	tex->streamReadPlugins(stream);
 | 
			
		||||
	return tex;
 | 
			
		||||
fail:
 | 
			
		||||
	tex->destroy();
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 | 
			
		||||
@ -32,8 +32,8 @@ uint32 makeFVFDeclaration(uint32 flags, int32 numTex);
 | 
			
		||||
int32 getStride(uint32 flags, int32 numTex);
 | 
			
		||||
 | 
			
		||||
void *destroyNativeData(void *object, int32, int32);
 | 
			
		||||
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
void writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
int32 getSizeNativeData(void *object, int32, int32);
 | 
			
		||||
void registerNativeDataPlugin(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -55,8 +55,8 @@ void *createVertexDeclaration(VertexElement *elements);
 | 
			
		||||
uint32 getDeclaration(void *declaration, VertexElement *elements);
 | 
			
		||||
 | 
			
		||||
void *destroyNativeData(void *object, int32, int32);
 | 
			
		||||
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
void writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
int32 getSizeNativeData(void *object, int32, int32);
 | 
			
		||||
void registerNativeDataPlugin(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
 | 
			
		||||
typedef void (*StreamWrite)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
 | 
			
		||||
typedef Stream *(*StreamRead)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
 | 
			
		||||
typedef Stream *(*StreamWrite)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
 | 
			
		||||
typedef int32 (*StreamGetSize)(void *object, int32 offset, int32 size);
 | 
			
		||||
typedef void (*RightsCallback)(void *object, int32 offset, int32 size, uint32 data);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -49,8 +49,8 @@ enum PS2AttibTypes {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void *destroyNativeData(void *object, int32, int32);
 | 
			
		||||
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
void writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
int32 getSizeNativeData(void *object, int32, int32);
 | 
			
		||||
void registerNativeDataPlugin(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,8 @@ ObjPipeline *makeMatFXPipeline(void);
 | 
			
		||||
void insertVertexSkin(Geometry *geo, int32 i, uint32 mask, Vertex *v);
 | 
			
		||||
int32 findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v);
 | 
			
		||||
 | 
			
		||||
void readNativeSkin(Stream *stream, int32, void *object, int32 offset);
 | 
			
		||||
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
 | 
			
		||||
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
 | 
			
		||||
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
 | 
			
		||||
int32 getSizeNativeSkin(void *object, int32 offset);
 | 
			
		||||
 | 
			
		||||
void instanceSkinData(Geometry *g, Mesh *m, Skin *skin, uint32 *data);
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
namespace wdgl {
 | 
			
		||||
 | 
			
		||||
@ -38,8 +39,8 @@ void packattrib(uint8 *dst, float32 *src, AttribDesc *a, float32 scale);
 | 
			
		||||
void unpackattrib(float *dst, uint8 *src, AttribDesc *a, float32 scale);
 | 
			
		||||
 | 
			
		||||
void *destroyNativeData(void *object, int32, int32);
 | 
			
		||||
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
void writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
int32 getSizeNativeData(void *object, int32, int32);
 | 
			
		||||
void registerNativeDataPlugin(void);
 | 
			
		||||
 | 
			
		||||
@ -59,8 +60,8 @@ ObjPipeline *makeDefaultPipeline(void);
 | 
			
		||||
 | 
			
		||||
// Skin plugin
 | 
			
		||||
 | 
			
		||||
void readNativeSkin(Stream *stream, int32, void *object, int32 offset);
 | 
			
		||||
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
 | 
			
		||||
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
 | 
			
		||||
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
 | 
			
		||||
int32 getSizeNativeSkin(void *object, int32 offset);
 | 
			
		||||
 | 
			
		||||
ObjPipeline *makeSkinPipeline(void);
 | 
			
		||||
 | 
			
		||||
@ -30,8 +30,8 @@ struct InstanceDataHeader : rw::InstanceDataHeader
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void *destroyNativeData(void *object, int32, int32);
 | 
			
		||||
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
void writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
 | 
			
		||||
int32 getSizeNativeData(void *object, int32, int32);
 | 
			
		||||
void registerNativeDataPlugin(void);
 | 
			
		||||
 | 
			
		||||
@ -48,8 +48,8 @@ ObjPipeline *makeDefaultPipeline(void);
 | 
			
		||||
 | 
			
		||||
// Skin plugin
 | 
			
		||||
 | 
			
		||||
void readNativeSkin(Stream *stream, int32, void *object, int32 offset);
 | 
			
		||||
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
 | 
			
		||||
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
 | 
			
		||||
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
 | 
			
		||||
int32 getSizeNativeSkin(void *object, int32 offset);
 | 
			
		||||
 | 
			
		||||
ObjPipeline *makeSkinPipeline(void);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								src/wdgl.cpp
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								src/wdgl.cpp
									
									
									
									
									
								
							@ -4,6 +4,7 @@
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include "rwbase.h"
 | 
			
		||||
#include "rwerror.h"
 | 
			
		||||
#include "rwplg.h"
 | 
			
		||||
#include "rwpipeline.h"
 | 
			
		||||
#include "rwobjects.h"
 | 
			
		||||
@ -15,7 +16,7 @@
 | 
			
		||||
#include <GL/glew.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
#define PLUGIN_ID 2
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
namespace wdgl {
 | 
			
		||||
@ -217,7 +218,9 @@ void*
 | 
			
		||||
destroyNativeData(void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_WDGL);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_WDGL)
 | 
			
		||||
		return object;
 | 
			
		||||
	InstanceDataHeader *header =
 | 
			
		||||
		(InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	geometry->instData = NULL;
 | 
			
		||||
@ -228,7 +231,7 @@ destroyNativeData(void *object, int32, int32)
 | 
			
		||||
	return object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
@ -244,24 +247,30 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
	header->dataSize = header->attribs[0].stride*geometry->numVertices;
 | 
			
		||||
	header->data = new uint8[header->dataSize];
 | 
			
		||||
	stream->read(header->data, header->dataSize);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
writeNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_WDGL);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_WDGL)
 | 
			
		||||
		return stream;
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	stream->writeU32(header->numAttribs);
 | 
			
		||||
	stream->write(header->attribs, header->numAttribs*sizeof(AttribDesc));
 | 
			
		||||
	stream->write(header->data, header->dataSize);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32
 | 
			
		||||
getSizeNativeData(void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_WDGL);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_WDGL)
 | 
			
		||||
		return 0;
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	return 4 + header->numAttribs*sizeof(AttribDesc) + header->dataSize;
 | 
			
		||||
}
 | 
			
		||||
@ -511,22 +520,30 @@ makeDefaultPipeline(void)
 | 
			
		||||
 | 
			
		||||
// Skin
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
 | 
			
		||||
{
 | 
			
		||||
	uint32 vers;
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, &vers));
 | 
			
		||||
	assert(stream->readU32() == PLATFORM_WDGL);
 | 
			
		||||
	uint32 platform;
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, nil)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	platform = stream->readU32();
 | 
			
		||||
	if(platform != PLATFORM_GL){
 | 
			
		||||
		RWERROR((ERR_PLATFORM, platform));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	Skin *skin = new Skin;
 | 
			
		||||
	*PLUGINOFFSET(Skin*, geometry, offset) = skin;
 | 
			
		||||
 | 
			
		||||
	int32 numBones = stream->readI32();
 | 
			
		||||
	skin->init(numBones, 0, 0);
 | 
			
		||||
	stream->read(skin->inverseMatrices, skin->numBones*64);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
 | 
			
		||||
{
 | 
			
		||||
	writeChunkHeader(stream, ID_STRUCT, len-12);
 | 
			
		||||
@ -534,6 +551,7 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
 | 
			
		||||
	Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
 | 
			
		||||
	stream->writeI32(skin->numBones);
 | 
			
		||||
	stream->write(skin->inverseMatrices, skin->numBones*64);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										98
									
								
								src/xbox.cpp
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								src/xbox.cpp
									
									
									
									
									
								
							@ -3,9 +3,8 @@
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include <new>
 | 
			
		||||
 | 
			
		||||
#include "rwbase.h"
 | 
			
		||||
#include "rwerror.h"
 | 
			
		||||
#include "rwplg.h"
 | 
			
		||||
#include "rwpipeline.h"
 | 
			
		||||
#include "rwobjects.h"
 | 
			
		||||
@ -13,7 +12,7 @@
 | 
			
		||||
#include "rwplugins.h"
 | 
			
		||||
#include "rwxbox.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
#define PLUGIN_ID 2
 | 
			
		||||
 | 
			
		||||
namespace rw {
 | 
			
		||||
namespace xbox {
 | 
			
		||||
@ -28,8 +27,9 @@ void*
 | 
			
		||||
destroyNativeData(void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_XBOX);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_XBOX)
 | 
			
		||||
		return object;
 | 
			
		||||
	InstanceDataHeader *header =
 | 
			
		||||
		(InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	geometry->instData = NULL;
 | 
			
		||||
@ -40,14 +40,25 @@ destroyNativeData(void *object, int32, int32)
 | 
			
		||||
	return object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	uint32 vers;
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, &vers));
 | 
			
		||||
	assert(stream->readU32() == PLATFORM_XBOX);
 | 
			
		||||
	assert(vers >= 0x35000 && "can't handle native Xbox data < 0x35000");
 | 
			
		||||
	uint32 platform;
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, &vers)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"))
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	platform = stream->readU32();
 | 
			
		||||
	if(platform != PLATFORM_XBOX){
 | 
			
		||||
		RWERROR((ERR_PLATFORM, platform));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	if(vers < 0x35000){
 | 
			
		||||
		RWERROR((ERR_VERSION, vers));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	InstanceDataHeader *header = new InstanceDataHeader;
 | 
			
		||||
	geometry->instData = header;
 | 
			
		||||
	header->platform = PLATFORM_XBOX;
 | 
			
		||||
@ -86,15 +97,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
 | 
			
		||||
 | 
			
		||||
	header->vertexBuffer = new uint8[header->stride*header->numVertices];
 | 
			
		||||
	stream->read(header->vertexBuffer, header->stride*header->numVertices);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	writeChunkHeader(stream, ID_STRUCT, len-12);
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_XBOX);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_XBOX)
 | 
			
		||||
		return stream;
 | 
			
		||||
	stream->writeU32(PLATFORM_XBOX);
 | 
			
		||||
	assert(rw::version >= 0x35000 && "can't write native Xbox data < 0x35000");
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
 | 
			
		||||
@ -125,14 +138,16 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
 | 
			
		||||
 | 
			
		||||
	stream->write(header->data+0x18, header->size);
 | 
			
		||||
	stream->write(header->vertexBuffer, header->stride*header->numVertices);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32
 | 
			
		||||
getSizeNativeData(void *object, int32, int32)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	assert(geometry->instData != NULL);
 | 
			
		||||
	assert(geometry->instData->platform == PLATFORM_XBOX);
 | 
			
		||||
	if(geometry->instData == nil ||
 | 
			
		||||
	   geometry->instData->platform != PLATFORM_XBOX)
 | 
			
		||||
		return 0;
 | 
			
		||||
	InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
 | 
			
		||||
	return 12 + 4 + header->size + header->stride*header->numVertices;
 | 
			
		||||
}
 | 
			
		||||
@ -347,14 +362,25 @@ struct NativeSkin
 | 
			
		||||
	int32 stride;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
	uint32 vers;
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, &vers));
 | 
			
		||||
	assert(vers >= 0x35000 && "can't handle native xbox skin < 0x35000");
 | 
			
		||||
	assert(stream->readU32() == PLATFORM_XBOX);
 | 
			
		||||
	uint32 vers, platform;
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, &vers)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"))
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	platform = stream->readU32();
 | 
			
		||||
	if(platform != PLATFORM_XBOX){
 | 
			
		||||
		RWERROR((ERR_PLATFORM, platform));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	if(vers < 0x35000){
 | 
			
		||||
		RWERROR((ERR_VERSION, vers));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Skin *skin = new Skin;
 | 
			
		||||
	*PLUGINOFFSET(Skin*, geometry, offset) = skin;
 | 
			
		||||
 | 
			
		||||
@ -375,9 +401,10 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
 | 
			
		||||
 | 
			
		||||
	// no split skins in GTA
 | 
			
		||||
	stream->seek(12);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Stream*
 | 
			
		||||
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
 | 
			
		||||
{
 | 
			
		||||
	Geometry *geometry = (Geometry*)object;
 | 
			
		||||
@ -400,6 +427,7 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
 | 
			
		||||
	stream->write(skin->inverseMatrices, skin->numBones*64);
 | 
			
		||||
	int32 buffer[3] = { 0, 0, 0};
 | 
			
		||||
	stream->write(buffer, 12);
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32
 | 
			
		||||
@ -604,18 +632,20 @@ copyVertexFmt(void *dst, void *src, int32 offset, int32)
 | 
			
		||||
	return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	uint32 fmt = stream->readU32();
 | 
			
		||||
	*PLUGINOFFSET(uint32, object, offset) = fmt;
 | 
			
		||||
	// TODO: ? create and attach "vertex shader"
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static Stream*
 | 
			
		||||
writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	stream->writeI32(*PLUGINOFFSET(uint32, object, offset));
 | 
			
		||||
	return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32
 | 
			
		||||
@ -842,7 +872,6 @@ static void*
 | 
			
		||||
createNativeRaster(void *object, int32 offset, int32)
 | 
			
		||||
{
 | 
			
		||||
	XboxRaster *raster = PLUGINOFFSET(XboxRaster, object, offset);
 | 
			
		||||
	new (raster) XboxRaster;
 | 
			
		||||
	raster->texture = NULL;
 | 
			
		||||
	raster->palette = NULL;
 | 
			
		||||
	raster->format = 0;
 | 
			
		||||
@ -888,11 +917,24 @@ registerNativeRaster(void)
 | 
			
		||||
Texture*
 | 
			
		||||
readNativeTexture(Stream *stream)
 | 
			
		||||
{
 | 
			
		||||
	uint32 version;
 | 
			
		||||
	assert(findChunk(stream, ID_STRUCT, NULL, &version));
 | 
			
		||||
	assert(version >= 0x34001);
 | 
			
		||||
	assert(stream->readU32() == PLATFORM_XBOX);
 | 
			
		||||
	Texture *tex = Texture::create(NULL);
 | 
			
		||||
	uint32 vers, platform;
 | 
			
		||||
	if(!findChunk(stream, ID_STRUCT, nil, &vers)){
 | 
			
		||||
		RWERROR((ERR_CHUNK, "STRUCT"))
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	platform = stream->readU32();
 | 
			
		||||
	if(platform != PLATFORM_XBOX){
 | 
			
		||||
		RWERROR((ERR_PLATFORM, platform));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	if(version < 0x34001){
 | 
			
		||||
		RWERROR((ERR_VERSION, version));
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	Texture *tex = Texture::create(nil);
 | 
			
		||||
	if(tex == nil)
 | 
			
		||||
		return nil;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// Texture
 | 
			
		||||
	tex->filterAddressing = stream->readU32();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user