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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [mw/] [src/] [demos/] [nanox/] [erase.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 770 simons
/* erase.c: Erase the screen in various more or less interesting ways.
2
 * (c) 1997 by Johannes Keukelaar <johannes@nada.kth.se>
3
 * Permission to use in any way granted. Provided "as is" without expressed
4
 * or implied warranty. NO WARRANTY, NO EXPRESSION OF SUITABILITY FOR ANY
5
 * PURPOSE. (I.e.: Use in any way, but at your own risk!)
6
 */
7
#include <stdio.h>
8
//#include <unistd.h>
9
#define usleep(x)
10
#include <stdlib.h>
11
#include <math.h>
12
#define MWINCLUDECOLORS
13
#include "nano-X.h"
14
#include "maze.h"
15
 
16
#undef countof
17
#define countof(x) (sizeof(x)/sizeof(*(x)))
18
 
19
typedef void (*Eraser) (int width, int height, int delay, int granularity);
20
typedef int Bool;
21
 
22
static void
23
random_lines (int width, int height, int delay, int granularity)
24
{
25
  Bool horiz_p = (random() & 1);
26
  int max = (horiz_p ? height : width);
27
  int *lines = (int *) calloc(max, sizeof(*lines));
28
  int i;
29
 
30
  for (i = 0; i < max; i++)
31
    lines[i] = i;
32
 
33
  for (i = 0; i < max; i++)
34
    {
35
      int t, r;
36
      t = lines[i];
37
      r = random() % max;
38
      lines[i] = lines[r];
39
      lines[r] = t;
40
    }
41
 
42
  for (i = 0; i < max; i++)
43
    {
44
      if (horiz_p)
45
        GrLine (wid, erase_gc, 0, lines[i], width, lines[i]);
46
      else
47
        GrLine (wid, erase_gc, lines[i], 0, lines[i], height);
48
 
49
      wait_sync ();
50
      if (delay > 0 && ((i % granularity) == 0))
51
        usleep (delay * granularity);
52
    }
53
  free(lines);
54
}
55
 
56
 
57
static void
58
venetian (int width, int height, int delay, int granularity)
59
{
60
  Bool horiz_p = (random() & 1);
61
  Bool flip_p = (random() & 1);
62
  int max = (horiz_p ? height : width);
63
  int *lines = (int *) calloc(max, sizeof(*lines));
64
  int i, j;
65
 
66
  granularity /= 6;
67
 
68
  j = 0;
69
  for (i = 0; i < max*2; i++)
70
    {
71
      int line = ((i / 16) * 16) - ((i % 16) * 15);
72
      if (line >= 0 && line < max)
73
        lines[j++] = (flip_p ? max - line : line);
74
    }
75
 
76
  for (i = 0; i < max; i++)
77
    {
78
      if (horiz_p)
79
        GrLine (wid, erase_gc, 0, lines[i], width, lines[i]);
80
      else
81
        GrLine (wid, erase_gc, lines[i], 0, lines[i], height);
82
 
83
      wait_sync ();
84
      if (delay > 0 && ((i % granularity) == 0))
85
        usleep (delay * granularity);
86
    }
87
  free(lines);
88
}
89
 
90
 
91
static void
92
triple_wipe (int width, int height, int delay, int granularity)
93
{
94
  Bool flip_x = random() & 1;
95
  Bool flip_y = random() & 1;
96
  int max = width + (height / 2);
97
  int *lines = (int *)calloc(max, sizeof(int));
98
  int i;
99
 
100
  for(i = 0; i < width/2; i++)
101
    lines[i] = i*2+height;
102
  for(i = 0; i < height/2; i++)
103
    lines[i+width/2] = i*2;
104
  for(i = 0; i < width/2; i++)
105
    lines[i+width/2+height/2] = width-i*2-(width%2?0:1)+height;
106
 
107
  granularity /= 6;
108
 
109
  for (i = 0; i < max; i++)
110
    {
111
      int x, y, x2, y2;
112
      if (lines[i] < height)
113
        x = 0, y = lines[i], x2 = width, y2 = y;
114
      else
115
        x = lines[i]-height, y = 0, x2 = x, y2 = height;
116
 
117
      if (flip_x)
118
        x = width-x, x2 = width-x2;
119
      if (flip_y)
120
        y = height-y, y2 = height-y2;
121
 
122
      GrLine (wid, erase_gc, x, y, x2, y2);
123
      wait_sync ();
124
      if (delay > 0 && ((i % granularity) == 0))
125
        usleep (delay*granularity);
126
    }
127
  free(lines);
128
}
129
 
130
 
131
static void
132
quad_wipe (int width, int height, int delay, int granularity)
133
{
134
  Bool flip_x = random() & 1;
135
  Bool flip_y = random() & 1;
136
  int max = width + height;
137
  int *lines = (int *)calloc(max, sizeof(int));
138
  int i;
139
 
140
  granularity /= 3;
141
 
142
  for (i = 0; i < max/4; i++)
143
    {
144
      lines[i*4]   = i*2;
145
      lines[i*4+1] = height-i*2-(height%2?0:1);
146
      lines[i*4+2] = height+i*2;
147
      lines[i*4+3] = height+width-i*2-(width%2?0:1);
148
    }
149
 
150
  for (i = 0; i < max; i++)
151
    {
152
      int x, y, x2, y2;
153
      if (lines[i] < height)
154
        x = 0, y = lines[i], x2 = width, y2 = y;
155
      else
156
        x = lines[i]-height, y = 0, x2 = x, y2 = height;
157
 
158
      if (flip_x)
159
        x = width-x, x2 = width-x2;
160
      if (flip_y)
161
        y = height-y, y2 = height-y2;
162
 
163
      GrLine (wid, erase_gc, x, y, x2, y2);
164
      wait_sync ();
165
      if (delay > 0 && ((i % granularity) == 0))
166
        usleep (delay*granularity);
167
    }
168
  free(lines);
169
}
170
 
171
#if 0
172
static void
173
circle_wipe (int width, int height, int delay, int granularity)
174
{
175
  int full = 360 * 64;
176
  int inc = full / 64;
177
  int start = random() % full;
178
  int rad = (width > height ? width : height);
179
  int i;
180
  if (random() & 1)
181
    inc = -inc;
182
  for (i = (inc > 0 ? 0 : full);
183
       (inc > 0 ? i < full : i > 0);
184
       i += inc)
185
    {
186
      GrArc(wid, erase_gc,
187
               (width/2)-rad, (height/2)-rad, rad*2, rad*2,
188
               (i+start) % full, inc);
189
      usleep (delay*granularity);
190
    }
191
}
192
#endif
193
 
194
#if 0
195
static void
196
three_circle_wipe (int width, int height, int delay, int granularity)
197
{
198
  int i;
199
  int full = 360 * 64;
200
  int q = full / 6;
201
  int q2 = q * 2;
202
  int inc = full / 240;
203
  int start = random() % q;
204
  int rad = (width > height ? width : height);
205
 
206
  for (i = 0; i < q; i += inc)
207
    {
208
      GrArc(wid, erase_gc, (width/2)-rad, (height/2)-rad, rad*2, rad*2,
209
               (start+i) % full, inc);
210
      GrArc(wid, erase_gc, (width/2)-rad, (height/2)-rad, rad*2, rad*2,
211
               (start-i) % full, -inc);
212
 
213
      GrArc(wid, erase_gc, (width/2)-rad, (height/2)-rad, rad*2, rad*2,
214
               (start+q2+i) % full, inc);
215
      GrArc(wid, erase_gc, (width/2)-rad, (height/2)-rad, rad*2, rad*2,
216
               (start+q2-i) % full, -inc);
217
 
218
      GrArc(wid, erase_gc, (width/2)-rad, (height/2)-rad, rad*2, rad*2,
219
               (start+q2+q2+i) % full, inc);
220
      GrArc(wid, erase_gc, (width/2)-rad, (height/2)-rad, rad*2, rad*2,
221
               (start+q2+q2-i) % full, -inc);
222
 
223
      wait_sync ();
224
      usleep (delay*granularity);
225
    }
226
}
227
#endif
228
 
229
static void
230
squaretate (int width, int height, int delay, int granularity)
231
{
232
  int steps = (((width > height ? width : width) * 2) / granularity);
233
  int i;
234
  Bool flip = random() & 1;
235
 
236
#define DRAW() \
237
      if (flip) { \
238
        points[0].x = width-points[0].x; \
239
        points[1].x = width-points[1].x; \
240
        points[2].x = width-points[2].x; } \
241
      GrFillPoly (wid, erase_gc, 3, points)
242
 
243
  for (i = 0; i < steps; i++)
244
    {
245
      GR_POINT points [3];
246
      points[0].x = 0;
247
      points[0].y = 0;
248
      points[1].x = width;
249
      points[1].y = 0;
250
      points[2].x = 0;
251
      points[2].y = points[0].y + ((i * height) / steps);
252
      DRAW();
253
 
254
      points[0].x = 0;
255
      points[0].y = 0;
256
      points[1].x = 0;
257
      points[1].y = height;
258
      points[2].x = ((i * width) / steps);
259
      points[2].y = height;
260
      DRAW();
261
 
262
      points[0].x = width;
263
      points[0].y = height;
264
      points[1].x = 0;
265
      points[1].y = height;
266
      points[2].x = width;
267
      points[2].y = height - ((i * height) / steps);
268
      DRAW();
269
 
270
      points[0].x = width;
271
      points[0].y = height;
272
      points[1].x = width;
273
      points[1].y = 0;
274
      points[2].x = width - ((i * width) / steps);
275
      points[2].y = 0;
276
      DRAW();
277
 
278
      wait_sync ();
279
      if (delay > 0)
280
        usleep (delay * granularity);
281
   }
282
#undef DRAW
283
}
284
 
285
 
286
/* from Frederick Roeber <roeber@netscape.com> */
287
static void
288
fizzle (int width, int height, int delay, int granularity)
289
{
290
  /* These dimensions must be prime numbers.  They should be roughly the
291
     square root of the width and height. */
292
# define BX 31
293
# define BY 31
294
# define SIZE (BX*BY)
295
 
296
  int array[SIZE];
297
  int i, j;
298
  GR_POINT *skews;
299
  int nx, ny;
300
 
301
  /* Distribute the numbers [0,SIZE) randomly in the array */
302
  {
303
    int indices[SIZE];
304
 
305
    for( i = 0; i < SIZE; i++ ) {
306
      array[i] = -1;
307
      indices[i] = i;
308
    }
309
 
310
    for( i = 0; i < SIZE; i++ ) {
311
      j = random()%(SIZE-i);
312
      array[indices[j]] = i;
313
      indices[j] = indices[SIZE-i-1];
314
    }
315
  }
316
 
317
  /* nx, ny are the number of cells across and down, rounded up */
318
  nx = width  / BX + (0 == (width %BX) ? 0 : 1);
319
  ny = height / BY + (0 == (height%BY) ? 0 : 1);
320
  skews = (GR_POINT *)malloc(sizeof(GR_POINT) * (nx*ny));
321
  if( (GR_POINT *)0 != skews ) {
322
    for( i = 0; i < nx; i++ ) {
323
      for( j = 0; j < ny; j++ ) {
324
        skews[j * nx + i].x = random()%BX;
325
        skews[j * nx + i].y = random()%BY;
326
      }
327
    }
328
  }
329
 
330
# define SKEWX(cx, cy) (((GR_POINT *)0 == skews)?0:skews[cy*nx + cx].x)
331
# define SKEWY(cx, cy) (((GR_POINT *)0 == skews)?0:skews[cy*nx + cx].y)
332
 
333
  for( i = 0; i < SIZE; i++ ) {
334
    int x = array[i] % BX;
335
    int y = array[i] / BX;
336
 
337
    {
338
      int iy, cy;
339
      for( iy = 0, cy = 0; iy < height; iy += BY, cy++ ) {
340
        int ix, cx;
341
        for( ix = 0, cx = 0; ix < width; ix += BX, cx++ ) {
342
          int xx = ix + (SKEWX(cx, cy) + x*((cx%(BX-1))+1))%BX;
343
          int yy = iy + (SKEWY(cx, cy) + y*((cy%(BY-1))+1))%BY;
344
          if (xx < width && yy < height)
345
            GrPoint(wid, erase_gc, xx, yy);
346
        }
347
      }
348
    }
349
 
350
    if( (BX-1) == (i%BX) ) {
351
      wait_sync ();
352
      usleep (delay*granularity);
353
    }
354
  }
355
 
356
# undef SKEWX
357
# undef SKEWY
358
 
359
  if( (GR_POINT *)0 != skews ) {
360
    free(skews);
361
  }
362
 
363
# undef BX
364
# undef BY
365
# undef SIZE
366
}
367
 
368
 
369
/* from Rick Campbell <rick@campbellcentral.org> */
370
static void
371
spiral (int width, int height, int delay, int granularity)
372
{
373
# define SPIRAL_ERASE_PI_2 (M_PI + M_PI)
374
# define SPIRAL_ERASE_LOOP_COUNT (10)
375
# define SPIRAL_ERASE_ARC_COUNT (360.0)
376
# define SPIRAL_ERASE_ANGLE_INCREMENT (SPIRAL_ERASE_PI_2 /     \
377
SPIRAL_ERASE_ARC_COUNT)
378
# define SPIRAL_ERASE_DELAY (0)
379
 
380
  double angle;
381
  int arc_limit;
382
  int arc_max_limit;
383
  int length_step;
384
  GR_POINT points [3];
385
 
386
  angle = 0.0;
387
  arc_limit = 1;
388
  arc_max_limit = (int) (ceil (sqrt ((width * width) + (height * height)))
389
                         / 2.0);
390
  length_step = ((arc_max_limit + SPIRAL_ERASE_LOOP_COUNT - 1) /
391
                 SPIRAL_ERASE_LOOP_COUNT);
392
  arc_max_limit += length_step;
393
  points [0].x = width / 2;
394
  points [0].y = height / 2;
395
  points [1].x = points [0].x + length_step;
396
  points [1].y = points [0].y;
397
  points [2].x = points [1].x;
398
  points [2].y = points [1].y;
399
 
400
  for (arc_limit = length_step;
401
       arc_limit < arc_max_limit;
402
       arc_limit += length_step)
403
    {
404
      int arc_length = length_step;
405
      int length_base = arc_limit;
406
      for (angle = 0.0; angle < SPIRAL_ERASE_PI_2;
407
           angle += SPIRAL_ERASE_ANGLE_INCREMENT)
408
        {
409
          arc_length = length_base + ((length_step * angle) /
410
                                      SPIRAL_ERASE_PI_2);
411
          points [1].x = points [2].x;
412
          points [1].y = points [2].y;
413
          points [2].x = points [0].x + (int)(cos (angle) * arc_length);
414
          points [2].y = points [0].y + (int)(sin (angle) * arc_length);
415
          GrFillPoly (wid, erase_gc, 3, points);
416
# if (SPIRAL_ERASE_DELAY != 0)
417
          usleep (SPIRAL_ERASE_DELAY);
418
# endif /* (SPIRAL_ERASE_DELAY != 0) */
419
        }
420
    }
421
# undef SPIRAL_ERASE_DELAY
422
# undef SPIRAL_ERASE_ANGLE_INCREMENT
423
# undef SPIRAL_ERASE_ARC_COUNT
424
# undef SPIRAL_ERASE_LOOP_COUNT
425
# undef SPIRAL_ERASE_PI_2
426
}
427
 
428
 
429
#undef MAX
430
#undef MIN
431
#define MAX(a,b) ((a)>(b)?(a):(b))
432
#define MIN(a,b) ((a)<(b)?(a):(b))
433
 
434
/* from David Bagley <bagleyd@tux.org> */
435
static void
436
random_squares(int width, int height, int delay, int granularity)
437
{
438
  int randsize = MAX(1, MIN(width, height) / (16 + (random() % 32)));
439
  int max = (height / randsize + 1) * (width / randsize + 1);
440
  int *squares = (int *) calloc(max, sizeof (*squares));
441
  int i;
442
  int columns = width / randsize + 1;  /* Add an extra for roundoff */
443
 
444
  for (i = 0; i < max; i++)
445
    squares[i] = i;
446
 
447
  for (i = 0; i < max; i++)
448
    {
449
      int t, r;
450
      t = squares[i];
451
      r = random() % max;
452
      squares[i] = squares[r];
453
      squares[r] = t;
454
    }
455
 
456
  for (i = 0; i < max; i++)
457
    {
458
      GrRect(wid, erase_gc,
459
                     (squares[i] % columns) * randsize,
460
                     (squares[i] / columns) * randsize,
461
                     randsize, randsize);
462
      wait_sync ();
463
      if (delay > 0 && ((i % granularity) == 0))
464
      usleep(delay * granularity);
465
    }
466
  free(squares);
467
}
468
 
469
/* I first saw something like this, albeit in reverse, in an early Tetris
470
   implementation for the Mac.
471
    -- Torbjörn Andersson <torbjorn@dev.eurotime.se>
472
 */
473
 
474
static void
475
slide_lines (int width, int height, int delay, int granularity)
476
{
477
  int slide_old_x, slide_new_x, clear_x;
478
  int x, y, dx, dy;
479
 
480
  /* This might need some tuning. The idea is to get sensible values no
481
     matter what the size of the window.
482
 
483
     Everything moves at constant speed. Should it accelerate instead? */
484
 
485
  granularity *= 2;
486
 
487
  dy = MAX (1, height / granularity);
488
  dx = MAX (1, width / 100);
489
 
490
  for (x = 0; x < width; x += dx)
491
    {
492
      for (y = 0; y < height; y += dy)
493
        {
494
          if ((y / dy) & 1)
495
            {
496
              slide_old_x = x;
497
              slide_new_x = x + dx;
498
              clear_x = x;
499
            }
500
          else
501
            {
502
              slide_old_x = dx;
503
              slide_new_x = 0;
504
              clear_x = width - x - dx;
505
            }
506
 
507
          GrCopyArea (wid, erase_gc, slide_old_x, y, width - x - dx,
508
                     dy, wid, slide_new_x, y, MWROP_SRCCOPY);
509
          GrRect (wid, erase_gc, clear_x, y, dx, dy);
510
        }
511
 
512
      wait_sync ();
513
      usleep(delay * 3);
514
    }
515
}
516
 
517
static Eraser erasers[] = {
518
  random_lines,
519
  venetian,
520
  triple_wipe,
521
  quad_wipe,
522
/*  circle_wipe,
523
  three_circle_wipe, // needs floating point */
524
  squaretate,
525
/*  fizzle, // Too slow */
526
  random_squares,
527
  spiral,
528
  slide_lines,
529
};
530
 
531
 
532
void
533
erase_full_window()
534
{
535
  int granularity = 25;
536
  int delay = 0;
537
  int mode = random() % countof(erasers);
538
  (*(erasers[mode])) (WINDOW_WIDTH, WINDOW_HEIGHT, delay, granularity);
539
  GrRect (wid, erase_gc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
540
  wait_sync ();
541
}
542
 

powered by: WebSVN 2.1.0

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