Modified: trunk/src/engine/material.c
===================================================================
--- trunk/src/engine/material.c	2008-07-19 12:03:49 UTC (rev 1190)
+++ trunk/src/engine/material.c	2008-07-24 11:17:14 UTC (rev 1191)
@@ -77,8 +77,25 @@
 
 #define Material_Offset(field) ( (Nsize) &( ((Material*)0)->field ) )
 
+static ParseField_Flag material_texture_flags[] =
+{
+	{ "DEFAULT", MATERIAL_DEFAULT_FLAGS },
+	{ "NO_MIPMAP", MATERIAL_FLAG_NO_MIPMAP },
+	{ "ALPHATEST", MATERIAL_FLAG_ALPHATEST },
+	{ NULL }
+};
+
 static ParseField material_texture_fields[] =
 {
+	// Theoretically, the flags can be changed for each texture component.
+	// eg: flags NO_MIPMAP
+	//     background SOMETHING
+	//     flags DEFAULT
+	//     color SOMETHING
+	// would use NO_MIPMAP for the background, and defaults for the color texture
+	{ "flags", PARSER_PARSETYPE_FLAG, Material_Offset(texture_flags), NULL,
+	  { .pt_flag = { material_texture_flags } } },
+	
 	{ "background", PARSER_PARSETYPE_RESOURCE, Material_Offset(texture_background), NULL,
 	  { .pt_resource = { RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP } } },
 	{ "color", PARSER_PARSETYPE_RESOURCE, Material_Offset(texture_color), NULL,
@@ -146,11 +163,21 @@
 };
 */
 
+NUint32 Material_GetResourceFlags(NUint32 def, NUint32 flags)
+{
+	if(flags & MATERIAL_FLAG_NO_MIPMAP)
+		def &= ~RESOURCEFLAG_MIPMAP;
+	// add others if needed...
+	
+	return def;
+}
+
 static void Material_Load(NUint32 resourceindex)
 {
 	char *filename, *text;
 	ResourceEntry *r;
 	Material *material;
+	NUint32 flags;
 
 	r = Resource_SharedCode_Load(RESOURCETYPE_MATERIAL, resourceindex, Material_Unload);
 	if(!r)
@@ -177,6 +204,8 @@
 	material->offsetmapping_bias = 0;
 	material->splatmap_scale = 1;
 
+	material->texture_flags = MATERIAL_DEFAULT_FLAGS;
+
 	text = File_LoadFile(filename, NULL);
 	if(!text)
 	{
@@ -188,27 +217,30 @@
 	{
 		Shell_Parser parser;
 		Shell_Parser_Init(&parser, text, NULL);
+		Parser_Resource_SetData(material_texture_fields, (void*)material);
 		Parser_Parse_Fields(&parser, filename, material, material_fields, 0);
+		Parser_Resource_SetData(material_texture_fields, NULL);
 		Shell_Parser_Destroy(&parser);
 	}
 
 	// if some textures are missing, load default
+	flags = Material_GetResourceFlags(RESOURCEFLAG_MIPMAP, material->texture_flags);
 	if (!material->texture_color)
 	{
 		Console_Printf("^6Failed to load material \"%s\"\n", r->name);
-		material->texture_color = Texture_FindResource("engine/default.tga", true, RESOURCEFLAG_MIPMAP, 0);
+		material->texture_color = Texture_FindResource("engine/default.tga", true, flags, 0);
 	}
 	if (!material->texture_normal)
-		material->texture_normal = Texture_FindResource("engine/default_norm.tga", true, RESOURCEFLAG_MIPMAP, 0);
+		material->texture_normal = Texture_FindResource("engine/default_norm.tga", true, flags, 0);
 	if (!material->texture_gloss)
 	{
 		material->specularintensity = 0;
-		material->texture_gloss = Texture_FindResource("engine/default_gloss.tga", true, RESOURCEFLAG_MIPMAP, 0);
+		material->texture_gloss = Texture_FindResource("engine/default_gloss.tga", true, flags, 0);
 	}
 	if (!material->texture_glow)
 	{
 		material->glowintensity = 0;
-		material->texture_glow = Texture_FindResource("engine/default_glow.tga", true, RESOURCEFLAG_MIPMAP, 0);
+		material->texture_glow = Texture_FindResource("engine/default_glow.tga", true, flags, 0);
 	}
 	if (!material->texture_background)
 		material->texture_background = 0;

Modified: trunk/src/engine/material.h
===================================================================
--- trunk/src/engine/material.h	2008-07-19 12:03:49 UTC (rev 1190)
+++ trunk/src/engine/material.h	2008-07-24 11:17:14 UTC (rev 1191)
@@ -2,7 +2,11 @@
 #ifndef MATERIAL_H
 #define MATERIAL_H
 
+#define MATERIAL_FLAG_NO_MIPMAP (1<<0)
+#define MATERIAL_FLAG_ALPHATEST (1<<1)
 
+#define MATERIAL_DEFAULT_FLAGS (0)
+
 typedef struct Material
 {
 	NUint32 texture_background;
@@ -19,6 +23,7 @@
 	NUint32 texture_splat_b_side_color;
 	NUint32 texture_splat_a_top_color;
 	NUint32 texture_splat_a_side_color;
+	NUint32 texture_flags;
 	Nfloat specularpower;
 	Nfloat ambientintensity;
 	Nfloat diffuseintensity;
@@ -32,6 +37,7 @@
 
 NUint32 Material_FindResource(const char *name, Nbool preload);
 Material *Material_GetData(NUint32 resourceindex);
+NUint32 Material_GetResourceFlags(NUint32 def, NUint32 flags);
 
 #endif
 

Modified: trunk/src/engine/parser.c
===================================================================
--- trunk/src/engine/parser.c	2008-07-19 12:03:49 UTC (rev 1190)
+++ trunk/src/engine/parser.c	2008-07-24 11:17:14 UTC (rev 1191)
@@ -2,6 +2,7 @@
 #include "shell.h"
 #include "parser.h"
 #include "texture.h"
+#include "material.h"
 
 /**
  * @brief Figure out if the given text is a pattern by checking for wildcards
@@ -138,6 +139,100 @@
 						else if(data)
 							( (NSint32*)( (char*)data + field->offset ) )[0] = atol(parser->token);
 						break;
+
+					case PARSER_PARSETYPE_FLAG:
+						// would it make sense to also support XOR?
+						// like, DEFAULT ^ SOMETHING to use default without `SOMETHING`?
+						while(1)
+						{
+							Shell_Parser_Parse(parser);
+							
+							if(parser->type == SHELL_TOKENTYPE_SYMBOL)
+							{
+								ParseField_Flag *flag;
+								for(flag = field->pt_flag.list; flag->name; ++flag)
+								{
+									if(String_ICompare(flag->name, parser->token) == 0)
+										break;
+								}
+								if(!flag->name)
+									Console_Printf("%s: %i: Error: Unknown flag \"%s\" for field \"%s\".\n",
+												   filename, parser->line, parser->token, field->name);
+								else
+									( (NUint32*)( (char*)data + field->offset ) )[0] |= flag->value;
+							}
+							else if(parser->type == SHELL_TOKENTYPE_VALUE)
+							{
+								// For completeness, allow integer values too.
+								( (NUint32*)( (char*)data + field->offset ) )[0] |= atol(parser->token);
+							}
+							else
+								Console_Printf("%s: %i: Error: Flagname or integer value expected for \"%s\" field.\n",
+											   filename, parser->line, field->name);
+
+							if(*parser->currentChar == '|')
+							{
+								// OR found
+								Shell_Parser_Parse(parser);
+							} else
+								break;
+						}
+						break;
+						
+					case PARSER_PARSETYPE_CONST_INT32:
+						Shell_Parser_Parse(parser);
+							
+						if(parser->type == SHELL_TOKENTYPE_SYMBOL)
+						{
+							ParseField_Constant *c;
+							for(c = field->pt_const.list; c->name; ++c)
+							{
+								if(String_ICompare(c->name, parser->token) == 0)
+									break;
+							}
+							if(!c->name)
+								Console_Printf("%s: %i: Error: Unknown constant \"%s\" for field \"%s\".\n",
+											   filename, parser->line, parser->token, field->name);
+							else
+								( (NSint32*)( (char*)data + field->offset ) )[0] = c->constant.sint;
+						}
+						else if(parser->type == SHELL_TOKENTYPE_VALUE)
+						{
+							// For completeness, allow integer values too.
+							( (NSint32*)( (char*)data + field->offset ) )[0] = atol(parser->token);
+						}
+						else
+							Console_Printf("%s: %i: Error: Constant or integer value expected for \"%s\" field.\n",
+										   filename, parser->line, field->name);
+						break;
+						
+					case PARSER_PARSETYPE_CONST_FLOAT:
+						Shell_Parser_Parse(parser);
+							
+						if(parser->type == SHELL_TOKENTYPE_SYMBOL)
+						{
+							ParseField_Constant *c;
+							for(c = field->pt_const.list; c->name; ++c)
+							{
+								if(String_ICompare(c->name, parser->token) == 0)
+									break;
+							}
+							if(!c->name)
+								Console_Printf("%s: %i: Error: Unknown constant \"%s\" for field \"%s\".\n",
+											   filename, parser->line, parser->token, field->name);
+							else
+								( (Nfloat*)( (char*)data + field->offset ) )[0] = c->constant.value;
+						}
+						else if(parser->type == SHELL_TOKENTYPE_VALUE)
+						{
+							// For completeness, allow integer values too.
+							( (Nfloat*)( (char*)data + field->offset ) )[0] = atof(parser->token);
+						}
+						else
+							Console_Printf("%s: %i: Error: Constant or integer value expected for \"%s\" field.\n",
+										   filename, parser->line, field->name);
+						break;
+						
 					case PARSER_PARSETYPE_STRING:
 						Shell_Parser_Parse(parser);
 						if(parser->type != SHELL_TOKENTYPE_STRING && parser->type != SHELL_TOKENTYPE_SYMBOL)
@@ -154,6 +249,7 @@
 							strcpy(*str, parser->token);
 						}
 						break;
+						
 					case PARSER_PARSETYPE_RESOURCE:
 						Shell_Parser_Parse(parser);
 						if(parser->type != SHELL_TOKENTYPE_STRING && parser->type != SHELL_TOKENTYPE_SYMBOL)
@@ -169,7 +265,12 @@
 							{
 								char *name;
 								Nfloat bump = 0.0;
+								void *data = field->pt_resource.data;
+								NUint32 flags = field->pt_resource.flags;
+								
 								name = parser->token;
+								if(field->pt_resource.data)
+									flags = Material_GetResourceFlags(flags, ((Material*)data)->texture_flags);
 
 								if(field->pt_resource.flags & RESOURCEFLAG_BUMPMAPASNORMALMAP)
 								{
@@ -183,11 +284,11 @@
 									else
 										bump = atof(parser->token);
 									( (NUint32*)( (char*)data + field->offset ) )[0] =
-										Texture_FindResource(name, true, field->pt_resource.flags, bump);
+										Texture_FindResource(name, true, flags, bump);
 									String_Free(&name);
 								} else {
 									( (NUint32*)( (char*)data + field->offset ) )[0] =
-										Texture_FindResource(name, true, field->pt_resource.flags, bump);
+										Texture_FindResource(name, true, flags, bump);
 								}
 								break;
 							}
@@ -199,19 +300,22 @@
 							};
 						}
 						break;
+						
 					case PARSER_PARSETYPE_SPECIFIC:
 						if(!data) // let it throw an error
 							Parser_Parse_Fields(parser, filename, NULL, field->subfields, -1);
 						else
 							Parser_Parse_Fields(parser, filename, ( (char*)data + field->offset ), field->subfields, -1);
 						break;
+						
 					case PARSER_PARSETYPE_SUBFIELDS:
 						Parser_Parse_Fields(parser, filename, ( (char*)data + field->offset ), field->subfields, level+1);
 						break;
+						
 					case PARSER_PARSETYPE_CALLBACK:
 						field->pt_callback.callback(parser, filename, &data, &field_list);
 						break;
-						// TODO: rest of the PT_ types
+						
 					default:
 						Console_Printf("%s:%i: Engine error, invalid field type %i\n", filename, parser->line, field->type);
 						break;
@@ -226,3 +330,12 @@
 	} while(parser->type != SHELL_TOKENTYPE_EOF && level >= 0);
 }
 
+void Parser_Resource_SetData(ParseField *field_list, void *data)
+{
+	ParseField *field;
+	for(field = field_list; field->name; ++field)
+	{
+		if(field->type == PARSER_PARSETYPE_RESOURCE)
+			field->pt_resource.data = data;
+	}
+}

Modified: trunk/src/engine/parser.h
===================================================================
--- trunk/src/engine/parser.h	2008-07-19 12:03:49 UTC (rev 1190)
+++ trunk/src/engine/parser.h	2008-07-24 11:17:14 UTC (rev 1191)
@@ -14,12 +14,14 @@
 	PARSER_PARSETYPE_RESOURCE, /// A resource by name
 	PARSER_PARSETYPE_FLOAT, /// A value stored as Nfloat
 	PARSER_PARSETYPE_INT32, /// A value stored as NSint32
+	
+	PARSER_PARSETYPE_CONST_FLOAT, /// A Nfloat constant
+	PARSER_PARSETYPE_CONST_INT32, /// A NSint32 constant
 
 	PARSER_PARSETYPE_STRING, /// String that needs allocation
 	PARSER_PARSETYPE_STRARR, /// String array of fixed length
 
 	PARSER_PARSETYPE_FLAG, /// a bitflag, either a number or a flag name
-	PARSER_PARSETYPE_FLAG_MATCH, /// all matching bitflags or a number
 
 	// These end when the field is unknown and go back to the level before
 	PARSER_PARSETYPE_SUBFIELDS, /// different subsection at an offset
@@ -35,6 +37,21 @@
 	PARSER_NUM_PARSETYPES,
 } ParseType;
 
+typedef struct ParseField_Flag
+{
+	const char *name;
+	const NUint32 value;
+} ParseField_Flag;
+
+typedef struct ParseField_Constant
+{
+	const char *name;
+	struct {
+		const Nfloat value;
+		const NSint32 sint;
+	} constant;
+} ParseField_Constant;
+
 /**
  * The ParseField structure Used to define the layout of a file
  */
@@ -53,10 +70,17 @@
 		struct {
 			ResourceType type;
 			NUint32 flags;
+			void *data;
 		} pt_resource;
 		struct {
 			Mem_Zone *memzone;
 		} pt_string;
+		struct {
+			ParseField_Flag *list; // A list terminated with a NULL `name`
+		} pt_flag;
+		struct {
+			ParseField_Constant *list; // A list terminated with a NULL `name`
+		} pt_const;
 	};
 
 } ParseField;
@@ -64,5 +88,6 @@
 void Parser_Parse_Fields(Shell_Parser *parser, char *filename, void *data, ParseField *field_list, int level);
 Nbool Parser_Match_Pattern(const char *in, const char *pattern, Nbool caseinsensitive);
 Nbool Parser_IsPattern(const char *in);
+void Parser_Resource_SetData(ParseField *fields, void *data);
 
 #endif

Modified: trunk/src/engine/r_dynglfuncs.h
===================================================================
--- trunk/src/engine/r_dynglfuncs.h	2008-07-19 12:03:49 UTC (rev 1190)
+++ trunk/src/engine/r_dynglfuncs.h	2008-07-24 11:17:14 UTC (rev 1191)
@@ -48,6 +48,7 @@
 DYNGL_NEED (void, glBegin, (GLenum mode), (mode), 1, "GL")
 DYNGL_NEED (void, glBindTexture, (GLenum target, GLuint texture), (target, texture), 1, "GL")
 DYNGL_NEED (void, glBlendFunc, (GLenum sfactor, GLenum dfactor), (sfactor, dfactor), 1, "GL")
+DYNGL_NEED (void, glAlphaFunc, (GLenum func, GLclampf ref), (func, ref), 1, "GL")
 DYNGL_NEED (void, glClear, (GLbitfield mask), (mask), 1, "GL")
 DYNGL_NEED (void, glColor4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha), (red, green, blue, alpha), 1, "GL")
 DYNGL_NEED (void, glColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer), (size, type, stride, pointer), 1, "GL")

Modified: trunk/src/engine/r_main.c
===================================================================
--- trunk/src/engine/r_main.c	2008-07-19 12:03:49 UTC (rev 1190)
+++ trunk/src/engine/r_main.c	2008-07-24 11:17:14 UTC (rev 1191)
@@ -791,6 +791,19 @@
 	R_CheckError();
 }
 
+void R_SetAlphaFunc(NUint func, Nfloat ref)
+{
+	R_CheckError();
+	if(func == GL_ALWAYS)
+		qglDisable(GL_ALPHA_TEST);
+	else
+	{
+		qglEnable(GL_ALPHA_TEST);
+		qglAlphaFunc(func, ref);
+	}
+	R_CheckError();
+}
+
 void R_SetDepthTest(Nbool enable)
 {
 	R_CheckError();

Modified: trunk/src/engine/r_main.h
===================================================================
--- trunk/src/engine/r_main.h	2008-07-19 12:03:49 UTC (rev 1190)
+++ trunk/src/engine/r_main.h	2008-07-24 11:17:14 UTC (rev 1191)
@@ -417,6 +417,7 @@
 void R_SetTextureCubeMap(NUint32 texunit, NUint32 resourceindex);
 void R_SetTextureMatrix(NUint32 texunit, matrix4x4_t *matrix);
 void R_SetBlendFunc(NUint b1, NUint b2);
+void R_SetAlphaFunc(NUint func, Nfloat ref);
 void R_SetDepthTest(Nbool enable);
 void R_SetDepthMask(Nbool enable);
 

