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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [services/] [gfx/] [mw/] [v2_0/] [src/] [demos/] [nxroach/] [nxroach.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
/*
2
    Xroach - A game of skill.  Try to find the roaches under your windows.
3
    Ported to Nano-X by Greg Haerr
4
 
5
    Copyright 1991 by J.T. Anderson
6
    jta@locus.com
7
 
8
    This program may be freely distributed provided that all
9
    copyright notices are retained.
10
 
11
    Dedicated to Greg McFarlane.   (gregm@otc.otca.oz.au)
12
*/
13
char Copyright[] = "nxroach\nCopyright 1991 J.T. Anderson";
14
 
15
#include <stdio.h>
16
#include <math.h>
17
#include <signal.h>
18
#include <stdlib.h>
19
#include <time.h>
20
#define MWINCLUDECOLORS
21
#include "nano-X.h"
22
 
23
#define None    0
24
#define Pixmap  GR_WINDOW_ID
25
#include "roachmap.h"
26
 
27
#define SCAMPER_EVENT   99
28
 
29
typedef struct Roach {
30
    RoachMap *rp;
31
    int index;
32
    float x;
33
    float y;
34
    int intX;
35
    int intY;
36
    int hidden;
37
    int turnLeft;
38
    int steps;
39
} Roach;
40
 
41
GR_COORD display_width, display_height;
42
GR_GC_ID gc;
43
GR_COLOR roachColor = BLACK;
44
GR_REGION_ID rootVisible = 0;
45
GR_BOOL done = GR_FALSE;
46
GR_BOOL eventBlock = GR_FALSE;
47
 
48
Roach *roaches;
49
int maxRoaches = 10;
50
int curRoaches = 0;
51
float roachSpeed = 20.0;
52
 
53
void Usage(void);
54
void SigHandler(int sig);
55
void AddRoach(void);
56
void MoveRoach(int Rx);
57
void DrawRoaches(void);
58
void CoverRoot(void);
59
int CalcRootVisible(void);
60
int MarkHiddenRoaches(void);
61
 
62
int
63
main(int ac, char **av)
64
{
65
    int ax;
66
    char *arg;
67
    RoachMap *rp;
68
    int rx;
69
    float angle;
70
    GR_EVENT ev;
71
    int nVis;
72
    int needCalc;
73
    GR_SCREEN_INFO sinfo;
74
 
75
    /*
76
       Process command line options.
77
    */
78
    for (ax=1; ax<ac; ax++) {
79
        arg = av[ax];
80
        if (strcmp(arg, "-rc") == 0) {
81
            roachColor = atoi(av[++ax]);
82
        }
83
        else if (strcmp(arg, "-speed") == 0) {
84
            roachSpeed = atof(av[++ax]);
85
        }
86
        else if (strcmp(arg, "-roaches") == 0) {
87
            maxRoaches = strtol(av[++ax], (char **)NULL, 0);
88
        }
89
        else {
90
            Usage();
91
        }
92
    }
93
 
94
    srand((int)time((long *)NULL));
95
 
96
    /*
97
       Catch some signals so we can erase any visible roaches.
98
    */
99
    signal(SIGKILL, SigHandler);
100
    signal(SIGINT, SigHandler);
101
    signal(SIGTERM, SigHandler);
102
    signal(SIGHUP, SigHandler);
103
 
104
    if (GrOpen() < 0) {
105
        fprintf(stderr, "can't open graphics\n");
106
        exit(1);
107
    }
108
 
109
    GrGetScreenInfo(&sinfo);
110
    display_width = sinfo.cols;
111
    display_height = sinfo.rows;
112
 
113
    /*
114
       Create roach pixmaps at several orientations.
115
    */
116
    for (ax=0; ax<360; ax+=ROACH_ANGLE) {
117
        rx = ax / ROACH_ANGLE;
118
        angle = rx * 0.261799387799;
119
        rp = &roachPix[rx];
120
        rp->pixmap = GrNewPixmapFromData(rp->width, rp->height, WHITE, BLACK,
121
                rp->roachBits, GR_BMDATA_BYTEREVERSE|GR_BMDATA_BYTESWAP);
122
        rp->sine = sin(angle);
123
        rp->cosine = cos(angle);
124
    }
125
 
126
    roaches = (Roach *)malloc(sizeof(Roach) * maxRoaches);
127
 
128
    gc = GrNewGC();
129
 
130
    while (curRoaches < maxRoaches)
131
        AddRoach();
132
 
133
    GrSelectEvents(GR_ROOT_WINDOW_ID, GR_EVENT_MASK_EXPOSURE | GR_EVENT_MASK_CHLD_UPDATE);
134
 
135
    needCalc = 1;
136
    while (!done) {
137
        if (GrPeekEvent(&ev))
138
            GrGetNextEvent(&ev);
139
        else {
140
            if (needCalc) {
141
                needCalc = CalcRootVisible();
142
            }
143
            nVis = MarkHiddenRoaches();
144
            if (nVis) {
145
                ev.type = SCAMPER_EVENT;
146
            }
147
            else {
148
                DrawRoaches();
149
                eventBlock = GR_TRUE;
150
                GrGetNextEvent(&ev);
151
                eventBlock = GR_FALSE;
152
            }
153
        }
154
 
155
        switch (ev.type) {
156
            case SCAMPER_EVENT:
157
                for (rx=0; rx<curRoaches; rx++) {
158
                    if (!roaches[rx].hidden)
159
                        MoveRoach(rx);
160
                }
161
                DrawRoaches();
162
                GrDelay(100);
163
                break;
164
 
165
            case GR_EVENT_TYPE_EXPOSURE:
166
            case GR_EVENT_TYPE_CHLD_UPDATE:
167
                needCalc = 1;
168
                break;
169
 
170
        }
171
    }
172
 
173
    CoverRoot();
174
    GrClose();
175
    return 0;
176
}
177
 
178
void
179
Usage(void)
180
{
181
    fprintf(stderr, "Usage: nxroach [options]\n\n");
182
    fprintf(stderr, "Options:\n");
183
    fprintf(stderr, "       -rc      roachcolor\n");
184
    fprintf(stderr, "       -roaches numroaches\n");
185
    fprintf(stderr, "       -speed   roachspeed\n");
186
 
187
    exit(1);
188
}
189
 
190
void
191
SigHandler(int sig)
192
{
193
    /*
194
       If we are blocked, no roaches are visible and we can just bail
195
       out.  If we are not blocked, then let the main procedure clean
196
       up the root window.
197
    */
198
    if (eventBlock) {
199
        GrClose();
200
        exit(0);
201
    }
202
    else {
203
        done = GR_TRUE;
204
    }
205
}
206
 
207
/*
208
   Generate random integer between 0 and maxVal-1.
209
*/
210
int
211
RandInt(int maxVal)
212
{
213
        return rand() % maxVal;
214
}
215
 
216
/*
217
   Check for roach completely in specified rectangle.
218
*/
219
int
220
RoachInRect(Roach *roach, int rx, int ry, int x, int y,
221
        unsigned int width, unsigned int height)
222
{
223
    if (rx < x) return 0;
224
    if ((rx + roach->rp->width) > (x + width)) return 0;
225
    if (ry < y) return 0;
226
    if ((ry + roach->rp->height) > (y + height)) return 0;
227
 
228
    return 1;
229
}
230
 
231
/*
232
   Check for roach overlapping specified rectangle.
233
*/
234
int
235
RoachOverRect(Roach *roach, int rx, int ry, int x, int y,
236
        unsigned int width, unsigned int height)
237
{
238
    if (rx >= (x + width)) return 0;
239
    if ((rx + roach->rp->width) <= x) return 0;
240
    if (ry >= (y + height)) return 0;
241
    if ((ry + roach->rp->height) <= y) return 0;
242
 
243
    return 1;
244
}
245
 
246
/*
247
   Give birth to a roach.
248
*/
249
void
250
AddRoach(void)
251
{
252
    Roach *r;
253
 
254
    if (curRoaches < maxRoaches) {
255
        r = &roaches[curRoaches++];
256
        r->index = RandInt(ROACH_HEADINGS);
257
        r->rp = &roachPix[r->index];
258
        r->x = RandInt(display_width - r->rp->width);
259
        r->y = RandInt(display_height - r->rp->height);
260
        r->intX = -1;
261
        r->intY = -1;
262
        r->hidden = 0;
263
        r->steps = RandInt(200);
264
        r->turnLeft = RandInt(100) >= 50;
265
    }
266
}
267
 
268
/*
269
   Turn a roach.
270
*/
271
void
272
TurnRoach(Roach *roach)
273
{
274
    if (roach->index != (roach->rp - roachPix)) return;
275
 
276
    if (roach->turnLeft) {
277
        roach->index += (RandInt(30) / 10) + 1;
278
        if (roach->index >= ROACH_HEADINGS)
279
            roach->index -= ROACH_HEADINGS;
280
    }
281
    else {
282
        roach->index -= (RandInt(30) / 10) + 1;
283
        if (roach->index < 0)
284
            roach->index += ROACH_HEADINGS;
285
    }
286
}
287
 
288
/*
289
   Move a roach.
290
*/
291
void
292
MoveRoach(int rx)
293
{
294
    Roach *roach;
295
    Roach *r2;
296
    float newX;
297
    float newY;
298
    int ii;
299
 
300
    roach = &roaches[rx];
301
    newX = roach->x + (roachSpeed * roach->rp->cosine);
302
    newY = roach->y - (roachSpeed * roach->rp->sine);
303
 
304
    if (RoachInRect(roach, (int)newX, (int)newY,
305
                            0, 0, display_width, display_height)) {
306
 
307
        roach->x = newX;
308
        roach->y = newY;
309
 
310
        if (roach->steps-- <= 0) {
311
            TurnRoach(roach);
312
            roach->steps = RandInt(200);
313
        }
314
 
315
        for (ii=rx+1; ii<curRoaches; ii++) {
316
            r2 = &roaches[ii];
317
            if (RoachOverRect(roach, (int)newX, (int)newY,
318
                r2->intX, r2->intY, r2->rp->width, r2->rp->height)) {
319
 
320
                TurnRoach(roach);
321
            }
322
        }
323
    }
324
    else {
325
        TurnRoach(roach);
326
    }
327
}
328
 
329
/*
330
   Draw all roaches.
331
*/
332
void
333
DrawRoaches(void)
334
{
335
    Roach *roach;
336
    int rx;
337
 
338
    for (rx=0; rx<curRoaches; rx++) {
339
        roach = &roaches[rx];
340
 
341
        if (roach->intX >= 0) {
342
            GrClearArea(GR_ROOT_WINDOW_ID, roach->intX, roach->intY,
343
                roach->rp->width, roach->rp->height, GR_FALSE);
344
        }
345
    }
346
 
347
    for (rx=0; rx<curRoaches; rx++) {
348
        roach = &roaches[rx];
349
 
350
        if (!roach->hidden) {
351
            int size = roach->rp->width * roach->rp->height;
352
            GR_PIXELVAL roachbuf[size];
353
            GR_PIXELVAL screenbuf[size];
354
            int i;
355
 
356
            roach->intX = roach->x;
357
            roach->intY = roach->y;
358
            roach->rp = &roachPix[roach->index];
359
 
360
            /*
361
            //XSetForeground(display, gc, AllocNamedColor(roachColor, black));
362
            //XSetFillStyle(display, gc, FillStippled);
363
            //XSetStipple(display, gc, roach->rp->pixmap);
364
            //XSetTSOrigin(display, gc, roach->intX, roach->intY);
365
            //XFillRectangle(display, rootWin, gc,
366
                //roach->intX, roach->intY, roach->rp->width, roach->rp->height);
367
            */
368
 
369
            /* read roach bitmap*/
370
            GrReadArea(roach->rp->pixmap, 0, 0,
371
                roach->rp->width, roach->rp->height, roachbuf);
372
 
373
            /* read root window*/
374
            GrReadArea(GR_ROOT_WINDOW_ID, roach->intX, roach->intY,
375
                roach->rp->width, roach->rp->height, screenbuf);
376
 
377
            /* convert fg roach bitmap bits to roach color on root window bits*/
378
            for (i=0; i<size; ++i)
379
                    if (roachbuf[i] != BLACK)
380
                            screenbuf[i] = roachColor;
381
 
382
            /* write root window*/
383
            GrArea(GR_ROOT_WINDOW_ID, gc, roach->intX, roach->intY,
384
                roach->rp->width, roach->rp->height, screenbuf, MWPF_PIXELVAL);
385
        }
386
        else {
387
            roach->intX = -1;
388
        }
389
    }
390
    GrFlush();
391
}
392
 
393
/*
394
   Cover root window to erase roaches.
395
*/
396
void
397
CoverRoot(void)
398
{
399
    GR_WINDOW_ID roachWin;
400
 
401
    roachWin = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, display_width, display_height,
402
                    0, CYAN, BLACK);
403
    GrLowerWindow(roachWin);
404
    GrMapWindow(roachWin);
405
    GrFlush();
406
}
407
 
408
/*
409
   Calculate Visible region of root window.
410
*/
411
int
412
CalcRootVisible(void)
413
{
414
    GR_REGION_ID covered;
415
    GR_REGION_ID visible;
416
    GR_WINDOW_ID parent;
417
    GR_WINDOW_ID *children;
418
    GR_COUNT nChildren;
419
    GR_COUNT wx;
420
    GR_RECT rect;
421
    GR_WINDOW_INFO info;
422
 
423
    /*
424
       Get children of root.
425
    */
426
    GrQueryTree(GR_ROOT_WINDOW_ID, &parent, &children, &nChildren);
427
 
428
    /*
429
       For each mapped child, add the window rectangle to the covered
430
       region.
431
    */
432
    covered = GrNewRegion();
433
    for (wx=0; wx<nChildren; wx++) {
434
        GrGetWindowInfo(children[wx], &info);
435
        if (info.unmapcount == 0) {
436
            rect.x = info.x;
437
            rect.y = info.y;
438
            rect.width = info.width;
439
            rect.height = info.height;
440
            GrUnionRectWithRegion(covered, &rect);
441
        }
442
    }
443
    free(children);
444
 
445
    /*
446
       Subtract the covered region from the root window region.
447
    */
448
    visible = GrNewRegion();
449
    rect.x = 0;
450
    rect.y = 0;
451
    rect.width = display_width;
452
    rect.height = display_height;
453
    GrUnionRectWithRegion(visible, &rect);
454
    GrSubtractRegion(visible, visible, covered);
455
    GrDestroyRegion(covered);
456
 
457
    /*
458
       Save visible region globally.
459
    */
460
    if (rootVisible)
461
        GrDestroyRegion(rootVisible);
462
    rootVisible = visible;
463
 
464
    /*
465
       Mark all roaches visible.
466
    */
467
    for (wx=0; wx<curRoaches; wx++)
468
        roaches[wx].hidden = 0;
469
 
470
    return 0;
471
}
472
 
473
/*
474
   Mark hidden roaches.
475
*/
476
int
477
MarkHiddenRoaches(void)
478
{
479
    int rx;
480
    Roach *r;
481
    int nVisible;
482
 
483
    nVisible = 0;
484
    for (rx=0; rx<curRoaches; rx++) {
485
        r = &roaches[rx];
486
 
487
        if (!r->hidden) {
488
            if (r->intX > 0 && GrRectInRegion(rootVisible, r->intX, r->intY,
489
                            r->rp->width, r->rp->height) == MWRECT_OUT) {
490
                r->hidden = 1;
491
            }
492
            else {
493
                nVisible++;
494
            }
495
        }
496
    }
497
 
498
    return nVisible;
499
}

powered by: WebSVN 2.1.0

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