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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [mw/] [src/] [demos/] [nanox/] [nsaver.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
 * The contents of this file are subject to the Mozilla Public License
3
 * Version 1.1 (the "License"); you may not use this file except in
4
 * compliance with the License. You may obtain a copy of the License at
5
 * http://www.mozilla.org/MPL/
6
 *
7
 * Software distributed under the License is distributed on an "AS IS"
8
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
9
 * License for the specific language governing rights and limitations
10
 * under the License.
11
 *
12
 * The Original Code is NanoScreenSaver.
13
 *
14
 * The Initial Developer of the Original Code is Alex Holden.
15
 * Portions created by Alex Holden are Copyright (C) 2000
16
 * Alex Holden <alex@linuxhacker.org>. All Rights Reserved.
17
 *
18
 * Contributor(s):
19
 *
20
 * Alternatively, the contents of this file may be used under the terms
21
 * of the GNU General Public license (the  "[GNU] License"), in which case the
22
 * provisions of [GNU] License are applicable instead of those
23
 * above.  If you wish to allow use of your version of this file only
24
 * under the terms of the [GNU] License and not to allow others to use
25
 * your version of this file under the MPL, indicate your decision by
26
 * deleting  the provisions above and replace  them with the notice and
27
 * other provisions required by the [GNU] License.  If you do not delete
28
 * the provisions above, a recipient may use your version of this file
29
 * under either the MPL or the [GNU] License.
30
 */
31
/*
32
 * A collection of screen savers for Nano-X by Alex Holden.
33
 */
34
 
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <time.h>
38
#include <math.h>
39
#include <sys/time.h>
40
 
41
#define MWINCLUDECOLORS
42
#include "nano-X.h"
43
#include "nsaver.h"
44
 
45
void *my_malloc(size_t size)
46
{
47
        void *ret;
48
 
49
        if(!(ret = malloc(size))) {
50
                fprintf(stderr, "Out of memory\n");
51
                exit(1);
52
        }
53
 
54
        return ret;
55
}
56
 
57
void get_random_point_on_screen(nstate *state, GR_COORD *x, GR_COORD *y,
58
                                                        GR_COLOR *c)
59
{
60
        if(x) {
61
                *x = (int) RANDRANGE(0, (state->si.cols - 1.0));
62
        }
63
        if(y) {
64
                *y = (int) RANDRANGE(0, (state->si.rows - 1.0));
65
        }
66
        if(c) {
67
                *c = MWPALINDEX((int)RANDRANGE(0, (state->si.ncolors - 1)));
68
        }
69
}
70
 
71
void saver1_init(nstate *state) {}
72
 
73
void saver1_exposure(nstate *state)
74
{
75
        GrClearWindow(state->main_window, 0);
76
}
77
 
78
void saver1_animate(nstate *state) {}
79
 
80
void saver2_init(nstate *state)
81
{
82
        (int)state->priv = SAVER2_MAXPIXELS;
83
        state->animate_interval = SAVER2_DELAY;
84
}
85
 
86
void saver2_exposure(nstate *state)
87
{
88
        GrClearWindow(state->main_window, 0);
89
}
90
 
91
void saver2_animate(nstate *state)
92
{
93
        GR_COORD x, y;
94
        GR_COLOR c;
95
        int pixels = SAVER2_PIXELS_PER_FRAME;
96
 
97
        while(pixels--) {
98
                if(!((int)state->priv--)) {
99
                        (int)state->priv = SAVER2_MAXPIXELS;
100
                        GrClearWindow(state->main_window, 0);
101
                }
102
                get_random_point_on_screen(state, &x, &y, &c);
103
                GrSetGCForeground(state->main_gc, c);
104
                GrPoint(state->main_window, state->main_gc, x, y);
105
        }
106
}
107
 
108
void saver3_init(nstate *state)
109
{
110
        s3state *s = my_malloc(sizeof(s3state));
111
        state->priv = s;
112
        s->maxsegments = SAVER3_MAXSEGMENTS;
113
        s->lastx = 0;
114
        s->lasty = 0;
115
        state->animate_interval = SAVER3_DELAY;
116
}
117
 
118
void saver3_exposure(nstate *state)
119
{
120
        GrClearWindow(state->main_window, 0);
121
}
122
 
123
void saver3_animate(nstate *state)
124
{
125
        GR_COORD newx, newy;
126
        GR_COLOR c;
127
        s3state *s = state->priv;
128
        int pixels = SAVER3_SEGMENTS_PER_FRAME;
129
 
130
        while(pixels--) {
131
                if(!(s->maxsegments--)) {
132
                        s->maxsegments = SAVER3_MAXSEGMENTS;
133
                        GrClearWindow(state->main_window, 0);
134
                }
135
                get_random_point_on_screen(state, &newx, &newy, &c);
136
                GrSetGCForeground(state->main_gc, c);
137
                GrLine(state->main_window, state->main_gc, s->lastx, s->lasty,
138
                                                        newx, newy);
139
                s->lastx = newx;
140
                s->lasty = newy;
141
        }
142
}
143
 
144
void saver4_init(nstate *state)
145
{
146
        int i;
147
 
148
        s4state *s = my_malloc(sizeof(s4state));
149
        state->priv = s;
150
 
151
        s->length = 0;
152
 
153
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
154
                s->tip = 0;
155
                get_random_point_on_screen(state, &s->worms[i].points[0].x,
156
                                                &s->worms[i].points[0].y,
157
                                                &s->worms[i].colour);
158
        }
159
 
160
        state->animate_interval = SAVER4_DELAY;
161
}
162
 
163
void saver4_exposure(nstate *state)
164
{
165
        int i;
166
        s4state *s = state->priv;
167
 
168
        GrClearWindow(state->main_window, 0);
169
 
170
        if(!s->length) return;
171
 
172
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
173
                GrSetGCForeground(state->main_gc, s->worms[i].colour);
174
                GrPoints(state->main_window, state->main_gc, s->length,
175
                                                        s->worms[i].points);
176
        }
177
}
178
 
179
void saver4_get_new_worm_position(nstate *state, s4state *s, int worm,
180
                                                GR_COORD *newx, GR_COORD *newy)
181
{
182
        int i;
183
        GR_COORD oldx = s->worms[worm].points[s->tip].x;
184
        GR_COORD oldy = s->worms[worm].points[s->tip].y;
185
 
186
        do {
187
                i = (int)RANDRANGE(0, 3.0);
188
                switch(i) {
189
                        case 0:
190
                                *newx = oldx + 1;
191
                                if(*newx == state->si.cols) *newx = 0;
192
                                break;
193
                        case 1:
194
                                *newx = oldx - 1;
195
                                if(*newx == -1) *newx = state->si.cols - 1;
196
                                break;
197
                        case 2:
198
                                *newx = oldx;
199
                                break;
200
                }
201
 
202
                i = (int)RANDRANGE(0, 3.0);
203
                switch(i) {
204
                        case 0:
205
                                *newy = oldy + 1;
206
                                if(*newy == state->si.rows) *newy = 0;
207
                                break;
208
                        case 1:
209
                                *newy = oldy - 1;
210
                                if(*newy == -1) *newy = state->si.rows - 1;
211
                                break;
212
                        case 2:
213
                                *newy = oldy;
214
                                break;
215
                }
216
        } while((*newx == oldx) && (*newy == oldy));
217
}
218
 
219
int saver4_worm_collides(nstate *state, s4state *s, int x, int y, int thisworm,
220
                                                                int thispoint)
221
{
222
        int i, n;
223
 
224
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
225
                for(n = 0; n < s->length; n++) {
226
                        if((i == thisworm) && (n == thispoint)) continue;
227
                        if((s->worms[i].points[n].x == x) &&
228
                                        (s->worms[i].points[n].y) == y) {
229
                                return 1;
230
                        }
231
                }
232
        }
233
        return 0;
234
}
235
 
236
void saver4_animate(nstate *state)
237
{
238
        int i, newx, newy, tail, newtip, tries;
239
        s4state *s = state->priv;
240
 
241
        if(s->length == SAVER4_WORMLENGTH) tail = s->tip + 1;
242
        else tail = 0;
243
        if(tail == SAVER4_WORMLENGTH) tail = 0;
244
        newtip = s->tip + 1;
245
        if(newtip == SAVER4_WORMLENGTH) newtip = 0;
246
 
247
        for(i = 0; i < SAVER4_NUMWORMS; i++) {
248
                if(!saver4_worm_collides(state, s, s->worms[i].points[tail].x,
249
                                        s->worms[i].points[tail].y, i, tail)) {
250
                        GrSetGCForeground(state->main_gc, BLACK);
251
                        GrPoint(state->main_window, state->main_gc,
252
                                        s->worms[i].points[tail].x,
253
                                        s->worms[i].points[tail].y);
254
                }
255
                for(tries = SAVER4_COLLISION_RELUCTANCE; tries; tries--) {
256
                                saver4_get_new_worm_position(state, s, i, &newx,
257
                                                                        &newy);
258
                        if(!saver4_worm_collides(state, s, newx, newy, -1, -1))
259
                                break;
260
                }
261
                s->worms[i].points[newtip].x = newx;
262
                s->worms[i].points[newtip].y = newy;
263
                if(tries) {
264
                        GrSetGCForeground(state->main_gc, s->worms[i].colour);
265
                        GrPoint(state->main_window, state->main_gc, newx, newy);
266
                }
267
        }
268
 
269
        s->tip = newtip;
270
        if(s->length < SAVER4_WORMLENGTH) s->length++;
271
}
272
 
273
void saver5_init(nstate *state)
274
{
275
        int i;
276
 
277
        s5state *s = my_malloc(sizeof(s5state));
278
        state->priv = s;
279
 
280
        s->numstars = 0;
281
 
282
        for(i = 0; i < SAVER5_NUMSTARS; i++) {
283
                s->stars[i].angle = RANDRANGE(0, (2 * M_PI));
284
                s->stars[i].pos = 1;
285
        }
286
 
287
        state->animate_interval = SAVER5_DELAY;
288
}
289
 
290
int saver5_drawstar(nstate *state, s5state *s, int star, int delete)
291
{
292
        int opp, adj;
293
        GR_COORD x, y;
294
 
295
        if(delete) GrSetGCForeground(state->main_gc, BLACK);
296
        else GrSetGCForeground(state->main_gc, WHITE);
297
 
298
        opp = (int)(sin(s->stars[star].angle) * s->stars[star].pos);
299
        adj = (int)(cos(s->stars[star].angle) * s->stars[star].pos);
300
 
301
        x = (state->si.cols / 2) + adj;
302
        y = (state->si.rows / 2) + opp;
303
 
304
        if((x < 0) || (y < 0) || (x >= state->si.cols) || (y >= state->si.rows))
305
                return 1;
306
 
307
        GrPoint(state->main_window, state->main_gc, x, y);
308
 
309
        return 0;
310
}
311
 
312
void saver5_exposure(nstate *state)
313
{
314
        int i;
315
        s5state *s = state->priv;
316
 
317
        GrClearWindow(state->main_window, 0);
318
 
319
        for(i = 0; i < SAVER5_NUMSTARS; i++) {
320
                saver5_drawstar(state, s, i, 0);
321
        }
322
}
323
 
324
void saver5_animate(nstate *state)
325
{
326
        int i;
327
        double position, scale, increment;
328
        s5state *s = state->priv;
329
 
330
        if(s->numstars < SAVER5_NUMSTARS) {
331
                s->numstars += SAVER5_STARS_INCREMENT;
332
                if(s->numstars > SAVER5_NUMSTARS)
333
                        s->numstars = SAVER5_NUMSTARS;
334
        }
335
 
336
        for(i = 0; i < s->numstars; i++) {
337
                saver5_drawstar(state, s, i, 1);
338
                position = (double)s->stars[i].pos /
339
                                (double)(state->si.cols / 2);
340
                scale = sin((position * M_PI_2) + M_PI + M_PI_2) + 1.0;
341
                increment = (scale * SAVER5_STARS_ACCEL_RATE) + 1;
342
                s->stars[i].pos += (int) increment;
343
                if(saver5_drawstar(state, s, i, 0)) {
344
                        s->stars[i].pos = 1;
345
                        s->stars[i].angle = RANDRANGE(0, (2 * M_PI));
346
                        saver5_drawstar(state, s, i, 0);
347
                }
348
        }
349
}
350
 
351
void saver6_init(nstate *state)
352
{
353
        int i, n;
354
 
355
        s6state *s = my_malloc(sizeof(s6state));
356
        state->priv = s;
357
 
358
        s->new_bolt_time = 0;
359
 
360
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
361
                s->bolts[i].duration = 0;
362
                for(n = 0; n < SAVER6_MAXFORKS; n++) {
363
                        s->bolts[i].forks[n].valid = 0;
364
                }
365
        }
366
 
367
        state->animate_interval = SAVER6_DELAY;
368
}
369
 
370
void saver6_drawfork(nstate *state, s6state *s, int bolt, int fork, int delete)
371
{
372
        int i;
373
 
374
        if(delete) GrSetGCForeground(state->main_gc, BLACK);
375
        for(i = 0; i < SAVER6_THICKNESS; i++) {
376
                if(!delete) {
377
                        if((i < 2) || (i >= SAVER6_THICKNESS - 2))
378
                                 GrSetGCForeground(state->main_gc, LTBLUE);
379
                        else GrSetGCForeground(state->main_gc, WHITE);
380
                }
381
                GrPoly(state->main_window, state->main_gc,
382
                                s->bolts[bolt].forks[fork].valid,
383
                                s->bolts[bolt].forks[fork].vertices[i]);
384
        }
385
}
386
 
387
void saver6_drawbolt(nstate *state, s6state *s, int bolt, int delete)
388
{
389
        int n;
390
 
391
        for(n = 0; n < SAVER6_MAXFORKS; n++)
392
                if(s->bolts[bolt].forks[n].valid)
393
                        saver6_drawfork(state, s, bolt, n, delete);
394
}
395
 
396
void saver6_drawlightning(nstate *state, s6state *s, int delete)
397
{
398
        int i;
399
 
400
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
401
                if(s->bolts[i].duration) {
402
                        if(delete) s->bolts[i].duration--;
403
                        saver6_drawbolt(state, s, i, delete);
404
                }
405
        }
406
}
407
 
408
void saver6_exposure(nstate *state)
409
{
410
        s6state *s = state->priv;
411
 
412
        GrClearWindow(state->main_window, 0);
413
 
414
        saver6_drawlightning(state, s, 0);
415
}
416
 
417
void saver6_setvertices(s6state *s, int bolt, int fork, int vert, GR_COORD x,
418
                                                                GR_COORD y)
419
{
420
        int i;
421
 
422
        for(i = 0; i < SAVER6_THICKNESS; i++) {
423
                s->bolts[bolt].forks[fork].vertices[i][vert].x = x + i;
424
                s->bolts[bolt].forks[fork].vertices[i][vert].y = y;
425
        }
426
}
427
 
428
void saver6_perturb(nstate *state, GR_COORD *x, GR_COORD *y, int maxperturb)
429
{
430
        *x += (int)RANDRANGE(0, (maxperturb - 1.0)) -
431
                                (double)(maxperturb / 2.0);
432
        if(*x < 0) *x = 0;
433
        if(*x > (state->si.cols - 1)) *x = state->si.cols - 1;
434
 
435
        *y += (int)RANDRANGE(0, (maxperturb - 1.0)) -
436
                                (double)(maxperturb / 2.0);
437
        if(*y < 0) *y = 0;
438
        if(*y > (state->si.cols - 1)) *y = state->si.cols - 1;
439
}
440
 
441
void saver6_makefork(nstate *state, s6state *s, int bolt, int fork, GR_COORD x,
442
                                                                GR_COORD y)
443
{
444
        int i, vertices;
445
        double length, incr, pos, angle, scale;
446
        GR_COORD ex, ey, nx, ny, xlen, ylen;
447
 
448
        saver6_setvertices(s, bolt, fork, 0, x , y);
449
 
450
        scale = (double)(state->si.rows - y) / (double)state->si.rows;
451
 
452
        vertices = (int)(scale * RANDRANGE(SAVER6_MINFULLVERTICES,
453
                                                SAVER6_MAXVERTICES));
454
 
455
        if(vertices < SAVER6_MINVERTICES) vertices = SAVER6_MINVERTICES;
456
 
457
        s->bolts[bolt].forks[fork].valid = vertices;
458
 
459
        ey = state->si.rows - SAVER6_MAXEND_Y +
460
                (int)RANDRANGE(0, SAVER6_MAXEND_Y - 1.0);
461
        if((ey - y) <= 0) ey = SAVER6_MINDROP;
462
        if(ey >= (state->si.rows - 1)) ey = state->si.rows - 1;
463
 
464
        if(!fork) {
465
                ex = x + (int)RANDRANGE(0, ((state->si.cols - 1.0) / 2.0));
466
        } else {
467
                ex = x + (int)(RANDRANGE(0, (ey - y)) / 2.0) - ((ey - y) / 2.0);
468
        }
469
 
470
        if(ex >= state->si.cols) ex = state->si.cols - 1;
471
        if(ex < 0) ex = 0;
472
 
473
        xlen = MAX(x, ex) - MIN(x, ex);
474
        ylen = MAX(y, ey) - MIN(y, ey);
475
 
476
        length = sqrt(((double)(xlen * xlen) + (double)(ylen * ylen)));
477
        incr = length / (vertices - 1);
478
        angle = atan(((double)xlen / (double)ylen));
479
 
480
        for(i = vertices - 1; i ; i--) {
481
                pos = (incr * (i - 1)) + (RANDRANGE(0, SAVER6_MAXZIGZAG) -
482
                                        ((double)SAVER6_MAXZIGZAG / 2.0));
483
                if(pos < 0) pos = 0;
484
                if(pos > length) pos = length;
485
                nx = x - (pos * sin(angle));
486
                ny = y + pos * cos(angle);
487
                saver6_perturb(state, &nx, &ny, SAVER6_MAXZIGZAG);
488
                saver6_setvertices(s, bolt, fork, i, nx , ny);
489
        }
490
}
491
 
492
int saver6_makeforks(nstate *state, s6state *s, int bolt, int fork,
493
                                                int *vert, int *nextfork)
494
{
495
        int thisvert = 1, thisfork;
496
        double prob;
497
 
498
        if(*vert == (s->bolts[bolt].forks[fork].valid - 1)) return 0;
499
        if(*nextfork == SAVER6_MAXFORKS) return 0;
500
 
501
        prob = (double)SAVER6_FORK_PROBABILITY * ((double)*vert /
502
                                (double)s->bolts[bolt].forks[fork].valid) *
503
                                        (1.0 / ((double)fork + 1.0));
504
        if(RANDRANGE(0, 1) < prob) {
505
                thisfork = *nextfork;
506
                saver6_makefork(state, s, bolt, thisfork,
507
                        s->bolts[bolt].forks[fork].vertices[0][*vert].x,
508
                        s->bolts[bolt].forks[fork].vertices[0][*vert].y);
509
                *nextfork += 1;
510
                while(saver6_makeforks(state, s, bolt, thisfork, &thisvert,
511
                                                                nextfork));
512
        }
513
 
514
        *vert += 1;
515
 
516
        return 1;
517
}
518
 
519
void saver6_makebolt(nstate *state, s6state *s, int bolt)
520
{
521
        GR_COORD x;
522
        int vert = 1, nextfork = 1, n;
523
 
524
        for(n = 0; n < SAVER6_MAXFORKS; n++)
525
                s->bolts[bolt].forks[n].valid = 0;
526
 
527
        x = (int)RANDRANGE(0, (state->si.cols - 1.0));
528
 
529
        saver6_makefork(state, s, bolt, 0, x, 0);
530
 
531
        while(saver6_makeforks(state, s, bolt, 0, &vert, &nextfork));
532
}
533
 
534
void saver6_newbolt(nstate *state, s6state *s)
535
{
536
        int i;
537
 
538
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
539
                if(!s->bolts[i].duration) {
540
                        saver6_makebolt(state, s, i);
541
                        s->bolts[i].duration = RANDRANGE(SAVER6_MINDURATION,
542
                                                        SAVER6_MAXDURATION);
543
                        saver6_drawbolt(state, s, i, 0);
544
                        break;
545
                }
546
        }
547
 
548
        s->new_bolt_time = RANDRANGE(1, SAVER6_MAXNEWBOLTTIME);
549
}
550
 
551
void saver6_perturb_bolt(nstate *state, s6state *s, int bolt, int fork)
552
{
553
        int m, o;
554
        GR_COORD x, ox, y, oy;
555
 
556
        for(m = 1; m < s->bolts[bolt].forks[fork].valid; m++) {
557
                ox = x = s->bolts[bolt].forks[fork].vertices[0][m].x;
558
                oy = y = s->bolts[bolt].forks[fork].vertices[0][m].y;
559
                saver6_perturb(state, &x, &y, SAVER6_MAXZIGZAG);
560
                saver6_setvertices(s, bolt, fork, m, x, y);
561
                for(o = fork + 1; o < SAVER6_MAXFORKS; o++) {
562
                        if((s->bolts[bolt].forks[o].vertices[0][0].x == ox) &&
563
                                (s->bolts[bolt].forks[o].vertices[0][0].y
564
                                                                == oy)) {
565
                                saver6_setvertices(s, bolt, o, 0, x, y);
566
                        }
567
                }
568
        }
569
}
570
 
571
void saver6_perturb_lightning(nstate *state, s6state *s)
572
{
573
        int i, n;
574
 
575
        for(i = 0; i < SAVER6_MAXBOLTS; i++) {
576
                if(!s->bolts[i].duration) continue;
577
                for(n = 0; n < SAVER6_MAXFORKS; n++) {
578
                        if(!s->bolts[i].forks[n].valid) continue;
579
                        saver6_perturb_bolt(state, s, i, n);
580
                }
581
        }
582
}
583
 
584
void saver6_animate(nstate *state)
585
{
586
        s6state *s = state->priv;
587
 
588
        saver6_drawlightning(state, s, 1);
589
        saver6_perturb_lightning(state, s);
590
        saver6_drawlightning(state, s, 0);
591
 
592
        if(!s->new_bolt_time--) saver6_newbolt(state, s);
593
}
594
 
595
/* The algorithm used in saver7 was adapted from "grav" by Greg Bowering */
596
 
597
void saver7_drawstar(nstate *state, s7state *s)
598
{
599
        GrSetGCForeground(state->main_gc, SAVER7_STARCOLOUR);
600
        GrFillEllipse(state->main_window, state->main_gc, s->starx, s->stary,
601
                                SAVER7_STARRADIUS, SAVER7_STARRADIUS);
602
}
603
 
604
void saver7_drawplanet(nstate *state, s7state *s, int planet, int erase)
605
{
606
        if(erase) GrSetGCForeground(state->main_gc, BLACK);
607
        else GrSetGCForeground(state->main_gc, s->planets[planet].colour);
608
 
609
        if((s->planets[planet].ax < 0) || (s->planets[planet].ay < 0) ||
610
                        (s->planets[planet].ax >= state->si.cols) ||
611
                        (s->planets[planet].ay >= state->si.rows)) {
612
                return;
613
        }
614
 
615
        GrFillEllipse(state->main_window, state->main_gc, s->planets[planet].ax,
616
                                s->planets[planet].ay,
617
                                SAVER7_PLANETRADIUS, SAVER7_PLANETRADIUS);
618
}
619
 
620
void saver7_calc_planet_position(nstate *state, s7state *s, int planet)
621
{
622
        if(s->planets[planet].r > -SAVER7_ALMOSTDIST) {
623
                s->planets[planet].ax = (int)((double) state->si.cols *
624
                        (0.5 + (s->planets[planet].x / (s->planets[planet].r +
625
                                                        SAVER7_DIST))));
626
                s->planets[planet].ay = (int)((double) state->si.rows *
627
                        (0.5 + (s->planets[planet].y / (s->planets[planet].r +
628
                                                        SAVER7_DIST))));
629
        } else {
630
                s->planets[planet].ax = -1;
631
                s->planets[planet].ay = -1;
632
        }
633
}
634
 
635
void saver7_init(nstate *state)
636
{
637
        int i;
638
        s7state *s = my_malloc(sizeof(s7state));
639
        state->priv = s;
640
 
641
        s->starx = state->si.cols / 2;
642
        s->stary = state->si.rows / 2;
643
 
644
        for(i = 0; i < SAVER7_PLANETS; i++) {
645
                s->planets[i].r = RANDRANGE(SAVER7_MIN_STARTDIM,
646
                                                SAVER7_MAX_STARTDIM);
647
                s->planets[i].x = RANDRANGE(SAVER7_MIN_STARTDIM,
648
                                                SAVER7_MAX_STARTDIM);
649
                s->planets[i].y = RANDRANGE(SAVER7_MIN_STARTDIM,
650
                                                SAVER7_MAX_STARTDIM);
651
                s->planets[i].rv = RANDRANGE(SAVER7_MIN_STARTVEL,
652
                                                SAVER7_MAX_STARTVEL);
653
                s->planets[i].xv = RANDRANGE(SAVER7_MIN_STARTVEL,
654
                                                SAVER7_MAX_STARTVEL);
655
                s->planets[i].yv = RANDRANGE(SAVER7_MIN_STARTVEL,
656
                                                SAVER7_MAX_STARTVEL);
657
                s->planets[i].colour = RANDRANGE(0, (state->si.ncolors - 1));
658
                saver7_calc_planet_position(state, s, i);
659
                saver7_drawplanet(state, s, i, 0);
660
        }
661
 
662
        saver7_drawstar(state, s);
663
 
664
        state->animate_interval = SAVER7_DELAY;
665
}
666
 
667
void saver7_exposure(nstate *state)
668
{
669
        int i;
670
        s7state *s = state->priv;
671
 
672
        GrClearWindow(state->main_window, 0);
673
 
674
        for(i = 0; i < SAVER7_PLANETS; i++)
675
                saver7_drawplanet(state, s, i, 0);
676
 
677
        saver7_drawstar(state, s);
678
}
679
 
680
void saver7_moveplanet(nstate *state, s7state *s, int planet)
681
{
682
        double dist;
683
        double accel;
684
 
685
        dist = (s->planets[planet].x * s->planets[planet].x) +
686
                (s->planets[planet].y * s->planets[planet].y) +
687
                (s->planets[planet].r * s->planets[planet].r);
688
        if(dist < SAVER7_COLLIDE) dist = SAVER7_COLLIDE;
689
        dist = sqrt(dist);
690
        dist = dist * dist * dist;
691
 
692
#ifdef SAVER7_USE_DAMPING
693
        accel = s->planets[planet].r * SAVER7_G / dist;
694
        if(accel > SAVER7_MAX_ACCEL) accel = SAVER7_MAX_ACCEL;
695
        else if(accel < -SAVER7_MAX_ACCEL) accel = -SAVER7_MAX_ACCEL;
696
        s->planets[planet].rv = (s->planets[planet].rv + accel) *
697
                                                SAVER7_DAMPING_FACTOR;
698
        s->planets[planet].r += s->planets[planet].rv;
699
        accel = s->planets[planet].x * SAVER7_G / dist;
700
        if(accel > SAVER7_MAX_ACCEL) accel = SAVER7_MAX_ACCEL;
701
        else if(accel < -SAVER7_MAX_ACCEL) accel = -SAVER7_MAX_ACCEL;
702
        s->planets[planet].xv = (s->planets[planet].xv + accel) *
703
                                                SAVER7_DAMPING_FACTOR;
704
        s->planets[planet].x += s->planets[planet].xv;
705
        accel = s->planets[planet].y * SAVER7_G / dist;
706
        if(accel > SAVER7_MAX_ACCEL) accel = SAVER7_MAX_ACCEL;
707
        else if(accel < -SAVER7_MAX_ACCEL) accel = -SAVER7_MAX_ACCEL;
708
        s->planets[planet].yv = (s->planets[planet].yv + accel) *
709
                                                SAVER7_DAMPING_FACTOR;
710
        s->planets[planet].y += s->planets[planet].yv;
711
#else
712
        accel = s->planets[planet].r * SAVER7_G / dist;
713
        s->planets[planet].rv += accel;
714
        s->planets[planet].r += s->planets[planet].rv;
715
        accel = s->planets[planet].x * SAVER7_G / dist;
716
        s->planets[planet].xv += accel;
717
        s->planets[planet].x += s->planets[planet].xv;
718
        accel = s->planets[planet].y * SAVER7_G / dist;
719
        s->planets[planet].yv += accel;
720
        s->planets[planet].y += s->planets[planet].yv;
721
#endif
722
}
723
 
724
void saver7_animate(nstate *state)
725
{
726
        int i;
727
        s7state *s = state->priv;
728
 
729
        for(i = 0; i < SAVER7_PLANETS; i++) {
730
                saver7_moveplanet(state, s, i);
731
                saver7_drawplanet(state, s, i, 1);
732
                saver7_calc_planet_position(state, s, i);
733
                saver7_drawplanet(state, s, i, 0);
734
        }
735
        saver7_drawstar(state, s);
736
}
737
 
738
/* The algorithm used in saver8 is based on that found at:
739
   http://www.go2net.com/internet/deep/1997/04/16/body.html */
740
 
741
void saver8_init(nstate *state)
742
{
743
        int red = 0, green = 0, blue = 0, step, i = 0;
744
 
745
        s8state *s = my_malloc(sizeof(s8state));
746
        state->priv = s;
747
 
748
        s->current_line = 0;
749
 
750
        step = 512 / SAVER8_NUMCOLOURS;
751
 
752
        for(green = 255; green > 0; green -= step, blue += step, i++)
753
                s->colours[i] = GR_RGB(0, green, blue);
754
        for(blue = 255; blue > 0; blue -= step, red += step, i++)
755
                s->colours[i] = GR_RGB(red, 0, blue);
756
 
757
        state->animate_interval = SAVER8_DELAY;
758
}
759
 
760
void saver8_drawpattern(nstate *state)
761
{
762
        int x, col, lines = SAVER8_LINES_PER_FRAME;
763
        s8state *s = state->priv;
764
 
765
        if(!s->current_line)
766
                s->factor = RANDRANGE(SAVER8_MINFACTOR, SAVER8_MAXFACTOR);
767
 
768
        while(s->current_line < state->si.rows) {
769
                if(!--lines) return;
770
                for(x = 0; x < state->si.cols; x++) {
771
                        col = ((((x * x) + (s->current_line * s->current_line))
772
                                        / s->factor) % SAVER8_NUMCOLOURS);
773
                        GrSetGCForeground(state->main_gc, s->colours[col]);
774
                        GrPoint(state->main_window, state->main_gc, x,
775
                                                        s->current_line);
776
                }
777
                s->current_line++;
778
        }
779
        s->current_line = 0;
780
}
781
 
782
void saver8_exposure(nstate *state)
783
{
784
        s8state *s = state->priv;
785
 
786
        GrClearWindow(state->main_window, 0);
787
        s->current_line = 0;
788
        saver8_drawpattern(state);
789
}
790
 
791
void saver8_animate(nstate *state)
792
{
793
        saver8_drawpattern(state);
794
}
795
 
796
int init(nstate *state)
797
{
798
        GR_WM_PROPERTIES props;
799
        GR_BITMAP cursor = 0;
800
 
801
        if(!GrOpen()) {
802
                fprintf(stderr, "Couldn't connect to Nano-X server\n");
803
                return 3;
804
        }
805
 
806
        GrGetScreenInfo(&state->si);
807
 
808
        state->main_window = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0,
809
                                state->si.cols, state->si.rows, 0, BLACK, 0);
810
 
811
        GrSelectEvents(state->main_window, GR_EVENT_MASK_EXPOSURE |
812
                                                GR_EVENT_MASK_BUTTON_UP |
813
                                                GR_EVENT_MASK_BUTTON_DOWN |
814
                                                GR_EVENT_MASK_MOUSE_MOTION |
815
                                                GR_EVENT_MASK_KEY_UP |
816
                                                GR_EVENT_MASK_KEY_DOWN |
817
                                                GR_EVENT_MASK_FOCUS_OUT |
818
                                                GR_EVENT_MASK_CLOSE_REQ);
819
 
820
        props.flags = GR_WM_FLAGS_PROPS;
821
        props.props = GR_WM_PROPS_NOMOVE | GR_WM_PROPS_NODECORATE |
822
                        GR_WM_PROPS_NOAUTOMOVE | GR_WM_PROPS_NOAUTORESIZE;
823
        GrSetWMProperties(state->main_window, &props);
824
 
825
        state->main_gc = GrNewGC();
826
        GrSetGCForeground(state->main_gc, WHITE);
827
        GrSetGCBackground(state->main_gc, BLACK);
828
 
829
        state->animate_interval = 0;
830
 
831
        srand(time(0));
832
 
833
        init_functions[state->saver](state);
834
 
835
        calculate_timeout(state);
836
 
837
        GrSelectEvents(GR_ROOT_WINDOW_ID, GR_EVENT_MASK_SCREENSAVER);
838
 
839
        GrSetCursor(state->main_window, 1, 1, 1, 1, 0, 0, &cursor, &cursor);
840
 
841
        GrMapWindow(state->main_window);
842
 
843
        GrSetFocus(state->main_window);
844
 
845
        return 0;
846
}
847
 
848
void calculate_timeout(nstate *state)
849
{
850
        struct timeval t;
851
        long u;
852
 
853
        gettimeofday(&t, NULL);
854
        u = t.tv_usec + (state->animate_interval * 1000);
855
        state->timeout.tv_sec = t.tv_sec + (u / 1000000);
856
        state->timeout.tv_usec = u % 1000000;
857
}
858
 
859
unsigned long timeout_delay(nstate *state)
860
{
861
        struct timeval t;
862
        signed long s, m, ret;
863
 
864
        gettimeofday(&t, NULL);
865
 
866
        if(!state->animate_interval) return 0;
867
 
868
        if((t.tv_sec > state->timeout.tv_sec) ||
869
                        ((t.tv_sec == state->timeout.tv_sec) &&
870
                        t.tv_usec >= state->timeout.tv_usec)) return 1;
871
 
872
        s = state->timeout.tv_sec - t.tv_sec;
873
        m = ((state->timeout.tv_usec - t.tv_usec) / 1000);
874
        ret = (unsigned long)((1000 * s) + m);
875
 
876
        if(ret <= 0) return 1;
877
        else return ret;
878
}
879
 
880
void do_animate(nstate *state)
881
{
882
        struct timeval t;
883
 
884
        if(!state->animate_interval) return;
885
 
886
        gettimeofday(&t, NULL);
887
 
888
        if((t.tv_sec > state->timeout.tv_sec) ||
889
                        ((t.tv_sec == state->timeout.tv_sec) &&
890
                        (t.tv_usec >= state->timeout.tv_usec))) {
891
                animate_functions[state->saver](state);
892
                calculate_timeout(state);
893
        }
894
}
895
 
896
int do_screensaver_event(nstate *state)
897
{
898
        GR_EVENT_SCREENSAVER *event = &state->event.screensaver;
899
 
900
        if(event->activate != GR_FALSE) {
901
                fprintf(stderr, "Got a non-deactivate screensaver event\n");
902
                return 0;
903
        }
904
 
905
        return 1;
906
}
907
 
908
int handle_event(nstate *state)
909
{
910
        switch(state->event.type) {
911
                case GR_EVENT_TYPE_EXPOSURE:
912
                        exposure_functions[state->saver](state);
913
                case GR_EVENT_TYPE_TIMEOUT:
914
                case GR_EVENT_TYPE_NONE:
915
                        break;
916
                case GR_EVENT_TYPE_SCREENSAVER:
917
                        if(do_screensaver_event(state)) return 0;
918
                        break;
919
                case GR_EVENT_TYPE_CLOSE_REQ:
920
                case GR_EVENT_MASK_BUTTON_UP:
921
                case GR_EVENT_MASK_BUTTON_DOWN:
922
                case GR_EVENT_MASK_MOUSE_MOTION:
923
                case GR_EVENT_MASK_KEY_UP:
924
                case GR_EVENT_MASK_KEY_DOWN:
925
                case GR_EVENT_MASK_FOCUS_OUT:
926
                        return 0;
927
                default:
928
                        fprintf(stderr, "Got unknown event type %d\n",
929
                                                        state->event.type);
930
                        break;
931
        }
932
        do_animate(state);
933
        return(1);
934
}
935
 
936
int main(int argc, char *argv[])
937
{
938
        int ret;
939
        nstate *state = my_malloc(sizeof(nstate));
940
 
941
        if(argc == 2) {
942
                state->saver = atoi(argv[1]) - 1;
943
                if((state->saver) < 0 || (state->saver >= NUM_SAVERS)) {
944
                        fprintf(stderr, "Invalid saver number \"%s\"\n",
945
                                                                argv[1]);
946
                        return 2;
947
                }
948
        } else state->saver = 0;
949
 
950
        if((ret = init(state))) return ret;
951
 
952
        do {
953
                GrGetNextEventTimeout(&state->event, timeout_delay(state));
954
        } while(handle_event(state));
955
 
956
        GrClose();
957
 
958
        return 0;
959
}

powered by: WebSVN 2.1.0

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