make sure "S" is generated.
[AROS-Contrib.git] / fish / aroach / ARoach.c
blobdcb9e724064cc7e6d9409b671c218877d9ce0a59
1 /**********************************************************************/
2 /* */
3 /* ARoach.c */
4 /* */
5 /* © Copyright Stefan Winterstein 1993. Freely Distributable. */
6 /* */
7 /**********************************************************************/
10 #include "ARoach.h"
12 /* #define DEBUG *//* general debugging output */
13 /* #define ROACHNUMBERING *//* each roach has a number */
14 /* #define USE_WB_WINDOW *//* use WB backdrop window if available (Hack!) */
15 /* #define CHECK_COLLISION *//* roaches turn when bumping into each other */
16 #define INTELLIGENT /* roaches sense near window */
18 #ifdef DEBUG
19 #define D(x) x;
20 #else
21 #define D(x) ;
22 #endif
24 int RandInt(int maxVal);
25 void AddRoach(void);
26 void TurnRoach(Roach *);
27 void MoveRoach(int rx);
28 int RoachOverRect(Roach *, int, int, int, int, unsigned int, unsigned int);
29 int RoachInRect(Roach *, int, int, int, int, unsigned int, unsigned int);
30 void DrawRoaches(void);
31 void MoveRoaches(void);
32 void RemoveRoaches(void);
33 int MarkHiddenRoaches(void);
34 void checkSquish(void);
35 void ConvertRoachData(void);
36 struct Window *FindRootWindow(struct Screen *);
37 struct Bob *MakeBOBFromData(char *data, UWORD width, UWORD height);
38 void SetupAnimation(void);
39 void CleanExit(LONG ReturnCode);
40 void Die(const UBYTE * msg);
41 int main(int argc, char **argv);
45 * Global Data
47 struct GelsInfo *GelsInfo;
48 struct Layer *myLayer;
49 struct Layer_Info *LayerInfo;
50 char PubScreen[MAXNAMESIZE];
51 int RasDepth;
52 struct RastPort *rp;
53 struct RDArgs RDArgs;
54 struct Screen *Screen;
55 struct ViewPort *vp;
56 struct Window *roachWindow;
57 struct Window *userWindow;
61 * Parameters for SAS/C 6
63 int __oslibversion = 37; /* for SAS/C auto-init */
64 char __stdiowin[] = "CON:10/10/600/100/ARoach Output"; /* SAS/C window from WB */
65 long __stack = 16000; /* enough for 1000 Roaches */
68 * Things for option parsing
70 #define ROACH_LIMIT 1000 /* max. # of roaches */
71 /* depends on __stack */
72 #define ROACH_SPEED 20 /* default speed */
73 #define ROACH_NUM 10 /* default # of roaches */
75 #define TEMPLATE "ROACHES/K/N,SPEED/K/N,SQUISH/S,SCREEN=PUBSCREEN/K,HELP/S"
76 enum { OPT_ROACHES, OPT_SPEED, OPT_SQUISH, OPT_SCREEN, OPT_HELP,
77 OPT_COUNT};
79 IPTR opts[OPT_COUNT];
81 char ExtendedHelp[] = /* Yes, ReadArgs() _can_ give extended help! */
82 "\n"
83 "ARoach - cockroaches hide under your windows\n"
84 "\n"
85 "© Stefan Winterstein 1993. Freely Distributable.\n"
86 "The original Xroach is © 1991 by J.T. Anderson.\n"
87 "Options:\n"
88 "\tROACHES=<n> : Number of roaches (default: 10)\n"
89 "\tSPEED=<n> : Speed for the insects (default: 20)\n"
90 "\tSQUISH : Enables roach squishing with mouse click\n"
91 "\tSCREEN=<string> : Name of public screen to run on.\n"
95 * Tags for the roach window
97 struct TagItem roachWindowTags[] = {
98 {WA_Backdrop, TRUE},
99 {WA_Borderless, TRUE},
100 // {WA_SimpleRefresh, TRUE}, /* -> faster, but garbage on screen */
101 {WA_SmartRefresh, TRUE},
102 {WA_IDCMP, IDCMP_MOUSEBUTTONS},
103 {WA_PubScreenName, (IPTR) PubScreen},
104 {WA_PubScreenFallBack, TRUE},
105 {TAG_DONE}
109 * Tags for the user window
111 struct TagItem userWindowTags[] = {
112 {WA_Width, 160},
113 {WA_Height, 50},
114 {WA_MaxWidth, -1},
115 {WA_MaxHeight, -1},
116 {WA_IDCMP, IDCMP_CLOSEWINDOW},
117 {WA_Flags, WFLG_CLOSEGADGET + WFLG_DRAGBAR + WFLG_SIZEGADGET + WFLG_DEPTHGADGET + WFLG_RMBTRAP},
118 {WA_Title, (IPTR) "ARoach"},
119 {WA_PubScreenName, (IPTR) PubScreen},
120 {WA_PubScreenFallBack, TRUE},
121 {TAG_DONE}
125 * Things from Xroach
127 unsigned int display_width, display_height;
128 int xoffset, yoffset;
130 Roach *roaches;
131 int maxRoaches;
132 int curRoaches;
133 float roachSpeed;
134 BOOL squishRoach = FALSE;
136 extern RoachMap roachPix[];
137 extern RoachMap squish;
138 extern unsigned char ReverseBits [];
140 /**********************************************************************/
141 /* */
142 /* XRoach functions */
143 /* */
144 /**********************************************************************/
147 Generate random integer between 0 and maxVal-1.
150 #define RandInt(x) RangeRand(x) /* from amiga.lib */
153 * __inline int RandInt(int maxVal)
155 * return ((rand()>>16) % maxVal);
162 Give birth to a roach.
163 i.e. set up "roaches[curRoaches]"
165 void
166 AddRoach()
168 Roach *r;
169 struct Bob *bob;
171 if (curRoaches >= maxRoaches)
172 return;
174 r = &roaches[curRoaches++];
175 /* chose a heading */
176 r->index = RandInt(ROACH_HEADINGS);
177 /* find appropriate RoachMap */
178 r->rm = &roachPix[r->index];
180 /* Coordinates are for screen, not window */
181 r->x = RandInt(display_width - r->rm->width) + xoffset;
182 r->y = RandInt(display_height - r->rm->height) + yoffset;
183 r->intX = r->x;
184 r->intY = r->y;
185 r->hidden = 0;
186 r->steps = RandInt(200);
187 r->turnLeft = RandInt(100) >= 50;
190 * Generate a bob for this roach.
191 * We find the image in our current RoachMap
193 bob = MakeBOBFromData(r->rm->roachBits, r->rm->width, r->rm->height);
195 bob->BobVSprite->X = r->x;
196 bob->BobVSprite->Y = r->y;
198 InitMasks(bob->BobVSprite);
199 AddBob(bob, rp);
201 r->bob = bob;
206 Check for roach overlapping specified rectangle.
208 __inline int
209 RoachOverRect(roach, rx, ry, x, y, width, height)
210 Roach *roach;
211 int rx;
212 int ry;
213 int x;
214 int y;
215 unsigned int width;
216 unsigned int height;
218 if (rx >= (x + width)) return 0;
219 if ((rx + roach->rm->width) <= x) return 0;
220 if (ry >= (y + height)) return 0;
221 if ((ry + roach->rm->height) <= y) return 0;
223 return 1;
227 Check for roach completely in specified rectangle.
230 RoachInRect(roach, rx, ry, x, y, width, height)
231 Roach *roach;
232 int rx;
233 int ry;
234 int x;
235 int y;
236 unsigned int width;
237 unsigned int height;
239 if (rx < x) return 0;
240 if ((rx + roach->rm->width) > (x + width)) return 0;
241 if (ry < y) return 0;
242 if ((ry + roach->rm->height) > (y + height)) return 0;
244 return 1;
248 Move a roach.
250 void
251 MoveRoach(rx)
252 int rx;
254 Roach *roach;
255 float newX;
256 float newY;
257 #ifdef CHECK_COLLISION
258 Roach *r2;
259 int ii;
260 #endif
262 roach = &roaches[rx];
263 newX = roach->x + (roachSpeed * roach->rm->cosine);
264 newY = roach->y - (roachSpeed * roach->rm->sine);
266 if (RoachInRect(roach, (int)newX, (int)newY,
267 xoffset, yoffset, display_width, display_height)) {
269 roach->x = newX;
270 roach->y = newY;
271 roach->bob->BobVSprite->X = roach->x;
272 roach->bob->BobVSprite->Y = roach->y;
274 if (roach->steps-- <= 0) {
275 TurnRoach(roach);
276 roach->steps = RandInt(200);
279 #ifdef CHECK_COLLISION
281 * collision checking
283 for (ii=rx+1; ii<curRoaches; ii++) {
284 r2 = &roaches[ii];
286 if (r2->hidden) /* so roach will not turn before window */
287 continue; /* if there are already others hiding */
289 if (RoachOverRect(roach, (int)newX, (int)newY,
290 r2->intX, r2->intY, r2->rm->width, r2->rm->height)) {
292 TurnRoach(roach);
295 #endif
297 else {
298 TurnRoach(roach);
299 roach->steps = RandInt(100);
305 Turn a roach.
307 void
308 TurnRoach(roach)
309 Roach *roach;
312 if (roach->turnLeft) {
313 roach->index += (RandInt(70) / 10) + 1;
314 if (roach->index >= ROACH_HEADINGS)
315 roach->index -= ROACH_HEADINGS;
317 else {
318 roach->index -= (RandInt(70) / 10) + 1;
319 if (roach->index < 0)
320 roach->index += ROACH_HEADINGS;
323 roach->rm = &roachPix[roach->index];
325 roach->bob->BobVSprite->ImageData = (UWORD *) roach->rm->roachBits;
326 InitMasks(roach->bob->BobVSprite);
329 #ifdef INTELLIGENT
330 void
331 TurnToHeading(Roach *roach, int index)
333 roach->steps = 100;
335 roach->index = index;
336 roach->rm = &roachPix[roach->index];
338 roach->bob->BobVSprite->ImageData = (UWORD *) roach->rm->roachBits;
339 InitMasks(roach->bob->BobVSprite);
342 #endif
345 Mark hidden roaches.
348 MarkHiddenRoaches()
350 int rx;
351 Roach *r;
352 int nVisible;
353 int ltvis, lbvis, rtvis, rbvis, visible;
356 nVisible = 0;
357 for (rx=0; rx<curRoaches; rx++) {
358 r = &roaches[rx];
361 * Since we don't really care for exact info but for speed,
362 * we do not call LockLayerInfo here.
364 ltvis = (WhichLayer(LayerInfo, r->intX +2, r->intY+13) == myLayer);
365 lbvis = (WhichLayer(LayerInfo, r->intX +2, r->intY + r->rm->height-13) == myLayer);
366 rtvis = (WhichLayer(LayerInfo, r->intX + r->rm->width -2, r->intY+13) == myLayer);
367 rbvis = (WhichLayer(LayerInfo, r->intX + r->rm->width -2, r->intY + r->rm->height-13) == myLayer);
369 visible = ltvis + lbvis + rtvis + rbvis;
371 if (!r->hidden) {
372 if (visible == 0) {
373 r->hidden = 1;
375 D(printf("%d becomes hidden\n", rx))
377 else { /* At least some part is hidden */
378 nVisible++;
380 #ifdef INTELLIGENT
381 if (visible <= 2) {
382 if (!(rbvis || rtvis)) /* right side is hidden */
383 TurnToHeading(r, 1);
384 else if (!(lbvis || ltvis)) /* left side is hidden */
385 TurnToHeading(r, 13);
386 else if (!(lbvis || rbvis)) /* bottom is hidden */
387 TurnToHeading(r, 17);
388 else if (!(ltvis || rtvis)) /* top is hidden */
389 TurnToHeading(r, 7);
391 else {
392 if (!rtvis)
393 TurnToHeading(r, 3);
394 else if (!rbvis)
395 TurnToHeading(r, 21);
396 else if (!lbvis)
397 TurnToHeading(r, 15);
398 else if (!ltvis)
399 TurnToHeading(r, 9);
401 #endif
404 else { /* Hidden roach becomes visible */
405 if (visible) {
406 r->hidden = 0;
407 r->turnLeft = RandInt(100) >= 50;
409 nVisible++;
411 TurnRoach(r);
414 * Might panic now!!!
420 return nVisible;
425 * checkSquish - Check to see if we have to squish any roaches.
427 void checkSquish()
429 int x, y;
430 int rx, i;
431 Roach *r;
432 struct Bob *tmpbob;
433 BOOL checksquish = FALSE;
434 struct IntuiMessage *imsg;
436 /* Check for CLICK*/
437 while ((imsg = (struct IntuiMessage *) GetMsg(roachWindow->UserPort))) {
438 if (imsg->Class == IDCMP_MOUSEBUTTONS && imsg->Code == SELECTDOWN) {
439 checksquish = TRUE;
440 x = imsg->MouseX;
441 y = imsg->MouseY;
443 else
444 D(printf("Received IDCMP %d\n", imsg->Class))
446 ReplyMsg((struct Message *) imsg);
449 if (checksquish) {
450 for (rx=0; rx<curRoaches; rx++) {
451 r = &roaches[rx];
453 if (x > r->intX &&
454 x < (r->intX + r->rm->width) &&
455 y > r->intY &&
456 y < (r->intY + r->rm->height)) {
459 * Roach r has been squished!
461 RemIBob(r->bob, rp, vp ); /* Remove Bob from GEL-system */
464 * This causes the next SortGList() to
465 * access illegal memory. WHY?
467 * freeBob(r->bob, RasDepth); / Free its Bob struct /
469 * Then change FreeAllRoaches(): for(.. <curRoaches...)
471 tmpbob = r->bob;
473 BltTemplate((PLANEPTR) squish.roachBits, 0, (squish.height / 8),
474 rp, r->intX, r->intY, r->rm->width, r->rm->height);
476 for (i = rx; i < curRoaches - 1; i++) {
477 roaches[i] = roaches[i + 1];
479 roaches[curRoaches-1].bob = tmpbob;
481 rx--;
482 curRoaches--;
486 return;
489 /**********************************************************************/
490 /* */
491 /* Amiga Animation functions */
492 /* */
493 /**********************************************************************/
495 void
496 DrawRoaches()
498 #ifdef ROACHNUMBERING
499 Roach *r;
500 char number[4];
501 int i;
502 #endif
504 SortGList(rp);
505 WaitTOF();
506 DrawGList(rp, vp);
508 #ifdef ROACHNUMBERING
509 for (i=0; i < maxRoaches; i++) {
510 r = &roaches[i];
512 sprintf(number, "%2d", i);
513 Move(rp, r->intX + 10, r->intY +10);
514 Text(rp, number, 2);
516 #endif
520 void
521 MoveRoaches()
523 int rx;
524 Roach *roach;
526 for (rx=0; rx<curRoaches; rx++) {
527 roach = &roaches[rx];
528 if (!roach->hidden) {
529 MoveRoach(rx);
530 roach->intX = roach->x;
531 roach->intY = roach->y;
537 struct Bob *
538 MakeBOBFromData(char *data, UWORD width, UWORD height)
540 NEWBOB newbob;
541 struct Bob *bob;
543 newbob.nb_Image = (UWORD *) data;
544 newbob.nb_WordWidth = (width + 15) / 16;
545 newbob.nb_LineHeight = height;
546 newbob.nb_ImageDepth = ROACH_DEPTH;
547 newbob.nb_PlanePick = 1;
548 newbob.nb_PlaneOnOff = 0;
549 newbob.nb_BFlags = SAVEBACK+OVERLAY;
550 newbob.nb_DBuf = 0;
551 newbob.nb_RasDepth = RasDepth;
552 newbob.nb_X = 0;
553 newbob.nb_Y = 0;
554 newbob.nb_HitMask = 0;
555 newbob.nb_MeMask = 0;
557 bob = makeBob(&newbob); /* from animtools */
559 return(bob);
564 * X-Bitmap data stores bits reversed: the leftmost bit in the bitmap is
565 * the least significant bit in the character.
566 * So we have to mirror them.
568 void
569 ConvertRoachData()
571 int i, rx;
572 unsigned char *a;
573 RoachMap *rm;
575 for (rx=0; rx<ROACH_HEADINGS; rx++) {
577 rm = &roachPix[rx];
578 a = rm->roachBits;
580 for (i=0; i < (rm->height * (rm->width / 8)); i++) {
581 a[i] = ReverseBits[a[i]];
585 a = squish.roachBits;
586 for (i=0; i < (squish.height * (squish.width / 8)); i++) {
587 a[i] = ReverseBits[a[i]];
593 void SetupAnimation()
595 int ax;
596 RoachMap *rm;
597 int rx;
598 float angle;
600 GelsInfo = setupGelSys(rp, 0);
601 if (GelsInfo == NULL)
602 Die("InitGELSystem() failed.\n");
604 ConvertRoachData();
607 Initialize sine & cosine in RoachMaps array.
609 for (ax=0; ax<360; ax+=ROACH_ANGLE) {
610 rx = ax / ROACH_ANGLE;
611 angle = rx * 0.261799387799;
612 rm = &roachPix[rx];
613 rm->sine = sin(angle);
614 rm->cosine = cos(angle);
618 * Setup roach array
620 roaches = (Roach *) AllocMem(sizeof(Roach) * maxRoaches, MEMF_CLEAR);
621 if (roaches == NULL)
622 Die("Out of memory.\n");
624 while (curRoaches < maxRoaches)
625 AddRoach(); /* initializes "roaches[curRoaches]" */
627 if (squishRoach) {
633 * Remove all remaining roaches from the GEL-system
635 void RemoveRoaches()
637 int i;
640 * All roaches >= curRoaches have already been removed by checkSquish
642 for (i=0; i<curRoaches; i++) {
643 RemBob(roaches[i].bob);
649 void FreeAllRoaches(void)
651 int i;
653 for (i=0; i < maxRoaches; i++) {
654 if (roaches[i].bob) {
655 freeBob(roaches[i].bob, RasDepth);
659 FreeMem(roaches, sizeof(Roach) * maxRoaches);
663 /**********************************************************************/
664 /* */
665 /* Own support functions */
666 /* */
667 /**********************************************************************/
671 * FindRootWindow
673 * Opens and returns backdrop window on screen or NULL.
674 * Screen must be locked.
676 struct Window *
677 FindRootWindow(struct Screen *screen)
679 struct Window *win = NULL;
681 #ifdef USE_WB_WINDOW
682 win = screen->FirstWindow;
684 while (win) {
685 if (win->Flags & WFLG_BACKDROP)
686 break;
687 win = win->NextWindow;
689 #endif /* USE_WB_WINDOW */
692 * Open a backdrop if none available
694 if (win == NULL) {
695 roachWindow = OpenWindowTagList(NULL, roachWindowTags); /* global */
696 win = roachWindow;
699 if (win == NULL)
700 Die("Could not open window.\n");
702 return(win);
707 * Generate a command line from Tooltypes and supply it to rda.
709 void
710 Tooltypes2RDArgs(struct RDArgs *rda, int argc, char **argv)
712 char *cmdline, tmpbuffer[MAXCMDLINE];
713 STRPTR *ttarray, tt;
714 int linelen;
716 if ((ttarray = ArgArrayInit(argc, (STRPTR *)argv))) {
718 *tmpbuffer = '\0';
719 tt = *ttarray;
721 for ( ; ttarray && tt; ttarray++, tt = *ttarray) {
722 D(printf("%s\n", tt))
724 if ( isalnum(*tt) ) {
726 * Idea: If there is a ' ' in ttarray, quote the argument
728 strncat(tmpbuffer, tt, MAXCMDLINE);
729 strncat(tmpbuffer, " ", MAXCMDLINE);
731 else { /* Skip commented tooltypes */
732 D(printf("Skipping `%s'\n", ttarray))
736 strncat(tmpbuffer, "\n", MAXCMDLINE); /* to make ReadArgs happy */
737 linelen = strlen(tmpbuffer);
739 if (linelen > 0) {
740 cmdline = AllocMem(linelen, MEMF_CLEAR);
741 if (cmdline == NULL) {
742 Die("No memory for cmdline.\n");
744 strncpy(cmdline, tmpbuffer, linelen);
746 rda->RDA_Source.CS_Buffer = cmdline;
747 rda->RDA_Source.CS_Length = linelen;
749 D(printf("Built cmdline:\n%s\n", cmdline))
752 ArgArrayDone();
755 return;
759 void Initialize(int argc, char **argv)
761 struct Window *rootWin; /* the window we will draw in */
764 * All libraries are opened by SAS/C autoinitialization (hopefully)
767 RDArgs.RDA_ExtHelp = ExtendedHelp;
769 if (argc == 0) { /* we were started from Workbench */
770 Tooltypes2RDArgs(&RDArgs, argc, argv);
773 if (ReadArgs(TEMPLATE, opts, &RDArgs) == NULL) {
774 PrintFault(IoErr(), NULL);
775 printf("Your options are not valid.\n");
776 CleanExit(RETURN_WARN);
779 if (opts[OPT_HELP]) {
780 printf("%s", ExtendedHelp);
781 FreeArgs(&RDArgs); /* don't forget! */
782 CleanExit(RETURN_OK);
785 if (opts[OPT_ROACHES]) {
786 maxRoaches = * (ULONG *) opts[OPT_ROACHES];
788 if (maxRoaches > ROACH_LIMIT) {
789 printf("Won't use more than %d roaches.\n", ROACH_LIMIT);
790 maxRoaches = ROACH_LIMIT;
792 if (maxRoaches < 1) {
793 maxRoaches = ROACH_NUM;
795 if (opts[OPT_SPEED]) {
796 roachSpeed = * (ULONG *) opts[OPT_SPEED];
798 if (roachSpeed < 1)
799 roachSpeed = ROACH_SPEED;
801 if (opts[OPT_SQUISH]) {
802 squishRoach = TRUE;
805 if (opts[OPT_SCREEN]) {
806 strncpy(PubScreen, (char *) opts[OPT_SCREEN], MAXNAMESIZE);
808 else
809 strcpy(PubScreen, "Workbench");
811 FreeArgs(&RDArgs);
813 Screen = LockPubScreen(PubScreen);
814 if (Screen == NULL) {
815 printf("Cannot lock screen `%s', using default screen.\n", PubScreen);
816 Screen = LockPubScreen(NULL);
817 if (Screen == NULL)
818 Die("No screen available.\n");
821 ScreenToFront(Screen);
823 userWindow = OpenWindowTagList(NULL, userWindowTags); /* global */
824 if (userWindow == NULL)
825 Die("Could not open user window.\n");
827 rootWin = FindRootWindow(Screen);
828 if (!rootWin)
829 Die("Cannot find root window.\n");
831 xoffset = 0;
832 yoffset = Screen->BarHeight;
834 display_width = rootWin->Width;
835 display_height = rootWin->Height;
837 rp = rootWin->RPort;
838 SetAPen(rp, 1);
839 SetDrMd(rp, JAM1);
841 vp = &(rootWin->WScreen->ViewPort);
842 RasDepth = rp->BitMap->Depth;
844 LayerInfo = &(Screen->LayerInfo);
845 myLayer = rp->Layer;
847 RangeSeed = -VBeamPos(); /* Seed generator for amiga.lib */
851 void CleanExit(LONG ReturnCode)
853 if (curRoaches > 0)
854 RemoveRoaches();
856 if (GelsInfo)
857 cleanupGelSys(GelsInfo, rp);
859 if (roaches)
860 FreeAllRoaches();
862 if (RDArgs.RDA_Source.CS_Buffer)
863 FreeMem(RDArgs.RDA_Source.CS_Buffer, RDArgs.RDA_Source.CS_Length);
865 if (roachWindow)
866 CloseWindow(roachWindow);
868 if (userWindow)
869 CloseWindow(userWindow);
871 if (Screen)
872 UnlockPubScreen(NULL, Screen);
874 exit(ReturnCode);
878 /* --------------------------------------------------------------
879 Die on fatal error. Prints out info text, then exits gracefully.
880 -------------------------------------------------------------- */
881 void Die(const UBYTE * msg)
883 printf("%s", msg);
884 CleanExit(RETURN_FAIL);
888 BOOL KeepRunning(void)
890 struct IntuiMessage *imsg;
891 BOOL running = TRUE;
893 if (curRoaches <= 0) {
894 running = FALSE;
897 /* Check for CTRL-C */
898 if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
899 running = FALSE;
902 /* Check for CLOSEWINDOW */
903 while ((imsg = (struct IntuiMessage *) GetMsg(userWindow->UserPort))) {
904 if (imsg->Class == IDCMP_CLOSEWINDOW) {
905 running = FALSE;
907 ReplyMsg((struct Message *) imsg);
910 return(running);
913 struct Library * LayersBase;
914 struct GfxBase * GfxBase;
915 struct Library * IconBase;
916 struct IntuitionBase * IntuitionBase;
918 BOOL openlibs(void)
920 LayersBase = OpenLibrary("layers.library",0);
921 GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
922 IconBase = OpenLibrary("icon.library",0);
923 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0);
925 if (!LayersBase || !GfxBase || !IconBase || !IntuitionBase)
926 return FALSE;
928 return TRUE;
931 void closelibs(void)
933 if (LayersBase) CloseLibrary(LayersBase);
934 if (GfxBase) CloseLibrary((struct Library *)GfxBase);
935 if (IconBase) CloseLibrary(IconBase);
936 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
940 void __chkabort(void) {}
943 main(int argc, char **argv)
945 int nVis;
947 if (TRUE == openlibs())
949 Initialize(argc, argv);
951 SetupAnimation();
953 nVis = maxRoaches;
955 while (KeepRunning()) {
957 MoveRoaches();
959 if (nVis > 0)
960 DrawRoaches();
961 else
962 Delay(5);
964 nVis = MarkHiddenRoaches();
966 if (squishRoach)
967 checkSquish();
970 closelibs();
972 CleanExit(RETURN_OK);
974 return 0;