home *** CD-ROM | disk | FTP | other *** search
- /*
- * explode.c - makes all Amiga windows "explode" when opening
- *
- * Bruno Costa - 30 Aug 89 - 31 Dec 89
- *
- * NOTE:
- * This program is VERY sensitive to compiler environment.
- * Compile under Lattice 5.0 with options -b0 -r0 -v.
- */
-
- /* TODO:
- - check for windows where 4*size(Window) > 5*size(Screen)
- */
-
- #define DELAY 1
- #define FASTDIV 0
- #define DETACH 1
- #define VERBOSE 1
-
- #include <exec/types.h>
- #include <intuition/intuition.h>
- #include <graphics/gfxmacros.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/layers.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include "intuition.lvo"
- #include "common.h"
-
- #define MAX(a,b) (((a)>(b))?(a):(b))
- #define MIN(a,b) (((a)<(b))?(a):(b))
-
- #if DETACH
- long _stack = 2000;
- char *_procname = "Window_Exploder";
- long _priority = 5;
- long _BackGroundIO = 1;
- extern BPTR _Backstdout;
- #else
- BPTR _Backstdout;
- #endif
-
- /*
- * Resident Amiga libraries
- */
- struct Library *IntuitionBase;
- struct Library *GfxBase;
- struct Library *LayersBase;
-
- /*
- * CLI Messages
- */
- #define BANNER "\x1b[33mExplode 1.2b\x1b[31m - \xa9 1989 by Bruno Costa\n"
- #define USAGE "usage: \x1b[1mexplode\x1b[0m [-0..2] [-f] [-d] [-s] [-q] [<filename>]\n"
- #define REMOVING "\x1b[1mExplode :\x1b[0m handler removed.\n"
-
- /*
- * pointer to old OpenWindow function
- */
- void (* openWindow) (void);
-
- /*
- * external assembly routine interface
- */
- extern void __far ExplodeWindow(void);
-
- /*
- * Patterns
- */
- #define DASHED 0x5555
- #define FULL 0xffff
-
- /*
- * These are globals just for the sake of efficiency
- * (avoids stack parameter passing).
- */
- static struct Screen scr;
- static struct RastPort *rp;
- static int x0, y0, x, y, w, h;
- static int xi, yi, xf, yf;
-
- /*
- * Extended message port - contains global data
- */
- #define PORTNAME "Explode_port"
-
- struct ExtMsgPort {
- struct MsgPort theport;
- unsigned long int tagcode;
- char tag[TAGSIZE]; /* tag to mark start of data */
- int timedelay, pattern, nsteps;
- struct {
- struct {
- int x, y;
- } topleft, botright;
- } step[MAXSTEPS];
- };
-
- static struct ExtMsgPort myport = {
- {NULL},
- TAG_CODE,
- TAG_ID,
- DEFDELAY, DEFPAT, 21,
- {
- { 0, 0, 0, 0 }, /* left, top, right, bottom */
- { 135, -22, 135, -22 },
- { 265, -30, 265, -30 },
- { 389, -25, 389, -25 },
- { 506, -6, 506, -6 },
- { 615, 23, 615, 23 },
- { 717, 62, 717, 62 },
- { 811, 111, 811, 111 },
- { 895, 168, 895, 168 },
- { 971, 231, 971, 231 },
- { 1036, 300, 1036, 300 },
- { 1090, 373, 1090, 373 },
- { 1134, 449, 1134, 449 },
- { 1166, 527, 1166, 527 },
- { 1186, 605, 1186, 605 },
- { 1194, 683, 1194, 683 },
- { 1188, 759, 1188, 759 },
- { 1169, 833, 1169, 833 },
- { 1135, 902, 1135, 902 },
- { 1087, 966, 1087, 966 },
- { 1024, 1024, 1024, 1024 } /* 21th entry */
- }
- };
- /*
- * The points above were generated using an HP-28S and a bezier curve
- * plotting program. The curve was broken in 20 line segments and the
- * control points were: (0, 0) ; (922, -205) ; (1587, 665) ; (1024, 1024)
- */
-
-
- #define xclip(x) (MAX(0, MIN(x, scr.Width - 1)))
- #define yclip(y) (MAX(0, MIN(y, scr.Height - 1)))
-
- /*
- * Draws a line performing a simple clipping that only works for
- * horizontal or vertical lines (the ones I draw).
- */
- void line (int x1, int y1, int x2, int y2)
- {
- int x1c, y1c, x2c, y2c;
-
- x1c = xclip (x1);
- y1c = yclip (y1);
- x2c = xclip (x2);
- y2c = yclip (y2);
-
- if ( ((x1c == x1) && (y1c == y1)) || ((x2c == x2) && (y2c == y2)) )
- {
- Move (rp, x1c, y1c);
- Draw (rp, x2c, y2c);
- }
- }
-
- /*
- * Draws the outline from (xi,yi)-(xf,yf)
- */
- void DrawOutline (void)
- {
- line (xi, yi, xf, yi);
- line (xf, yi, xf, yf);
- line (xf, yf, xi, yf);
- line (xi, yf, xi, yi);
- }
-
- /*
- * Does the animation of the outline along the path
- */
- void MoveOutline (void)
- {
- register int i;
- int dxi, dyi, dxf, dyf;
- int nxi, nyi, nxf, nyf;
-
- dxi = x - x0;
- dyi = y - y0;
- dxf = (x + w - 1) - x0;
- dyf = (y + h - 1) - y0;
-
- for (i = 0; i < myport.nsteps; i++)
- {
- #if FASTDIV
- /*
- * "Divides" faster by shifting (does it work for negative numbers ?)
- */
- nxi = x0 + ((myport.step[i].topleft.x * dxi) >> 10);
- nyi = y0 + ((myport.step[i].topleft.y * dyi) >> 10);
- nxf = x0 + ((myport.step[i].botright.x * dxf) >> 10);
- nyf = y0 + ((myport.step[i].botright.y * dyf) >> 10);
- #else
- nxi = x0 + ((myport.step[i].topleft.x * dxi) / 1024);
- nyi = y0 + ((myport.step[i].topleft.y * dyi) / 1024);
- nxf = x0 + ((myport.step[i].botright.x * dxf) / 1024);
- nyf = y0 + ((myport.step[i].botright.y * dyf) / 1024);
- #endif
-
- if (i)
- DrawOutline (); /* erases outline */
-
- xi = nxi;
- yi = nyi;
- xf = nxf;
- yf = nyf;
-
- DrawOutline (); /* draws outline */
-
- #if DELAY
- Delay (myport.timedelay); /* quick pause */
- #endif
- }
- DrawOutline ();
- }
-
- /*
- * C routine that does the real explosion
- */
- void __far DoExplode(struct NewWindow *nw)
- {
- if (GetScreenData (&scr, sizeof(struct Screen), nw->Type, nw->Screen))
- {
- /*
- * I am working on a copy of the RastPort, so I won't care to restore
- * old values like drawing modes and current position.
- */
-
- rp = &scr.RastPort;
- SetDrMd (rp, COMPLEMENT | JAM1);
- SetDrPt (rp, myport.pattern);
-
- x0 = xclip (scr.MouseX); /* assure that coordinates are */
- y0 = yclip (scr.MouseY); /* inside this screen. */
-
- x = nw->LeftEdge;
- y = nw->TopEdge;
- w = nw->Width;
- h = nw->Height;
-
- LockLayers (&scr.LayerInfo);
-
- MoveOutline (); /* Now move window along the path */
-
- UnlockLayers (&scr.LayerInfo);
- }
- }
-
- #if VERBOSE
- /*
- * window text shadows
- */
-
- static struct IntuiText TextS3 = {
- 2,0,JAM1,
- 26,30,
- NULL,
- "(September, 26th 1989)",
- NULL
- };
-
- static struct IntuiText TextS2 = {
- 2,0,JAM1,
- 25,19,
- NULL,
- "written by Bruno Costa",
- &TextS3
- };
-
- static struct IntuiText TextS1 = {
- 2,0,JAM1,
- 71,6,
- NULL,
- "Explode 1.2",
- &TextS2
- };
-
- #define windshadow TextS1
-
- static struct IntuiText IText3 = {
- 1,0,JAM1,
- 26,30,
- NULL,
- "(September, 26th 1989)",
- NULL
- };
-
- static struct IntuiText IText2 = {
- 1,0,JAM1,
- 25,19,
- NULL,
- "written by Bruno Costa",
- &IText3
- };
-
- static struct IntuiText IText1 = {
- 3,0,JAM1,
- 71,6,
- NULL,
- "Explode 1.2",
- &IText2
- };
-
- #define windtext IText1
-
- static struct NewWindow wind = {
- 207, 71, 227, 47, 0, 1, NULL,
- SIMPLE_REFRESH + RMBTRAP + NOCAREREFRESH,
- NULL, NULL, NULL, NULL, NULL,
- 0, 0, 0, 0, WBENCHSCREEN
- };
- #endif
-
- void usage (void) /* dead end */
- {
- Write (_Backstdout, USAGE, sizeof(USAGE));
- #if DETACH
- Close (_Backstdout);
- #endif
- exit (5);
- }
-
- main(int argc, char *argv[])
- {
- int i, removed, verbose = TRUE, stay = FALSE;
- struct Window *w;
- struct ExtMsgPort *port;
-
- #if !DETACH
- _Backstdout = Output();
- #endif
-
- port = (struct ExtMsgPort *) FindPort (PORTNAME);
- if (!port)
- {
- port = &myport;
- stay = TRUE;
- }
-
- if (_Backstdout && argc)
- {
- if (stay)
- Write (_Backstdout, BANNER, sizeof(BANNER));
- for (i = 1; i < argc; i++)
- {
- if (argv[i][0] == '-')
- { /* argument is an option */
- if (argv[i][1] >= '0' && argv[i][1] <= '2')
- port->timedelay = argv[i][1] - '0';
- else if (argv[i][1] == 'f')
- port->pattern = FULL;
- else if (argv[i][1] == 'd')
- port->pattern = DASHED;
- else if (argv[i][1] == 's')
- verbose = FALSE;
- else if (argv[i][1] == 'q')
- {
- if (stay)
- stay = FALSE;
- else
- {
- Signal (port->theport.mp_SigTask, 1L << port->theport.mp_SigBit);
- port = &myport;
- }
- Write (_Backstdout, REMOVING, sizeof(REMOVING));
- }
- else
- usage();
- }
- else
- { /* argument is a filename */
- usage();
- }
- }
- #if DETACH
- Close (_Backstdout);
- #endif
- }
-
- if (stay)
- {
- /* create port */
- myport.theport.mp_Node.ln_Name = PORTNAME;
- myport.theport.mp_Node.ln_Pri = 0;
- myport.theport.mp_Node.ln_Type = NT_MSGPORT;
- myport.theport.mp_Flags = PA_SIGNAL;
- myport.theport.mp_SigBit = AllocSignal (-1);
- myport.theport.mp_SigTask = FindTask (NULL);
- AddPort (&myport.theport);
- port = &myport;
- }
- else
- goto final;
-
- GfxBase = OpenLibrary ("graphics.library", 0);
- LayersBase = OpenLibrary ("layers.library", 0);
- IntuitionBase = OpenLibrary ("intuition.library", 0);
-
- openWindow = SetFunction (IntuitionBase, _LVOOpenWindow, ExplodeWindow);
-
- #if VERBOSE
- if (verbose)
- {
- w = OpenWindow (&wind); /* notify that handler is installed */
- if (w)
- {
- PrintIText (w->RPort, &windshadow, 2, 1);
- PrintIText (w->RPort, &windtext, 0, 0);
- Delay (200);
- CloseWindow (w);
- }
- }
- #endif
-
- do
- {
- Wait (1L << port->theport.mp_SigBit); /* wait for termination signal */
-
- Forbid ();
-
- if (SetFunction (IntuitionBase, _LVOOpenWindow, openWindow) != ExplodeWindow)
- {
- /*
- * Someone has interposed a handler after me. My handler can't be
- * removed: otherwise the system will crash after the other handler
- * removes itself.
- */
- (void) SetFunction (IntuitionBase, _LVOOpenWindow, ExplodeWindow);
- removed = FALSE;
- }
- else
- removed = TRUE;
-
- Permit();
-
- } while (!removed);
-
- CloseLibrary (IntuitionBase);
- CloseLibrary (LayersBase);
- CloseLibrary (GfxBase);
-
- /* Delete port */
- RemPort (&port->theport);
- FreeSignal (port->theport.mp_SigBit);
-
- final:
- exit (0);
- }
-