tweak statistics display
[rdex:client.git] / src / rdex.c
1 /* =====================================================================
2 flavourcollider
3 Copyright (C) 2008-2011  Claude Heiland-Allen <claudiusmaximus@goto10.org>
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, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 ------------------------------------------------------------------------
18 Main Module
19 ===================================================================== */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "rdex.h"
24
25 //======================================================================
26 // main module global mutable state
27 static struct rdex rdex;
28
29 //======================================================================
30 // main module initialization
31 int rdex_init() {
32   if (! recvosc_init(&rdex.recvosc)) { return 0; }
33   if (! reactiondiffusion_init(&rdex.reactiondiffusion)) { return 0; }
34   if (! copysquare_init       (&rdex.copysquare       )) { return 0; }
35   if (! arithmeticmean_init   (&rdex.arithmeticmean, rdex_aspect, 4)) { return 0; }
36   if (! numericerror_init     (&rdex.numericerror,   rdex_aspect))  { return 0; }
37   if (! falsecolour_init      (&rdex.falsecolour      )) { return 0; }
38   if (! library_init          (&rdex.library          )) { return 0; }
39   if (! screenshot_init       (&rdex.screenshot       )) { return 0; }
40   glGenFramebuffersEXT(1, &rdex.fbo);
41   rdex.starttime = 0;
42   rdex.fullscreen = 0;
43   reactiondiffusion_reset(&rdex.reactiondiffusion);
44   return 1;
45 }
46
47 //======================================================================
48 // main module reshape callback
49 void rdex_reshape(int w, int h) {
50   reactiondiffusion_reshape(&rdex.reactiondiffusion, rdex_tex_width, rdex_tex_height);
51   copysquare_reshape       (&rdex.copysquare,        rdex_tex_width, rdex_tex_height);
52   arithmeticmean_reshape   (&rdex.arithmeticmean,    rdex_tex_width, rdex_tex_height);
53   numericerror_reshape     (&rdex.numericerror,      rdex_tex_width, rdex_tex_height);
54   falsecolour_reshape      (&rdex.falsecolour,       rdex_tex_width, rdex_tex_height);
55   library_reshape          (&rdex.library,           w, h);
56   screenshot_reshape       (&rdex.screenshot,        w, h);
57 }
58
59 //======================================================================
60 // main module display callback
61 void rdex_display() {
62   for (int g = 0; g < rdex_overdrive; ++g) {
63     reactiondiffusion_display(&rdex.reactiondiffusion, rdex.fbo, g);
64   }
65
66   if (rdex.reactiondiffusion.frame % rdex_analysis_period == 0) {
67     int s = (rdex.reactiondiffusion.frame / rdex_analysis_period) % rdex_aspect;
68     copysquare_display       (&rdex.copysquare,        rdex.fbo, rdex.reactiondiffusion.texture);
69     arithmeticmean_display   (&rdex.arithmeticmean,    rdex.fbo, rdex.copysquare       .texture, s);
70     numericerror_display     (&rdex.numericerror,      rdex.fbo, rdex.reactiondiffusion.texture, s);
71   }
72
73   falsecolour_display      (&rdex.falsecolour,       rdex.fbo, rdex.reactiondiffusion.texture);
74
75   library_display          (&rdex.library, rdex.falsecolour.texture);
76   glutSwapBuffers();
77   glutReportErrors();
78   screenshot_display       (&rdex.screenshot);
79   rdex.frame += 1;
80 }
81
82 //======================================================================
83 // main module exit callback
84 void rdex_atexit(void) {
85   double timeelapsed = (double) time(NULL) - (double) rdex.starttime;
86   fprintf(stderr, "\n\n--------------------------------------------------------------------------\n");
87   fprintf(stderr, "------------------------------- statistics -------------------------------\n");
88   fprintf(stderr, "--------------------------------------------------------------------------\n");
89   fprintf(stderr, "%10d seconds elapsed (+/- 1)\n", (int) timeelapsed);
90   fprintf(stderr, "%10d frames rendered (%f fps)\n", rdex.frame, rdex.frame / timeelapsed);
91   fprintf(stderr, "%10d resets required (%f secs)\n", rdex.species, timeelapsed / rdex.species);
92   fprintf(stderr, "        %6.2f%% uniformity\n", 100.0 * rdex.uniform / (double) rdex.species);
93   fprintf(stderr, "        %6.2f%% erraticity\n", 100.0 * rdex.erratic / (double) rdex.species);
94   fprintf(stderr, "--------------------------------------------------------------------------\n");
95 }
96
97 //======================================================================
98 // main module idle callback
99 void rdex_idle() {
100   if (rdex.starttime == 0) {
101     rdex.starttime = time(NULL);
102     rdex.frame = 0;
103     atexit(rdex_atexit);
104   }
105   recvosc_idle(&rdex.recvosc);
106   // FIXME
107   rdex.reactiondiffusion.left .attention_target = rdex.recvosc.attention;
108   rdex.reactiondiffusion.right.attention_target = rdex.recvosc.attention;
109   for (int g = 0; g < rdex_overdrive; ++g) {
110     reactiondiffusion_idle(&rdex.reactiondiffusion);
111   }
112
113   copysquare_idle       (&rdex.copysquare);
114   arithmeticmean_idle   (&rdex.arithmeticmean);
115   numericerror_idle     (&rdex.numericerror);
116
117   falsecolour_idle      (&rdex.falsecolour);
118   library_idle          (&rdex.library);
119   screenshot_idle       (&rdex.screenshot);
120
121   int reset = 0;
122   if (rdex.reactiondiffusion.frame > rdex_analysis_period) {
123     if (rdex.arithmeticmean.stddev < 0.01) {
124       fprintf(stderr, "reset: uniform = %f\n", (double) rdex.arithmeticmean.stddev);
125       reset = 1;
126       rdex.species += 1;
127       rdex.uniform += 1;
128     } else if (rdex.numericerror.mean > 0.2) {
129       fprintf(stderr, "reset: erratic = %f\n", (double) rdex.numericerror.mean);
130       reset = 1;
131       rdex.species += 1;
132       rdex.erratic += 1;
133     }
134   }
135   if (reset) {
136     reactiondiffusion_reset(&rdex.reactiondiffusion);
137     arithmeticmean_reset(&rdex.arithmeticmean);
138     numericerror_reset(&rdex.numericerror);
139   }
140   glutPostRedisplay();
141 }
142
143 void rdex_keynormal(unsigned char key, int x, int y) {
144   switch (key) {
145   case 27: // escape
146                 exit(0);  // FIXME
147     break;
148   default:
149     break;
150   }
151 }
152
153 void rdex_keyspecial(int key, int x, int y) {
154   switch (key) {
155   default:
156     break;
157   }
158 }
159
160 // EOF