home *** CD-ROM | disk | FTP | other *** search
- /* :ts=8 bk=0
- * ing.c: The next logical step in "Boing"-type display hacks.
- *
- * Written by Leo L. Schwab 8702.3
- * Released into the public domain, but please keep the original author's
- * name on it.
- *
- * Note: After preliminary experiments, I get the impression that this could
- * somehow be faster. Suggestions appreciated.
- */
-
- #include <exec/types.h>
- #include <intuition/intuition.h>
- #include <math.h>
-
- #define DEPTH 2
-
-
- extern void *OpenLibrary(), *OpenWindow(), *OpenScreen(), *AllocRaster(),
- *GetMsg(), *malloc();
- extern long VBeamPos();
-
-
- struct NewScreen scrdef = {
- 0, 0, 0, 0, DEPTH, /* Size filled in later */
- 0, 1,
- HIRES,
- CUSTOMSCREEN,
- NULL,
- NULL, /* Title filled in later */
- NULL, NULL
- };
-
- struct NewWindow windef = {
- 0, 30, 150, 10,
- -1, -1,
- CLOSEWINDOW,
- WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SMART_REFRESH | ACTIVATE,
- NULL, NULL,
- "Ing!",
- NULL, NULL,
- 0, 0, 0, 0,
- WBENCHSCREEN
- };
-
-
- struct wlist {
- struct wlist *next, *prev;
- struct BitMap bitmap;
- long sizx, sizy;
- int maxx, maxy;
- int x, y, dx, dy;
- int maxdy;
- };
-
-
- struct Screen *scr, *wb;
- struct Window *win;
- struct BitMap *bm1, bm2, barmap;
- struct wlist *listbase;
- void *IntuitionBase, *GfxBase;
-
-
- main ()
- {
- struct Window *wbwin;
- struct ViewPort *svp;
- register struct BitMap *abm;
- struct BitMap *wbbm, **vbm;
- register struct wlist *this = NULL;
- struct wlist *new;
- long wide, high, barhigh, wbhigh;
- int i;
- void *msg;
-
- openstuff ();
- rnd ((short) -VBeamPos());
- wb = win -> WScreen; /* Workbench screen */
- wbbm = wb -> RastPort.BitMap;
- scrdef.LeftEdge = wb -> LeftEdge;
- scrdef.TopEdge = wb -> TopEdge;
- scrdef.Width = wb -> Width;
- scrdef.Height = wbhigh = wb -> Height;
-
- /* Scan all windows in workbench screen */
- for (wbwin = wb -> FirstWindow; wbwin; wbwin = wbwin -> NextWindow) {
- if (wbwin->Flags & BACKDROP && wbwin->Flags & WBENCHWINDOW) {
- scrdef.DefaultTitle = wbwin -> ScreenTitle;
- continue;
- }
-
- if (wbwin -> Height > wbhigh-21)
- continue; /* too tall, no fun */
- if (wbwin -> Width > wb->Width - 40)
- continue; /* too wide, no fun */
-
- /* Allocate new entry in list */
- if (!(new = malloc (sizeof (*new))))
- die ("malloc failed.");
- new -> prev = this;
- new -> next = NULL;
- if (this)
- this -> next = new;
- listbase = new;
-
- /* Grab necessary info */
- wide = new -> sizx = wbwin -> Width;
- high = new -> sizy = wbwin -> Height;
- new -> maxx = wb -> Width - wide;
- new -> maxy = wb -> Height - high;
- new -> x = wbwin -> LeftEdge;
- new -> y = wbwin -> TopEdge;
- new -> dx = new -> dy = 0;
-
- /*
- * Compute maximum initial vertical velocity.
- * (Do you know how long it took me to arrive at this
- * formula?)
- * Note: If gravity is anything other than one, this
- * formula falls apart.
- */
- new -> maxdy = sqrt (2 * new->maxy + 0.25) - 0.5 + 1.0;
-
- /* Create bitmap and copy window into it */
- InitBitMap (&new -> bitmap, (long) DEPTH, wide, high);
- for (i=0; i<DEPTH; i++)
- if (!(new -> bitmap.Planes[i] = AllocRaster (wide, high)))
- die ("AllocRaster failed.");
-
- WindowToFront (wbwin); /* WindowToFront() doesn't happen */
- Delay (5L); /* immediately, so wait. */
- BltBitMap
- (wbbm, (long) wbwin -> LeftEdge, (long) wbwin -> TopEdge,
- &new -> bitmap, 0L, 0L,
- wide, high, 0xC0L, 0xffL, NULL);
-
- this = new;
- }
-
- /* All windows scanned and copied, now to do the hard part */
- scr = OpenScreen (&scrdef); /* Clone WorkBench */
- bm1 = scr -> ViewPort.RasInfo -> BitMap;
- svp = &scr -> ViewPort;
-
- /* Make second set of bitplanes for double buffering */
- wide = wb -> Width;
- InitBitMap (&bm2, (long) DEPTH, wide, wbhigh);
- for (i=0; i<DEPTH; i++)
- if (!(bm2.Planes[i] = AllocRaster (wide, wbhigh)))
- die ("AllocRaster 2 failed.");
- BltBitMap
- (bm1, 0L, 0L, &bm2, 0L, 0L, wide, wbhigh, 0xc0L, 0xffL, NULL);
-
- /* Create private bitmap to hold screen title bar */
- barhigh = wb -> BarHeight;
- InitBitMap (&barmap, (long) DEPTH, wide, barhigh);
- for (i=0; i<DEPTH; i++)
- if (!(barmap.Planes[i] = AllocRaster (wide, barhigh)))
- die ("AllocRaster 3 failed.");
- BltBitMap
- (bm1, 0L, 0L, &barmap, 0L, 0L, wide, barhigh, 0xc0L, 0xffL, NULL);
-
- i = 0;
- vbm = &scr -> ViewPort.RasInfo -> BitMap;
- abm = &bm2;
- while (1) {
- /* Copy screen bar */
- BltBitMap (&barmap, 0L, 0L,
- abm, 0L, 0L,
- wide, barhigh, 0xc0L, 0xffL, NULL);
- /* Clear rest of screen */
- BltBitMap (abm, 0L, 0L,
- abm, 0L, barhigh,
- wide, wbhigh-barhigh, 0L, 0xffL, NULL);
-
- /* Scan window copies backwards */
- for (this = listbase; this; this = this -> prev) {
- if ((this -> x += this -> dx) > this -> maxx) {
- this -> x = this->maxx * 2 - this->x;
- this -> dx = -this -> dx;
- } else if (this -> x < 0) {
- this -> x = -this -> x;
- this -> dx = -this -> dx;
- }
-
- if ((this -> y += this -> dy) > this -> maxy) {
- this -> y = this -> maxy;
- this -> dy = -rnd (this->maxdy - 4) - 4;
- this -> dx = rnd (31) - 15;
- } else
- this -> dy++;
-
- /* Copy window image */
- BltBitMap
- (&this -> bitmap, 0L, 0L,
- abm, (long) this -> x, (long) this -> y,
- this -> sizx, this -> sizy, 0xc0L, 0xffL, NULL);
- }
-
- /*
- * This is the hairy part. I've tried to arrange things so
- * that there will be a minimum of hashing, but under certain
- * phases of the moon, it's unavoidable. Sorry.
- */
- Forbid ();
- if (i) { /* Ping */
- *vbm = bm1;
- abm = &bm2;
- } else { /* Pong */
- *vbm = &bm2;
- abm = bm1;
- }
- i = !i;
- /* Surprise! Intuition doesn't mind this! */
- ScrollVPort (svp);
- Permit ();
-
- if (msg = GetMsg (win -> UserPort)) {
- ReplyMsg (msg);
- break;
- }
- WaitTOF ();
- }
-
- /* Restore the original */
- Forbid ();
- *vbm = bm1;
- ScrollVPort (svp); /* Ping! */
- Permit ();
-
- closestuff ();
- }
-
-
- openstuff ()
- {
- if (!(IntuitionBase = OpenLibrary ("intuition.library", 0L))) {
- printf ("Intuition missing.\n");
- exit (100);
- }
-
- if (!(GfxBase = OpenLibrary ("graphics.library", 0L))) {
- printf ("Art shop closed.\n");
- closestuff ();
- exit (100);
- }
-
- if (!(win = OpenWindow (&windef))) {
- printf ("Window painted shut.\n");
- closestuff ();
- exit (100);
- }
- }
-
- die (str)
- char *str;
- {
- puts (str);
- closestuff ();
- exit (100);
- }
-
- closestuff ()
- {
- register int i;
-
- for (i=0; i<DEPTH; i++) {
- if (barmap.Planes[i])
- FreeRaster (barmap.Planes[i],
- (long) wb->Width, (long) wb->BarHeight);
- if (bm2.Planes[i])
- FreeRaster (bm2.Planes[i],
- (long) wb->Width, (long) wb->Height);
- }
-
- if (listbase) freelist ();
- if (scr) CloseScreen (scr);
- if (win) CloseWindow (win);
- if (GfxBase) CloseLibrary (GfxBase);
- if (IntuitionBase) CloseLibrary (IntuitionBase);
- }
-
- freelist ()
- {
- register struct wlist *this = listbase, *tmp;
- register int i;
-
- while (this) {
- for (i=0; i<DEPTH; i++)
- if (this -> bitmap.Planes[i])
- FreeRaster (this -> bitmap.Planes[i],
- this -> sizx, this -> sizy);
- tmp = this;
- this = this -> prev;
- free (tmp);
- }
- }
-