257 lines
6.9 KiB
C
257 lines
6.9 KiB
C
/* -*- Mode: C; tab-width: 4 -*- */
|
|
/* sproingiewrap.c - sproingies wrapper */
|
|
|
|
#if !defined( lint ) && !defined( SABER )
|
|
static const char sccsid[] = "@(#)sproingiewrap.c 5.00 2000/11/01 xlockmore";
|
|
|
|
#endif
|
|
|
|
/*-
|
|
* sproingiewrap.c - Copyright 1996 Sproingie Technologies Incorporated.
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software and its
|
|
* documentation for any purpose and without fee is hereby granted,
|
|
* provided that the above copyright notice appear in all copies and that
|
|
* both that copyright notice and this permission notice appear in
|
|
* supporting documentation.
|
|
*
|
|
* This file is provided AS IS with no warranties of any kind. The author
|
|
* shall have no liability with respect to the infringement of copyrights,
|
|
* trade secrets or any patents by this file or any part thereof. In no
|
|
* event will the author be liable for any lost revenue or profits or
|
|
* other special, indirect and consequential damages.
|
|
*
|
|
* Programming: Ed Mackey, http://www.netaxs.com/~emackey/
|
|
* Sproingie 3D objects modeled by: Al Mackey, al@iam.com
|
|
* (using MetaNURBS in NewTek's Lightwave 3D v5).
|
|
*
|
|
* Revision History:
|
|
* 01-Nov-2000: Allocation checks
|
|
* 26-Apr-1997: Added glPointSize() calls around explosions, plus other fixes.
|
|
* 28-Mar-1997: Added size support.
|
|
* 22-Mar-1997: Updated to use glX interface instead of xmesa one.
|
|
* Also, support for multiscreens added.
|
|
* 20-Mar-1997: Updated for xlockmore v4.02alpha7 and higher, using
|
|
* xlockmore's built-in Mesa/OpenGL support instead of
|
|
* my own. Submitted for inclusion in xlockmore.
|
|
* 09-Dec-1996: Written.
|
|
*/
|
|
|
|
/*-
|
|
* The sproingies have six "real" frames, (s1_1 to s1_6) that show a
|
|
* sproingie jumping off a block, headed down and to the right. But
|
|
* the program thinks of sproingies as having twelve "virtual" frames,
|
|
* with the latter six being copies of the first, only lowered and
|
|
* rotated by 90 degrees (jumping to the left). So after going
|
|
* through 12 frames, a sproingie has gone down two rows but not
|
|
* moved horizontally.
|
|
*
|
|
* To have the sproingies randomly choose left/right jumps at each
|
|
* block, the program should go back to thinking of only 6 frames,
|
|
* and jumping down only one row when it is done. Then it can pick a
|
|
* direction for the next row.
|
|
*
|
|
* (Falling off the end might not be so bad either. :) )
|
|
*/
|
|
|
|
#ifdef STANDALONE
|
|
#define MODE_sproingies
|
|
#define PROGCLASS "Sproingies"
|
|
#define HACK_INIT init_sproingies
|
|
#define HACK_DRAW draw_sproingies
|
|
#define sproingies_opts xlockmore_opts
|
|
#define DEFAULTS "*delay: 80000 \n" \
|
|
"*count: 5 \n" \
|
|
"*cycles: 0 \n" \
|
|
"*size: 0 \n" \
|
|
"*wireframe: False \n"
|
|
#include "xlockmore.h" /* from the xscreensaver distribution */
|
|
#else /* !STANDALONE */
|
|
#include "xlock.h" /* from the xlockmore distribution */
|
|
#include "vis.h"
|
|
#endif /* !STANDALONE */
|
|
|
|
#ifdef MODE_sproingies
|
|
|
|
ModeSpecOpt sproingies_opts =
|
|
{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
|
|
|
|
#ifdef USE_MODULES
|
|
ModStruct sproingies_description =
|
|
{"sproingies", "init_sproingies", "draw_sproingies", "release_sproingies",
|
|
"refresh_sproingies", "init_sproingies", (char *) NULL, &sproingies_opts,
|
|
80000, 5, 0, 0, 64, 1.0, "",
|
|
"Shows Sproingies! Nontoxic. Safe for pets and small children", 0, NULL};
|
|
|
|
#endif
|
|
|
|
#define MINSIZE 32
|
|
|
|
#include <GL/glu.h>
|
|
#include <time.h>
|
|
|
|
void NextSproingie(int screen);
|
|
void NextSproingieDisplay(int screen);
|
|
void DisplaySproingies(int screen);
|
|
|
|
#if 0
|
|
void ReshapeSproingies(int w, int h);
|
|
|
|
#endif
|
|
void CleanupSproingies(int screen);
|
|
Bool InitSproingies(int wfmode, int grnd, int mspr, int screen, int numscreens, int mono);
|
|
|
|
typedef struct {
|
|
GLfloat view_rotx, view_roty, view_rotz;
|
|
GLint gear1, gear2, gear3;
|
|
GLfloat angle;
|
|
GLuint limit;
|
|
GLuint count;
|
|
GLXContext *glx_context;
|
|
int mono;
|
|
Window window;
|
|
int init;
|
|
} sproingiesstruct;
|
|
|
|
static sproingiesstruct *sproingies = (sproingiesstruct *) NULL;
|
|
|
|
static Display *swap_display;
|
|
static Window swap_window;
|
|
|
|
void
|
|
SproingieSwap(void)
|
|
{
|
|
glFinish();
|
|
glXSwapBuffers(swap_display, swap_window);
|
|
}
|
|
|
|
|
|
void
|
|
init_sproingies(ModeInfo * mi)
|
|
{
|
|
Display *display = MI_DISPLAY(mi);
|
|
Window window = MI_WINDOW(mi);
|
|
|
|
int cycles = MI_CYCLES(mi);
|
|
int count = MI_COUNT(mi);
|
|
int size = MI_SIZE(mi);
|
|
int wfmode = 0, grnd, mspr, w, h;
|
|
sproingiesstruct *sp;
|
|
|
|
if (sproingies == NULL) {
|
|
if ((sproingies = (sproingiesstruct *) calloc(MI_NUM_SCREENS(mi),
|
|
sizeof (sproingiesstruct))) == NULL)
|
|
return;
|
|
}
|
|
sp = &sproingies[MI_SCREEN(mi)];
|
|
|
|
sp->mono = (MI_IS_MONO(mi) ? 1 : 0);
|
|
sp->window = window;
|
|
if ((sp->glx_context = init_GL(mi)) != NULL) {
|
|
|
|
if ((cycles & 1) || MI_IS_WIREFRAME(mi))
|
|
wfmode = 1;
|
|
grnd = (cycles >> 1);
|
|
if (grnd > 2)
|
|
grnd = 2;
|
|
|
|
mspr = count;
|
|
if (mspr > 100)
|
|
mspr = 100;
|
|
|
|
/* wireframe, ground, maxsproingies */
|
|
if (!InitSproingies(wfmode, grnd, mspr, MI_SCREEN(mi),
|
|
MI_NUM_SCREENS(mi), sp->mono)) {
|
|
return;
|
|
}
|
|
sp->init = True;
|
|
/* Viewport is specified size if size >= MINSIZE && size < screensize */
|
|
if (size <= 1) {
|
|
w = MI_WIDTH(mi);
|
|
h = MI_HEIGHT(mi);
|
|
} else if (size < MINSIZE) {
|
|
w = MINSIZE;
|
|
h = MINSIZE;
|
|
} else {
|
|
w = (size > MI_WIDTH(mi)) ? MI_WIDTH(mi) : size;
|
|
h = (size > MI_HEIGHT(mi)) ? MI_HEIGHT(mi) : size;
|
|
}
|
|
|
|
glViewport((MI_WIDTH(mi) - w) / 2, (MI_HEIGHT(mi) - h) / 2, w, h);
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
gluPerspective(65.0, (GLfloat) w / (GLfloat) h, 0.1, 2000.0); /* was 200000.0 */
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
swap_display = display;
|
|
swap_window = window;
|
|
DisplaySproingies(MI_SCREEN(mi));
|
|
} else {
|
|
MI_CLEARWINDOW(mi);
|
|
}
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
void
|
|
draw_sproingies(ModeInfo * mi)
|
|
{
|
|
Display *display = MI_DISPLAY(mi);
|
|
Window window = MI_WINDOW(mi);
|
|
sproingiesstruct *sp;
|
|
|
|
if (sproingies == NULL)
|
|
return;
|
|
sp = &sproingies[MI_SCREEN(mi)];
|
|
if (!sp->init)
|
|
return;
|
|
|
|
MI_IS_DRAWN(mi) = True;
|
|
if (!sp->glx_context)
|
|
return;
|
|
|
|
glDrawBuffer(GL_BACK);
|
|
glXMakeCurrent(display, window, *(sp->glx_context));
|
|
|
|
swap_display = display;
|
|
swap_window = window;
|
|
|
|
NextSproingieDisplay(MI_SCREEN(mi)); /* It will swap. */
|
|
}
|
|
|
|
void
|
|
refresh_sproingies(ModeInfo * mi)
|
|
{
|
|
/* No need to do anything here... The whole screen is updated
|
|
* every frame anyway. Otherwise this would be just like
|
|
* draw_sproingies, above, but replace NextSproingieDisplay(...)
|
|
* with DisplaySproingies(...).
|
|
*/
|
|
}
|
|
|
|
void
|
|
release_sproingies(ModeInfo * mi)
|
|
{
|
|
if (sproingies != NULL) {
|
|
int screen;
|
|
|
|
for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
|
|
sproingiesstruct *sp = &sproingies[screen];
|
|
|
|
if (sp->glx_context) {
|
|
|
|
glXMakeCurrent(MI_DISPLAY(mi), sp->window, *(sp->glx_context));
|
|
CleanupSproingies(screen);
|
|
}
|
|
}
|
|
|
|
free(sproingies);
|
|
sproingies = (sproingiesstruct *) NULL;
|
|
}
|
|
FreeAllGL(mi);
|
|
}
|
|
|
|
#endif
|
|
|
|
/* End of sproingiewrap.c */
|