mirror of
				https://github.com/aap/librw.git
				synced 2025-10-31 15:09:17 +00:00 
			
		
		
		
	implemented basic error system; restructured some files; replaced a few asserts
This commit is contained in:
		
							parent
							
								
									416ee91bb7
								
							
						
					
					
						commit
						6e71e34933
					
				
							
								
								
									
										1
									
								
								rw.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								rw.h
									
									
									
									
									
								
							| @ -2,6 +2,7 @@ | |||||||
| #include <cmath> | #include <cmath> | ||||||
| 
 | 
 | ||||||
| #include "src/rwbase.h" | #include "src/rwbase.h" | ||||||
|  | #include "src/rwerror.h" | ||||||
| #include "src/rwplg.h" | #include "src/rwplg.h" | ||||||
| #include "src/rwpipeline.h" | #include "src/rwpipeline.h" | ||||||
| #include "src/rwobjects.h" | #include "src/rwobjects.h" | ||||||
|  | |||||||
							
								
								
									
										8
									
								
								src/base.err
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/base.err
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | ECODE(ERR_GENERAL, | ||||||
|  |       "General Error") | ||||||
|  | ECODE(ERR_ALLOC, | ||||||
|  |       "Couldn't allocate 0x%X bytes") | ||||||
|  | ECODE(ERR_FILE, | ||||||
|  |       "Couldn't open file %s") | ||||||
|  | ECODE(ERR_CHUNK, | ||||||
|  |       "Couldn't find chunk %s") | ||||||
							
								
								
									
										167
									
								
								src/camera.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/camera.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,167 @@ | |||||||
|  | #include <cstdio> | ||||||
|  | #include <cstdlib> | ||||||
|  | 
 | ||||||
|  | #include "rwbase.h" | ||||||
|  | #include "rwerror.h" | ||||||
|  | #include "rwplg.h" | ||||||
|  | #include "rwpipeline.h" | ||||||
|  | #include "rwobjects.h" | ||||||
|  | 
 | ||||||
|  | #define PLUGIN_ID 0 | ||||||
|  | 
 | ||||||
|  | namespace rw { | ||||||
|  | 
 | ||||||
|  | Camera* | ||||||
|  | Camera::create(void) | ||||||
|  | { | ||||||
|  | 	Camera *cam = (Camera*)malloc(PluginBase::s_size); | ||||||
|  | 	if(cam == NULL){ | ||||||
|  | 		RWERROR((ERR_ALLOC, PluginBase::s_size)); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	cam->object.object.init(Camera::ID, 0); | ||||||
|  | 	cam->viewWindow.set(1.0f, 1.0f); | ||||||
|  | 	cam->viewOffset.set(0.0f, 0.0f); | ||||||
|  | 	cam->nearPlane = 0.05f; | ||||||
|  | 	cam->farPlane = 10.0f; | ||||||
|  | 	cam->fogPlane = 5.0f; | ||||||
|  | 	cam->projection = Camera::PERSPECTIVE; | ||||||
|  | 	cam->clump = NULL; | ||||||
|  | 	cam->inClump.init(); | ||||||
|  | 	cam->constructPlugins(); | ||||||
|  | 	return cam; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Camera* | ||||||
|  | Camera::clone(void) | ||||||
|  | { | ||||||
|  | 	Camera *cam = Camera::create(); | ||||||
|  | 	if(cam == NULL) | ||||||
|  | 		return NULL; | ||||||
|  | 	cam->object.object.copy(&this->object.object); | ||||||
|  | 	cam->setFrame(this->getFrame()); | ||||||
|  | 	cam->viewWindow = this->viewWindow; | ||||||
|  | 	cam->viewOffset = this->viewOffset; | ||||||
|  | 	cam->nearPlane = this->nearPlane; | ||||||
|  | 	cam->farPlane = this->farPlane; | ||||||
|  | 	cam->fogPlane = this->fogPlane; | ||||||
|  | 	cam->projection = this->projection; | ||||||
|  | 	cam->copyPlugins(this); | ||||||
|  | 	return cam; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | Camera::destroy(void) | ||||||
|  | { | ||||||
|  | 	this->destructPlugins(); | ||||||
|  | 	if(this->clump) | ||||||
|  | 		this->inClump.remove(); | ||||||
|  | 	free(this); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct CameraChunkData | ||||||
|  | { | ||||||
|  | 	V2d viewWindow; | ||||||
|  | 	V2d viewOffset; | ||||||
|  | 	float32 nearPlane, farPlane; | ||||||
|  | 	float32 fogPlane; | ||||||
|  | 	int32 projection; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | Camera* | ||||||
|  | Camera::streamRead(Stream *stream) | ||||||
|  | { | ||||||
|  | 	CameraChunkData buf; | ||||||
|  | 	if(!findChunk(stream, ID_STRUCT, NULL, NULL)){ | ||||||
|  | 		RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	stream->read(&buf, sizeof(CameraChunkData)); | ||||||
|  | 	Camera *cam = Camera::create(); | ||||||
|  | 	cam->viewWindow = buf.viewWindow; | ||||||
|  | 	cam->viewOffset = buf.viewOffset; | ||||||
|  | 	cam->nearPlane = buf.nearPlane; | ||||||
|  | 	cam->farPlane = buf.farPlane; | ||||||
|  | 	cam->fogPlane = buf.fogPlane; | ||||||
|  | 	cam->projection = buf.projection; | ||||||
|  | 	cam->streamReadPlugins(stream); | ||||||
|  | 	return cam; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool | ||||||
|  | Camera::streamWrite(Stream *stream) | ||||||
|  | { | ||||||
|  | 	CameraChunkData buf; | ||||||
|  | 	writeChunkHeader(stream, ID_CAMERA, this->streamGetSize()); | ||||||
|  | 	writeChunkHeader(stream, ID_STRUCT, sizeof(CameraChunkData)); | ||||||
|  | 	buf.viewWindow = this->viewWindow; | ||||||
|  | 	buf.viewOffset = this->viewOffset; | ||||||
|  | 	buf.nearPlane = this->nearPlane; | ||||||
|  | 	buf.farPlane  = this->farPlane; | ||||||
|  | 	buf.fogPlane = this->fogPlane; | ||||||
|  | 	buf.projection = this->projection; | ||||||
|  | 	stream->write(&buf, sizeof(CameraChunkData)); | ||||||
|  | 	this->streamWritePlugins(stream); | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint32 | ||||||
|  | Camera::streamGetSize(void) | ||||||
|  | { | ||||||
|  | 	return 12 + sizeof(CameraChunkData) + 12 + this->streamGetPluginSize(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | Camera::updateProjectionMatrix(void) | ||||||
|  | { | ||||||
|  | 	float32 invwx = 1.0f/this->viewWindow.x; | ||||||
|  | 	float32 invwy = 1.0f/this->viewWindow.y; | ||||||
|  | 	float32 invz = 1.0f/(this->farPlane-this->nearPlane); | ||||||
|  | 	if(rw::platform == PLATFORM_D3D8 || rw::platform == PLATFORM_D3D9 || | ||||||
|  | 	   rw::platform == PLATFORM_XBOX){ | ||||||
|  | 		// is this all really correct?
 | ||||||
|  | 		this->projMat[0] = invwx; | ||||||
|  | 		this->projMat[1] = 0.0f; | ||||||
|  | 		this->projMat[2] = 0.0f; | ||||||
|  | 		this->projMat[3] = 0.0f; | ||||||
|  | 
 | ||||||
|  | 		this->projMat[4] = 0.0f; | ||||||
|  | 		this->projMat[5] = invwy; | ||||||
|  | 		this->projMat[6] = 0.0f; | ||||||
|  | 		this->projMat[7] = 0.0f; | ||||||
|  | 
 | ||||||
|  | 		if(this->projection == PERSPECTIVE){ | ||||||
|  | 			this->projMat[8] = this->viewOffset.x*invwx; | ||||||
|  | 			this->projMat[9] = this->viewOffset.y*invwy; | ||||||
|  | 			this->projMat[10] = this->farPlane*invz; | ||||||
|  | 			this->projMat[11] = 1.0f; | ||||||
|  | 
 | ||||||
|  | 			this->projMat[12] = 0.0f; | ||||||
|  | 			this->projMat[13] = 0.0f; | ||||||
|  | 			this->projMat[14] = -this->nearPlane*this->projMat[10]; | ||||||
|  | 			this->projMat[15] = 0.0f; | ||||||
|  | 		}else{ | ||||||
|  | 			this->projMat[8] = 0.0f; | ||||||
|  | 			this->projMat[9] = 0.0f; | ||||||
|  | 			this->projMat[10] = invz; | ||||||
|  | 			this->projMat[11] = 0.0f; | ||||||
|  | 
 | ||||||
|  | 			this->projMat[12] = this->viewOffset.x*invwx; | ||||||
|  | 			this->projMat[13] = this->viewOffset.y*invwy; | ||||||
|  | 			this->projMat[14] = -this->nearPlane*this->projMat[10]; | ||||||
|  | 			this->projMat[15] = 1.0f; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | Camera::setFOV(float32 fov, float32 ratio) | ||||||
|  | { | ||||||
|  | 	float32 a = tan(fov*3.14159f/360.0f); | ||||||
|  | 	this->viewWindow.x = a; | ||||||
|  | 	this->viewWindow.y = a/ratio; | ||||||
|  | 	this->viewOffset.set(0.0f, 0.0f); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										656
									
								
								src/clump.cpp
									
									
									
									
									
								
							
							
						
						
									
										656
									
								
								src/clump.cpp
									
									
									
									
									
								
							| @ -1,267 +1,19 @@ | |||||||
| #include <cstdio> | #include <cstdio> | ||||||
| #include <cstdlib> | #include <cstdlib> | ||||||
| #include <cstring> |  | ||||||
| #include <cassert> |  | ||||||
| #include <cmath> |  | ||||||
| 
 | 
 | ||||||
| #include "rwbase.h" | #include "rwbase.h" | ||||||
|  | #include "rwerror.h" | ||||||
| #include "rwplg.h" | #include "rwplg.h" | ||||||
| #include "rwpipeline.h" | #include "rwpipeline.h" | ||||||
| #include "rwobjects.h" | #include "rwobjects.h" | ||||||
| #include "rwengine.h" | #include "rwengine.h" | ||||||
| #include "rwps2.h" |  | ||||||
| #include "rwxbox.h" |  | ||||||
| #include "rwd3d8.h" |  | ||||||
| #include "rwd3d9.h" |  | ||||||
| #include "rwwdgl.h" |  | ||||||
| 
 | 
 | ||||||
| using namespace std; | using namespace std; | ||||||
| 
 | 
 | ||||||
|  | #define PLUGIN_ID 2 | ||||||
|  | 
 | ||||||
| namespace rw { | namespace rw { | ||||||
| 
 | 
 | ||||||
| LinkList Frame::dirtyList; |  | ||||||
| 
 |  | ||||||
| Frame* |  | ||||||
| Frame::create(void) |  | ||||||
| { |  | ||||||
| 	Frame *f = (Frame*)malloc(PluginBase::s_size); |  | ||||||
| 	assert(f != NULL); |  | ||||||
| 	f->object.init(Frame::ID, 0); |  | ||||||
| 	f->objectList.init(); |  | ||||||
| 	f->child = NULL; |  | ||||||
| 	f->next = NULL; |  | ||||||
| 	f->root = f; |  | ||||||
| 	f->matrix.setIdentity(); |  | ||||||
| 	f->ltm.setIdentity(); |  | ||||||
| 	f->constructPlugins(); |  | ||||||
| 	return f; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Frame* |  | ||||||
| Frame::cloneHierarchy(void) |  | ||||||
| { |  | ||||||
| 	Frame *frame = this->cloneAndLink(NULL); |  | ||||||
| 	frame->purgeClone(); |  | ||||||
| 	return frame; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| Frame::destroy(void) |  | ||||||
| { |  | ||||||
| 	this->destructPlugins(); |  | ||||||
| 	Frame *parent = this->getParent(); |  | ||||||
| 	Frame *child; |  | ||||||
| 	if(parent){ |  | ||||||
| 		// remove from child list
 |  | ||||||
| 		child = parent->child; |  | ||||||
| 		if(child == this) |  | ||||||
| 			parent->child = this->next; |  | ||||||
| 		else{ |  | ||||||
| 			for(child = child->next; child != this; child = child->next) |  | ||||||
| 				; |  | ||||||
| 			child->next = this->next; |  | ||||||
| 		} |  | ||||||
| 		this->object.parent = NULL; |  | ||||||
| 		// Doesn't seem to make much sense, blame criterion.
 |  | ||||||
| 		this->setHierarchyRoot(this); |  | ||||||
| 	} |  | ||||||
| 	for(Frame *f = this->child; f; f = f->next) |  | ||||||
| 		f->object.parent = NULL; |  | ||||||
| 	free(this); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| Frame::destroyHierarchy(void) |  | ||||||
| { |  | ||||||
| 	Frame *next; |  | ||||||
| 	for(Frame *child = this->child; child; child = next){ |  | ||||||
| 		next = child->next; |  | ||||||
| 		child->destroyHierarchy(); |  | ||||||
| 	} |  | ||||||
| 	this->destructPlugins(); |  | ||||||
| 	free(this); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Frame* |  | ||||||
| Frame::addChild(Frame *child, bool32 append) |  | ||||||
| { |  | ||||||
| 	Frame *c; |  | ||||||
| 	if(child->getParent()) |  | ||||||
| 		child->removeChild(); |  | ||||||
| 	if(append){ |  | ||||||
| 		if(this->child == NULL) |  | ||||||
| 			this->child = child; |  | ||||||
| 		else{ |  | ||||||
| 			for(c = this->child; c->next; c = c->next); |  | ||||||
| 			c->next = child; |  | ||||||
| 		} |  | ||||||
| 		child->next = NULL; |  | ||||||
| 	}else{ |  | ||||||
| 		child->next = this->child; |  | ||||||
| 		this->child = child; |  | ||||||
| 	} |  | ||||||
| 	child->object.parent = this; |  | ||||||
| 	child->root = this->root; |  | ||||||
| 	for(c = child->child; c; c = c->next) |  | ||||||
| 		c->setHierarchyRoot(this); |  | ||||||
| 	if(child->object.privateFlags & Frame::HIERARCHYSYNC){ |  | ||||||
| 		child->inDirtyList.remove(); |  | ||||||
| 		child->object.privateFlags &= ~Frame::HIERARCHYSYNC; |  | ||||||
| 	} |  | ||||||
| 	this->updateObjects(); |  | ||||||
| 	return this; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Frame* |  | ||||||
| Frame::removeChild(void) |  | ||||||
| { |  | ||||||
| 	Frame *parent = this->getParent(); |  | ||||||
| 	Frame *child = parent->child; |  | ||||||
| 	if(child == this) |  | ||||||
| 		parent->child = this->next; |  | ||||||
| 	else{ |  | ||||||
| 		while(child->next != this) |  | ||||||
| 			child = child->next; |  | ||||||
| 		child->next = this->next; |  | ||||||
| 	} |  | ||||||
| 	this->object.parent = this->next = NULL; |  | ||||||
| 	this->root = this; |  | ||||||
| 	for(child = this->child; child; child = child->next) |  | ||||||
| 		child->setHierarchyRoot(this); |  | ||||||
| 	this->updateObjects(); |  | ||||||
| 	return this; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Frame* |  | ||||||
| Frame::forAllChildren(Callback cb, void *data) |  | ||||||
| { |  | ||||||
| 	for(Frame *f = this->child; f; f = f->next) |  | ||||||
| 		cb(f, data); |  | ||||||
| 	return this; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static Frame* |  | ||||||
| countCB(Frame *f, void *count) |  | ||||||
| { |  | ||||||
| 	(*(int32*)count)++; |  | ||||||
| 	f->forAllChildren(countCB, count); |  | ||||||
| 	return f; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int32 |  | ||||||
| Frame::count(void) |  | ||||||
| { |  | ||||||
| 	int32 count = 1; |  | ||||||
| 	this->forAllChildren(countCB, (void*)&count); |  | ||||||
| 	return count; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void |  | ||||||
| syncRecurse(Frame *frame, uint8 flags) |  | ||||||
| { |  | ||||||
| 	uint8 flg; |  | ||||||
| 	for(; frame; frame = frame->next){ |  | ||||||
| 		flg = flags | frame->object.privateFlags; |  | ||||||
| 		if(flg & Frame::SUBTREESYNCLTM){ |  | ||||||
| 			Matrix::mult(&frame->ltm, &frame->getParent()->ltm, &frame->matrix); |  | ||||||
| 			frame->object.privateFlags &= ~Frame::SUBTREESYNCLTM; |  | ||||||
| 		} |  | ||||||
| 		syncRecurse(frame->child, flg); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| Frame::syncHierarchyLTM(void) |  | ||||||
| { |  | ||||||
| 	Frame *child; |  | ||||||
| 	uint8 flg; |  | ||||||
| 	if(this->object.privateFlags & Frame::SUBTREESYNCLTM) |  | ||||||
| 		this->ltm = this->matrix; |  | ||||||
| 	for(child = this->child; child; child = child->next){ |  | ||||||
| 		flg = this->object.privateFlags | child->object.privateFlags; |  | ||||||
| 		if(flg & Frame::SUBTREESYNCLTM){ |  | ||||||
| 			Matrix::mult(&child->ltm, &this->ltm, &child->matrix); |  | ||||||
| 			child->object.privateFlags &= ~Frame::SUBTREESYNCLTM; |  | ||||||
| 		} |  | ||||||
| 		syncRecurse(child, flg); |  | ||||||
| 	} |  | ||||||
| 	this->object.privateFlags &= ~Frame::SYNCLTM; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Matrix* |  | ||||||
| Frame::getLTM(void) |  | ||||||
| { |  | ||||||
| 	if(this->root->object.privateFlags & Frame::HIERARCHYSYNCLTM) |  | ||||||
| 		this->root->syncHierarchyLTM(); |  | ||||||
| 	return &this->ltm; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| Frame::updateObjects(void) |  | ||||||
| { |  | ||||||
| 	if((this->root->object.privateFlags & HIERARCHYSYNC) == 0) |  | ||||||
| 		Frame::dirtyList.add(&this->inDirtyList); |  | ||||||
| 	this->root->object.privateFlags |= HIERARCHYSYNC; |  | ||||||
| 	this->object.privateFlags |= SUBTREESYNC; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| Frame::setHierarchyRoot(Frame *root) |  | ||||||
| { |  | ||||||
| 	this->root = root; |  | ||||||
| 	for(Frame *child = this->child; child; child = child->next) |  | ||||||
| 		child->setHierarchyRoot(root); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Clone a frame hierarchy. Link cloned frames into Frame::root of the originals.
 |  | ||||||
| Frame* |  | ||||||
| Frame::cloneAndLink(Frame *clonedroot) |  | ||||||
| { |  | ||||||
| 	Frame *frame = Frame::create(); |  | ||||||
| 	if(clonedroot == NULL) |  | ||||||
| 		clonedroot = frame; |  | ||||||
| 	frame->object.copy(&this->object); |  | ||||||
| 	frame->matrix = this->matrix; |  | ||||||
| 	//memcpy(frame->matrix, this->matrix, sizeof(this->matrix));
 |  | ||||||
| 	frame->root = clonedroot; |  | ||||||
| 	this->root = frame;	// Remember cloned frame
 |  | ||||||
| 	for(Frame *child = this->child; child; child = child->next){ |  | ||||||
| 		Frame *clonedchild = child->cloneAndLink(clonedroot); |  | ||||||
| 		clonedchild->next = frame->child; |  | ||||||
| 		frame->child = clonedchild; |  | ||||||
| 		clonedchild->object.parent = frame; |  | ||||||
| 	} |  | ||||||
| 	frame->copyPlugins(this); |  | ||||||
| 	return frame; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Remove links to cloned frames from hierarchy.
 |  | ||||||
| void |  | ||||||
| Frame::purgeClone(void) |  | ||||||
| { |  | ||||||
| 	Frame *parent = this->getParent(); |  | ||||||
| 	this->setHierarchyRoot(parent ? parent->root : this); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static Frame* |  | ||||||
| sizeCB(Frame *f, void *size) |  | ||||||
| { |  | ||||||
| 	*(int32*)size += f->streamGetPluginSize(); |  | ||||||
| 	f->forAllChildren(sizeCB, size); |  | ||||||
| 	return f; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Frame** |  | ||||||
| makeFrameList(Frame *frame, Frame **flist) |  | ||||||
| { |  | ||||||
| 	*flist++ = frame; |  | ||||||
| 	if(frame->next) |  | ||||||
| 		flist = makeFrameList(frame->next, flist); |  | ||||||
| 	if(frame->child) |  | ||||||
| 		flist = makeFrameList(frame->child, flist); |  | ||||||
| 	return flist; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| //
 | //
 | ||||||
| // Clump
 | // Clump
 | ||||||
| //
 | //
 | ||||||
| @ -270,7 +22,10 @@ Clump* | |||||||
| Clump::create(void) | Clump::create(void) | ||||||
| { | { | ||||||
| 	Clump *clump = (Clump*)malloc(PluginBase::s_size); | 	Clump *clump = (Clump*)malloc(PluginBase::s_size); | ||||||
| 	assert(clump != NULL); | 	if(clump == nil){ | ||||||
|  | 		RWERROR((ERR_ALLOC, PluginBase::s_size)); | ||||||
|  | 		return nil; | ||||||
|  | 	} | ||||||
| 	clump->object.init(Clump::ID, 0); | 	clump->object.init(Clump::ID, 0); | ||||||
| 	clump->atomics.init(); | 	clump->atomics.init(); | ||||||
| 	clump->lights.init(); | 	clump->lights.init(); | ||||||
| @ -318,8 +73,14 @@ Clump::streamRead(Stream *stream) | |||||||
| 	uint32 length, version; | 	uint32 length, version; | ||||||
| 	int32 buf[3]; | 	int32 buf[3]; | ||||||
| 	Clump *clump; | 	Clump *clump; | ||||||
| 	assert(findChunk(stream, ID_STRUCT, &length, &version)); | 
 | ||||||
|  | 	if(!findChunk(stream, ID_STRUCT, &length, &version)){ | ||||||
|  | 		RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 		return nil; | ||||||
|  | 	} | ||||||
| 	clump = Clump::create(); | 	clump = Clump::create(); | ||||||
|  | 	if(clump == nil) | ||||||
|  | 		return nil; | ||||||
| 	stream->read(buf, length); | 	stream->read(buf, length); | ||||||
| 	int32 numAtomics = buf[0]; | 	int32 numAtomics = buf[0]; | ||||||
| 	int32 numLights = 0; | 	int32 numLights = 0; | ||||||
| @ -339,31 +100,68 @@ Clump::streamRead(Stream *stream) | |||||||
| 	if(version >= 0x30400){ | 	if(version >= 0x30400){ | ||||||
| 		// Geometry list
 | 		// Geometry list
 | ||||||
| 		int32 numGeometries = 0; | 		int32 numGeometries = 0; | ||||||
| 		assert(findChunk(stream, ID_GEOMETRYLIST, NULL, NULL)); | 		if(!findChunk(stream, ID_GEOMETRYLIST, nil, nil)){ | ||||||
| 		assert(findChunk(stream, ID_STRUCT, NULL, NULL)); | 			RWERROR((ERR_CHUNK, "GEOMETRYLIST")); | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
|  | 		if(!findChunk(stream, ID_STRUCT, nil, nil)){ | ||||||
|  | 			RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 		numGeometries = stream->readI32(); | 		numGeometries = stream->readI32(); | ||||||
| 		if(numGeometries) | 		if(numGeometries) | ||||||
| 			geometryList = new Geometry*[numGeometries]; | 			geometryList = new Geometry*[numGeometries]; | ||||||
| 		for(int32 i = 0; i < numGeometries; i++){ | 		for(int32 i = 0; i < numGeometries; i++){ | ||||||
| 			assert(findChunk(stream, ID_GEOMETRY, NULL, NULL)); | 			if(!findChunk(stream, ID_GEOMETRY, nil, nil)){ | ||||||
|  | 				RWERROR((ERR_CHUNK, "GEOMETRY")); | ||||||
|  | 				// TODO: free
 | ||||||
|  | 				return nil; | ||||||
|  | 			} | ||||||
| 			geometryList[i] = Geometry::streamRead(stream); | 			geometryList[i] = Geometry::streamRead(stream); | ||||||
|  | 			if(geometryList[i] == nil){ | ||||||
|  | 				// TODO: free
 | ||||||
|  | 				return nil; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Atomics
 | 	// Atomics
 | ||||||
|  | 	Atomic *a; | ||||||
| 	for(int32 i = 0; i < numAtomics; i++){ | 	for(int32 i = 0; i < numAtomics; i++){ | ||||||
| 		assert(findChunk(stream, ID_ATOMIC, NULL, NULL)); | 		if(!findChunk(stream, ID_ATOMIC, nil, nil)){ | ||||||
| 		Atomic *a = Atomic::streamReadClump(stream, frameList, geometryList); | 			RWERROR((ERR_CHUNK, "ATOMIC")); | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
|  | 		a = Atomic::streamReadClump(stream, frameList, geometryList); | ||||||
|  | 		if(a == nil){ | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 		clump->addAtomic(a); | 		clump->addAtomic(a); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Lights
 | 	// Lights
 | ||||||
| 	for(int32 i = 0; i < numLights; i++){ | 	for(int32 i = 0; i < numLights; i++){ | ||||||
| 		int32 frm; | 		int32 frm; | ||||||
| 		assert(findChunk(stream, ID_STRUCT, NULL, NULL)); | 		if(!findChunk(stream, ID_STRUCT, nil, nil)){ | ||||||
|  | 			RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 		frm = stream->readI32(); | 		frm = stream->readI32(); | ||||||
| 		assert(findChunk(stream, ID_LIGHT, NULL, NULL)); | 		if(!findChunk(stream, ID_LIGHT, nil, nil)){ | ||||||
|  | 			RWERROR((ERR_CHUNK, "LIGHT")); | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 		Light *l = Light::streamRead(stream); | 		Light *l = Light::streamRead(stream); | ||||||
|  | 		if(l == nil){ | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 		l->setFrame(frameList[frm]); | 		l->setFrame(frameList[frm]); | ||||||
| 		clump->addLight(l); | 		clump->addLight(l); | ||||||
| 	} | 	} | ||||||
| @ -371,10 +169,22 @@ Clump::streamRead(Stream *stream) | |||||||
| 	// Cameras
 | 	// Cameras
 | ||||||
| 	for(int32 i = 0; i < numCameras; i++){ | 	for(int32 i = 0; i < numCameras; i++){ | ||||||
| 		int32 frm; | 		int32 frm; | ||||||
| 		assert(findChunk(stream, ID_STRUCT, NULL, NULL)); | 		if(!findChunk(stream, ID_STRUCT, nil, nil)){ | ||||||
|  | 			RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 		frm = stream->readI32(); | 		frm = stream->readI32(); | ||||||
| 		assert(findChunk(stream, ID_CAMERA, NULL, NULL)); | 		if(!findChunk(stream, ID_CAMERA, nil, nil)){ | ||||||
|  | 			RWERROR((ERR_CHUNK, "CAMERA")); | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 		Camera *cam = Camera::streamRead(stream); | 		Camera *cam = Camera::streamRead(stream); | ||||||
|  | 		if(cam == nil){ | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 		cam->setFrame(frameList[frm]); | 		cam->setFrame(frameList[frm]); | ||||||
| 		clump->addCamera(cam); | 		clump->addCamera(cam); | ||||||
| 	} | 	} | ||||||
| @ -450,6 +260,14 @@ struct FrameStreamData | |||||||
| 	int32 matflag; | 	int32 matflag; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | static Frame* | ||||||
|  | sizeCB(Frame *f, void *size) | ||||||
|  | { | ||||||
|  | 	*(int32*)size += f->streamGetPluginSize(); | ||||||
|  | 	f->forAllChildren(sizeCB, size); | ||||||
|  | 	return f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| uint32 | uint32 | ||||||
| Clump::streamGetSize(void) | Clump::streamGetSize(void) | ||||||
| { | { | ||||||
| @ -498,13 +316,19 @@ Clump::render(void) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | bool | ||||||
| Clump::frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf) | Clump::frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf) | ||||||
| { | { | ||||||
| 	FrameStreamData buf; | 	FrameStreamData buf; | ||||||
| 	int32 numFrames = 0; | 	int32 numFrames = 0; | ||||||
| 	assert(findChunk(stream, ID_FRAMELIST, NULL, NULL)); | 	if(!findChunk(stream, ID_FRAMELIST, nil, nil)){ | ||||||
| 	assert(findChunk(stream, ID_STRUCT, NULL, NULL)); | 		RWERROR((ERR_CHUNK, "FRAMELIST")); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 	if(!findChunk(stream, ID_STRUCT, nil, nil)){ | ||||||
|  | 		RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
| 	numFrames = stream->readI32(); | 	numFrames = stream->readI32(); | ||||||
| 	Frame **frameList = new Frame*[numFrames]; | 	Frame **frameList = new Frame*[numFrames]; | ||||||
| 	for(int32 i = 0; i < numFrames; i++){ | 	for(int32 i = 0; i < numFrames; i++){ | ||||||
| @ -527,6 +351,7 @@ Clump::frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf) | |||||||
| 		frameList[i]->streamReadPlugins(stream); | 		frameList[i]->streamReadPlugins(stream); | ||||||
| 	*nf = numFrames; | 	*nf = numFrames; | ||||||
| 	*flp = frameList; | 	*flp = frameList; | ||||||
|  | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| @ -566,14 +391,17 @@ Atomic* | |||||||
| Atomic::create(void) | Atomic::create(void) | ||||||
| { | { | ||||||
| 	Atomic *atomic = (Atomic*)malloc(PluginBase::s_size); | 	Atomic *atomic = (Atomic*)malloc(PluginBase::s_size); | ||||||
| 	assert(atomic != NULL); | 	if(atomic == nil){ | ||||||
|  | 		RWERROR((ERR_ALLOC, PluginBase::s_size)); | ||||||
|  | 		return nil; | ||||||
|  | 	} | ||||||
| 	atomic->object.object.init(Atomic::ID, 0); | 	atomic->object.object.init(Atomic::ID, 0); | ||||||
| 	atomic->geometry = NULL; | 	atomic->geometry = nil; | ||||||
| 	atomic->worldBoundingSphere.center.set(0.0f, 0.0f, 0.0f); | 	atomic->worldBoundingSphere.center.set(0.0f, 0.0f, 0.0f); | ||||||
| 	atomic->worldBoundingSphere.radius = 0.0f; | 	atomic->worldBoundingSphere.radius = 0.0f; | ||||||
| 	atomic->setFrame(NULL); | 	atomic->setFrame(nil); | ||||||
| 	atomic->clump = NULL; | 	atomic->clump = nil; | ||||||
| 	atomic->pipeline = NULL; | 	atomic->pipeline = nil; | ||||||
| 	atomic->renderCB = Atomic::defaultRenderCB; | 	atomic->renderCB = Atomic::defaultRenderCB; | ||||||
| 	atomic->object.object.flags = Atomic::COLLISIONTEST | Atomic::RENDER; | 	atomic->object.object.flags = Atomic::COLLISIONTEST | Atomic::RENDER; | ||||||
| 	atomic->constructPlugins(); | 	atomic->constructPlugins(); | ||||||
| @ -603,7 +431,7 @@ Atomic::destroy(void) | |||||||
| 		this->geometry->destroy(); | 		this->geometry->destroy(); | ||||||
| 	if(this->clump) | 	if(this->clump) | ||||||
| 		this->inClump.remove(); | 		this->inClump.remove(); | ||||||
| 	this->setFrame(NULL); | 	this->setFrame(nil); | ||||||
| 	free(this); | 	free(this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -612,7 +440,7 @@ Atomic::removeFromClump(void) | |||||||
| { | { | ||||||
| 	if(this->clump){ | 	if(this->clump){ | ||||||
| 		this->inClump.remove(); | 		this->inClump.remove(); | ||||||
| 		this->clump = NULL; | 		this->clump = nil; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -640,13 +468,26 @@ Atomic::streamReadClump(Stream *stream, | |||||||
| { | { | ||||||
| 	int32 buf[4]; | 	int32 buf[4]; | ||||||
| 	uint32 version; | 	uint32 version; | ||||||
| 	assert(findChunk(stream, ID_STRUCT, NULL, &version)); | 	if(!findChunk(stream, ID_STRUCT, nil, &version)){ | ||||||
|  | 		RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 		return nil; | ||||||
|  | 	} | ||||||
| 	stream->read(buf, version < 0x30400 ? 12 : 16); | 	stream->read(buf, version < 0x30400 ? 12 : 16); | ||||||
| 	Atomic *atomic = Atomic::create(); | 	Atomic *atomic = Atomic::create(); | ||||||
|  | 	if(atomic == nil) | ||||||
|  | 		return nil; | ||||||
| 	atomic->setFrame(frameList[buf[0]]); | 	atomic->setFrame(frameList[buf[0]]); | ||||||
| 	if(version < 0x30400){ | 	if(version < 0x30400){ | ||||||
| 		assert(findChunk(stream, ID_GEOMETRY, NULL, NULL)); | 		if(!findChunk(stream, ID_GEOMETRY, nil, nil)){ | ||||||
|  | 			RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 		atomic->geometry = Geometry::streamRead(stream); | 		atomic->geometry = Geometry::streamRead(stream); | ||||||
|  | 		if(atomic->geometry == nil){ | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 	}else | 	}else | ||||||
| 		atomic->geometry = geometryList[buf[1]]; | 		atomic->geometry = geometryList[buf[1]]; | ||||||
| 	atomic->object.object.flags = buf[2]; | 	atomic->object.object.flags = buf[2]; | ||||||
| @ -663,7 +504,7 @@ Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames) | |||||||
| { | { | ||||||
| 	int32 buf[4] = { 0, 0, 0, 0 }; | 	int32 buf[4] = { 0, 0, 0, 0 }; | ||||||
| 	Clump *c = this->clump; | 	Clump *c = this->clump; | ||||||
| 	if(c == NULL) | 	if(c == nil) | ||||||
| 		return false; | 		return false; | ||||||
| 	writeChunkHeader(stream, ID_ATOMIC, this->streamGetSize()); | 	writeChunkHeader(stream, ID_ATOMIC, this->streamGetSize()); | ||||||
| 	writeChunkHeader(stream, ID_STRUCT, rw::version < 0x30400 ? 12 : 16); | 	writeChunkHeader(stream, ID_STRUCT, rw::version < 0x30400 ? 12 : 16); | ||||||
| @ -737,7 +578,7 @@ static int32 | |||||||
| getSizeAtomicRights(void *object, int32, int32) | getSizeAtomicRights(void *object, int32, int32) | ||||||
| { | { | ||||||
| 	Atomic *atomic = (Atomic*)object; | 	Atomic *atomic = (Atomic*)object; | ||||||
| 	if(atomic->pipeline == NULL || atomic->pipeline->pluginID == 0) | 	if(atomic->pipeline == nil || atomic->pipeline->pluginID == 0) | ||||||
| 		return -1; | 		return -1; | ||||||
| 	return 8; | 	return 8; | ||||||
| } | } | ||||||
| @ -745,272 +586,11 @@ getSizeAtomicRights(void *object, int32, int32) | |||||||
| void | void | ||||||
| registerAtomicRightsPlugin(void) | registerAtomicRightsPlugin(void) | ||||||
| { | { | ||||||
| 	Atomic::registerPlugin(0, ID_RIGHTTORENDER, NULL, NULL, NULL); | 	Atomic::registerPlugin(0, ID_RIGHTTORENDER, nil, nil, nil); | ||||||
| 	Atomic::registerPluginStream(ID_RIGHTTORENDER, | 	Atomic::registerPluginStream(ID_RIGHTTORENDER, | ||||||
| 	                             readAtomicRights, | 	                             readAtomicRights, | ||||||
| 	                             writeAtomicRights, | 	                             writeAtomicRights, | ||||||
| 	                             getSizeAtomicRights); | 	                             getSizeAtomicRights); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // Light
 |  | ||||||
| //
 |  | ||||||
| 
 |  | ||||||
| Light* |  | ||||||
| Light::create(int32 type) |  | ||||||
| { |  | ||||||
| 	Light *light = (Light*)malloc(PluginBase::s_size); |  | ||||||
| 	assert(light != NULL); |  | ||||||
| 	light->object.object.init(Light::ID, type); |  | ||||||
| 	light->radius = 0.0f; |  | ||||||
| 	light->color.red = 1.0f; |  | ||||||
| 	light->color.green = 1.0f; |  | ||||||
| 	light->color.blue = 1.0f; |  | ||||||
| 	light->color.alpha = 1.0f; |  | ||||||
| 	light->minusCosAngle = 1.0f; |  | ||||||
| 	light->object.object.privateFlags = 1; |  | ||||||
| 	light->object.object.flags = LIGHTATOMICS | LIGHTWORLD; |  | ||||||
| 	light->clump = NULL; |  | ||||||
| 	light->inClump.init(); |  | ||||||
| 	light->constructPlugins(); |  | ||||||
| 	return light; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| Light::destroy(void) |  | ||||||
| { |  | ||||||
| 	this->destructPlugins(); |  | ||||||
| 	if(this->clump) |  | ||||||
| 		this->inClump.remove(); |  | ||||||
| 	free(this); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| Light::setAngle(float32 angle) |  | ||||||
| { |  | ||||||
| 	this->minusCosAngle = -cos(angle); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| float32 |  | ||||||
| Light::getAngle(void) |  | ||||||
| { |  | ||||||
| 	return acos(-this->minusCosAngle); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| Light::setColor(float32 r, float32 g, float32 b) |  | ||||||
| { |  | ||||||
| 	this->color.red = r; |  | ||||||
| 	this->color.green = g; |  | ||||||
| 	this->color.blue = b; |  | ||||||
| 	this->object.object.privateFlags = r == g && r == b; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct LightChunkData |  | ||||||
| { |  | ||||||
| 	float32 radius; |  | ||||||
| 	float32 red, green, blue; |  | ||||||
| 	float32 minusCosAngle; |  | ||||||
| 	uint16 flags; |  | ||||||
| 	uint16 type; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| Light* |  | ||||||
| Light::streamRead(Stream *stream) |  | ||||||
| { |  | ||||||
| 	uint32 version; |  | ||||||
| 	LightChunkData buf; |  | ||||||
| 	assert(findChunk(stream, ID_STRUCT, NULL, &version)); |  | ||||||
| 	stream->read(&buf, sizeof(LightChunkData)); |  | ||||||
| 	Light *light = Light::create(buf.type); |  | ||||||
| 	light->radius = buf.radius; |  | ||||||
| 	light->setColor(buf.red, buf.green, buf.blue); |  | ||||||
| 	float32 a = buf.minusCosAngle; |  | ||||||
| 	if(version >= 0x30300) |  | ||||||
| 		light->minusCosAngle = a; |  | ||||||
| 	else |  | ||||||
| 		// tan -> -cos
 |  | ||||||
| 		light->minusCosAngle = -1.0f/sqrt(a*a+1.0f); |  | ||||||
| 	light->object.object.flags = (uint8)buf.flags; |  | ||||||
| 	light->streamReadPlugins(stream); |  | ||||||
| 	return light; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool |  | ||||||
| Light::streamWrite(Stream *stream) |  | ||||||
| { |  | ||||||
| 	LightChunkData buf; |  | ||||||
| 	writeChunkHeader(stream, ID_LIGHT, this->streamGetSize()); |  | ||||||
| 	writeChunkHeader(stream, ID_STRUCT, sizeof(LightChunkData)); |  | ||||||
| 	buf.radius = this->radius; |  | ||||||
| 	buf.red   = this->color.red; |  | ||||||
| 	buf.green = this->color.green; |  | ||||||
| 	buf.blue  = this->color.blue; |  | ||||||
| 	if(version >= 0x30300) |  | ||||||
| 		buf.minusCosAngle = this->minusCosAngle; |  | ||||||
| 	else |  | ||||||
| 		buf.minusCosAngle = tan(acos(-this->minusCosAngle)); |  | ||||||
| 	buf.flags = this->object.object.flags; |  | ||||||
| 	buf.type = this->object.object.subType; |  | ||||||
| 	stream->write(&buf, sizeof(LightChunkData)); |  | ||||||
| 
 |  | ||||||
| 	this->streamWritePlugins(stream); |  | ||||||
| 	return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uint32 |  | ||||||
| Light::streamGetSize(void) |  | ||||||
| { |  | ||||||
| 	return 12 + sizeof(LightChunkData) + 12 + this->streamGetPluginSize(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| //
 |  | ||||||
| // Camera
 |  | ||||||
| //
 |  | ||||||
| 
 |  | ||||||
| Camera* |  | ||||||
| Camera::create(void) |  | ||||||
| { |  | ||||||
| 	Camera *cam = (Camera*)malloc(PluginBase::s_size); |  | ||||||
| 	cam->object.object.init(Camera::ID, 0); |  | ||||||
| 	cam->viewWindow.set(1.0f, 1.0f); |  | ||||||
| 	cam->viewOffset.set(0.0f, 0.0f); |  | ||||||
| 	cam->nearPlane = 0.05f; |  | ||||||
| 	cam->farPlane = 10.0f; |  | ||||||
| 	cam->fogPlane = 5.0f; |  | ||||||
| 	cam->projection = Camera::PERSPECTIVE; |  | ||||||
| 	cam->clump = NULL; |  | ||||||
| 	cam->inClump.init(); |  | ||||||
| 	cam->constructPlugins(); |  | ||||||
| 	return cam; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Camera* |  | ||||||
| Camera::clone(void) |  | ||||||
| { |  | ||||||
| 	Camera *cam = Camera::create(); |  | ||||||
| 	cam->object.object.copy(&this->object.object); |  | ||||||
| 	cam->setFrame(this->getFrame()); |  | ||||||
| 	cam->viewWindow = this->viewWindow; |  | ||||||
| 	cam->viewOffset = this->viewOffset; |  | ||||||
| 	cam->nearPlane = this->nearPlane; |  | ||||||
| 	cam->farPlane = this->farPlane; |  | ||||||
| 	cam->fogPlane = this->fogPlane; |  | ||||||
| 	cam->projection = this->projection; |  | ||||||
| 	cam->copyPlugins(this); |  | ||||||
| 	return cam; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| Camera::destroy(void) |  | ||||||
| { |  | ||||||
| 	this->destructPlugins(); |  | ||||||
| 	if(this->clump) |  | ||||||
| 		this->inClump.remove(); |  | ||||||
| 	free(this); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct CameraChunkData |  | ||||||
| { |  | ||||||
| 	V2d viewWindow; |  | ||||||
| 	V2d viewOffset; |  | ||||||
| 	float32 nearPlane, farPlane; |  | ||||||
| 	float32 fogPlane; |  | ||||||
| 	int32 projection; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| Camera* |  | ||||||
| Camera::streamRead(Stream *stream) |  | ||||||
| { |  | ||||||
| 	CameraChunkData buf; |  | ||||||
| 	assert(findChunk(stream, ID_STRUCT, NULL, NULL)); |  | ||||||
| 	stream->read(&buf, sizeof(CameraChunkData)); |  | ||||||
| 	Camera *cam = Camera::create(); |  | ||||||
| 	cam->viewWindow = buf.viewWindow; |  | ||||||
| 	cam->viewOffset = buf.viewOffset; |  | ||||||
| 	cam->nearPlane = buf.nearPlane; |  | ||||||
| 	cam->farPlane = buf.farPlane; |  | ||||||
| 	cam->fogPlane = buf.fogPlane; |  | ||||||
| 	cam->projection = buf.projection; |  | ||||||
| 	cam->streamReadPlugins(stream); |  | ||||||
| 	return cam; |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool |  | ||||||
| Camera::streamWrite(Stream *stream) |  | ||||||
| { |  | ||||||
| 	CameraChunkData buf; |  | ||||||
| 	writeChunkHeader(stream, ID_CAMERA, this->streamGetSize()); |  | ||||||
| 	writeChunkHeader(stream, ID_STRUCT, sizeof(CameraChunkData)); |  | ||||||
| 	buf.viewWindow = this->viewWindow; |  | ||||||
| 	buf.viewOffset = this->viewOffset; |  | ||||||
| 	buf.nearPlane = this->nearPlane; |  | ||||||
| 	buf.farPlane  = this->farPlane; |  | ||||||
| 	buf.fogPlane = this->fogPlane; |  | ||||||
| 	buf.projection = this->projection; |  | ||||||
| 	stream->write(&buf, sizeof(CameraChunkData)); |  | ||||||
| 	this->streamWritePlugins(stream); |  | ||||||
| 	return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uint32 |  | ||||||
| Camera::streamGetSize(void) |  | ||||||
| { |  | ||||||
| 	return 12 + sizeof(CameraChunkData) + 12 + this->streamGetPluginSize(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| Camera::updateProjectionMatrix(void) |  | ||||||
| { |  | ||||||
| 	float32 invwx = 1.0f/this->viewWindow.x; |  | ||||||
| 	float32 invwy = 1.0f/this->viewWindow.y; |  | ||||||
| 	float32 invz = 1.0f/(this->farPlane-this->nearPlane); |  | ||||||
| 	if(rw::platform == PLATFORM_D3D8 || rw::platform == PLATFORM_D3D9 || |  | ||||||
| 	   rw::platform == PLATFORM_XBOX){ |  | ||||||
| 		// is this all really correct?
 |  | ||||||
| 		this->projMat[0] = invwx; |  | ||||||
| 		this->projMat[1] = 0.0f; |  | ||||||
| 		this->projMat[2] = 0.0f; |  | ||||||
| 		this->projMat[3] = 0.0f; |  | ||||||
| 
 |  | ||||||
| 		this->projMat[4] = 0.0f; |  | ||||||
| 		this->projMat[5] = invwy; |  | ||||||
| 		this->projMat[6] = 0.0f; |  | ||||||
| 		this->projMat[7] = 0.0f; |  | ||||||
| 
 |  | ||||||
| 		if(this->projection == PERSPECTIVE){ |  | ||||||
| 			this->projMat[8] = this->viewOffset.x*invwx; |  | ||||||
| 			this->projMat[9] = this->viewOffset.y*invwy; |  | ||||||
| 			this->projMat[10] = this->farPlane*invz; |  | ||||||
| 			this->projMat[11] = 1.0f; |  | ||||||
| 
 |  | ||||||
| 			this->projMat[12] = 0.0f; |  | ||||||
| 			this->projMat[13] = 0.0f; |  | ||||||
| 			this->projMat[14] = -this->nearPlane*this->projMat[10]; |  | ||||||
| 			this->projMat[15] = 0.0f; |  | ||||||
| 		}else{ |  | ||||||
| 			this->projMat[8] = 0.0f; |  | ||||||
| 			this->projMat[9] = 0.0f; |  | ||||||
| 			this->projMat[10] = invz; |  | ||||||
| 			this->projMat[11] = 0.0f; |  | ||||||
| 
 |  | ||||||
| 			this->projMat[12] = this->viewOffset.x*invwx; |  | ||||||
| 			this->projMat[13] = this->viewOffset.y*invwy; |  | ||||||
| 			this->projMat[14] = -this->nearPlane*this->projMat[10]; |  | ||||||
| 			this->projMat[15] = 1.0f; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| Camera::setFOV(float32 fov, float32 ratio) |  | ||||||
| { |  | ||||||
| 	float32 a = tan(fov*3.14159f/360.0f); |  | ||||||
| 	this->viewWindow.x = a; |  | ||||||
| 	this->viewWindow.y = a/ratio; |  | ||||||
| 	this->viewOffset.set(0.0f, 0.0f); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| #include <cstdio> | #include <cstdio> | ||||||
| #include <assert.h> | #include <cstdlib> | ||||||
|  | #include <cassert> | ||||||
| 
 | 
 | ||||||
| #include "rwbase.h" | #include "rwbase.h" | ||||||
| #include "rwplg.h" | #include "rwplg.h" | ||||||
|  | |||||||
							
								
								
									
										49
									
								
								src/error.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/error.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | #include <cstdio> | ||||||
|  | #include <stdarg.h> | ||||||
|  | 
 | ||||||
|  | #include "rwbase.h" | ||||||
|  | #include "rwerror.h" | ||||||
|  | 
 | ||||||
|  | namespace rw { | ||||||
|  | 
 | ||||||
|  | static Error error; | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | setError(Error *e) | ||||||
|  | { | ||||||
|  | 	error = *e; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Error* | ||||||
|  | getError(Error *e) | ||||||
|  | { | ||||||
|  | 	*e = error; | ||||||
|  | 	error.plugin = 0; | ||||||
|  | 	error.code = 0; | ||||||
|  | 	return e; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define ECODE(c, s) s, | ||||||
|  | 
 | ||||||
|  | const char *errstrs[] = { | ||||||
|  | 	"No error", | ||||||
|  | #include "base.err" | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #undef ECODE | ||||||
|  | 
 | ||||||
|  | char* | ||||||
|  | dbgsprint(int32 code, ...) | ||||||
|  | { | ||||||
|  | 	va_list ap; | ||||||
|  | 	static char strbuf[512]; | ||||||
|  | 
 | ||||||
|  | 	if(code & 0x80000000) | ||||||
|  | 		code &= ~0x80000000; | ||||||
|  | 	va_start(ap, code); | ||||||
|  | 	vsprintf(strbuf, errstrs[code], ap); | ||||||
|  | 	va_end(ap); | ||||||
|  | 	return strbuf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										262
									
								
								src/frame.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								src/frame.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,262 @@ | |||||||
|  | #include <cstdio> | ||||||
|  | #include <cstdlib> | ||||||
|  | #include <cstring> | ||||||
|  | #include <cassert> | ||||||
|  | #include <cmath> | ||||||
|  | 
 | ||||||
|  | #include "rwbase.h" | ||||||
|  | #include "rwerror.h" | ||||||
|  | #include "rwplg.h" | ||||||
|  | #include "rwpipeline.h" | ||||||
|  | #include "rwobjects.h" | ||||||
|  | #include "rwengine.h" | ||||||
|  | #include "rwps2.h" | ||||||
|  | #include "rwxbox.h" | ||||||
|  | #include "rwd3d8.h" | ||||||
|  | #include "rwd3d9.h" | ||||||
|  | #include "rwwdgl.h" | ||||||
|  | 
 | ||||||
|  | #define PLUGIN_ID 0 | ||||||
|  | 
 | ||||||
|  | namespace rw { | ||||||
|  | 
 | ||||||
|  | LinkList Frame::dirtyList; | ||||||
|  | 
 | ||||||
|  | Frame* | ||||||
|  | Frame::create(void) | ||||||
|  | { | ||||||
|  | 	Frame *f = (Frame*)malloc(PluginBase::s_size); | ||||||
|  | 	if(f == NULL){ | ||||||
|  | 		RWERROR((ERR_ALLOC, PluginBase::s_size)); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	f->object.init(Frame::ID, 0); | ||||||
|  | 	f->objectList.init(); | ||||||
|  | 	f->child = NULL; | ||||||
|  | 	f->next = NULL; | ||||||
|  | 	f->root = f; | ||||||
|  | 	f->matrix.setIdentity(); | ||||||
|  | 	f->ltm.setIdentity(); | ||||||
|  | 	f->constructPlugins(); | ||||||
|  | 	return f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Frame* | ||||||
|  | Frame::cloneHierarchy(void) | ||||||
|  | { | ||||||
|  | 	Frame *frame = this->cloneAndLink(NULL); | ||||||
|  | 	frame->purgeClone(); | ||||||
|  | 	return frame; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | Frame::destroy(void) | ||||||
|  | { | ||||||
|  | 	this->destructPlugins(); | ||||||
|  | 	Frame *parent = this->getParent(); | ||||||
|  | 	Frame *child; | ||||||
|  | 	if(parent){ | ||||||
|  | 		// remove from child list
 | ||||||
|  | 		child = parent->child; | ||||||
|  | 		if(child == this) | ||||||
|  | 			parent->child = this->next; | ||||||
|  | 		else{ | ||||||
|  | 			for(child = child->next; child != this; child = child->next) | ||||||
|  | 				; | ||||||
|  | 			child->next = this->next; | ||||||
|  | 		} | ||||||
|  | 		this->object.parent = NULL; | ||||||
|  | 		// Doesn't seem to make much sense, blame criterion.
 | ||||||
|  | 		this->setHierarchyRoot(this); | ||||||
|  | 	} | ||||||
|  | 	for(Frame *f = this->child; f; f = f->next) | ||||||
|  | 		f->object.parent = NULL; | ||||||
|  | 	free(this); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | Frame::destroyHierarchy(void) | ||||||
|  | { | ||||||
|  | 	Frame *next; | ||||||
|  | 	for(Frame *child = this->child; child; child = next){ | ||||||
|  | 		next = child->next; | ||||||
|  | 		child->destroyHierarchy(); | ||||||
|  | 	} | ||||||
|  | 	this->destructPlugins(); | ||||||
|  | 	free(this); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Frame* | ||||||
|  | Frame::addChild(Frame *child, bool32 append) | ||||||
|  | { | ||||||
|  | 	Frame *c; | ||||||
|  | 	if(child->getParent()) | ||||||
|  | 		child->removeChild(); | ||||||
|  | 	if(append){ | ||||||
|  | 		if(this->child == NULL) | ||||||
|  | 			this->child = child; | ||||||
|  | 		else{ | ||||||
|  | 			for(c = this->child; c->next; c = c->next); | ||||||
|  | 			c->next = child; | ||||||
|  | 		} | ||||||
|  | 		child->next = NULL; | ||||||
|  | 	}else{ | ||||||
|  | 		child->next = this->child; | ||||||
|  | 		this->child = child; | ||||||
|  | 	} | ||||||
|  | 	child->object.parent = this; | ||||||
|  | 	child->root = this->root; | ||||||
|  | 	for(c = child->child; c; c = c->next) | ||||||
|  | 		c->setHierarchyRoot(this); | ||||||
|  | 	if(child->object.privateFlags & Frame::HIERARCHYSYNC){ | ||||||
|  | 		child->inDirtyList.remove(); | ||||||
|  | 		child->object.privateFlags &= ~Frame::HIERARCHYSYNC; | ||||||
|  | 	} | ||||||
|  | 	this->updateObjects(); | ||||||
|  | 	return this; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Frame* | ||||||
|  | Frame::removeChild(void) | ||||||
|  | { | ||||||
|  | 	Frame *parent = this->getParent(); | ||||||
|  | 	Frame *child = parent->child; | ||||||
|  | 	if(child == this) | ||||||
|  | 		parent->child = this->next; | ||||||
|  | 	else{ | ||||||
|  | 		while(child->next != this) | ||||||
|  | 			child = child->next; | ||||||
|  | 		child->next = this->next; | ||||||
|  | 	} | ||||||
|  | 	this->object.parent = this->next = NULL; | ||||||
|  | 	this->root = this; | ||||||
|  | 	for(child = this->child; child; child = child->next) | ||||||
|  | 		child->setHierarchyRoot(this); | ||||||
|  | 	this->updateObjects(); | ||||||
|  | 	return this; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Frame* | ||||||
|  | Frame::forAllChildren(Callback cb, void *data) | ||||||
|  | { | ||||||
|  | 	for(Frame *f = this->child; f; f = f->next) | ||||||
|  | 		cb(f, data); | ||||||
|  | 	return this; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static Frame* | ||||||
|  | countCB(Frame *f, void *count) | ||||||
|  | { | ||||||
|  | 	(*(int32*)count)++; | ||||||
|  | 	f->forAllChildren(countCB, count); | ||||||
|  | 	return f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int32 | ||||||
|  | Frame::count(void) | ||||||
|  | { | ||||||
|  | 	int32 count = 1; | ||||||
|  | 	this->forAllChildren(countCB, (void*)&count); | ||||||
|  | 	return count; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | syncRecurse(Frame *frame, uint8 flags) | ||||||
|  | { | ||||||
|  | 	uint8 flg; | ||||||
|  | 	for(; frame; frame = frame->next){ | ||||||
|  | 		flg = flags | frame->object.privateFlags; | ||||||
|  | 		if(flg & Frame::SUBTREESYNCLTM){ | ||||||
|  | 			Matrix::mult(&frame->ltm, &frame->getParent()->ltm, | ||||||
|  | 			                          &frame->matrix); | ||||||
|  | 			frame->object.privateFlags &= ~Frame::SUBTREESYNCLTM; | ||||||
|  | 		} | ||||||
|  | 		syncRecurse(frame->child, flg); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | Frame::syncHierarchyLTM(void) | ||||||
|  | { | ||||||
|  | 	Frame *child; | ||||||
|  | 	uint8 flg; | ||||||
|  | 	if(this->object.privateFlags & Frame::SUBTREESYNCLTM) | ||||||
|  | 		this->ltm = this->matrix; | ||||||
|  | 	for(child = this->child; child; child = child->next){ | ||||||
|  | 		flg = this->object.privateFlags | child->object.privateFlags; | ||||||
|  | 		if(flg & Frame::SUBTREESYNCLTM){ | ||||||
|  | 			Matrix::mult(&child->ltm, &this->ltm, &child->matrix); | ||||||
|  | 			child->object.privateFlags &= ~Frame::SUBTREESYNCLTM; | ||||||
|  | 		} | ||||||
|  | 		syncRecurse(child, flg); | ||||||
|  | 	} | ||||||
|  | 	this->object.privateFlags &= ~Frame::SYNCLTM; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Matrix* | ||||||
|  | Frame::getLTM(void) | ||||||
|  | { | ||||||
|  | 	if(this->root->object.privateFlags & Frame::HIERARCHYSYNCLTM) | ||||||
|  | 		this->root->syncHierarchyLTM(); | ||||||
|  | 	return &this->ltm; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | Frame::updateObjects(void) | ||||||
|  | { | ||||||
|  | 	if((this->root->object.privateFlags & HIERARCHYSYNC) == 0) | ||||||
|  | 		Frame::dirtyList.add(&this->inDirtyList); | ||||||
|  | 	this->root->object.privateFlags |= HIERARCHYSYNC; | ||||||
|  | 	this->object.privateFlags |= SUBTREESYNC; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | Frame::setHierarchyRoot(Frame *root) | ||||||
|  | { | ||||||
|  | 	this->root = root; | ||||||
|  | 	for(Frame *child = this->child; child; child = child->next) | ||||||
|  | 		child->setHierarchyRoot(root); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Clone a frame hierarchy. Link cloned frames into Frame::root of the originals.
 | ||||||
|  | Frame* | ||||||
|  | Frame::cloneAndLink(Frame *clonedroot) | ||||||
|  | { | ||||||
|  | 	Frame *frame = Frame::create(); | ||||||
|  | 	if(clonedroot == NULL) | ||||||
|  | 		clonedroot = frame; | ||||||
|  | 	frame->object.copy(&this->object); | ||||||
|  | 	frame->matrix = this->matrix; | ||||||
|  | 	//memcpy(frame->matrix, this->matrix, sizeof(this->matrix));
 | ||||||
|  | 	frame->root = clonedroot; | ||||||
|  | 	this->root = frame;	// Remember cloned frame
 | ||||||
|  | 	for(Frame *child = this->child; child; child = child->next){ | ||||||
|  | 		Frame *clonedchild = child->cloneAndLink(clonedroot); | ||||||
|  | 		clonedchild->next = frame->child; | ||||||
|  | 		frame->child = clonedchild; | ||||||
|  | 		clonedchild->object.parent = frame; | ||||||
|  | 	} | ||||||
|  | 	frame->copyPlugins(this); | ||||||
|  | 	return frame; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Remove links to cloned frames from hierarchy.
 | ||||||
|  | void | ||||||
|  | Frame::purgeClone(void) | ||||||
|  | { | ||||||
|  | 	Frame *parent = this->getParent(); | ||||||
|  | 	this->setHierarchyRoot(parent ? parent->root : this); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Frame** | ||||||
|  | makeFrameList(Frame *frame, Frame **flist) | ||||||
|  | { | ||||||
|  | 	*flist++ = frame; | ||||||
|  | 	if(frame->next) | ||||||
|  | 		flist = makeFrameList(frame->next, flist); | ||||||
|  | 	if(frame->child) | ||||||
|  | 		flist = makeFrameList(frame->child, flist); | ||||||
|  | 	return flist; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -5,10 +5,13 @@ | |||||||
| #include <cmath> | #include <cmath> | ||||||
| 
 | 
 | ||||||
| #include "rwbase.h" | #include "rwbase.h" | ||||||
|  | #include "rwerror.h" | ||||||
| #include "rwplg.h" | #include "rwplg.h" | ||||||
| #include "rwpipeline.h" | #include "rwpipeline.h" | ||||||
| #include "rwobjects.h" | #include "rwobjects.h" | ||||||
| 
 | 
 | ||||||
|  | #define PLUGIN_ID 2 | ||||||
|  | 
 | ||||||
| using namespace std; | using namespace std; | ||||||
| 
 | 
 | ||||||
| namespace rw { | namespace rw { | ||||||
| @ -17,7 +20,10 @@ Geometry* | |||||||
| Geometry::create(int32 numVerts, int32 numTris, uint32 flags) | Geometry::create(int32 numVerts, int32 numTris, uint32 flags) | ||||||
| { | { | ||||||
| 	Geometry *geo = (Geometry*)malloc(PluginBase::s_size); | 	Geometry *geo = (Geometry*)malloc(PluginBase::s_size); | ||||||
| 	assert(geo != NULL); | 	if(geo == nil){ | ||||||
|  | 		RWERROR((ERR_ALLOC, PluginBase::s_size)); | ||||||
|  | 		return nil; | ||||||
|  | 	} | ||||||
| 	geo->object.init(Geometry::ID, 0); | 	geo->object.init(Geometry::ID, 0); | ||||||
| 	geo->geoflags = flags & 0xFF00FFFF; | 	geo->geoflags = flags & 0xFF00FFFF; | ||||||
| 	geo->numTexCoordSets = (flags & 0xFF0000) >> 16; | 	geo->numTexCoordSets = (flags & 0xFF0000) >> 16; | ||||||
| @ -28,10 +34,10 @@ Geometry::create(int32 numVerts, int32 numTris, uint32 flags) | |||||||
| 	geo->numVertices = numVerts; | 	geo->numVertices = numVerts; | ||||||
| 	geo->numMorphTargets = 1; | 	geo->numMorphTargets = 1; | ||||||
| 
 | 
 | ||||||
| 	geo->colors = NULL; | 	geo->colors = nil; | ||||||
| 	for(int32 i = 0; i < geo->numTexCoordSets; i++) | 	for(int32 i = 0; i < geo->numTexCoordSets; i++) | ||||||
| 		geo->texCoords[i] = NULL; | 		geo->texCoords[i] = nil; | ||||||
| 	geo->triangles = NULL; | 	geo->triangles = nil; | ||||||
| 	if(!(geo->geoflags & NATIVE) && geo->numVertices){ | 	if(!(geo->geoflags & NATIVE) && geo->numVertices){ | ||||||
| 		if(geo->geoflags & PRELIT) | 		if(geo->geoflags & PRELIT) | ||||||
| 			geo->colors = new uint8[4*geo->numVertices]; | 			geo->colors = new uint8[4*geo->numVertices]; | ||||||
| @ -45,24 +51,23 @@ Geometry::create(int32 numVerts, int32 numTris, uint32 flags) | |||||||
| 	MorphTarget *m = geo->morphTargets; | 	MorphTarget *m = geo->morphTargets; | ||||||
| 	m->boundingSphere.center.set(0.0f, 0.0f, 0.0f); | 	m->boundingSphere.center.set(0.0f, 0.0f, 0.0f); | ||||||
| 	m->boundingSphere.radius = 0.0f; | 	m->boundingSphere.radius = 0.0f; | ||||||
| 	m->vertices = NULL; | 	m->vertices = nil; | ||||||
| 	m->normals = NULL; | 	m->normals = nil; | ||||||
| 	if(!(geo->geoflags & NATIVE) && geo->numVertices){ | 	if(!(geo->geoflags & NATIVE) && geo->numVertices){ | ||||||
| 		m->vertices = new float32[3*geo->numVertices]; | 		m->vertices = new float32[3*geo->numVertices]; | ||||||
| 		if(geo->geoflags & NORMALS) | 		if(geo->geoflags & NORMALS) | ||||||
| 			m->normals = new float32[3*geo->numVertices]; | 			m->normals = new float32[3*geo->numVertices]; | ||||||
| 	} | 	} | ||||||
| 	geo->numMaterials = 0; | 	geo->numMaterials = 0; | ||||||
| 	geo->materialList = NULL; | 	geo->materialList = nil; | ||||||
| 	geo->meshHeader = NULL; | 	geo->meshHeader = nil; | ||||||
| 	geo->instData = NULL; | 	geo->instData = nil; | ||||||
| 	geo->refCount = 1; | 	geo->refCount = 1; | ||||||
| 
 | 
 | ||||||
| 	geo->constructPlugins(); | 	geo->constructPlugins(); | ||||||
| 	return geo; | 	return geo; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| void | void | ||||||
| Geometry::destroy(void) | Geometry::destroy(void) | ||||||
| { | { | ||||||
| @ -101,10 +106,15 @@ Geometry::streamRead(Stream *stream) | |||||||
| { | { | ||||||
| 	uint32 version; | 	uint32 version; | ||||||
| 	GeoStreamData buf; | 	GeoStreamData buf; | ||||||
| 	assert(findChunk(stream, ID_STRUCT, NULL, &version)); | 	if(!findChunk(stream, ID_STRUCT, nil, &version)){ | ||||||
|  | 		RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 		return nil; | ||||||
|  | 	} | ||||||
| 	stream->read(&buf, sizeof(buf)); | 	stream->read(&buf, sizeof(buf)); | ||||||
| 	Geometry *geo = Geometry::create(buf.numVertices, | 	Geometry *geo = Geometry::create(buf.numVertices, | ||||||
| 	                                 buf.numTriangles, buf.flags); | 	                                 buf.numTriangles, buf.flags); | ||||||
|  | 	if(geo == nil) | ||||||
|  | 		return nil; | ||||||
| 	geo->addMorphTargets(buf.numMorphTargets-1); | 	geo->addMorphTargets(buf.numMorphTargets-1); | ||||||
| 	// skip surface properties
 | 	// skip surface properties
 | ||||||
| 	if(version < 0x34000) | 	if(version < 0x34000) | ||||||
| @ -137,13 +147,25 @@ Geometry::streamRead(Stream *stream) | |||||||
| 			stream->read(m->normals, 3*geo->numVertices*4); | 			stream->read(m->normals, 3*geo->numVertices*4); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	assert(findChunk(stream, ID_MATLIST, NULL, NULL)); | 	if(!findChunk(stream, ID_MATLIST, nil, nil)){ | ||||||
| 	assert(findChunk(stream, ID_STRUCT, NULL, NULL)); | 		RWERROR((ERR_CHUNK, "MATLIST")); | ||||||
|  | 		// TODO: free
 | ||||||
|  | 		return nil; | ||||||
|  | 	} | ||||||
|  | 	if(!findChunk(stream, ID_STRUCT, nil, nil)){ | ||||||
|  | 		RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 		// TODO: free
 | ||||||
|  | 		return nil; | ||||||
|  | 	} | ||||||
| 	geo->numMaterials = stream->readI32(); | 	geo->numMaterials = stream->readI32(); | ||||||
| 	geo->materialList = new Material*[geo->numMaterials]; | 	geo->materialList = new Material*[geo->numMaterials]; | ||||||
| 	stream->seek(geo->numMaterials*4);	// unused (-1)
 | 	stream->seek(geo->numMaterials*4);	// unused (-1)
 | ||||||
| 	for(int32 i = 0; i < geo->numMaterials; i++){ | 	for(int32 i = 0; i < geo->numMaterials; i++){ | ||||||
| 		assert(findChunk(stream, ID_MATERIAL, NULL, NULL)); | 		if(!findChunk(stream, ID_MATERIAL, nil, nil)){ | ||||||
|  | 			RWERROR((ERR_CHUNK, "MATERIAL")); | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 		geo->materialList[i] = Material::streamRead(stream); | 		geo->materialList[i] = Material::streamRead(stream); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -217,8 +239,8 @@ Geometry::streamWrite(Stream *stream) | |||||||
| 		MorphTarget *m = &this->morphTargets[i]; | 		MorphTarget *m = &this->morphTargets[i]; | ||||||
| 		stream->write(&m->boundingSphere, 4*4); | 		stream->write(&m->boundingSphere, 4*4); | ||||||
| 		if(!(this->geoflags & NATIVE)){ | 		if(!(this->geoflags & NATIVE)){ | ||||||
| 			stream->writeI32(m->vertices != NULL); | 			stream->writeI32(m->vertices != nil); | ||||||
| 			stream->writeI32(m->normals != NULL); | 			stream->writeI32(m->normals != nil); | ||||||
| 			if(m->vertices) | 			if(m->vertices) | ||||||
| 				stream->write(m->vertices, | 				stream->write(m->vertices, | ||||||
| 				             3*this->numVertices*4); | 				             3*this->numVertices*4); | ||||||
| @ -270,8 +292,8 @@ Geometry::addMorphTargets(int32 n) | |||||||
| 	this->morphTargets = morphTargets; | 	this->morphTargets = morphTargets; | ||||||
| 	for(int32 i = this->numMorphTargets; i < n; i++){ | 	for(int32 i = this->numMorphTargets; i < n; i++){ | ||||||
| 		MorphTarget *m = &morphTargets[i]; | 		MorphTarget *m = &morphTargets[i]; | ||||||
| 		m->vertices = NULL; | 		m->vertices = nil; | ||||||
| 		m->normals = NULL; | 		m->normals = nil; | ||||||
| 		if(!(this->geoflags & NATIVE)){ | 		if(!(this->geoflags & NATIVE)){ | ||||||
| 			m->vertices = new float32[3*this->numVertices]; | 			m->vertices = new float32[3*this->numVertices]; | ||||||
| 			if(this->geoflags & NORMALS) | 			if(this->geoflags & NORMALS) | ||||||
| @ -344,7 +366,7 @@ void | |||||||
| Geometry::generateTriangles(int8 *adc) | Geometry::generateTriangles(int8 *adc) | ||||||
| { | { | ||||||
| 	MeshHeader *header = this->meshHeader; | 	MeshHeader *header = this->meshHeader; | ||||||
| 	assert(header != NULL); | 	assert(header != nil); | ||||||
| 
 | 
 | ||||||
| 	this->numTriangles = 0; | 	this->numTriangles = 0; | ||||||
| 	Mesh *m = header->mesh; | 	Mesh *m = header->mesh; | ||||||
| @ -452,7 +474,7 @@ Geometry::buildMeshes(void) | |||||||
| void | void | ||||||
| Geometry::removeUnusedMaterials(void) | Geometry::removeUnusedMaterials(void) | ||||||
| { | { | ||||||
| 	if(this->meshHeader == NULL) | 	if(this->meshHeader == nil) | ||||||
| 		return; | 		return; | ||||||
| 	MeshHeader *mh = this->meshHeader; | 	MeshHeader *mh = this->meshHeader; | ||||||
| 	int32 *map = new int32[this->numMaterials]; | 	int32 *map = new int32[this->numMaterials]; | ||||||
| @ -515,13 +537,16 @@ Material* | |||||||
| Material::create(void) | Material::create(void) | ||||||
| { | { | ||||||
| 	Material *mat = (Material*)malloc(PluginBase::s_size); | 	Material *mat = (Material*)malloc(PluginBase::s_size); | ||||||
| 	assert(mat != NULL); | 	if(mat == nil){ | ||||||
| 	mat->texture = NULL; | 		RWERROR((ERR_ALLOC, PluginBase::s_size)); | ||||||
|  | 		return nil; | ||||||
|  | 	} | ||||||
|  | 	mat->texture = nil; | ||||||
| 	memset(&mat->color, 0xFF, 4); | 	memset(&mat->color, 0xFF, 4); | ||||||
| 	mat->surfaceProps.ambient = 1.0f; | 	mat->surfaceProps.ambient = 1.0f; | ||||||
| 	mat->surfaceProps.specular = 1.0f; | 	mat->surfaceProps.specular = 1.0f; | ||||||
| 	mat->surfaceProps.diffuse = 1.0f; | 	mat->surfaceProps.diffuse = 1.0f; | ||||||
| 	mat->pipeline = NULL; | 	mat->pipeline = nil; | ||||||
| 	mat->refCount = 1; | 	mat->refCount = 1; | ||||||
| 	mat->constructPlugins(); | 	mat->constructPlugins(); | ||||||
| 	return mat; | 	return mat; | ||||||
| @ -531,6 +556,10 @@ Material* | |||||||
| Material::clone(void) | Material::clone(void) | ||||||
| { | { | ||||||
| 	Material *mat = Material::create(); | 	Material *mat = Material::create(); | ||||||
|  | 	if(mat == nil){ | ||||||
|  | 		RWERROR((ERR_ALLOC, PluginBase::s_size)); | ||||||
|  | 		return nil; | ||||||
|  | 	} | ||||||
| 	mat->color = this->color; | 	mat->color = this->color; | ||||||
| 	mat->surfaceProps = this->surfaceProps; | 	mat->surfaceProps = this->surfaceProps; | ||||||
| 	if(this->texture){ | 	if(this->texture){ | ||||||
| @ -570,9 +599,14 @@ Material::streamRead(Stream *stream) | |||||||
| 	uint32 length, version; | 	uint32 length, version; | ||||||
| 	MatStreamData buf; | 	MatStreamData buf; | ||||||
| 
 | 
 | ||||||
| 	assert(findChunk(stream, ID_STRUCT, NULL, &version)); | 	if(!findChunk(stream, ID_STRUCT, nil, &version)){ | ||||||
|  | 		RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 		return nil; | ||||||
|  | 	} | ||||||
| 	stream->read(&buf, sizeof(buf)); | 	stream->read(&buf, sizeof(buf)); | ||||||
| 	Material *mat = Material::create(); | 	Material *mat = Material::create(); | ||||||
|  | 	if(mat == nil) | ||||||
|  | 		return nil; | ||||||
| 	mat->color = buf.color; | 	mat->color = buf.color; | ||||||
| 	if(version < 0x30400){ | 	if(version < 0x30400){ | ||||||
| 		mat->surfaceProps.ambient = 1.0f; | 		mat->surfaceProps.ambient = 1.0f; | ||||||
| @ -586,8 +620,16 @@ Material::streamRead(Stream *stream) | |||||||
| 		mat->surfaceProps.diffuse = surfaceProps[2]; | 		mat->surfaceProps.diffuse = surfaceProps[2]; | ||||||
| 	} | 	} | ||||||
| 	if(buf.textured){ | 	if(buf.textured){ | ||||||
| 		assert(findChunk(stream, ID_TEXTURE, &length, NULL)); | 		if(!findChunk(stream, ID_TEXTURE, &length, nil)){ | ||||||
|  | 			RWERROR((ERR_CHUNK, "TEXTURE")); | ||||||
|  | 			// TODO: free
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 		mat->texture = Texture::streamRead(stream); | 		mat->texture = Texture::streamRead(stream); | ||||||
|  | 		if(mat->texture == nil){ | ||||||
|  | 			// TODO: fre
 | ||||||
|  | 			return nil; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	materialRights[0] = 0; | 	materialRights[0] = 0; | ||||||
| @ -609,7 +651,7 @@ Material::streamWrite(Stream *stream) | |||||||
| 	buf.color = this->color; | 	buf.color = this->color; | ||||||
| 	buf.flags = 0; | 	buf.flags = 0; | ||||||
| 	buf.unused = 0; | 	buf.unused = 0; | ||||||
| 	buf.textured = this->texture != NULL; | 	buf.textured = this->texture != nil; | ||||||
| 	stream->write(&buf, sizeof(buf)); | 	stream->write(&buf, sizeof(buf)); | ||||||
| 
 | 
 | ||||||
| 	if(rw::version >= 0x30400){ | 	if(rw::version >= 0x30400){ | ||||||
| @ -663,7 +705,7 @@ static int32 | |||||||
| getSizeMaterialRights(void *object, int32, int32) | getSizeMaterialRights(void *object, int32, int32) | ||||||
| { | { | ||||||
| 	Material *material = (Material*)object; | 	Material *material = (Material*)object; | ||||||
| 	if(material->pipeline == NULL || material->pipeline->pluginID == 0) | 	if(material->pipeline == nil || material->pipeline->pluginID == 0) | ||||||
| 		return -1; | 		return -1; | ||||||
| 	return 8; | 	return 8; | ||||||
| } | } | ||||||
| @ -671,7 +713,7 @@ getSizeMaterialRights(void *object, int32, int32) | |||||||
| void | void | ||||||
| registerMaterialRightsPlugin(void) | registerMaterialRightsPlugin(void) | ||||||
| { | { | ||||||
| 	Material::registerPlugin(0, ID_RIGHTTORENDER, NULL, NULL, NULL); | 	Material::registerPlugin(0, ID_RIGHTTORENDER, nil, nil, nil); | ||||||
| 	Material::registerPluginStream(ID_RIGHTTORENDER, | 	Material::registerPluginStream(ID_RIGHTTORENDER, | ||||||
| 	                               readMaterialRights, | 	                               readMaterialRights, | ||||||
| 	                               writeMaterialRights, | 	                               writeMaterialRights, | ||||||
|  | |||||||
							
								
								
									
										131
									
								
								src/light.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								src/light.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | |||||||
|  | #include <cstdio> | ||||||
|  | #include <cstdlib> | ||||||
|  | 
 | ||||||
|  | #include "rwbase.h" | ||||||
|  | #include "rwerror.h" | ||||||
|  | #include "rwplg.h" | ||||||
|  | #include "rwpipeline.h" | ||||||
|  | #include "rwobjects.h" | ||||||
|  | 
 | ||||||
|  | #define PLUGIN_ID 2 | ||||||
|  | 
 | ||||||
|  | namespace rw { | ||||||
|  | 
 | ||||||
|  | Light* | ||||||
|  | Light::create(int32 type) | ||||||
|  | { | ||||||
|  | 	Light *light = (Light*)malloc(PluginBase::s_size); | ||||||
|  | 	if(light == NULL){ | ||||||
|  | 		RWERROR((ERR_ALLOC, PluginBase::s_size)); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	light->object.object.init(Light::ID, type); | ||||||
|  | 	light->radius = 0.0f; | ||||||
|  | 	light->color.red = 1.0f; | ||||||
|  | 	light->color.green = 1.0f; | ||||||
|  | 	light->color.blue = 1.0f; | ||||||
|  | 	light->color.alpha = 1.0f; | ||||||
|  | 	light->minusCosAngle = 1.0f; | ||||||
|  | 	light->object.object.privateFlags = 1; | ||||||
|  | 	light->object.object.flags = LIGHTATOMICS | LIGHTWORLD; | ||||||
|  | 	light->clump = NULL; | ||||||
|  | 	light->inClump.init(); | ||||||
|  | 	light->constructPlugins(); | ||||||
|  | 	return light; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | Light::destroy(void) | ||||||
|  | { | ||||||
|  | 	this->destructPlugins(); | ||||||
|  | 	if(this->clump) | ||||||
|  | 		this->inClump.remove(); | ||||||
|  | 	free(this); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | Light::setAngle(float32 angle) | ||||||
|  | { | ||||||
|  | 	this->minusCosAngle = -cos(angle); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | float32 | ||||||
|  | Light::getAngle(void) | ||||||
|  | { | ||||||
|  | 	return acos(-this->minusCosAngle); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | Light::setColor(float32 r, float32 g, float32 b) | ||||||
|  | { | ||||||
|  | 	this->color.red = r; | ||||||
|  | 	this->color.green = g; | ||||||
|  | 	this->color.blue = b; | ||||||
|  | 	this->object.object.privateFlags = r == g && r == b; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct LightChunkData | ||||||
|  | { | ||||||
|  | 	float32 radius; | ||||||
|  | 	float32 red, green, blue; | ||||||
|  | 	float32 minusCosAngle; | ||||||
|  | 	uint16 flags; | ||||||
|  | 	uint16 type; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | Light* | ||||||
|  | Light::streamRead(Stream *stream) | ||||||
|  | { | ||||||
|  | 	uint32 version; | ||||||
|  | 	LightChunkData buf; | ||||||
|  | 
 | ||||||
|  | 	if(!findChunk(stream, ID_STRUCT, NULL, &version)){ | ||||||
|  | 		RWERROR((ERR_CHUNK, "STRUCT")); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	stream->read(&buf, sizeof(LightChunkData)); | ||||||
|  | 	Light *light = Light::create(buf.type); | ||||||
|  | 	if(light == NULL) | ||||||
|  | 		return NULL; | ||||||
|  | 	light->radius = buf.radius; | ||||||
|  | 	light->setColor(buf.red, buf.green, buf.blue); | ||||||
|  | 	float32 a = buf.minusCosAngle; | ||||||
|  | 	if(version >= 0x30300) | ||||||
|  | 		light->minusCosAngle = a; | ||||||
|  | 	else | ||||||
|  | 		// tan -> -cos
 | ||||||
|  | 		light->minusCosAngle = -1.0f/sqrt(a*a+1.0f); | ||||||
|  | 	light->object.object.flags = (uint8)buf.flags; | ||||||
|  | 	light->streamReadPlugins(stream); | ||||||
|  | 	return light; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool | ||||||
|  | Light::streamWrite(Stream *stream) | ||||||
|  | { | ||||||
|  | 	LightChunkData buf; | ||||||
|  | 	writeChunkHeader(stream, ID_LIGHT, this->streamGetSize()); | ||||||
|  | 	writeChunkHeader(stream, ID_STRUCT, sizeof(LightChunkData)); | ||||||
|  | 	buf.radius = this->radius; | ||||||
|  | 	buf.red   = this->color.red; | ||||||
|  | 	buf.green = this->color.green; | ||||||
|  | 	buf.blue  = this->color.blue; | ||||||
|  | 	if(version >= 0x30300) | ||||||
|  | 		buf.minusCosAngle = this->minusCosAngle; | ||||||
|  | 	else | ||||||
|  | 		buf.minusCosAngle = tan(acos(-this->minusCosAngle)); | ||||||
|  | 	buf.flags = this->object.object.flags; | ||||||
|  | 	buf.type = this->object.object.subType; | ||||||
|  | 	stream->write(&buf, sizeof(LightChunkData)); | ||||||
|  | 
 | ||||||
|  | 	this->streamWritePlugins(stream); | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint32 | ||||||
|  | Light::streamGetSize(void) | ||||||
|  | { | ||||||
|  | 	return 12 + sizeof(LightChunkData) + 12 + this->streamGetPluginSize(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -6,6 +6,7 @@ | |||||||
| #include <cctype> | #include <cctype> | ||||||
| 
 | 
 | ||||||
| #include "rwbase.h" | #include "rwbase.h" | ||||||
|  | #include "rwerror.h" | ||||||
| #include "rwplg.h" | #include "rwplg.h" | ||||||
| #include "rwpipeline.h" | #include "rwpipeline.h" | ||||||
| #include "rwobjects.h" | #include "rwobjects.h" | ||||||
| @ -21,6 +22,8 @@ using namespace std; | |||||||
| 
 | 
 | ||||||
| namespace rw { | namespace rw { | ||||||
| 
 | 
 | ||||||
|  | #define PLUGIN_ID 0 | ||||||
|  | 
 | ||||||
| int32 version = 0x36003; | int32 version = 0x36003; | ||||||
| int32 build = 0xFFFF; | int32 build = 0xFFFF; | ||||||
| #ifdef RW_PS2 | #ifdef RW_PS2 | ||||||
| @ -665,7 +668,11 @@ StreamFile* | |||||||
| StreamFile::open(const char *path, const char *mode) | StreamFile::open(const char *path, const char *mode) | ||||||
| { | { | ||||||
| 	this->file = fopen(path, mode); | 	this->file = fopen(path, mode); | ||||||
| 	return this->file ? this : NULL; | 	if(this->file == NULL){ | ||||||
|  | 		RWERROR((ERR_FILE, path)); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	return this; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| @ -758,10 +765,8 @@ findPointer(void *p, void **list, int32 num) | |||||||
| 	int i; | 	int i; | ||||||
| 	for(i = 0; i < num; i++) | 	for(i = 0; i < num; i++) | ||||||
| 		if(list[i] == p) | 		if(list[i] == p) | ||||||
| 			goto found; |  | ||||||
| 	return -1; |  | ||||||
| found: |  | ||||||
| 			return i; | 			return i; | ||||||
|  | 	return -1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint8* | uint8* | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								src/rwbase.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/rwbase.h
									
									
									
									
									
								
							| @ -33,6 +33,8 @@ typedef int32 bool32; | |||||||
| typedef uint8 byte; | typedef uint8 byte; | ||||||
| typedef uint32 uint; | typedef uint32 uint; | ||||||
| 
 | 
 | ||||||
|  | #define nil NULL | ||||||
|  | 
 | ||||||
| #define nelem(A) (sizeof(A) / sizeof A[0]) | #define nelem(A) (sizeof(A) / sizeof A[0]) | ||||||
| 
 | 
 | ||||||
| struct RGBA | struct RGBA | ||||||
| @ -284,6 +286,16 @@ enum PluginID | |||||||
| 	ID_VERTEXFMT     = 0x511, | 	ID_VERTEXFMT     = 0x511, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | #define ECODE(c, s) c, | ||||||
|  | 
 | ||||||
|  | enum Errors | ||||||
|  | { | ||||||
|  | 	ERR_NONE = 0x80000000, | ||||||
|  | #include "base.err" | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #undef ECODE | ||||||
|  | 
 | ||||||
| extern int version; | extern int version; | ||||||
| extern int build; | extern int build; | ||||||
| extern int platform; | extern int platform; | ||||||
|  | |||||||
							
								
								
									
										25
									
								
								src/rwerror.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/rwerror.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | namespace rw { | ||||||
|  | 
 | ||||||
|  | struct Error | ||||||
|  | { | ||||||
|  | 	uint32 plugin; | ||||||
|  | 	uint32 code; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void setError(Error *e); | ||||||
|  | Error *getError(Error *e); | ||||||
|  | 
 | ||||||
|  | #define _ERRORCODE(code, ...) code | ||||||
|  | char *dbgsprint(int32 code, ...); | ||||||
|  | 
 | ||||||
|  | /* ecode is supposed to be in format "(errorcode, printf-arguments..)" */ | ||||||
|  | #define RWERROR(ecode) do{          \ | ||||||
|  | 	rw::Error _e;                   \ | ||||||
|  | 	_e.plugin = PLUGIN_ID;      \ | ||||||
|  | 	_e.code = _ERRORCODE ecode; \ | ||||||
|  | 	fprintf(stderr, "%s:%d: ", __FILE__, __LINE__); \ | ||||||
|  | 	fprintf(stderr, "%s\n", rw::dbgsprint ecode);       \ | ||||||
|  | 	rw::setError(&_e);              \ | ||||||
|  | }while(0); | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -544,7 +544,7 @@ struct Clump : PluginBase<Clump> | |||||||
| 	uint32 streamGetSize(void); | 	uint32 streamGetSize(void); | ||||||
| 	void render(void); | 	void render(void); | ||||||
| 
 | 
 | ||||||
| 	void frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf); | 	bool frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf); | ||||||
| 	void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf); | 	void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -205,13 +205,13 @@ PluginBase<T>::getPluginOffset(uint32 id) | |||||||
| template <typename T> void* | template <typename T> void* | ||||||
| PluginBase<T>::operator new(size_t) | PluginBase<T>::operator new(size_t) | ||||||
| { | { | ||||||
| 	assert(0); | 	abort(); | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <typename T> void | template <typename T> void | ||||||
| PluginBase<T>::operator delete(void *p) | PluginBase<T>::operator delete(void *p) | ||||||
| { | { | ||||||
| 	assert(0); | 	abort(); | ||||||
| } | } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user