Sfoglia il codice sorgente

update materials to use newest parser

Ivan Avdeev 6 anni fa
parent
commit
c0431f2b2a
3 ha cambiato i file con 101 aggiunte e 122 eliminazioni
  1. 98 118
      src/material.c
  2. 1 1
      src/render.c
  3. 2 3
      src/vmfparser.c

+ 98 - 118
src/material.c

@@ -10,137 +10,108 @@ typedef struct {
 	Stack *temp;
 	StringView shader;
 	struct Material *mat;
-	StringView key;
+	int depth;
 } MaterialContext;
 
-#if 0
-static const char * const ignore_params[] = {
-	"$surfaceprop", "$surfaceprop2", "$tooltexture",
-	"%tooltexture", "%keywords", "%compilewater", "%detailtype",
-	"%compilenolight", "%compilepassbullets",
-	"replace", /* TODO implement */
-	0
-};
-#endif
-
-#if 0
-static ParserCallbackResult materialReadShader(ParserState *state, StringView s);
-static ParserCallbackResult materialReadKeyOrSection(ParserState *state, StringView s);
-static ParserCallbackResult materialReadValue(ParserState *state, StringView s);
-static ParserCallbackResult materialEnd(ParserState *state, StringView s);
-
-static ParserCallbackResult materialOpenShader(ParserState *state, StringView s) {
-	MaterialContext *ctx = state->user_data;
-	ctx->shader = s;
+static VMFAction materialReadKeyValue(MaterialContext *ctx, const VMFKeyValue *kv) {
+	if (kv->value.length > 127)
+		return VMFAction_SemanticError;
 
-	state->callbacks.string = materialReadKeyOrSection;
-	state->callbacks.curlyOpen = parserError;
+	char value[128];
+	memcpy(value, kv->value.str, kv->value.length);
+	value[kv->value.length] = '\0';
 
-	return Parser_Continue;
+	if (strncasecmp("$basetexture", kv->key.str, kv->key.length) == 0) {
+		ctx->mat->base_texture[0] = textureGet(value, ctx->collection, ctx->temp);
+	} else if (strncasecmp("include", kv->key.str, kv->key.length) == 0) {
+		char *vmt = strstr(value, ".vmt");
+		if (vmt)
+			*vmt = '\0';
+		if (strstr(value, "materials/") == value)
+			*ctx->mat = *materialGet(value + 10, ctx->collection, ctx->temp);
+	}
+
+	return VMFAction_Continue;
 }
 
-static ParserCallbackResult materialReadShader(ParserState *state, StringView s) {
-	MaterialContext *ctx = state->user_data;
-	ctx->shader = s;
+static VMFAction materialParserCallback(VMFState *state, VMFEntryType entry, const VMFKeyValue *kv);
+static VMFAction materialShaderCallback(VMFState *state, VMFEntryType entry, const VMFKeyValue *kv);
+static VMFAction materialPatchCallback(VMFState *state, VMFEntryType entry, const VMFKeyValue *kv);
 
-	PRINTF("Material shader %.*s", PRI_SVV(ctx->shader));
+static VMFAction materialPatchCallback(VMFState *state, VMFEntryType entry, const VMFKeyValue *kv) {
+	//PRINTF("Entry %d (%.*s -> %.*s)", entry, PRI_SVV(kv->key), PRI_SVV(kv->value));
+	MaterialContext *ctx = state->user_data;
 
-	state->callbacks.string = parserError;
-	state->callbacks.curlyOpen = materialOpenShader;
-	return Parser_Continue;
-}
+	VMFAction retval = VMFAction_SemanticError;
+
+	switch (entry) {
+		case VMFEntryType_KeyValue:
+			retval = materialReadKeyValue(ctx, kv);
+			break;
+		case VMFEntryType_SectionOpen:
+			++ctx->depth;
+			retval = VMFAction_Continue;
+			break;
+		case VMFEntryType_SectionClose:
+			--ctx->depth;
+			retval = ctx->depth == 0 ? VMFAction_Exit : VMFAction_Continue;
+			break;
+	}
 
-static ParserCallbackResult materialReadKeyOrSection(ParserState *state, StringView s) {
-	MaterialContext *ctx = state->user_data;
-	ctx->key = s;
-	state->callbacks.string = materialReadValue;
-	state->callbacks.curlyClose = state->callbacks.curlyOpen = parserError;
-	return Parser_Continue;
+	return retval;
 }
 
-static ParserCallbackResult materialReadValue(ParserState *state, StringView s) {
+static VMFAction materialShaderCallback(VMFState *state, VMFEntryType entry, const VMFKeyValue *kv) {
+	//PRINTF("Entry %d (%.*s -> %.*s)", entry, PRI_SVV(kv->key), PRI_SVV(kv->value));
 	MaterialContext *ctx = state->user_data;
 
-	if (s.length > 127)
-		return Parser_Error;
-
-	char value[128];
-	memcpy(value, s.str, s.length);
-	value[s.length] = '\0';
-
-	if (strncasecmp("$basetexture", ctx->key.str, ctx->key.length) == 0) {
-		ctx->mat->base_texture[0] = textureGet(value, ctx->collection, ctx->temp);
-	} else if (strncasecmp("$basetexture2", ctx->key.str, ctx->key.length) == 0) {
-		ctx->mat->base_texture[1] = textureGet(value, ctx->collection, ctx->temp);
-	} else if (strncasecmp("$basetexturetransform", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$basetexturetransform2", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$detail", ctx->key.str, ctx->key.length) == 0) {
-		//output->detail = textureGet(ctx.value, ctx->collection, ctx->temp);
-	} else if (strncasecmp("$detailscale", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$detailblendfactor", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$detailblendmode", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$parallaxmap", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$parallaxmapscale", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$bumpmap", ctx->key.str, ctx->key.length) == 0) {
-		/* output->bump = textureGet(ctx.value, ctx->collection, ctx->temp); */
-	} else if (strncasecmp("$envmap", ctx->key.str, ctx->key.length) == 0) {
-		/* output->envmap = textureGet(ctx.value, ctx->collection, ctx->temp); */
-	} else if (strncasecmp("$fogenable", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$fogcolor", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$alphatest", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$translucent", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$envmapcontrast", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$envmapsaturation", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$envmaptint", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$normalmapalphaenvmapmask", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$envmapmask", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$nodiffusebumplighting", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$AlphaTestReference", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$basealphaenvmapmask", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$selfillum", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("$reflectivity", ctx->key.str, ctx->key.length) == 0) {
-	} else if (strncasecmp("include", ctx->key.str, ctx->key.length) == 0) {
-		char *vmt = strstr(value, ".vmt");
-		if (vmt)
-			*vmt = '\0';
-		if (strstr(value, "materials/") == value)
-			*ctx->mat = *materialGet(value + 10, ctx->collection, ctx->temp);
-	} else {
-		PRINTF("Material shader:%.*s, unknown param %.*s = %s",
-				ctx->shader.length, ctx->shader.str, ctx->key.length, ctx->key.str, value);
+	VMFAction retval = VMFAction_SemanticError;
+
+	switch (entry) {
+		case VMFEntryType_KeyValue:
+			// Ignore any nested settings for no
+			retval = (ctx->depth == 1) ? materialReadKeyValue(ctx, kv) : VMFAction_Continue;
+			break;
+		case VMFEntryType_SectionOpen:
+			++ctx->depth;
+			retval = VMFAction_Continue;
+			break;
+		case VMFEntryType_SectionClose:
+			--ctx->depth;
+			retval = ctx->depth == 0 ? VMFAction_Exit : VMFAction_Continue;
+			break;
 	}
 
-	state->callbacks.string = materialReadKeyOrSection;
-	state->callbacks.curlyClose = materialEnd;
-	state->callbacks.curlyOpen = parserError;
-	return Parser_Continue;
+	return retval;
 }
 
-static ParserCallbackResult materialEnd(ParserState *state, StringView s) {
-	(void)(s);
+static VMFAction materialParserCallback(VMFState *state, VMFEntryType entry, const VMFKeyValue *kv) {
+	//PRINTF("Entry %d (%.*s -> %.*s)", entry, PRI_SVV(kv->key), PRI_SVV(kv->value));
 	MaterialContext *ctx = state->user_data;
 
-	if (!ctx->mat->base_texture[0]) {
-		PRINTF("Material with ctx->shader %.*s doesn't have base texture", ctx->shader.length, ctx->shader.str);
-		ctx->mat->shader = MaterialShader_LightmappedAverageColor;
-		// HACK to notice these materials
-		ctx->mat->average_color = aVec3f(1.f, 0.f, 1.f);
-	} else {
-		ctx->mat->shader = MaterialShader_LightmappedGeneric;
-		ctx->mat->average_color = ctx->mat->base_texture[0]->avg_color;
+	VMFAction retval = VMFAction_SemanticError;
+
+	switch (entry) {
+		case VMFEntryType_KeyValue:
+			break;
+		case VMFEntryType_SectionOpen:
+			++ctx->depth;
+			if (strncasecmp("patch", kv->key.str, kv->key.length) == 0) {
+				state->callback = materialPatchCallback;
+			} else {
+				ctx->shader = kv->key;
+				state->callback = materialShaderCallback;
+			}
+			retval = VMFAction_Continue;
+			break;
+		case VMFEntryType_SectionClose:
+			break;
 	}
 
-	return Parser_Exit;
+	return retval;
 }
-#endif
 
 static int materialLoad(struct IFile *file, struct ICollection *coll, struct Material *output, struct Stack *tmp) {
-	(void)file;
-	(void)coll;
-	(void)output;
-	(void)tmp;
-	return 0;
-#if 0
 	char *buffer = stackAlloc(tmp, file->size);
 
 	if (!buffer) {
@@ -148,31 +119,40 @@ static int materialLoad(struct IFile *file, struct ICollection *coll, struct Mat
 		return 0;
 	}
 
-	if (file->size != file->read(file, 0, file->size, buffer)) return 0;
+	if (file->size != file->read(file, 0, file->size, buffer))
+		return 0;
 
 	MaterialContext ctx = {
 		.collection = coll,
 		.temp = tmp,
-		.mat = output
+		.mat = output,
+		.depth = 0,
 	};
 
-	ParserState parser = {
+	VMFState parser_state = {
 		.user_data = &ctx,
-		.callbacks = {
-			.curlyOpen = parserError,
-			.curlyClose = parserError,
-			.string = materialReadShader
-		}
+		.data = { .str = buffer, .length = file->size },
+		.callback = materialParserCallback
 	};
 
-	StringView buf_sv = { .str = buffer, .length = file->size };
+	const int success = VMFResult_Success == vmfParse(&parser_state);
+
+	if (success) {
+		if (!ctx.mat->base_texture[0]) {
+			PRINTF("Material with ctx.shader %.*s doesn't have base texture", ctx.shader.length, ctx.shader.str);
+			ctx.mat->shader = MaterialShader_LightmappedAverageColor;
+			// HACK to notice these materials
+			ctx.mat->average_color = aVec3f(1.f, 0.f, 1.f);
+		} else {
+			ctx.mat->shader = MaterialShader_LightmappedGeneric;
+			ctx.mat->average_color = ctx.mat->base_texture[0]->avg_color;
+		}
+	}
 
-	int success = ParseResult_Success == parserParse(&parser, buf_sv);
 
 	stackFreeUpToPosition(tmp, buffer);
 
 	return success;
-#endif
 }
 
 const struct Material *materialGet(const char *name, struct ICollection *collection, struct Stack *tmp) {

+ 1 - 1
src/render.c

@@ -723,5 +723,5 @@ void renderBegin() {
 }
 
 void renderEnd(const struct Camera *camera) {
-	if (0) renderSkybox(camera, r.closest_map.model);
+	renderSkybox(camera, r.closest_map.model);
 }

+ 2 - 3
src/vmfparser.c

@@ -85,8 +85,7 @@ exit:
 	if (error_message)
 		PRINTF("Parsing error \"%s\" @%d (%.*s)", error_message,
 				(int)(c - state->data.str), (int)(end - c < 32 ? end - c : 32), c);
-	else
-		PRINTF("Token %d, (%.*s)", token.type, PRI_SVV(token.string));
+	//else PRINTF("Token %d, (%.*s)", token.type, PRI_SVV(token.string));
 
 	state->data.str = c + 1;
 	state->data.length = end - c - 1;
@@ -119,7 +118,7 @@ VMFResult vmfParse(VMFState *state) {
 				action = state->callback(state, VMFEntryType_SectionOpen, &kv);
 				continue;
 			case VMFTokenType_Close:
-				action = state->callback(state, VMFEntryType_SectionClose, NULL);
+				action = state->callback(state, VMFEntryType_SectionClose, &kv);
 				continue;
 			case VMFTokenType_End:
 				return VMFResult_Success;