#include #include #include #include #include #include #include #include #include #include #define COPY NANBC|NABC|ABNC|ABC long seed[] = {0xB807C324, 0x9E8732B5, 0x4E50957BC}; /* random number generator */ rand(i) register short i; { seed[i] = seed[i] < 0 ? seed[i] << 1 ^ 0x1D872B41 : seed[i] << 1; return(seed[i]); } #define RWidth Get_RWidth(w) #define RHeight Get_RHeight(w) #define MAX_CLOSEWINDOW 1 /* #define DEBUG */ /* #define KPRINTF */ #ifdef KPRINTF #define printf kprintf #endif int close_count; extern struct Gadget *vgadget_ptr; extern struct Gadget *hgadget_ptr; lbnc(w) struct RastPort *w; { register long i; short lx,ly,lvx,lvy; short rx,ry,rvx,rvy; short clrDepth,linDepth; struct Layer *l; int counter; int lcounter; int xoffset,yoffset; struct Window *window; struct IntuiMessage *message; close_count = MAX_CLOSEWINDOW; counter = 0; lcounter = 0; l = w->Layer; lx = 0; ly = 0; rx = 30; ry = 10; lvx = 2; lvy = 3; rvx = 5; rvy = 7; clrDepth = 320; linDepth = 160; SetDrMd(w,1); xoffset = Get_xoffset(w); yoffset = Get_yoffset(w); #ifdef DEBUG printf("xoffset = %ld yoffset = %ld\n",xoffset,yoffset); #endif if (l) window = l->Window; restart: while ((message = (struct IntuiMessage *)GetMsg(window->UserPort)) == 0) { if (clrDepth-- == 0) { clrDepth = 320; SetAPen(w,w->FgPen+1); } if (linDepth-- == 0) { newvel(&lvx); newvel(&lvy); newvel(&rvx); newvel(&rvy); linDepth = 320; } Move(w,xoffset+lx,yoffset+ly); Draw(w,xoffset+rx,yoffset+ry); lx += lvx; ly += lvy; rx += rvx; ry += rvy; if (lx<0) zbounce(&lx,&lvx); if (rx<0) zbounce(&rx,&rvx); if (ly<0) zbounce(&ly,&lvy); if (ry<0) zbounce(&ry,&rvy); if (lx>RWidth-1) mbounce(&lx,&lvx,RWidth-1); if (ly>RHeight-1) mbounce(&ly,&lvy,RHeight-1); if (rx>RWidth-1) mbounce(&rx,&rvx,RWidth-1); if (ry>RHeight-1) mbounce(&ry,&rvy,RHeight-1); endit: ; } switch (message->Class) { case CLOSEWINDOW : { ReplyMsg(message); return; } case GADGETDOWN: { struct IntuiMessage copymsg; /* copy all fields */ copymsg = *message; /* reply to original */ ReplyMsg(message); /* smooth-scroll until gadget is released */ { ULONG old_idcmp_flags; ULONG new_idcmp_flags; /* save old idcmp_flags */ old_idcmp_flags = copymsg.IDCMPWindow->IDCMPFlags; /* listen for ticks as long as gadget is down */ new_idcmp_flags = (old_idcmp_flags | INTUITICKS); ModifyIDCMP(copymsg.IDCMPWindow,new_idcmp_flags); /* loop for intuiticks messages */ { struct IntuiMessage *loopmsg; while((loopmsg = (struct IntuiMessage *) WaitPort(copymsg.IDCMPWindow->UserPort)) && (loopmsg->Class == INTUITICKS)) { if(loopmsg = (struct IntuiMessage *)GetMsg(copymsg.IDCMPWindow->UserPort)) { ReplyMsg(loopmsg); do_gadget_up(©msg); /* draw after smooth scrolling */ { if (clrDepth-- == 0) { clrDepth = 320; SetAPen(w,w->FgPen+1); } if (linDepth-- == 0) { newvel(&lvx); newvel(&lvy); newvel(&rvx); newvel(&rvy); linDepth = 320; } Move(w,xoffset+lx,yoffset+ly); Draw(w,xoffset+rx,yoffset+ry); lx += lvx; ly += lvy; rx += rvx; ry += rvy; if (lx<0) zbounce(&lx,&lvx); if (rx<0) zbounce(&rx,&rvx); if (ly<0) zbounce(&ly,&lvy); if (ry<0) zbounce(&ry,&rvy); if (lx>RWidth-1) mbounce(&lx,&lvx,RWidth-1); if (ly>RHeight-1) mbounce(&ly,&lvy,RHeight-1); if (rx>RWidth-1) mbounce(&rx,&rvx,RWidth-1); if (ry>RHeight-1) mbounce(&ry,&rvy,RHeight-1); } /* done drawing */ } } /* next message was not a tick */ } /* restore old idcmp_flags */ ModifyIDCMP(copymsg.IDCMPWindow,old_idcmp_flags); } } break; case GADGETUP: { struct IntuiMessage copymsg; /* copy all fields */ copymsg = *message; /* reply to original */ ReplyMsg(message); /* process message */ do_gadget_up(©msg); } break; case SIZEVERIFY: { ReplyMsg(message); /* wait for newsize */ WaitPort(window->UserPort); } break; case NEWSIZE: { struct IntuiMessage copymsg; /* copy all fields */ copymsg = *message; /* reply to original */ ReplyMsg(message); /* provide vertical gadget address */ copymsg.IAddress = vgadget_ptr; /* set vertical scroll */ do_gadget_up(©msg); /* bart - 04.23.86 */ /* re-calculate vertical pot body for new size */ { struct Window *w; struct RastPort *rp; struct Layer *l; if(w = copymsg.IDCMPWindow) { if(rp = w->RPort) { if(l = rp->Layer) { struct PropInfo *pi; UWORD sb_height; ULONG rel_body; pi = (struct PropInfo *)vgadget_ptr->SpecialInfo; sb_height = l->SuperBitMap->Rows; rel_body=(MAXPOT*(usable_height(w)))/(sb_height); ModifyProp(vgadget_ptr, window, NULL, pi->Flags, pi->HorizPot, pi->VertPot, pi->HorizBody, rel_body); } } } } /* provide vertical gadget address */ copymsg.IAddress = hgadget_ptr; /* set horizontal scroll */ do_gadget_up(©msg); /* bart - 04.23.86 */ /* re-calculate horizontal pot body for new size */ { struct Window *w; struct RastPort *rp; struct Layer *l; if(w = copymsg.IDCMPWindow) { if(rp = w->RPort) { if(l = rp->Layer) { struct PropInfo *pi; UWORD bb_width; ULONG rel_body; pi = (struct PropInfo *)hgadget_ptr->SpecialInfo; bb_width = l->SuperBitMap->BytesPerRow << 3; rel_body=(MAXPOT*(usable_width(w)))/(bb_width); ModifyProp(hgadget_ptr, window, NULL, pi->Flags, pi->HorizPot, pi->VertPot, rel_body, pi->VertBody); } } } } } break; default: { ReplyMsg(message); } break; } goto restart; } newvel(v) short *v; { *v = (15 & rand(0)) - 7; } zbounce(p,v) short *p,*v; { *p = -*p; *v = -*v; } mbounce(p,v,c) short *p,*v; short c; { *p = 2*c - *p; *v = -*v; }