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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [mw/] [src/] [demos/] [nxroach/] [nxroach.x] - Blame information for rev 1765

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
    Xroach - A game of skill.  Try to find the roaches under your windows.
3
 
4
    Copyright 1991 by J.T. Anderson
5
 
6
    jta@locus.com
7
 
8
    This program may be freely distributed provided that all
9
    copyright notices are retained.
10
 
11
    To build:
12
      cc -o xroach roach.c -lX11 [-lsocketorwhatever] [-lm] [-l...]
13
 
14
    Dedicated to Greg McFarlane.   (gregm@otc.otca.oz.au)
15
*/
16
//#include 
17
//#include 
18
//#include 
19
 
20
#include 
21
#include 
22
#include 
23
#include 
24
#include 
25
#define MWINCLUDECOLORS
26
#include "nano-X.h"
27
#include "XtoNX.h"
28
 
29
char Copyright[] = "Xroach\nCopyright 1991 J.T. Anderson";
30
 
31
#include "roachmap.h"
32
 
33
typedef unsigned long Pixel;
34
typedef int ErrorHandler();
35
 
36
#define SCAMPER_EVENT   99              // LASTEvent+1?
37
 
38
#if !defined(GRAB_SERVER)
39
#define GRAB_SERVER     0
40
#endif
41
 
42
STATIC_FUNCTIONS;
43
 
44
Display *display;
45
int screen;
46
Window rootWin;
47
unsigned int display_width, display_height;
48
int center_x, center_y;
49
GC gc;
50
char *display_name = NULL;
51
Pixel black, white;
52
 
53
int done = 0;
54
int eventBlock = 0;
55
int errorVal = 0;
56
 
57
typedef struct Roach {
58
    RoachMap *rp;
59
    int index;
60
    float x;
61
    float y;
62
    int intX;
63
    int intY;
64
    int hidden;
65
    int turnLeft;
66
    int steps;
67
} Roach;
68
 
69
Roach *roaches;
70
int maxRoaches = 10;
71
int curRoaches = 0;
72
float roachSpeed = 20.0;
73
 
74
Region rootVisible = 0;
75
 
76
void Usage(void);
77
void SigHandler(int sig);
78
void AddRoach(void);
79
void MoveRoach(int Rx);
80
void DrawRoaches(void);
81
void CoverRoot(void);
82
int CalcRootVisible(void);
83
int MarkHiddenRoaches(void);
84
//Pixel AllocNamedColor();
85
 
86
int
87
main(int ac, char **av)
88
{
89
    //XGCValues xgcv;
90
    int ax;
91
    char *arg;
92
    RoachMap *rp;
93
    int rx;
94
    float angle;
95
    XEvent ev;
96
    char *roachColor = "black";
97
    int nVis;
98
    int needCalc;
99
 
100
    /*
101
       Process command line options.
102
    */
103
    for (ax=1; ax
104
        arg = av[ax];
105
        if (strcmp(arg, "-display") == 0) {
106
            display_name = av[++ax];
107
        }
108
        else if (strcmp(arg, "-rc") == 0) {
109
            roachColor = av[++ax];
110
        }
111
        else if (strcmp(arg, "-speed") == 0) {
112
            roachSpeed = atof(av[++ax]);
113
        }
114
        else if (strcmp(arg, "-roaches") == 0) {
115
            maxRoaches = strtol(av[++ax], (char **)NULL, 0);
116
        }
117
        else {
118
            Usage();
119
        }
120
    }
121
 
122
    srand((int)time((long *)NULL));
123
 
124
    /*
125
       Catch some signals so we can erase any visible roaches.
126
    */
127
    signal(SIGKILL, SigHandler);
128
    signal(SIGINT, SigHandler);
129
    signal(SIGTERM, SigHandler);
130
    signal(SIGHUP, SigHandler);
131
 
132
    display = XOpenDisplay(display_name);
133
    if (display == NULL) {
134
        if (display_name == NULL) display_name = getenv("DISPLAY");
135
        (void) fprintf(stderr, "%s: cannot connect to server %s\n", av[0],
136
            display_name ? display_name : "(default)");
137
        exit(1);
138
    }
139
 
140
    screen = DefaultScreen(display);
141
    rootWin = RootWindow(display, screen);
142
    black = BlackPixel(display, screen);
143
    white = WhitePixel(display, screen);
144
 
145
    display_width = DisplayWidth(display, screen);
146
    display_height = DisplayHeight(display, screen);
147
    center_x = display_width / 2;
148
    center_y = display_height / 2;
149
 
150
    /*
151
       Create roach pixmaps at several orientations.
152
    */
153
    for (ax=0; ax<360; ax+=ROACH_ANGLE) {
154
        rx = ax / ROACH_ANGLE;
155
        angle = rx * 0.261799387799;
156
        rp = &roachPix[rx];
157
        //rp->pixmap = XCreateBitmapFromData(display, rootWin,
158
            //rp->roachBits, rp->width, rp->height);
159
        rp->pixmap = XCreatePixmapFromBitmapData(display, rootWin,
160
            rp->roachBits, rp->width, rp->height, BLACK, CYAN, 1);      //FIXME
161
        rp->sine = sin(angle);
162
        rp->cosine = cos(angle);
163
    }
164
 
165
    roaches = (Roach *)malloc(sizeof(Roach) * maxRoaches);
166
 
167
    gc = XCreateGC(display, rootWin, 0L, &xgcv);
168
    //XSetForeground(display, gc, AllocNamedColor(roachColor, black));
169
    //XSetFillStyle(display, gc, FillStippled);
170
 
171
    while (curRoaches < maxRoaches)
172
        AddRoach();
173
 
174
    XSelectInput(display, rootWin, ExposureMask | SubstructureNotifyMask);
175
 
176
    needCalc = 1;
177
    while (!done) {
178
        if (XPending(display)) {
179
            XNextEvent(display, &ev);
180
        }
181
        else {
182
            if (needCalc) {
183
                needCalc = CalcRootVisible();
184
            }
185
            nVis = MarkHiddenRoaches();
186
            if (nVis) {
187
                ev.type = SCAMPER_EVENT;
188
            }
189
            else {
190
                DrawRoaches();
191
                GrDelay(100);
192
                eventBlock = 1;
193
                XNextEvent(display, &ev);
194
                eventBlock = 0;
195
            }
196
        }
197
 
198
        switch (ev.type) {
199
 
200
            case SCAMPER_EVENT:
201
                for (rx=0; rx
202
                    if (!roaches[rx].hidden)
203
                        MoveRoach(rx);
204
                }
205
                DrawRoaches();
206
                GrDelay(100);
207
                XSync(display, False);
208
                break;
209
 
210
            case Expose:
211
            //case MapNotify:
212
            //case UnmapNotify:
213
            case ConfigureNotify:
214
                needCalc = 1;
215
                break;
216
 
217
        }
218
    }
219
 
220
    CoverRoot();
221
 
222
    XCloseDisplay(display);
223
    return 0;
224
}
225
 
226
#define USEPRT(msg) fprintf(stderr, msg)
227
 
228
void
229
Usage(void)
230
{
231
    USEPRT("Usage: nxroach [options]\n\n");
232
    USEPRT("Options:\n");
233
    USEPRT("       -display displayname\n");
234
    USEPRT("       -rc      roachcolor\n");
235
    USEPRT("       -roaches numroaches\n");
236
    USEPRT("       -speed   roachspeed\n");
237
 
238
    exit(1);
239
}
240
 
241
void
242
SigHandler(int sig)
243
{
244
 
245
    /*
246
       If we are blocked, no roaches are visible and we can just bail
247
       out.  If we are not blocked, then let the main procedure clean
248
       up the root window.
249
    */
250
    if (eventBlock) {
251
        XCloseDisplay(display);
252
        exit(0);
253
    }
254
    else {
255
        done = 1;
256
    }
257
}
258
 
259
/*
260
   Generate random integer between 0 and maxVal-1.
261
*/
262
int
263
RandInt(int maxVal)
264
{
265
        return rand() % maxVal;
266
}
267
 
268
/*
269
   Check for roach completely in specified rectangle.
270
*/
271
int
272
RoachInRect(roach, rx, ry, x, y, width, height)
273
Roach *roach;
274
int rx;
275
int ry;
276
int x;
277
int y;
278
unsigned int width;
279
unsigned int height;
280
{
281
    if (rx < x) return 0;
282
    if ((rx + roach->rp->width) > (x + width)) return 0;
283
    if (ry < y) return 0;
284
    if ((ry + roach->rp->height) > (y + height)) return 0;
285
 
286
    return 1;
287
}
288
 
289
/*
290
   Check for roach overlapping specified rectangle.
291
*/
292
int
293
RoachOverRect(roach, rx, ry, x, y, width, height)
294
Roach *roach;
295
int rx;
296
int ry;
297
int x;
298
int y;
299
unsigned int width;
300
unsigned int height;
301
{
302
    if (rx >= (x + width)) return 0;
303
    if ((rx + roach->rp->width) <= x) return 0;
304
    if (ry >= (y + height)) return 0;
305
    if ((ry + roach->rp->height) <= y) return 0;
306
 
307
    return 1;
308
}
309
 
310
/*
311
   Give birth to a roach.
312
*/
313
void
314
AddRoach(void)
315
{
316
    Roach *r;
317
 
318
    if (curRoaches < maxRoaches) {
319
        r = &roaches[curRoaches++];
320
        r->index = RandInt(ROACH_HEADINGS);
321
        r->rp = &roachPix[r->index];
322
        r->x = RandInt(display_width - r->rp->width);
323
        r->y = RandInt(display_height - r->rp->height);
324
        r->intX = -1;
325
        r->intY = -1;
326
        r->hidden = 0;
327
        r->steps = RandInt(200);
328
        r->turnLeft = RandInt(100) >= 50;
329
    }
330
}
331
 
332
/*
333
   Turn a roach.
334
*/
335
void
336
TurnRoach(roach)
337
Roach *roach;
338
{
339
    if (roach->index != (roach->rp - roachPix)) return;
340
 
341
    if (roach->turnLeft) {
342
        roach->index += (RandInt(30) / 10) + 1;
343
        if (roach->index >= ROACH_HEADINGS)
344
            roach->index -= ROACH_HEADINGS;
345
    }
346
    else {
347
        roach->index -= (RandInt(30) / 10) + 1;
348
        if (roach->index < 0)
349
            roach->index += ROACH_HEADINGS;
350
    }
351
}
352
 
353
/*
354
   Move a roach.
355
*/
356
void
357
MoveRoach(int rx)
358
{
359
    Roach *roach;
360
    Roach *r2;
361
    float newX;
362
    float newY;
363
    int ii;
364
 
365
    roach = &roaches[rx];
366
    newX = roach->x + (roachSpeed * roach->rp->cosine);
367
    newY = roach->y - (roachSpeed * roach->rp->sine);
368
 
369
    if (RoachInRect(roach, (int)newX, (int)newY,
370
                            0, 0, display_width, display_height)) {
371
 
372
        roach->x = newX;
373
        roach->y = newY;
374
 
375
        if (roach->steps-- <= 0) {
376
            TurnRoach(roach);
377
            roach->steps = RandInt(200);
378
        }
379
 
380
        for (ii=rx+1; ii
381
            r2 = &roaches[ii];
382
            if (RoachOverRect(roach, (int)newX, (int)newY,
383
                r2->intX, r2->intY, r2->rp->width, r2->rp->height)) {
384
 
385
                TurnRoach(roach);
386
            }
387
        }
388
    }
389
    else {
390
        TurnRoach(roach);
391
    }
392
}
393
 
394
/*
395
   Draw all roaches.
396
*/
397
void
398
DrawRoaches(void)
399
{
400
    Roach *roach;
401
    int rx;
402
 
403
    for (rx=0; rx
404
        roach = &roaches[rx];
405
 
406
        if (roach->intX >= 0) {
407
            XClearArea(display, rootWin, roach->intX, roach->intY,
408
                roach->rp->width, roach->rp->height, False);
409
        }
410
    }
411
 
412
    for (rx=0; rx
413
        roach = &roaches[rx];
414
 
415
        if (!roach->hidden) {
416
            roach->intX = roach->x;
417
            roach->intY = roach->y;
418
            roach->rp = &roachPix[roach->index];
419
 
420
            //XSetStipple(display, gc, roach->rp->pixmap);
421
            //XSetTSOrigin(display, gc, roach->intX, roach->intY);
422
            //XFillRectangle(display, rootWin, gc,
423
                //roach->intX, roach->intY, roach->rp->width, roach->rp->height);
424
            GrCopyArea(GR_ROOT_WINDOW_ID, gc, roach->intX, roach->intY,
425
                roach->rp->width, roach->rp->height, roach->rp->pixmap, 0, 0,
426
                MWROP_SRCCOPY);
427
        }
428
        else {
429
            roach->intX = -1;
430
        }
431
    }
432
}
433
 
434
/*
435
   Cover root window to erase roaches.
436
*/
437
void
438
CoverRoot(void)
439
{
440
    //XSetWindowAttributes xswa;
441
    //long wamask;
442
    Window roachWin;
443
 
444
#define CopyFromParent  0
445
#define InputOutput     0
446
    //xswa.background_pixmap = ParentRelative;
447
    //xswa.override_redirect = True;
448
    //wamask = CWBackPixmap | CWOverrideRedirect;
449
    roachWin = XCreateWindow(display, rootWin, 0, 0,
450
                    display_width, display_height, 0, CopyFromParent,
451
                    InputOutput, CopyFromParent, wamask, &xswa);
452
    XLowerWindow(display, roachWin);
453
    XMapWindow(display, roachWin);
454
    XFlush(display);
455
}
456
 
457
#if !GRAB_SERVER
458
 
459
#if 0
460
int
461
RoachErrors(dpy, err)
462
Display *dpy;
463
XErrorEvent *err;
464
{
465
    errorVal = err->error_code;
466
 
467
    return 0;
468
}
469
#endif
470
#endif /* GRAB_SERVER */
471
 
472
/*
473
   Calculate Visible region of root window.
474
*/
475
int
476
CalcRootVisible(void)
477
{
478
    Region covered;
479
    Region visible;
480
    Window *children;
481
    int nChildren;
482
    Window dummy;
483
    //XWindowAttributes wa;
484
    int wx;
485
    XRectangle rect;
486
    int winX, winY;
487
    unsigned int winHeight, winWidth;
488
    unsigned int borderWidth;
489
    unsigned int depth;
490
    GR_WINDOW_INFO info;
491
 
492
    /*
493
       If we don't grab the server, the XGetWindowAttribute or XGetGeometry
494
       calls can abort us.  On the other hand, the server grabs can make for
495
       some annoying delays.
496
    */
497
#if GRAB_SERVER
498
    //XGrabServer(display);
499
#else
500
    //XSetErrorHandler(RoachErrors);
501
#endif
502
 
503
    /*
504
       Get children of root.
505
    */
506
    XQueryTree(display, rootWin, &dummy, &dummy, &children, &nChildren);
507
 
508
    /*
509
       For each mapped child, add the window rectangle to the covered
510
       region.
511
    */
512
    covered = XCreateRegion();
513
    for (wx=0; wx
514
        //if (XEventsQueued(display, QueuedAlready)) return 1;
515
        //errorVal = 0;
516
        //XGetWindowAttributes(display, children[wx], &wa);
517
        //if (errorVal) continue;
518
        GrGetWindowInfo(children[wx], &info);
519
        //if (wa.map_state == IsViewable) {
520
        if (info.unmapcount == 0) {
521
            //XGetGeometry(display, children[wx], &dummy, &winX, &winY,
522
                //&winWidth, &winHeight, &borderWidth, &depth);
523
            //if (errorVal) continue;
524
            rect.x = info.x;
525
            rect.y = info.y;
526
            //rect.width = winWidth + (borderWidth * 2);
527
            //rect.height = winHeight + (borderWidth * 2);
528
            rect.width = info.width;
529
            rect.height = info.height;
530
            XUnionRectWithRegion(&rect, covered, covered);
531
        }
532
    }
533
    XFree((char *)children);
534
 
535
#if GRAB_SERVER
536
    //XUngrabServer(display);
537
#else
538
    //XSetErrorHandler((ErrorHandler *)NULL);
539
#endif
540
 
541
    /*
542
       Subtract the covered region from the root window region.
543
    */
544
    visible = XCreateRegion();
545
    rect.x = 0;
546
    rect.y = 0;
547
    rect.width = display_width;
548
    rect.height = display_height;
549
    XUnionRectWithRegion(&rect, visible, visible);
550
    XSubtractRegion(visible, covered, visible);
551
    XDestroyRegion(covered);
552
 
553
    /*
554
       Save visible region globally.
555
    */
556
    if (rootVisible)
557
        XDestroyRegion(rootVisible);
558
    rootVisible = visible;
559
 
560
 
561
    /*
562
       Mark all roaches visible.
563
    */
564
    for (wx=0; wx
565
        roaches[wx].hidden = 0;
566
 
567
    return 0;
568
}
569
 
570
/*
571
   Mark hidden roaches.
572
*/
573
int
574
MarkHiddenRoaches(void)
575
{
576
    int rx;
577
    Roach *r;
578
    int nVisible;
579
 
580
    nVisible = 0;
581
    for (rx=0; rx
582
        r = &roaches[rx];
583
 
584
        if (!r->hidden) {
585
            if (r->intX > 0 && XRectInRegion(rootVisible, r->intX, r->intY,
586
                            r->rp->width, r->rp->height) == RectangleOut) {
587
                r->hidden = 1;
588
            }
589
            else {
590
                nVisible++;
591
            }
592
        }
593
    }
594
 
595
    return nVisible;
596
}
597
 
598
#if 0
599
/*
600
   Allocate a color by name.
601
*/
602
Pixel
603
AllocNamedColor(colorName, dfltPix)
604
char *colorName;
605
Pixel dfltPix;
606
{
607
        Pixel pix;
608
        XColor scrncolor;
609
        XColor exactcolor;
610
 
611
        if (XAllocNamedColor(display, DefaultColormap(display, screen),
612
                colorName, &scrncolor, &exactcolor)) {
613
                pix = scrncolor.pixel;
614
        }
615
        else {
616
                pix = dfltPix;
617
        }
618
 
619
        return pix;
620
}
621
#endif

powered by: WebSVN 2.1.0

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