http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.14.tar.gz
[xscreensaver] / hacks / glx / sproingiewrap.c
1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* sproingiewrap.c - sproingies wrapper */
3
4 #if 0
5 static const char sccsid[] = "@(#)sproingiewrap.c       4.07 97/11/24 xlockmore";
6 #endif
7
8 /*-
9  * sproingiewrap.c - Copyright 1996 Sproingie Technologies Incorporated.
10  *
11  * Permission to use, copy, modify, and distribute this software and its
12  * documentation for any purpose and without fee is hereby granted,
13  * provided that the above copyright notice appear in all copies and that
14  * both that copyright notice and this permission notice appear in
15  * supporting documentation.
16  *
17  * This file is provided AS IS with no warranties of any kind.  The author
18  * shall have no liability with respect to the infringement of copyrights,
19  * trade secrets or any patents by this file or any part thereof.  In no
20  * event will the author be liable for any lost revenue or profits or
21  * other special, indirect and consequential damages.
22  *
23  *    Programming:  Ed Mackey, http://www.netaxs.com/~emackey/
24  *                  Gordon Wrigley, gdw33@student.canterbury.ac.nz
25  *    Sproingie 3D objects modeled by:  Al Mackey, al@iam.com
26  *       (using MetaNURBS in NewTek's Lightwave 3D v5).
27  *
28  * Revision History:
29  * 13-Dec-02: Changed triangle normals into vertex normals to give a smooth
30                 apperance and moved the sproingies from Display Lists to 
31                                 Vertex Arrays, still need to do this for the TopsSides.
32                 (gordon)
33  * 26-Apr-97: Added glPointSize() calls around explosions, plus other fixes.
34  * 28-Mar-97: Added size support.
35  * 22-Mar-97: Updated to use glX interface instead of xmesa one.
36  *              Also, support for multiscreens added.
37  * 20-Mar-97: Updated for xlockmore v4.02alpha7 and higher, using
38  *              xlockmore's built-in Mesa/OpenGL support instead of
39  *              my own.  Submitted for inclusion in xlockmore.
40  * 09-Dec-96: Written.
41  */
42
43 /*-
44  * The sproingies have six "real" frames, (s1_1 to s1_6) that show a
45  * sproingie jumping off a block, headed down and to the right.  But
46  * the program thinks of sproingies as having twelve "virtual" frames,
47  * with the latter six being copies of the first, only lowered and
48  * rotated by 90 degrees (jumping to the left).  So after going
49  * through 12 frames, a sproingie has gone down two rows but not
50  * moved horizontally. 
51  *
52  * To have the sproingies randomly choose left/right jumps at each
53  * block, the program should go back to thinking of only 6 frames,
54  * and jumping down only one row when it is done.  Then it can pick a
55  * direction for the next row.
56  *
57  * (Falling off the end might not be so bad either.  :) )  
58  */
59
60 #ifdef STANDALONE
61 # define PROGCLASS                                      "Sproingies"
62 # define HACK_INIT                                      init_sproingies
63 # define HACK_DRAW                                      draw_sproingies
64 # define HACK_RESHAPE                           reshape_sproingies
65 # define sproingies_opts                        xlockmore_opts
66 # define DEFAULTS       "*delay:                25000   \n"                     \
67                                         "*count:                5       \n"                     \
68                                         "*cycles:               0       \n"                     \
69                                         "*size:                 0       \n"                     \
70                                         "*showFPS:      False   \n"                     \
71                                         "*fpsTop:       True    \n"                     \
72                                         "*wireframe:    False   \n"
73 # include "xlockmore.h"                         /* from the xscreensaver distribution */
74 #else  /* !STANDALONE */
75 # include "xlock.h"                                     /* from the xlockmore distribution */
76 #endif /* !STANDALONE */
77
78 #ifdef USE_GL
79
80 ModeSpecOpt sproingies_opts =
81 {0, NULL, 0, NULL, NULL};
82
83 #ifdef USE_MODULES
84 ModStruct   sproingies_description =
85 {"sproingies", "init_sproingies", "draw_sproingies", "release_sproingies",
86  "refresh_sproingies", "init_sproingies", NULL, &sproingies_opts,
87  1000, 5, 0, 400, 4, 1.0, "",
88  "Shows Sproingies!  Nontoxic.  Safe for pets and small children", 0, NULL};
89
90 #endif
91
92 #define MINSIZE 32
93
94 #include <GL/glu.h>
95 #include <time.h>
96
97 void        NextSproingie(int screen);
98 void        NextSproingieDisplay(int screen,int pause);
99 void        DisplaySproingies(int screen,int pause);
100 void        ReshapeSproingies(int w, int h);
101 void        CleanupSproingies(int screen);
102 void        InitSproingies(int wfmode, int grnd, int mspr, int screen, int numscreens, int mono);
103
104 typedef struct {
105         GLfloat     view_rotx, view_roty, view_rotz;
106         GLint       gear1, gear2, gear3;
107         GLfloat     angle;
108         GLuint      limit;
109         GLuint      count;
110         GLXContext *glx_context;
111         int         mono;
112         Window      window;
113 } sproingiesstruct;
114
115 static sproingiesstruct *sproingies = NULL;
116
117 static Display *swap_display;
118 static Window swap_window;
119
120 static ModeInfo *global_mi_kludge;
121
122 void
123 SproingieSwap(void)
124 {
125     ModeInfo *mi = global_mi_kludge;
126     if (mi->fps_p) do_fps (mi);
127         glFinish();
128         glXSwapBuffers(swap_display, swap_window);
129 }
130
131
132 void
133 init_sproingies(ModeInfo * mi)
134 {
135         Display    *display = MI_DISPLAY(mi);
136         Window      window = MI_WINDOW(mi);
137         int         screen = MI_SCREEN(mi);
138
139         int         cycles = MI_CYCLES(mi);
140         int         count = MI_COUNT(mi);
141         int         size = MI_SIZE(mi);
142
143         sproingiesstruct *sp;
144         int         wfmode = 0, grnd, mspr, w, h;
145
146     global_mi_kludge = mi;
147
148         if (sproingies == NULL) {
149                 if ((sproingies = (sproingiesstruct *) calloc(MI_NUM_SCREENS(mi),
150                                          sizeof (sproingiesstruct))) == NULL)
151                         return;
152         }
153         sp = &sproingies[screen];
154
155         sp->mono = (MI_IS_MONO(mi) ? 1 : 0);
156         sp->window = window;
157         if ((sp->glx_context = init_GL(mi)) != NULL) {
158
159                 if ((cycles & 1) || MI_IS_WIREFRAME(mi))
160                         wfmode = 1;
161                 grnd = (cycles >> 1);
162                 if (grnd > 2)
163                         grnd = 2;
164
165                 mspr = count;
166                 if (mspr > 100)
167                         mspr = 100;
168
169                 /* wireframe, ground, maxsproingies */
170                 InitSproingies(wfmode, grnd, mspr, MI_SCREEN(mi), MI_NUM_SCREENS(mi), sp->mono);
171
172                 /* Viewport is specified size if size >= MINSIZE && size < screensize */
173                 if (size == 0) {
174                         w = MI_WIDTH(mi);
175                         h = MI_HEIGHT(mi);
176                 } else if (size < MINSIZE) {
177                         w = MINSIZE;
178                         h = MINSIZE;
179                 } else {
180                         w = (size > MI_WIDTH(mi)) ? MI_WIDTH(mi) : size;
181                         h = (size > MI_HEIGHT(mi)) ? MI_HEIGHT(mi) : size;
182                 }
183
184                 glViewport((MI_WIDTH(mi) - w) / 2, (MI_HEIGHT(mi) - h) / 2, w, h);
185                 glMatrixMode(GL_PROJECTION);
186                 glLoadIdentity();
187                 gluPerspective(65.0, (GLfloat) w / (GLfloat) h, 0.1, 2000.0);   /* was 200000.0 */
188                 glMatrixMode(GL_MODELVIEW);
189                 glLoadIdentity();
190
191                 swap_display = display;
192                 swap_window = window;
193                 DisplaySproingies(MI_SCREEN(mi),mi->pause);
194         } else {
195                 MI_CLEARWINDOW(mi);
196         }
197 }
198
199 /* ARGSUSED */
200 void
201 draw_sproingies(ModeInfo * mi)
202 {
203         sproingiesstruct *sp = &sproingies[MI_SCREEN(mi)];
204         Display    *display = MI_DISPLAY(mi);
205         Window      window = MI_WINDOW(mi);
206
207         if (!sp->glx_context)
208                 return;
209
210         glDrawBuffer(GL_BACK);
211         glXMakeCurrent(display, window, *(sp->glx_context));
212
213         swap_display = display;
214         swap_window = window;
215
216         NextSproingieDisplay(MI_SCREEN(mi),mi->pause);  /* It will swap. */
217 }
218
219 void
220 refresh_sproingies(ModeInfo * mi)
221 {
222         /* No need to do anything here... The whole screen is updated
223          * every frame anyway.  Otherwise this would be just like
224          * draw_sproingies, above, but replace NextSproingieDisplay(...)
225          * with DisplaySproingies(...).
226          */
227 }
228
229 void
230 reshape_sproingies (ModeInfo *mi, int w, int h)
231 {
232   ReshapeSproingies(w, h);
233 }
234
235
236 void
237 release_sproingies(ModeInfo * mi)
238 {
239         if (sproingies != NULL) {
240                 int         screen;
241
242                 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
243                         sproingiesstruct *sp = &sproingies[screen];
244
245                         if (sp->glx_context) {
246
247                                 glXMakeCurrent(MI_DISPLAY(mi), sp->window, *(sp->glx_context));
248                                 CleanupSproingies(MI_SCREEN(mi));
249                         }
250                 }
251
252                 (void) free((void *) sproingies);
253                 sproingies = NULL;
254         }
255         FreeAllGL(mi);
256 }
257
258 #endif
259
260 /* End of sproingiewrap.c */