1 /*
2  * Copyright (C) 2003 Alex Zolotov <nightradio@knoppix.ru>
3  * Mucked with by Tugrul Galatali <tugrul@galatali.com>
4  *
5  * MatrixView 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 2 of the License, or
8  * (at your option) any later version.
9  *
10  * MatrixView 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 along
16  * with MatrixView; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 /**
21  * Ported to an MPlayer video out plugin by Pigeon <pigeon at pigeond.net>
22  * August 2006
23  */
24 
25 #include <math.h>
26 #include <stdio.h>
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include "gl_common.h"
31 #include "matrixview.h"
32 #include "matrixview_font.h"
33 
34 static float matrix_contrast   = 1.5;
35 static float matrix_brightness = 1.0;
36 
37 #define MAX_TEXT_X 0x4000
38 #define MAX_TEXT_Y 0x4000
39 static int text_x = 0;
40 static int text_y = 0;
41 #define _text_x (text_x/2)
42 #define _text_y (text_y/2)
43 
44 // Scene position
45 #define Z_Off -128.0f
46 #define Z_Depth 8
47 
48 static uint8_t *speed;
49 static uint8_t *text;
50 static uint8_t *text_light;
51 
52 static float *bump_pic;
53 
54 static void draw_flare(float x, float y, float z);
55 
draw_char(int num,int light,int illuminated,float x,float y,float z)56 static void draw_char(int num, int light, int illuminated, float x, float y, float z)
57 {
58     int light2 = 0;
59     float tx, ty;
60 
61     num %= 55;
62     if (light < 10) light = 0;
63     //light = light / 255;        //light=7-light;num+=(light*60);
64     light *= matrix_brightness;
65     if (illuminated) {
66         draw_flare(x, y, z);
67         light += 128;
68         if (light > 255) light = 255;
69         light2 = 128;
70     }
71     ty = (float)(num / 10) / 6;
72     tx = (float)(num % 10) / 10;
73     mpglColor4ub(light2, light, light2, 255);        // Basic polygon color
74 
75     mpglTexCoord2f(tx, ty);
76     mpglVertex3f(x, y, z);
77     mpglTexCoord2f(tx + 0.1, ty);
78     mpglVertex3f(x + 1, y, z);
79     mpglTexCoord2f(tx + 0.1, ty + 0.166);
80     mpglVertex3f(x + 1, y - 1, z);
81     mpglTexCoord2f(tx, ty + 0.166);
82     mpglVertex3f(x, y - 1, z);
83 }
84 
draw_flare(float x,float y,float z)85 static void draw_flare(float x, float y, float z)        //flare
86 {
87     mpglColor4ub(204, 204, 204, 255);        // Basic polygon color
88 
89     mpglTexCoord2f(1.0 - 4.0/128, 1.0 - 4.0/64);
90     mpglVertex3f(x - 1, y + 1, z);
91     mpglTexCoord2f(1.0 - 1.0/128, 1.0 - 4.0/64);
92     mpglVertex3f(x + 2, y + 1, z);
93     mpglTexCoord2f(1.0 - 1.0/128, 1.0 - 1.0/64);
94     mpglVertex3f(x + 2, y - 2, z);
95     mpglTexCoord2f(1.0 - 4.0/128, 1.0 - 1.0/64);
96     mpglVertex3f(x - 1, y - 2, z);
97 }
98 
draw_text(const uint8_t * pic)99 static void draw_text(const uint8_t *pic)
100 {
101     int x, y;
102     int p = 0;
103     int c, c_pic;
104     int pic_fade = 255;
105     int illuminated;
106 
107     for (y = _text_y; y > -_text_y; y--) {
108         for (x = -_text_x; x < _text_x; x++) {
109             c  = text_light[p] - (text[p] >> 1);
110             c += pic_fade;
111             if (c > 255)
112                 c = 255;
113 
114             if (pic) {
115                 // Original code
116                 //c_pic = pic[p] * matrix_contrast - (255 - pic_fade);
117 
118                 c_pic = (255 - pic[p]) * matrix_contrast - (255 - pic_fade);
119 
120                 if (c_pic < 0)
121                     c_pic = 0;
122 
123                 c -= c_pic;
124 
125                 if (c < 0)
126                     c = 0;
127 
128                 bump_pic[p] = (255.0f - c_pic) / (256 / Z_Depth);
129             } else {
130                 bump_pic[p] = Z_Depth;
131             }
132 
133             illuminated = text_light[p] > 128 && text_light[p + text_x] < 10;
134             draw_char(text[p], c, illuminated, x, y, bump_pic[p]);
135 
136             p++;
137         }
138     }
139 }
140 
scroll(double dCurrentTime)141 static void scroll(double dCurrentTime)
142 {
143     int a, s, polovina;
144     //static double dLastCycle = -1;
145     static double dLastMove = -1;
146 
147     if (dCurrentTime - dLastMove > 1.0 / (text_y / 1.5)) {
148         dLastMove = dCurrentTime;
149 
150         polovina = text_x * text_y / 2;
151         s = 0;
152         for (a = text_x * text_y + text_x - 1; a >= text_x; a--) {
153             if (speed[s])
154                 text_light[a] = text_light[a - text_x];        //scroll light table down
155             s++;
156             if (s >= text_x)
157                 s = 0;
158         }
159         memmove(text_light + text_x, text_light, text_x * text_y);
160         memset(text_light, 253, text_x);
161 
162         s = 0;
163         for (a = polovina; a < text_x * text_y; a++) {
164             if (text_light[a] == 255)
165                 text_light[s] = text_light[s + text_x] >> 1;        //make black bugs in top line
166 
167             s++;
168 
169             if (s >= text_x)
170                 s = 0;
171         }
172     }
173 }
174 
make_change(double dCurrentTime)175 static void make_change(double dCurrentTime)
176 {
177     int r = rand() % text_x * text_y;
178 
179     text[r] += 133;        //random bugs
180 
181     r = rand() % (4 * text_x);
182     if (r < text_x && text_light[r])
183         text_light[r] = 255;        //white bugs
184 
185     scroll (dCurrentTime);
186 }
187 
188 
make_text(void)189 static void make_text(void)
190 {
191     int a;
192 
193     for (a = 0; a < text_x * text_y; a++)
194         text[a] = rand() >> 8; // avoid the lowest bits of rand()
195 
196     for (a = 0; a < text_x; a++)
197         speed[a] = rand() >= RAND_MAX / 2;
198 }
199 
ourBuildTextures(void)200 static void ourBuildTextures(void)
201 {
202     mpglTexImage2D(GL_TEXTURE_2D, 0, 1, 128, 64, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
203                    font_texture);
204     mpglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
205     mpglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
206 }
207 
matrixview_init(int w,int h)208 void matrixview_init(int w, int h)
209 {
210     make_text();
211 
212     ourBuildTextures();
213 
214     // Color to clear color buffer to.
215     mpglClearColor(0.0f, 0.0f, 0.0f, 0.0f);
216 
217     // Allow adjusting of texture color via glColor
218     mpglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
219 
220     mpglEnable(GL_BLEND);
221     mpglEnable(GL_TEXTURE_2D);
222 
223     mpglBlendFunc(GL_ONE, GL_ONE);
224 
225     matrixview_reshape(w, h);
226 }
227 
228 
matrixview_reshape(int w,int h)229 void matrixview_reshape(int w, int h)
230 {
231     double nearplane = -Z_Off - Z_Depth;
232     // perspective projection, also adjusting vertex position
233     // by Z_Off and with simplified Z equation since the absolute
234     // Z value does not matter, only relative to other pixels
235     float matrix[16] = {
236       nearplane / _text_x, 0, 0, 0,
237       0, nearplane / _text_y, 0, 0,
238       0, 0,  1, -1,
239       0, 0,  0, -Z_Off
240     };
241     mpglViewport(0, 0, w, h);
242 
243     mpglLoadMatrixf(matrix);
244 }
245 
246 
matrixview_draw(double currentTime,const uint8_t * data)247 void matrixview_draw(double currentTime, const uint8_t *data)
248 {
249     // Clear the color and depth buffers.
250     mpglClear(GL_COLOR_BUFFER_BIT);
251 
252     // OK, let's start drawing our planer quads.
253     mpglBegin(GL_QUADS);
254     draw_text(data);
255     mpglEnd();
256 
257     make_change(currentTime);
258 }
259 
matrixview_contrast_set(float contrast)260 void matrixview_contrast_set(float contrast)
261 {
262     matrix_contrast = contrast;
263 }
264 
matrixview_brightness_set(float brightness)265 void matrixview_brightness_set(float brightness)
266 {
267     matrix_brightness = brightness;
268 }
269 
270 
matrixview_matrix_resize(int w,int h)271 void matrixview_matrix_resize(int w, int h)
272 {
273     int elems;
274     free(speed);
275     speed = NULL;
276     free(text);
277     text = NULL;
278     free(text_light);
279     text_light = NULL;
280     if (w > MAX_TEXT_X || h > MAX_TEXT_Y)
281         return;
282     elems = w * (h + 1);
283     speed      = calloc(w,     sizeof(*speed));
284     text       = calloc(elems, sizeof(*text));
285     text_light = calloc(elems, sizeof(*text_light));
286     bump_pic   = calloc(elems, sizeof(*bump_pic));
287     text_x = w;
288     text_y = h;
289     make_text();
290 }
291