home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d01xx / d0112.lha / Bully / bully.c < prev    next >
C/C++ Source or Header  |  1987-11-15  |  9KB  |  350 lines

  1. /*
  2.  * bully - push all open screens around. This is designed for showing off
  3.  *    more than one demo at a time.
  4.  *
  5.  * Copyright (c) 1987, Mike Meyer
  6.  * This program can be redistributed freely, under two conditions:
  7.  *    1) The source must be part of the distribution.
  8.  *    2) All copyright notices must stay in the source as is.
  9.  *
  10.  * usage: bully [scriptname]
  11.  *
  12.  *    scriptname, if provided, will be executed before bully actually
  13.  *        starts. It should "run" demos (or some equivalent thing)
  14.  *        and exit, at which time bully proper will start.
  15.  *
  16.  * Note: this started as a hack to push windows around, but that doesn't
  17.  *    seem to want to work reliably. So I blew it off, and made it a
  18.  *    screen bully. The code still shows some of this, and hopefully
  19.  *    someone will figure out what I did wrong and fix the window
  20.  *    part of it.
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <libraries/dos.h>
  26. #include <exec/types.h>
  27. #include <exec/lists.h>
  28. #include <intuition/intuitionbase.h>
  29.  
  30. /*
  31.  * Declare names for the error returns.
  32.  */
  33. #define    OK        0
  34. #define ARG_ERROR    100
  35. #define NO_INTUITION    200
  36. #define NO_MEMORY    300
  37. #define    NO_WINDOW    400
  38. #define ONEXIT_BROKE    500
  39.  
  40. /*
  41.  * Things for the world to use.
  42.  */
  43. struct IntuitionBase    *IntuitionBase;
  44. static char        *my_name ;
  45. static struct Screen    *work_bench ;
  46.  
  47. /*
  48.  * playground holds a screen descriptor. Screens just go up and down, so
  49.  * we only need one velocity component. There are multiple windows per
  50.  * screen, so we add a pointer to the new ones each time around.
  51.  */
  52. struct playground {
  53.     struct Screen    *p_screen ;
  54.     short        p_y_delta ;
  55.     } ;
  56. /*
  57.  * bullied holds a window pointer, and the velocity of the window. It also
  58.  * has an indicator for the playground the victim is in.
  59.  */
  60. struct bully {
  61.     struct Node        b_node ;
  62.     struct Window        *b_window ;
  63.     struct playground    *b_playground ;
  64.     short            b_x_delta, b_y_delta ;
  65.     } ;
  66.  
  67. /*
  68.  * Now, we have a fake bully to insure that each window is
  69.  * looked at at least once.
  70.  */
  71.  
  72. /*
  73.  * Declare all our functions!
  74.  */
  75. struct bully    *bully_init(struct Window *, struct Screen *, struct List *) ;
  76. void        move_window(struct bully *, int) ;
  77. void        barf(int, char *) ;
  78. int        catch_break(void) ;
  79.  
  80. void
  81. main(argc, argv) char **argv; {
  82.     register short            length, screen_count = 0 ;
  83.     register struct Window        *w ;
  84.     register struct Screen        *s ;
  85.     register struct bully        *b ;
  86.     char                command[128] ;
  87.     struct List            windows ;
  88.     long                lock ;
  89.  
  90. /*
  91.  * Save my name for the outside world.
  92.  */
  93.     my_name = argv[0] ;
  94. /*
  95.  * First, make sure we have either 0, or 1 arguments.
  96.  */
  97.     if (argc > 2) barf(ARG_ERROR, "usage: %s [ scriptname ]\n") ;
  98. /*
  99.  * Just make sure that user aborts exit correctly! If we can't set it, we
  100.  *    really don't care, so ignore the return value.
  101.  */
  102.     (void) onbreak(&catch_break) ;
  103.  
  104. /*
  105.  * Now, get IntuitionBase so we can find the window we need.
  106.  */
  107.     if ((IntuitionBase = (struct IntuitionBase *)
  108.         OpenLibrary("intuition.library", 0)) == NULL)
  109.         barf(NO_INTUITION, "%s: Can't open intuition\n") ;
  110. /*
  111.  * If we have an argument, go execue the script.
  112.  */
  113.     if (argc == 2) {
  114.         sprintf(command, "execute %s", argv[1]) ;
  115.         Execute(command, 0, 0) ;
  116.         }
  117. /*
  118.  * Tell the world who we are, and how to get out of us!
  119.  */
  120.     WBenchToFront() ;
  121.     printf("%s Copyright (c) 1987, Mike Meyer\n", my_name) ;
  122.     puts("This program catchs Control-C to exit. If the window it") ;
  123.     puts("is running in isn't active, you should activate it NOW.") ;
  124.     puts("\nOnce again, that's Control-C to exit!") ;
  125.     fflush(stdout) ;
  126.     Delay(TICKS_PER_SECOND * 30) ;
  127. /*
  128.  * Initialize the list header for the window list.
  129.  */
  130.     NewList(&windows) ;
  131. #ifdef    notdef
  132. /*
  133.  * If we don't have any arguments, then do things to all windows, on all
  134.  * screens.
  135.  */
  136.     if (argc == 1) {
  137. #endif
  138.         lock = LockIBase(0L) ;
  139.         for (s = IntuitionBase -> FirstScreen; s; s = s -> NextScreen) {
  140. /*
  141.  * If it's the workbench screen, save it, then scan all the windows.
  142.  */
  143.             if ((s -> Flags & SCREENTYPE) == WBENCHSCREEN)
  144.                 work_bench = s ;
  145. #ifdef    notdef
  146.             for (w = s -> FirstWindow; w; w = w -> NextWindow)
  147.                 AddHead(&windows, bully_init(w, s, &windows)) ;
  148. #endif
  149.             screen_count += 1 ;
  150. /*
  151.  * Make sure this screen is on the list.
  152.  */
  153.             AddHead(&windows, bully_init(NULL, s, &windows)) ;
  154.             }
  155.         UnlockIBase(lock) ;
  156. #ifdef    notdef
  157.         }
  158. /*
  159.  * Otherwise, we have one argument, so we'll chase down all windows that
  160.  * have that as a prefix of their name, and move them.
  161.  */
  162.     else {
  163. /*
  164.  * We want the length of the argument so we no how much to check for.
  165.  */
  166.         length = strlen(argv[1]) ;
  167. /*
  168.  * Now, scan all the windows until we find it, complaining if we don't.
  169.  */
  170.         lock = LockIBase(0L) ;
  171.         for (s = IntuitionBase->FirstScreen; s; s = s->NextScreen)
  172.             for (w = s->FirstWindow; w; w = w->NextWindow)
  173.                 if (strncmp(w->Title, argv[1], length) ==  0)
  174.                     AddHead(&windows,
  175.                         bully_init(w, s, &windows)) ;
  176. /*
  177.  * Really ought to do something about having similarly named windows on
  178.  * multiple screens, but we'll forget it for now.
  179.  */
  180.         UnlockIBase(lock) ;
  181. /*
  182.  * If we never found any windows. Clean up, and go tell the user.
  183.  * go.
  184.  */
  185.         if (windows . lh_Head -> ln_Succ == 0)
  186.             barf(NO_WINDOW, "%s: Couldn't find window!\n") ;
  187.         }
  188. #endif
  189. /*
  190.  * Now, loop forever moving the windows around, taking care to bounce off the
  191.  *    screen edges. But first, shove the workbench to the back!
  192.  */
  193.     WBenchToBack() ;
  194.     for (;;) {
  195.         for (b = (struct bully *) windows . lh_Head ;
  196.             b -> b_node . ln_Succ ;
  197.             b = (struct bully *) b -> b_node . ln_Succ)
  198.             move_window(b, screen_count > 1) ;
  199.         chkabort() ;
  200.         RemakeDisplay() ;
  201.         }
  202. /*
  203.  * And clean up and exit.
  204.  */
  205.     exit(OK) ;
  206.     }
  207. /*
  208.  * bully_init just plugs in the velocity on a window.
  209.  */
  210. struct bully *
  211. bully_init(w, s, list) struct Window *w; struct Screen *s; struct List *list; {
  212.     register struct bully        *b, *xb ;
  213.     register struct playground    *p ;
  214.     register short            x_delta, y_delta ;
  215.     void                *malloc(int) ;
  216.  
  217. /*
  218.  * Get me a bully for this window.
  219.  */
  220.     if ((b = (struct bully *) malloc(sizeof(struct bully))) == NULL)
  221.         barf(NO_MEMORY, "%s: Can't allocate bully\n") ;
  222. /*
  223.  * If window is NULL, we're just adding this screen to the list so that
  224.  * it gets pushed. So we skip the bully init code. But we need to put the
  225.  * window in place anyway.
  226.  */
  227.     if ((b -> b_window = w) == NULL) {
  228. /*
  229.  * Now, get a velocity for this window. Take care to make sure we've got
  230.  * room to move it back and forth in.
  231.  */
  232.         x_delta = y_delta = 0 ;
  233.         if (s -> Width - w -> Width > 13)
  234.             while (x_delta == 0)
  235.                 x_delta = (rand() >> 4) % 13 - 6 ;
  236.         if (s -> Height - w -> Height > 9)
  237.             while (y_delta == 0)
  238.                 y_delta = (rand() >> 4) % 9 - 4 ;
  239. /*
  240.  * And install everything for the window in place.
  241.  */
  242.         b -> b_x_delta = x_delta ;
  243.         b -> b_y_delta = y_delta ;
  244.         }
  245. /*
  246.  * phase two - set up the playground for this bully, if needed.
  247.  */
  248.     for (xb = (struct bully *) list -> lh_Head ;
  249.         xb -> b_node . ln_Succ ;
  250.         xb = (struct bully *) xb -> b_node . ln_Succ)
  251.         if (xb -> b_playground -> p_screen == s) {
  252.             b -> b_playground = xb -> b_playground ;
  253.             return b ;
  254.             }
  255. /*
  256.  * No playground in place, so we've gotta make a new playground for this thing.
  257.  */
  258.     if ((p = (struct playground *)
  259.         malloc(sizeof(struct playground))) == NULL)
  260.         barf(NO_MEMORY, "%s: Can't allocate playground!\n") ;
  261.     p -> p_screen = s ;
  262.     y_delta = 0 ;
  263.     while (y_delta == 0)
  264.         y_delta = (rand() >> 4) % 21 - 10 ;
  265.     p -> p_y_delta = y_delta ;
  266.     b -> b_playground = p ;
  267.     return b ;
  268.     }
  269. /*
  270.  * move_window - actually push the little beggar around.
  271.  */
  272. void
  273. move_window(b, move_screen) struct bully *b; int move_screen; {
  274.     register short        x_delta = b -> b_x_delta ;
  275.     register short        y_delta = b -> b_y_delta ;
  276.     register struct Window    *w = b -> b_window ;
  277.     register struct Screen    *s = b -> b_playground -> p_screen ;
  278.  
  279. /* Sigh. Moving windows doesn't work.... */
  280. #ifdef    notdef
  281. /*
  282.  * If we have a window to move...
  283.  */
  284.     if (w != NULL) {
  285. /*
  286.  * Make sure we don't run off the edge of the screen.
  287.  */
  288.         if (w -> LeftEdge + x_delta + w -> Width >= s -> Width
  289.         ||  w -> LeftEdge + x_delta <= 0)
  290.             b -> b_x_delta = x_delta = -x_delta ;
  291.         if (w -> TopEdge + y_delta + w -> Height >= s -> Height
  292.         ||  w -> TopEdge + y_delta <= 0)
  293.             b -> b_y_delta = y_delta = -y_delta ;
  294. /*
  295.  * Now, move the beggar.
  296.  */
  297.         MoveWindow(w, x_delta, y_delta) ;
  298.         }
  299. #endif
  300. /*
  301.  * And maybe move the screen while we're at it...
  302.  */
  303.     if (move_screen) {
  304.         y_delta = b -> b_playground -> p_y_delta ;
  305.         if (s -> TopEdge + y_delta > s -> Height
  306.         ||  s -> TopEdge + y_delta < 0) {
  307. /*
  308.  * To many patterns here. Need to do something to let the user specify which
  309.  * of the 9 patterns they want.
  310.  */
  311.             if (y_delta < 0) ScreenToBack(s) ;
  312.             if (y_delta > 0) ScreenToFront(s) ;
  313.             b -> b_playground -> p_y_delta = y_delta = -y_delta ;
  314.             }
  315.         MoveScreen(s, 0, y_delta) ;
  316.         }
  317.     }
  318. /*
  319.  * barf - print a message, adding my name to it, then exit.
  320.  */
  321. void
  322. barf(how, why) int how; char *why; {
  323.  
  324.     fprintf(stderr, why, my_name) ;
  325.     (void) exit(how) ;
  326.     }
  327. /*
  328.  * The routine to make user breaks work cleanly.
  329.  */
  330. catch_break() {
  331.  
  332. /*
  333.  * Put the workbench back.
  334.  */
  335.     MoveScreen(work_bench, 0, -(work_bench -> TopEdge)) ;
  336.     WBenchToFront() ;
  337. /*
  338.  * Now, warn the user that things may still be running.
  339.  */
  340.     puts("Ok, I'm all through. But other demos you left running may") ;
  341.     puts("still be out there. You'll have to kill them by hand.") ;
  342. /*
  343.  * Now, close up everything and exit.
  344.  */
  345.     if (IntuitionBase != NULL) CloseLibrary(IntuitionBase) ;
  346.     exit(0) ;
  347.     return 0 ;    /* Sigh */
  348.     }
  349.  
  350.