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