change includes to use new csr base address
[mw/milkymist.git] / software / demo / renderer.c
1 /*
2  * Milkymist VJ SoC (Software)
3  * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, version 3 of the License.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <math.h>
21 #include <system.h>
22
23 #include <hal/pfpu.h>
24 #include <hal/vga.h>
25
26 #include "eval.h"
27 #include "apipe.h"
28 #include "renderer.h"
29
30 int renderer_on;
31
32 int renderer_hmeshlast;
33 int renderer_vmeshlast;
34 int renderer_texsize;
35
36 void renderer_init()
37 {
38         renderer_on = 0;
39         renderer_hmeshlast = 32;
40         renderer_vmeshlast = 32;
41         renderer_texsize = 512;
42         printf("RDR: renderer ready (mesh:%dx%d, texsize:%d)\n", renderer_hmeshlast, renderer_vmeshlast, renderer_texsize);
43 }
44
45 static int linenr;
46
47 static int process_equation(char *equation, int per_vertex)
48 {
49         char *c, *c2;
50
51         c = strchr(equation, '=');
52         if(!c) {
53                 printf("RDR: error l.%d: malformed equation (%s)\n", linenr, equation);
54                 return 0;
55         }
56         *c = 0;
57
58         if(*equation == 0) {
59                 printf("RDR: error l.%d: missing lvalue\n", linenr);
60                 return 0;
61         }
62         c2 = c - 1;
63         while((c2 > equation) && (*c2 == ' ')) *c2-- = 0;
64         
65         c++;
66         while(*c == ' ') c++;
67
68         if(*equation == 0) {
69                 printf("RDR: error l.%d: missing lvalue\n", linenr);
70                 return 0;
71         }
72         if(*c == 0) {
73                 printf("RDR: error l.%d: missing rvalue\n", linenr);
74                 return 0;
75         }
76
77         if(per_vertex)
78                 return eval_add_per_vertex(linenr, equation, c);
79         else
80                 return eval_add_per_frame(linenr, equation, c);
81 }
82
83 static int process_equations(char *equations, int per_vertex)
84 {
85         char *c;
86
87         while(*equations) {
88                 c = strchr(equations, ';');
89                 if(!c)
90                         return process_equation(equations, per_vertex);
91                 *c = 0;
92                 if(!process_equation(equations, per_vertex)) return 0;
93                 equations = c + 1;
94         }
95         return 1;
96 }
97
98 static int process_top_assign(char *left, char *right)
99 {
100         int pfv;
101         
102         while(*right == ' ') right++;
103         if(*right == 0) return 1;
104
105         pfv = eval_pfv_from_name(left);
106         if(pfv >= 0) {
107                 /* patch initial condition or global parameter */
108                 eval_set_initial(pfv, atof(right));
109                 return 1;
110         }
111
112         if(strncmp(left, "per_frame_", 10) == 0)
113                 /* per-frame equation */
114                 return process_equations(right, 0);
115
116         if((strncmp(left, "per_vertex_", 11) == 0) || (strncmp(left, "per_pixel_", 10) == 0))
117                 /* per-vertex equation */
118                 return process_equations(right, 1);
119
120         printf("RDR: warning l.%d: ignoring unknown parameter %s\n", linenr, left);
121         
122         return 1;
123 }
124
125 static int process_line(char *line)
126 {
127         char *c;
128         
129         while(*line == ' ') line++;
130         if(*line == 0) return 1;
131         if(*line == '[') return 1;
132
133         c = strstr(line, "//");
134         if(c) *c = 0;
135         
136         c = line + strlen(line) - 1;
137         while((c >= line) && (*c == ' ')) *c-- = 0;
138         if(*line == 0) return 1;
139
140         c = strchr(line, '=');
141         if(!c) {
142                 printf("RDR: error l.%d: '=' expected\n", linenr);
143                 return 0;
144         }
145         *c = 0;
146         return process_top_assign(line, c+1);
147 }
148
149 static int load_patch(char *patch_code)
150 {
151         char *eol;
152         
153         linenr = 0;
154         while(*patch_code) {
155                 linenr++;
156                 eol = strchr(patch_code, '\n');
157                 if(!eol)
158                         return process_line(patch_code);
159                 *eol = 0;
160                 if(*patch_code == 0) {
161                         patch_code = eol + 1;
162                         continue;
163                 }
164                 if(*(eol - 1) == '\r') *(eol - 1) = 0;
165                 if(!process_line(patch_code)) return 0;
166                 patch_code = eol + 1;
167         }
168         return 1;
169 }
170
171 int renderer_start(char *patch_code)
172 {
173         if(renderer_on) renderer_stop();
174         eval_init();
175         if(!load_patch(patch_code)) return 0;
176         if(!eval_schedule()) return 0;
177         apipe_start();
178         renderer_on = 1;
179         printf("RDR: started\n");
180         return 1;
181 }
182
183 void renderer_istart()
184 {
185         if(renderer_on) renderer_stop();
186         eval_init();
187         linenr = 0;
188 }
189
190 int renderer_iinput(char *line)
191 {
192         linenr++;
193         return process_line(line);
194 }
195
196 int renderer_idone()
197 {
198         if(!eval_schedule()) return 0;
199         apipe_start();
200         renderer_on = 1;
201         printf("RDR: started\n");
202         return 1;
203 }
204
205 void renderer_stop()
206 {
207         printf("RDR: stopped\n");
208         renderer_on = 0;
209         apipe_stop();
210 }