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