/* lavalite --- 3D Simulation a Lava Lite, written by jwz.
*
- * This software Copyright (c) 2002-2004 Jamie Zawinski <jwz@jwz.org>
+ * This software Copyright (c) 2002-2017 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* with depth buffering turned off?
*/
-#include <X11/Intrinsic.h>
-
-extern XtAppContext app;
-
-#define PROGCLASS "LavaLite"
-#define HACK_INIT init_lavalite
-#define HACK_DRAW draw_lavalite
-#define HACK_RESHAPE reshape_lavalite
-#define HACK_HANDLE_EVENT lavalite_handle_event
-#define EVENT_MASK PointerMotionMask
-#define sws_opts xlockmore_opts
-
-#define DEF_SPIN "Z"
-#define DEF_WANDER "False"
-#define DEF_SPEED "0.003"
-#define DEF_RESOLUTION "40"
-#define DEF_SMOOTH "True"
-#define DEF_COUNT "3"
-#define DEF_STYLE "random"
-#define DEF_IMPATIENT "False"
-#define DEF_LCOLOR "#FF0000" /* lava */
-#define DEF_FCOLOR "#00AAFF" /* fluid */
-#define DEF_BCOLOR "#666666" /* base */
-#define DEF_TCOLOR "#000000" /*"#00FF00"*/ /* table */
-
-#define DEF_FTEX "(none)"
-#define DEF_BTEX "(none)"
-#define DEF_TTEX "(none)"
-
#define DEFAULTS "*delay: 30000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
- "*geometry: 600x900 \n" \
+ "*geometry: 600x900\n" \
"*count: " DEF_COUNT " \n" \
- "*style: " DEF_STYLE " \n" \
- "*speed: " DEF_SPEED " \n" \
- "*spin: " DEF_SPIN "\n" \
- "*wander: " DEF_WANDER "\n" \
- "*resolution: " DEF_RESOLUTION "\n" \
- "*smooth: " DEF_SMOOTH "\n" \
- "*impatient: " DEF_IMPATIENT " \n" \
- "*lavaColor: " DEF_LCOLOR "\n" \
- "*fluidColor: " DEF_FCOLOR "\n" \
- "*baseColor: " DEF_BCOLOR "\n" \
- "*tableColor: " DEF_TCOLOR "\n" \
- "*fluidTexture: " DEF_FTEX "\n" \
- "*baseTexture: " DEF_BTEX "\n" \
- "*tableTexture: " DEF_TTEX "\n" \
+
+# define free_lavalite 0
+# define release_lavalite 0
#define BLOBS_PER_GROUP 4
#include "marching.h"
#include "rotator.h"
#include "gltrackball.h"
-#include "xpm-ximage.h"
+#include "ximage-loader.h"
#include <ctype.h>
#ifdef USE_GL /* whole file */
-#include <GL/glu.h>
+#define DEF_SPIN "Z"
+#define DEF_WANDER "False"
+#define DEF_SPEED "0.003"
+#define DEF_RESOLUTION "40"
+#define DEF_SMOOTH "True"
+#define DEF_COUNT "3"
+#define DEF_STYLE "random"
+#define DEF_IMPATIENT "False"
+#define DEF_LCOLOR "#FF0000" /* lava */
+#define DEF_FCOLOR "#00AAFF" /* fluid */
+#define DEF_BCOLOR "#666666" /* base */
+#define DEF_TCOLOR "#000000" /*"#00FF00"*/ /* table */
+
+#define DEF_FTEX "(none)"
+#define DEF_BTEX "(none)"
+#define DEF_TTEX "(none)"
typedef struct metaball metaball;
GLfloat texture_elevation;
} lamp_geometry;
-static lamp_geometry classic_lamp[] = {
+static const lamp_geometry classic_lamp[] = {
{ CAP, 1.16, 0.089, 0.00 },
{ BOTTLE, 0.97, 0.120, 0.40 },
{ BOTTLE, 0.13, 0.300, 0.87 },
{ 0, 0, 0, 0 },
};
-static lamp_geometry giant_lamp[] = {
+static const lamp_geometry giant_lamp[] = {
{ CAP, 1.12, 0.105, 0.00 },
{ BOTTLE, 0.97, 0.130, 0.30 },
{ BOTTLE, 0.20, 0.300, 0.87 },
{ 0, 0, 0, 0 },
};
-static lamp_geometry cone_lamp[] = {
+static const lamp_geometry cone_lamp[] = {
{ CAP, 1.35, 0.001, 0.00 },
{ CAP, 1.35, 0.020, 0.00 },
{ CAP, 1.30, 0.055, 0.05 },
{ 0, 0, 0, 0 },
};
-static lamp_geometry rocket_lamp[] = {
+static const lamp_geometry rocket_lamp[] = {
{ CAP, 1.35, 0.001, 0.00 },
{ CAP, 1.34, 0.020, 0.00 },
{ CAP, 1.30, 0.055, 0.05 },
typedef struct {
GLXContext *glx_context;
lamp_style style;
- lamp_geometry *model;
+ const lamp_geometry *model;
rotator *rot;
rotator *rot2;
trackball_state *trackball;
static char *fluid_tex, *base_tex, *table_tex;
static GLfloat lava_color[4], fluid_color[4], base_color[4], table_color[4];
-static GLfloat lava_spec[4] = {1.0, 1.0, 1.0, 1.0};
-static GLfloat lava_shininess = 128.0;
-static GLfloat foot_color[4] = {0.2, 0.2, 0.2, 1.0};
-static GLfloat light0_pos[4] = {-0.6, 0.0, 1.0, 0.0};
-static GLfloat light1_pos[4] = { 1.0, 0.0, 0.2, 0.0};
-static GLfloat light2_pos[4] = { 0.6, 0.0, 1.0, 0.0};
+static const GLfloat lava_spec[4] = {1.0, 1.0, 1.0, 1.0};
+static const GLfloat lava_shininess = 128.0;
+static const GLfloat foot_color[4] = {0.2, 0.2, 0.2, 1.0};
+
+static const GLfloat light0_pos[4] = {-0.6, 0.0, 1.0, 0.0};
+static const GLfloat light1_pos[4] = { 1.0, 0.0, 0.2, 0.0};
+static const GLfloat light2_pos[4] = { 0.6, 0.0, 1.0, 0.0};
{&table_tex, "tableTexture", "BaseTexture", DEF_TTEX, t_String},
};
-ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL};
+ENTRYPOINT ModeSpecOpt lavalite_opts = {countof(opts), opts, countof(vars), vars, NULL};
/* Window management, etc
*/
-void
+ENTRYPOINT void
reshape_lavalite (ModeInfo *mi, int width, int height)
{
GLfloat h = (GLfloat) height / (GLfloat) width;
+ int y = 0;
+
+ if (width > height * 5) { /* tiny window: show middle */
+ height = width * 3;
+ y = -height/2;
+ h = height / (GLfloat) width;
+ }
- glViewport (0, 0, (GLint) width, (GLint) height);
+ glViewport (0, y, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
{
Display *dpy = mi->dpy;
Visual *visual = mi->xgwa.visual;
- Colormap cmap = mi->xgwa.colormap;
char buf[1024];
XImage *image;
return False;
}
- image = xpm_file_to_ximage (dpy, visual, cmap, filename);
+ image = file_to_ximage (dpy, visual, filename);
+ if (!image) return False;
clear_gl_error();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
static int
draw_wing (GLfloat w, GLfloat h, GLfloat d, Bool wire)
{
- static int coords[2][8][2] = {
+ static const int coords[2][8][2] = {
{ { 0, 0 },
{ 10, 10 },
{ 20, 23 },
int wire = MI_IS_WIREFRAME(mi);
int faces = resolution * 1.5;
Bool smooth = do_smooth;
- Bool have_texture = False;
- lamp_geometry *top_slice = bp->model;
+ const lamp_geometry *top_slice = bp->model;
const char *current_texture = 0;
lamp_part last_part = 0;
while (1)
{
- lamp_geometry *bot_slice = top_slice + 1;
+ const lamp_geometry *bot_slice = top_slice + 1;
const char *texture = 0;
GLfloat *color = 0;
break;
}
- have_texture = False;
if (!wire && texture && texture != current_texture)
{
current_texture = texture;
- have_texture = load_texture (mi, current_texture);
+ load_texture (mi, current_texture);
}
/* Color the discs darker than the tube walls. */
if ((top_slice->part == CAP && bot_slice->part == BOTTLE) ||
(top_slice->part == BASE && bot_slice->part == 0))
{
- lamp_geometry *sl = (bot_slice->part == 0 ? top_slice : bot_slice);
+ const lamp_geometry *sl = (bot_slice->part == 0
+ ? top_slice : bot_slice);
bp->bottle_poly_count +=
draw_disc (sl->radius, sl->elevation, faces, False, wire);
}
}
- have_texture = !wire && load_texture (mi, table_tex);
+ if (!wire) load_texture (mi, table_tex);
glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_color);
bp->bottle_poly_count += draw_table (top_slice->elevation, wire);
max_bottle_radius (lavalite_configuration *bp)
{
GLfloat r = 0;
- lamp_geometry *slice;
+ const lamp_geometry *slice;
for (slice = bp->model; slice->part != 0; slice++)
{
if (slice->part == BOTTLE && slice->radius > r)
bottle_radius_at (lavalite_configuration *bp, GLfloat z)
{
GLfloat topz = -999, botz = -999, topr = 0, botr = 0;
- lamp_geometry *slice;
+ const lamp_geometry *slice;
GLfloat ratio;
for (slice = bp->model; slice->part != 0; slice++)
/* Startup initialization
*/
-Bool
+ENTRYPOINT Bool
lavalite_handle_event (ModeInfo *mi, XEvent *event)
{
lavalite_configuration *bp = &bps[MI_SCREEN(mi)];
- if (event->xany.type == ButtonPress &&
- event->xbutton.button & Button1)
- {
- bp->button_down_p = True;
- gltrackball_start (bp->trackball,
- event->xbutton.x, event->xbutton.y,
- MI_WIDTH (mi), MI_HEIGHT (mi));
- return True;
- }
- else if (event->xany.type == ButtonRelease &&
- event->xbutton.button & Button1)
- {
- bp->button_down_p = False;
- return True;
- }
- else if (event->xany.type == MotionNotify &&
- bp->button_down_p)
- {
- gltrackball_track (bp->trackball,
- event->xmotion.x, event->xmotion.y,
- MI_WIDTH (mi), MI_HEIGHT (mi));
- return True;
- }
+ if (gltrackball_event_handler (event, bp->trackball,
+ MI_WIDTH (mi), MI_HEIGHT (mi),
+ &bp->button_down_p))
+ return True;
return False;
}
parse_color (ModeInfo *mi, const char *name, const char *s, GLfloat *a)
{
XColor c;
- a[4] = 1.0; /* alpha */
+ a[3] = 1.0; /* alpha */
if (! XParseColor (MI_DISPLAY(mi), MI_COLORMAP(mi), s, &c))
{
}
-void
+ENTRYPOINT void
init_lavalite (ModeInfo *mi)
{
lavalite_configuration *bp;
int wire = MI_IS_WIREFRAME(mi);
- if (!bps) {
- bps = (lavalite_configuration *)
- calloc (MI_NUM_SCREENS(mi), sizeof (lavalite_configuration));
- if (!bps) {
- fprintf(stderr, "%s: out of memory\n", progname);
- exit(1);
- }
-
- bp = &bps[MI_SCREEN(mi)];
- }
+ MI_INIT (mi, bps);
bp = &bps[MI_SCREEN(mi)];
if (*s == 'x' || *s == 'X') spinx = True;
else if (*s == 'y' || *s == 'Y') spiny = True;
else if (*s == 'z' || *s == 'Z') spinz = True;
+ else if (*s == '0') ;
else
{
fprintf (stderr,
bp->rot2 = make_rotator (spin_speed, 0, 0,
1, 0.1,
False);
- bp->trackball = gltrackball_init ();
-
- /* move initial camera position up by around 15 degrees:
- in other words, tilt the scene toward the viewer. */
- gltrackball_start (bp->trackball, 50, 50, 100, 100);
- gltrackball_track (bp->trackball, 50, 5, 100, 100);
-
- /* Oh, but if it's the "Giant" model, tilt the scene away: make it
- look like we're looking up at it instead of odwn at it! */
- if (bp->style == GIANT)
- gltrackball_track (bp->trackball, 50, -12, 100, 100);
- else if (bp->style == ROCKET) /* same for rocket, but not as much */
- gltrackball_track (bp->trackball, 50, -4, 100, 100);
+ bp->trackball = gltrackball_init (False);
+
+ /* Tilt the scene a bit: lean the normal lamps toward the viewer,
+ and the huge lamps away. */
+ gltrackball_reset (bp->trackball,
+ -0.3 + frand(0.6),
+ (bp->style == ROCKET || bp->style == GIANT
+ ? frand (0.2)
+ : -frand (0.6)));
}
switch (bp->style)
/* Render one frame
*/
-void
+ENTRYPOINT void
draw_lavalite (ModeInfo *mi)
{
lavalite_configuration *bp = &bps[MI_SCREEN(mi)];
if (!bp->glx_context)
return;
+ glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));
+
glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
#endif /* 0 */
glLoadIdentity();
+ glRotatef(current_device_rotation(), 0, 0, 1);
gluLookAt ((cx - 0.5) * 8, /* Position the camera */
(cy - 0.5) * 8,
gltrackball_rotate (bp->trackball); /* Apply mouse-based camera position */
+ glRotatef (-90, 1, 0, 0); /* Right side up */
+
/* Place the lights relative to the object, before the object has
been rotated or wandered within the scene. */
glXSwapBuffers(dpy, window);
}
+XSCREENSAVER_MODULE ("Lavalite", lavalite)
+
#endif /* USE_GL */