OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [MW_0_8_9PRE7/] [mw/] [src/] [demos/] [nanox/] [nsaver.c] - Diff between revs 674 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 674 Rev 1765
/*
/*
 * The contents of this file are subject to the Mozilla Public License
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 * http://www.mozilla.org/MPL/
 *
 *
 * Software distributed under the License is distributed on an "AS IS"
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * License for the specific language governing rights and limitations
 * under the License.
 * under the License.
 *
 *
 * The Original Code is NanoScreenSaver.
 * The Original Code is NanoScreenSaver.
 *
 *
 * The Initial Developer of the Original Code is Alex Holden.
 * The Initial Developer of the Original Code is Alex Holden.
 * Portions created by Alex Holden are Copyright (C) 2000
 * Portions created by Alex Holden are Copyright (C) 2000
 * Alex Holden <alex@linuxhacker.org>. All Rights Reserved.
 * Alex Holden <alex@linuxhacker.org>. All Rights Reserved.
 *
 *
 * Contributor(s):
 * Contributor(s):
 *
 *
 * Alternatively, the contents of this file may be used under the terms
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU General Public license (the  "[GNU] License"), in which case the
 * of the GNU General Public license (the  "[GNU] License"), in which case the
 * provisions of [GNU] License are applicable instead of those
 * provisions of [GNU] License are applicable instead of those
 * above.  If you wish to allow use of your version of this file only
 * above.  If you wish to allow use of your version of this file only
 * under the terms of the [GNU] License and not to allow others to use
 * under the terms of the [GNU] License and not to allow others to use
 * your version of this file under the MPL, indicate your decision by
 * your version of this file under the MPL, indicate your decision by
 * deleting  the provisions above and replace  them with the notice and
 * deleting  the provisions above and replace  them with the notice and
 * other provisions required by the [GNU] License.  If you do not delete
 * other provisions required by the [GNU] License.  If you do not delete
 * the provisions above, a recipient may use your version of this file
 * the provisions above, a recipient may use your version of this file
 * under either the MPL or the [GNU] License.
 * under either the MPL or the [GNU] License.
 */
 */
/*
/*
 * A collection of screen savers for Nano-X by Alex Holden.
 * A collection of screen savers for Nano-X by Alex Holden.
 */
 */
 
 
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <time.h>
#include <time.h>
#include <math.h>
#include <math.h>
#include <sys/time.h>
#include <sys/time.h>
 
 
#define MWINCLUDECOLORS
#define MWINCLUDECOLORS
#include "nano-X.h"
#include "nano-X.h"
#include "nsaver.h"
#include "nsaver.h"
 
 
void *my_malloc(size_t size)
void *my_malloc(size_t size)
{
{
        void *ret;
        void *ret;
 
 
        if(!(ret = malloc(size))) {
        if(!(ret = malloc(size))) {
                fprintf(stderr, "Out of memory\n");
                fprintf(stderr, "Out of memory\n");
                exit(1);
                exit(1);
        }
        }
 
 
        return ret;
        return ret;
}
}
 
 
void get_random_point_on_screen(nstate *state, GR_COORD *x, GR_COORD *y,
void get_random_point_on_screen(nstate *state, GR_COORD *x, GR_COORD *y,
                                                        GR_COLOR *c)
                                                        GR_COLOR *c)
{
{
        if(x) {
        if(x) {
                *x = (int) RANDRANGE(0, (state->si.cols - 1.0));
                *x = (int) RANDRANGE(0, (state->si.cols - 1.0));
        }
        }
        if(y) {
        if(y) {
                *y = (int) RANDRANGE(0, (state->si.rows - 1.0));
                *y = (int) RANDRANGE(0, (state->si.rows - 1.0));
        }
        }
        if(c) {
        if(c) {
                *c = MWPALINDEX((int)RANDRANGE(0, (state->si.ncolors - 1)));
                *c = MWPALINDEX((int)RANDRANGE(0, (state->si.ncolors - 1)));
        }
        }
}
}
 
 
void saver1_init(nstate *state) {}
void saver1_init(nstate *state) {}
 
 
void saver1_exposure(nstate *state)
void saver1_exposure(nstate *state)
{
{
        GrClearWindow(state->main_window, 0);
        GrClearWindow(state->main_window, 0);
}
}
 
 
void saver1_animate(nstate *state) {}
void saver1_animate(nstate *state) {}
 
 
void saver2_init(nstate *state)
void saver2_init(nstate *state)
{
{
        (int)state->priv = SAVER2_MAXPIXELS;
        (int)state->priv = SAVER2_MAXPIXELS;
        state->animate_interval = SAVER2_DELAY;
        state->animate_interval = SAVER2_DELAY;
}
}
 
 
void saver2_exposure(nstate *state)
void saver2_exposure(nstate *state)
{
{
        GrClearWindow(state->main_window, 0);
        GrClearWindow(state->main_window, 0);
}
}
 
 
void saver2_animate(nstate *state)
void saver2_animate(nstate *state)
{
{
        GR_COORD x, y;
        GR_COORD x, y;
        GR_COLOR c;
        GR_COLOR c;
        int pixels = SAVER2_PIXELS_PER_FRAME;
        int pixels = SAVER2_PIXELS_PER_FRAME;
 
 
        while(pixels--) {
        while(pixels--) {
                if(!((int)state->priv--)) {
                if(!((int)state->priv--)) {
                        (int)state->priv = SAVER2_MAXPIXELS;
                        (int)state->priv = SAVER2_MAXPIXELS;
                        GrClearWindow(state->main_window, 0);
                        GrClearWindow(state->main_window, 0);
                }
                }
                get_random_point_on_screen(state, &x, &y, &c);
                get_random_point_on_screen(state, &x, &y, &c);
                GrSetGCForeground(state->main_gc, c);
                GrSetGCForeground(state->main_gc, c);
                GrPoint(state->main_window, state->main_gc, x, y);
                GrPoint(state->main_window, state->main_gc, x, y);
        }
        }
}
}
 
 
void saver3_init(nstate *state)
void saver3_init(nstate *state)
{
{
        s3state *s = my_malloc(sizeof(s3state));
        s3state *s = my_malloc(sizeof(s3state));
        state->priv = s;
        state->priv = s;
        s->maxsegments = SAVER3_MAXSEGMENTS;
        s->maxsegments = SAVER3_MAXSEGMENTS;
        s->lastx = 0;
        s->lastx = 0;
        s->lasty = 0;
        s->lasty = 0;
        state->animate_interval = SAVER3_DELAY;
        state->animate_interval = SAVER3_DELAY;
}
}
 
 
void saver3_exposure(nstate *state)
void saver3_exposure(nstate *state)
{
{
        GrClearWindow(state->main_window, 0);
        GrClearWindow(state->main_window, 0);
}
}
 
 
void saver3_animate(nstate *state)
void saver3_animate(nstate *state)
{
{
        GR_COORD newx, newy;
        GR_COORD newx, newy;
        GR_COLOR c;
        GR_COLOR c;
        s3state *s = state->priv;
        s3state *s = state->priv;
        int pixels = SAVER3_SEGMENTS_PER_FRAME;
        int pixels = SAVER3_SEGMENTS_PER_FRAME;
 
 
        while(pixels--) {
        while(pixels--) {
                if(!(s->maxsegments--)) {
                if(!(s->maxsegments--)) {
                        s->maxsegments = SAVER3_MAXSEGMENTS;
                        s->maxsegments = SAVER3_MAXSEGMENTS;
                        GrClearWindow(state->main_window, 0);
                        GrClearWindow(state->main_window, 0);
                }
                }
                get_random_point_on_screen(state, &newx, &newy, &c);
                get_random_point_on_screen(state, &newx, &newy, &c);
                GrSetGCForeground(state->main_gc, c);
                GrSetGCForeground(state->main_gc, c);
                GrLine(state->main_window, state->main_gc, s->lastx, s->lasty,
                GrLine(state->main_window, state->main_gc, s->lastx, s->lasty,
                                                        newx, newy);
                                                        newx, newy);
                s->lastx = newx;
                s->lastx = newx;
                s->lasty = newy;
                s->lasty = newy;
        }
        }
}
}
 
 
void saver4_init(nstate *state)
void saver4_init(nstate *state)
{
{
        int i;
        int i;
 
 
        s4state *s = my_malloc(sizeof(s4state));
        s4state *s = my_malloc(sizeof(s4state));
        state->priv = s;
        state->priv = s;
 
 
        s->length = 0;
        s->length = 0;
 
 
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
                s->tip = 0;
                s->tip = 0;
                get_random_point_on_screen(state, &s->worms[i].points[0].x,
                get_random_point_on_screen(state, &s->worms[i].points[0].x,
                                                &s->worms[i].points[0].y,
                                                &s->worms[i].points[0].y,
                                                &s->worms[i].colour);
                                                &s->worms[i].colour);
        }
        }
 
 
        state->animate_interval = SAVER4_DELAY;
        state->animate_interval = SAVER4_DELAY;
}
}
 
 
void saver4_exposure(nstate *state)
void saver4_exposure(nstate *state)
{
{
        int i;
        int i;
        s4state *s = state->priv;
        s4state *s = state->priv;
 
 
        GrClearWindow(state->main_window, 0);
        GrClearWindow(state->main_window, 0);
 
 
        if(!s->length) return;
        if(!s->length) return;
 
 
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
                GrSetGCForeground(state->main_gc, s->worms[i].colour);
                GrSetGCForeground(state->main_gc, s->worms[i].colour);
                GrPoints(state->main_window, state->main_gc, s->length,
                GrPoints(state->main_window, state->main_gc, s->length,
                                                        s->worms[i].points);
                                                        s->worms[i].points);
        }
        }
}
}
 
 
void saver4_get_new_worm_position(nstate *state, s4state *s, int worm,
void saver4_get_new_worm_position(nstate *state, s4state *s, int worm,
                                                GR_COORD *newx, GR_COORD *newy)
                                                GR_COORD *newx, GR_COORD *newy)
{
{
        int i;
        int i;
        GR_COORD oldx = s->worms[worm].points[s->tip].x;
        GR_COORD oldx = s->worms[worm].points[s->tip].x;
        GR_COORD oldy = s->worms[worm].points[s->tip].y;
        GR_COORD oldy = s->worms[worm].points[s->tip].y;
 
 
        do {
        do {
                i = (int)RANDRANGE(0, 3.0);
                i = (int)RANDRANGE(0, 3.0);
                switch(i) {
                switch(i) {
                        case 0:
                        case 0:
                                *newx = oldx + 1;
                                *newx = oldx + 1;
                                if(*newx == state->si.cols) *newx = 0;
                                if(*newx == state->si.cols) *newx = 0;
                                break;
                                break;
                        case 1:
                        case 1:
                                *newx = oldx - 1;
                                *newx = oldx - 1;
                                if(*newx == -1) *newx = state->si.cols - 1;
                                if(*newx == -1) *newx = state->si.cols - 1;
                                break;
                                break;
                        case 2:
                        case 2:
                                *newx = oldx;
                                *newx = oldx;
                                break;
                                break;
                }
                }
 
 
                i = (int)RANDRANGE(0, 3.0);
                i = (int)RANDRANGE(0, 3.0);
                switch(i) {
                switch(i) {
                        case 0:
                        case 0:
                                *newy = oldy + 1;
                                *newy = oldy + 1;
                                if(*newy == state->si.rows) *newy = 0;
                                if(*newy == state->si.rows) *newy = 0;
                                break;
                                break;
                        case 1:
                        case 1:
                                *newy = oldy - 1;
                                *newy = oldy - 1;
                                if(*newy == -1) *newy = state->si.rows - 1;
                                if(*newy == -1) *newy = state->si.rows - 1;
                                break;
                                break;
                        case 2:
                        case 2:
                                *newy = oldy;
                                *newy = oldy;
                                break;
                                break;
                }
                }
        } while((*newx == oldx) && (*newy == oldy));
        } while((*newx == oldx) && (*newy == oldy));
}
}
 
 
int saver4_worm_collides(nstate *state, s4state *s, int x, int y, int thisworm,
int saver4_worm_collides(nstate *state, s4state *s, int x, int y, int thisworm,
                                                                int thispoint)
                                                                int thispoint)
{
{
        int i, n;
        int i, n;
 
 
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
                for(n = 0; n < s->length; n++) {
                for(n = 0; n < s->length; n++) {
                        if((i == thisworm) && (n == thispoint)) continue;
                        if((i == thisworm) && (n == thispoint)) continue;
                        if((s->worms[i].points[n].x == x) &&
                        if((s->worms[i].points[n].x == x) &&
                                        (s->worms[i].points[n].y) == y) {
                                        (s->worms[i].points[n].y) == y) {
                                return 1;
                                return 1;
                        }
                        }
                }
                }
        }
        }
        return 0;
        return 0;
}
}
 
 
void saver4_animate(nstate *state)
void saver4_animate(nstate *state)
{
{
        int i, newx, newy, tail, newtip, tries;
        int i, newx, newy, tail, newtip, tries;
        s4state *s = state->priv;
        s4state *s = state->priv;
 
 
        if(s->length == SAVER4_WORMLENGTH) tail = s->tip + 1;
        if(s->length == SAVER4_WORMLENGTH) tail = s->tip + 1;
        else tail = 0;
        else tail = 0;
        if(tail == SAVER4_WORMLENGTH) tail = 0;
        if(tail == SAVER4_WORMLENGTH) tail = 0;
        newtip = s->tip + 1;
        newtip = s->tip + 1;
        if(newtip == SAVER4_WORMLENGTH) newtip = 0;
        if(newtip == SAVER4_WORMLENGTH) newtip = 0;
 
 
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
                if(!saver4_worm_collides(state, s, s->worms[i].points[tail].x,
                if(!saver4_worm_collides(state, s, s->worms[i].points[tail].x,
                                        s->worms[i].points[tail].y, i, tail)) {
                                        s->worms[i].points[tail].y, i, tail)) {
                        GrSetGCForeground(state->main_gc, BLACK);
                        GrSetGCForeground(state->main_gc, BLACK);
                        GrPoint(state->main_window, state->main_gc,
                        GrPoint(state->main_window, state->main_gc,
                                        s->worms[i].points[tail].x,
                                        s->worms[i].points[tail].x,
                                        s->worms[i].points[tail].y);
                                        s->worms[i].points[tail].y);
                }
                }
                for(tries = SAVER4_COLLISION_RELUCTANCE; tries; tries--) {
                for(tries = SAVER4_COLLISION_RELUCTANCE; tries; tries--) {
                                saver4_get_new_worm_position(state, s, i, &newx,
                                saver4_get_new_worm_position(state, s, i, &newx,
                                                                        &newy);
                                                                        &newy);
                        if(!saver4_worm_collides(state, s, newx, newy, -1, -1))
                        if(!saver4_worm_collides(state, s, newx, newy, -1, -1))
                                break;
                                break;
                }
                }
                s->worms[i].points[newtip].x = newx;
                s->worms[i].points[newtip].x = newx;
                s->worms[i].points[newtip].y = newy;
                s->worms[i].points[newtip].y = newy;
                if(tries) {
                if(tries) {
                        GrSetGCForeground(state->main_gc, s->worms[i].colour);
                        GrSetGCForeground(state->main_gc, s->worms[i].colour);
                        GrPoint(state->main_window, state->main_gc, newx, newy);
                        GrPoint(state->main_window, state->main_gc, newx, newy);
                }
                }
        }
        }
 
 
        s->tip = newtip;
        s->tip = newtip;
        if(s->length < SAVER4_WORMLENGTH) s->length++;
        if(s->length < SAVER4_WORMLENGTH) s->length++;
}
}
 
 
void saver5_init(nstate *state)
void saver5_init(nstate *state)
{
{
        int i;
        int i;
 
 
        s5state *s = my_malloc(sizeof(s5state));
        s5state *s = my_malloc(sizeof(s5state));
        state->priv = s;
        state->priv = s;
 
 
        s->numstars = 0;
        s->numstars = 0;
 
 
        for(i = 0; i < SAVER5_NUMSTARS; i++) {
        for(i = 0; i < SAVER5_NUMSTARS; i++) {
                s->stars[i].angle = RANDRANGE(0, (2 * M_PI));
                s->stars[i].angle = RANDRANGE(0, (2 * M_PI));
                s->stars[i].pos = 1;
                s->stars[i].pos = 1;
        }
        }
 
 
        state->animate_interval = SAVER5_DELAY;
        state->animate_interval = SAVER5_DELAY;
}
}
 
 
int saver5_drawstar(nstate *state, s5state *s, int star, int delete)
int saver5_drawstar(nstate *state, s5state *s, int star, int delete)
{
{
        int opp, adj;
        int opp, adj;
        GR_COORD x, y;
        GR_COORD x, y;
 
 
        if(delete) GrSetGCForeground(state->main_gc, BLACK);
        if(delete) GrSetGCForeground(state->main_gc, BLACK);
        else GrSetGCForeground(state->main_gc, WHITE);
        else GrSetGCForeground(state->main_gc, WHITE);
 
 
        opp = (int)(sin(s->stars[star].angle) * s->stars[star].pos);
        opp = (int)(sin(s->stars[star].angle) * s->stars[star].pos);
        adj = (int)(cos(s->stars[star].angle) * s->stars[star].pos);
        adj = (int)(cos(s->stars[star].angle) * s->stars[star].pos);
 
 
        x = (state->si.cols / 2) + adj;
        x = (state->si.cols / 2) + adj;
        y = (state->si.rows / 2) + opp;
        y = (state->si.rows / 2) + opp;
 
 
        if((x < 0) || (y < 0) || (x >= state->si.cols) || (y >= state->si.rows))
        if((x < 0) || (y < 0) || (x >= state->si.cols) || (y >= state->si.rows))
                return 1;
                return 1;
 
 
        GrPoint(state->main_window, state->main_gc, x, y);
        GrPoint(state->main_window, state->main_gc, x, y);
 
 
        return 0;
        return 0;
}
}
 
 
void saver5_exposure(nstate *state)
void saver5_exposure(nstate *state)
{
{
        int i;
        int i;
        s5state *s = state->priv;
        s5state *s = state->priv;
 
 
        GrClearWindow(state->main_window, 0);
        GrClearWindow(state->main_window, 0);
 
 
        for(i = 0; i < SAVER5_NUMSTARS; i++) {
        for(i = 0; i < SAVER5_NUMSTARS; i++) {
                saver5_drawstar(state, s, i, 0);
                saver5_drawstar(state, s, i, 0);
        }
        }
}
}
 
 
void saver5_animate(nstate *state)
void saver5_animate(nstate *state)
{
{
        int i;
        int i;
        double position, scale, increment;
        double position, scale, increment;
        s5state *s = state->priv;
        s5state *s = state->priv;
 
 
        if(s->numstars < SAVER5_NUMSTARS) {
        if(s->numstars < SAVER5_NUMSTARS) {
                s->numstars += SAVER5_STARS_INCREMENT;
                s->numstars += SAVER5_STARS_INCREMENT;
                if(s->numstars > SAVER5_NUMSTARS)
                if(s->numstars > SAVER5_NUMSTARS)
                        s->numstars = SAVER5_NUMSTARS;
                        s->numstars = SAVER5_NUMSTARS;
        }
        }
 
 
        for(i = 0; i < s->numstars; i++) {
        for(i = 0; i < s->numstars; i++) {
                saver5_drawstar(state, s, i, 1);
                saver5_drawstar(state, s, i, 1);
                position = (double)s->stars[i].pos /
                position = (double)s->stars[i].pos /
                                (double)(state->si.cols / 2);
                                (double)(state->si.cols / 2);
                scale = sin((position * M_PI_2) + M_PI + M_PI_2) + 1.0;
                scale = sin((position * M_PI_2) + M_PI + M_PI_2) + 1.0;
                increment = (scale * SAVER5_STARS_ACCEL_RATE) + 1;
                increment = (scale * SAVER5_STARS_ACCEL_RATE) + 1;
                s->stars[i].pos += (int) increment;
                s->stars[i].pos += (int) increment;
                if(saver5_drawstar(state, s, i, 0)) {
                if(saver5_drawstar(state, s, i, 0)) {
                        s->stars[i].pos = 1;
                        s->stars[i].pos = 1;
                        s->stars[i].angle = RANDRANGE(0, (2 * M_PI));
                        s->stars[i].angle = RANDRANGE(0, (2 * M_PI));
                        saver5_drawstar(state, s, i, 0);
                        saver5_drawstar(state, s, i, 0);
                }
                }
        }
        }
}
}
 
 
void saver6_init(nstate *state)
void saver6_init(nstate *state)
{
{
        int i, n;
        int i, n;
 
 
        s6state *s = my_malloc(sizeof(s6state));
        s6state *s = my_malloc(sizeof(s6state));
        state->priv = s;
        state->priv = s;
 
 
        s->new_bolt_time = 0;
        s->new_bolt_time = 0;
 
 
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
                s->bolts[i].duration = 0;
                s->bolts[i].duration = 0;
                for(n = 0; n < SAVER6_MAXFORKS; n++) {
                for(n = 0; n < SAVER6_MAXFORKS; n++) {
                        s->bolts[i].forks[n].valid = 0;
                        s->bolts[i].forks[n].valid = 0;
                }
                }
        }
        }
 
 
        state->animate_interval = SAVER6_DELAY;
        state->animate_interval = SAVER6_DELAY;
}
}
 
 
void saver6_drawfork(nstate *state, s6state *s, int bolt, int fork, int delete)
void saver6_drawfork(nstate *state, s6state *s, int bolt, int fork, int delete)
{
{
        int i;
        int i;
 
 
        if(delete) GrSetGCForeground(state->main_gc, BLACK);
        if(delete) GrSetGCForeground(state->main_gc, BLACK);
        for(i = 0; i < SAVER6_THICKNESS; i++) {
        for(i = 0; i < SAVER6_THICKNESS; i++) {
                if(!delete) {
                if(!delete) {
                        if((i < 2) || (i >= SAVER6_THICKNESS - 2))
                        if((i < 2) || (i >= SAVER6_THICKNESS - 2))
                                 GrSetGCForeground(state->main_gc, LTBLUE);
                                 GrSetGCForeground(state->main_gc, LTBLUE);
                        else GrSetGCForeground(state->main_gc, WHITE);
                        else GrSetGCForeground(state->main_gc, WHITE);
                }
                }
                GrPoly(state->main_window, state->main_gc,
                GrPoly(state->main_window, state->main_gc,
                                s->bolts[bolt].forks[fork].valid,
                                s->bolts[bolt].forks[fork].valid,
                                s->bolts[bolt].forks[fork].vertices[i]);
                                s->bolts[bolt].forks[fork].vertices[i]);
        }
        }
}
}
 
 
void saver6_drawbolt(nstate *state, s6state *s, int bolt, int delete)
void saver6_drawbolt(nstate *state, s6state *s, int bolt, int delete)
{
{
        int n;
        int n;
 
 
        for(n = 0; n < SAVER6_MAXFORKS; n++)
        for(n = 0; n < SAVER6_MAXFORKS; n++)
                if(s->bolts[bolt].forks[n].valid)
                if(s->bolts[bolt].forks[n].valid)
                        saver6_drawfork(state, s, bolt, n, delete);
                        saver6_drawfork(state, s, bolt, n, delete);
}
}
 
 
void saver6_drawlightning(nstate *state, s6state *s, int delete)
void saver6_drawlightning(nstate *state, s6state *s, int delete)
{
{
        int i;
        int i;
 
 
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
                if(s->bolts[i].duration) {
                if(s->bolts[i].duration) {
                        if(delete) s->bolts[i].duration--;
                        if(delete) s->bolts[i].duration--;
                        saver6_drawbolt(state, s, i, delete);
                        saver6_drawbolt(state, s, i, delete);
                }
                }
        }
        }
}
}
 
 
void saver6_exposure(nstate *state)
void saver6_exposure(nstate *state)
{
{
        s6state *s = state->priv;
        s6state *s = state->priv;
 
 
        GrClearWindow(state->main_window, 0);
        GrClearWindow(state->main_window, 0);
 
 
        saver6_drawlightning(state, s, 0);
        saver6_drawlightning(state, s, 0);
}
}
 
 
void saver6_setvertices(s6state *s, int bolt, int fork, int vert, GR_COORD x,
void saver6_setvertices(s6state *s, int bolt, int fork, int vert, GR_COORD x,
                                                                GR_COORD y)
                                                                GR_COORD y)
{
{
        int i;
        int i;
 
 
        for(i = 0; i < SAVER6_THICKNESS; i++) {
        for(i = 0; i < SAVER6_THICKNESS; i++) {
                s->bolts[bolt].forks[fork].vertices[i][vert].x = x + i;
                s->bolts[bolt].forks[fork].vertices[i][vert].x = x + i;
                s->bolts[bolt].forks[fork].vertices[i][vert].y = y;
                s->bolts[bolt].forks[fork].vertices[i][vert].y = y;
        }
        }
}
}
 
 
void saver6_perturb(nstate *state, GR_COORD *x, GR_COORD *y, int maxperturb)
void saver6_perturb(nstate *state, GR_COORD *x, GR_COORD *y, int maxperturb)
{
{
        *x += (int)RANDRANGE(0, (maxperturb - 1.0)) -
        *x += (int)RANDRANGE(0, (maxperturb - 1.0)) -
                                (double)(maxperturb / 2.0);
                                (double)(maxperturb / 2.0);
        if(*x < 0) *x = 0;
        if(*x < 0) *x = 0;
        if(*x > (state->si.cols - 1)) *x = state->si.cols - 1;
        if(*x > (state->si.cols - 1)) *x = state->si.cols - 1;
 
 
        *y += (int)RANDRANGE(0, (maxperturb - 1.0)) -
        *y += (int)RANDRANGE(0, (maxperturb - 1.0)) -
                                (double)(maxperturb / 2.0);
                                (double)(maxperturb / 2.0);
        if(*y < 0) *y = 0;
        if(*y < 0) *y = 0;
        if(*y > (state->si.cols - 1)) *y = state->si.cols - 1;
        if(*y > (state->si.cols - 1)) *y = state->si.cols - 1;
}
}
 
 
void saver6_makefork(nstate *state, s6state *s, int bolt, int fork, GR_COORD x,
void saver6_makefork(nstate *state, s6state *s, int bolt, int fork, GR_COORD x,
                                                                GR_COORD y)
                                                                GR_COORD y)
{
{
        int i, vertices;
        int i, vertices;
        double length, incr, pos, angle, scale;
        double length, incr, pos, angle, scale;
        GR_COORD ex, ey, nx, ny, xlen, ylen;
        GR_COORD ex, ey, nx, ny, xlen, ylen;
 
 
        saver6_setvertices(s, bolt, fork, 0, x , y);
        saver6_setvertices(s, bolt, fork, 0, x , y);
 
 
        scale = (double)(state->si.rows - y) / (double)state->si.rows;
        scale = (double)(state->si.rows - y) / (double)state->si.rows;
 
 
        vertices = (int)(scale * RANDRANGE(SAVER6_MINFULLVERTICES,
        vertices = (int)(scale * RANDRANGE(SAVER6_MINFULLVERTICES,
                                                SAVER6_MAXVERTICES));
                                                SAVER6_MAXVERTICES));
 
 
        if(vertices < SAVER6_MINVERTICES) vertices = SAVER6_MINVERTICES;
        if(vertices < SAVER6_MINVERTICES) vertices = SAVER6_MINVERTICES;
 
 
        s->bolts[bolt].forks[fork].valid = vertices;
        s->bolts[bolt].forks[fork].valid = vertices;
 
 
        ey = state->si.rows - SAVER6_MAXEND_Y +
        ey = state->si.rows - SAVER6_MAXEND_Y +
                (int)RANDRANGE(0, SAVER6_MAXEND_Y - 1.0);
                (int)RANDRANGE(0, SAVER6_MAXEND_Y - 1.0);
        if((ey - y) <= 0) ey = SAVER6_MINDROP;
        if((ey - y) <= 0) ey = SAVER6_MINDROP;
        if(ey >= (state->si.rows - 1)) ey = state->si.rows - 1;
        if(ey >= (state->si.rows - 1)) ey = state->si.rows - 1;
 
 
        if(!fork) {
        if(!fork) {
                ex = x + (int)RANDRANGE(0, ((state->si.cols - 1.0) / 2.0));
                ex = x + (int)RANDRANGE(0, ((state->si.cols - 1.0) / 2.0));
        } else {
        } else {
                ex = x + (int)(RANDRANGE(0, (ey - y)) / 2.0) - ((ey - y) / 2.0);
                ex = x + (int)(RANDRANGE(0, (ey - y)) / 2.0) - ((ey - y) / 2.0);
        }
        }
 
 
        if(ex >= state->si.cols) ex = state->si.cols - 1;
        if(ex >= state->si.cols) ex = state->si.cols - 1;
        if(ex < 0) ex = 0;
        if(ex < 0) ex = 0;
 
 
        xlen = MAX(x, ex) - MIN(x, ex);
        xlen = MAX(x, ex) - MIN(x, ex);
        ylen = MAX(y, ey) - MIN(y, ey);
        ylen = MAX(y, ey) - MIN(y, ey);
 
 
        length = sqrt(((double)(xlen * xlen) + (double)(ylen * ylen)));
        length = sqrt(((double)(xlen * xlen) + (double)(ylen * ylen)));
        incr = length / (vertices - 1);
        incr = length / (vertices - 1);
        angle = atan(((double)xlen / (double)ylen));
        angle = atan(((double)xlen / (double)ylen));
 
 
        for(i = vertices - 1; i ; i--) {
        for(i = vertices - 1; i ; i--) {
                pos = (incr * (i - 1)) + (RANDRANGE(0, SAVER6_MAXZIGZAG) -
                pos = (incr * (i - 1)) + (RANDRANGE(0, SAVER6_MAXZIGZAG) -
                                        ((double)SAVER6_MAXZIGZAG / 2.0));
                                        ((double)SAVER6_MAXZIGZAG / 2.0));
                if(pos < 0) pos = 0;
                if(pos < 0) pos = 0;
                if(pos > length) pos = length;
                if(pos > length) pos = length;
                nx = x - (pos * sin(angle));
                nx = x - (pos * sin(angle));
                ny = y + pos * cos(angle);
                ny = y + pos * cos(angle);
                saver6_perturb(state, &nx, &ny, SAVER6_MAXZIGZAG);
                saver6_perturb(state, &nx, &ny, SAVER6_MAXZIGZAG);
                saver6_setvertices(s, bolt, fork, i, nx , ny);
                saver6_setvertices(s, bolt, fork, i, nx , ny);
        }
        }
}
}
 
 
int saver6_makeforks(nstate *state, s6state *s, int bolt, int fork,
int saver6_makeforks(nstate *state, s6state *s, int bolt, int fork,
                                                int *vert, int *nextfork)
                                                int *vert, int *nextfork)
{
{
        int thisvert = 1, thisfork;
        int thisvert = 1, thisfork;
        double prob;
        double prob;
 
 
        if(*vert == (s->bolts[bolt].forks[fork].valid - 1)) return 0;
        if(*vert == (s->bolts[bolt].forks[fork].valid - 1)) return 0;
        if(*nextfork == SAVER6_MAXFORKS) return 0;
        if(*nextfork == SAVER6_MAXFORKS) return 0;
 
 
        prob = (double)SAVER6_FORK_PROBABILITY * ((double)*vert /
        prob = (double)SAVER6_FORK_PROBABILITY * ((double)*vert /
                                (double)s->bolts[bolt].forks[fork].valid) *
                                (double)s->bolts[bolt].forks[fork].valid) *
                                        (1.0 / ((double)fork + 1.0));
                                        (1.0 / ((double)fork + 1.0));
        if(RANDRANGE(0, 1) < prob) {
        if(RANDRANGE(0, 1) < prob) {
                thisfork = *nextfork;
                thisfork = *nextfork;
                saver6_makefork(state, s, bolt, thisfork,
                saver6_makefork(state, s, bolt, thisfork,
                        s->bolts[bolt].forks[fork].vertices[0][*vert].x,
                        s->bolts[bolt].forks[fork].vertices[0][*vert].x,
                        s->bolts[bolt].forks[fork].vertices[0][*vert].y);
                        s->bolts[bolt].forks[fork].vertices[0][*vert].y);
                *nextfork += 1;
                *nextfork += 1;
                while(saver6_makeforks(state, s, bolt, thisfork, &thisvert,
                while(saver6_makeforks(state, s, bolt, thisfork, &thisvert,
                                                                nextfork));
                                                                nextfork));
        }
        }
 
 
        *vert += 1;
        *vert += 1;
 
 
        return 1;
        return 1;
}
}
 
 
void saver6_makebolt(nstate *state, s6state *s, int bolt)
void saver6_makebolt(nstate *state, s6state *s, int bolt)
{
{
        GR_COORD x;
        GR_COORD x;
        int vert = 1, nextfork = 1, n;
        int vert = 1, nextfork = 1, n;
 
 
        for(n = 0; n < SAVER6_MAXFORKS; n++)
        for(n = 0; n < SAVER6_MAXFORKS; n++)
                s->bolts[bolt].forks[n].valid = 0;
                s->bolts[bolt].forks[n].valid = 0;
 
 
        x = (int)RANDRANGE(0, (state->si.cols - 1.0));
        x = (int)RANDRANGE(0, (state->si.cols - 1.0));
 
 
        saver6_makefork(state, s, bolt, 0, x, 0);
        saver6_makefork(state, s, bolt, 0, x, 0);
 
 
        while(saver6_makeforks(state, s, bolt, 0, &vert, &nextfork));
        while(saver6_makeforks(state, s, bolt, 0, &vert, &nextfork));
}
}
 
 
void saver6_newbolt(nstate *state, s6state *s)
void saver6_newbolt(nstate *state, s6state *s)
{
{
        int i;
        int i;
 
 
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
                if(!s->bolts[i].duration) {
                if(!s->bolts[i].duration) {
                        saver6_makebolt(state, s, i);
                        saver6_makebolt(state, s, i);
                        s->bolts[i].duration = RANDRANGE(SAVER6_MINDURATION,
                        s->bolts[i].duration = RANDRANGE(SAVER6_MINDURATION,
                                                        SAVER6_MAXDURATION);
                                                        SAVER6_MAXDURATION);
                        saver6_drawbolt(state, s, i, 0);
                        saver6_drawbolt(state, s, i, 0);
                        break;
                        break;
                }
                }
        }
        }
 
 
        s->new_bolt_time = RANDRANGE(1, SAVER6_MAXNEWBOLTTIME);
        s->new_bolt_time = RANDRANGE(1, SAVER6_MAXNEWBOLTTIME);
}
}
 
 
void saver6_perturb_bolt(nstate *state, s6state *s, int bolt, int fork)
void saver6_perturb_bolt(nstate *state, s6state *s, int bolt, int fork)
{
{
        int m, o;
        int m, o;
        GR_COORD x, ox, y, oy;
        GR_COORD x, ox, y, oy;
 
 
        for(m = 1; m < s->bolts[bolt].forks[fork].valid; m++) {
        for(m = 1; m < s->bolts[bolt].forks[fork].valid; m++) {
                ox = x = s->bolts[bolt].forks[fork].vertices[0][m].x;
                ox = x = s->bolts[bolt].forks[fork].vertices[0][m].x;
                oy = y = s->bolts[bolt].forks[fork].vertices[0][m].y;
                oy = y = s->bolts[bolt].forks[fork].vertices[0][m].y;
                saver6_perturb(state, &x, &y, SAVER6_MAXZIGZAG);
                saver6_perturb(state, &x, &y, SAVER6_MAXZIGZAG);
                saver6_setvertices(s, bolt, fork, m, x, y);
                saver6_setvertices(s, bolt, fork, m, x, y);
                for(o = fork + 1; o < SAVER6_MAXFORKS; o++) {
                for(o = fork + 1; o < SAVER6_MAXFORKS; o++) {
                        if((s->bolts[bolt].forks[o].vertices[0][0].x == ox) &&
                        if((s->bolts[bolt].forks[o].vertices[0][0].x == ox) &&
                                (s->bolts[bolt].forks[o].vertices[0][0].y
                                (s->bolts[bolt].forks[o].vertices[0][0].y
                                                                == oy)) {
                                                                == oy)) {
                                saver6_setvertices(s, bolt, o, 0, x, y);
                                saver6_setvertices(s, bolt, o, 0, x, y);
                        }
                        }
                }
                }
        }
        }
}
}
 
 
void saver6_perturb_lightning(nstate *state, s6state *s)
void saver6_perturb_lightning(nstate *state, s6state *s)
{
{
        int i, n;
        int i, n;
 
 
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
                if(!s->bolts[i].duration) continue;
                if(!s->bolts[i].duration) continue;
                for(n = 0; n < SAVER6_MAXFORKS; n++) {
                for(n = 0; n < SAVER6_MAXFORKS; n++) {
                        if(!s->bolts[i].forks[n].valid) continue;
                        if(!s->bolts[i].forks[n].valid) continue;
                        saver6_perturb_bolt(state, s, i, n);
                        saver6_perturb_bolt(state, s, i, n);
                }
                }
        }
        }
}
}
 
 
void saver6_animate(nstate *state)
void saver6_animate(nstate *state)
{
{
        s6state *s = state->priv;
        s6state *s = state->priv;
 
 
        saver6_drawlightning(state, s, 1);
        saver6_drawlightning(state, s, 1);
        saver6_perturb_lightning(state, s);
        saver6_perturb_lightning(state, s);
        saver6_drawlightning(state, s, 0);
        saver6_drawlightning(state, s, 0);
 
 
        if(!s->new_bolt_time--) saver6_newbolt(state, s);
        if(!s->new_bolt_time--) saver6_newbolt(state, s);
}
}
 
 
/* The algorithm used in saver7 was adapted from "grav" by Greg Bowering */
/* The algorithm used in saver7 was adapted from "grav" by Greg Bowering */
 
 
void saver7_drawstar(nstate *state, s7state *s)
void saver7_drawstar(nstate *state, s7state *s)
{
{
        GrSetGCForeground(state->main_gc, SAVER7_STARCOLOUR);
        GrSetGCForeground(state->main_gc, SAVER7_STARCOLOUR);
        GrFillEllipse(state->main_window, state->main_gc, s->starx, s->stary,
        GrFillEllipse(state->main_window, state->main_gc, s->starx, s->stary,
                                SAVER7_STARRADIUS, SAVER7_STARRADIUS);
                                SAVER7_STARRADIUS, SAVER7_STARRADIUS);
}
}
 
 
void saver7_drawplanet(nstate *state, s7state *s, int planet, int erase)
void saver7_drawplanet(nstate *state, s7state *s, int planet, int erase)
{
{
        if(erase) GrSetGCForeground(state->main_gc, BLACK);
        if(erase) GrSetGCForeground(state->main_gc, BLACK);
        else GrSetGCForeground(state->main_gc, s->planets[planet].colour);
        else GrSetGCForeground(state->main_gc, s->planets[planet].colour);
 
 
        if((s->planets[planet].ax < 0) || (s->planets[planet].ay < 0) ||
        if((s->planets[planet].ax < 0) || (s->planets[planet].ay < 0) ||
                        (s->planets[planet].ax >= state->si.cols) ||
                        (s->planets[planet].ax >= state->si.cols) ||
                        (s->planets[planet].ay >= state->si.rows)) {
                        (s->planets[planet].ay >= state->si.rows)) {
                return;
                return;
        }
        }
 
 
        GrFillEllipse(state->main_window, state->main_gc, s->planets[planet].ax,
        GrFillEllipse(state->main_window, state->main_gc, s->planets[planet].ax,
                                s->planets[planet].ay,
                                s->planets[planet].ay,
                                SAVER7_PLANETRADIUS, SAVER7_PLANETRADIUS);
                                SAVER7_PLANETRADIUS, SAVER7_PLANETRADIUS);
}
}
 
 
void saver7_calc_planet_position(nstate *state, s7state *s, int planet)
void saver7_calc_planet_position(nstate *state, s7state *s, int planet)
{
{
        if(s->planets[planet].r > -SAVER7_ALMOSTDIST) {
        if(s->planets[planet].r > -SAVER7_ALMOSTDIST) {
                s->planets[planet].ax = (int)((double) state->si.cols *
                s->planets[planet].ax = (int)((double) state->si.cols *
                        (0.5 + (s->planets[planet].x / (s->planets[planet].r +
                        (0.5 + (s->planets[planet].x / (s->planets[planet].r +
                                                        SAVER7_DIST))));
                                                        SAVER7_DIST))));
                s->planets[planet].ay = (int)((double) state->si.rows *
                s->planets[planet].ay = (int)((double) state->si.rows *
                        (0.5 + (s->planets[planet].y / (s->planets[planet].r +
                        (0.5 + (s->planets[planet].y / (s->planets[planet].r +
                                                        SAVER7_DIST))));
                                                        SAVER7_DIST))));
        } else {
        } else {
                s->planets[planet].ax = -1;
                s->planets[planet].ax = -1;
                s->planets[planet].ay = -1;
                s->planets[planet].ay = -1;
        }
        }
}
}
 
 
void saver7_init(nstate *state)
void saver7_init(nstate *state)
{
{
        int i;
        int i;
        s7state *s = my_malloc(sizeof(s7state));
        s7state *s = my_malloc(sizeof(s7state));
        state->priv = s;
        state->priv = s;
 
 
        s->starx = state->si.cols / 2;
        s->starx = state->si.cols / 2;
        s->stary = state->si.rows / 2;
        s->stary = state->si.rows / 2;
 
 
        for(i = 0; i < SAVER7_PLANETS; i++) {
        for(i = 0; i < SAVER7_PLANETS; i++) {
                s->planets[i].r = RANDRANGE(SAVER7_MIN_STARTDIM,
                s->planets[i].r = RANDRANGE(SAVER7_MIN_STARTDIM,
                                                SAVER7_MAX_STARTDIM);
                                                SAVER7_MAX_STARTDIM);
                s->planets[i].x = RANDRANGE(SAVER7_MIN_STARTDIM,
                s->planets[i].x = RANDRANGE(SAVER7_MIN_STARTDIM,
                                                SAVER7_MAX_STARTDIM);
                                                SAVER7_MAX_STARTDIM);
                s->planets[i].y = RANDRANGE(SAVER7_MIN_STARTDIM,
                s->planets[i].y = RANDRANGE(SAVER7_MIN_STARTDIM,
                                                SAVER7_MAX_STARTDIM);
                                                SAVER7_MAX_STARTDIM);
                s->planets[i].rv = RANDRANGE(SAVER7_MIN_STARTVEL,
                s->planets[i].rv = RANDRANGE(SAVER7_MIN_STARTVEL,
                                                SAVER7_MAX_STARTVEL);
                                                SAVER7_MAX_STARTVEL);
                s->planets[i].xv = RANDRANGE(SAVER7_MIN_STARTVEL,
                s->planets[i].xv = RANDRANGE(SAVER7_MIN_STARTVEL,
                                                SAVER7_MAX_STARTVEL);
                                                SAVER7_MAX_STARTVEL);
                s->planets[i].yv = RANDRANGE(SAVER7_MIN_STARTVEL,
                s->planets[i].yv = RANDRANGE(SAVER7_MIN_STARTVEL,
                                                SAVER7_MAX_STARTVEL);
                                                SAVER7_MAX_STARTVEL);
                s->planets[i].colour = RANDRANGE(0, (state->si.ncolors - 1));
                s->planets[i].colour = RANDRANGE(0, (state->si.ncolors - 1));
                saver7_calc_planet_position(state, s, i);
                saver7_calc_planet_position(state, s, i);
                saver7_drawplanet(state, s, i, 0);
                saver7_drawplanet(state, s, i, 0);
        }
        }
 
 
        saver7_drawstar(state, s);
        saver7_drawstar(state, s);
 
 
        state->animate_interval = SAVER7_DELAY;
        state->animate_interval = SAVER7_DELAY;
}
}
 
 
void saver7_exposure(nstate *state)
void saver7_exposure(nstate *state)
{
{
        int i;
        int i;
        s7state *s = state->priv;
        s7state *s = state->priv;
 
 
        GrClearWindow(state->main_window, 0);
        GrClearWindow(state->main_window, 0);
 
 
        for(i = 0; i < SAVER7_PLANETS; i++)
        for(i = 0; i < SAVER7_PLANETS; i++)
                saver7_drawplanet(state, s, i, 0);
                saver7_drawplanet(state, s, i, 0);
 
 
        saver7_drawstar(state, s);
        saver7_drawstar(state, s);
}
}
 
 
void saver7_moveplanet(nstate *state, s7state *s, int planet)
void saver7_moveplanet(nstate *state, s7state *s, int planet)
{
{
        double dist;
        double dist;
        double accel;
        double accel;
 
 
        dist = (s->planets[planet].x * s->planets[planet].x) +
        dist = (s->planets[planet].x * s->planets[planet].x) +
                (s->planets[planet].y * s->planets[planet].y) +
                (s->planets[planet].y * s->planets[planet].y) +
                (s->planets[planet].r * s->planets[planet].r);
                (s->planets[planet].r * s->planets[planet].r);
        if(dist < SAVER7_COLLIDE) dist = SAVER7_COLLIDE;
        if(dist < SAVER7_COLLIDE) dist = SAVER7_COLLIDE;
        dist = sqrt(dist);
        dist = sqrt(dist);
        dist = dist * dist * dist;
        dist = dist * dist * dist;
 
 
#ifdef SAVER7_USE_DAMPING
#ifdef SAVER7_USE_DAMPING
        accel = s->planets[planet].r * SAVER7_G / dist;
        accel = s->planets[planet].r * SAVER7_G / dist;
        if(accel > SAVER7_MAX_ACCEL) accel = SAVER7_MAX_ACCEL;
        if(accel > SAVER7_MAX_ACCEL) accel = SAVER7_MAX_ACCEL;
        else if(accel < -SAVER7_MAX_ACCEL) accel = -SAVER7_MAX_ACCEL;
        else if(accel < -SAVER7_MAX_ACCEL) accel = -SAVER7_MAX_ACCEL;
        s->planets[planet].rv = (s->planets[planet].rv + accel) *
        s->planets[planet].rv = (s->planets[planet].rv + accel) *
                                                SAVER7_DAMPING_FACTOR;
                                                SAVER7_DAMPING_FACTOR;
        s->planets[planet].r += s->planets[planet].rv;
        s->planets[planet].r += s->planets[planet].rv;
        accel = s->planets[planet].x * SAVER7_G / dist;
        accel = s->planets[planet].x * SAVER7_G / dist;
        if(accel > SAVER7_MAX_ACCEL) accel = SAVER7_MAX_ACCEL;
        if(accel > SAVER7_MAX_ACCEL) accel = SAVER7_MAX_ACCEL;
        else if(accel < -SAVER7_MAX_ACCEL) accel = -SAVER7_MAX_ACCEL;
        else if(accel < -SAVER7_MAX_ACCEL) accel = -SAVER7_MAX_ACCEL;
        s->planets[planet].xv = (s->planets[planet].xv + accel) *
        s->planets[planet].xv = (s->planets[planet].xv + accel) *
                                                SAVER7_DAMPING_FACTOR;
                                                SAVER7_DAMPING_FACTOR;
        s->planets[planet].x += s->planets[planet].xv;
        s->planets[planet].x += s->planets[planet].xv;
        accel = s->planets[planet].y * SAVER7_G / dist;
        accel = s->planets[planet].y * SAVER7_G / dist;
        if(accel > SAVER7_MAX_ACCEL) accel = SAVER7_MAX_ACCEL;
        if(accel > SAVER7_MAX_ACCEL) accel = SAVER7_MAX_ACCEL;
        else if(accel < -SAVER7_MAX_ACCEL) accel = -SAVER7_MAX_ACCEL;
        else if(accel < -SAVER7_MAX_ACCEL) accel = -SAVER7_MAX_ACCEL;
        s->planets[planet].yv = (s->planets[planet].yv + accel) *
        s->planets[planet].yv = (s->planets[planet].yv + accel) *
                                                SAVER7_DAMPING_FACTOR;
                                                SAVER7_DAMPING_FACTOR;
        s->planets[planet].y += s->planets[planet].yv;
        s->planets[planet].y += s->planets[planet].yv;
#else
#else
        accel = s->planets[planet].r * SAVER7_G / dist;
        accel = s->planets[planet].r * SAVER7_G / dist;
        s->planets[planet].rv += accel;
        s->planets[planet].rv += accel;
        s->planets[planet].r += s->planets[planet].rv;
        s->planets[planet].r += s->planets[planet].rv;
        accel = s->planets[planet].x * SAVER7_G / dist;
        accel = s->planets[planet].x * SAVER7_G / dist;
        s->planets[planet].xv += accel;
        s->planets[planet].xv += accel;
        s->planets[planet].x += s->planets[planet].xv;
        s->planets[planet].x += s->planets[planet].xv;
        accel = s->planets[planet].y * SAVER7_G / dist;
        accel = s->planets[planet].y * SAVER7_G / dist;
        s->planets[planet].yv += accel;
        s->planets[planet].yv += accel;
        s->planets[planet].y += s->planets[planet].yv;
        s->planets[planet].y += s->planets[planet].yv;
#endif
#endif
}
}
 
 
void saver7_animate(nstate *state)
void saver7_animate(nstate *state)
{
{
        int i;
        int i;
        s7state *s = state->priv;
        s7state *s = state->priv;
 
 
        for(i = 0; i < SAVER7_PLANETS; i++) {
        for(i = 0; i < SAVER7_PLANETS; i++) {
                saver7_moveplanet(state, s, i);
                saver7_moveplanet(state, s, i);
                saver7_drawplanet(state, s, i, 1);
                saver7_drawplanet(state, s, i, 1);
                saver7_calc_planet_position(state, s, i);
                saver7_calc_planet_position(state, s, i);
                saver7_drawplanet(state, s, i, 0);
                saver7_drawplanet(state, s, i, 0);
        }
        }
        saver7_drawstar(state, s);
        saver7_drawstar(state, s);
}
}
 
 
/* The algorithm used in saver8 is based on that found at:
/* The algorithm used in saver8 is based on that found at:
   http://www.go2net.com/internet/deep/1997/04/16/body.html */
   http://www.go2net.com/internet/deep/1997/04/16/body.html */
 
 
void saver8_init(nstate *state)
void saver8_init(nstate *state)
{
{
        int red = 0, green = 0, blue = 0, step, i = 0;
        int red = 0, green = 0, blue = 0, step, i = 0;
 
 
        s8state *s = my_malloc(sizeof(s8state));
        s8state *s = my_malloc(sizeof(s8state));
        state->priv = s;
        state->priv = s;
 
 
        s->current_line = 0;
        s->current_line = 0;
 
 
        step = 512 / SAVER8_NUMCOLOURS;
        step = 512 / SAVER8_NUMCOLOURS;
 
 
        for(green = 255; green > 0; green -= step, blue += step, i++)
        for(green = 255; green > 0; green -= step, blue += step, i++)
                s->colours[i] = GR_RGB(0, green, blue);
                s->colours[i] = GR_RGB(0, green, blue);
        for(blue = 255; blue > 0; blue -= step, red += step, i++)
        for(blue = 255; blue > 0; blue -= step, red += step, i++)
                s->colours[i] = GR_RGB(red, 0, blue);
                s->colours[i] = GR_RGB(red, 0, blue);
 
 
        state->animate_interval = SAVER8_DELAY;
        state->animate_interval = SAVER8_DELAY;
}
}
 
 
void saver8_drawpattern(nstate *state)
void saver8_drawpattern(nstate *state)
{
{
        int x, col, lines = SAVER8_LINES_PER_FRAME;
        int x, col, lines = SAVER8_LINES_PER_FRAME;
        s8state *s = state->priv;
        s8state *s = state->priv;
 
 
        if(!s->current_line)
        if(!s->current_line)
                s->factor = RANDRANGE(SAVER8_MINFACTOR, SAVER8_MAXFACTOR);
                s->factor = RANDRANGE(SAVER8_MINFACTOR, SAVER8_MAXFACTOR);
 
 
        while(s->current_line < state->si.rows) {
        while(s->current_line < state->si.rows) {
                if(!--lines) return;
                if(!--lines) return;
                for(x = 0; x < state->si.cols; x++) {
                for(x = 0; x < state->si.cols; x++) {
                        col = ((((x * x) + (s->current_line * s->current_line))
                        col = ((((x * x) + (s->current_line * s->current_line))
                                        / s->factor) % SAVER8_NUMCOLOURS);
                                        / s->factor) % SAVER8_NUMCOLOURS);
                        GrSetGCForeground(state->main_gc, s->colours[col]);
                        GrSetGCForeground(state->main_gc, s->colours[col]);
                        GrPoint(state->main_window, state->main_gc, x,
                        GrPoint(state->main_window, state->main_gc, x,
                                                        s->current_line);
                                                        s->current_line);
                }
                }
                s->current_line++;
                s->current_line++;
        }
        }
        s->current_line = 0;
        s->current_line = 0;
}
}
 
 
void saver8_exposure(nstate *state)
void saver8_exposure(nstate *state)
{
{
        s8state *s = state->priv;
        s8state *s = state->priv;
 
 
        GrClearWindow(state->main_window, 0);
        GrClearWindow(state->main_window, 0);
        s->current_line = 0;
        s->current_line = 0;
        saver8_drawpattern(state);
        saver8_drawpattern(state);
}
}
 
 
void saver8_animate(nstate *state)
void saver8_animate(nstate *state)
{
{
        saver8_drawpattern(state);
        saver8_drawpattern(state);
}
}
 
 
int init(nstate *state)
int init(nstate *state)
{
{
        GR_WM_PROPERTIES props;
        GR_WM_PROPERTIES props;
        GR_BITMAP cursor = 0;
        GR_BITMAP cursor = 0;
 
 
        if(!GrOpen()) {
        if(!GrOpen()) {
                fprintf(stderr, "Couldn't connect to Nano-X server\n");
                fprintf(stderr, "Couldn't connect to Nano-X server\n");
                return 3;
                return 3;
        }
        }
 
 
        GrGetScreenInfo(&state->si);
        GrGetScreenInfo(&state->si);
 
 
        state->main_window = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0,
        state->main_window = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0,
                                state->si.cols, state->si.rows, 0, BLACK, 0);
                                state->si.cols, state->si.rows, 0, BLACK, 0);
 
 
        GrSelectEvents(state->main_window, GR_EVENT_MASK_EXPOSURE |
        GrSelectEvents(state->main_window, GR_EVENT_MASK_EXPOSURE |
                                                GR_EVENT_MASK_BUTTON_UP |
                                                GR_EVENT_MASK_BUTTON_UP |
                                                GR_EVENT_MASK_BUTTON_DOWN |
                                                GR_EVENT_MASK_BUTTON_DOWN |
                                                GR_EVENT_MASK_MOUSE_MOTION |
                                                GR_EVENT_MASK_MOUSE_MOTION |
                                                GR_EVENT_MASK_KEY_UP |
                                                GR_EVENT_MASK_KEY_UP |
                                                GR_EVENT_MASK_KEY_DOWN |
                                                GR_EVENT_MASK_KEY_DOWN |
                                                GR_EVENT_MASK_FOCUS_OUT |
                                                GR_EVENT_MASK_FOCUS_OUT |
                                                GR_EVENT_MASK_CLOSE_REQ);
                                                GR_EVENT_MASK_CLOSE_REQ);
 
 
        props.flags = GR_WM_FLAGS_PROPS;
        props.flags = GR_WM_FLAGS_PROPS;
        props.props = GR_WM_PROPS_NOMOVE | GR_WM_PROPS_NODECORATE |
        props.props = GR_WM_PROPS_NOMOVE | GR_WM_PROPS_NODECORATE |
                        GR_WM_PROPS_NOAUTOMOVE | GR_WM_PROPS_NOAUTORESIZE;
                        GR_WM_PROPS_NOAUTOMOVE | GR_WM_PROPS_NOAUTORESIZE;
        GrSetWMProperties(state->main_window, &props);
        GrSetWMProperties(state->main_window, &props);
 
 
        state->main_gc = GrNewGC();
        state->main_gc = GrNewGC();
        GrSetGCForeground(state->main_gc, WHITE);
        GrSetGCForeground(state->main_gc, WHITE);
        GrSetGCBackground(state->main_gc, BLACK);
        GrSetGCBackground(state->main_gc, BLACK);
 
 
        state->animate_interval = 0;
        state->animate_interval = 0;
 
 
        srand(time(0));
        srand(time(0));
 
 
        init_functions[state->saver](state);
        init_functions[state->saver](state);
 
 
        calculate_timeout(state);
        calculate_timeout(state);
 
 
        GrSelectEvents(GR_ROOT_WINDOW_ID, GR_EVENT_MASK_SCREENSAVER);
        GrSelectEvents(GR_ROOT_WINDOW_ID, GR_EVENT_MASK_SCREENSAVER);
 
 
        GrSetCursor(state->main_window, 1, 1, 1, 1, 0, 0, &cursor, &cursor);
        GrSetCursor(state->main_window, 1, 1, 1, 1, 0, 0, &cursor, &cursor);
 
 
        GrMapWindow(state->main_window);
        GrMapWindow(state->main_window);
 
 
        GrSetFocus(state->main_window);
        GrSetFocus(state->main_window);
 
 
        return 0;
        return 0;
}
}
 
 
void calculate_timeout(nstate *state)
void calculate_timeout(nstate *state)
{
{
        struct timeval t;
        struct timeval t;
        long u;
        long u;
 
 
        gettimeofday(&t, NULL);
        gettimeofday(&t, NULL);
        u = t.tv_usec + (state->animate_interval * 1000);
        u = t.tv_usec + (state->animate_interval * 1000);
        state->timeout.tv_sec = t.tv_sec + (u / 1000000);
        state->timeout.tv_sec = t.tv_sec + (u / 1000000);
        state->timeout.tv_usec = u % 1000000;
        state->timeout.tv_usec = u % 1000000;
}
}
 
 
unsigned long timeout_delay(nstate *state)
unsigned long timeout_delay(nstate *state)
{
{
        struct timeval t;
        struct timeval t;
        signed long s, m, ret;
        signed long s, m, ret;
 
 
        gettimeofday(&t, NULL);
        gettimeofday(&t, NULL);
 
 
        if(!state->animate_interval) return 0;
        if(!state->animate_interval) return 0;
 
 
        if((t.tv_sec > state->timeout.tv_sec) ||
        if((t.tv_sec > state->timeout.tv_sec) ||
                        ((t.tv_sec == state->timeout.tv_sec) &&
                        ((t.tv_sec == state->timeout.tv_sec) &&
                        t.tv_usec >= state->timeout.tv_usec)) return 1;
                        t.tv_usec >= state->timeout.tv_usec)) return 1;
 
 
        s = state->timeout.tv_sec - t.tv_sec;
        s = state->timeout.tv_sec - t.tv_sec;
        m = ((state->timeout.tv_usec - t.tv_usec) / 1000);
        m = ((state->timeout.tv_usec - t.tv_usec) / 1000);
        ret = (unsigned long)((1000 * s) + m);
        ret = (unsigned long)((1000 * s) + m);
 
 
        if(ret <= 0) return 1;
        if(ret <= 0) return 1;
        else return ret;
        else return ret;
}
}
 
 
void do_animate(nstate *state)
void do_animate(nstate *state)
{
{
        struct timeval t;
        struct timeval t;
 
 
        if(!state->animate_interval) return;
        if(!state->animate_interval) return;
 
 
        gettimeofday(&t, NULL);
        gettimeofday(&t, NULL);
 
 
        if((t.tv_sec > state->timeout.tv_sec) ||
        if((t.tv_sec > state->timeout.tv_sec) ||
                        ((t.tv_sec == state->timeout.tv_sec) &&
                        ((t.tv_sec == state->timeout.tv_sec) &&
                        (t.tv_usec >= state->timeout.tv_usec))) {
                        (t.tv_usec >= state->timeout.tv_usec))) {
                animate_functions[state->saver](state);
                animate_functions[state->saver](state);
                calculate_timeout(state);
                calculate_timeout(state);
        }
        }
}
}
 
 
int do_screensaver_event(nstate *state)
int do_screensaver_event(nstate *state)
{
{
        GR_EVENT_SCREENSAVER *event = &state->event.screensaver;
        GR_EVENT_SCREENSAVER *event = &state->event.screensaver;
 
 
        if(event->activate != GR_FALSE) {
        if(event->activate != GR_FALSE) {
                fprintf(stderr, "Got a non-deactivate screensaver event\n");
                fprintf(stderr, "Got a non-deactivate screensaver event\n");
                return 0;
                return 0;
        }
        }
 
 
        return 1;
        return 1;
}
}
 
 
int handle_event(nstate *state)
int handle_event(nstate *state)
{
{
        switch(state->event.type) {
        switch(state->event.type) {
                case GR_EVENT_TYPE_EXPOSURE:
                case GR_EVENT_TYPE_EXPOSURE:
                        exposure_functions[state->saver](state);
                        exposure_functions[state->saver](state);
                case GR_EVENT_TYPE_TIMEOUT:
                case GR_EVENT_TYPE_TIMEOUT:
                case GR_EVENT_TYPE_NONE:
                case GR_EVENT_TYPE_NONE:
                        break;
                        break;
                case GR_EVENT_TYPE_SCREENSAVER:
                case GR_EVENT_TYPE_SCREENSAVER:
                        if(do_screensaver_event(state)) return 0;
                        if(do_screensaver_event(state)) return 0;
                        break;
                        break;
                case GR_EVENT_TYPE_CLOSE_REQ:
                case GR_EVENT_TYPE_CLOSE_REQ:
                case GR_EVENT_MASK_BUTTON_UP:
                case GR_EVENT_MASK_BUTTON_UP:
                case GR_EVENT_MASK_BUTTON_DOWN:
                case GR_EVENT_MASK_BUTTON_DOWN:
                case GR_EVENT_MASK_MOUSE_MOTION:
                case GR_EVENT_MASK_MOUSE_MOTION:
                case GR_EVENT_MASK_KEY_UP:
                case GR_EVENT_MASK_KEY_UP:
                case GR_EVENT_MASK_KEY_DOWN:
                case GR_EVENT_MASK_KEY_DOWN:
                case GR_EVENT_MASK_FOCUS_OUT:
                case GR_EVENT_MASK_FOCUS_OUT:
                        return 0;
                        return 0;
                default:
                default:
                        fprintf(stderr, "Got unknown event type %d\n",
                        fprintf(stderr, "Got unknown event type %d\n",
                                                        state->event.type);
                                                        state->event.type);
                        break;
                        break;
        }
        }
        do_animate(state);
        do_animate(state);
        return(1);
        return(1);
}
}
 
 
int main(int argc, char *argv[])
int main(int argc, char *argv[])
{
{
        int ret;
        int ret;
        nstate *state = my_malloc(sizeof(nstate));
        nstate *state = my_malloc(sizeof(nstate));
 
 
        if(argc == 2) {
        if(argc == 2) {
                state->saver = atoi(argv[1]) - 1;
                state->saver = atoi(argv[1]) - 1;
                if((state->saver) < 0 || (state->saver >= NUM_SAVERS)) {
                if((state->saver) < 0 || (state->saver >= NUM_SAVERS)) {
                        fprintf(stderr, "Invalid saver number \"%s\"\n",
                        fprintf(stderr, "Invalid saver number \"%s\"\n",
                                                                argv[1]);
                                                                argv[1]);
                        return 2;
                        return 2;
                }
                }
        } else state->saver = 0;
        } else state->saver = 0;
 
 
        if((ret = init(state))) return ret;
        if((ret = init(state))) return ret;
 
 
        do {
        do {
                GrGetNextEventTimeout(&state->event, timeout_delay(state));
                GrGetNextEventTimeout(&state->event, timeout_delay(state));
        } while(handle_event(state));
        } while(handle_event(state));
 
 
        GrClose();
        GrClose();
 
 
        return 0;
        return 0;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.