ewhac@well.UUCP (02/05/87)
[ The line eater is really Pac Man moonlighting. ]
To atone for my sin of posting a 200+ line MCIBTYC-type flame, I
have created the following little goodie. Once again, I invite comments
from Commodore or Amiga (or both) regarding this code. I'm doing unusual
things, and wonder just how well-behaved such tromping is.
Remember, if you don't say anything, I'll assume the code is
practical, and may end up using it in a commercial product one day (yes,
this is a threat).
Oh well. Enjoy your new toy.
Schwab
############### Apply Andy Finkel's drill here. ########################
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# README
# ing.c
# rnd.s
# This archive created: Wed Feb 4 22:49:40 1987
# By: Leo 'Bols Ewhac' Schwab ()
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'README'
then
echo shar: "will not over-write existing file 'README'"
else
cat << \SHAR_EOF > 'README'
Welcome to Ing, the next logical step in Boing-type display hacks.
It took me about two evenings to cook this up. This is written for the Manx
3.20a compiler. Conversion to Lettuce C *should* be simple.
To make this monster:
Copy the heapmem.o module to your working directory.
cc ing.c
as rnd.s
ln ing.o rnd.o heapmem.o -lm -lc -o ing
USEAGE:
This works best from the Workbench. Open a few small to medium-
sized windows (2-4 is good). Then run Ing. Enjoy. To stop the program, go
back to the Workbench screen and click on Ing's close gadget.
NOTES:
I tried my best to eliminate display hashing, but it still happens
under certain phases of the moon. However, it seems to be completely
Intuition-friendly, so you can drag the screen around all you want.
I'm a bit disappointed at the performance, and suspect that it could
be made to run faster, but I've no idea how. Suggestions would be
appreciated.
I'm reasonably sure that I'm cleaning up everything properly when I
exit. If anyone discovers that I'm not, please point it out to me.
Have fun.
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
________ ___ Leo L. Schwab
\ /___--__ The Guy in The Cape
___ ___ /\ ---##\ ihnp4!ptsfa!well!ewhac
/ X \_____ | __ _---)) ..or..
/ /_\-- -----+==____\ // \ _ well ---\
___ ( o---+------------------O/ \/ \ dual ----> !unicom!ewhac
\ / ___ \_ (`o ) hplabs -/ ("AE-wack")
____ \___/ \_/
Recumbent Bikes: "Work FOR? I don't work FOR
The _O_n_l_y Way To Fly! anybody! I'm just having fun."
SHAR_EOF
fi
if test -f 'ing.c'
then
echo shar: "will not over-write existing file 'ing.c'"
else
cat << \SHAR_EOF > 'ing.c'
/* :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);
}
}
SHAR_EOF
fi
if test -f 'rnd.s'
then
echo shar: "will not over-write existing file 'rnd.s'"
else
cat << \SHAR_EOF > 'rnd.s'
*\
* :ts=8
* Yet Another random number generator. By Leo Schwab.
* Based on an idea posted on the USENET (Thanks, Sam Dicker!)
* For the Manx assembler.
*
* Calling convention:
* short rnd (range);
* short range;
*
* 8606.30
*/
public _rnd
_rnd lea rndseed,a0 Get address of seed
move.w 4(sp),d1 Get range argument
tst.w d1
ble.s setseed Go reset seed
move.l (a0),d0 Get seed
ADD.L D0,D0
BHI.S over
EORI.L #$1D872B41,D0
over
move.l d0,(a0) Save new seed
andi.l #$ffff,d0 Coerce into word
divu d1,d0 Divide by range
swap d0 and get remainder (modulus)
rts
setseed neg.w d1 Probably don't need this
move.l d1,(a0)
rts
dseg
rndseed dc.l 0
cseg
SHAR_EOF
fi
exit 0
# End of shell archiveali@navajo.UUCP (02/06/87)
Keywords: In article <2526@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes: > Welcome to Ing, the next logical step in Boing-type display hacks. I like it. As much as oing! >.. To stop the program, go back to the Workbench screen and click on Ing's >close gadget. I think you should've required the user to click on the close gadget of the COPY of the Ing! window to end the program. Now *that* would've been some game. > I'm a bit disappointed at the performance... Oh, it seems fast enough. Watching it for a few minutes makes me dizzy, and any faster would've been worse! Anyway, thanks Leo, for yet another display hack. Ali Ozer, ali@navajo.stanford.edu