| 
					
				 | 
			
			
				@@ -18,7 +18,10 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "gl-subsystem.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "gl-shaderparser.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static void gl_write_type_n(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void gl_write_function_contents(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct cf_token **p_token, const char *end); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static bool gl_write_type_n(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const char *type, size_t len) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (astrcmp_n(type, "float2", len) == 0) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -40,19 +43,22 @@ static void gl_write_type_n(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	else if (astrcmp_n(type, "texture_cube", len) == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		dstr_cat(&glsp->gl_string, "samplerCube"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		dstr_ncat(&glsp->gl_string, type, len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static inline void gl_write_type(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const char *type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	gl_write_type_n(glsp, type, strlen(type)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!gl_write_type_n(glsp, type, strlen(type))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static inline void gl_write_type_token(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline bool gl_write_type_token(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		struct cf_token *token) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	gl_write_type_n(glsp, token->str.array, token->str.len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return gl_write_type_n(glsp, token->str.array, token->str.len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void gl_write_var(struct gl_shader_parser *glsp, struct shader_var *var) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -65,7 +71,6 @@ static void gl_write_var(struct gl_shader_parser *glsp, struct shader_var *var) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	gl_write_type(glsp, var->type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	dstr_cat(&glsp->gl_string, " "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	dstr_cat(&glsp->gl_string, var->name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	dstr_cat(&glsp->gl_string, ";\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static inline void gl_write_params(struct gl_shader_parser *glsp) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -74,6 +79,7 @@ static inline void gl_write_params(struct gl_shader_parser *glsp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	for (i = 0; i < glsp->parser.params.num; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		struct shader_var *var = glsp->parser.params.array+i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gl_write_var(glsp, var); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, ";\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	dstr_cat(&glsp->gl_string, "\n"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -85,7 +91,7 @@ static void gl_write_storage_var(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* unwraps a structure that's used for input/output */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void gl_unwrap_storage_struct(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		struct shader_struct *st, const char *storage, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct shader_struct *st, const char *name, const char *storage, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const char *prefix) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	struct dstr prefix_str; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -94,7 +100,7 @@ static void gl_unwrap_storage_struct(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	dstr_init(&prefix_str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (prefix) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		dstr_copy(&prefix_str, prefix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	dstr_cat(&prefix_str, st->name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&prefix_str, name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	dstr_cat(&prefix_str, "_"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	for (i = 0; i < st->vars.num; i++) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -112,7 +118,7 @@ static void gl_write_storage_var(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			var->type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (st) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		gl_unwrap_storage_struct(glsp, st, storage, prefix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gl_unwrap_storage_struct(glsp, st, var->name, storage, prefix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (storage) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			dstr_cat(&glsp->gl_string, storage); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -132,25 +138,23 @@ static inline void gl_write_inputs(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		struct shader_func *main) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	size_t i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	for (i = 0; i < main->params.num; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		struct shader_var *var = main->params.array+i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		gl_write_storage_var(glsp, var, "in", "in_"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (i = 0; i < main->params.num; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gl_write_storage_var(glsp, main->params.array+i, "in", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				"inputval_"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, "\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void gl_write_outputs(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		struct shader_func *main) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	struct shader_var var; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	shader_var_init(&var); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var.type = bstrdup(main->return_type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	var.name = bstrdup("return_val"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (main->return_mapping) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var.mapping = bstrdup(main->return_mapping); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct shader_var var = {0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	var.type = main->return_type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	var.name = "outputval"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (main->mapping) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var.mapping = main->mapping; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	gl_write_storage_var(glsp, &var, "out", "out_"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	shader_var_free(&var); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	gl_write_storage_var(glsp, &var, "out", NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, "\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void gl_write_struct(struct gl_shader_parser *glsp, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -166,6 +170,7 @@ static void gl_write_struct(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		dstr_cat(&glsp->gl_string, "\t"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		gl_write_var(glsp, var); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, ";\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	dstr_cat(&glsp->gl_string, "};\n\n"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -203,8 +208,272 @@ static inline void gl_write_structs(struct gl_shader_parser *glsp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  *   All else can be left as-is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static void gl_write_functions(struct gl_shader_parser *glsp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline bool gl_write_texture_call(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct shader_var *var, const char *call) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct cf_parser *cfp = &glsp->parser.cfp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!go_to_token(cfp, ",", NULL)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, call); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, "("); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, var->name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, ", "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* processes texture.Sample(sampler, texcoord) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static bool gl_write_texture_code(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct cf_token **p_token, struct shader_var *var) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct cf_parser *cfp = &glsp->parser.cfp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	bool written = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	cfp->cur_token = *p_token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!next_token(cfp))    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!token_is(cfp, ".")) return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!next_token(cfp))    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (token_is(cfp, "Sample")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		written = gl_write_texture_call(glsp, var, "texture"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	else if (token_is(cfp, "SampleBias")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		written = gl_write_texture_call(glsp, var, "texture"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	else if (token_is(cfp, "SampleGrad")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		written = gl_write_texture_call(glsp, var, "textureGrad"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	else if (token_is(cfp, "SampleLevel")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		written = gl_write_texture_call(glsp, var, "textureLod"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!written) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!next_token(cfp)) return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	gl_write_function_contents(glsp, &cfp->cur_token, ")"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, ")"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*p_token = cfp->cur_token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline struct shader_var *sp_getparam(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct cf_token *token) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	size_t i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (i = 0; i < glsp->parser.params.num; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct shader_var *param = glsp->parser.params.array+i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (strref_cmp(&token->str, param->name) == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return param; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static bool gl_write_intrinsic(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct cf_token **p_token) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct cf_token *token = *p_token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	bool written = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (strref_cmp(&token->str, "atan2") == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, "atan2"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else if (strref_cmp(&token->str, "ddx") == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, "dFdx"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else if (strref_cmp(&token->str, "ddy") == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, "dFdy"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else if (strref_cmp(&token->str, "frac") == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, "fract"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else if (strref_cmp(&token->str, "lerp") == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, "mix"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else if (strref_cmp(&token->str, "rsqrt") == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, "inversesqrt"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct shader_var *var = sp_getparam(glsp, token); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (var && astrcmp_n(var->type, "texture", 7) == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			written = gl_write_texture_code(glsp, &token, var); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			written = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (written) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		*p_token = token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return written; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void gl_write_function_contents(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct cf_token **p_token, const char *end) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct cf_token *token = *p_token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat_strref(&glsp->gl_string, &token->str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	while (token->type != CFTOKEN_NONE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		token++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (end && strref_cmp(&token->str, end) == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (token->type == CFTOKEN_NAME) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (!gl_write_type_token(glsp, token) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			    !gl_write_intrinsic(glsp, &token)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				dstr_cat_strref(&glsp->gl_string, &token->str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else if (token->type == CFTOKEN_OTHER) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (*token->str.array == '{') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				gl_write_function_contents(glsp, &token, "}"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			else if (*token->str.array == '(') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				gl_write_function_contents(glsp, &token, ")"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			dstr_cat_strref(&glsp->gl_string, &token->str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			dstr_cat_strref(&glsp->gl_string, &token->str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*p_token = token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void gl_write_function(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct shader_func *func) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	size_t i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct cf_token *token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	gl_write_type(glsp, func->return_type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, " "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (strcmp(func->name, "main") == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, "__main__"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, func->name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, "("); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (i = 0; i < func->params.num; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct shader_var *param = func->params.array+i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (i > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			dstr_cat(&glsp->gl_string, ", "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gl_write_var(glsp, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, ")\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	token = func->start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	gl_write_function_contents(glsp, &token, "}"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, "}\n\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void gl_write_functions(struct gl_shader_parser *glsp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	size_t i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (i = 0; i < glsp->parser.funcs.num; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct shader_func *func = glsp->parser.funcs.array+i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gl_write_function(glsp, func); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void gl_write_main_storage_var(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct shader_var *var, const char *dst, const char *src, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		bool input) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct shader_struct *st; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct dstr dst_copy = {0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	char ch_left  = input ? '.' : '_'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	char ch_right = input ? '_' : '.'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (dst) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_copy(&dst_copy, dst); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat_ch(&dst_copy, ch_left); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_copy(&dst_copy, "\t"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&dst_copy, var->name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	st = shader_parser_getstruct(&glsp->parser, var->type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (st) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct dstr src_copy = {0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		size_t i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (src) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			dstr_copy(&src_copy, src); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&src_copy, var->name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat_ch(&src_copy, ch_right); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for (i = 0; i < st->vars.num; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			struct shader_var *var = st->vars.array+i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			gl_write_main_storage_var(glsp, var, dst_copy.array, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					src_copy.array, input); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_free(&src_copy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (!dstr_isempty(&dst_copy)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			dstr_cat_dstr(&glsp->gl_string, &dst_copy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, " = "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (src) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			dstr_cat(&glsp->gl_string, src); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, var->name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, ";\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_free(&dst_copy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void gl_write_main_storage_output(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		bool input, const char *type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct shader_var var = {0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (input) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var.name = "inputval"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var.type = (char*)type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gl_write_main_storage_var(glsp, &var, NULL, NULL, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var.name = "outputval"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var.type = (char*)type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gl_write_main_storage_var(glsp, &var, NULL, NULL, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void gl_write_main(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		struct shader_func *main) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	size_t i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, "void main(void)\n{\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (i = 0; i < main->params.num; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, "\t"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, main->params.array[i].type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, " "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, main->params.array[i].name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, "\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!main->mapping) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, "\t"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, main->return_type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, " outputval;\n\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* gl_write_main_storage(glsp, true, main->params.array[0].type); */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	gl_write_main_storage_var(glsp, main->params.array, NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			"inputval_", true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, "\n\toutputval = __main__("); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (i = 0; i < main->params.num; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			dstr_cat(&glsp->gl_string, ", "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, main->params.array[i].name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, ");\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!main->mapping) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dstr_cat(&glsp->gl_string, "\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gl_write_main_storage_output(glsp, false, main->return_type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dstr_cat(&glsp->gl_string, "}\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static bool gl_shader_buildstring(struct gl_shader_parser *glsp) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -221,7 +490,7 @@ static bool gl_shader_buildstring(struct gl_shader_parser *glsp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	gl_write_outputs(glsp, main); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	gl_write_structs(glsp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	gl_write_functions(glsp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	// gl_write_main(glsp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	gl_write_main(glsp, main); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -236,5 +505,8 @@ bool gl_shader_parse(struct gl_shader_parser *glsp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		bfree(str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (success) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		success = gl_shader_buildstring(glsp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return success; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |