예제 #1
0
파일: 3DOParser.cpp 프로젝트: nixtux/spring
static void READ_VERTEX(float3& v, const std::vector<unsigned char>& fileBuf, int& curOffset)
{
	unsigned int __tmp;
	unsigned short __isize = sizeof(unsigned int);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	v.x = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	v.y = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	v.z = (int)swabDWord(__tmp);
}
예제 #2
0
void C3DOParser::GetPrimitives(S3DOPiece* obj, int pos, int num, int excludePrim, const std::vector<unsigned char>& fileBuf)
{
	std::map<int,int> prevHashes;

	for (int a=0; a<num; a++) {
		if (a == excludePrim) {
			continue;
		}

		_Primitive p;
		int curOffset = pos + a * sizeof(_Primitive);
		READ_PRIMITIVE(p, fileBuf, curOffset);

		if (p.NumberOfVertexIndexes < 3)
			continue;

		S3DOPrimitive sp;
		sp.indices.resize(p.NumberOfVertexIndexes);
		sp.vnormals.resize(p.NumberOfVertexIndexes);

		// load vertex indices list
		curOffset = p.OffsetToVertexIndexArray;
		for (int b=0; b<p.NumberOfVertexIndexes; b++) {
			boost::uint16_t w;
			STREAM_READ(&w,2, fileBuf, curOffset);
			swabWordInPlace(w);
			sp.indices[b] = w;
		}

		// find texture
		sp.texture = GetTexture(obj, &p, fileBuf);

		// set the primitive-normal
		const float3 v0v1 = (obj->vertexPos[sp.indices[1]] - obj->vertexPos[sp.indices[0]]);
		const float3 v0v2 = (obj->vertexPos[sp.indices[2]] - obj->vertexPos[sp.indices[0]]);
		sp.primNormal = (-v0v1.cross(v0v2)).SafeANormalize();

		// some 3dos got multiple baseplates a.k.a. `selection primitive`
		// it's not meant to be rendered, so hide it
		if (IsBasePlate(obj, &sp))
			continue;

		// 3do has often duplicated faces (with equal geometry)
		// with different textures (e.g. for animations and other effects)
		// we don't support those, only render the last one
		std::vector<int> orderVert = sp.indices;
		std::sort(orderVert.begin(), orderVert.end());
		const int vertHash = HsiehHash(&orderVert[0], orderVert.size() * sizeof(orderVert[0]), 0x123456);

		auto phi = prevHashes.find(vertHash);
		if (phi != prevHashes.end()) {
			obj->prims[phi->second] = sp;
			continue;
		}
		prevHashes[vertHash] = obj->prims.size();
		obj->prims.push_back(sp);
	}
}
예제 #3
0
파일: 3DOParser.cpp 프로젝트: nixtux/spring
static std::string GET_TEXT(int pos, const std::vector<unsigned char>& fileBuf, int& curOffset)
{
	curOffset = pos;
	std::string s;
	s.reserve(16);
	do {
		s.push_back(0);
		STREAM_READ(&s.back(), 1, fileBuf, curOffset);
	} while (s.back() != 0);
	s.pop_back(); // pop the \0
	return s;
}
예제 #4
0
파일: 3DOParser.cpp 프로젝트: nixtux/spring
static void READ_PRIMITIVE(C3DOParser::_Primitive& p, const std::vector<unsigned char>& fileBuf, int& curOffset)
{
	unsigned int __tmp;
	unsigned short __isize = sizeof(unsigned int);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	p.PaletteEntry = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	p.NumberOfVertexIndexes = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	p.Always_0 = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	p.OffsetToVertexIndexArray = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	p.OffsetToTextureName = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	p.Unknown_1 = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	p.Unknown_2 = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	p.Unknown_3 = (int)swabDWord(__tmp);
}
예제 #5
0
파일: 3DOParser.cpp 프로젝트: nixtux/spring
static void READ_3DOBJECT(C3DOParser::_3DObject& o, const std::vector<unsigned char>& fileBuf, int& curOffset)
{
	unsigned int __tmp;
	unsigned short __isize = sizeof(unsigned int);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.VersionSignature = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.NumberOfVertices = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.NumberOfPrimitives = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.SelectionPrimitive = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.XFromParent = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.YFromParent = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.ZFromParent = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.OffsetToObjectName = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.Always_0 = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.OffsetToVertexArray = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.OffsetToPrimitiveArray = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.OffsetToSiblingObject = (int)swabDWord(__tmp);
	STREAM_READ(&__tmp,__isize, fileBuf, curOffset);
	o.OffsetToChildObject = (int)swabDWord(__tmp);
}
예제 #6
0
/* delete a portion of an index, adjusting offset appropriately.  Returns 0 if
   things work and we should be called again, 1 if success full and done, and -1
   if an error occurred.  It adjusts offset appropriately on 0 or 1 return codes,
   and otherwise doesn't touch it */
static int
ObliterateRegion(Volume * avp, VnodeClass aclass, StreamHandle_t * afile,
		 afs_int32 * aoffset)
{
    register struct VnodeClassInfo *vcp;
    Inode inodes[MAXOBLITATONCE];
    register afs_int32 iindex, nscanned;
    afs_int32 offset;
    char buf[SIZEOF_LARGEDISKVNODE];
    int hitEOF;
    register int i;
    register afs_int32 code;
    register struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf;

    hitEOF = 0;
    vcp = &VnodeClassInfo[aclass];
    offset = *aoffset;		/* original offset */
    iindex = 0;
    nscanned = 0;
    /* advance over up to MAXOBLITATONCE inodes.  nscanned tells us how many we examined.
     * We remember the inodes in an array, and idec them after zeroing them in the index.
     * The reason for these contortions is to make volume deletion idempotent, even
     * if we crash in the middle of a delete operation. */
    STREAM_SEEK(afile, offset, 0);
    while (1) {
	if (iindex >= MAXOBLITATONCE) {
	    break;
	}
	code = STREAM_READ(vnode, vcp->diskSize, 1, afile);
	nscanned++;
	offset += vcp->diskSize;
	if (code != 1) {
	    hitEOF = 1;
	    break;
	}
	if (vnode->type != vNull) {
	    if (vnode->vnodeMagic != vcp->magic)
		goto fail;	/* something really wrong; let salvager take care of it */
	    if (VNDISK_GET_INO(vnode))
		inodes[iindex++] = VNDISK_GET_INO(vnode);
	}
    }

    /* next, obliterate the index and fflush (and fsync) it */
    STREAM_SEEK(afile, *aoffset, 0);	/* seek back to start of vnode index region */
    memset(buf, 0, sizeof(buf));	/* zero out our proto-vnode */
    for (i = 0; i < nscanned; i++) {
	if (STREAM_WRITE(buf, vcp->diskSize, 1, afile) != 1)
	    goto fail;
    }
    STREAM_FLUSH(afile);	/* ensure 0s are on the disk */
    OS_SYNC(afile->str_fd);

    /* finally, do the idec's */
    for (i = 0; i < iindex; i++) {
	IH_DEC(V_linkHandle(avp), inodes[i], V_parentId(avp));
	DOPOLL;
    }

    /* return the new offset */
    *aoffset = offset;
    return hitEOF;		/* return 1 if hit EOF (don't call again), otherwise 0 */

  fail:
    return -1;
}
예제 #7
0
Sprite* spr_Create(ILTStream *pStream)
{
	uint32 nFrames, nFrameRate, bTransparent, bTranslucent, colourKey;
	uint32 i, iAnim;
	char s[1024];
	Sprite *pSprite;
	SpriteAnim *pAnim;
	uint16 strLen;
	FileRef ref;


	pSprite = LTNULL;

	// Setup the Sprite.
	LT_MEM_TRACK_ALLOC(pSprite = (Sprite*)dalloc(sizeof(Sprite)),LT_MEM_TYPE_SPRITE);
	memset(pSprite, 0, sizeof(Sprite));
	pSprite->m_Link.m_pData = pSprite;

	// Read in the animations
	pSprite->m_nAnims = 1;  // Sprites only get one animation currently...
	
	LT_MEM_TRACK_ALLOC(pSprite->m_Anims = (SpriteAnim*)dalloc(sizeof(SpriteAnim) * pSprite->m_nAnims),LT_MEM_TYPE_SPRITE);
	memset(pSprite->m_Anims, 0, sizeof(SpriteAnim) * pSprite->m_nAnims);
	
	for(iAnim=0; iAnim < pSprite->m_nAnims; iAnim++)
	{
		pAnim = &pSprite->m_Anims[iAnim];

		STREAM_READ(nFrames);
		STREAM_READ(nFrameRate);
		STREAM_READ(bTransparent);
		STREAM_READ(bTranslucent);
		STREAM_READ(colourKey);

		// Allocate array for resource ID's
		LT_MEM_TRACK_ALLOC(pAnim->m_Frames = (SpriteEntry*)dalloc(sizeof(SpriteEntry) * nFrames),LT_MEM_TYPE_SPRITE);

		// Record the name of the animation
		LTStrCpy(pAnim->m_sName, "Untitled", sizeof(pAnim->m_sName));
		
		// Set the number of frames in this animation to zero
		pAnim->m_nFrames = nFrames;
		pAnim->m_MsFrameRate = nFrameRate;
		pAnim->m_MsAnimLength = (1000 / nFrameRate) * nFrames;

		pAnim->m_bKeyed = (uint8)bTransparent;
		pAnim->m_bTranslucent = (uint8)bTranslucent;
		pAnim->m_ColourKey = colourKey;


		// Read in the frames for the animation.
		for(i=0; i < nFrames; i++)
		{
			// Read in frame file name
			STREAM_READ(strLen);
			if(strLen > 1000)
			{
				spr_Destroy(pSprite);
				return LTNULL;
			}

			pStream->Read(s, strLen);
			s[strLen] = 0;

			ref.m_FileType = FILE_CLIENTFILE;
			ref.m_pFilename = s;
			pAnim->m_Frames[i].m_pTex = g_pClientMgr->AddSharedTexture(&ref);
		}
	}

	if(pStream->ErrorStatus() != LT_OK)
	{
		spr_Destroy(pSprite);
		return LTNULL;
	}
	else
	{
		return pSprite;
	}
}