http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.14.tar.gz
[xscreensaver] / hacks / glx / blinkbox.c
1 /* blinkbox, Copyright (c) 2003 Jeremy English <jenglish@myself.com>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  */
11
12 #include <X11/Intrinsic.h>
13
14 extern XtAppContext app;
15
16 #define PROGCLASS         "BlinkBox"
17 #define HACK_INIT         init_ball
18 #define HACK_DRAW         draw_ball
19 #define HACK_RESHAPE  reshape_ball
20 #define sws_opts          xlockmore_opts
21
22 #define MAX_COUNT 20
23
24 #define DEFAULTS        "*delay:        30000       \n" \
25
26 #include "xlockmore.h"
27 #include "sphere.h"
28 #include <ctype.h>
29
30 #ifdef USE_GL /* whole file */
31
32
33 #include <GL/glu.h>
34
35 typedef struct{
36   GLfloat x,y,z;
37 } Tdpos;
38
39 typedef struct{
40   int hit;
41   Tdpos pos;
42   int counter;
43   GLfloat color[3];
44   GLfloat rot[4];
45 }Side;
46
47 struct Bounding_box {
48   Tdpos top;
49   Tdpos bottom;
50 } bbox = {{7,7,10},{-7,-7,-10}};
51
52 struct Ball {
53   GLfloat x;
54   GLfloat y;
55   GLfloat z;
56   int d;
57 } ball = {0,0,0,1};
58
59 static GLuint ballList;
60 static GLuint boxList;
61 Tdpos mo = { 1.0, 1.0, 1.0};  /*motion*/
62 Tdpos moh= {-1.0,-1.5,-1.5}; /*hold motion value*/
63
64 GLfloat bscale[3] = {1,1,0.25};
65 GLfloat bpos[3];
66
67 /*sides*/
68 static Side lside = {0, {0, 0, 0,}, MAX_COUNT,  {1.0, 0.0, 0.0},{90,0,1,0}};/*Red*/
69 static Side rside = {0, {0, 0, 0,}, MAX_COUNT,  {0.0, 1.0, 0.0},{90,0,1,0}};/*Green*/
70 static Side tside = {0, {0, 0, 0,}, MAX_COUNT,  {0.0, 0.0, 1.0},{90,1,0,0}};/*Blue*/
71 static Side bside = {0, {0, 0, 0,}, MAX_COUNT,  {1.0, 0.5, 0.0},{90,1,0,0}};/*Orange*/
72 static Side fside = {0, {0, 0, 0,}, MAX_COUNT,  {1.0, 1.0, 0.0},{90,0,0,1}};/*Yellow*/
73 static Side aside = {0, {0, 0, 0,}, MAX_COUNT,  {0.5, 0.0, 1.0},{90,0,0,1}};/*Purple*/
74 Side *sp;
75
76 /* lights */
77 static float LightDiffuse[]=   { 1.0f, 1.0f, 1.0f, 1.0f };
78 static float LightPosition[]=  { 20.0f, 100.0f, 20.0f, 1.0f };
79
80 ModeSpecOpt sws_opts = {0,NULL,0,NULL,NULL};
81
82 void
83 swap(GLfloat *a, GLfloat *b)
84 {
85   GLfloat t = *a;
86   *a = *b;
87   *b = t;
88 }
89
90 float 
91 get_rand(void)
92 {
93   GLfloat j = 1+(random() % 2);
94   return (j);
95 }
96
97 void
98 swap_mov(GLfloat *a, GLfloat *b)
99 {
100   int j;
101   swap(a,b);
102   j = get_rand();
103   if (*a < 0)
104     *a = (j *= -1);
105   else
106     *a = j;
107 }
108
109 void 
110 cp_b_pos(Tdpos *s_pos){
111   s_pos->x = ball.x;
112   s_pos->y = ball.y;
113   s_pos->z = ball.z;
114 }
115
116 void
117 hit_side(void)
118 {
119   if ((ball.x - ball.d) <= bbox.bottom.x){ 
120     lside.hit = 1;
121     lside.counter = MAX_COUNT;
122     cp_b_pos(&lside.pos);
123     swap_mov(&mo.x,&moh.x);
124   }else
125   if ((ball.x + ball.d) >= bbox.top.x){ 
126     rside.hit = 1;
127     rside.counter = MAX_COUNT;
128     cp_b_pos(&rside.pos);
129     swap_mov(&mo.x,&moh.x);
130   }
131 }
132
133 void
134 hit_top_bottom(void)
135 {
136   if ((ball.y - ball.d) <= bbox.bottom.y){
137     bside.hit = 1;
138     bside.counter = MAX_COUNT;    
139     cp_b_pos(&bside.pos);
140     swap_mov(&mo.y,&moh.y);
141   }else
142   if ((ball.y + ball.d) >= bbox.top.y){
143     tside.hit = 1;
144     tside.counter = MAX_COUNT;
145     cp_b_pos(&tside.pos);
146     swap_mov(&mo.y,&moh.y);
147   }
148 }
149
150 void
151 hit_front_back(void)
152 {    
153   if ((ball.z - ball.d) <= bbox.bottom.z){
154     aside.hit = 1;
155     aside.counter = MAX_COUNT;
156     cp_b_pos(&aside.pos);
157     swap_mov(&mo.z,&moh.z);
158   }else
159   if((ball.z + ball.d) >= bbox.top.z){
160     fside.hit = 1;
161     fside.counter = MAX_COUNT;
162     cp_b_pos(&fside.pos);
163     swap_mov(&mo.z,&moh.z);
164   }
165 }
166
167 void
168 reshape_ball (ModeInfo *mi, int width, int height)
169 {
170   GLfloat h = (GLfloat) height / (GLfloat) width;
171
172   glViewport (0, 0, (GLint) width, (GLint) height);
173   glMatrixMode(GL_PROJECTION);
174   glLoadIdentity();
175   gluPerspective (30.0, 1/h, 1.0, 100.0);
176
177   glMatrixMode(GL_MODELVIEW);
178   glLoadIdentity();
179   gluLookAt( 0.0, 0.0, 40.0,
180              0.0, 0.0, 0.0,
181              0.0, 2.0,  10.0);
182
183 }
184
185 void
186 unit_cube(void)
187 {
188   glBegin(GL_QUADS);            
189   glNormal3f( 0.0f, -1.0f, 0.0f);
190   glVertex3f(-1.0f, -1.0f, -1.0f);      
191   glVertex3f( 1.0f, -1.0f, -1.0f);
192   glVertex3f( 1.0f, -1.0f,  1.0f);
193   glVertex3f(-1.0f, -1.0f,  1.0f);
194   glNormal3f( 0.0f,  0.0f,  1.0f);
195   glVertex3f(-1.0f, -1.0f,  1.0f);
196   glVertex3f( 1.0f, -1.0f,  1.0f);
197   glVertex3f( 1.0f,  1.0f,  1.0f);
198   glVertex3f(-1.0f,  1.0f,  1.0f);
199   glNormal3f( 0.0f,  0.0f, -1.0f);
200   glVertex3f(-1.0f, -1.0f, -1.0f);
201   glVertex3f(-1.0f,  1.0f, -1.0f);
202   glVertex3f( 1.0f,  1.0f, -1.0f);
203   glVertex3f( 1.0f, -1.0f, -1.0f);      
204   glNormal3f( 1.0f,  0.0f,  0.0f);
205   glVertex3f( 1.0f, -1.0f, -1.0f);
206   glVertex3f( 1.0f,  1.0f, -1.0f);
207   glVertex3f( 1.0f,  1.0f,  1.0f);
208   glVertex3f( 1.0f, -1.0f,  1.0f);
209   glNormal3f( -1.0f, 0.0f,  0.0f);
210   glVertex3f(-1.0f, -1.0f, -1.0f);
211   glVertex3f(-1.0f, -1.0f,  1.0f);
212   glVertex3f(-1.0f,  1.0f,  1.0f);
213   glVertex3f(-1.0f,  1.0f, -1.0f);
214   glNormal3f( 1.0f,  1.0f,  0.0f);
215   glVertex3f(-1.0f,  1.0f, -1.0f);
216   glVertex3f(-1.0f,  1.0f,  1.0f);
217   glVertex3f( 1.0f,  1.0f,  1.0f);
218   glVertex3f( 1.0f,  1.0f, -1.0f);
219   glEnd();                                              
220 }
221
222 void 
223 init_ball (ModeInfo *mi)
224
225   #define SPHERE_SLICES 32  /* how densely to render spheres */
226   #define SPHERE_STACKS 16
227   sp = malloc(sizeof(*sp));
228   if(sp == NULL){
229     fprintf(stderr,"Could not allocate memory\n");
230     exit(1);
231   }
232   init_GL(mi);
233   reshape_ball(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
234   ballList = glGenLists(1);
235   glNewList(ballList, GL_COMPILE);
236   unit_sphere (SPHERE_STACKS, SPHERE_SLICES, False);
237   glEndList ();
238
239   boxList = glGenLists(1);
240   glNewList(boxList, GL_COMPILE);
241   unit_cube();
242   glEndList();
243
244   glEnable(GL_COLOR_MATERIAL);
245   glShadeModel(GL_SMOOTH);                              
246   glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
247   glClearDepth(1.0f);                           
248   glEnable(GL_DEPTH_TEST);              
249   glDepthFunc(GL_LEQUAL);
250   glEnable(GL_LIGHTING);
251   glClearDepth(1);
252   glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
253   glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);
254   glEnable(GL_LIGHT1);
255 }
256
257 void
258 draw_ball (ModeInfo *mi)
259 {  
260    Display *dpy = MI_DISPLAY(mi);
261    Window window = MI_WINDOW(mi);
262    /*int dem = 1;*/
263    int i = 0;
264    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
265
266    hit_top_bottom();
267    hit_front_back();
268    hit_side();
269
270    glRotated(0.25,0,0,1);
271    glRotated(0.25,0,1,0);
272    glRotated(0.25,1,0,0);
273
274    glColor3f(1,1,1);
275    glPushMatrix();
276    glTranslatef(ball.x += mo.x,
277                 ball.y += mo.y,
278                 ball.z += mo.z);
279
280    glCallList(ballList);
281    glPopMatrix();
282
283    while(i < 6){
284     switch(i){
285       case 0:{
286                sp = &lside;
287                bpos[0] = lside.pos.z*-1;
288                bpos[1] = lside.pos.y;
289                bpos[2] = bbox.bottom.x - bscale[3];
290                break;
291              }
292       case 1:{
293                sp = &rside;
294                bpos[0] = rside.pos.z*-1;
295                bpos[1] = rside.pos.y;
296                bpos[2] = bbox.top.x + bscale[3];
297                break;
298              }
299       case 2:{
300                sp = &tside;
301                bpos[0] = tside.pos.x;
302                bpos[1] = tside.pos.z;
303                bpos[2] = bbox.bottom.y - bscale[3];
304                break;
305              }
306       case 3:{
307                sp = &bside;
308                bpos[0] = bside.pos.x;
309                bpos[1] = bside.pos.z;
310                bpos[2] = bbox.top.y + bscale[3];
311                break;
312              }
313       case 4:{
314                sp = &fside;
315                bpos[0] = fside.pos.y;
316                bpos[1] = fside.pos.x*-1;
317                bpos[2] = bbox.top.z + bscale[3];
318                break;
319              }
320       case 5:{
321                sp = &aside;
322                bpos[0] = aside.pos.y;
323                bpos[1] = aside.pos.x*-1;
324                bpos[2] = bbox.bottom.z + bscale[3];
325                break;
326              }
327     }
328     if(sp->hit){
329      glColor3fv(sp->color);
330      glPushMatrix();
331      glRotatef(sp->rot[0],sp->rot[1],sp->rot[2],sp->rot[3]);
332      glTranslatef(bpos[0],bpos[1],bpos[2]);
333      /*dem = (MAX_COUNT-(sp->counter+1));*/
334      /*glScalef(bscale[0]/dem,bscale[1]/dem,bscale[2]);*/
335      glScalef(bscale[0],bscale[1],bscale[2]);
336      glCallList(boxList);
337      glPopMatrix();
338      sp->counter--;
339      if(!sp->counter)
340        sp->hit = 0;
341     }
342     i++;
343   }
344
345
346    glFinish();
347    glXSwapBuffers(dpy, window);
348
349 }
350
351 #endif /* USE_GL */