コード例 #1
0
// ppFileData is incremented to the end of the file on exit!
static iIMDShape *iV_ProcessIMD(const QString &filename, const char **ppFileData, const char *FileDataEnd)
{
	const char *pFileData = *ppFileData;
	char buffer[PATH_MAX], texfile[PATH_MAX], normalfile[PATH_MAX], specfile[PATH_MAX];
	int cnt, nlevels;
	iIMDShape *shape;
	UDWORD level;
	int32_t imd_version;
	uint32_t imd_flags;
	bool bTextured = false;
	iIMDShape *objanimpie[ANIM_EVENT_COUNT];

	memset(normalfile, 0, sizeof(normalfile));
	memset(specfile, 0, sizeof(specfile));

	if (sscanf(pFileData, "%255s %d%n", buffer, &imd_version, &cnt) != 2)
	{
		debug(LOG_ERROR, "%s: bad PIE version: (%s)", filename.toUtf8().constData(), buffer);
		assert(false);
		return nullptr;
	}
	pFileData += cnt;

	if (strcmp(PIE_NAME, buffer) != 0)
	{
		debug(LOG_ERROR, "%s: Not an IMD file (%s %d)", filename.toUtf8().constData(), buffer, imd_version);
		return nullptr;
	}

	//Now supporting version PIE_VER and PIE_FLOAT_VER files
	if (imd_version != PIE_VER && imd_version != PIE_FLOAT_VER)
	{
		debug(LOG_ERROR, "%s: Version %d not supported", filename.toUtf8().constData(), imd_version);
		return nullptr;
	}

	// Read flag
	if (sscanf(pFileData, "%255s %x%n", buffer, &imd_flags, &cnt) != 2)
	{
		debug(LOG_ERROR, "%s: bad flags: %s", filename.toUtf8().constData(), buffer);
		return nullptr;
	}
	pFileData += cnt;

	/* This can be either texture or levels */
	if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2)
	{
		debug(LOG_ERROR, "%s: Expecting TEXTURE or LEVELS: %s", filename.toUtf8().constData(), buffer);
		return nullptr;
	}
	pFileData += cnt;

	// get texture page if specified
	if (strncmp(buffer, "TEXTURE", 7) == 0)
	{
		int i, pwidth, pheight;
		char ch, texType[PATH_MAX];

		/* the first parameter for textures is always ignored; which is why we ignore
		 * nlevels read in above */
		ch = *pFileData++;

		// Run up to the dot or till the buffer is filled. Leave room for the extension.
		for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i)
		{
			texfile[i] = ch;
		}
		texfile[i] = '\0';

		if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1)
		{
			debug(LOG_ERROR, "%s: Texture info corrupt: %s", filename.toUtf8().constData(), buffer);
			return nullptr;
		}
		pFileData += cnt;

		if (strcmp(texType, "png") != 0)
		{
			debug(LOG_ERROR, "%s: Only png textures supported", filename.toUtf8().constData());
			return nullptr;
		}
		sstrcat(texfile, ".png");

		if (sscanf(pFileData, "%d %d%n", &pwidth, &pheight, &cnt) != 2)
		{
			debug(LOG_ERROR, "%s: Bad texture size: %s", filename.toUtf8().constData(), buffer);
			return nullptr;
		}
		pFileData += cnt;

		/* Now read in LEVELS directive */
		if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2)
		{
			debug(LOG_ERROR, "%s: Bad levels info: %s", filename.toUtf8().constData(), buffer);
			return nullptr;
		}
		pFileData += cnt;

		bTextured = true;
	}

	if (strncmp(buffer, "NORMALMAP", 9) == 0)
	{
		char ch, texType[PATH_MAX];
		int i;

		/* the first parameter for textures is always ignored; which is why we ignore
		 * nlevels read in above */
		ch = *pFileData++;

		// Run up to the dot or till the buffer is filled. Leave room for the extension.
		for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i)
		{
			normalfile[i] = ch;
		}
		normalfile[i] = '\0';

		if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1)
		{
			debug(LOG_ERROR, "%s: Normal map info corrupt: %s", filename.toUtf8().constData(), buffer);
			return nullptr;
		}
		pFileData += cnt;

		if (strcmp(texType, "png") != 0)
		{
			debug(LOG_ERROR, "%s: Only png normal maps supported", filename.toUtf8().constData());
			return nullptr;
		}
		sstrcat(normalfile, ".png");

		/* Now read in LEVELS directive */
		if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2)
		{
			debug(LOG_ERROR, "%s: Bad levels info: %s", filename.toUtf8().constData(), buffer);
			return nullptr;
		}
		pFileData += cnt;
	}

	if (strncmp(buffer, "SPECULARMAP", 11) == 0)
	{
		char ch, texType[PATH_MAX];
		int i;

		/* the first parameter for textures is always ignored; which is why we ignore nlevels read in above */
		ch = *pFileData++;

		// Run up to the dot or till the buffer is filled. Leave room for the extension.
		for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i)
		{
			specfile[i] = ch;
		}
		specfile[i] = '\0';

		if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1)
		{
			debug(LOG_ERROR, "%s specular map info corrupt: %s", filename.toUtf8().constData(), buffer);
			return nullptr;
		}
		pFileData += cnt;

		if (strcmp(texType, "png") != 0)
		{
			debug(LOG_ERROR, "%s: only png specular maps supported", filename.toUtf8().constData());
			return nullptr;
		}
		sstrcat(specfile, ".png");

		/* Try -again- to read in LEVELS directive */
		if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2)
		{
			debug(LOG_ERROR, "%s: Bad levels info: %s", filename.toUtf8().constData(), buffer);
			return nullptr;
		}
		pFileData += cnt;
	}

	for (int i = 0; i < ANIM_EVENT_COUNT; i++)
	{
		objanimpie[i] = nullptr;
	}
	while (strncmp(buffer, "EVENT", 5) == 0)
	{
		char animpie[PATH_MAX];

		ASSERT(nlevels < ANIM_EVENT_COUNT && nlevels >= 0, "Invalid event type %d", nlevels);
		pFileData++;
		if (sscanf(pFileData, "%255s%n", animpie, &cnt) != 1)
		{
			debug(LOG_ERROR, "%s animation model corrupt: %s", filename.toUtf8().constData(), buffer);
			return nullptr;
		}
		pFileData += cnt;

		objanimpie[nlevels] = modelGet(animpie);

		/* Try -yet again- to read in LEVELS directive */
		if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2)
		{
			debug(LOG_ERROR, "%s: Bad levels info: %s", filename.toUtf8().constData(), buffer);
			return nullptr;
		}
		pFileData += cnt;
	}

	if (strncmp(buffer, "LEVELS", 6) != 0)
	{
		debug(LOG_ERROR, "%s: Expecting 'LEVELS' directive (%s)", filename.toUtf8().constData(), buffer);
		return nullptr;
	}

	/* Read first LEVEL directive */
	if (sscanf(pFileData, "%255s %d%n", buffer, &level, &cnt) != 2)
	{
		debug(LOG_ERROR, "(_load_level) file corrupt -J");
		return nullptr;
	}
	pFileData += cnt;

	if (strncmp(buffer, "LEVEL", 5) != 0)
	{
		debug(LOG_ERROR, "%s: Expecting 'LEVEL' directive (%s)", filename.toUtf8().constData(), buffer);
		return nullptr;
	}

	shape = _imd_load_level(filename, &pFileData, FileDataEnd, nlevels, imd_version, level);
	if (shape == nullptr)
	{
		debug(LOG_ERROR, "%s: Unsuccessful", filename.toUtf8().constData());
		return nullptr;
	}

	// load texture page if specified
	if (bTextured)
	{
		int texpage = iV_GetTexture(texfile);
		int normalpage = iV_TEX_INVALID;
		int specpage = iV_TEX_INVALID;

		ASSERT_OR_RETURN(nullptr, texpage >= 0, "%s could not load tex page %s", filename.toUtf8().constData(), texfile);

		if (normalfile[0] != '\0')
		{
			debug(LOG_TEXTURE, "Loading normal map %s for %s", normalfile, filename.toUtf8().constData());
			normalpage = iV_GetTexture(normalfile, false);
			ASSERT_OR_RETURN(nullptr, normalpage >= 0, "%s could not load tex page %s", filename.toUtf8().constData(), normalfile);
		}

		if (specfile[0] != '\0')
		{
			debug(LOG_TEXTURE, "Loading specular map %s for %s", specfile, filename.toUtf8().constData());
			specpage = iV_GetTexture(specfile, false);
			ASSERT_OR_RETURN(nullptr, specpage >= 0, "%s could not load tex page %s", filename.toUtf8().constData(), specfile);
		}

		// assign tex pages and flags to all levels
		for (iIMDShape *psShape = shape; psShape != nullptr; psShape = psShape->next)
		{
			psShape->texpage = texpage;
			psShape->normalpage = normalpage;
			psShape->specularpage = specpage;
			psShape->flags = imd_flags;
		}

		// check if model should use team colour mask
		if (imd_flags & iV_IMD_TCMASK)
		{
			int texpage_mask;

			pie_MakeTexPageTCMaskName(texfile);
			sstrcat(texfile, ".png");
			texpage_mask = iV_GetTexture(texfile);

			ASSERT_OR_RETURN(shape, texpage_mask >= 0, "%s could not load tcmask %s", filename.toUtf8().constData(), texfile);

			// Propagate settings through levels
			for (iIMDShape *psShape = shape; psShape != nullptr; psShape = psShape->next)
			{
				psShape->tcmaskpage = texpage_mask;
			}
		}
	}

	// copy over model-wide animation information, stored only in the first level
	for (int i = 0; i < ANIM_EVENT_COUNT; i++)
	{
		shape->objanimpie[i] = objanimpie[i];
	}

	*ppFileData = pFileData;
	return shape;
}
コード例 #2
0
ファイル: imdload.cpp プロジェクト: Manistein/warzone2100
// ppFileData is incremented to the end of the file on exit!
static iIMDShape *iV_ProcessIMD(const char **ppFileData, const char *FileDataEnd)
{
	const char *pFileName = GetLastResourceFilename(); // Last loaded filename
	const char *pFileData = *ppFileData;
	char buffer[PATH_MAX], texfile[PATH_MAX], normalfile[PATH_MAX], specfile[PATH_MAX];
	int cnt, nlevels;
	iIMDShape *shape;
	UDWORD level;
	int32_t imd_version;
	uint32_t imd_flags;
	bool bTextured = false;
	GLuint shader = 0;

	memset(normalfile, 0, sizeof(normalfile));
	memset(specfile, 0, sizeof(specfile));

	if (sscanf(pFileData, "%255s %d%n", buffer, &imd_version, &cnt) != 2)
	{
		debug(LOG_ERROR, "iV_ProcessIMD %s bad version: (%s)", pFileName, buffer);
		assert(false);
		return NULL;
	}
	pFileData += cnt;

	if (strcmp(PIE_NAME, buffer) != 0)
	{
		debug(LOG_ERROR, "iV_ProcessIMD %s not an IMD file (%s %d)", pFileName, buffer, imd_version);
		return NULL;
	}

	//Now supporting version PIE_VER and PIE_FLOAT_VER files
	if (imd_version != PIE_VER && imd_version != PIE_FLOAT_VER)
	{
		debug(LOG_ERROR, "iV_ProcessIMD %s version %d not supported", pFileName, imd_version);
		return NULL;
	}

	// Read flag
	if (sscanf(pFileData, "%255s %x%n", buffer, &imd_flags, &cnt) != 2)
	{
		debug(LOG_ERROR, "iV_ProcessIMD %s bad flags: %s", pFileName, buffer);
		return NULL;
	}
	pFileData += cnt;

	/* This can be either texture or levels */
	if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2)
	{
		debug(LOG_ERROR, "iV_ProcessIMD %s expecting TEXTURE or LEVELS: %s", pFileName, buffer);
		return NULL;
	}
	pFileData += cnt;

	// get texture page if specified
	if (strncmp(buffer, "TEXTURE", 7) == 0)
	{
		int i, pwidth, pheight;
		char ch, texType[PATH_MAX];

		/* the first parameter for textures is always ignored; which is why we ignore
		 * nlevels read in above */
		ch = *pFileData++;

		// Run up to the dot or till the buffer is filled. Leave room for the extension.
		for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i)
		{
			texfile[i] = ch;
		}
		texfile[i] = '\0';

		if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1)
		{
			debug(LOG_ERROR, "iV_ProcessIMD %s texture info corrupt: %s", pFileName, buffer);
			return NULL;
		}
		pFileData += cnt;

		if (strcmp(texType, "png") != 0)
		{
			debug(LOG_ERROR, "iV_ProcessIMD %s: only png textures supported", pFileName);
			return NULL;
		}
		sstrcat(texfile, ".png");

		if (sscanf(pFileData, "%d %d%n", &pwidth, &pheight, &cnt) != 2)
		{
			debug(LOG_ERROR, "iV_ProcessIMD %s bad texture size: %s", pFileName, buffer);
			return NULL;
		}
		pFileData += cnt;

		/* Now read in LEVELS directive */
		if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2)
		{
			debug(LOG_ERROR, "iV_ProcessIMD %s bad levels info: %s", pFileName, buffer);
			return NULL;
		}
		pFileData += cnt;

		bTextured = true;
	}

	if (strncmp(buffer, "NORMALMAP", 9) == 0)
	{
		char ch, texType[PATH_MAX];
		int i;

		/* the first parameter for textures is always ignored; which is why we ignore
		 * nlevels read in above */
		ch = *pFileData++;

		// Run up to the dot or till the buffer is filled. Leave room for the extension.
		for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i)
		{
			normalfile[i] = ch;
		}
		normalfile[i] = '\0';

		if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1)
		{
			debug(LOG_ERROR, "iV_ProcessIMD %s normal map info corrupt: %s", pFileName, buffer);
			return NULL;
		}
		pFileData += cnt;

		if (strcmp(texType, "png") != 0)
		{
			debug(LOG_ERROR, "iV_ProcessIMD %s: only png normal maps supported", pFileName);
			return NULL;
		}
		sstrcat(normalfile, ".png");

		/* Now read in LEVELS directive */
		if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2)
		{
			debug(LOG_ERROR, "iV_ProcessIMD %s bad levels info: %s", pFileName, buffer);
			return NULL;
		}
		pFileData += cnt;
	}

	if (strncmp(buffer, "SPECULARMAP", 11) == 0)
	{
		char ch, texType[PATH_MAX];
		int i;

		/* the first parameter for textures is always ignored; which is why we ignore nlevels read in above */
		ch = *pFileData++;

		// Run up to the dot or till the buffer is filled. Leave room for the extension.
		for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i)
		{
			specfile[i] = ch;
		}
		specfile[i] = '\0';

		if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1)
		{
			debug(LOG_ERROR, "%s specular map info corrupt: %s", pFileName, buffer);
			return NULL;
		}
		pFileData += cnt;

		if (strcmp(texType, "png") != 0)
		{
			debug(LOG_ERROR, "%s: only png specular maps supported", pFileName);
			return NULL;
		}
		sstrcat(specfile, ".png");

		/* Try -again- to read in LEVELS directive */
		if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2)
		{
			debug(LOG_ERROR, "iV_ProcessIMD %s bad levels info: %s", pFileName, buffer);
			return NULL;
		}
		pFileData += cnt;
	}

	// DEPRECATED SHADERS DIRECTIVE! Has been moved into levels block now. Remove me later.
	if (strncmp(buffer, "SHADERS", 7) == 0)
	{
		char vertex[PATH_MAX], fragment[PATH_MAX];

		/* the first parameter for "textures" is always ignored; which is why we ignore nlevels read in above */
		pFileData++;

		if (sscanf(pFileData, "%255s %255s%n", vertex, fragment, &cnt) != 2)
		{
			debug(LOG_ERROR, "%s shader corrupt: %s", pFileName, buffer);
			return NULL;
		}
		pFileData += cnt;
		shader = pie_LoadShader(pFileName, vertex, fragment);

		/* Try -yet again- to read in LEVELS directive */
		if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2)
		{
			debug(LOG_ERROR, "iV_ProcessIMD %s bad levels info: %s", pFileName, buffer);
			return NULL;
		}
		pFileData += cnt;
	}

	if (strncmp(buffer, "LEVELS", 6) != 0)
	{
		debug(LOG_ERROR, "iV_ProcessIMD: expecting 'LEVELS' directive (%s)", buffer);
		return NULL;
	}

	/* Read first LEVEL directive */
	if (sscanf(pFileData, "%255s %d%n", buffer, &level, &cnt) != 2)
	{
		debug(LOG_ERROR, "(_load_level) file corrupt -J");
		return NULL;
	}
	pFileData += cnt;

	if (strncmp(buffer, "LEVEL", 5) != 0)
	{
		debug(LOG_ERROR, "iV_ProcessIMD(2): expecting 'LEVEL' directive (%s)", buffer);
		return NULL;
	}

	shape = _imd_load_level(&pFileData, FileDataEnd, nlevels, imd_version);
	if (shape == NULL)
	{
		debug(LOG_ERROR, "iV_ProcessIMD %s unsuccessful", pFileName);
		return NULL;
	}

	// assign shader to all levels, if old deprecated SHADERS directive used. FIXME remove this later.
	for (iIMDShape *psShape = shape; shader && psShape != NULL; psShape = psShape->next)
	{
		shape->shaderProgram = shader;
	}

	// load texture page if specified
	if (bTextured)
	{
		int texpage = iV_GetTexture(texfile);
		int normalpage = iV_TEX_INVALID;
		int specpage = iV_TEX_INVALID;

		ASSERT_OR_RETURN(NULL, texpage >= 0, "%s could not load tex page %s", pFileName, texfile);

		if (normalfile[0] != '\0')
		{
			debug(LOG_TEXTURE, "Loading normal map %s for %s", normalfile, pFileName);
			normalpage = iV_GetTexture(normalfile);
			ASSERT_OR_RETURN(NULL, normalpage >= 0, "%s could not load tex page %s", pFileName, normalfile);
		}

		if (specfile[0] != '\0')
		{
			debug(LOG_TEXTURE, "Loading specular map %s for %s", specfile, pFileName);
			specpage = iV_GetTexture(specfile);
			ASSERT_OR_RETURN(NULL, specpage >= 0, "%s could not load tex page %s", pFileName, specfile);
		}

		// assign tex pages and flags to all levels
		for (iIMDShape *psShape = shape; psShape != NULL; psShape = psShape->next)
		{
			psShape->texpage = texpage;
			psShape->normalpage = normalpage;
			psShape->specularpage = specpage;
			psShape->flags = imd_flags;
		}

		// check if model should use team colour mask
		if (imd_flags & iV_IMD_TCMASK)
		{
			int texpage_mask;

			pie_MakeTexPageTCMaskName(texfile);
			sstrcat(texfile, ".png");
			texpage_mask = iV_GetTexture(texfile);

			ASSERT_OR_RETURN(shape, texpage_mask >= 0, "%s could not load tcmask %s", pFileName, texfile);

			// Propagate settings through levels
			for (iIMDShape *psShape = shape; psShape != NULL; psShape = psShape->next)
			{
				psShape->tcmaskpage = texpage_mask;
			}
		}
	}

	*ppFileData = pFileData;
	return shape;
}
コード例 #3
0
/*!
 * Load shape levels recursively
 * \param ppFileData Pointer to the data (usualy read from a file)
 * \param FileDataEnd ???
 * \param nlevels Number of levels to load
 * \return pointer to iFSDShape structure (or NULL on error)
 * \pre ppFileData loaded
 * \post s allocated
 */
static iIMDShape *_imd_load_level(const QString &filename, const char **ppFileData, const char *FileDataEnd, int nlevels, int pieVersion, int level)
{
	const char *pFileData = *ppFileData;
	char buffer[PATH_MAX] = {'\0'};
	int cnt = 0, n = 0, i;
	iIMDShape *s = nullptr;
	float dummy;

	if (nlevels == 0)
	{
		return nullptr;
	}

	i = sscanf(pFileData, "%255s %n", buffer, &cnt);
	ASSERT_OR_RETURN(nullptr, i == 1, "Bad directive following LEVEL");

	s = new iIMDShape;

	// Optionally load and ignore deprecated MATERIALS directive
	if (strcmp(buffer, "MATERIALS") == 0)
	{
		i = sscanf(pFileData, "%255s %f %f %f %f %f %f %f %f %f %f%n", buffer, &dummy, &dummy, &dummy, &dummy,
		           &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &cnt);
		ASSERT_OR_RETURN(nullptr, i == 11, "Bad MATERIALS directive");
		debug(LOG_WARNING, "MATERIALS directive no longer supported!");
		pFileData += cnt;
	}
	else if (strcmp(buffer, "SHADERS") == 0)
	{
		char vertex[PATH_MAX], fragment[PATH_MAX];

		if (sscanf(pFileData, "%255s %255s %255s%n", buffer, vertex, fragment, &cnt) != 3)
		{
			debug(LOG_ERROR, "%s shader corrupt: %s", filename.toUtf8().constData(), buffer);
			return nullptr;
		}
		std::vector<std::string> uniform_names { "colour", "teamcolour", "stretch", "tcmask", "fogEnabled", "normalmap",
		                                         "specularmap", "ecmEffect", "alphaTest", "graphicsCycle", "ModelViewProjectionMatrix" };
		s->shaderProgram = pie_LoadShader(filename.toUtf8().constData(), vertex, fragment, uniform_names);
		pFileData += cnt;
	}

	if (sscanf(pFileData, "%255s %d%n", buffer, &s->npoints, &cnt) != 2)
	{
		debug(LOG_ERROR, "_imd_load_level(2): file corrupt");
		return nullptr;
	}
	pFileData += cnt;

	// load points

	ASSERT_OR_RETURN(nullptr, strcmp(buffer, "POINTS") == 0, "Expecting 'POINTS' directive, got: %s", buffer);

	_imd_load_points(&pFileData, s);

	if (sscanf(pFileData, "%255s %d%n", buffer, &s->npolys, &cnt) != 2)
	{
		debug(LOG_ERROR, "_imd_load_level(3): file corrupt");
		return nullptr;
	}
	pFileData += cnt;

	ASSERT_OR_RETURN(nullptr, strcmp(buffer, "POLYGONS") == 0, "Expecting 'POLYGONS' directive, got: %s", buffer);

	_imd_load_polys(filename, &pFileData, s, pieVersion);

	// optional stuff : levels, object animations, connectors
	s->objanimframes = 0;
	while (!AtEndOfFile(pFileData, FileDataEnd)) // check for end of file (give or take white space)
	{
		// Scans in the line ... if we don't get 2 parameters then quit
		if (sscanf(pFileData, "%255s %d%n", buffer, &n, &cnt) != 2)
		{
			break;
		}
		pFileData += cnt;

		if (strcmp(buffer, "LEVEL") == 0)	// check for next level
		{
			debug(LOG_3D, "imd[_load_level] = npoints %d, npolys %d", s->npoints, s->npolys);
			s->next = _imd_load_level(filename, &pFileData, FileDataEnd, nlevels - 1, pieVersion, level + 1);
		}
		else if (strcmp(buffer, "CONNECTORS") == 0)
		{
			//load connector stuff
			s->nconnectors = n;
			_imd_load_connectors(&pFileData, s);
		}
		else if (strcmp(buffer, "ANIMOBJECT") == 0)
		{
			s->objanimtime = n;
			if (sscanf(pFileData, "%d %d%n", &s->objanimcycles, &s->objanimframes, &cnt) != 2)
			{
				debug(LOG_ERROR, "%s bad ANIMOBJ: %s", filename.toUtf8().constData(), pFileData);
				return nullptr;
			}
			pFileData += cnt;
			s->objanimdata.resize(s->objanimframes);
			for (int i = 0; i < s->objanimframes; i++)
			{
				int frame;
				Vector3i pos, rot;

				if (sscanf(pFileData, "%d %d %d %d %d %d %d %f %f %f%n",
				           &frame, &pos.x, &pos.y, &pos.z, &rot.x, &rot.y, &rot.z,
				           &s->objanimdata[i].scale.x, &s->objanimdata[i].scale.y, &s->objanimdata[i].scale.z, &cnt) != 10)
				{
					debug(LOG_ERROR, "%s: Invalid object animation level %d, line %d, frame %d", filename.toUtf8().constData(), level, i, frame);
				}
				ASSERT(frame == i, "%s: Invalid frame enumeration object animation (level %d) %d: %d", filename.toUtf8().constData(), level, i, frame);
				s->objanimdata[i].pos.x = pos.x / INT_SCALE;
				s->objanimdata[i].pos.y = pos.z / INT_SCALE;
				s->objanimdata[i].pos.z = pos.y / INT_SCALE;
				s->objanimdata[i].rot.pitch = -(rot.x * DEG_1 / INT_SCALE);
				s->objanimdata[i].rot.direction = -(rot.z * DEG_1 / INT_SCALE);
				s->objanimdata[i].rot.roll = -(rot.y * DEG_1 / INT_SCALE);
				pFileData += cnt;
			}
		}
		else
		{
			debug(LOG_ERROR, "(_load_level) unexpected directive %s %d", buffer, n);
			break;
		}
	}

	// FINALLY, massage the data into what can stream directly to OpenGL
	glGenBuffers(VBO_COUNT, s->buffers);
	vertexCount = 0;
	for (int k = 0; k < MAX(1, s->numFrames); k++)
	{
		// Go through all polygons for each frame
		for (unsigned i = 0; i < s->npolys; i++)
		{
			const iIMDPoly *pPolys = &s->polys[i];

			// Do we already have the vertex data for this polygon?
			indices.append(addVertex(s, 0, pPolys, k));
			indices.append(addVertex(s, 1, pPolys, k));
			indices.append(addVertex(s, 2, pPolys, k));
		}
	}
	glBindBuffer(GL_ARRAY_BUFFER, s->buffers[VBO_VERTEX]);
	glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, s->buffers[VBO_NORMAL]);
	glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(GLfloat), normals.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->buffers[VBO_INDEX]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, s->buffers[VBO_TEXCOORD]);
	glBufferData(GL_ARRAY_BUFFER, texcoords.size() * sizeof(GLfloat), texcoords.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind

	indices.resize(0);
	vertices.resize(0);
	texcoords.resize(0);
	normals.resize(0);

	*ppFileData = pFileData;

	return s;
}
コード例 #4
0
ファイル: imdload.cpp プロジェクト: Manistein/warzone2100
/*!
 * Load shape levels recursively
 * \param ppFileData Pointer to the data (usualy read from a file)
 * \param FileDataEnd ???
 * \param nlevels Number of levels to load
 * \return pointer to iFSDShape structure (or NULL on error)
 * \pre ppFileData loaded
 * \post s allocated
 */
static iIMDShape *_imd_load_level(const char **ppFileData, const char *FileDataEnd, int nlevels, int pieVersion)
{
	const char *pFileName = GetLastResourceFilename(); // Last loaded filename
	const char *pFileData = *ppFileData;
	char buffer[PATH_MAX] = {'\0'};
	int cnt = 0, n = 0, i;
	iIMDShape *s = NULL;
	float dummy;

	if (nlevels == 0)
	{
		return NULL;
	}

	i = sscanf(pFileData, "%255s %n", buffer, &cnt);
	ASSERT_OR_RETURN(NULL, i == 1, "Bad directive following LEVEL");

	s = new iIMDShape;

	// Optionally load and ignore deprecated MATERIALS directive
	if (strcmp(buffer, "MATERIALS") == 0)
	{
		i = sscanf(pFileData, "%255s %f %f %f %f %f %f %f %f %f %f%n", buffer, &dummy, &dummy, &dummy, &dummy,
		           &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &cnt);
		ASSERT_OR_RETURN(NULL, i == 11, "Bad MATERIALS directive");
		debug(LOG_WARNING, "MATERIALS directive no longer supported!");
		pFileData += cnt;
	}
	else if (strcmp(buffer, "SHADERS") == 0)
	{
		char vertex[PATH_MAX], fragment[PATH_MAX];

		if (sscanf(pFileData, "%255s %255s %255s%n", buffer, vertex, fragment, &cnt) != 3)
		{
			debug(LOG_ERROR, "%s shader corrupt: %s", pFileName, buffer);
			return NULL;
		}
		s->shaderProgram = pie_LoadShader(pFileName, vertex, fragment);
		pFileData += cnt;
	}

	if (sscanf(pFileData, "%255s %d%n", buffer, &s->npoints, &cnt) != 2)
	{
		debug(LOG_ERROR, "_imd_load_level(2): file corrupt");
		return NULL;
	}
	pFileData += cnt;

	// load points

	ASSERT_OR_RETURN(NULL, strcmp(buffer, "POINTS") == 0, "Expecting 'POINTS' directive, got: %s", buffer);

	_imd_load_points(&pFileData, s);

	if (sscanf(pFileData, "%255s %d%n", buffer, &s->npolys, &cnt) != 2)
	{
		debug(LOG_ERROR, "_imd_load_level(3): file corrupt");
		return NULL;
	}
	pFileData += cnt;

	ASSERT_OR_RETURN(NULL, strcmp(buffer, "POLYGONS") == 0, "Expecting 'POLYGONS' directive, got: %s", buffer);

	_imd_load_polys(&pFileData, s, pieVersion);

	// NOW load optional stuff
	while (!AtEndOfFile(pFileData, FileDataEnd)) // check for end of file (give or take white space)
	{
		// Scans in the line ... if we don't get 2 parameters then quit
		if (sscanf(pFileData, "%255s %d%n", buffer, &n, &cnt) != 2)
		{
			break;
		}
		pFileData += cnt;

		if (strcmp(buffer, "LEVEL") == 0)	// check for next level
		{
			debug(LOG_3D, "imd[_load_level] = npoints %d, npolys %d", s->npoints, s->npolys);
			s->next = _imd_load_level(&pFileData, FileDataEnd, nlevels - 1, pieVersion);
		}
		else if (strcmp(buffer, "CONNECTORS") == 0)
		{
			//load connector stuff
			s->nconnectors = n;
			_imd_load_connectors(&pFileData, s);
		}
		else
		{
			debug(LOG_ERROR, "(_load_level) unexpected directive %s %d", buffer, n);
			break;
		}
	}

	// FINALLY, massage the data into what can stream directly to OpenGL
	glGenBuffers(VBO_COUNT, s->buffers);
	vertexCount = 0;
	for (int k = 0; k < MAX(1, s->numFrames); k++)
	{
		// Go through all polygons for each frame
		for (int i = 0; i < s->npolys; i++)
		{
			const iIMDPoly *pPolys = &s->polys[i];

			// Do we already have the vertex data for this polygon?
			indices.append(addVertex(s, 0, pPolys, k));
			indices.append(addVertex(s, 1, pPolys, k));
			indices.append(addVertex(s, 2, pPolys, k));
		}
	}
	glBindBuffer(GL_ARRAY_BUFFER, s->buffers[VBO_VERTEX]);
	glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, s->buffers[VBO_NORMAL]);
	glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(GLfloat), normals.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->buffers[VBO_INDEX]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, s->buffers[VBO_TEXCOORD]);
	glBufferData(GL_ARRAY_BUFFER, texcoords.size() * sizeof(GLfloat), texcoords.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind

	indices.resize(0);
	vertices.resize(0);
	texcoords.resize(0);
	normals.resize(0);

	*ppFileData = pFileData;

	return s;
}
コード例 #5
0
ファイル: imdload.cpp プロジェクト: noccy80/warzone2100
/*!
 * Load shape levels recursively
 * \param ppFileData Pointer to the data (usualy read from a file)
 * \param FileDataEnd ???
 * \param nlevels Number of levels to load
 * \return pointer to iFSDShape structure (or NULL on error)
 * \pre ppFileData loaded
 * \post s allocated
 */
static iIMDShape *_imd_load_level(const char **ppFileData, const char *FileDataEnd, int nlevels, int pieVersion)
{
	const char *pTmp, *pFileData = *ppFileData;
	char buffer[PATH_MAX] = {'\0'};
	int cnt = 0, n = 0, i;
	iIMDShape *s = NULL;

	if (nlevels == 0)
	{
		return NULL;
	}

	// Load optional MATERIALS directive
	pTmp = pFileData;	// remember position
	i = sscanf(pFileData, "%255s %n", buffer, &cnt);
	ASSERT_OR_RETURN(NULL, i == 1, "Bad directive following LEVEL");

	s = new iIMDShape;

	if (strcmp(buffer, "MATERIALS") == 0)
	{
		i = sscanf(pFileData, "%255s %f %f %f %f %f %f %f %f %f %f%n", buffer,
		           &s->material[LIGHT_AMBIENT][0], &s->material[LIGHT_AMBIENT][1], &s->material[LIGHT_AMBIENT][2],
		           &s->material[LIGHT_DIFFUSE][0], &s->material[LIGHT_DIFFUSE][1], &s->material[LIGHT_DIFFUSE][2],
	                   &s->material[LIGHT_SPECULAR][0], &s->material[LIGHT_SPECULAR][1], &s->material[LIGHT_SPECULAR][2],
		           &s->shininess, &cnt);
		ASSERT_OR_RETURN(NULL, i == 11, "Bad MATERIALS directive");
		pFileData += cnt;
	}
	else // use defaults
	{
		pFileData = pTmp;
	}

	if (sscanf(pFileData, "%255s %d%n", buffer, &s->npoints, &cnt) != 2)
	{
		debug(LOG_ERROR, "_imd_load_level(2): file corrupt");
		return NULL;
	}
	pFileData += cnt;

	// load points

	ASSERT_OR_RETURN(NULL, strcmp(buffer, "POINTS") == 0, "Expecting 'POINTS' directive, got: %s", buffer);

	_imd_load_points( &pFileData, s );

	if (sscanf(pFileData, "%255s %d%n", buffer, &s->npolys, &cnt) != 2)
	{
		debug(LOG_ERROR, "_imd_load_level(3): file corrupt");
		return NULL;
	}
	pFileData += cnt;

	ASSERT_OR_RETURN(NULL, strcmp(buffer, "POLYGONS") == 0, "Expecting 'POLYGONS' directive, got: %s", buffer);

	_imd_load_polys( &pFileData, s, pieVersion);

	// NOW load optional stuff
	while (!AtEndOfFile(pFileData, FileDataEnd)) // check for end of file (give or take white space)
	{
		// Scans in the line ... if we don't get 2 parameters then quit
		if (sscanf(pFileData, "%255s %d%n", buffer, &n, &cnt) != 2)
		{
			break;
		}
		pFileData += cnt;

		// check for next level ... or might be a BSP - This should handle an imd if it has a BSP tree attached to it
		// might be "BSP" or "LEVEL"
		if (strcmp(buffer, "LEVEL") == 0)
		{
			debug(LOG_3D, "imd[_load_level] = npoints %d, npolys %d", s->npoints, s->npolys);
			s->next = _imd_load_level(&pFileData, FileDataEnd, nlevels - 1, pieVersion);
		}
		else if (strcmp(buffer, "CONNECTORS") == 0)
		{
			//load connector stuff
			s->nconnectors = n;
			_imd_load_connectors( &pFileData, s );
		}
		else
		{
			debug(LOG_ERROR, "(_load_level) unexpected directive %s %d", buffer, n);
			break;
		}
	}

	// FINALLY, massage the data into what can stream directly to OpenGL
	glGenBuffers(VBO_COUNT, s->buffers);
	vertexCount = 0;
	for (int k = 0; k < MAX(1, s->numFrames); k++)
	{
		// Go through all polygons for each frame
		for (int i = 0; i < s->npolys; i++)
		{
			const iIMDPoly *pPolys = &s->polys[i];

			// Do we already have the vertex data for this polygon?
			indices.append(addVertex(s, 0, pPolys, k));
			indices.append(addVertex(s, 1, pPolys, k));
			indices.append(addVertex(s, 2, pPolys, k));
		}
	}
	glBindBuffer(GL_ARRAY_BUFFER, s->buffers[VBO_VERTEX]);
	glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, s->buffers[VBO_NORMAL]);
	glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(GLfloat), normals.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->buffers[VBO_INDEX]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, s->buffers[VBO_TEXCOORD]);
	glBufferData(GL_ARRAY_BUFFER, texcoords.size() * sizeof(GLfloat), texcoords.constData(), GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind

	indices.resize(0);
	vertices.resize(0);
	texcoords.resize(0);
	normals.resize(0);

	*ppFileData = pFileData;

	return s;
}
コード例 #6
0
ファイル: imdloader.cpp プロジェクト: blezek/warzone2100
// ppFileData is incremented to the end of the file on exit!
iIMDShape *iV_ProcessIMD( const char *filename )
{
	const char *pFileData, *pFileDataEnd;
	char buffer[MAX_PATH] = "-_-", texfile[MAX_PATH];
	int cnt, nlevels, filelength;
	iIMDShape *shape, *psShape;
	Uint32 level;
	Sint32 imd_version;
	Uint32 imd_flags; // FIXME UNUSED
	bool bTextured = false;
	FILE *FileToOpen = NULL;

	fprintf(stderr, "filename: %s", filename);
	printf("filename: %s", filename);

	FileToOpen = fopen(filename, "rb");
	if (FileToOpen == NULL)
	{
		fprintf(stderr, "iV_ProcessIMD %s file doesn't exist: (%s)\n", filename);
		return NULL;
	}

	pFileData = (char*)malloc(1024*1024);

	filelength = fread((void*)pFileData, 1, 1024*1024,FileToOpen);

	pFileDataEnd = pFileData + filelength;

	if (sscanf(pFileData, "%s %d%n", buffer, &imd_version, &cnt) != 2)
	{
		fprintf(stderr, "iV_ProcessIMD %s bad version: (%s)\n", filename, buffer);
		return NULL;
	}
	pFileData += cnt;

	if (strcmp(IMD_NAME, buffer) != 0 && strcmp(PIE_NAME, buffer) !=0 )
	{
		fprintf(stderr, "iV_ProcessIMD %s not an IMD file (%s %d)\n", filename, buffer, imd_version);
		return NULL;
	}

	//Now supporting version 4 files
	if (imd_version < 2 || imd_version > 5)
	{
		fprintf(stderr, "iV_ProcessIMD %s version %d not supported\n", filename, imd_version);
		return NULL;
	}

	/* Flags are ignored now. Reading them in just to pass the buffer. */
	if (sscanf(pFileData, "%s %x%n", buffer, &imd_flags, &cnt) != 2)
	{
		fprintf(stderr, "iV_ProcessIMD %s bad flags: %s\n", filename, buffer);
		return NULL;
	}
	pFileData += cnt;

	/* This can be either texture or levels */
	if (sscanf(pFileData, "%s %d%n", buffer, &nlevels, &cnt) != 2)
	{
		fprintf(stderr, "iV_ProcessIMD %s expecting TEXTURE or LEVELS: %s\n", filename, buffer);
		return NULL;
	}
	pFileData += cnt;

	// get texture page if specified
	if (strncmp(buffer, "TEXTURE", 7) == 0)
	{
		int i, pwidth, pheight;
		char ch, texType[MAX_PATH];

		/* the first parameter for textures is always ignored; which is why we ignore
		 * nlevels read in above */
		ch = *pFileData++;

		// Run up to the dot or till the buffer is filled. Leave room for the extension.
		for( i = 0; i < MAX_PATH-5 && (ch = *pFileData++) != EOF && ch != '.'; i++ )
		{
 			texfile[i] = (char)ch;
		}
		texfile[i] = '\0';

		if (sscanf(pFileData, "%s%n", texType, &cnt) != 1)
		{
			fprintf(stderr, "iV_ProcessIMD %s texture info corrupt: %s\n", filename, buffer);
			return NULL;
		}
		pFileData += cnt;

		//more texture types using SDL_Image
		if (!strcmp(texType, "png"))
		{
			strcat(texfile, ".png");
		}
		else if (!strcmp(texType, "bmp"))
		{
			strcat(texfile, ".bmp");
		}
		else if (!strcmp(texType, "pcx"))
		{
			strcat(texfile, ".pcx");
		}
		else if (!strcmp(texType, "jpg"))
		{
			strcat(texfile, ".jpg");
		}
		else if (!strcmp(texType, "gif"))
		{
			strcat(texfile, ".gif");
		}
		else
		{
			fprintf(stderr, "iV_ProcessIMD %s: only png bmp pcx jpg gif textures supported\n", filename);
			return NULL;
		}

		//pie_MakeTexPageName(texfile);

		if (sscanf(pFileData, "%d %d%n", &pwidth, &pheight, &cnt) != 2)
		{
			fprintf(stderr, "iV_ProcessIMD %s bad texture size: %s\n", filename, buffer);
			return NULL;
		}
		pFileData += cnt;

		/* Now read in LEVELS directive */
		if (sscanf(pFileData, "%s %d%n", buffer, &nlevels, &cnt) != 2)
		{
			fprintf(stderr, "iV_ProcessIMD %s bad levels info: %s\n", filename, buffer);
			return NULL;
		}
		pFileData += cnt;

		bTextured = true;
	}

	if (strncmp(buffer, "LEVELS", 6) != 0)
	{
		fprintf(stderr, "iV_ProcessIMD: expecting 'LEVELS' directive (%s)", buffer);
		return NULL;
	}

	/* Read first LEVEL directive */
	if (sscanf(pFileData, "%s %d%n", buffer, &level, &cnt) != 2)
	{
		fprintf(stderr, "(_load_level) file corrupt -J\n");
		return NULL;
	}
	pFileData += cnt;

	if (strncmp(buffer, "LEVEL", 5) != 0)
	{
		fprintf(stderr, "iV_ProcessIMD(2): expecting 'LEVELS' directive (%s)", buffer);
		return NULL;
	}

	shape = _imd_load_level(&pFileData, pFileDataEnd, nlevels);
	if (shape == NULL)
	{
		fprintf(stderr, "iV_ProcessIMD %s unsuccessful\n", filename);
		return NULL;
	}

	// load texture page if specified
	if (bTextured)
	{
		int texpage = iV_GetTexture(texfile);

		if (texpage < 0)
		{
			fprintf(stderr, "iV_ProcessIMD %s could not load tex page %s\n", filename, texfile);
			return NULL;
		}
		/* assign tex page to levels */
		for (psShape = shape; psShape != NULL; psShape = psShape->next)
		{
			psShape->texpage = texpage;
		}
	}

	return shape;
}
コード例 #7
0
ファイル: imdloader.cpp プロジェクト: blezek/warzone2100
/*!
 * Load shape levels recursively
 * \param ppFileData Pointer to the data (usualy read from a file)
 * \param FileDataEnd ???
 * \param nlevels Number of levels to load
 * \return pointer to iFSDShape structure (or NULL on error)
 * \pre ppFileData loaded
 * \post s allocated
 */
static iIMDShape *_imd_load_level(const char **ppFileData, const char *FileDataEnd, int nlevels)
{
	const char *pFileData = *ppFileData;
	char buffer[MAX_PATH] = {'\0'};
	int cnt = 0, n = 0;
	iIMDShape *s = NULL;

	if (nlevels == 0)
		return NULL;

	s = (iIMDShape*)malloc(sizeof(iIMDShape));
	if (s == NULL)
	{
		/* Failed to allocate memory for s */
		fprintf(stderr, "_imd_load_level: Memory allocation error\n");
		return NULL;
	}

	s->nconnectors = 0; // Default number of connectors must be 0
	s->npoints = 0;
	s->npolys = 0;

	s->points = NULL;
	s->polys = NULL;
	s->connectors = NULL;
	s->next = NULL;

	s->shadowEdgeList = NULL;
	s->nShadowEdges = 0;
	s->texpage = iV_TEX_INVALID;


	if (sscanf(pFileData, "%s %d%n", buffer, &s->npoints, &cnt) != 2)
	{
		fprintf(stderr, "_imd_load_level(2): file corrupt\n");
		return NULL;
	}
	pFileData += cnt;

	// load points
	if (strcmp(buffer, "POINTS") != 0)
	{
		fprintf(stderr, "_imd_load_level: expecting 'POINTS' directive, got: %s", buffer);
		return NULL;
	}

	if (s->npoints > iV_IMD_MAX_POINTS)
	{
		fprintf(stderr, "_imd_load_level: too many points in IMD\n");
		return NULL;
	}

	_imd_load_points( &pFileData, s );


	if (sscanf(pFileData, "%s %d%n", buffer, &s->npolys, &cnt) != 2)
	{
		fprintf(stderr, "_imd_load_level(3): file corrupt\n");
		return NULL;
	}
	pFileData += cnt;

	if (strcmp(buffer, "POLYGONS") != 0)
	{
		fprintf(stderr,"_imd_load_level: expecting 'POLYGONS' directive\n");
		return NULL;
	}

	_imd_load_polys( &pFileData, s );


	// NOW load optional stuff
	while (!AtEndOfFile(pFileData, FileDataEnd)) // check for end of file (give or take white space)
	{
		// Scans in the line ... if we don't get 2 parameters then quit
		if (sscanf(pFileData, "%s %d%n", buffer, &n, &cnt) != 2)
		{
			break;
		}
		pFileData += cnt;

		// check for next level ... or might be a BSP - This should handle an imd if it has a BSP tree attached to it
		// might be "BSP" or "LEVEL"
		if (strcmp(buffer, "LEVEL") == 0)
		{
			fprintf(stderr, "imd[_load_level] = npoints %d, npolys %d\n", s->npoints, s->npolys);
			s->next = _imd_load_level(&pFileData, FileDataEnd, nlevels - 1);
		}
		else if (strcmp(buffer, "CONNECTORS") == 0)
		{
			//load connector stuff
			s->nconnectors = n;
			_imd_load_connectors( &pFileData, s );
		}
		else
		{
			fprintf(stderr, "(_load_level) unexpected directive %s %d", buffer, n);
			break;
		}
	}

	*ppFileData = pFileData;

	return s;
}
コード例 #8
0
ファイル: imdload.cpp プロジェクト: npangilinan/warzone2100
/*!
 * Load shape levels recursively
 * \param ppFileData Pointer to the data (usualy read from a file)
 * \param FileDataEnd ???
 * \param nlevels Number of levels to load
 * \return pointer to iFSDShape structure (or NULL on error)
 * \pre ppFileData loaded
 * \post s allocated
 */
static iIMDShape *_imd_load_level(const char **ppFileData, const char *FileDataEnd, int nlevels, int pieVersion)
{
    const char *pTmp, *pFileData = *ppFileData;
    char buffer[PATH_MAX] = {'\0'};
    int cnt = 0, n = 0, i;
    iIMDShape *s = NULL;

    if (nlevels == 0)
    {
        return NULL;
    }

    // Load optional MATERIALS directive
    pTmp = pFileData;	// remember position
    i = sscanf(pFileData, "%255s %n", buffer, &cnt);
    ASSERT_OR_RETURN(NULL, i == 1, "Bad directive following LEVEL");

    s = (iIMDShape*)malloc(sizeof(iIMDShape));
    if (s == NULL)
    {
        /* Failed to allocate memory for s */
        debug(LOG_ERROR, "_imd_load_level: Memory allocation error");
        return NULL;
    }
    s->flags = 0;
    s->nconnectors = 0; // Default number of connectors must be 0
    s->npoints = 0;
    s->npolys = 0;
    s->points = NULL;
    s->polys = NULL;
    s->connectors = NULL;
    s->next = NULL;
    s->shadowEdgeList = NULL;
    s->nShadowEdges = 0;
    s->texpage = iV_TEX_INVALID;
    s->tcmaskpage = iV_TEX_INVALID;
    s->normalpage = iV_TEX_INVALID;
    memset(s->material, 0, sizeof(s->material));
    s->material[LIGHT_AMBIENT][3] = 1.0f;
    s->material[LIGHT_DIFFUSE][3] = 1.0f;
    s->material[LIGHT_SPECULAR][3] = 1.0f;
    if (strcmp(buffer, "MATERIALS") == 0)
    {
        i = sscanf(pFileData, "%255s %f %f %f %f %f %f %f %f %f %f%n", buffer,
                   &s->material[LIGHT_AMBIENT][0], &s->material[LIGHT_AMBIENT][1], &s->material[LIGHT_AMBIENT][2],
                   &s->material[LIGHT_DIFFUSE][0], &s->material[LIGHT_DIFFUSE][1], &s->material[LIGHT_DIFFUSE][2],
                   &s->material[LIGHT_SPECULAR][0], &s->material[LIGHT_SPECULAR][1], &s->material[LIGHT_SPECULAR][2],
                   &s->shininess, &cnt);
        ASSERT_OR_RETURN(NULL, i == 11, "Bad MATERIALS directive");
        pFileData += cnt;
    }
    else
    {
        // Set default values
        s->material[LIGHT_AMBIENT][0] = 1.0f;
        s->material[LIGHT_AMBIENT][1] = 1.0f;
        s->material[LIGHT_AMBIENT][2] = 1.0f;
        s->material[LIGHT_DIFFUSE][0] = 1.0f;
        s->material[LIGHT_DIFFUSE][1] = 1.0f;
        s->material[LIGHT_DIFFUSE][2] = 1.0f;
        s->material[LIGHT_SPECULAR][0] = 1.0f;
        s->material[LIGHT_SPECULAR][1] = 1.0f;
        s->material[LIGHT_SPECULAR][2] = 1.0f;
        s->shininess = 10;
        pFileData = pTmp;
    }

    if (sscanf(pFileData, "%255s %d%n", buffer, &s->npoints, &cnt) != 2)
    {
        debug(LOG_ERROR, "_imd_load_level(2): file corrupt");
        return NULL;
    }
    pFileData += cnt;

    // load points

    ASSERT_OR_RETURN(NULL, strcmp(buffer, "POINTS") == 0, "Expecting 'POINTS' directive, got: %s", buffer);

    _imd_load_points( &pFileData, s );

    if (sscanf(pFileData, "%255s %d%n", buffer, &s->npolys, &cnt) != 2)
    {
        debug(LOG_ERROR, "_imd_load_level(3): file corrupt");
        return NULL;
    }
    pFileData += cnt;

    ASSERT_OR_RETURN(NULL, strcmp(buffer, "POLYGONS") == 0, "Expecting 'POLYGONS' directive, got: %s", buffer);

    _imd_load_polys( &pFileData, s, pieVersion);


    // NOW load optional stuff
    while (!AtEndOfFile(pFileData, FileDataEnd)) // check for end of file (give or take white space)
    {
        // Scans in the line ... if we don't get 2 parameters then quit
        if (sscanf(pFileData, "%255s %d%n", buffer, &n, &cnt) != 2)
        {
            break;
        }
        pFileData += cnt;

        // check for next level ... or might be a BSP - This should handle an imd if it has a BSP tree attached to it
        // might be "BSP" or "LEVEL"
        if (strcmp(buffer, "LEVEL") == 0)
        {
            debug(LOG_3D, "imd[_load_level] = npoints %d, npolys %d", s->npoints, s->npolys);
            s->next = _imd_load_level(&pFileData, FileDataEnd, nlevels - 1, pieVersion);
        }
        else if (strcmp(buffer, "CONNECTORS") == 0)
        {
            //load connector stuff
            s->nconnectors = n;
            _imd_load_connectors( &pFileData, s );
        }
        else
        {
            debug(LOG_ERROR, "(_load_level) unexpected directive %s %d", buffer, n);
            break;
        }
    }

    *ppFileData = pFileData;

    return s;
}