g_entity.c

来自「著名物理引擎Hawk的源代码」· C语言 代码 · 共 296 行

C
296
字号
/* G_entity.c, HAWK game engine
 *
 * Copyright 1997-1998 by Phil Frisbie, Jr.
 * for Hawk Software
 *
 */

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "G_main.h"


#define	MAX_INCLUDES	8
#define	MAX_KEY		32
script_t	scriptstack[MAX_INCLUDES];
script_t	*script;
int			scriptline;
#define	MAXTOKEN	1024
char    token[MAXTOKEN];
BOOL endofscript;
BOOL tokenready;                     /* only true if UnGetToken was just called */

#define	MAX_MAP_ENTITIES	2048
#define	MAX_MAP_ENTSTRING	0x40000
int			num_entities;
entity_t	entities[MAX_MAP_ENTITIES];
int			entdatasize;
char		*dentdata;

BOOL GetToken(BOOL crossline);

char *copystring(char *s)
{
	char	*b;
	b = gi.TagMalloc(strlen(s)+1, TAG_LEVEL);
	strcpy (b, s);
	return b;
}

void StripTrailing (char *e)
{
	char	*s;

	s = e + strlen(e)-1;
	while (s >= e && *s <= 32)
	{
		*s = 0;
		s--;
	}
}

void ParseFromMemory (char *buffer, int size)
{
	script = scriptstack;
	script++;
	strcpy(script->filename, "memory buffer" );

	script->buffer = buffer;
	script->line = 1;
	script->script_p = script->buffer;
	script->end_p = script->buffer + size;

	endofscript = FALSE;
	tokenready = FALSE;
}

BOOL EndOfScript(BOOL crossline)
{
	if(!strcmp(script->filename, "memory buffer"))
	{
		endofscript = TRUE;
		return FALSE;
	}

	free(script->buffer);
	if(script == scriptstack+1)
	{
		endofscript = TRUE;
		return FALSE;
	}
	script--;
	scriptline = script->line;
	printf ("returning to %s\n", script->filename);
	return GetToken(crossline);
}

BOOL GetToken(BOOL crossline)
{
	char    *token_p;

	if (tokenready)  /* is a token allready waiting? */
	{
		tokenready = FALSE;
		return TRUE;
	}

	if (script->script_p >= script->end_p)
		return EndOfScript(crossline);

skipspace:
	while(*script->script_p <= 32)
	{
		if (script->script_p >= script->end_p)
			return EndOfScript(crossline);
		if (*script->script_p++ == '\n')
		{
			scriptline = script->line++;
		}
	}

	if(script->script_p >= script->end_p)
		return EndOfScript (crossline);

	if(*script->script_p == ';' || *script->script_p == '#'
		|| ( script->script_p[0] == '/' && script->script_p[1] == '/') )
	{
		while(*script->script_p++ != '\n')
			if(script->script_p >= script->end_p)
				return EndOfScript (crossline);
		goto skipspace;
	}

	if (script->script_p[0] == '/' && script->script_p[1] == '*')
	{
		script->script_p+=2;
		while(script->script_p[0] != '*' && script->script_p[1] != '/')
		{
			script->script_p++;
			if(script->script_p >= script->end_p)
				return EndOfScript (crossline);
		}
		script->script_p += 2;
		goto skipspace;
	}

	/* copy token */
	token_p = token;

	if(*script->script_p == '"')
	{
		/* quoted token */
		script->script_p++;
		while(*script->script_p != '"')
		{
			*token_p++ = *script->script_p++;
			if(script->script_p == script->end_p)
				break;
		}
		script->script_p++;
	}
	else	/* regular token */
	while( *script->script_p > 32 && *script->script_p != ';')
	{
		*token_p++ = *script->script_p++;
		if (script->script_p == script->end_p)
			break;
	}

	*token_p = 0;

	return TRUE;
}

epair_t *ParseEpair (void)
{
	epair_t	*e;

	e = malloc(sizeof(epair_t));
	memset(e, 0, sizeof(epair_t));
	
	e->key = copystring(token);
	GetToken(FALSE);
	e->value = copystring(token);

	StripTrailing (e->key);
	StripTrailing (e->value);

	return e;
}

BOOL ParseEntity (void)
{
	epair_t		*e;
	entity_t	*mapent;

	if(!GetToken(TRUE))
		return FALSE;

	mapent = &entities[num_entities];
	num_entities++;

	do
	{
		if(!strcmp (token, "}") )
			break;
		e = ParseEpair();
		e->next = mapent->epairs;
		mapent->epairs = e;
	}while(1);
	
	return TRUE;
}

int ParseEntities(char *entdata, int datasize)
{
	entdatasize = datasize;
	dentdata = entdata;

	num_entities = 0;
	ParseFromMemory(dentdata, entdatasize);

	while(ParseEntity())
	{
	}
	return num_entities;
}

char *ValueForKey(entity_t *ent, char *key)
{
	epair_t	*ep;
	
	for (ep=ent->epairs ; ep ; ep=ep->next)
	{
		if(!strcmp (ep->key, key) )
			return ep->value;
	}

	return NULL;
}

vec_t FloatForKey(entity_t *ent, char *key)
{
	char	*k;
	
	k = ValueForKey (ent, key);
	if(!k)
		return 0.0f;

	return atof(k);
}

int IntForKey(entity_t *ent, char *key)
{
	char	*k;
	
	k = ValueForKey (ent, key);
	if(!k)
		return 0;

	return atoi(k);
}

void GetVectorForKey(entity_t *ent, char *key, vec3_t vec)
{
	char	*k;
	double	v1, v2, v3;

	k = ValueForKey (ent, key);
	if(!k)
	{
		vec[0] = 0.0f;
		vec[1] = 0.0f;
		vec[2] = 0.0f;
		return;
	}
	/* scanf into doubles, then assign, so it is vec_t size independent */
	v1 = v2 = v3 = 0;
	sscanf (k, "%lf %lf %lf", &v1, &v2, &v3);
	vec[0] = (float)v1;
	vec[1] = (float)v2;
	vec[2] = (float)v3;
}

int FindNextEntityClass(int e, char *name)
{
	int		i;
	char	*n;
	
	e++;
	for (i=e ; i<num_entities ; i++)
	{
		n = ValueForKey (&entities[i], "classname");
		if (!strcmp (n, name))
			return i;
	}
	
	return 0;
}

entity_t	*GetEntity(int e)
{
	return &entities[e];
}

⌨️ 快捷键说明

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