home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 229.lha / watcher.c < prev    next >
C/C++ Source or Header  |  1989-04-06  |  6KB  |  218 lines

  1.  
  2. /*
  3.  * Watcher.c - A silly little program inspired by a second-hand description
  4.  *             of a probably just as silly program on Sun workstations.
  5.  *
  6.  * Author   : Andrew Folkins
  7.  *            (CIS : 72060,740  UUCP : ...!alberta!edm!cuenews!andrew)
  8.  *
  9.  * Date     : March 22, 1989
  10.  *
  11.  * Version  : 0.1
  12.  *
  13.  * Language : Lattice C 5.02 - compile with -Lt -v
  14.  *
  15.  * Legalese : Public Domain.  Permission is hereby granted to bend, fold
  16.  *            spindle or mutilate this code in any way you see fit.
  17.  *
  18.  * If you feel ambitious, here's a few things you can try :
  19.  *    - Make the movement smoother.  The big problem right now is erasing
  20.  *      the previous rendering, which allows the white background to
  21.  *      flash through.  The proper way to do this is to render everything
  22.  *      off screen then BltBitMapRastPort() or whatever.
  23.  *    - Add eyelids.  The watcher should go to sleep if nothing happens
  24.  *      for a while.  Of course, he might also peek through one eye
  25.  *      every now and then to see what's going on.
  26.  *    - Get rid of the window border, and make the system gadgets invisible.
  27.  */
  28.  
  29. #include <exec/types.h>
  30. #include <graphics/rastport.h>
  31. #include <graphics/gfxmacros.h>
  32. #include <intuition/intuition.h>
  33. #include <intuition/preferences.h>
  34. #include <intuition/intuitionbase.h>
  35. #include <proto/intuition.h>
  36. #include <proto/graphics.h>
  37. #include <proto/exec.h>
  38.  
  39. static char *ForHexDumpers = "Watcher 0.1 by Andrew Folkins (Public Domain)";
  40.  
  41. extern struct IntuitionBase *IntuitionBase;
  42. extern struct GfxBase *GfxBase;
  43.  
  44. #define WIDTH 105
  45. #define HEIGHT 32
  46.  
  47. struct NewWindow newwindow = {
  48.    100, 10, WIDTH, HEIGHT,
  49.    -1, -1,
  50.    CLOSEWINDOW,
  51.    WINDOWCLOSE | WINDOWDRAG | NOCAREREFRESH,
  52.    NULL,         /* Gadget list */
  53.    NULL,         /* Checkmark   */
  54.    NULL,         /* Title       */
  55.    NULL,         /* Screen      */
  56.    NULL,         /* Bitmap      */
  57.    0, 0, 0, 0,   /* minwidth, minheight, maxwidth, maxheight */
  58.    WBENCHSCREEN
  59. };
  60.  
  61. struct Window *window;
  62. short PrefsX, PrefsY,    /* Offset of the pointer hotspot */
  63.       OfsX, OfsY,        /* Approximate distance from eye to pointer */
  64.       EyeColor;
  65.  
  66. /* Yow! Area fills! Warning - the magic numbers may not be quite right */
  67. WORD buffer[75];
  68. struct AreaInfo AreaInfo;
  69. struct TmpRas TmpRas;
  70.  
  71. #define RASWIDTH   60
  72. #define RASHEIGHT  30
  73. PLANEPTR raster;
  74.  
  75. void CloseStuff()
  76. {
  77.    if (raster) FreeRaster(raster, RASWIDTH, RASHEIGHT);
  78.    if (window) CloseWindow(window);
  79.    if (GfxBase) CloseLibrary((struct Library *)GfxBase);
  80.    if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  81.    _exit(0);
  82. }
  83.  
  84. void OpenStuff()
  85. {
  86.    struct Preferences pref;
  87.  
  88.    IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
  89.    if (!IntuitionBase) CloseStuff();
  90.  
  91.    GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
  92.    if (!GfxBase) CloseStuff();
  93.  
  94.    window = OpenWindow(&newwindow);
  95.    if (!window) CloseStuff();
  96.  
  97.    raster = AllocRaster(RASWIDTH, RASHEIGHT);
  98.    if (!raster) CloseStuff();
  99.  
  100.    /* Get the offset of the pointer's 'hot spot'. */
  101.    GetPrefs(&pref, sizeof(struct Preferences));
  102.    PrefsX = pref.XOffset;
  103.    PrefsY = pref.YOffset;
  104.  
  105.    window->RPort->TmpRas = InitTmpRas(&TmpRas, raster, RASSIZE(RASWIDTH, RASHEIGHT));
  106.  
  107.    /* Pick a semi-random eye color */
  108.    EyeColor = IntuitionBase->MouseX & 0x01;
  109.    if (EyeColor == 1) EyeColor = 3;
  110. }
  111.  
  112. /* From "Assembler Language Programming S/370", 2nd Ed, by Struble, pg 341 */
  113. long sqrt(n)
  114. long n;
  115. {
  116.    long x0, x1;
  117.  
  118.    x0 = (1 + n) / 2;
  119.    for (;;) {          /* A vaguely Newton-ish iteration */
  120.       x1 = x0 + ((n / x0) - x0) / 2;
  121.       if (x1 >= x0) return(x1);
  122.       x0 = x1;
  123.    }
  124. }
  125.  
  126. /* Store previous position */
  127. short left[2] = {30, 20},
  128.       right[2] = {75, 20};
  129.  
  130. void DrawEye(ex, ey, position)
  131. short ex, ey, *position;
  132. {
  133.    long dx, dy, t, oldex, oldey;
  134.  
  135.    /* First figure out where we're supposed to be looking */
  136.    oldex = ex;
  137.    oldey = ey;
  138.    dx = ex + OfsX;
  139.    dy = ey + OfsY;
  140.    t = dx * dx + dy * dy;
  141.    if (t > 25) {
  142.       t = sqrt(t);
  143.       dx = 5 * dx / t;
  144.       dy = 5 * dy / t;
  145.    }
  146.    ex -= dx * 2;
  147.    ey -= dy;
  148.    /* If we have a new position, redraw the eye */
  149.    if (ex != position[0] || ey != position[1]) {
  150.       /* Draw the background */
  151.       InitArea(&AreaInfo, (short *)buffer, 15);
  152.       SetAPen(window->RPort, 1);
  153.       AreaEllipse(window->RPort, oldex, oldey, 20, 9);
  154.       AreaEnd(window->RPort);
  155.  
  156.       /* Draw the iris */
  157.       InitArea(&AreaInfo, (short *)buffer, 15);
  158.       SetAPen(window->RPort, EyeColor);
  159.       AreaEllipse(window->RPort, ex, ey, 8, 4);
  160.       AreaEnd(window->RPort);
  161.  
  162.       /* Draw the pupil */
  163.       InitArea(&AreaInfo, (short *)buffer, 15);
  164.       SetAPen(window->RPort, 2);
  165.       AreaEllipse(window->RPort, ex, ey, 4, 2);
  166.       AreaEnd(window->RPort);
  167.  
  168.       position[0] = ex;
  169.       position[1] = ey;
  170.    }
  171. }
  172.  
  173. void DrawWatcher()
  174. {
  175.    SetDrMd(window->RPort, JAM1);
  176.    window->RPort->AreaInfo = &AreaInfo;
  177.  
  178.    DrawEye(30, 20, left);
  179.    DrawEye(75, 20, right);
  180. }
  181.  
  182. void DoMessages()
  183. {
  184.    struct IntuiMessage *message;
  185.    ULONG class;
  186.    SHORT mousex, mousey;
  187.    struct Screen *screen;
  188.  
  189.    screen = window->WScreen;
  190.    mousex = 0;
  191.    mousey = 0;
  192.    for (;;) {    /* Excuse the polling, but . . . */
  193.       Delay(2);
  194.       if (mousex != screen->MouseX || mousey != screen->MouseY) {
  195.          mousex = screen->MouseX;
  196.          mousey = screen->MouseY;
  197.          OfsX = window->LeftEdge - (mousex - PrefsX);
  198.          OfsY = window->TopEdge - (mousey - PrefsY);
  199.          DrawWatcher();
  200.       }
  201.       while (message = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  202.          class = message->Class;
  203.          ReplyMsg((struct Message *)message);
  204.          if (class == CLOSEWINDOW)
  205.             return;
  206.       }
  207.    }
  208. }
  209.  
  210. void _main()
  211. {
  212.    OpenStuff();
  213.  
  214.    DoMessages();
  215.  
  216.    CloseStuff();
  217. }
  218.