297 lines
9.4 KiB
C
297 lines
9.4 KiB
C
|
/* -*- Mode: C; tab-width: 4 -*- */
|
||
|
/* world --- world spinner */
|
||
|
|
||
|
#if !defined( lint ) && !defined( SABER )
|
||
|
static const char sccsid[] = "@(#)world.c 5.00 2000/11/01 xlockmore";
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/*-
|
||
|
* Copyright (c) 1993 Matthew Moyle-Croft <matthew@moyle-croft.com>
|
||
|
*
|
||
|
* 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.
|
||
|
*
|
||
|
* Revision History:
|
||
|
* 01-Nov-2000:
|
||
|
* 10-May-1997: Compatible with xscreensaver
|
||
|
* 04-Oct-1995: multiscreen patch, thanks to Grant McDorman <grant@isgtec.com>.
|
||
|
* 10-Jul-1995: Backward spinning jump fixed by Neale Pickett <zephyr@nmt.edu>.
|
||
|
* 17-Jul-1994: Got batchcount to work.
|
||
|
* 09-Jan-1994: Written [ Modified from image.c ]
|
||
|
* 29-Jul-1990: image.c written. Copyright (c) 1991 by Patrick J. Naughton.
|
||
|
*/
|
||
|
|
||
|
#ifdef STANDALONE
|
||
|
#define MODE_world
|
||
|
#define PROGCLASS "World"
|
||
|
#define HACK_INIT init_world
|
||
|
#define HACK_DRAW draw_world
|
||
|
#define world_opts xlockmore_opts
|
||
|
#define DEFAULTS "*delay: 100000 \n" \
|
||
|
"*count: -16 \n" \
|
||
|
"*ncolors: 200 \n"
|
||
|
#include "xlockmore.h" /* in xscreensaver distribution */
|
||
|
#else /* STANDALONE */
|
||
|
#include "xlock.h" /* in xlockmore distribution */
|
||
|
#endif /* STANDALONE */
|
||
|
|
||
|
#ifdef MODE_world
|
||
|
|
||
|
ModeSpecOpt world_opts =
|
||
|
{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
|
||
|
|
||
|
#ifdef USE_MODULES
|
||
|
ModStruct world_description =
|
||
|
{"world", "init_world", "draw_world", "release_world",
|
||
|
"refresh_world", "init_world", (char *) NULL, &world_opts,
|
||
|
100000, -16, 1, 1, 64, 0.3, "",
|
||
|
"Shows spinning Earths", 0, NULL};
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#include "bitmaps/terra-00.xbm"
|
||
|
#include "bitmaps/terra-01.xbm"
|
||
|
#include "bitmaps/terra-02.xbm"
|
||
|
#include "bitmaps/terra-03.xbm"
|
||
|
#include "bitmaps/terra-04.xbm"
|
||
|
#include "bitmaps/terra-05.xbm"
|
||
|
#include "bitmaps/terra-06.xbm"
|
||
|
#include "bitmaps/terra-07.xbm"
|
||
|
#include "bitmaps/terra-08.xbm"
|
||
|
#include "bitmaps/terra-09.xbm"
|
||
|
#include "bitmaps/terra-10.xbm"
|
||
|
#include "bitmaps/terra-11.xbm"
|
||
|
#include "bitmaps/terra-12.xbm"
|
||
|
#include "bitmaps/terra-13.xbm"
|
||
|
#include "bitmaps/terra-14.xbm"
|
||
|
#include "bitmaps/terra-15.xbm"
|
||
|
#include "bitmaps/terra-16.xbm"
|
||
|
#include "bitmaps/terra-17.xbm"
|
||
|
#include "bitmaps/terra-18.xbm"
|
||
|
#include "bitmaps/terra-19.xbm"
|
||
|
#include "bitmaps/terra-20.xbm"
|
||
|
#include "bitmaps/terra-21.xbm"
|
||
|
#include "bitmaps/terra-22.xbm"
|
||
|
#include "bitmaps/terra-23.xbm"
|
||
|
#include "bitmaps/terra-24.xbm"
|
||
|
#include "bitmaps/terra-25.xbm"
|
||
|
#include "bitmaps/terra-26.xbm"
|
||
|
#include "bitmaps/terra-27.xbm"
|
||
|
#include "bitmaps/terra-28.xbm"
|
||
|
#include "bitmaps/terra-29.xbm"
|
||
|
|
||
|
#define NUM_EARTHS 30
|
||
|
#define SIZE_X terra00_width /* 64 */
|
||
|
#define SIZE_Y terra00_height /* 64 */
|
||
|
#define NUM_REV 4
|
||
|
#define MINWORLDS 1
|
||
|
|
||
|
static XImage Earths[NUM_EARTHS] =
|
||
|
{
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra00_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra01_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra02_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra03_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra04_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra05_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra06_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra07_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra08_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra09_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra10_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra11_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra12_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra13_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra14_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra15_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra16_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra17_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra18_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra19_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra20_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra21_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra22_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra23_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra24_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra25_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra26_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra27_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra28_bits, LSBFirst, 8, LSBFirst, 8, 1},
|
||
|
{SIZE_X, SIZE_Y, 0, XYBitmap, (char *) terra29_bits, LSBFirst, 8, LSBFirst, 8, 1}};
|
||
|
|
||
|
typedef struct {
|
||
|
int x;
|
||
|
int y;
|
||
|
unsigned long color;
|
||
|
int frame;
|
||
|
int direction;
|
||
|
} planetstruct;
|
||
|
|
||
|
typedef struct {
|
||
|
int width;
|
||
|
int height;
|
||
|
int nrows;
|
||
|
int ncols;
|
||
|
int xb;
|
||
|
int yb;
|
||
|
int frame_num;
|
||
|
int nplanets;
|
||
|
planetstruct *planets;
|
||
|
} worldstruct;
|
||
|
|
||
|
static worldstruct *worlds = (worldstruct *) NULL;
|
||
|
|
||
|
void
|
||
|
init_world(ModeInfo * mi)
|
||
|
{
|
||
|
int i;
|
||
|
worldstruct *wp;
|
||
|
|
||
|
if (worlds == NULL) {
|
||
|
if ((worlds = (worldstruct *) calloc(MI_NUM_SCREENS(mi),
|
||
|
sizeof (worldstruct))) == NULL)
|
||
|
return;
|
||
|
}
|
||
|
wp = &worlds[MI_SCREEN(mi)];
|
||
|
wp->frame_num = NUM_EARTHS * NUM_REV;
|
||
|
for (i = 0; i < NUM_EARTHS; i++)
|
||
|
Earths[i].bytes_per_line = 8;
|
||
|
wp->width = MI_WIDTH(mi);
|
||
|
wp->height = MI_HEIGHT(mi);
|
||
|
wp->ncols = wp->width / SIZE_X;
|
||
|
if (!wp->ncols)
|
||
|
wp->ncols = 1;
|
||
|
wp->nrows = wp->height / SIZE_Y;
|
||
|
if (!wp->nrows)
|
||
|
wp->nrows = 1;
|
||
|
wp->xb = (wp->width - SIZE_X * wp->ncols) / 2;
|
||
|
wp->yb = (wp->height - SIZE_Y * wp->nrows) / 2;
|
||
|
wp->nplanets = MI_COUNT(mi);
|
||
|
if (wp->nplanets < -MINWORLDS)
|
||
|
wp->nplanets = NRAND(-wp->nplanets - MINWORLDS + 1) + MINWORLDS;
|
||
|
else if (wp->nplanets < MINWORLDS)
|
||
|
wp->nplanets = MINWORLDS;
|
||
|
|
||
|
if (wp->nplanets > wp->ncols * wp->nrows)
|
||
|
wp->nplanets = wp->ncols * wp->nrows;
|
||
|
#ifndef NOFLASH
|
||
|
if (wp->nplanets > wp->ncols)
|
||
|
wp->nplanets = wp->ncols;
|
||
|
#endif
|
||
|
if (wp->planets != NULL)
|
||
|
free(wp->planets);
|
||
|
if ((wp->planets = (planetstruct *) malloc(wp->nplanets *
|
||
|
sizeof (planetstruct))) == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
for (i = 0; i < wp->nplanets; i++)
|
||
|
wp->planets[i].x = wp->planets[i].y = -1;
|
||
|
|
||
|
MI_CLEARWINDOW(mi);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
draw_world(ModeInfo * mi)
|
||
|
{
|
||
|
Display *display = MI_DISPLAY(mi);
|
||
|
GC gc = MI_GC(mi);
|
||
|
int i;
|
||
|
#ifndef NOFLASH
|
||
|
int *col, j;
|
||
|
#endif
|
||
|
worldstruct *wp;
|
||
|
|
||
|
if (worlds == NULL)
|
||
|
return;
|
||
|
wp = &worlds[MI_SCREEN(mi)];
|
||
|
if (wp->planets == NULL)
|
||
|
return;
|
||
|
|
||
|
#ifndef NOFLASH
|
||
|
if ((col = (int *) calloc(wp->ncols, sizeof (int))) == NULL)
|
||
|
return;
|
||
|
#endif
|
||
|
|
||
|
MI_IS_DRAWN(mi) = True;
|
||
|
|
||
|
if (wp->frame_num == NUM_EARTHS * NUM_REV) {
|
||
|
wp->frame_num = 0;
|
||
|
XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
|
||
|
for (i = 0; i < wp->nplanets; i++) {
|
||
|
XFillRectangle(display, MI_WINDOW(mi), gc,
|
||
|
wp->xb + SIZE_X * wp->planets[i].x,
|
||
|
wp->yb + SIZE_Y * wp->planets[i].y,
|
||
|
SIZE_X, SIZE_Y);
|
||
|
#ifdef NOFLASH
|
||
|
wp->planets[i].x = NRAND(wp->ncols);
|
||
|
#else
|
||
|
do {
|
||
|
j = NRAND(wp->ncols);
|
||
|
if (!col[j])
|
||
|
wp->planets[i].x = j;
|
||
|
col[j]++;
|
||
|
} while (col[j] > 1);
|
||
|
#endif
|
||
|
wp->planets[i].y = NRAND(wp->nrows);
|
||
|
wp->planets[i].direction = (int) (LRAND() & 1);
|
||
|
wp->planets[i].frame = NRAND(NUM_EARTHS);
|
||
|
if (MI_NPIXELS(mi) > 2)
|
||
|
wp->planets[i].color = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)));
|
||
|
else
|
||
|
wp->planets[i].color = MI_WHITE_PIXEL(mi);
|
||
|
}
|
||
|
}
|
||
|
#ifndef NOFLASH
|
||
|
free(col);
|
||
|
#endif
|
||
|
for (i = 0; i < wp->nplanets; i++) {
|
||
|
XSetForeground(display, gc, wp->planets[i].color);
|
||
|
if (wp->planets[i].frame == NUM_EARTHS)
|
||
|
wp->planets[i].frame = 0;
|
||
|
else {
|
||
|
if ((wp->planets[i].frame < 0) && wp->planets[i].direction == 0)
|
||
|
wp->planets[i].frame = NUM_EARTHS - 1;
|
||
|
}
|
||
|
(void) XPutImage(display, MI_WINDOW(mi), gc,
|
||
|
(Earths + wp->planets[i].frame), 0, 0,
|
||
|
wp->xb + SIZE_X * wp->planets[i].x,
|
||
|
wp->yb + SIZE_Y * wp->planets[i].y,
|
||
|
SIZE_X, SIZE_Y);
|
||
|
|
||
|
(wp->planets[i].direction) ? wp->planets[i].frame++ : wp->planets[i].frame--;
|
||
|
}
|
||
|
wp->frame_num++;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
release_world(ModeInfo * mi)
|
||
|
{
|
||
|
if (worlds != NULL) {
|
||
|
int screen;
|
||
|
|
||
|
for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
|
||
|
if (worlds[screen].planets != NULL)
|
||
|
free(worlds[screen].planets);
|
||
|
free(worlds);
|
||
|
worlds = (worldstruct *) NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
refresh_world(ModeInfo * mi)
|
||
|
{
|
||
|
MI_CLEARWINDOW(mi);
|
||
|
}
|
||
|
|
||
|
#endif /* MODE_world */
|