Use FPVM in demo firmware (unfinished, broken)
[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_hmeshlast;
31 int renderer_vmeshlast;
32 int renderer_texsize;
33
34 void renderer_init()
35 {
36         renderer_hmeshlast = 32;
37         renderer_vmeshlast = 32;
38         renderer_texsize = 512;
39         printf("RDR: renderer ready (mesh:%dx%d, texsize:%d)\n", renderer_hmeshlast, renderer_vmeshlast, renderer_texsize);
40 }
41
42 static unsigned int linenr;
43
44 static int process_equation(char *equation, int per_vertex)
45 {
46         char *c, *c2;
47
48         c = strchr(equation, '=');
49         if(!c) {
50                 printf("RDR: error l.%d: malformed equation\n");
51                 return 0;
52         }
53         *c = 0;
54         
55         c2 = c;
56         while((c2 > equation) && (*c2 == ' ')) c2--;
57         *c2 = 0;
58         
59         c++;
60         while(*c == ' ') c++;
61
62         if(*equation == 0) {
63                 printf("RDR: error l.%d: missing lvalue\n");
64                 return 0;
65         }
66         if(*c == 0) {
67                 printf("RDR: error l.%d: missing rvalue\n");
68                 return 0;
69         }
70
71         if(per_vertex)
72                 return eval_add_per_vertex(equation, c);
73         else
74                 return eval_add_per_frame(equation, c);
75 }
76
77 static int process_equations(char *equations, int per_vertex)
78 {
79         char *c;
80
81         while(*equations) {
82                 c = strchr(equations, ';');
83                 if(!c)
84                         return process_equation(equations, per_vertex);
85                 *c = 0;
86                 if(!process_equation(equations, per_vertex)) return 0;
87                 equations = c + 1;
88         }
89         return 1;
90 }
91
92 static int process_top_assign(char *left, char *right)
93 {
94         int pfv;
95         
96         while(*right == ' ') right++;
97         if(*right == 0) return 1;
98
99         pfv = eval_pfv_from_name(left);
100         if(pfv >= 0) {
101                 /* preset initial condition or global parameter */
102                 eval_set_initial(pfv, atof(right));
103                 return 1;
104         }
105
106         if(strncmp(left, "per_frame_", 10) == 0)
107                 /* per-frame equation */
108                 return process_equations(right, 0);
109
110         if((strncmp(left, "per_vertex_", 11) == 0) || (strncmp(left, "per_pixel_", 10) == 0))
111                 /* per-vertex equation */
112                 return process_equations(right, 1);
113
114         printf("RDR: warning l.%d: ignoring unknown parameter %s\n", linenr, left);
115         
116         return 1;
117 }
118
119 static int process_line(char *line)
120 {
121         char *c;
122         
123         while(*line == ' ') line++;
124         if(*line == 0) return 1;
125         if(*line == '[') return 1;
126
127         c = strstr(line, "//");
128         if(c) *c = 0;
129         
130         c = line + strlen(line);
131         while((c > line) && (*c == ' ')) c--;
132         *c = 0;
133         if(*line == 0) return 1;
134
135         c = strchr(line, '=');
136         if(!c) {
137                 printf("RDR: error l.%d: '=' expected\n", linenr);
138                 return 0;
139         }
140         *c = 0;
141         return process_top_assign(line, c+1);
142 }
143
144 static int load_preset(char *preset_code)
145 {
146         char *eol;
147         
148         linenr = 0;
149         while(*preset_code) {
150                 linenr++;
151                 eol = strchr(preset_code, '\n');
152                 if(!eol)
153                         return process_line(preset_code);
154                 *eol = 0;
155                 if(*preset_code == 0) {
156                         preset_code = eol + 1;
157                         continue;
158                 }
159                 if(*(eol - 1) == '\r') *(eol - 1) = 0;
160                 if(!process_line(preset_code)) return 0;
161                 preset_code = eol + 1;
162         }
163         return 1;
164 }
165
166 int renderer_start(char *preset_code)
167 {
168         eval_init();
169         if(!load_preset(preset_code)) return 0;
170         eval_schedule();
171         apipe_start();
172         return 1;
173 }
174
175 void renderer_stop()
176 {
177         apipe_stop();
178 }