/* Keeping to tradition, the Khaled Mardam-Bey philosophy, this program is completely undocumented so as to give you prime experience in learning how to debug source code. The program also contains many redundant bits and pieces so as to make your learning experience that much more profoundly educational and exceptional. This is how NOT to write a program. Got it ? Okay, great, now YOU can start teaching others by coding in exactly the same way. There's something very deep in that last sentence, can't quite pinpoint it though, hmmm... compile with cc Msizer.c ln Msizer.o -lc Warning - It won't bite unless you try to compile it. Linking is okay though... This source is totally PD. written by Khaled Mardam-Bey, 14th October 1989. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Key Definitions */ #define QKEY 0x45 #define CONTROL 0x63 #define THRESHX 16 #define THRESHY 8 #define MINX 40 #define MINY 24 /* input events */ #define QUIT 0x1 #define FINISHUP 0x2 #define MOVEIT 0x4 #define DOWINDOW 0x8 #define DELAY 1000000L char PortName[] = "PePeTe"; char WrittenBy[] = "Khaled Mardam-Bey 1989"; SHORT i,j,k,l; SHORT nomore = 0, NoGo = 0; SHORT corner = 0; SHORT dx,dy,ff,xx,yy,oo; SHORT DoIT = 0, there = 0; SHORT LastX,LastY; SHORT x,y,ox,oy,fx,fy; SHORT event; SHORT lastcode = 0; long sec = 0,micro = 0; SHORT rbuttonisdown = 0, lbuttonisdown = 0; SHORT ww, wh, te, le, sw, sh; struct Library *OpenLibrary(); struct ViewPort *ViewPortAddress(); struct MsgPort *inputPort = NULL; struct IOStdReq *inputReq = NULL; struct MsgPort *TimerPort = NULL; struct Screen *s, *Screen = NULL; struct IntuitionBase *IntuitionBase = NULL; struct GfxBase *GfxBase = NULL; struct Window *window; struct RastPort *rp; struct Layer_Info *li; struct LayersBase *LayersBase = NULL; void move(x,y) SHORT x,y; { Move(rp, (long) x, (long) y); } void draw(x,y) SHORT x,y; { Draw(rp, (long) x, (long) y); } void plot(x,y) SHORT x,y; { WritePixel(rp, (long) x, (long) y); } struct timerequest Timer_Req; long TimerSig,tdevice = 1; struct InputEvent phoney; struct HotInfo { struct Task *hotTask; long hotSig; } hotStuff; long signum = -1; struct Interrupt handlerStuff; struct defPort { struct MsgPort mp; }; struct defPort *defPortPtr; char defPortName[] = "WiNnYpO"; SHORT updating = 0; void HandlerInterface() { #asm movem.l a4,-(sp) jsr _geta4# movem.l A0/A1,-(sp) jsr _myhandler addq.l #8,A7 movem.l (sp)+,a4 #endasm } struct InputEvent *myhandler(ev1, hotStuff) struct InputEvent *ev1; struct HotInfo *hotStuff; { struct InputEvent *ev, *last; SHORT removeit; SHORT evcode,evqual; event = 0; for (ev=ev1,last = NULL; ev; ev=ev->ie_NextEvent) { evcode = ev->ie_Code; evqual = ev->ie_Qualifier; removeit = 0; if ((ev->ie_Class != IECLASS_TIMER)) { if (ev->ie_Class == IECLASS_RAWKEY) { if ((evcode >= 0x80) && (evcode == (lastcode | 0x80))) { DoIT = 0; event |= FINISHUP; removeit = 1; lastcode = 0; } else { lastcode = 0; removeit = 0; } if (evcode == CONTROL) { lastcode = evcode; removeit = 1; DoIT = 1; } else if (evcode == QKEY) { if (DoIT) DoIT = 2; lastcode = evcode; removeit = 1; } else DoIT = 0; } } if (ev->ie_Class == IECLASS_RAWMOUSE) { if (evcode == (IECODE_LBUTTON | 0x80)) { lbuttonisdown = 0; if (DoIT) event |= DOWINDOW; else event |= FINISHUP; } else { if (evcode == IECODE_LBUTTON) { if (DoIT == 2) event |= QUIT; if ((lbuttonisdown == 0) && (DoIT == 1)) removeit = 1; lbuttonisdown = 1; } if ((lbuttonisdown) && (DoIT)) { event |= MOVEIT; } } } if (removeit) if (last == NULL) ev1 = ev->ie_NextEvent; else last->ie_NextEvent = ev->ie_NextEvent; else last = ev; } if (event) Signal(hotStuff->hotTask,hotStuff->hotSig); return(ev1); } main() { struct IntuiMessage *Msg; long class; IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L); if (!IntuitionBase) exit(0L); GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L); if (!GfxBase) exit(0L); LayersBase = (struct LayersBase *) OpenLibrary("layers.library",0L); if (!LayersBase) exit(0L); defPortPtr = (struct defPort *) FindPort(defPortName); if (defPortPtr == NULL) { if ((defPortPtr = (struct defPort *) AllocMem((long)sizeof(struct defPort),MEMF_PUBLIC | MEMF_CLEAR)) == NULL) exit(10); } else updating = 1; if (updating) Uninstall(); defPortPtr->mp.mp_Node.ln_Pri = 0; defPortPtr->mp.mp_Node.ln_Type = NT_MSGPORT; NewList(&(defPortPtr->mp.mp_MsgList)); defPortPtr->mp.mp_Node.ln_Name = (char *) &(defPortName); AddPort(defPortPtr); if((signum = AllocSignal((long)-1)) == -1) Uninstall(); hotStuff.hotSig = 1 << signum; hotStuff.hotTask = FindTask(NULL); if(!(inputPort = CreatePort(PortName,0))) Uninstall(); if(!(inputReq = CreateStdIO(inputPort))) Uninstall(); handlerStuff.is_Data = (APTR)&hotStuff; handlerStuff.is_Code = HandlerInterface; handlerStuff.is_Node.ln_Pri = 55; handlerStuff.is_Node.ln_Name = "PoOpHaNy"; if(OpenDevice("input.device",0L,inputReq,0L) != 0) Uninstall(); inputReq->io_Command = IND_ADDHANDLER; inputReq->io_Data = (APTR)&handlerStuff; DoIO(inputReq); if ((TimerPort = CreatePort("TimPodle", 0L)) == NULL) Uninstall(); if ((tdevice = OpenDevice(TIMERNAME, UNIT_VBLANK, &Timer_Req, 0L)) != 0) Uninstall(); Timer_Req.tr_node.io_Message.mn_ReplyPort = TimerPort; Timer_Req.tr_node.io_Command = TR_ADDREQUEST; Timer_Req.tr_node.io_Flags = 0; Timer_Req.tr_node.io_Error = 0; TimerSig = (1L << TimerPort->mp_SigBit); QueTimer(); (void)SetTaskPri(FindTask(NULL), 20L); for (;;) { Wait(hotStuff.hotSig | TimerSig); if (Msg = (struct IntuiMessage *)GetMsg(TimerPort)) if (Msg) QueTimer(); if (breakcheck()) Uninstall(); breakreset(); if (event & QUIT) Uninstall(); if (event & FINISHUP) { FiniUpi(); corner = 0; nomore = 0; } if (event & DOWINDOW) MoveThatWindow(); if (event & MOVEIT) { if (nomore == 0) CheckPP(); else if (corner != 0) ElBorders(); } event = 0; } } FiniUpi() { if (there) { xx = LastX + dx; yy = LastY + dy; DoEm(); UnlockLayers(li); there = 0; } } QueTimer() { Timer_Req.tr_time.tv_secs = 0; Timer_Req.tr_time.tv_micro = DELAY; SendIO(&Timer_Req.tr_node); } ElBorders() { if ((LastX != s->MouseX) || (LastY != s->MouseY)) { xx = LastX + dx; yy = LastY + dy; DoEm(); xx = s->MouseX + dx; yy = s->MouseY + dy; DoEm(); } there = 1; LastX = s->MouseX; LastY = s->MouseY; } DoEm() { if (corner == 1) do1(); else if (corner == 2) do2(); else if (corner == 3) do3(); else if (corner == 4) do4(); } do1() { while (xx < 0) xx = xx + 1; while (yy < 0) yy = yy + 1; while ((le+ww) > s->Width) ww = ww -1; while ((te+wh) > s->Height) wh = wh - 1; if (xx > (le+ww-MINX)) xx = (le+ww-MINX); if (yy > (te+wh-MINY)) yy = (te+wh-MINY); move( (SHORT) xx, (SHORT) yy); draw( (SHORT) (le+ww-1), (SHORT) yy); draw( (SHORT) (le+ww-1), (SHORT) (te+wh-1)); draw( (SHORT) xx, (SHORT) (te+wh-1)); draw( (SHORT) xx, (SHORT) yy); } do2() { while (xx > s->Width) xx = xx - 1; while (xx < 0) xx = xx + 1; while (yy < 0) yy = yy + 1; while (yy > s->Height) yy = yy - 1; while ((te+wh) > s->Height) wh = wh - 1; if (xx < (le+MINX)) xx = le+MINX; if (yy > (te+wh-MINY)) yy = (te+wh-MINY); move( (SHORT) xx-1, (SHORT) yy); draw( (SHORT) le, (SHORT) yy); draw( (SHORT) le, (SHORT) (te+wh-1)); draw( (SHORT) xx-1, (SHORT) (te+wh-1)); draw( (SHORT) xx-1, (SHORT) yy); } do3() { while (xx < 0) xx = xx + 1; while (xx > s->Width) xx = xx - 1; while (yy < 0) yy = yy + 1; while (yy > s->Height) yy = yy - 1; while ((le+ww) > s->Width) ww = ww -1; if (xx > (le+ww-MINX)) xx = (le+ww-MINX); if (yy < (te+MINY)) yy = (te+MINY); move( (SHORT) xx, (SHORT) yy-1); draw( (SHORT) (le+ww-1), (SHORT) yy-1); draw( (SHORT) (le+ww-1), (SHORT) te); draw( (SHORT) xx, (SHORT) te); draw( (SHORT) xx, (SHORT) yy-1); } do4() { while (xx < 0) xx = xx + 1; while (xx > s->Width) xx = xx - 1; while (yy < 0) yy = yy + 1; while (yy > s->Height) yy = yy - 1; if (xx < (le+MINX)) xx = (le+MINX); if (yy < (te+MINY)) yy = (te+MINY); move( (SHORT) xx-1, (SHORT) yy-1); draw( (SHORT) xx-1, (SHORT) te); draw( (SHORT) le, (SHORT) te); draw( (SHORT) le, (SHORT) yy-1); draw( (SHORT) xx-1, (SHORT) yy-1); } CheckPP() { window = IntuitionBase->ActiveWindow; if (window != NULL) { le = window->LeftEdge; te = window->TopEdge; ww = window->Width; wh = window->Height; s = window->WScreen; sw = s->Width; sh = s->Height; rp=&(s->RastPort); SetAPen(rp,1L); SetBPen(rp,2L); SetDrMd(rp, COMPLEMENT | JAM1); LastX = ox = x = s->MouseX; LastY = oy = y = s->MouseY; corner = 0; if ((y >= te) && (y < (te + THRESHY))) { /* top edge */ if ((x >= le) && (x < (le + THRESHX))) /* left */ { corner = 1; dx = le - x; dy = te - y; } else if ((x <= (le + ww)) && (x > (le + ww - THRESHX))) /* right */ { corner = 2; dx = (le+ww) - x; dy = te - y; } } else if ((y <= (te + wh)) && (y > (te + wh - THRESHY))) { /* bottom edge */ if ((x >= le) && (x < (le + THRESHX))) /* left */ { corner = 3; dx = le - x; dy = (te+wh) - y; } else if ((x <= (le + ww)) && (x > (le + ww - THRESHX))) /* right */ { corner = 4; dx = (le+ww) - x; dy = (te+wh) - y; } } if (corner != 0) { LastX = x = s->MouseX; LastY = y = s->MouseY; li = &(s->LayerInfo); LockLayers(li); ox = xx = LastX + dx; oy = yy = LastY + dy; DoEm(); nomore = 1; there = 1; } else nomore = 0; } } MoveThatWindow() { Forbid(); Disable(); FiniUpi(); fx = xx; fy = yy; xx = fx - ox; if (xx < 0) xx = xx * -1; yy = fy - oy; if (yy < 0) yy = yy * -1; if (corner == 1) { if ((fx >= ox) && (fy >= oy)) { while (xx > (le+ww-MINX)) xx = xx - 1; while (yy > (te+wh-MINY)) yy = yy - 1; SizeWindow(window, (-1L * xx), (-1L * yy)); MoveWindow(window, (1L * xx), (1L * yy)); } else if ((fx <= ox) && (fy <= oy)) { while ((le-xx) < 0) xx = xx - 1; while ((te-yy) < 0) yy = yy - 1; MoveWindow(window, (-1L * xx), (-1L * yy)); SizeWindow(window, (1L * xx), (1L * yy)); } else if ((fx >= ox) && (fy <= oy)) { while (xx > (le+ww-MINX)) xx = xx - 1; while ((te-yy) < 0) yy = yy - 1; SizeWindow(window, (-1L * xx), 0L); MoveWindow(window, (1L * xx), (-1L * yy)); SizeWindow(window, 0L, (1L * yy)); } else if ((fx <= ox) && (fy >= oy)) { while (yy > (te+wh-MINY)) yy = yy - 1; while ((le-xx) < 0) xx = xx - 1; SizeWindow(window, 0L, (-1L * yy)); MoveWindow(window, (-1L * xx), (1L * yy)); SizeWindow(window, (1L * xx), 0L); } } else if (corner == 2) { if ((fx >= ox) && (fy >= oy)) { while (yy > (te+wh-MINY)) yy = yy - 1; while ((xx+le+ww) > s->Width) xx = xx - 1; SizeWindow(window, (1L * xx), (-1L * yy)); MoveWindow(window, 0L, (1L * yy)); } else if ((fx <= ox) && (fy <= oy)) { while ((te-yy) < 0) yy = yy - 1; MoveWindow(window, 0L , (-1L * yy)); SizeWindow(window, (-1L * xx), (1L * yy)); } else if ((fx >= ox) && (fy <= oy)) { while ((le+ww+xx) > s->Width) xx = xx - 1; while ((te-yy) < 0) yy = yy - 1; MoveWindow(window, 0L, (-1L * yy)); SizeWindow(window, (1L * xx), (1L * yy)); } else if ((fx <= ox) && (fy >= oy)) { while (yy > (te+wh-MINY)) yy = yy - 1; SizeWindow(window, (-1L * xx), (-1L * yy)); MoveWindow(window, 0L, (1L * yy)); } } else if (corner == 3) { if ((fx >= ox) && (fy >= oy)) { while (xx > (le+ww-MINX)) xx = xx - 1; while ((te+yy+wh) > s->Height) yy = yy - 1; SizeWindow(window, (-1L * xx), (1L * yy)); MoveWindow(window, (1L * xx), 0L); } else if ((fx <= ox) && (fy <= oy)) { while ((le-xx) < 0) xx = xx - 1; while ((te+wh-yy) < MINY) yy = yy - 1; MoveWindow(window, (-1L * xx), 0L); SizeWindow(window, (1L * xx), (-1L * yy)); } else if ((fx >= ox) && (fy <= oy)) { while ((te+wh-yy) < MINY) yy = yy - 1; while (xx > (le+ww-MINX)) xx = xx - 1; SizeWindow(window, (-1L * xx), (-1L * yy)); MoveWindow(window, (1L * xx), 0L); } else if ((fx <= ox) && (fy >= oy)) { while ((le-xx) < 0) xx = xx - 1; while ((te+yy+wh) > s->Height) yy = yy - 1; MoveWindow(window, (-1L * xx), 0L); SizeWindow(window, (1L * xx), (1L * yy)); } } else if (corner == 4) { if ((fx >= ox) && (fy >= oy)) { while ((te+yy+wh) > s->Height) yy = yy - 1; while ((xx+le+ww) > s->Width) xx = xx - 1; SizeWindow(window, (1L * xx), (1L * yy)); } else if ((fx <= ox) && (fy <= oy)) { while (xx > (le+ww-MINX)) xx = xx - 1; while ((te+wh-yy) < MINY) yy = yy - 1; SizeWindow(window, (-1L * xx), (-1L * yy)); } else if ((fx >= ox) && (fy <= oy)) { while ((le+ww+xx) > s->Width) xx = xx - 1; while ((te+wh-yy) < MINY) yy = yy - 1; SizeWindow(window, (1L * xx), (-1L * yy)); } else if ((fx <= ox) && (fy >= oy)) { while (xx > (le+ww-MINX)) xx = xx - 1; while ((te+yy+wh) > s->Height) yy = yy - 1; SizeWindow(window, (-1L * xx), (1L * yy)); } } Enable(); Permit(); nomore = corner = 0; } breakcheck() { if (SetSignal(0L,0L) & SIGBREAKF_CTRL_C) return (1); else return (0); } breakreset() { SetSignal(0L, SIGBREAKF_CTRL_C); } Chk_Abort() { return(0); } Uninstall() { if (!updating) { if (inputReq) { inputReq->io_Command = IND_REMHANDLER; inputReq->io_Data = (APTR)&handlerStuff; DoIO(inputReq); CloseDevice(inputReq); DeleteStdIO(inputReq); } if (inputPort) DeletePort(inputPort); if (signum > -1) FreeSignal(signum); if (tdevice == 0) { AbortIO(&Timer_Req.tr_node); CloseDevice(&Timer_Req); } if (TimerPort) DeletePort(TimerPort); if (defPortPtr) { if (defPortPtr->mp.mp_Node.ln_Name) RemPort(defPortPtr); FreeMem(defPortPtr,(long)sizeof(struct defPort)); } } if (LayersBase) CloseLibrary(LayersBase); if (GfxBase) CloseLibrary(GfxBase); if (IntuitionBase) CloseLibrary(IntuitionBase); exit(0L); }