home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 245.lha / watcher2.c < prev    next >
C/C++ Source or Header  |  1989-06-08  |  7KB  |  261 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.  * Modified by Mike Topf to add sleep with non activity. 
  30.  * Also removed part of the border. 
  31.  */
  32.  
  33.  
  34. #include <exec/types.h>
  35. #include <graphics/rastport.h>
  36. #include <graphics/gfxmacros.h>
  37. #include <intuition/intuition.h>
  38. #include <intuition/preferences.h>
  39. #include <intuition/intuitionbase.h>
  40. #include <proto/intuition.h>
  41. #include <proto/graphics.h>
  42. #include <proto/exec.h>
  43.  
  44. static char *ForHexDumpers = "Watcher 0.1 by Andrew Folkins (Public Domain)";
  45.  
  46. extern struct IntuitionBase *IntuitionBase;
  47. extern struct GfxBase *GfxBase;
  48.  
  49. #define WIDTH 105
  50. #define HEIGHT 32
  51.  
  52. struct NewWindow newwindow = {
  53.    100, 10, WIDTH, HEIGHT,
  54.    -1, -1,
  55.    CLOSEWINDOW,
  56.    WINDOWCLOSE | WINDOWDRAG | BORDERLESS | NOCAREREFRESH,
  57.    NULL,         /* Gadget list */
  58.    NULL,         /* Checkmark   */
  59.    NULL,         /* Title       */
  60.    NULL,         /* Screen      */
  61.    NULL,         /* Bitmap      */
  62.    0, 0, 0, 0,   /* minwidth, minheight, maxwidth , maxheight  */
  63.    WBENCHSCREEN
  64. };
  65.  
  66.  
  67. struct Window *window;
  68. short PrefsX, PrefsY,    /* Offset of the pointer hotspot */
  69.       OfsX, OfsY,        /* Approximate distance from eye to pointer */
  70.       EyeColor;
  71.  
  72. /* Yow! Area fills! Warning - the magic numbers may not be quite right */
  73. WORD buffer[75];
  74. struct AreaInfo AreaInfo;
  75. struct TmpRas TmpRas;
  76.  
  77. #define RASWIDTH   80
  78. #define RASHEIGHT  40
  79. PLANEPTR raster;
  80.  
  81. void CloseStuff()
  82. {
  83.    if (raster) FreeRaster(raster, RASWIDTH, RASHEIGHT);
  84.    if (window) CloseWindow(window);
  85.    if (GfxBase) CloseLibrary((struct Library *)GfxBase);
  86.    if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  87.    _exit(0);
  88. }
  89.  
  90. void OpenStuff()
  91. {
  92.    struct Preferences pref;
  93.  
  94.    IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
  95.    if (!IntuitionBase) CloseStuff();
  96.  
  97.    GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
  98.    if (!GfxBase) CloseStuff();
  99.  
  100.    window = OpenWindow(&newwindow);
  101.    if (!window) CloseStuff();
  102.  
  103.    raster = AllocRaster(RASWIDTH, RASHEIGHT);
  104.    if (!raster) CloseStuff();
  105.  
  106.    /* Get the offset of the pointer's 'hot spot'. */
  107.    GetPrefs(&pref, sizeof(struct Preferences));
  108.    PrefsX = pref.XOffset;
  109.    PrefsY = pref.YOffset;
  110.  
  111.    window->RPort->TmpRas = InitTmpRas(&TmpRas, raster, RASSIZE(RASWIDTH, RASHEIGHT));
  112.  
  113.    /* Pick a semi-random eye color */
  114.    /* I changed it to a constant colour since the long pupil looked better */
  115.    EyeColor = 3;
  116. }
  117.  
  118. /* From "Assembler Language Programming S/370", 2nd Ed, by Struble, pg 341 */
  119. long sqrt(n)
  120. long n;
  121. {
  122.    long x0, x1;
  123.  
  124.    x0 = (1 + n) / 2;
  125.    for (;;) {          /* A vaguely Newton-ish iteration */
  126.       x1 = x0 + ((n / x0) - x0) / 2;
  127.       if (x1 >= x0) return(x1);
  128.       x0 = x1;
  129.    }
  130. }
  131.  
  132. /* Store previous position */
  133. short left[2] = {30, 20},
  134.       right[2] = {75, 20};
  135.  
  136. void DrawEye(ex, ey, position)
  137. short ex, ey, *position;
  138. {
  139.    long dx, dy, t, oldex, oldey;
  140.  
  141.    /* First figure out where we're supposed to be looking */
  142.    oldex = ex;
  143.    oldey = ey;
  144.    dx = ex + OfsX;
  145.    dy = ey + OfsY;
  146.    t = dx * dx + dy * dy;
  147.    if (t > 25) {
  148.       t = sqrt(t);
  149.       dx = 5 * dx / t;
  150.       dy = 5 * dy / t;
  151.    }
  152.    ex -= dx * 2;
  153.    ey -= dy;
  154.  
  155.       
  156.    /* If we have a new position, redraw the eye */
  157.    if (ex != position[0] || ey != position[1]) {
  158.       /* Draw the background */
  159.       InitArea(&AreaInfo, (short *)buffer, 15);
  160.       SetAPen(window->RPort, 1);
  161.       AreaEllipse(window->RPort, oldex, oldey, 21, 10);
  162.       AreaEnd(window->RPort);
  163.  
  164.       /* Draw the iris */
  165.       InitArea(&AreaInfo, (short *)buffer, 15);
  166.       SetAPen(window->RPort, EyeColor);
  167.       AreaEllipse(window->RPort, ex, ey, 10, 5);
  168.       AreaEnd(window->RPort);
  169.  
  170.       /* Draw the pupil */
  171.       InitArea(&AreaInfo, (short *)buffer, 15);
  172.       SetAPen(window->RPort, 2);
  173.       AreaEllipse(window->RPort, ex, ey, t/40, 4);
  174.       AreaEnd(window->RPort);
  175.  
  176.       position[0] = ex;
  177.       position[1] = ey;
  178.    }
  179. }
  180.  
  181. void DrawWatcher()
  182. {
  183.    SetDrMd(window->RPort, JAM1);
  184.    window->RPort->AreaInfo = &AreaInfo;
  185.  
  186.    DrawEye(30, 20, left);
  187.    DrawEye(75, 20, right);
  188. }
  189.  
  190.  
  191. void DrawClose(ex, ey)
  192. short ex, ey;
  193. {
  194.    /* Draw the background */
  195.    InitArea(&AreaInfo, (short *)buffer, 15);
  196.    SetAPen(window->RPort, 1);
  197.    AreaEllipse(window->RPort, ex, ey, 21, 10);
  198.    AreaEnd(window->RPort);
  199.       
  200.    /* Draw Eyelid closed */
  201.    InitArea(&AreaInfo, (short *)buffer, 15);
  202.    SetAPen(window->RPort, 2);
  203.    AreaEllipse(window->RPort, ex, ey, 21, 0);
  204.    AreaEnd(window->RPort);
  205. }
  206.  
  207. void DrawSleeper()
  208. {
  209.    SetDrMd(window->RPort, JAM1);
  210.    window->RPort->AreaInfo = &AreaInfo;
  211.    
  212.    DrawClose(30, 20);
  213.    DrawClose(75, 20);
  214. }
  215.  
  216. void DoMessages()
  217. {
  218.    struct IntuiMessage *message;
  219.    ULONG class;
  220.    SHORT mousex, mousey, time1;
  221.    struct Screen *screen;
  222.  
  223.    screen = window->WScreen;
  224.    mousex = 0;
  225.    mousey = 0;
  226.    time1 = 0;    /* set the sleep counters */
  227.    for (;;) {    /* Excuse the polling, but . . . */
  228.       time1 = time1 + 1;
  229.       /* check to see if needs sleep */
  230.       if (time1 == 1024) {
  231.          DrawSleeper();
  232.       }    
  233.     
  234.       Delay(2);
  235.       if (mousex != screen->MouseX || mousey != screen->MouseY) {
  236.          mousex = screen->MouseX;
  237.          mousey = screen->MouseY;
  238.          OfsX = window->LeftEdge - (mousex - PrefsX);
  239.          OfsY = window->TopEdge - (mousey - PrefsY);
  240.          DrawWatcher();
  241.      time1 = 0;
  242.       }
  243.       while (message = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  244.          class = message->Class;
  245.          ReplyMsg((struct Message *)message);
  246.          if (class == CLOSEWINDOW)
  247.             return;
  248.       }
  249.    }
  250. }
  251.  
  252. void _main()
  253. {
  254.    OpenStuff();
  255.  
  256.    DoMessages();
  257.  
  258.    CloseStuff();
  259. }
  260.  
  261.