⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hotreadr.cpp

📁 空战游戏flacon源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//-----------------------------------------------------------------------------

#include "hotreadr.h"
#include "..\..\3Dlib\util.h"
#include "..\..\3Dlib\inline.h"
#include "..\..\3Dlib\object.h"
#include "..\..\3Dlib\math.h"

//-----------------------------------------------------------------------------

#define	MAX_DEGREE_OF_FREEDOM	100
#define	MAX_SWITCH				100
#define	MAX_SLOT				100

GLbeadSlot *GlobalSlotTable[MAX_SLOT];
GLbeadDegreeOfFreedom *GlobalDOFTable[MAX_DEGREE_OF_FREEDOM];
GLint	GlobalSwitchTable[MAX_SWITCH];

GLint	GlobalErrorFlag;
char	inString[256], beadName[256];

//-----------------------------------------------------------------------------

GLuint CHOTReader::CacheColor (GLuint color)
{
	GLint i;
	if (ColorCacheWrap) {
		for (i=0;i < MAX_COLOR_CACHE; i++) {
			if (color == ColorCache[i]) return ColorIndexCache[i];
		}
	}
	for (i=0;i < ColorCacheIndex; i++) {
		if (color == ColorCache[i]) return ColorIndexCache[i];
	}
	ColorCache[ColorCacheIndex] = color;
	i = SearchColor (color);
	if (i < 0) return 0;

	ColorIndexCache[ColorCacheIndex] = i;
	ColorCacheIndex++;
	if (ColorCacheIndex >= MAX_COLOR_CACHE) {
		ColorCacheWrap = 1;
		ColorCacheIndex = 0;
	}
	return i;
}

GLfloat CHOTReader::CalculateRadius (GLvertex *max, GLvertex *min)
{
	GLvertex	coord;
	GLfloat		dist, radius;

// minx, miny, minz
	coord.x = min -> x;
	coord.y = min -> y;
	coord.z = min -> z;
	radius = glVectorLength (&coord);
// minx, miny, maxz
	coord.x = min -> x;
	coord.y = min -> y;
	coord.z = max -> z;
	dist = glVectorLength (&coord);
	if (radius < dist) radius = dist;
// minx, maxy, minz
	coord.x = min -> x;
	coord.y = max -> y;
	coord.z = min -> z;
	dist = glVectorLength (&coord);
	if (radius < dist) radius = dist;
// minx, maxy, maxz
	coord.x = min -> x;
	coord.y = max -> y;
	coord.z = max -> z;
	dist = glVectorLength (&coord);
	if (radius < dist) radius = dist;
// maxx, miny, minz
	coord.x = max -> x;
	coord.y = min -> y;
	coord.z = min -> z;
	dist = glVectorLength (&coord);
	if (radius < dist) radius = dist;
// maxx, miny, maxz
	coord.x = max -> x;
	coord.y = min -> y;
	coord.z = max -> z;
	dist = glVectorLength (&coord);
	if (radius < dist) radius = dist;
// maxx, maxy, minz
	coord.x = max -> x;
	coord.y = max -> y;
	coord.z = min -> z;
	dist = glVectorLength (&coord);
	if (radius < dist) radius = dist;
// maxx, maxy, maxz
	coord.x = max -> x;
	coord.y = max -> y;
	coord.z = max -> z;
	dist = glVectorLength (&coord);
	if (radius < dist) radius = dist;

	return radius;
}

inline GLint CHOTReader::GetStringType (GLbyte *str)
{
	union {
		char	c[4];
		GLint	l;
	} type;
	char c;
	type.l = (GLint) *((GLint *) str);
	c = type.c[0];
	type.c[0] = type.c[3];
	type.c[3] = c;
	c = type.c[1];
	type.c[1] = type.c[2];
	type.c[2] = c;
	return type.l;
}

GLint CHOTReader::SearchColor (GLuint color)
{
	GLint i = SearchColorInTable (ColorTable, 0, ColorTableSize-1, color);
	if (i < 0) {
		printf ("Warning!! Can not find color 0x%x in color table\n", color);
	}
	return i;
}

GLint CHOTReader::SearchColorInTable (ColorListRecord *table, GLint colstart, GLint colend, GLuint color)
{
	if (colstart > colend) return -1;
	int	mid = (colstart+colend) >> 1;
	if (table[mid].color == color) return table[mid].colorindex;
	else if (color < table[mid].color) {
		if (mid == colstart) return -1;
		return SearchColorInTable (table, colstart, mid, color); 
	}
	return SearchColorInTable (table, mid+1, colend, color); 
}

GLObjectData *CHOTReader::readHOT (char *filename, ColorListRecord *coltable, GLint totalcol, GLint texflag)
{
	if (!in.openread ((char *) filename)) return 0;

	ColorTableSize = totalcol;
	ColorTable = coltable;

	objData = (GLObjectData *) glAllocateMemory (sizeof (GLObjectData));
	if (!objData) {
		DisplayErrorMessage ((GLbyte *) "Can not allocate object data structure!");
		in.closefile();
		return 0;
	}
	Setup ();
	if (readHeader ()) {
		glReleaseMemory ((char*) objData);
		Cleanup ();
		DisplayErrorMessage ((GLbyte *) "Problem reading header file!");
		return 0;
	}
	if (readVerticesList ()) {
		glReleaseMemory ((char*) objData);
		Cleanup ();
		DisplayErrorMessage ((GLbyte *) "Problem reading vertices list!");
		return 0;
	}
	if (readTextureList (texflag) < 0) {
		glReleaseMemory ((char*) objData);
		Cleanup ();
		DisplayErrorMessage ((GLbyte *) "Problem reading texture list!");
		return 0;
	}
	if (readBeadList ()) {
		glReleaseMemory ((char*) objData);
		Cleanup ();
		DisplayErrorMessage ((GLbyte *) "Problem reading data file!");
		return 0;
	}
	BSPproblem = 0;
	removeBSPBead (&objData -> beadRoot);
	if (BSPproblem) {
		glReleaseMemory ((char*) objData);
		Cleanup ();
		DisplayErrorMessage ((GLbyte *) "Problem with BSP bead!");
		return 0;
	}
	createDOFTree (objData -> beadRoot);
	createSwitchList ();
	createObjectSlot ();
	removeBeadWithoutChild (&objData -> beadRoot);

	if (CreateVertexList(objData, totaldynamicvertex, dynamicvertex)) {
		glReleaseMemory ((char*) objData);
		Cleanup ();
		DisplayErrorMessage ((GLbyte *) "Problem with creating vertex table!");
		return 0;
	}

	if (objData -> objectRadius == (GLfloat) 0.0) {
		objData -> objectMax = BeadVertexMax;
		objData -> objectMin = BeadVertexMin;
		objData -> objectRadius = CalculateRadius (&BeadVertexMax, &BeadVertexMin);
	}

	objData -> TotalDynamicVertex = 0;
	objData -> DynamicVertex = 0;
	if (dynamicvertex) {
		objData -> DynamicVertex = (GLdynamicVertex *) glAllocateMemory (sizeof(GLdynamicVertex)*totaldynamicvertex);
		if (objData -> DynamicVertex) {
			GLint		i, j, k;
			for (i=0;i < totaldynamicvertex;i++) {
				j = dynamicvertex[i].index;
				if (j != -1) {
					k = objData -> VertexList[j].vtxindex;
					objData -> DynamicVertex[i].vtx = objData -> VertexCoord[k].vtx;
					objData -> DynamicVertex[i].index = j * sizeof (GLvertexCoord);
				}
				else objData -> DynamicVertex[i].index = -1;
			}
			objData -> TotalDynamicVertex = totaldynamicvertex;
			objData -> objectFlag |= OBJECT_TYPE_HAS_DYNAMIC_VERTEX;
		}
		else {
			DisplayErrorMessage ((GLbyte *) "Warning!! Can not allocate memory for Dynamic Vertex");
		}
	}

	GLAnimation anim;
	anim.TotalDOF = objData -> TotalDOF;
	anim.TotalSwitch = objData -> TotalSwitch;
	anim.Switchptr = objData -> switchList;
	anim.TotalObjectSlot = objData -> TotalObjectSlot;
	anim.Flags = animFlag;
	anim.TotalDynamicVertex = objData -> TotalDynamicVertex;

	objData -> objectAnimation = CreateAnimationData (&anim);
	objData -> version = 100;	// version 1.00
	Cleanup ();
	return objData;
}

void CHOTReader::Cleanup () 
{
	CBSPUtil::Cleanup ();
	in.closefile();
	glReleaseMemory ((char*) colorpatch);
	glReleaseMemory ((char*) dynamicvertex);
}

void CHOTReader::Setup () 
{
	CBSPUtil::Setup ();

	GLint i;
	for (i=0;i < MAX_DEGREE_OF_FREEDOM;i++) {
		GlobalDOFTable[i] = 0;
	}
	for (i=0;i < MAX_SLOT;i++) {
		GlobalSlotTable[i] = 0;
	}

	colorpatch = 0;
	totalcolorpatch = 0;
	dynamicvertex = 0;
	totaldynamicvertex = 0;

	GlobalErrorFlag = 0;
	animFlag = 0;
	objectScale = (GLfloat) 1.0;
	VertexListPos = TextureListPos = BeadListPos = -1;
	BeadVertexMax.x = BeadVertexMax.y = BeadVertexMax.z = (GLfloat) -1e10;
	BeadVertexMin.x = BeadVertexMin.y = BeadVertexMin.z = (GLfloat) 1e10;

	objData -> objectAnimation = 0;
	objData -> dofTree = 0;
	objData -> Slotptr = 0;
	objData -> switchList = 0;
	objData -> beadRoot = 0;
	objData -> beadTexture = 0;
	objData -> TotalDOF = 0;
	objData -> TotalSwitch = 0;
	objData -> TotalObjectSlot	= 0;
	objData -> TotalTextures = 0;
	objData -> objectFlag = 0;
	objData -> objectRadius = (GLfloat) 0.0; 
	objData -> StructureSize = sizeof(GLObjectData);
	objData -> TotalTextureSet = 1;
	objData -> TextureSetSize = 0;
}

void CHOTReader::removeBeadWithoutChild (GLbeadTree **bead)
{
	GLbeadTree *curbead = *bead;
	if (curbead) {
		if ((curbead -> type == BEAD_TYPE_GROUP) || 
			(curbead -> type == BEAD_TYPE_OBJECT)) {
			if (!curbead -> child) {
				removeBeadWithoutChild (&curbead -> next);
				*bead = curbead -> next;
				glReleaseMemory ((char *) curbead);
				return;
			}
		}
		removeBeadWithoutChild (&curbead -> next);
		removeBeadWithoutChild (&curbead -> child);
	}
}

void CHOTReader::removeBSPBead (GLbeadTree **bead)
{
	GLbeadTree *curbead = *bead;
	if (curbead) {
		if (curbead -> type == BEAD_TYPE_BSP) {
			GLbeadTree *child = curbead -> child;
			if (child) {
				GLbeadTree *nextchild = child -> next;
				if (nextchild -> type != BEAD_TYPE_POLYGON) {
					GLbeadTree *lastchild = nextchild;
					while (nextchild) {
						if (nextchild -> type == BEAD_TYPE_POLYGON) {
							lastchild -> next = 0;
							break;
						}
						lastchild = nextchild;
						nextchild = nextchild -> next;
					}
					if (!nextchild) BSPproblem = 1;
					else if (!nextchild -> next) BSPproblem = 1;
				}
				else child -> next = 0;
				nextchild -> child = child;
				nextchild -> type = BEAD_TYPE_POLYGON_BSP;
				glReleaseMemory ((char *) curbead -> beadElement);
				if (curbead -> next) {
					curbead -> child = nextchild;
					curbead -> type = BEAD_TYPE_GROUP;
				}
				else {
					glReleaseMemory ((char *) curbead);
					*bead = nextchild;
					curbead = nextchild;
				}
			}
		}
		removeBSPBead (&curbead -> next);
		removeBSPBead (&curbead -> child);
	}
}

void CHOTReader::createSwitchList ()
{
	if (objData -> TotalSwitch) {
		GLint i = objData -> TotalSwitch * sizeof (GLint);
		objData -> switchList = (GLint *) glAllocateMemory (i);
		if (!objData -> switchList) {
			DisplayErrorMessage ((GLbyte *) "Can not allocate memory for Switch List!");
			return;
		}
		objData -> objectFlag |= OBJECT_TYPE_USE_SWITCH;
		memcpy (objData -> switchList, GlobalSwitchTable, i);
	}
}

void CHOTReader::createObjectSlot ()
{
	if (objData -> TotalObjectSlot) {
		GLint i;
		i = (objData -> TotalObjectSlot) * sizeof (GLbeadSlot);
		objData -> Slotptr = (GLbeadSlot *) glAllocateMemory (i);
		if (!objData -> Slotptr) {
			DisplayErrorMessage ((GLbyte *) "Can not allocate memory for Object Slot!");
			return;
		}
		objData -> objectFlag |= OBJECT_TYPE_HAS_OBJECT_SLOT;
		traverseObjectSlotBead (objData -> beadRoot);
		GLbeadSlot *slot = objData -> Slotptr;
		for (i=0; i <= objData -> TotalObjectSlot; i++) {
			if (GlobalSlotTable[i]) {
				slot[i] = *(GlobalSlotTable[i]);
				glReleaseMemory ((char *) GlobalSlotTable[i]);
			}
		}
	}
}

void CHOTReader::traverseObjectSlotBead (GLbeadTree *bead)
{
	if (bead) {
		if (bead -> type == BEAD_TYPE_OBJECT_SLOT) {
			GLbeadTree *child = bead -> child;
			if (!child) {
				DisplayErrorMessage ((GLbyte *) "ObjectSlot must have polygon child!");
				return;
			}
			if (child -> child) {
				DisplayErrorMessage ((GLbyte *) "ObjectSlot child can not have child!");
				return;
			}
			if (child -> next) {
				DisplayErrorMessage ((GLbyte *) "ObjectSlot can only have one child!");
				return;
			}
			if (child -> type != BEAD_TYPE_POLYGON) {
				DisplayErrorMessage ((GLbyte *) "ObjectSlot child must be polygon type!");
				return;
			}
			GLbeadPolygon *poly = (GLbeadPolygon *) child -> beadElement;
			if (poly -> subface) {
				DisplayErrorMessage ((GLbyte *) "ObjectSlot child can not have subface!");
				return;
			}
			GLbeadSlot *slot = GlobalSlotTable[(GLint) bead -> beadElement];
			GLvertex *slotvtx = GetVertexCoord (poly -> vertices[0]);
			slot -> objectCenter = *slotvtx;
			slot -> slotMatrix.M11 = slot -> slotMatrix.M22 =
			slot -> slotMatrix.M33 = 1.0f;
			slot -> slotMatrix.M12 = slot -> slotMatrix.M13 =
			slot -> slotMatrix.M21 = slot -> slotMatrix.M23 =
			slot -> slotMatrix.M31 = slot -> slotMatrix.M32 = 0.0f;

			GLbeadTree *next = bead -> next;
			if (next && next -> type == BEAD_TYPE_MATRIX) {
				GLmatrix *mat = (GLmatrix *) next -> beadElement;
				slot -> slotMatrix = *mat;
			}
			RemovePolygon (child);
			bead -> child = 0;
		}
		traverseObjectSlotBead (bead -> next);
		traverseObjectSlotBead (bead -> child);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -