quakeforge/tools/Forge/Bundles/MapEdit/EntityClass.m
Bill Currie d23300d58b Pass .m files through indent.
The result isn't perfect, but it cleans up the whitespace and makes the
code more consistent with the rest of the project.
2010-11-28 15:31:31 +09:00

274 lines
4.7 KiB
Objective-C

#include <dirent.h>
#include "QF/dstring.h"
#include "QF/quakeio.h"
#include "QF/script.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "EntityClass.h"
@implementation EntityClass
static int
parse_vector (script_t * script, vec3_t vec)
{
int r;
if (!Script_GetToken (script, 0))
return 0;
if (strcmp (script->token->str, "("))
return 0;
r = sscanf (script->p, "%f %f %f)", &vec[0], &vec[1], &vec[2]);
if (r != 3)
return 0;
while (strcmp (script->token->str, ")")) {
if (!Script_GetToken (script, 0))
return 0;
}
return 1;
}
// the classname, color triple, and bounding box are parsed out of comments
// A ? size means take the exact brush size.
//
// /*QUAKED <classname> (0 0 0) ?
// /*QUAKED <classname> (0 0 0) (-8 -8 -8) (8 8 8)
//
// Flag names can follow the size description:
//
// /*QUAKED func_door (0 .5 .8) ? START_OPEN STONE_SOUND DOOR_DONT_LINK GOLD_KEY SILVER_KEY
-initFromText:(const char *)
text source:(const char *) filename
{
const char *t;
size_t len;
int i;
script_t *script;
[super init];
text += strlen ("/*QUAKED ");
script = Script_New ();
Script_Start (script, filename, text);
// grab the name
if (!Script_GetToken (script, 0))
return 0;
if (!strcmp (script->token->str, "*/"))
return 0;
name = strdup (script->token->str);
// grab the color
if (!parse_vector (script, color))
return 0;
// get the size
if (!strcmp (script->token->str, "(")) {
Script_UngetToken (script);
if (!parse_vector (script, mins))
return 0;
if (!parse_vector (script, maxs))
return 0;
esize = esize_fixed;
} else if (!strcmp (script->token->str, "?")) {
// use the brushes
esize = esize_model;
} else {
return 0;
}
// get the flags
// any remaining words on the line are parm flags
for (i = 0; i < MAX_FLAGS; i++) {
if (!Script_TokenAvailable (script, 0))
break;
Script_GetToken (script, 0);
flagnames[i] = strdup (script->token->str);
}
while (Script_TokenAvailable (script, 0))
Script_GetToken (script, 0);
// find the length until close comment
for (t = script->p; t[0] && !(t[0] == '*' && t[1] == '/'); t++);
// copy the comment block out
len = t - text;
comments = malloc (len + 1);
memcpy (comments, text, len);
comments[len] = 0;
return self;
}
-(esize_t) esize
{
return esize;
}
-(char *) classname
{
return name;
}
-(float *) mins
{
return mins;
}
-(float *) maxs
{
return maxs;
}
-(float *) drawColor
{
return color;
}
-(char *) comments
{
return comments;
}
-(char *) flagName:(unsigned) flagnum
{
if (flagnum >= MAX_FLAGS)
Sys_Error ("EntityClass flagName: bad number");
return flagnames[flagnum];
}
@end
//===========================================================================
@implementation EntityClassList
/*
=================
insertEC:
=================
*/
- (void) insertEC:ec
{
char *name;
int i;
name =[ec classname];
for (i = 0; i <[self count]; i++) {
if (strcasecmp (name,[[self objectAtIndex:i] classname]) < 0) {
[self insertObject: ec atIndex:i];
return;
}
}
[self addObject:ec];
}
/*
=================
scanFile
=================
*/
-(void) scanFile:(char *) filename
{
int size, line;
char *data;
id cl;
int i;
char path[1024];
QFile *file;
sprintf (path, "%s/%s", source_path, filename);
file = Qopen (path, "rt");
if (!file)
return;
size = Qfilesize (file);
data = malloc (size + 1);
size = Qread (file, data, size);
data[size] = 0;
Qclose (file);
line = 1;
for (i = 0; i < size; i++) {
if (!strncmp (data + i, "/*QUAKED", 8)) {
cl =[[EntityClass alloc] initFromText:(data + i)
source:va ("%s:%d", filename, line)];
if (cl)
[self insertEC:cl];
} else if (data[i] == '\n') {
line++;
}
}
free (data);
}
/*
=================
scanDirectory
=================
*/
-(void) scanDirectory
{
int count, i;
struct dirent **namelist, *ent;
[self removeAllObjects];
count = scandir (source_path, &namelist, NULL, NULL);
for (i = 0; i < count; i++) {
int len;
ent = namelist[i];
len = strlen (ent->d_name);
if (len <= 3)
continue;
if (!strcmp (ent->d_name + len - 3, ".qc"))
[self scanFile:ent->d_name];
}
}
id entity_classes_i;
-initForSourceDirectory:(char *) path
{
[super init];
source_path = path;
[self scanDirectory];
entity_classes_i = self;
nullclass =[[EntityClass alloc]
initFromText: "/*QUAKED UNKNOWN_CLASS (0 0.5 0) ?*/" source:va ("%s:%d", __FILE__,
__LINE__ -
1)];
return self;
}
-(id) classForName:(char *) name
{
int i;
id o;
for (i = 0; i <[self count]; i++) {
o =[self objectAtIndex:i];
if (!strcmp (name,[o classname]))
return o;
}
return nullclass;
}
@end