add original source
authorDavid Hulsman <davidhulsmannl@gmail.com>
Fri, 5 Jul 2019 13:46:03 +0000 (15:46 +0200)
committerDavid Hulsman <davidhulsmannl@gmail.com>
Fri, 5 Jul 2019 13:46:03 +0000 (15:46 +0200)
89 files changed:
ACTBMS.C [new file with mode: 0644]
AIRBRUSH.C [new file with mode: 0644]
BEND.C [new file with mode: 0644]
BITMAPS.C [new file with mode: 0644]
BLEND.C [new file with mode: 0644]
BLITOPS.C [new file with mode: 0644]
BLITREGS.H [new file with mode: 0644]
BMOB.C [new file with mode: 0644]
BOX.C [new file with mode: 0644]
BRXFORM.C [new file with mode: 0644]
CCYCLE.C [new file with mode: 0644]
CHPROC.C [new file with mode: 0644]
CLIP.C [new file with mode: 0644]
CONIC.C [new file with mode: 0644]
CTRPAN.C [new file with mode: 0644]
CURBRUSH.C [new file with mode: 0644]
CURSBMS.C [new file with mode: 0644]
CURSOR.C [new file with mode: 0644]
DALLOC.C [new file with mode: 0644]
DISPNUM.C [new file with mode: 0644]
DISTANCE.C [new file with mode: 0644]
DOPALETT.C [new file with mode: 0644]
DOSYMREQ.C [new file with mode: 0644]
DOTBMS.C [new file with mode: 0644]
DPHOOK.H [new file with mode: 0644]
DPIFF.C [new file with mode: 0644]
DPIFF.H [new file with mode: 0644]
DPINIT.C [new file with mode: 0644]
DPINIT2.C [new file with mode: 0644]
DPIO.C [new file with mode: 0644]
FILL.C [new file with mode: 0644]
FNBMS.C [new file with mode: 0644]
FNREQ.C [new file with mode: 0644]
FNREQ.H [new file with mode: 0644]
FONTINIT.C [new file with mode: 0644]
GEOM.C [new file with mode: 0644]
GRDEFS.H [new file with mode: 0644]
HOOK.C [new file with mode: 0644]
HSV.C [new file with mode: 0644]
IFFR.C [new file with mode: 0644]
IFFW.C [new file with mode: 0644]
ILBMR.C [new file with mode: 0644]
ILBMW.C [new file with mode: 0644]
INITOVS.C [new file with mode: 0644]
INITREAD.C [new file with mode: 0644]
INITWRIT.C [new file with mode: 0644]
INTUALL.H [new file with mode: 0644]
KEYJUNK.C [new file with mode: 0644]
MAGBITS.C [new file with mode: 0644]
MAGOPS.C [new file with mode: 0644]
MAGWIN.C [new file with mode: 0644]
MAINMAG.C [new file with mode: 0644]
MAKEICON.C [new file with mode: 0644]
MASKBLIT.C [new file with mode: 0644]
MENU.C [new file with mode: 0644]
MESSAGE.C [new file with mode: 0644]
MODES.C [new file with mode: 0644]
MOUSEBUT.C [new file with mode: 0644]
PACKER.H [new file with mode: 0644]
PACKERF.C [new file with mode: 0644]
PAINTW.C [new file with mode: 0644]
PALBMS.C [new file with mode: 0644]
PALETTE.C [new file with mode: 0644]
PANE.C [new file with mode: 0644]
PENMENU.C [new file with mode: 0644]
PGRAPH.C [new file with mode: 0644]
PLBM.H [new file with mode: 0644]
PNTS.H [new file with mode: 0644]
POLYF.C [new file with mode: 0644]
POLYH.C [new file with mode: 0644]
PRINT.C [new file with mode: 0644]
PRISM.C [new file with mode: 0644]
PRISM.H [new file with mode: 0644]
PRISM.txt [new file with mode: 0644]
PSYM.C [new file with mode: 0644]
RANDOM.C [new file with mode: 0644]
REMAP.C [new file with mode: 0644]
REQCOM.C [new file with mode: 0644]
ROT90.C [new file with mode: 0644]
ROTATE.C [new file with mode: 0644]
SHADE.C [new file with mode: 0644]
SHEAR.C [new file with mode: 0644]
SPARE.C [new file with mode: 0644]
STRETCH.C [new file with mode: 0644]
SYMREQ.C [new file with mode: 0644]
SYSTEM.H [new file with mode: 0644]
TEXT.C [new file with mode: 0644]
TIMER.C [new file with mode: 0644]
UNPACKER.C [new file with mode: 0644]

diff --git a/ACTBMS.C b/ACTBMS.C
new file mode 100644 (file)
index 0000000..152685e
--- /dev/null
+++ b/ACTBMS.C
@@ -0,0 +1,494 @@
+/* Bitmap name = act1,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act1[11] = { 
+  0xFFE0, 
+  0xFFE0, 
+  0xEFE0, 
+  0xFBE0, 
+  0xFFE0, 
+  0xFDE0, 
+  0xFFE0, 
+  0xFDE0, 
+  0xFFE0, 
+  0xFFE0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act2,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act2[11] = { 
+  0xFFE0, 
+  0xFFE0, 
+  0xFFE0, 
+  0xE3E0, 
+  0xDBE0, 
+  0xFDE0, 
+  0xFDE0, 
+  0xFDA0, 
+  0xFD60, 
+  0xFCE0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act3,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act3[11] = { 
+  0xFFE0, 
+  0xFFE0, 
+  0xFF60, 
+  0xFEE0, 
+  0xFDE0, 
+  0xFBE0, 
+  0xF7E0, 
+  0xEFE0, 
+  0xDFE0, 
+  0xFFE0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act4,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act4[11] = { 
+  0xFFE0, 
+  0xFFE0, 
+  0x87E0, 
+  0xF9E0, 
+  0xFEE0, 
+  0xFF60, 
+  0xFF60, 
+  0xFFA0, 
+  0xFFA0, 
+  0xFFA0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act5,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act5[11] = { 
+  0xFFE0, 
+  0xFFA0, 
+  0xC060, 
+  0xDE60, 
+  0xDC60, 
+  0xD860, 
+  0xD060, 
+  0xC060, 
+  0xC060, 
+  0xBFE0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act5H,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act5H[11] = { 
+  0x0, 
+  0x0, 
+  0x3F80, 
+  0x2080, 
+  0x2080, 
+  0x2080, 
+  0x2080, 
+  0x2080, 
+  0x3F80, 
+  0x0, 
+  0x0
+  }; 
+
+
+
+/* Bitmap name = act5F,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act5F[11] = { 
+  0x0, 
+  0x0, 
+  0x3F80, 
+  0x3F80, 
+  0x3F80, 
+  0x3F80, 
+  0x3F80, 
+  0x3F80, 
+  0x3F80, 
+  0x0, 
+  0x0
+  }; 
+
+
+
+/* Bitmap name = act6,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act6[11] = { 
+  0xFFE0, 
+  0xF1A0, 
+  0xCE60, 
+  0xDE60, 
+  0xBC20, 
+  0xB820, 
+  0xB020, 
+  0xC060, 
+  0xC060, 
+  0xB1E0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act6H,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act6H[11] = { 
+  0x0, 
+  0x0, 
+  0xE00, 
+  0x1100, 
+  0x2080, 
+  0x2080, 
+  0x2080, 
+  0x1100, 
+  0xE00, 
+  0x0, 
+  0x0
+  }; 
+
+
+
+/* Bitmap name = act6F,  Amiga-BOB format.   */
+/* Width = 10, Height = 11 */ 
+
+short act6F[11] = { 
+  0x0, 
+  0x0, 
+  0xE00, 
+  0x1F00, 
+  0x3F80, 
+  0x3F80, 
+  0x3F80, 
+  0x1F00, 
+  0xE00, 
+  0x0, 
+  0x0
+  }; 
+
+
+
+/* Bitmap name = act7,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act7[11] = { 
+  0xFFE0, 
+  0xFFA0, 
+  0xFF60, 
+  0xE0E0, 
+  0xDC60, 
+  0xB820, 
+  0xD060, 
+  0xE0E0, 
+  0xDFE0, 
+  0xBFE0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act7H,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act7H[11] = { 
+  0x0, 
+  0x0, 
+  0x0, 
+  0x1F00, 
+  0x2080, 
+  0x4040, 
+  0x2080, 
+  0x1F00, 
+  0x0, 
+  0x0, 
+  0x0
+  }; 
+
+
+
+/* Bitmap name = act7F,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act7F[11] = { 
+  0x0, 
+  0x0, 
+  0x0, 
+  0x1F00, 
+  0x3F80, 
+  0x7FC0, 
+  0x3F80, 
+  0x1F00, 
+  0x0, 
+  0x0, 
+  0x0
+  }; 
+
+
+
+/* Bitmap name = act8,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act8[11] = { 
+  0xFFE0, 
+  0xFBA0, 
+  0xF560, 
+  0xEEE0, 
+  0xDC60, 
+  0xB820, 
+  0xD060, 
+  0xE0E0, 
+  0xD1E0, 
+  0xBBE0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act8H,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act8H[11] = { 
+  0x0, 
+  0x400, 
+  0xA00, 
+  0x1100, 
+  0x2080, 
+  0x4040, 
+  0x2080, 
+  0x1100, 
+  0xA00, 
+  0x400, 
+  0x0
+  }; 
+
+
+
+/* Bitmap name = act8F,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act8F[11] = { 
+  0x0, 
+  0x400, 
+  0xE00, 
+  0x1F00, 
+  0x3F80, 
+  0x7FC0, 
+  0x3F80, 
+  0x1F00, 
+  0xE00, 
+  0x400, 
+  0x0
+  }; 
+
+
+
+/* Bitmap name = act9,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act9[11] = { 
+  0xFFE0, 
+  0xFBE0, 
+  0xF5E0, 
+  0xEEE0, 
+  0xDF60, 
+  0xEEE0, 
+  0xF5E0, 
+  0xF3E0, 
+  0xF7E0, 
+  0xC3E0, 
+  0xFFE0
+  }; 
+
+
+/* Bitmap name = act10,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act10[11] = { 
+  0xFFE0, 
+  0xFFE0, 
+  0xFD60, 
+  0xFBE0, 
+  0xF6A0, 
+  0x8BE0, 
+  0xF6A0, 
+  0xFBE0, 
+  0xFD60, 
+  0xFFE0, 
+  0xFFE0
+  }; 
+
+
+
+
+/* Bitmap name = act11,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act11[11] = { 
+  0xFFE0, 
+  0xFFE0, 
+  0xCE60, 
+  0xDF60, 
+  0xFFE0, 
+  0xFFE0, 
+  0xFFE0, 
+  0xDF60, 
+  0xCE60, 
+  0xFFE0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act12,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act12[11] = { 
+  0xFFE0, 
+  0xFFE0, 
+  0xF3E0, 
+  0xE1E0, 
+  0xCCE0, 
+  0xCCE0, 
+  0xC0E0, 
+  0xCCE0, 
+  0xCCE0, 
+  0xFFE0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act13,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act13[11] = { 
+  0xFFE0, 
+  0x8020, 
+  0xBBA0, 
+  0xBBA0, 
+  0xBBA0, 
+  0x8020, 
+  0xBBA0, 
+  0xBBA0, 
+  0xBBA0, 
+  0x8020, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act14,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act14[11] = { 
+  0xFFE0, 
+  0xFBE0, 
+  0xF5E0, 
+  0xFBE0, 
+  0xD160, 
+  0xA4A0, 
+  0xD160, 
+  0xFBE0, 
+  0xF5E0, 
+  0xFBE0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act15,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act15[11] = { 
+  0xFFE0, 
+  0xF8E0, 
+  0xF760, 
+  0xEFA0, 
+  0xEFA0, 
+  0xEFA0, 
+  0xE760, 
+  0xC0E0, 
+  0x8FE0, 
+  0x9FE0, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act16,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act16[11] = { 
+  0xFFE0, 
+  0x8020, 
+  0xBFA0, 
+  0xA0A0, 
+  0xAEA0, 
+  0xAAA0, 
+  0xAEA0, 
+  0xA0A0, 
+  0xBFA0, 
+  0x8020, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act17,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act17[11] = { 
+  0xFFE0, 
+  0xB5A0, 
+  0xB4A0, 
+  0xB520, 
+  0xCDA0, 
+  0xFFE0, 
+  0x8E60, 
+  0xB5A0, 
+  0xB5A0, 
+  0x8E60, 
+  0xFFE0
+  }; 
+
+
+
+/* Bitmap name = act18,  Amiga-BOB format.   */
+/* Width = 11, Height = 11 */ 
+
+short act18[11] = { 
+  0xFFE0, 
+  0xFFE0, 
+  0x9660, 
+  0xB6A0, 
+  0xB6A0, 
+  0xB620, 
+  0xB660, 
+  0xB6A0, 
+  0xB6A0, 
+  0x92A0, 
+  0xFFE0
+  }; 
+
+
+
diff --git a/AIRBRUSH.C b/AIRBRUSH.C
new file mode 100644 (file)
index 0000000..afab09b
--- /dev/null
@@ -0,0 +1,65 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*        airbrush.c                                                   */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+#include <pnts.h>
+
+extern PointRec pnts;
+extern BOOL abortFlag, symON;
+extern void obmv(), obclr(), (*nop)();
+extern SHORT xShft, yShft;
+
+#define local  static
+
+extern SHORT abRadius;
+
+local SHORT ab2Rad = 2*INITABRADIUS, abRad2 = INITABRADIUS*INITABRADIUS;
+
+/* ------ Air Brush Mode ------------------- */
+local Point abpt;
+
+local void abDoDot() { mDispOB(abpt.x, abpt.y); }
+local airbSym(x,y) SHORT x,y; {
+    abortFlag = NO;
+    abpt.x = x; 
+    abpt.y = y;
+    SymDo(1,&abpt,abDoDot);
+    }
+    
+local void AirBDots(x,y,proc) SHORT x,y; void (*proc)(); {
+    SHORT dx,dy;
+    for(;;) { /* repeat until generate a point */
+       /* first get a r.v. uniform in a square area */
+       dx = ((Rand16()&0x7fff)%ab2Rad) - abRadius;
+       dy = ((Rand16()&0x7fff)%ab2Rad) - abRadius;
+       /*  now filter into circular distribution */
+       if ( (Random(abRad2)+Random(abRad2))/2 > ((SHORT)(dx*dx+dy*dy))) {
+           (*proc)(x+PMapX(dx),y+PMapY(dy));
+           break;
+           }
+       }
+    }
+
+local airbsplat() {
+    if (symON)  AirBDots(mx,my,airbSym);
+    else  AirBDots(mx,my,mDispOB);
+    CycPaint();
+    }
+    
+/* ------ Exported procedure calls ----- */
+SetAirBRad(n) int n; {
+    n = MAX(2,n);  abRadius = n; ab2Rad = 2*n; abRad2 = n*n; 
+    }
+
+ChgABRadius(d) int d; { SetAirBRad(abRadius + d); }
+
+IMAirBrush() {
+    IModeProcs(obmv,obmv,obclr,airbsplat,nop,airbsplat,nop,nop);
+    }
+
+
+
diff --git a/BEND.C b/BEND.C
new file mode 100644 (file)
index 0000000..35ff6c3
--- /dev/null
+++ b/BEND.C
@@ -0,0 +1,189 @@
+/*--------------------------------------------------------------*/
+/*             Bend.c                                          */
+/*--------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+#include <pnts.h>
+
+#define local static
+#define lfHalf 0x8000
+
+extern PointRec pnts;
+extern SHORT curpen;
+extern struct RastPort tempRP;
+extern BMOB curbr,origBr;
+extern void (*nop)();
+extern SHORT usePen;
+extern void frobsh(),frobmv(),frobclr();
+
+local Point p0,p1,p2;
+local Point q0,q1,q2;
+local SHORT topY,botY,leftX,rightX;
+local SHORT crx,cry;
+
+struct BitMap *frombm, *tobm;
+local BOOL isHoriz;
+
+local void hBendOp(x,y) SHORT x,y; {
+    if (y==cry) return;
+    BltBitMap(frombm,0,y,tobm, x, y, origBr.pict.box.w, 1 ,REPOP,0xff,NULL);
+    cry = y;
+    }
+
+local BoxFromPts(bx) Box *bx; {
+    return(BoxThreePts(bx,q0.x,q0.y,q1.x,q1.y,q2.x,q2.y));
+    }
+
+/* horizontal bend */
+local BOOL BMBendH() 
+    {
+    SHORT dx,winc;
+    Box bx;
+    frombm = origBr.pict.bm;  tobm = curbr.pict.bm;
+    BoxFromPts(&bx);
+    winc = bx.w - 1;
+    if (q0.x == q2.x) {
+       dx = q1.x - q0.x;
+       winc = ABS(dx)/2; /* increase width by this amount */
+       /* if bending to left, move box in from p1 to curve */
+       if (q1.x<q0.x) bx.x  += (-dx-winc);
+       }    
+    if (NewSizeBitMap(tobm,frombm->Depth, frombm->BytesPerRow*8 + winc, 
+           frombm->Rows)) return(FAIL);
+    SetBitMap(tobm,origBr.xpcolor);
+    cry = - 1;
+    PCurve(q0.x-bx.x,0,q1.x-bx.x,q1.y-q0.y,q2.x-bx.x,q2.y-q0.y,64,hBendOp);
+    return(SUCCESS);
+    }
+
+void vBendOp(x,y) SHORT x,y; {
+    if (x==crx) return;
+    BltBitMap(frombm,x,0,tobm, x, y, 1, origBr.pict.box.h,REPOP,0xff,NULL);
+    crx = x;
+    }
+
+/* vertical bend */
+local BOOL BMBendV()  {
+    SHORT hinc;
+    Box bx;
+    SHORT dy;
+    frombm = origBr.pict.bm;  tobm = curbr.pict.bm;
+    BoxFromPts(&bx);
+    hinc = bx.h -1;
+    if (q0.y == q2.y) {
+       dy = q1.y - q0.y;
+       hinc = ABS(dy)/2;
+       if (q1.y<q0.y) bx.y  += (-dy-hinc);
+       }    
+    if (NewSizeBitMap(tobm,frombm->Depth, frombm->BytesPerRow*8,
+        frombm->Rows+hinc)) return(FAIL);
+    SetBitMap(tobm,origBr.xpcolor);
+    crx = - 1;
+    PCurve(0, q0.y - bx.y, q1.x - q0.x, q1.y - bx.y, q2.x - q0.x,
+       q2.y - bx.y,64,vBendOp);
+    return(SUCCESS);
+    }
+
+local XorCurve(x0,y0,x1,y1,x2,y2) SHORT x0,y0,x1,y1,x2,y2; {
+    SHORT svUsePen;
+    TempXOR();
+    svUsePen = usePen;
+    usePen = 0;
+    mCurve(x0,y0,x1,y1,x2,y2);
+    usePen = svUsePen;
+    RestoreMode();
+    }
+
+
+local invHbend()  {
+    SHORT dx;
+    q0 = p0;    q1 = p1;    q2 = p2;
+    if (my<topY) q0.x = mx;
+    else if (my>botY) q2.x = mx;
+    else { q1.x = mx; q1.y = my; }
+    dx = origBr.pict.box.w-1;
+    XorLine(q0.x - dx,q0.y, q0.x,q0.y);
+    XorLine(q2.x - dx,q2.y, q2.x,q2.y);
+    XorCurve(q0.x,q0.y,q1.x,q1.y,q2.x,q2.y); 
+    XorCurve(q0.x - dx,q0.y,q1.x - dx,q1.y, q2.x - dx,q2.y); 
+    }
+
+local invVbend()  {
+    SHORT dy;
+    q0 = p0;    q1 = p1;    q2 = p2;
+    if (mx<leftX) q0.y = my;
+    else if (mx>rightX) q2.y = my;
+    else { q1.x = mx; q1.y = my; }
+    dy = origBr.pict.box.h-1;
+    XorLine(q0.x, q0.y - dy, q0.x, q0.y);
+    XorLine(q2.x, q2.y - dy, q2.x, q2.y);
+    XorCurve(q0.x, q0.y, q1.x, q1.y, q2.x, q2.y); 
+    XorCurve(q0.x, q0.y - dy, q1.x, q1.y - dy, q2.x, q2.y - dy); 
+    }
+
+/* button down proc */
+    
+local void  beginHbend() { 
+    p0.x = mx; p0.y = my-curbr.yoffs; 
+    p1.x = mx; p1.y = my;
+    p2.x = mx; p2.y = p0.y+origBr.pict.box.h -1;
+    topY = p0.y; 
+    botY = p2.y; 
+    }
+    
+local void  beginVbend() { 
+    p0.y = my; p0.x = mx-curbr.xoffs; 
+    p1.y = my; p1.x = mx;
+    p2.y = my; p2.x = p0.x+origBr.pict.box.w -1;
+    leftX = p0.x; 
+    rightX = p2.x; 
+    }
+    
+local BOOL (*bendbm)();
+
+local endbend() {  /* button up proc */
+    ZZZCursor();
+    if ((*bendbm)())
+       { /* memory allocation failure or abort */
+       RestoreBrush();
+       AbortIMode();
+       }
+    else { 
+       curbr.pict.box.h = curbr.pict.bm->Rows;
+       curbr.pict.box.w = curbr.pict.bm->BytesPerRow*8;
+       curbr.xoffs = curbr.pict.box.w/2; /* not correct but ... */
+       curbr.yoffs = curbr.pict.box.h/2;
+       if (isHoriz) curbr.yoffs = origBr.yoffs;
+       else curbr.xoffs = origBr.xoffs; 
+       if (BMOBMask(&curbr)) {   RestoreBrush();   AbortIMode();   }
+       }
+    UnZZZCursor();
+    }
+
+local BOOL PrepBend() {
+    if (curpen != USERBRUSH)  return(FAIL); 
+    if (SaveBrush(BENT)) return(FAIL);
+    if (CopyBMOBPict(&origBr,&curbr)==FAIL) {RestoreBrush(); return(FAIL); }
+    origBr.xoffs = curbr.xoffs; origBr.yoffs = curbr.yoffs; 
+    curbr.xoffs = curbr.pict.box.w-1;  curbr.yoffs = curbr.pict.box.h-1;
+    return(SUCCESS);
+    }
+
+void IMHBendBrush(){
+    if (PrepBend()==FAIL) { RevertIMode(); return; }
+    curbr.yoffs>>=1;
+    isHoriz = YES;
+    bendbm = &BMBendH;
+    IModeProcs(frobsh,frobmv,frobclr,beginHbend,invHbend,nop,invHbend,endbend);
+    }
+
+
+void IMVBendBrush() {
+    if (PrepBend()==FAIL) { RevertIMode(); return; }
+    curbr.xoffs >>=1;
+    isHoriz = NO;
+    bendbm = &BMBendV;
+    IModeProcs(frobsh,frobmv,frobclr,beginVbend,invVbend,nop,invVbend,endbend);
+    }
+
diff --git a/BITMAPS.C b/BITMAPS.C
new file mode 100644 (file)
index 0000000..c929d5f
--- /dev/null
+++ b/BITMAPS.C
@@ -0,0 +1,238 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*     bitmaps.c  -- BitMap operations  (c) Electronic Arts            */
+/*                                                                     */
+/*     6/22/85   Created       Dan Silva                               */
+/*     7/11/85   Added MakeMask Dan Silva                              */
+/*     8/1/85    Added prism functions Dan Silva                       */
+/*----------------------------------------------------------------------*/
+/* Note: all Bitmap allocating functions will first try to free                */
+/*  the planes of the BitMap. Initially all bm.Plane[] values should   */
+/*  be set to NULL.                                                    */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+#define KPrintF printf
+extern struct RastPort tempRP;
+extern struct TmpRas tmpRas;
+extern BOOL haveWBench;
+
+BOOL dbgalloc = NO;
+               
+prbm(bm)  struct BitMap *bm;  {
+#ifdef DBGBM
+    dprintf("BitMap: bpr=%ld, rows= %ld, deep = %ld \n",
+       bm->BytesPerRow, bm->Rows, bm->Depth);
+#endif
+    }
+    
+static AllocErr(s) char *s; { 
+#ifdef DBGBM
+    if (dbgalloc) dprintf(" Alloc or Freeing error in %s\n",s);   
+#endif
+    }
+
+#define MINAVAILMEM 13000
+
+/* Allocate planes seperately-- wont work for BOBs */
+/* This routine Does NOT free planes first */
+TmpAllocBitMap(bm)  struct BitMap *bm;  {
+    SHORT i;
+    int psize = BMPlaneSize(bm);
+    setmem(bm->Planes, 8*sizeof(LONG), 0);
+    for (i=0; i<bm->Depth; i++) {
+       bm->Planes[i]= (PLANEPTR)ChipAlloc(psize);
+       if (bm->Planes[i]==NULL){
+           if (dbgalloc){   
+#ifdef DBGBM
+               dprintf(" AllocBitmap failure: \n");
+               prbm(bm);
+#endif
+               }
+           FreeBitMap(bm);
+           return(FAIL); 
+           }
+       }
+    return(SUCCESS);
+    }
+
+AllocBitMap(bm)  struct BitMap *bm;  {
+    BOOL res = TmpAllocBitMap(bm);
+    if (res==FAIL) return(FAIL);
+    if (AvailMem(MEMF_CHIP|MEMF_PUBLIC) < MINAVAILMEM) {
+       FreeBitMap(bm);
+       return(FAIL);
+       }
+    return(SUCCESS);
+    }
+    
+UBYTE *BMAllocMask(bm) struct BitMap *bm; {
+    return( (UBYTE *) ChipAlloc(bm->BytesPerRow * bm->Rows) );
+    }
+
+FreeBitMap(bm) struct BitMap *bm; {
+    SHORT i;
+    for (i=0; i<bm->Depth; i++)  if (bm->Planes[i] != NULL) {
+       DFree(bm->Planes[i]);
+       bm->Planes[i] = NULL;
+       }
+    }
+    
+NewSizeBitMap(bm,deep,w,h)  struct BitMap *bm; SHORT deep,w,h;   {
+    int ret;
+    int bw = BytesNeeded(w);
+    if ((bm->Planes[0] != NULL)&&(bm->Depth==deep)&&
+       (bm->BytesPerRow==bw)&&(bm->Rows==h)) return(0);
+    FreeBitMap(bm);
+    bm->Depth = deep;
+    bm->BytesPerRow = bw;
+    bm->Rows = h;
+    ret = AllocBitMap(bm);
+    if (ret) AllocErr("NewSizeBitMap");
+    return(ret);
+    }
+
+ClearBitMap(bm) struct BitMap *bm; {
+    SHORT i;
+    for (i=0; i<bm->Depth; i++)        
+       BltClear(bm->Planes[i],(bm->Rows<<16)+bm->BytesPerRow, 3);
+    }
+
+SetBitMap(bm,color) struct BitMap *bm; SHORT color; {
+    tempRP.BitMap = bm;
+    SetRast(&tempRP,color);
+    }
+
+/* USE WITH CAUTION: WILL OVERWRITE Planes[] POINTERS */
+BlankBitMap(bm) struct BitMap *bm; {
+    setmem(bm, sizeof(struct BitMap), 0);
+    }
+
+/* This assures that bitmap b is the same size as a */    
+MakeEquivBM(a,b) struct BitMap *a,*b; {
+    int ret;
+    if (ret=NewSizeBitMap(b,a->Depth,a->BytesPerRow*8,a->Rows))
+       AllocErr("MakeEquivBM");
+    return(ret);
+    }
+
+FillBitMap(pb,v) struct BitMap *pb; int v; {
+    SHORT i;
+    for (i=0; i<pb->Depth; i++) setmem(pb->Planes[i],BMPlaneSize(pb),v);
+    }
+
+/* this results in two totally identical BitMap structures */
+/* pointing at the same data */
+DupBitMap(a,b) struct BitMap *a,*b; {
+    FreeBitMap(b);
+    movmem(a,b,sizeof(struct BitMap));
+    }
+
+/* this makes a copy of the data too */     
+CopyBitMap(a,b) struct BitMap *a,*b; {
+    if(MakeEquivBM(a,b)){ AllocErr("CopyBitMap"); return(FAIL); }
+    WaitBlit();
+    BltBitMap(a,0,0,b,0,0,a->BytesPerRow*8,a->Rows,REPOP,0xff,NULL);
+    return(SUCCESS);
+    }
+
+/*--------------------------------------------------------------*/
+/*                                                             */
+/*                     Make Mask                               */
+/*                                                             */
+/*--------------------------------------------------------------*/
+/* 
+
+This makes masks for a bitmap associated with a particular
+"special" color.  It will either make a mask which has 1's in it ONLY 
+where the bitmap has that special color (a POSITIVE mask) or it will 
+make a mask which has 1's in it where the bitmap is NOT that special 
+color ( a NEGATIVE mask ).
+
+To make a positive mask for the special color 10110, 
+where p<i> is the <i>th plane of the Bitmap: 
+
+       mask  = p4 & (^p3) & p2 & p1 & (^p0);
+
+To a negative mask mask for a Bitmap for a particular "transparent" 
+color, you want a 1 where the color of the bitmap is NOT the 
+transparent color, zero where it IS is the transparent color .
+    
+       e.g. if xpcol = 10110 then want
+    
+       mask = (^p4) | p3 | (^p2) | (^p1) | p0
+    
+---------------------------------------------------------------------**/
+MakeMask(bm,mask,color,sign) 
+    struct BitMap *bm;         /* bitmap for which mask is to be made*/
+    UBYTE *mask;               /* holds the result: should be as big as
+                                                one plane of bm */
+    SHORT color;               /* special color        */
+    BOOL sign;                 /* TRUE = positive, FALSE = negative */
+    {
+    SHORT depth,i,mt,bltSize;
+    UBYTE op1,op2;
+    depth = bm->Depth;
+    bltSize = BlitSize(bm->BytesPerRow,bm->Rows);
+    if (sign) { mt = REPOP; op1 = ANDOP;   op2 = NOTANDOP;  }
+    else     { mt = NOTOP;  op1 = NOTOROP; op2 = OROP;         }
+    if (!(color&1)) mt ^= 0xff;
+    for (i=0; i<depth; i++) {
+       BltABCD(NULL, bm->Planes[i], mask, mask, bltSize, mt);
+       color >>= 1;
+       mt = (color&1) ? op1: op2; 
+       }
+    WaitBlit();
+    }
+
+
+#ifdef theOldWay
+MakeMask(bm,mask,color,pos) 
+    struct BitMap *bm;         /* bitmapr for which mask is to be made*/
+    UBYTE *mask;               /* should be as big as one plane of bm */
+    SHORT color;               /* special color        */
+    BOOL pos;                  /* TRUE = positive, FALSE = negative */
+    
+    {
+    struct BitMap mbm;
+    SHORT depth,i,mt,w;
+    PLANEPTR plane0;
+    UBYTE op1,op2;
+    mbm.BytesPerRow = bm->BytesPerRow;
+    mbm.Rows = bm->Rows;    mbm.Depth = 1;    mbm.Flags = 0;
+    mbm.Planes[0] = (PLANEPTR)mask;
+    depth = bm->Depth;
+    w = bm->BytesPerRow*8;
+    if (pos) {         SetBitMap(&mbm,0xff);   op1 = ANDOP;   op2 = NOTANDOP;  }
+    else     {         ClearBitMap(&mbm);      op1 = NOTOROP; op2 = OROP;      }
+    bm->Depth = 1;
+    plane0 = bm->Planes[0];
+    for (i=0; i<depth; i++) {
+       bm->Planes[0] = bm->Planes[i];
+       mt = (color&1) ? op1: op2; 
+       WaitBlit();
+       BltBitMap(bm,0,0,&mbm,0,0,w,mbm.Rows,mt,0x01,NULL);
+       color >>= 1;
+       }
+    WaitBlit();
+    bm->Depth = depth;
+    bm->Planes[0] = plane0;
+    }
+#endif
+/* Changes all pixels in a bitmap which are color number "acol" to
+   be color number "bcol" */
+
+
+BMMapColor(sbm,dbm,acol,bcol) struct BitMap *sbm, *dbm; SHORT acol,bcol; {
+    BYTE *tmpmask = tmpRas.RasPtr;
+    SHORT w = sbm->BytesPerRow*8;
+    MakeMask(sbm,tmpmask,acol,POSITIVE);
+    tempRP.BitMap = dbm;
+    SetAPen(&tempRP,bcol); 
+    SetDrMd(&tempRP,JAM1);
+    BltTemplate(tmpmask, 0, sbm->BytesPerRow, &tempRP, 0,0,w,sbm->Rows); 
+    }
+
+    
+
diff --git a/BLEND.C b/BLEND.C
new file mode 100644 (file)
index 0000000..1155820
--- /dev/null
+++ b/BLEND.C
@@ -0,0 +1,79 @@
+/*----------------------------------------------------------------------*/
+/*  BLEND mode:                                                                */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+#define local
+extern BoxBM temp;
+extern BOOL erasing,firstDown;
+extern Range *shadeRange;
+extern struct TmpRas tmpRas;
+
+local UBYTE *blSmask, *blDmask=0;/* used by blend to point at the mask for the save.bm */
+
+void DoBlend(ob,canv,clip)   BMOB *ob; BoxBM *canv; Box *clip; {                   
+    UBYTE *wmask, *tmp;
+    if ( BMPlaneSize(ob->pict.bm) > tmpRas.Size/3) return;
+    if (SaveSizeBM(temp.bm, ob)) return;
+    temp.box = ob->pict.box;
+    CopyBoxBM(canv, &temp, &temp.box, clip, REPOP);
+    if (firstDown) { 
+       blDmask = tmpRas.RasPtr +tmpRas.Size/3;
+       blSmask = tmpRas.RasPtr + 2*tmpRas.Size/3;
+       }
+    MaskRange(temp.bm, blDmask, tmpRas.RasPtr, shadeRange->low, shadeRange->high);
+    if (!firstDown) {
+       wmask = ob->mask;
+       if (shadeRange!=NULL) {
+           wmask = blSmask;
+           BltABCD(blSmask,blDmask,ob->mask,wmask,BMBlitSize(ob->pict.bm),0x80);
+           }
+       BlendBM(temp.bm, ob->save.bm, tmpRas.RasPtr);
+       MBSaveAtPict(ob,canv,clip,wmask);
+       }
+    else firstDown = NO;
+    tmp = blSmask; blSmask= blDmask; blDmask = tmp;
+    RelocBoxBM(&temp,&ob->save); /* save  = temp */
+    }
+
+#define yA     0xf0
+#define yB     0xcc
+#define yC     0xaa
+#define nA     0x0f
+#define nB     0x33
+#define nC     0x55
+#define A_AND_B   yA&yB
+
+/* sum bit is on if odd number of sources are 1 */
+#define ADD_ABC        (yA&nB&nC)|(nA&yB&nC)|(nA&nB&yC)|(yA&yB&yC)
+
+/* carry if at least 2 of three sources are 1's */
+#define CARRY_ABC (yA&yB&nC)|(yA&nB&yC)|(nA&yB&yC)|(yA&yB&yC)
+#define POST_CARRY_ABC  0xB2   /* black magic.. trust me */
+
+/* b = (a + b)/2 */
+BlendBM(a,b,car)  
+    struct BitMap *a, *b;
+    UBYTE *car;        /* one plane scratch area( carry bit) */
+    {
+    int i;
+    int bpr = a->BytesPerRow;
+    int h = a->Rows;
+    int depth = a->Depth;
+    int bsz = BlitSize(bpr,h);
+
+    /* AND low order bits to get initial carry */
+    BltABCD(a->Planes[0], b->Planes[0], NULL, car, bsz, A_AND_B);
+    
+    for (i=1; i<depth; i++) {
+       /* add i'th bit and carry, store as new i-1'th bit */
+       BltABCD(a->Planes[i], b->Planes[i], car, b->Planes[i-1],bsz, ADD_ABC );
+       /* compute new carry bit */
+       BltABCD(a->Planes[i], b->Planes[i], car, 
+           (i == (depth-1))? b->Planes[i] : car, bsz, CARRY_ABC);
+       }
+    }
+
diff --git a/BLITOPS.C b/BLITOPS.C
new file mode 100644 (file)
index 0000000..efda755
--- /dev/null
+++ b/BLITOPS.C
@@ -0,0 +1,196 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*     Blitops.c       (c) Electronic Arts     1985                    */
+/*                                                                     */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+#undef sx
+#undef sy
+
+#define local  static
+
+USHORT masks[17] = {
+       0xffff,0x7fff,0x3fff,0x1fff,
+       0x0fff,0x07ff,0x03ff,0x01ff,
+       0x00ff,0x007f,0x003f,0x001f,
+       0x000f,0x0007,0x0003,0x0001,0000
+       };
+
+BlitterRegs *ar = (BlitterRegs *)0xDFF040;
+
+#define yA     0xf0
+#define yB     0xcc
+#define yC     0xaa
+#define nA     0x0f
+#define nB     0x33
+#define nC     0x55
+
+#define USEA 0x0800
+#define USEB 0x0400
+#define USEC 0x0200
+#define USED 0x0100
+#define MASKWRITE      0x0F00  /* USEA|USEB|USEC|USED */
+#define CONSTWRITE     0x0B00  /* USEA|USEC|USED */
+    
+#define COPYA 0xf0     /* minterm = A */
+
+#define WordOffs(x)     (((x)>>3)&0xfffe)
+
+extern UWORD *curFilPat;
+    
+/*----------------------------------------------------------------------*/
+/* HLineBlt: fill a horizontal span of pixels with the current area    */
+/* fill pattern.                                                       */
+/* NOTE: this should be changed to use rp's minterms                   */
+/*----------------------------------------------------------------------*/
+HLineBlt(rp,lx,y,rx,mint) struct RastPort *rp; int lx,y,rx;SHORT mint; {
+    int bytes,lwrd,i;
+    LONG offset;
+    SHORT blsize,apen;
+    UWORD *patadr;
+    struct BitMap *dbm = rp->BitMap;
+
+    lwrd = WordOffs(lx);
+    bytes = WordOffs(rx)- lwrd + 2;
+    offset = y*dbm->BytesPerRow + lwrd;
+    blsize = (1<<6)|(bytes>>1);
+    WaitBlit();
+    OwnBlitter(); 
+    ar->fwmask = masks[lx&15];
+    ar->lwmask = ~masks[(rx&15)+1]; 
+    ar->bltcon0 = USEC|USED|mint;  
+    ar->bltcon1 = 0;
+    ar->adata = 0xffff;
+    ar->bltmdd = ar->bltmdc = dbm->BytesPerRow - bytes;
+    if (curFilPat) {
+       patadr = curFilPat + (y&PATMOD);
+       for (i = 0; i< dbm->Depth; i++) {
+           WaitBlit();
+           ar->bdata = curFilPat?*patadr: 0xFFFF;
+           patadr += PATHIGH;
+           ar->bltptd = ar->bltptc = dbm->Planes[i] + offset;
+           ar->bltsize = blsize;  /* start the blit */
+           }
+       }
+    else { /* no fill pattern: solid color */
+       apen = rp->FgPen;
+       for (i = 0; i< dbm->Depth; i++) {
+           WaitBlit();
+           ar->bdata = (apen&1)?0xffff: 0;
+           ar->bltptd = ar->bltptc = dbm->Planes[i] + offset;
+           ar->bltsize = blsize;  /* start the blit */
+           apen >>= 1;
+           }
+       }
+    WaitBlit();
+    DisownBlitter(); 
+    }
+
+
+#ifdef oldversion    
+/*----------------------------------------------------------------------*/
+/* HLineBlt: fill a horizontal span of pixels with the current area    */
+/* fill pattern.                                                       */
+/* NOTE: this should be changed to use rp's minterms                   */
+/*----------------------------------------------------------------------*/
+HLineBlt(rp,lx,y,rx,mint) struct RastPort *rp; int lx,y,rx;SHORT mint; {
+    int bytes,lwrd,i;
+    LONG offset;
+    SHORT pattern,blsize,bit,apen,bpen,wrd;
+    struct BitMap *dbm = rp->BitMap;
+
+    lwrd = WordOffs(lx);
+    bytes = WordOffs(rx)- lwrd + 2;
+    offset = y*dbm->BytesPerRow + lwrd;
+    if (rp->AreaPtrn != NULL)
+       pattern = rp->AreaPtrn[y&((1<<rp->AreaPtSz)-1)];
+    else pattern = 0xffff;
+    apen = rp->FgPen;
+    bpen = rp->BgPen;
+    blsize = (1<<6)|(bytes>>1);
+    WaitBlit();
+    OwnBlitter(); 
+    ar->fwmask = masks[lx&15];
+    ar->lwmask = ~masks[(rx&15)+1]; 
+    ar->bltcon0 = USEC|USED|mint;  
+    ar->bltcon1 = 0;
+    ar->adata = 0xffff;
+    ar->bltmdd = ar->bltmdc = dbm->BytesPerRow - bytes;
+    bit = 1;
+    for (i = 0; i< dbm->Depth; i++) {
+       wrd = 0;
+       if (bit&apen) wrd = pattern;
+       if (bit&bpen) wrd |= (~pattern);
+       WaitBlit();
+       ar->bdata = wrd;
+       ar->bltptd = ar->bltptc = dbm->Planes[i] + offset;
+       ar->bltsize = blsize;  /* start the blit */
+       bit <<= 1;
+       }
+    WaitBlit();
+    DisownBlitter(); 
+    }
+#endif
+
+BltABCD(a, b, c, d, bltSize, minterm) 
+    UBYTE *a,*c,*b,*d;
+    SHORT bltSize;
+    UBYTE minterm;
+    {
+    SHORT con0;
+    con0 = (a?USEA:0)|(b?USEB:0)|(c?USEC:0)|USED|(minterm&0xff);
+    WaitBlit();
+    OwnBlitter(); 
+    ar->fwmask = 0xffff;
+    ar->lwmask = 0xffff; 
+    ar->bltcon0 = con0;
+    ar->bltcon1 = 0;
+    ar->bltmda = ar->bltmdb = ar->bltmdc = ar->bltmdd = 0;
+    ar->bltpta = a;
+    ar->bltptb = b;
+    ar->bltptc = c;
+    ar->bltptd = d;
+    ar->bltsize = bltSize;  /* start the hardware blit */
+    WaitBlit();
+    WaitBlit();
+    DisownBlitter(); 
+    }
+
+#define A_AND_B   yA&yB
+
+/* sum bit is on if odd number of sources are 1 */
+#define ADD_ABC        (yA&nB&nC)|(nA&yB&nC)|(nA&nB&yC)|(yA&yB&yC)
+       
+/* carry if at least 2 of three sources are 1's */
+#define CARRY_ABC (yA&yB&nC)|(yA&nB&yC)|(nA&yB&yC)|(yA&yB&yC)
+#define POST_CARRY_ABC  0xB2   /* black magic.. trust me */
+
+
+
+#ifdef usingAddBM
+/*  b += a  */
+AddBM(a,b,car)  
+    struct BitMap *a, *b;
+    UBYTE *car;        /* one plane scratch area( carry bit) */
+    {
+    int i;
+    int bpr = a->BytesPerRow;
+    int h = a->Rows;
+    int depth = a->Depth;
+    int bsz = BlitSize(bpr,h);
+    /* carry = 0 */
+    BltClear(car,(a->Rows<<16)+a->BytesPerRow, 3);
+    for (i=0; i<depth; i++) {
+       /* --- add i'th bit and carry, store as new b[i] */
+        BltABCD(a->Planes[i], b->Planes[i], car, b->Planes[i], bsz, ADD_ABC );
+       /* --- compute new carry bit */
+        BltABCD(a->Planes[i], b->Planes[i], car, car, bsz, POST_CARRY_ABC);
+       }
+    }
+#endif
+
+
diff --git a/BLITREGS.H b/BLITREGS.H
new file mode 100644 (file)
index 0000000..5cb6697
--- /dev/null
@@ -0,0 +1,23 @@
+
+typedef struct {
+    USHORT     bltcon0,bltcon1,fwmask,lwmask;
+    UBYTE      *bltptc,*bltptb,*bltpta,*bltptd;
+    USHORT     bltsize;
+    SHORT      ioskip2[3];
+    SHORT      bltmdc,bltmdb,bltmda,bltmdd;
+    SHORT      ioskip3[4];
+    USHORT     cdata,bdata,adata;
+    } BlitterRegs;
+    
+BlitterRegs *ar = (BlitterRegs *)0xDFF040;
+
+struct bltnode myNode;
+
+#define USEA 0x0800
+#define USEB 0x0400
+#define USEC 0x0200
+#define USED 0x0100
+#define MASKWRITE      0x0F00  /* USEA|USEB|USEC|USED */
+#define CONSTWRITE     0x0B00  /* USEA|USEC|USED */
+    
+#define COPYA 0xf0     /* minterm = A */
diff --git a/BMOB.C b/BMOB.C
new file mode 100644 (file)
index 0000000..a85a343
--- /dev/null
+++ b/BMOB.C
@@ -0,0 +1,416 @@
+/*--------------------------------------------------------------*/
+/*                                                             */
+/*     bmob.c   Movable, Sizable Bitmap Object                 */
+/*                                                             */
+/*     8-14-85  created        Dan Silva                       */
+/*     8-15-85  BoxBM version  Dan Silva                       */
+/*--------------------------------------------------------------*/
+#include <system.h>
+#include <prism.h>
+
+#define local static
+
+extern UBYTE *BMAllocMask();
+
+extern BOOL Painting;
+extern BoxBM canvas;
+extern Box clipBox;
+extern struct RastPort *curRP, tempRP;
+extern SHORT curFormat, curxpc, xShft, yShft, curDepth;
+extern SHORT curpen;
+extern Range *shadeRange;
+extern struct TmpRas tmpRas;
+
+extern SHORT dbgbmob;
+extern struct BitMap tmpbm;
+extern BoxBM temp;
+extern struct BitMap tmpbm2;
+extern BoxBM temp2;
+
+/*--------------------------------------------------------------*/
+/*     Debug printout stuff                                    */
+#ifdef DebUG  
+
+prlf() { dprintf("\n"); }
+prBox(b) Box *b; {
+    dprintf("  Box :(%ld, %ld, %ld, %ld)\n", b->x, b->y, b->w, b->h);
+    }
+prBoxBM(bbm) BoxBM *bbm;
+    { dprintf("BoxBM:"); prBox(&bbm->box); prbm(bbm->bm);    }
+
+XBltBitMap(sbm,sx,sy,dbm,dx,dy,w,h,mint,mask,tmp)
+    struct BitMap *sbm,*dbm; SHORT sx,sy,dx,dy,w,h;
+    UBYTE mint,mask, *tmp; {
+/*    if (dbgbmob) */
+    dprintf("BltBitMap, src xy = %ld,%ld, dst xy = %ld, %ld, w,h=%ld,%ld\n",sx,sy,dx,dy,w,h);
+    BltBitMap(sbm,sx,sy,dbm,dx,dy,w,h,mint,mask,tmp);
+    }
+
+#endif 
+
+/**
+dbgbm(bm) struct BitMap *bm; {
+    if (dbgbmob) 
+    BltBitMap(bm,0,0,canvas.bm,0,0,bm->BytesPerRow*8,bm->Rows,REPOP,0xff,NULL);
+    }
+**/
+
+/*--------------------------------------------------------------*/
+/* all the boxes are relative to the same coordinate system    */
+CopyBoxBM(src,dst,mb,clip,mint)  
+    BoxBM *src; /* source */
+    BoxBM *dst;        /* destination */
+    Box *mb;   /* box to be moved */
+    Box *clip;         /* clipping box */
+    SHORT mint;        /* minterm */
+    {
+    Box cb;
+    BOOL res;
+    if (clip) res = BoxAnd(&cb,mb,clip);
+    else {res = YES; cb = *mb; }
+    if (res) {  
+       WaitBlit();
+       BltBitMap(src->bm, cb.x - src->box.x, cb.y - src->box.y, dst->bm, 
+         cb.x - dst->box.x, cb.y - dst->box.y, cb.w, cb.h, mint, 0xff, NULL);
+       WaitBlit();
+       }
+    }
+
+/*----------------------------------------------------------------------*/
+/* BoxNot creates an array of four boxes "n" which represent the       */
+/*  complement of the input box "b":  n = NOT(b)                       */
+/*----------------------------------------------------------------------*/
+#define BIG 25000
+BoxNot(n, b) Box *n, *b; {     
+    SHORT xm = b->x + b->w;
+    SHORT ym = b->y + b->h;
+    n->x = b->x;  n->y = -BIG;  n->w = BIG;        n->h = BIG + b->y;  n++;
+    n->x = xm;    n->y = b->y;  n->w = BIG;        n->h = BIG;         n++;
+    n->x = -BIG;  n->y = ym;    n->w = BIG + xm;   n->h = BIG;         n++;
+    n->x = -BIG;  n->y = -BIG;  n->w = BIG + b->x; n->h = BIG + ym;
+    }
+    
+/*----------- Synchronize with the vertical beam motion */
+
+#ifdef awawawa 
+void WaitBeam(n) SHORT n; { 
+    SHORT vb,tol;
+    /* WaitBeam causes problems with interlace so skip it*/
+    n = MAX(0, MIN(256,n));
+    if (curFormat == 2) return;
+    tol = curFormat?100:50;
+    for (;;) { 
+       vb = VBeamPos() - n;
+       if (vb<0) vb += 256;
+       if (( 0 <= vb) && ( vb < tol))  return; 
+       }
+    }
+#endif
+
+extern PaintMode paintMode;
+extern BOOL erasing;
+extern BOOL firstDown;
+extern SHORT lastSmX, lastSmY;
+
+/* make bm same size as pict bm of object, curdepth in depth */
+SaveSizeBM(bm,ob) struct BitMap *bm;  BMOB *ob; {
+    return(NewSizeBitMap(bm, curDepth, ob->pict.box.w, ob->pict.box.h));
+    }
+
+int BMBlitSize(bm) struct BitMap *bm; {
+    return((int) BlitSize(bm->BytesPerRow, bm->Rows));
+    }
+
+
+/*----------------------------------------------------------------------*/
+/*  SMEAR mode:                                                                */
+/*----------------------------------------------------------------------*/
+
+/* First some utilities .... */
+
+/* maskblit the save.bm at the CURRENT position */
+MBSaveAtPict(ob,canv,clip,mask) 
+    BMOB *ob; BoxBM *canv; Box *clip; UBYTE *mask;  {              
+    Box b;
+    BoxAnd(&b,&ob->save.box,clip);
+    b.x += ob->pict.box.x - ob->save.box.x;
+    b.y += ob->pict.box.y - ob->save.box.y;
+    MaskBlit( ob->save.bm, &ob->pict.box, mask, canv->bm,
+           &canv->box, &b, clip, COOKIEOP, tmpRas.RasPtr, 0xff,0);
+    }
+    
+RelocBoxBM(fr,to) BoxBM *fr,*to; {
+    DupBitMap(fr->bm,to->bm);
+    BlankBitMap(fr->bm);
+    to->box = fr->box;
+    }
+
+void DoSmear(ob,canv,clip)  BMOB *ob; BoxBM *canv; Box *clip;  {                   
+    if (SaveSizeBM(temp.bm, ob)) return;
+    temp.box = ob->pict.box;
+    CopyBoxBM(canv, &temp, &temp.box, clip, REPOP);
+    if (!firstDown) MBSaveAtPict(ob,canv,clip,ob->mask);
+    else firstDown = NO;
+    RelocBoxBM(&temp,&ob->save); /* save = temp */
+    }
+
+#ifdef DOADD
+void DoAdd(ob,canv,clip)  BMOB *ob; BoxBM *canv; Box *clip;  {             
+    if (SaveSizeBM(temp.bm, ob)) return;
+    temp.box = ob->pict.box;
+    CopyBoxBM(canv, &temp, &temp.box, clip, REPOP);
+    AddBM(ob->pict.bm, temp.bm, tmpRas.RasPtr);
+    CopyBoxBM(&temp,camv, &temp.box,clip,REPOP);
+    }
+#endif
+    
+
+#define USEMSK  0x100
+#define USEPCT  0x200
+#define SPECIAL 0x400
+
+USHORT paintProps[NPaintModes] = {
+    USEPCT| USEMSK| COOKIEOP,          /*  Mask */
+           USEMSK| COOKIEOP,   /*  Color  */
+    USEPCT| REPOP,             /*  Replace */
+    SPECIAL,                           /*  Smear */
+    SPECIAL,                   /*  Shade */
+    SPECIAL,                   /*  Blend */
+           USEMSK| COOKIEOP,   /*  Cycle Paint*/
+    USEPCT| USEMSK| XORMASK    /*  Xor */
+    };
+
+/* pens don't have Picture: just mask so they do the best they can
+   in Mask and Replace modes */
+USHORT penModes[NPaintModes] = {
+    Color,     /*  Mask */
+    Color,     /* Color  */
+    Color,     /*  Replace */
+    Smear,     /*  Smear */
+    Shade,     /*  Shade */
+    Blend,     /*  Blend */
+    Color,     /*  Cycle Paint*/
+    Xor                /*  Xor */
+    };
+
+#define ERASPROPS   USEMSK|COOKIEOP
+
+               
+    
+/*--------------------------------------------------------------*/
+/* Paint the object onto the canvas through the clip box       */
+/* using "paintMode", the current global painting mode         */
+/*--------------------------------------------------------------*/
+void PaintOb(ob, canv, clip)  BMOB *ob; BoxBM *canv; Box *clip;  {
+    UBYTE *tmpMask = NULL;
+    SHORT pluse,pldef,props;
+    PaintMode pntMode;
+    tmpMask = tmpRas.RasPtr;
+    pntMode = paintMode;
+    if (curpen!=USERBRUSH) pntMode = penModes[pntMode];
+    if ((pntMode==Smear)||(pntMode==Blend)) { 
+       if (erasing||!Painting) pntMode = Color;
+       }
+    props = paintProps[pntMode]; 
+    pluse = 0;
+    if (erasing) {
+       if (pntMode==Replace) { PFillBox(&ob->pict.box); return; }
+         else if (pntMode!=Shade) 
+               { props = ERASPROPS; pldef = curxpc; }
+       }
+    else if  (props&USEPCT) pluse = ob->planeUse; 
+           else  { pldef = curRP->FgPen;   }
+    if (props&SPECIAL)  switch(pntMode) {
+       case Shade: DoShade(ob,canv,clip); break;
+       case Smear: DoSmear(ob,canv,clip); break;
+       case Blend: DoBlend(ob,canv,clip); break;
+       }
+    else  if (props&USEMSK) {
+           if ((pntMode==Xor)&!erasing)  pldef = 0xff;
+           MaskBlit(ob->pict.bm, &ob->pict.box,ob->mask,canv->bm,&canv->box,
+                &ob->pict.box,clip, props&0xff, tmpMask,pluse,pldef);
+           }
+       else  CopyBoxBM(&ob->pict, canv,&ob->pict.box, clip,props&0xff);
+    }
+
+/*---Create a BoxBM type object, Copying a rectangle of bits from curRP*/    
+/* assumes pict.bm and save.bm already point at BitMap structs         */
+
+SHORT ExtractBMOB(ob,bx,xoff,yoff) 
+    BMOB *ob;          /* object to be created  */
+    Box *bx;           /* bounds of object in curRP */
+    int xoff,yoff;     /* offset of handle from u.l. of source */
+    {
+    if (NewSizeBitMap(ob->pict.bm, curDepth, bx->w, bx->h)) return(FAIL);
+
+/** put in AllocMem instead
+    if (AvailMem(MEMF_PUBLIC|MEMF_CHIP) < 12000) {
+       FreeBitMap(ob->pict.bm);
+       return(FAIL);
+       }
+**/
+    ob->pict.box = *bx;
+    ob->save.box = *bx;
+    DFree(ob->mask);
+    ob->mask = BMAllocMask(ob->pict.bm);
+    if (ob->mask == NULL) { FreeBitMap(ob->pict.bm); return(FAIL);}
+
+    SetBitMap(ob->pict.bm, curxpc);
+    CopyBoxBM(&canvas,&ob->pict, &ob->pict.box, &clipBox, REPOP);
+    MakeMask(ob->pict.bm,ob->mask, curxpc, NEGATIVE);
+    ob->minTerm = COOKIEOP;
+    ob->planeUse = 0xff;
+    ob->planeDef = 0;
+    ob->flags = 0;
+    ob->xoffs = xoff;    ob->yoffs = yoff;
+    ob->xpcolor = curxpc;
+    return(SUCCESS);
+    }
+
+/*--------------------------------------------------------------*/
+
+FreeBMOB(ob) BMOB *ob; {
+    FreeBitMap(ob->pict.bm);
+    FreeBitMap(ob->save.bm);
+    FreeBitMap(&tmpbm);        /* just being compulsive */
+    DFree(ob->mask);
+    }
+
+/* this needs to get called on button up in smear mode */              
+BMOBFreeTmp() { FreeBitMap(&tmpbm); }
+
+BMOBMask(ob) BMOB *ob; {
+    DFree(ob->mask);
+    ob->mask = (UBYTE *)BMAllocMask(ob->pict.bm);
+    if (ob->mask==NULL) return(FAIL);
+    MakeMask(ob->pict.bm,ob->mask,ob->xpcolor,NEGATIVE);
+    return(SUCCESS);
+    }
+
+
+BMOBNewSize(ob,d,w,h) BMOB *ob; SHORT d,w,h; {
+    if (NewSizeBitMap(ob->pict.bm,d,w,h)) return(FAIL);
+    ob->pict.box.w = w;
+    ob->pict.box.h = h;
+    DFree(ob->mask);
+    ob->mask = (UBYTE *)BMAllocMask(ob->pict.bm);
+    if (ob->mask==NULL){ FreeBitMap(ob->pict.bm); return(FAIL); }
+    return(SUCCESS);
+    }
+
+
+local InvSaveBox(ob) BMOB *ob; {
+#ifdef DBGSTR
+    dprintf(" InvSaveBox ... \n");
+#endif
+    TempXOR();
+    PThinFrame(&ob->save.box);
+    RestoreMode();
+    }
+    
+local void ShowBMOB(ob) BMOB *ob; {
+    if (ob->flags&SHOWING) return;
+    ob->save.box = ob->pict.box;
+    if (NewSizeBitMap(ob->save.bm, curDepth, ob->pict.box.w,ob->pict.box.h))
+       { 
+       ob->flags |= TOOBIGTOPAINT;
+       InvSaveBox(ob);
+       }
+    else {
+       CopyBoxBM(&canvas, &ob->save, &ob->save.box, &clipBox, REPOP);
+       PaintOb(ob,&canvas,&clipBox);
+       }
+    ob->flags |= SHOWING;
+    }
+
+
+void ClearBMOB(ob) BMOB *ob; {
+    if (!(ob->flags&SHOWING)) return;
+    if (ob->flags&TOOBIGTOPAINT) {
+       InvSaveBox(ob);
+       ob->flags &= (~TOOBIGTOPAINT); 
+       }
+    else CopyBoxBM(&ob->save, &canvas, &ob->save.box, &clipBox, REPOP);
+    FreeBitMap(ob->save.bm); 
+    FreeBitMap(&tmpbm);
+    ob->flags &= (~SHOWING);
+    }
+
+CheapMove(ob) BMOB *ob; {
+#ifdef DBGSTR
+    dprintf("Cheap move... \n");
+#endif
+    ClearBMOB(ob); /* so do economy version */
+    ShowBMOB(ob);
+    }
+
+/* updates the screen for a BMOB that has changed position or size 
+   pict is it's new position, and saves it's old one */
+
+void ChangeBMOB(ob) BMOB *ob;{
+    SHORT i;
+    Box  c, *d, notb[4];
+    Box *new = &ob->pict.box, *old = &ob->save.box;
+    if (!(ob->flags&SHOWING)) ShowBMOB(ob);
+    else {
+       if ((ob->flags&TOOBIGTOPAINT)||
+        ( NewSizeBitMap(temp.bm, curDepth, new->w, new->h))) 
+           { CheapMove(ob); return; }
+       temp.box = *new; 
+       
+       /*----- copy intersection of old and new to new */
+       CopyBoxBM(&ob->save, &temp, old, new, REPOP);
+    
+       /* -----copy the newly covered areas (new-old) from scrn to new */ 
+       BoxNot(&notb, old);
+       for (i=0, d = &notb[0]; i<4; i++,d++) if (BoxAnd(&c,d,new))
+           CopyBoxBM(&canvas, &temp, &c, &clipBox, REPOP);
+    
+       /*-----fix up the uncovered areas (old-new) on the screen */
+       BoxNot(&notb, new);
+       for (i=0, d = &notb[0]; i<4; i++,d++)  if (BoxAnd(&c,d,old))
+           CopyBoxBM(&ob->save, &canvas, &c, &clipBox, REPOP);
+    
+       /*-----save an unpolluted copy of the area the object will cover */
+       if (CopyBitMap(temp.bm,ob->save.bm)) { 
+           /* stretching: couldn't alloc save.bm-- must be stretching */
+#ifdef DBGSTR
+           dprintf(" ChangeBM: Couldnt alloc save.bm \n");
+#endif
+           DupBitMap(temp.bm, ob->save.bm);
+           ob->save.box = ob->pict.box;
+           BlankBitMap(temp.bm);
+           CheapMove(ob);
+           return;
+           }
+
+       /*-----paint object onto background in temp */
+       PaintOb(ob,&temp,NULL);
+
+       /*-----copy updated area to screen, synced with vertical retrace */
+/*     WaitBeam( new->y + new->h ); */
+
+#ifdef DOLAYERS
+       tempRP.BitMap = &tmpbm;
+       /* ----play the layers game:--- */
+       ClipBlit(&tempRP,0,0,curRP,new->x,new->y,new->w,new->h,REPOP);
+#else
+       /* use my own clipping */
+       CopyBoxBM(&temp, &canvas, new, &clipBox, REPOP); 
+#endif
+       }
+    ob->save.box = ob->pict.box;
+    }
+
+local PosBMOB(ob,nx,ny) BMOB *ob; SHORT nx,ny; {
+    ob->pict.box.x = nx - ob->xoffs;
+    ob->pict.box.y = ny - ob->yoffs;
+    }
+    
+MoveBMOB(ob,nx,ny) BMOB *ob; SHORT nx,ny; { PosBMOB(ob,nx,ny); ChangeBMOB(ob); }
+
+DispBMOB(ob,nx,ny) BMOB *ob; SHORT nx,ny; {
+    PosBMOB(ob,nx,ny); 
+    PaintOb(ob,&canvas, &clipBox);  
+    }
+
diff --git a/BOX.C b/BOX.C
new file mode 100644 (file)
index 0000000..08235e2
--- /dev/null
+++ b/BOX.C
@@ -0,0 +1,69 @@
+/*--------------------------------------------------------------*/
+/*                                                             */
+/*        box.c  -- operations on boxes                        */
+/*                                                             */
+/*--------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+Box *MakeBox(bx,x,y,w,h) Box *bx; int x,y,w,h; { 
+    bx->x = x; bx->y = y; bx->w = w; bx->h = h; 
+    return(bx);
+    }
+
+BOOL BoxContains(b,x,y) Box *b; int x,y; {
+    return((BOOL)((x>=b->x)&&(x<(b->x+b->w))&&(y>=b->y) && (y<(b->y+b->h))));
+    }
+
+/* intersection of two boxes:  compute c = intersect(a,b)  */
+    
+BOOL BoxAnd(c,a,b) Box *c,*a,*b; {
+    BOOL res = YES;
+    SHORT amx,amy,bmx,bmy;
+    amx = a->x + a->w;    amy = a->y + a->h;
+    bmx = b->x + b->w;    bmy = b->y + b->h;
+    c->w = MIN(amx, bmx) - (c->x = MAX(a->x, b->x));
+    c->h = MIN(amy, bmy) - (c->y = MAX(a->y, b->y));
+    if ( (c->w<=0) || (c->h<=0) ) { c->x = c->y = c->w = c->h = res = 0; }
+    return(res);
+    }
+    
+Box *BoxTwoPts(b,x1,y1,x2,y2) Box *b; int x1,y1,x2,y2; {
+    ORDER(x1,x2);    ORDER(y1,y2);
+    b->x = x1; b->y = y1; b->w = x2-x1+1;  b->h = y2-y1+1;
+    return(b);
+    }
+
+Box *BoxThreePts(b,x1,y1,x2,y2,x3,y3) Box *b; int x1,y1,x2,y2,x3,y3; {
+    ORDER(x1,x2); ORDER(x1,x3); ORDER(x2,x3);
+    ORDER(y1,y2); ORDER(y1,y3); ORDER(y2,y3);
+    b->x = x1; b->y = y1; b->w = x3-x1+1;  b->h = y3-y1+1;
+    return(b);
+    }
+
+/* constrain box a to be inside b  */
+BoxBeInside(a,b) Box *a,*b; {
+    SHORT nout;
+    a->x = MAX(b->x,a->x);
+    a->y = MAX(b->y,a->y);
+    nout = (a->x + a->w) - (b->x + b->w);
+    if (nout>0) a->x -= nout;
+    nout = (a->y + a->h) - (b->y + b->h);
+    if (nout>0) a->y -= nout;
+    }
+
+/* make box c bigger so it encloses b */
+EncloseBox(c,b) Box *c,*b; {
+    SHORT xm,ym;
+    if (c->w==0) *c = *b;      /* w = 0 is null box by convention */
+    else {
+       xm = MAX(c->x+c->w,b->x+b->w);
+       ym = MAX(c->y+c->h,b->y+b->h);
+       c->x = MIN(c->x,b->x);
+       c->y = MIN(c->y,b->y);
+       c->w = xm-c->x;
+       c->h = ym-c->y;
+       }
+    }
+
diff --git a/BRXFORM.C b/BRXFORM.C
new file mode 100644 (file)
index 0000000..53b0ca5
--- /dev/null
+++ b/BRXFORM.C
@@ -0,0 +1,145 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*        brxform -- Brush transformations                             */
+/*                                                                     */
+/*      BrFlipX, BrFlipY, BrRot90, BrRemapCols, BrBgToFg               */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+#define local
+
+extern UBYTE *BMAllocMask();
+extern SHORT curxpc;
+extern struct RastPort *curRP;
+extern struct TmpRas tmpRas;
+extern SHORT curpen;
+extern BMOB curbr;
+
+/*----------------------------------------------------------------------*/
+/*     Maintain "Original" brush, before transforming                  */
+/*----------------------------------------------------------------------*/
+extern BMOB origBr;
+extern struct BitMap origBM;
+extern SHORT curBrXform;
+    
+/* copy the picture information of a BMOB */    
+BOOL CopyBMOBPict(a,b) BMOB *a,*b; {
+    BOOL res =  CopyBitMap(a->pict.bm,b->pict.bm);
+    if (res) { /* dprintf(" CopyBMOBPict: alloc err \n");*/ return(FAIL);}
+    b->pict.box = a->pict.box;
+    DFree(b->mask);
+    b->mask = BMAllocMask(curbr.pict.bm);
+    if (b->mask==0) return(FAIL);
+    movmem(a->mask,b->mask, BMPlaneSize(a->pict.bm));
+    b->xoffs = a->xoffs;
+    b->yoffs = a->yoffs;
+    b->xpcolor = a->xpcolor;
+    return(SUCCESS);
+    }
+
+/* save a copy of the brush preparatory to Transorming it */    
+BOOL SaveBrush(newxf)  {
+    BOOL res=SUCCESS;
+    origBr.pict.bm = &origBM;
+    FreeBitMap(curbr.save.bm);
+    if (curBrXform != newxf) res = CopyBMOBPict(&curbr, &origBr);
+    if (!res) curBrXform = newxf;
+    else curBrXform = NOXFORM;
+    return(res);
+    }
+
+
+/*----Restores the brush to its original state before transforming. */
+/* this frees the storage for the transformed version */
+void RestoreBrush() {
+    if (curBrXform == NOXFORM) return;
+    FreeBitMap(curbr.pict.bm);
+    DFree(curbr.mask);
+    curbr.mask = origBr.mask;
+    origBr.mask = NULL;
+    DupBitMap(origBr.pict.bm, curbr.pict.bm);
+    setmem(origBr.pict.bm,sizeof(struct BitMap),0);
+    curbr.pict.box = origBr.pict.box;
+    curbr.xoffs = origBr.xoffs;
+    curbr.yoffs = origBr.yoffs;
+    curBrXform = NOXFORM;
+    curbr.flags = 0;
+    }
+
+
+/*----------------------------------------------------------------------*/
+/*  Map BG color to FG Color                                           */
+/*----------------------------------------------------------------------*/
+
+void BrBgToFg() {
+    if (curpen!=USERBRUSH) return;
+    BMMapColor(curbr.pict.bm,curbr.pict.bm, curxpc, curRP->FgPen);
+    BMOBMask(&curbr);
+    }
+
+
+/*----------------------------------------------------------------------*/
+/*  Reverse brush in X - direction                                     */
+/*----------------------------------------------------------------------*/
+
+FlipX(sbm,sw,dbm)  struct BitMap *sbm,*dbm; SHORT sw; {
+    SHORT x,h;
+    h = sbm->Rows;
+    for (x = 0; x < sw; x++ ) 
+       BltBitMap(sbm,x,0,dbm,sw-x-1,0,1,h,REPOP,0xff,tmpRas.RasPtr);   
+    }
+    
+BOOL ObFlipX(ob) BMOB *ob; {
+    struct BitMap tmpbm;
+    BlankBitMap(&tmpbm);
+    if (CopyBitMap(ob->pict.bm, &tmpbm)) return(FAIL);
+    FlipX(&tmpbm,ob->pict.box.w, ob->pict.bm);
+    ob->xoffs = ob->pict.box.w - ob->xoffs -1;
+    BMOBMask(ob);
+    FreeBitMap(&tmpbm);
+    return(SUCCESS);
+    }
+
+void BrFlipX() {
+    if (curpen!=USERBRUSH) return;
+    ZZZCursor();
+    if (ObFlipX(&curbr)) goto finish;
+    if (curBrXform != NOXFORM) ObFlipX(&origBr);
+    finish: UnZZZCursor();
+    }
+
+/*----------------------------------------------------------------------*/
+/*  Reverse brush in Y - direction                                     */
+/*----------------------------------------------------------------------*/
+FlipY(sbm,dbm)  struct BitMap *sbm,*dbm; {
+    SHORT y,w,h;
+    w = sbm->BytesPerRow*8;
+    h = sbm->Rows;
+    for (y = 0; y < h; y++ ) 
+       BltBitMap(sbm,0,y,dbm,0,h-y-1,w,1,REPOP,0xff,tmpRas.RasPtr);   
+    }
+
+
+BOOL ObFlipY(ob) BMOB *ob; {
+    struct BitMap tmpbm;
+    BlankBitMap(&tmpbm);
+    if (CopyBitMap(ob->pict.bm, &tmpbm)) return(FAIL);
+    FlipY(&tmpbm, ob->pict.bm);
+    ob->yoffs = ob->pict.box.h - ob->yoffs -1;
+    BMOBMask(ob);
+    FreeBitMap(&tmpbm);
+    return(SUCCESS);
+    }
+
+void BrFlipY() {
+    if (curpen!=USERBRUSH) return;
+    ZZZCursor();
+    if (ObFlipY(&curbr)) goto finish;
+    if (curBrXform != NOXFORM) ObFlipY(&origBr);
+    finish: UnZZZCursor();
+    }
+
+
diff --git a/CCYCLE.C b/CCYCLE.C
new file mode 100644 (file)
index 0000000..78e10c7
--- /dev/null
+++ b/CCYCLE.C
@@ -0,0 +1,190 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*        ccycle -- Color cycling and cycle paint                      */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+extern struct ViewPort *vport;
+extern struct RastPort *curRP;
+extern SHORT nColors;
+extern BOOL erasing;
+
+#define local static 
+
+
+/* cycling frame rates */
+#define OnePerTick     16384
+#define OnePerSec      OnePerTick/60
+
+Range cycles[MAXNCYCS] = {
+    /* count, rate, active, low, high */
+    {0, 0, YES, 20, 31 },              /* shade range */
+    {0, OnePerSec*10, YES, 3,7 },
+    {0, OnePerSec*10, YES, 0,0 },
+    {0, OnePerSec*10, YES, 0,0 }
+    };
+
+local BOOL cycling = NO;
+local BOOL wasCyc = NO;
+local BOOL paused = NO;
+local LONG timer = 0;
+
+local WORD colors[MAXNCOLORS];
+local WORD saveCols[MAXNCOLORS];
+
+SHORT curlow=0,curhigh=31;
+Range *curCyc = NULL;
+Range *shadeRange = cycles;
+
+extern void SetCycPaint();
+
+
+LoadCols(cols) WORD cols[]; { LoadRGB4(vport,cols,nColors); }
+
+local void StartCCyc()  { 
+    if (cycling) return;
+    GetColors(saveCols); GetColors(colors);   
+    StartVBlank(); 
+    cycling = YES;
+    }
+    
+local void StopCCyc() { 
+    if (!cycling) return;
+    StopVBlank(); 
+    LoadCols(saveCols); 
+    cycling = NO; 
+    }
+       
+KillCCyc() {
+    if (cycling) StopCCyc();
+    else if (paused) wasCyc = NO;
+    }
+
+TogColCyc() { 
+    if (paused) wasCyc = !wasCyc; else
+    if (!cycling)  StartCCyc();   else StopCCyc();
+    }
+PauseCCyc() { wasCyc = cycling;  if (cycling) StopCCyc(); paused = YES; }
+ResumeCCyc() { if (wasCyc) StartCCyc(); paused = NO; }
+
+BOOL NoCycle = NO;
+
+local void CycleColors()    {            
+    int i,j;  Range *cyc;
+    WORD temp;
+    BOOL anyChange = NO;
+    if (!cycling) return; 
+    for (i = 1; i<MAXNCYCS; i++) {
+       cyc = &cycles[i];
+       if (cyc->active) {
+           cyc->count += cyc->rate;
+           if (cyc->count >= OnePerTick ) {
+               anyChange = YES;
+               cyc->count -= OnePerTick;
+               temp = colors[cyc->high];
+               for (j = cyc->high; j >cyc->low; j--) colors[j] = colors[j-1];
+               colors[cyc->low] = temp;
+               }
+           }
+       }
+    if (anyChange&&(!NoCycle)) LoadCols(colors);
+    }
+
+/*----------- Vertical Blank Routine to Cycle state.colors --------------*/
+local LONG mystack[64];          /* stack space for the int handler */
+local char myname[]="MyVb";       /* Name of the int handler */
+local struct Interrupt intServ;
+
+typedef void (*VoidFunc)();
+
+local MyVBlank() {
+    timer++;
+    CycleColors();
+    return(0);
+    }
+    
+local StartVBlank()   {
+    intServ.is_Data = (APTR) mystack;
+    intServ.is_Code = (VoidFunc)&MyVBlank;
+    intServ.is_Node.ln_Succ = NULL;
+    intServ.is_Node.ln_Pred = NULL;
+    intServ.is_Node.ln_Type = NT_INTERRUPT;
+    intServ.is_Node.ln_Pri = 0;
+    intServ.is_Node.ln_Name = myname;
+    AddIntServer(5,&intServ);
+    }
+
+local StopVBlank() { RemIntServer(5,&intServ); }
+
+
+/* ---- Incrementally Change Color table Values --------------- */    
+
+local SetCTab(c,i) SHORT c,i;{SetRGB4(vport, i, (c>>8)&0xf, (c>>4)&0xf, c&0xf); }
+
+IncRGB(inc)SHORT inc; {
+    SHORT n = curRP->FgPen;
+    if (!cycling)   SetCTab(GetRGB4(vport->ColorMap,n)+inc , n);
+    else {
+       cycling = NO;
+       saveCols[n] += inc;
+       movmem(saveCols,colors,MAXNCOLORS*sizeof(SHORT));
+       LoadCols(colors);
+       cycling = YES;
+       }
+    }
+
+
+BOOL cycPntOn = NO;
+
+
+/*
+TogCycPaint() {   cycPntOn = !cycPntOn; SetCycPaint();    }
+*/
+
+
+local Range *FindCycle(n) SHORT n; {
+    int i;
+    Range *cyc;
+    for (i=1; i<MAXNCYCS; i++) {
+       cyc = &cycles[i];
+       if ( (n>=cyc->low) && (n<=cyc->high) ) return(cyc);
+       }
+    return(NULL);
+    }
+
+static SHORT cycFgPen = -1;
+
+void SetCycPaint() {
+    cycFgPen = curRP->FgPen;
+    curCyc = FindCycle(cycFgPen);
+    if (curCyc!=NULL) { curlow = curCyc->low; curhigh = curCyc->high;  }
+    else { curlow = 0; curhigh = nColors-1; }
+    }
+
+
+OnCycPaint(){ cycPntOn = YES; SetCycPaint(); }
+OffCycPaint() { cycPntOn = NO; SetCycPaint(); }
+
+/*----------------------------------------------------------------------*/
+/*        cycle Painting                                               */
+/*----------------------------------------------------------------------*/
+
+/* calling this routine will increment the current painting color */
+/* You dont want to be updating the control panel every time and this 
+doesn't. Call EndCycPaint() to do that. */
+
+CycPaint() {
+    SHORT n;
+    if (cycPntOn&&(curCyc!=NULL)&&(!erasing)) {
+       n = curRP->FgPen + 1;
+       if (n > curhigh) n = curlow;
+       SetFGCol(n); 
+       }
+    }
+
+EndCycPaint(){ CPChgCol(curRP->FgPen); }
+
+    
diff --git a/CHPROC.C b/CHPROC.C
new file mode 100644 (file)
index 0000000..fb29a87
--- /dev/null
+++ b/CHPROC.C
@@ -0,0 +1,252 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*             chproc.c -- Main character dispatch proc                */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+#include <pnts.h>
+
+extern PointRec pnts; /* contains mx,my,sx,sy, etc */
+extern BOOL Ctrl;
+extern BOOL modeHelp;
+extern void ShadMode(),NullMode(),SelBrush(),CircMode();
+extern void FCircMode(),DrawMode(),OvalMode(),FOvalMode();
+extern void AFillMode(),BFillMode(),CurvMode(),RectMode();
+extern void FRectMode(),VectMode(),BrStretch(),TextMode(),ReadMode();
+extern void ToglMagW();
+extern short curpen,curFormat;
+extern struct Window *mainW;
+extern SHORT getch();
+extern BOOL kbhit();
+extern BOOL titleShowing;
+extern BOOL Painting,gridON,inside;
+extern struct RastPort *curRP,tempRP;
+extern struct ViewPort *vport;
+extern struct BitMap hidbm;
+extern struct ViewPort *vport;
+extern SHORT curxpc,nColors,curIMode;
+extern Box screenBox,bigBox;
+extern struct TmpRas tmpRas;
+extern SHORT curPixFmt, xShft, yShft, nColors;
+
+SHORT chgToMode = IM_none;
+
+#define local static
+
+IncFG(inc) SHORT inc; { CPChgCol((nColors-1)&(curRP->FgPen + inc));  }
+
+IncBG(inc) SHORT inc; { CPChgBg((nColors-1)&(curxpc + inc));  }
+
+void (*tempChProc)() = NULL;
+
+PlugChProc(proc) void (*proc)(); {    tempChProc = proc;    }
+
+whoa() {}
+
+DispAndSetMode(m) int m; {
+    SetModeMenu(m);
+    DispPntMode();
+    }
+
+IncPen() { CPChgPen(curpen?curpen+1:RoundB(1));   }
+
+DecPen() { if ((curpen&0xfff) > 1) CPChgPen(curpen-1);
+    else CPChgPen(0);  }
+
+
+HelpMe() {
+    BasicBandW();
+    CPChgPen(0);
+    NewIMode(IM_draw);
+    DispAndSetMode(modeHelp? Color: Mask);
+    SymState(NO);
+    SetGridSt(NO);
+    SetGridXY(8,8);
+    SetGridOrg(0,0);
+    ShowCtrPan(YES);
+    if (!titleShowing) TogTitle();
+    RemoveMag();
+    KillCCyc();
+    }
+
+/* #define accelScroll */ /* BUGGY */
+
+scrollKeys(wh,i,j) Pane *wh; int i,j; {
+    SHORT c;
+    int xs = PMapX(8);
+    int ys = PMapY(8);
+    MWScroll(wh,i*xs,j*ys);
+    while (kbhit()) {
+       i = j = 0;
+       while (kbhit()) if (getch()==0) {
+           c = GetNextCh();
+#ifdef accelScroll
+           switch(c) {
+               case CLeft:  i++; break;
+               case CRight: i--; break;
+               case CUp:    j++; break;
+               case CDown:  j--; break;
+               }
+#endif
+           }
+#ifdef accelScroll
+       if ((i!=0)||(j!=0)) MWScroll(wh,i*xs,j*ys);
+#endif
+       }
+    }
+
+Half() {  if (curpen==USERBRUSH) BrHalf();
+    else CPChgPen((curpen&0xf000)|((curpen&0xfff)>>1));
+    }
+
+Dubl() {  if (curpen==USERBRUSH) BrDubl();
+    else CPChgPen((curpen&0xf000)|MAX((curpen&0xfff)<<1,1));
+    }  
+
+    
+/* toggle grid, but adust grid offset so brushes doesn't move */
+extern SHORT gridx,gridy, gridOrgX, gridOrgY;
+extern BOOL gridON;
+extern BMOB *curob;
+extern Point nogrid;
+    
+/* move grid is on the grid point so when
+    toggle grid brush doesnt move*/ 
+void TogGridFixed() { 
+    SHORT tx,ty;
+    TogGridSt();
+    if (gridON) {
+       tx = mx; ty = my;
+       Gridify(&tx,&ty);
+       gridOrgX += (mx - tx);
+       gridOrgY += (my - ty);
+       }
+    }
+
+/* --Process keyboard character(s) ----*/ 
+
+void mainCproc(pn,c) Pane *pn; char c; { 
+    BOOL svpnt = Painting;
+    if (tempChProc!=NULL) {
+       (*tempChProc)(c); 
+       /* this lets text, when <esc>, change to mode in parallel overlay */
+       if (chgToMode!=IM_none) {
+           NewIMode(chgToMode);
+           chgToMode = IM_none;
+           }
+       return;
+       }
+    ClearFB();
+    switch(c) { 
+       /*---------Change Color Pallete( use Keypad ) */
+       case '7': IncRGB(-REDC); break;
+       case '8': IncRGB( REDC); break;
+       case '4': IncRGB(-GREENC); break;
+       case '5': IncRGB( GREENC); break;
+       case '1': IncRGB(-BLUEC); break;
+       case '2': IncRGB( BLUEC); break;
+       
+       case '.': CPChgPen(0); break;           /*  1 pixel Pen */
+       case '-': if (curIMode == IM_airBrush) ChgABRadius(-1);
+                   else DecPen(); break; /* cycle thru pens */
+       case '=': if (curIMode == IM_airBrush) ChgABRadius(1);
+                  else IncPen(); break;
+
+       case '[': IncFG(-1); break;     /* Cycle thru foreground cols*/
+       case ']': IncFG(1); break;      
+       
+       case '{': IncBG(-1); break;     /* cycle thru background cols*/
+       case '}': IncBG(1); break;
+       
+       case '/': TogSymSt(); break;    /* Symmetry on and off */
+       
+       case ' ': AbortIMode(); break;  /* Kills any action */
+       
+       case ',': NewIMode(IM_readPix); break;  /* Read color from 
+               screen-- Left Button for FG col, Right Button for BG */
+       
+       case TAB: TogColCyc();  break;
+       
+       case 'j': SwapSpare(); break;
+#ifdef agagag
+       /*----- Rudimentary File IO  */
+       case 'i': LoadPicNamed("temp.pic"); break;
+       case 'o': SavePicNamed("temp.pic"); break;
+       case 'I': LoadPicNamed("temp1.pic"); break;
+       case 'O': SavePicNamed("temp1.pic"); break;
+#endif
+
+       case 'a': if (Ctrl) DispAvailMem(); else NewIMode(IM_airBrush);  break;
+       case 'A': SizeAirBrush();  break;
+               
+       case 'b': NewIMode(IM_selBrush); break; /* select a new brush*/
+       case 'B': UserBr(); break;              /* use last brush selected */
+
+/* The rest is like PC Prism */                
+       case 'c': NewIMode(IM_circ); break;     /*  draw circle */      
+       case 'C': NewIMode(IM_fcirc); break;    /* fill circle */
+       case 'd': NewIMode(IM_draw); break;     /* draw  */             
+       case 'D': CPChgPen(0); NewIMode(IM_draw); break; /* draw with 1-pixel pen */
+       case 'e': NewIMode(IM_oval); break;     /* ellipse */
+       case 'E': NewIMode(IM_foval); break;    /* filled ellipse*/ 
+       case 'f': NewIMode(IM_fill); break;     /* flood area*/
+       case 'g': TogGridSt(); break;           /* grid on-off */
+       case 'G': TogGridFixed();break;         /* grid on-off, keep pos fixed */
+       case 'h': Half(); break;                /* halve brush size */
+       case 'H': Dubl(); break;                /* double brush size */
+       case 'K': mClearToBg(); break;          /* clear screen to b.g. color */        
+#ifdef OWell
+       case 'm': ShowMag(mx,my); break;        /* show magnify window*/
+       case 'n': RemoveMag(); break;           /* remove mag window */
+#else
+       case 'm': ToggleMag(); break;   /* show magnify window*/
+       case 'n': CenterPoint(mx,my); break;            /* remove mag window */
+#endif
+       case 'p': ShowPallet(); break;          /* Show the RGB-HSV pallet*/
+       case 'q': NewIMode(IM_curve1); break;   /* curve */     
+       case 'r': NewIMode(IM_rect); break;     /* rectangle */
+       case 'R': NewIMode(IM_frect); break;    /*filled rectangle */
+       case 's': NewIMode(IM_shade); break;    /* shade */
+       case 't': NewIMode(IM_text1); break;    /* text */
+       case 'u': Undo(); break;                /* Undo  */
+       case 'v': NewIMode(IM_vect); break;      /* straight lines */
+       case 'x': BrFlipX(); break;             /* Flip brush horizontally */
+       case 'y': BrFlipY(); break;             /* Flip brush vertically */
+       case 'z': BrRot90(); break;             /* Rotate brush 90 degrees */
+       case 'Z': NewIMode(IM_strBrush); break;         /* stretch brush */
+       case '>': MWZoom(1); break;             /* Zoom mag window in*/
+       case '<': MWZoom(-1); break;            /* Zoom mag window out */
+       case 'w': whoa(); break;                /* for break points */
+       case 0: switch(c = GetNextCh()) { 
+       
+           /* Set painting mode with function keys F1..F7 */
+           case F1Key:  case F2Key:   case F3Key:
+           case F4Key:  case F5Key:   case F6Key:
+           case F7Key:  DispAndSetMode(c-F1Key); break;
+
+           case HELPKEY: HelpMe(); break;
+               
+           /* Turn cursor On/Off  */
+           case F8Key: TogCursor(); break; 
+           
+           /* Show/Hide Title Bar */
+           case F9Key: TogTitle(); break;
+           
+           /* Show/Hide Graphics Menu (Control panel) */
+           case F10Key: TogBoth(); break;
+           
+           /* Scroll Window contents  with Arrow keys */
+           case CLeft: scrollKeys(pn,1,0); break;
+           case CRight: scrollKeys(pn,-1,0); break;
+           case CUp: scrollKeys(pn,0,1); break;
+           case CDown: scrollKeys(pn,0,-1); break;
+           }
+       break;
+       }
+    LoadIMode(); /* incase overlay happened */
+    if (svpnt) UpdtON(); else UpdtOFF();
+    PaneFakeMove(); /* make sure the feedback is turned back on*/
+    }
+
diff --git a/CLIP.C b/CLIP.C
new file mode 100644 (file)
index 0000000..93f89af
--- /dev/null
+++ b/CLIP.C
@@ -0,0 +1,214 @@
+/*--------------------------------------------------------------*/
+/*                                                             */
+/*                       CLIP.C                                */
+/*                                                             */
+/*     Provides a clipping interface to the Amiga area fill.   */
+/*     Uses a modified verion of the Sutherland-Hodgman        */
+/*     Reentrant Polygon Clipper.                              */
+/*                                                             */
+/*     ClipInit(xmin,ymin,xmax,ymax)   -- sets clip box        */
+/*     ClipDraw        -- corresponds to AreaDraw              */
+/*     ClipMove        -- corresponds to AreaMove              */
+/*     ClipEnd         -- corresponds to AreaEnd               */
+/*                                                             */
+/*     Dan Silva 3-6-85  created                               */
+/*     "         3-10-85 changed to 2-stage from 4-stage       */
+/*                       to speed up.                          */
+/*                                                             */
+/*             Copyright 1985, Electronic Arts                 */
+/*--------------------------------------------------------------*/
+
+#include "system.h"
+
+
+/* #define dbgClip */
+
+#define YES  1
+#define NO   0
+#define NIL  0
+#define local static
+
+typedef char Boolean;
+typedef struct { int x,y; } Point;
+
+typedef struct {
+    short lastcode,isFirst,fcode;
+    Point last,f;
+    } clrec;
+    
+local clrec ud = {0,YES,0,{0,0},{0,0}};
+local clrec rl = {0,YES,0,{0,0},{0,0}};
+
+local struct RastPort *clrp;
+
+/* ------ clipping box -------*/
+local short clxmin = 0;
+local short clymin = 0;
+local short clxmax = 319;
+local short clymax = 199;
+local short anyOutput = NO;
+
+
+local ClipUD(x,y) int x,y; {
+    short code = 0;
+    short xp,yclip;
+#ifdef dbgClip
+    printf("ClipUD x= %d, y = %d\n",x,y);
+#endif
+    if (y<clymin) code|= 1; else if (y>clymax)  code |= 2;
+    if (ud.isFirst) {
+       ud.f.x = x; ud.f.y = y;
+       ud.fcode = 0;
+       ud.isFirst = NO;
+       }
+    else {
+       if (!(code|ud.lastcode)) ClipRL(x,y,0);  /* trivial accept */
+       else if (!(code&ud.lastcode)) {   /* --cant reject-- */
+           if (ud.lastcode) { /* last point was out of bounds */
+               yclip = (ud.lastcode&1)?clymin: clymax;
+               xp = ud.last.x + (yclip-ud.last.y)*(x-ud.last.x)/(y-ud.last.y);
+               ClipRL(xp,yclip,ud.lastcode);
+               }
+           xp = x; yclip = y;
+           if (code) {  /*---- this point is out---- */
+               yclip = (code&1)?clymin: clymax;
+               xp = ud.last.x + (yclip-ud.last.y)*(x-ud.last.x)/(y-ud.last.y);
+               }
+           ClipRL(xp,yclip,code);
+           }
+       }
+    ud.last.x = x;
+    ud.last.y = y;
+    ud.lastcode = code;
+    }
+
+local short lastrlcode;
+
+local ClipRL(x,y,udcode) 
+    int x,y;           /* point clipped by UD */
+    short udcode;      /* records how it was clipped by UD */
+    {
+    short code = 0;
+    short yp,xclip,lcode,ocode;
+#ifdef dbgClip
+    printf("ClipRL x= %d, y = %d, code = d\n",x,y,udcode);
+#endif
+    if (x<clxmin) code|= 4; else if (x>clxmax)  code |= 8;
+    if (rl.isFirst) {
+       rl.f.x = x; rl.f.y = y;
+       rl.fcode = udcode;
+       rl.isFirst = NO;
+       }
+    else {
+       if (!(code|lastrlcode)) Output(x,y,udcode);  /* trivial accept */
+       else if (!(code&lastrlcode)) 
+           {/* ---- cant reject ----- */
+           lcode = rl.lastcode&udcode;
+           if (lastrlcode) { /* last point was out of bounds */
+               xclip = (lastrlcode&4)?clxmin: clxmax;
+               yp = rl.last.y+(xclip-rl.last.x)*(y-rl.last.y)/(x-rl.last.x);
+               Output(xclip,yp,lcode|lastrlcode);
+               }
+           yp = y; xclip = x; ocode = udcode;
+           if (code) {  /* ----- this point is out -----*/
+               xclip = (code&4)?clxmin: clxmax;
+               ocode = lcode|code;
+               yp = rl.last.y + (xclip-rl.last.x)*(y-rl.last.y)/(x-rl.last.x);
+               }
+           Output(xclip,yp,ocode);
+           }
+       }
+    rl.last.x = x;
+    rl.last.y = y;
+    rl.lastcode = udcode;
+    lastrlcode = code;
+    }
+
+
+/*---- the final stage: output the points to the area fill */
+
+local Boolean lastOutCode;
+local Point first;
+local short firstCode;
+
+
+local Output(x,y,incode) int x,y,incode; {
+    short saveState;
+#ifdef dbgClip
+    printf("Output x= %d, y = %d, code = %d\n",x,y,incode);
+#endif
+    if (!anyOutput) { 
+       AreaMove(clrp,x,y); 
+       anyOutput= YES; 
+       first.x = x;
+       first.y = y;
+       firstCode = incode;
+       }
+    else 
+       {
+       if ((lastOutCode&incode))
+           { /* "virtual" edges--ie along screen boundary */
+           saveState = clrp->Flags&AREAOUTLINE;
+           clrp->Flags &= ~AREAOUTLINE;
+           AreaDraw(clrp,x,y);
+           clrp->Flags |= saveState;
+           }
+       else AreaDraw(clrp,x,y);
+       }
+    lastOutCode = incode;
+    }
+
+local Close() {
+#ifdef dbgClip
+    printf(" Close\n");
+#endif
+    if (!ud.isFirst) ClipUD(ud.f.x,ud.f.y);
+    if (!rl.isFirst) ClipRL(rl.f.x,rl.f.y,rl.fcode);
+    if (anyOutput) Output(first.x,first.y,firstCode);
+    ud.isFirst = rl.isFirst = YES;
+    anyOutput = NO;
+    }
+
+/* ---------- Interface to Outside World -------------*/
+
+ClipInit(xmin,ymin,xmax,ymax) short xmin,ymin,xmax,ymax;
+    {
+    clxmin = xmin;    clymin = ymin;    
+    clxmax = xmax;    clymax = ymax;
+    }
+
+local short drawYet = NO;
+
+ClipDraw(rp,x,y) struct RastPort *rp; short x,y; {
+#ifdef dbgClip
+    printf(" ClipDraw: x = %d, y = %d\n",x,y);
+#endif
+    clrp = rp;
+    ClipUD(x,y);
+    drawYet = YES;
+    }
+
+ClipMove(rp,x,y) struct RastPort *rp; short x,y; {
+#ifdef dbgClip
+    printf(" ClipMove: x = %d, y = %d\n",x,y);
+#endif
+    if (drawYet) Close(); else { ud.isFirst = rl.isFirst = YES; }
+    clrp = rp;
+    ClipUD(x,y);
+    drawYet = NO;
+    }
+
+ClipEnd(rp) struct RastPort *rp; {
+    BOOL wasAny = anyOutput;
+#ifdef dbgClip
+    printf(" Clip END -----------------------\n");
+#endif
+    
+    if (drawYet)  Close();
+    WaitBlit();
+    if (wasAny) AreaEnd(rp);
+    drawYet = NO;
+    }
+
+static short dum;
+static short dum2 = 0;
diff --git a/CONIC.C b/CONIC.C
new file mode 100644 (file)
index 0000000..857465b
--- /dev/null
+++ b/CONIC.C
@@ -0,0 +1,238 @@
+/*-------------------------------------------------------------        */
+/*                                                             */
+/*                     Conic Curves                            */
+/*                                                             */
+/*-------------------------------------------------------------        */
+
+#include <system.h>
+#include <prism.h>
+
+#define local static
+
+extern SHORT xShft, yShft;
+extern void (*CurPWritePix)();
+extern void (*curfunc)();
+extern void quadpts();
+extern SHORT xcen,ycen;
+
+/* table of move increments */
+typedef struct { SHORT dx1,dy1,dx2,dy2;} movRec;
+
+BOOL cncdbg = NO;
+               
+local movRec moves[8] = {
+    { 1, 0, 1, 1},
+    { 0, 1, 1, 1},
+    { 0, 1,-1, 1},
+    {-1, 0, -1, 1},
+    {-1, 0, -1,-1},
+    { 0,-1,-1, -1},
+    { 0,-1, 1, -1},
+    { 1, 0, 1,-1}
+    };
+
+local movRec cmv;
+local BYTE nxtdiag[8] = {1,0,3,2,5,4,7,6};
+local BYTE nxtsq[8]   = {7,2,1,4,3,6,5,0};
+local SHORT octchgs;
+local LONG w,a,b,d,k1,k2,k3;
+local SHORT eps = 1;
+    
+typedef union{
+    LONG l;
+    struct { SHORT hi,lo;} wrd;
+    } LongInt;
+
+BYTE curoct;
+BYTE octTab[8] = {0,1,3,2,7,6,4,5};
+
+#define NFRAC  4
+#define scale(foo)     (foo<<NFRAC)
+#define ival(foo) ( (SHORT) (foo>>NFRAC))
+LONG longone = 0x100;
+
+LONG LF(i) SHORT i; {
+    LongInt lf;
+    lf.wrd.lo = 0;
+    lf.wrd.hi = i;
+    return(lf.l);
+    }
+     
+LONG lngtmp;
+#define lswap(a,b) {lngtmp = a; a = b; b = lngtmp; }
+#define neg(a)  (a = -a)
+
+/*
+static prstate() {
+    if (cncdbg)
+  printf("oct=%d, k1=%d, k2=%d, k3=%d, b=%d, a=%d,d=%d \n",
+       curoct,ival(k1),ival(k2),ival(k3),ival(b),ival(a),ival(d));
+    }
+*/     
+
+          
+sqOctChange() {
+    curoct = nxtsq[curoct];
+    cmv = moves[curoct]; 
+    w = k2-k1;
+    k1 = -k1;
+    k2 = k1+w;
+    k3= 4*w-k3;
+    b = -w-b;
+    d = b-a-d;
+    a -= 2*b+w;
+    }
+
+diagOctChange() {
+    curoct = nxtdiag[curoct];
+    cmv = moves[curoct]; 
+    w = 2*k2-k3;
+    k1 = w-k1;
+    k2 -= k3;
+    k3 = -k3;
+    b += a - (k2>>1);
+    d = b -(a>>1) -d +(k3>>3);
+    a = (w>>1)-a;
+    }
+    
+#define cabs(foo) (( (tmp=(foo)) > 0 ) ? tmp : -tmp )    
+
+/*--------------------------------------------------------------*/
+/* plot general conic whose equation is                                */
+/*    alpha*y*y + beta*x*x + 2*gamma*x*y + 2*u*y -2*v*x = 0;   */
+/* the curve is displaced so that (0,0) maps to (x0,y0)                */
+/*--------------------------------------------------------------*/
+    
+void Conic(alpha,beta,gamma,u,v,x0,y0,x1,y1,func,maxoct,tol)
+    LONG alpha,beta,gamma,u,v;
+    SHORT x0,y0;               /* starting point*/
+    SHORT x1,y1;               /* stopping point*/
+    SHORT (*func)();           /* function to call */
+    SHORT maxoct;              /* limit on number of octant changes */
+    SHORT tol;                 /* tolerance for termination test */
+    {
+    SHORT x,y,tmp;
+    x = x0; y = y0; 
+/*
+    if (cncdbg)  printf("alpha =%d, beta= %d, gamma= %d, u= %d, v= %d \n",
+       ival(alpha),ival(beta),ival(gamma),ival(u),ival(v));
+*/
+    curoct = 0;
+    if (v<0) curoct += 4;
+    if (u<0) curoct += 2;
+    if (ABS(v)>ABS(u)) {curoct+=1; lswap(alpha,beta); lswap(u,v); neg(gamma);}
+    curoct = octTab[curoct];
+    if (curoct&1) { neg(beta); neg(alpha); }
+    if ((curoct>2)&&(curoct<7)) neg(u); 
+    if (curoct>3) neg(v);  if ( (curoct&3) == 2 ) neg(v); 
+    k1 = 2*beta;
+    k2 = k1 + 2*gamma;
+    k3 = 2*alpha + 2*gamma + k2;
+    b = 2*v - beta - gamma;
+    a = 2*u - b;
+    d = b - u - (alpha>>2);
+    cmv = moves[curoct]; 
+    octchgs = 0;
+    (*func)(x,y);
+    for (;;) {
+       if (d<0){  /* move 1 */
+           x += cmv.dx1; y += cmv.dy1;
+           b -=  k1;     a +=  k2;       d +=  b;
+           } 
+       else {   /* move 2 */
+           x += cmv.dx2; y += cmv.dy2;
+           b -=  k2;     a +=  k3;       d -=  a;
+           }
+       (*func)(x,y);
+       if ((cabs(x-x1)<tol)&&(cabs(y-y1)<tol)) break;
+       if (b<0) { sqOctChange(); if ((++octchgs)>maxoct) break;}
+       else if (a<0) { diagOctChange(); if ((++octchgs)>maxoct) break;}
+       if (CheckAbort()) return;
+       }
+    if ((x!=x1)||(y!=y1)) (*func)(x1,y1);
+    }
+
+
+/*--------------------------------------------------------------*/
+/*  Conic Curve given start point, stop point, and middle point */
+/* which defines the tangents at the start and stop point      */
+/*--------------------------------------------------------------*/
+PCurve(x0,y0,x1,y1,x2,y2,lam,func) 
+    SHORT x0,y0,x1,y1,x2,y2;
+    USHORT lam;  /* 8 bit binary fraction between 0 and 1 */
+    SHORT (*func)();
+    {
+    LONG a1,a2,a3,b1,b2,b3,det,lambda,alam,halam;
+    LONG alpha,beta,gamma,u,v;
+/*
+    if (cncdbg) printf("conic x0=%d,y0=%d,x1=%d,y1=%d,x2=%d,y2=%d \n",
+           x0,y0,x1,y1,x2,y2);
+
+*/
+    lambda =  lam;
+    alam = longone - lambda;
+    halam = alam>>1;
+    a1 = y0-y1; b1 = x1-x0;
+    a2 = y2-y1; b2 = x1-x2;
+    a3 = y2-y0; b3 = x0-x2;
+    det = a1*b3 - a3*b1;
+/*    if (cncdbg) printf(" det = %u|%d \n",det); */
+    if (det==0) 
+       { alpha = beta = gamma = (LONG) 0 ; u = -scale(b3); v = scale(a3); }
+    else {
+       alpha = alam*b1*b2 + lambda*b3*b3;
+       beta = alam*a1*a2 + lambda*a3*a3;
+       gamma = halam*(a1*b2+a2*b1) + lambda*a3*b3;
+       u = halam*(b1*det);
+       v = -halam*(a1*det);
+       if (det<0) { neg(alpha); neg(beta); neg(gamma); neg(u); neg(v); }
+       }
+    Conic(alpha,beta,gamma,u,v,x0,y0,x2,y2,func,8,2);
+    }
+    
+void PEllpsWith(xc,yc,a,b,func) SHORT xc,yc,a,b; SHORT (*func)(); {
+    LONG alpha,beta,gamma,u,v;
+    if ((a<2)||(b<2)) return;
+    alpha = scale(((LONG)a)*((LONG)a));
+    beta =  scale(((LONG)b)*((LONG)b));
+    gamma = (LONG)0;
+    u = ((LONG)b)*alpha;
+    v = (LONG)0;
+    Conic(alpha,beta,gamma,u,v,xc,yc+b,xc,yc+b,func,8,1);
+    }
+
+/* traverse 1 quadrant of ellipse, calling "func" at each point */
+void PQEllps(xc,yc,a,b,func) SHORT xc,yc,a,b; SHORT (*func)(); {
+    LONG alpha,beta,gamma,u,v;
+    if ((a<1)||(b<1)) return;
+    alpha = scale(((LONG)a)*((LONG)a));
+    beta =  scale(((LONG)b)*((LONG)b));
+    gamma = (LONG)0;
+    u = ((LONG)b)*alpha;
+    v = (LONG)0;
+    xcen = xc;
+    ycen = yc;
+    Conic(alpha,beta,gamma,u,v,0,b,a,0,func,3,2);
+    }
+
+PQEllpsWith(xc,yc,a,b,func) SHORT xc,yc,a,b; void (*func)(); {
+    curfunc = func;
+    PQEllps(xc,yc,a,b, &quadpts); 
+    }
+
+/* fast 1 dot thick ellipse */
+PEllpse(xc,yc,a,b) SHORT xc,yc,a,b; {
+    curfunc = CurPWritePix;
+    PQEllps(xc,yc,a,b, &quadpts); 
+    }
+
+static SHORT qfill(x,y) SHORT x,y; {
+    SHORT w = 2*x+1;
+    PatHLine(xcen-x,ycen+y,w);
+    PatHLine(xcen-x,ycen-y,w);
+    }
+    
+PFillEllps(xc,yc,a,b) SHORT xc,yc,a,b; {  PQEllps(xc,yc,a,b,qfill);  }
+
+
+
diff --git a/CTRPAN.C b/CTRPAN.C
new file mode 100644 (file)
index 0000000..aef59c9
--- /dev/null
+++ b/CTRPAN.C
@@ -0,0 +1,528 @@
+/*--------------------------------------------------------------*/
+/*                                                             */
+/*        ctrpan.c  -- graphics control panel                  */
+/*                                                             */
+/*--------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+extern void ToglMagw();
+extern void (*nop)();
+
+extern struct Window *mainW;
+extern Box bigBox, mainBox, screenBox;
+extern struct RastPort screenRP,tempRP;
+extern BOOL symON,gridON,magOn;
+extern SHORT nColors, solidpat[];
+extern SHORT xShft, yShft, curDepth,curFormat;
+extern struct TmpRas tmpRas;
+extern SHORT curIMode, lastPermMode;
+extern IModeDesc imodes[];
+       
+extern SHORT act1[],act2[],act3[],act4[],act5[],act6[],act7[];
+extern SHORT act8[],act9[],act10[],act11[],act12[],act13[],act14[];
+extern SHORT act15[],act16[],act17[],act18[];
+extern SHORT act5H[],act5F[];
+extern SHORT act6H[],act6F[];
+extern SHORT act7H[],act7F[];
+extern SHORT act8H[],act8F[];
+extern SHORT penmenu[];
+    
+SHORT *actbm[18] = {act1,act2,act3,act4,act9,act10,act5,act6,act7,act8,
+    act11,act12,act13,act14,act15,act16,act17,act18};
+
+SHORT *acthbm[4] = {act5H,act6H,act7H,act8H};
+SHORT *actfbm[4] = {act5F,act6F,act7F,act8F};
+
+#define local
+
+#define BLACK 0
+
+/* Dimensions of activity menu */
+#define actNPL 2
+
+/* Dimensions of Pen Menu*/
+#define penNPL 3
+
+/* Dimensions of Color Pallet*/
+
+SHORT actUH = 24;
+SHORT colNColumns = 4;
+SHORT colNRows = 8;
+SHORT colUH = 6;
+SHORT colDspH = 12;
+SHORT cpWidth,actUW,colUW,penUW;
+SHORT penH,actH;
+
+#define noActBut  128
+
+/*************************************************/
+/* initialize Panes for debugging purposes */
+Pane  penwin={0},actwin={0},cdspwin={0},colwin={0}; 
+SHORT cpfgcol=-1,cpbgcol,activity,cpPen;
+UBYTE actBut = noActBut;
+BOOL  cpShowing;
+
+extern void CPInvAct();
+
+/** Dummy Calls **/
+extern void mainCproc();
+/*============== utilities===================== */
+
+ScreenDest() {  PushGrDest(&screenRP,&screenBox); }
+
+XorScreenBox(bx) Box *bx; {
+    ScreenDest();
+    SetAPen(&screenRP,1);
+    SetXorFgPen(&screenRP);
+    PFillBox(bx);
+    SetDrMd(&screenRP,JAM2);
+    PopGrDest();
+    }
+
+ColorBox(b,c) Box *b;SHORT c; {
+    ScreenDest();
+    TempMode(Replace,c,solidpat);
+    PFillBox(b);
+    RestoreMode();
+    PopGrDest();
+    }
+
+
+local SHORT downIn;
+local SHORT cpButton;
+SHORT NXMag, NYMag;
+
+/*--------------------------------------------------------------*/
+/*        Pen Menu                                             */
+/*--------------------------------------------------------------*/
+#ifdef thisIsInPrism_H
+#define ROUND_B                1
+#define SQUARE_B       2
+#define DOT_B          3
+#define RoundB(n)      ((ROUND_B<<12)|n)
+#define SquareB(n)     ((SQUARE_B<<12)|n)
+#define DotB(n)                ((DOT_B<<12)|n)
+#endif
+
+
+typedef struct {BYTE x,y,w,h; } ByteBox;
+
+#define NPenBoxes 10
+
+/* these coordinates are in VDC */
+ByteBox penBoxes[NPenBoxes] = {
+    {0,0,8,12}, {8,0,10,12}, {18,0,12,14}, {30,0,14,14},
+    {0,14,14,12}, {14,14,12,12}, {26,14,10,10}, {34,14,10,8},
+    {4,26,14,12}, {23,25,22,14}
+    };
+
+
+SHORT penNums[NPenBoxes] = {
+    0,RoundB(1),RoundB(2), RoundB(3),
+    SquareB(5),SquareB(4),SquareB(3),SquareB(2),
+    DotB(1),DotB(2)
+    };
+    
+local void xorPenBox(n) int n; {
+    Box bx;
+    ByteBox *byb;
+    if (!cpShowing) return;
+    if ((n < 0)|| (n>10)) return;
+    byb = &penBoxes[n];
+    bx.x = PMapX(byb->x+2) + penwin.box.x;
+    bx.y = PMapY(byb->y+2) + penwin.box.y;
+    bx.w = PMapX(byb->w);
+    bx.h = PMapY(byb->h);
+    XorScreenBox(&bx);
+    }
+
+Box *BoxFrByteBox(bx,bbx) Box *bx; ByteBox *bbx; {
+    return((Box *)MakeBox(bx,bbx->x,bbx->y,bbx->w,bbx->h));
+    }
+    
+BOOL InByteBox(bbx,x,y)  ByteBox *bbx; SHORT x,y; {
+    Box bx;
+    return((BOOL)BoxContains(BoxFrByteBox(&bx,bbx),x,y));
+    }
+    
+local int GetPenBox(x,y) SHORT x,y; {
+    int i;
+    x = VMapX(x)-2;
+    y = VMapY(y)-4;
+    for (i=0; i<NPenBoxes; i++)  if ( InByteBox(&penBoxes[i], x, y) )
+       return(i);
+    return(-1);
+    }
+
+
+local SHORT penForXY(x,y) SHORT x,y; { return(penNums[GetPenBox(x,y)]); }
+   
+local penMproc(ph,why,but,x,y) Pane *ph; MouseEvent why; SHORT but,x,y; {
+    SHORT pNum,n;
+    n = GetPenBox(x,y);
+    switch(why) {
+       case BDOWN: cpButton = but; downIn = n; xorPenBox(n); break;
+       case BUP: xorPenBox(downIn); 
+           if (downIn>=0) {
+               pNum = penNums[downIn];
+               if (cpButton==1) CPChgPen(pNum);
+               else SizePen(pNum);
+               }
+           break;
+       }
+    }
+
+BoxForPen(pn) SHORT pn; {
+    int i;
+    for (i=0; i<NPenBoxes; i++) if (pn == penNums[i]) return(i);
+    return(-1);
+    }
+
+SHORT cpPenBox = -1;    
+       
+/* new is a pen# */
+CPChgPen(new) SHORT new; {    
+    xorPenBox(cpPenBox); 
+    cpPen = new;
+    cpPenBox = BoxForPen(new);
+    xorPenBox(cpPenBox);
+    if (cpPen!=USERBRUSH) if ((curIMode==IM_null)||(imodes[lastPermMode].flags&NOBR))
+       NewIMode(IM_shade);
+    SelPen(new);
+    }
+
+#define PENMENUW 25
+#define PENMENUH 20
+
+void PenWPaint()  {
+    struct BitMap tmp;
+    Box sbx;
+    InitBitMap(&tmp,1,PENMENUW,PENMENUH);
+    tmp.Planes[0] = (PLANEPTR)penmenu;
+    if (!cpShowing) return;
+    penwin.box.y = mainBox.y;
+    penwin.box.x = screenBox.w - cpWidth;
+    ColorBox(&penwin.box, BLACK);
+    MagBits(&tmp, MakeBox(&sbx,0,0,PENMENUW,PENMENUH), screenRP.BitMap,
+       penwin.box.x, penwin.box.y, NXMag,NYMag,&screenBox);
+    xorPenBox(cpPenBox);
+    }
+
+
+/*--------------------------------------------------------------*/
+/*        Activity Menu                                                */
+/*--------------------------------------------------------------*/
+
+#define NACTBUTS 18
+
+Delay(n) SHORT n; { SHORT i; for (i=0; i<500*n; i++) {} }
+
+    
+BOOL LRButton = NO;
+local BOOL LSide;
+local ActButton(but,i) SHORT but,i; {
+    BOOL doLeft = (LRButton)? (but==1) : LSide;
+    switch(i) {
+       case 0:  NewIMode(IM_shade); break;
+       case 1:  NewIMode(IM_draw); break;
+       case 2:  NewIMode(IM_vect); break;
+       case 3:  NewIMode(IM_curve1); break;
+       case 4:  NewIMode(IM_fill); break;    
+       case 5:  if (but==1) NewIMode(IM_airBrush); 
+               else SizeAirBrush();  break;    
+       case 6:  NewButIMode(doLeft ? IM_rect:IM_frect, cpButton); break;    
+       case 7:  NewButIMode(doLeft ? IM_circ:IM_fcirc, cpButton); break;
+       case 8:  NewButIMode(doLeft ? IM_oval:IM_foval, cpButton); break;    
+       case 9:  NewButIMode(doLeft ? IM_poly:IM_fpoly, cpButton); break;    
+       case 10: if (but==1) NewIMode(IM_selBrush); 
+               else {  CPInvAct(selbAct);   UserBr();   
+                       Delay(5);    CPInvAct(selbAct);
+                   }   break;
+       case 11: NewIMode(IM_text1); break;    
+       case 12: if (but==1) TogGridSt(); else NewIMode(IM_gridSpec); break;    
+       case 13: if (but==1) TogSymSt(); else DoSymReq(); break;    
+       case 14: ToglMagw();  break;    
+       case 15: MWZoom( (but==1)? 1: -1 ); break;
+       case 16: Undo();  break;    
+       case 17: mClearToBg(); break;
+       }
+    }
+
+extern void xorActBut();
+
+/* Im not quite sure why I need (y-1) here but it works */
+
+local SHORT actBoxForXY(x,y) SHORT x,y; { 
+       return((SHORT)(MIN(x,cpWidth-2)/actUW+((y-1)/actUH)*actNPL)); }
+    
+local actMproc(ph,why,but,x,y) Pane *ph; MouseEvent why; SHORT but,x,y; {
+       SHORT n = actBoxForXY(x,y);
+       switch(why) {
+           case BDOWN: cpButton = but; downIn = n; 
+               LSide = (VMapX(x)%24) + (VMapY(y-NYMag)% 24)< 24; xorActBut(n); 
+               break;
+           case BUP: xorActBut(downIn);  
+               ActButton(cpButton,downIn);
+               break;
+       }
+    }
+
+
+/* the "n" here is button number, not activity */
+actX(n) SHORT n; { return(actwin.box.x + NXMag + actUW*(n%actNPL)); }
+actY(n) SHORT n; { return(actwin.box.y + NYMag + actUH*(n/actNPL)); }
+
+#define actPUH 12
+#define actPUW  12
+               
+DispActBut(pic,n)
+    UBYTE *pic;  /* pointer to the bits to be diplayed */
+    int n;     /* button # */
+    {  
+    int x,y;
+    Box sbx;
+    struct BitMap tmp;
+    InitBitMap(&tmp,1,11,11);
+    tmp.Planes[0] = pic;
+    SetDrMd(&screenRP,JAM2);
+    x = actX(n); y = actY(n);
+    MagBits(&tmp,MakeBox(&sbx,0,0,11,11), screenRP.BitMap,
+       x, y, NXMag,NYMag,&screenBox);
+    }
+   
+
+/* #define slowway  */
+
+#ifdef slowway
+DispActMenu() {
+    SHORT i;
+    ColorBox(&actwin.box, BLACK);
+    for (i=0; i< NACTBUTS; i++ ) DispActBut(actbm[i],i);
+    }
+#endif
+
+#ifdef DBGCP
+SHORT dbgcp = NO;
+tstbm(bm) struct BitMap *bm; {
+    SHORT w,h;
+    w = bm->BytesPerRow*8;
+    h = bm->Rows;
+    SetAPen(&screenRP,0);
+    RectFill(&screenRP,0,20, w-1, 20 + h - 1);
+    BltBitMap(bm,0,0,screenRP.BitMap,0,20,w,h,REPOP,0xff,NULL);
+    }
+#endif
+
+void DispActMenu() {
+    SHORT i; Box sbx;
+    struct BitMap tmp;
+    SHORT h = actPUH*NACTBUTS/actNPL;
+    InitBitMap(&tmp,1,32,h);
+    if (tmpRas.RasPtr==NULL) return;
+    tmp.Planes[0] = tmpRas.RasPtr;
+    ColorBox(&actwin.box,BLACK); 
+    ClearBitMap(&tmp);
+    tempRP.BitMap = &tmp;
+    SetDrMd(&tempRP,JAM2);
+    SetAPen(&tempRP,1);
+    for (i=0; i< NACTBUTS; i++ ) {
+       BltTemplate(actbm[i],0,2,&tempRP,
+           actPUW*(i%actNPL)+1, actPUH*(i/actNPL)+1, 11, 11);
+       }
+    MagBits(&tmp,MakeBox(&sbx,0,0,25,h), screenRP.BitMap,
+       actwin.box.x, actwin.box.y, NXMag, NYMag, &screenBox);
+    WaitBlit();
+    }
+
+void xorActBut(but) SHORT but; {
+    Box bx;
+    if (!cpShowing) return;
+    if (but==noActBut) return;
+    XorScreenBox(MakeBox(&bx,actX(but),actY(but),actUW-NXMag,actUH-NYMag));
+    }
+    
+/* two different activities are now associated with one button */
+/* given an activity, determine the button # by the following: */
+/* bit 5 denotes left button activity, bit 6 denotes right button*/
+#define LBACT 32
+#define RBACT 64
+    
+UBYTE butForAct[] = {
+       noActBut,0,1,2,3,4,5,32+6,64+6,32+7,64+7,32+8,64+8,32+9,64+9,
+       10,11,12,13,14,15,16,17 };
+
+void CPInvAct(act) SHORT act; { xorActBut((SHORT)butForAct[act]); }
+
+void CPShowBut(abut) SHORT abut; {
+    SHORT butN;
+    if (!cpShowing) return;
+    if (abut==noActBut) return;
+    butN = abut&0x1f;
+    if (abut&LBACT) DispActBut(acthbm[butN-6], butN); 
+    else {
+       if (abut&RBACT) DispActBut(actfbm[butN-6], butN);
+       else xorActBut(butN);
+       }
+    }
+    
+void CPClearBut()  {
+    SHORT butN;
+    if (!cpShowing) return;
+    if (actBut==noActBut) return;
+    butN = actBut&0x1f;
+    if ((actBut&(LBACT|RBACT)))        DispActBut(actbm[butN], butN);
+    else xorActBut(butN);
+    }
+       
+void CPChgAct(new) SHORT new; {    
+    if (new==activity) return;
+    CPClearBut(); 
+    activity = new;
+    actBut = butForAct[new];
+    CPShowBut(actBut);
+    }
+
+    
+CPShowAct(act) { CPShowBut(butForAct[act]); }
+    
+void ActWPaint() {
+    if (!cpShowing) return;
+    actwin.box.y = mainBox.y + penH;
+    actwin.box.x = screenBox.w - cpWidth;
+    DispActMenu();
+    if (gridON) CPShowAct(gridAct);
+    if (symON) CPShowAct(symAct);
+    if (magOn) CPShowAct(magAct);
+    CPShowBut(actBut);
+    }
+
+
+/*--------------------------------------------------------------*/
+/*      Current  Color Display                                 */
+/*--------------------------------------------------------------*/
+local void cDspMproc(ph,why,but,x,y) Pane *ph; MouseEvent why; SHORT but,x,y; {
+    if (why == BUP) if (but==2) ShowPallet();
+    else  NewIMode(IM_readPix);
+    }
+
+local void cDspPaint()  {
+    SHORT x,y; Box bx;
+    if (!cpShowing) return;
+    cdspwin.box.y = mainBox.y + penH + actH;
+    cdspwin.box.x = screenBox.w - cpWidth;
+    ColorBox(&cdspwin.box, BLACK);
+    ScreenDest();
+    x = cdspwin.box.x;
+    y = cdspwin.box.y;
+    TempMode(Replace,cpbgcol,solidpat);
+    PFillBox(MakeBox(&bx,x+1,y+1,cpWidth-2,PMapY(24)-1));
+    SetFGCol(cpfgcol);
+    PFillCirc(x+(cpWidth-1)/2,y+PMapY(12),cpWidth/6);
+    RestoreMode();
+    PopGrDest();
+    }
+
+
+/*--------------------------------------------------------------*/
+/*        Color Menu                                           */
+/*--------------------------------------------------------------*/
+
+/*--- Paint the Color menu --------------------*/
+
+void XorCol() {
+    Box bx;
+    if  (!cpShowing) return;
+    bx.x = (cpfgcol/colNRows)*colUW + colwin.box.x;
+    bx.y = (cpfgcol%colNRows)*colUH + colwin.box.y;
+    bx.w = colUW+1;
+    bx.h = colUH+1;
+    ScreenDest();
+    SetAPen(&screenRP,1);
+    TempXOR();
+    PThinFrame(&bx);
+    RestoreMode();
+    PopGrDest();
+    }
+
+void ColWPaint(ph,b) Pane *ph; Box *b; {
+    SHORT pn,x,y,i,j;
+    Box bx;
+    if (!cpShowing) return;
+    colwin.box.y = mainBox.y + penH + actH + colDspH;
+    colUH = (screenBox.h - colwin.box.y)/colNRows;
+    colwin.box.x = screenBox.w - cpWidth;
+    ColorBox(MakeBox(&bx,colwin.box.x,colwin.box.y,colwin.box.w,
+       colwin.box.h), BLACK);
+    x=colwin.box.x+1;
+    y=colwin.box.y+1;
+    pn = 0;
+    bx.w = colUW-1;  
+    bx.h = colUH-1;   
+    bx.x = x;
+    ScreenDest();
+    SetDrMd(&screenRP,JAM2);
+    for (j=0; j<colNColumns; j++) {
+       bx.y = y;
+       for (i=0; i<colNRows; i++) {
+           SetFGCol(pn++);
+           PFillBox(&bx);
+           bx.y += colUH;
+           }
+       bx.x += colUW;
+       }
+    PopGrDest();
+    XorCol();
+    }
+
+    
+local int colForXY(x,y) SHORT x,y; { 
+    return(MIN(y,colUH*colNRows-1)/colUH+(MIN(x,cpWidth-2)/colUW)*colNRows);  
+    }
+       
+local ColNewXY(button,x,y) SHORT button,x,y;{
+    SHORT item = colForXY(x,y);
+    if (button==1) if (item != cpfgcol)  CPChgCol(item);  else;
+    else if (item!= cpbgcol) CPChgBg(item); 
+    }
+
+local colMproc(ph,why,but,x,y) Pane *ph; MouseEvent why; SHORT but,x,y; {
+    if (why == BDOWN) { ColNewXY(but,x,y);
+           if (but==1) SetFGCol(cpfgcol); else  SetXPCol(cpbgcol);
+           }
+   }
+
+CPChgCol(new) SHORT new;{ 
+    SetFGCol(new); 
+    if (new!=cpfgcol) {
+       if (cpfgcol>=0) XorCol();
+       cpfgcol = new;
+       cDspPaint();
+       XorCol();
+       }
+    SetCycPaint(); /* keep the current cycle up to date */
+    }
+    
+CPChgBg(new) SHORT new; { if (new<nColors) {SetXPCol(cpbgcol=new); 
+       cDspPaint();}
+    }
+
+/* ------------------------- */
+InstCP() {
+    PaneInstall(&penwin); 
+    PaneInstall(&actwin); 
+    PaneInstall(&cdspwin);
+    PaneInstall(&colwin);
+    cpShowing = YES;
+    } 
+
+RmvCP()  {
+    PaneRemove(&penwin);  
+    PaneRemove(&actwin);  
+    PaneRemove(&cdspwin);
+    PaneRemove(&colwin);
+    cpShowing = NO;
+    }
+
+ShowCtrPan(st) BOOL st; { if (st!=cpShowing) TogBoth(); }
diff --git a/CURBRUSH.C b/CURBRUSH.C
new file mode 100644 (file)
index 0000000..c1bde47
--- /dev/null
@@ -0,0 +1,170 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*        curbrush.c -- The current brush & pen                                */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+#include <system.h>
+#include <prism.h>
+
+extern short xShft, yShft;
+extern Box screenBox;
+extern SHORT prevColors[];
+extern SHORT LoadBrColors[32];
+extern struct BitMap brBM,brSVBM;
+extern BMOB curbr;
+extern SHORT curpen;
+extern struct BitMap penBM,penSVBM;
+extern BMOB curpenob;
+extern BOOL modeHelp;
+
+#define local static 
+
+BOOL LegalMode(i) int i; {
+    if (modeHelp)
+       return((BOOL)! ( (curpen!=USERBRUSH) && ((i==Mask)||(i==Replace)) ) );
+    else  return((BOOL)YES);
+    }
+
+BOOL BrushDefined() { return((BOOL)(curbr.pict.bm->Planes[0] != NULL)); }
+
+UseBrPalette() { if (curpen==USERBRUSH) {
+       GetColors(prevColors);
+       LoadCMap(LoadBrColors);
+       }
+    }
+    
+/* Pens have only a MASK and no source bit-planes.  FixUpPen
+   fixes pen data structure to reflect this */
+local FixUpPen() {
+    curpenob.xpcolor = 0;
+    curpenob.minTerm = COOKIEOP;
+    DFree(curpenob.mask);
+    curpenob.mask = penBM.Planes[0];
+    penBM.Planes[0] = (APTR)0;
+    penBM.Depth = 0;
+    curpenob.planeUse = 0;
+    curpenob.planeDef = 0; 
+    curpenob.xoffs = curpenob.pict.box.w/2;
+    curpenob.yoffs = curpenob.pict.box.h/2;
+    }
+
+local SzPen() { return(NewSizeBitMap(curpenob.pict.bm,1,
+           curpenob.pict.box.w,curpenob.pict.box.h));}
+
+local SizePenBM() {
+    if (SzPen()) {
+       FreeBMOB(&curbr);
+       if (SzPen()) return(FAIL);
+       }
+    ClearBitMap(&penBM);
+    return(SUCCESS);
+    }
+
+/* ------------- Circular Pen radius r: 
+    r is in VDC (virtual device coords )
+*/ 
+RoundPen(r) SHORT r; {
+    struct RastPort crp;
+    SHORT rx,ry;
+    rx = PMapX(r);
+    ry = MAX(PMapY(r),1);
+    MakeBox(&curpenob.pict.box,0,0,2*rx+1,2*ry+1);
+    InitRastPort(&crp);
+    SizePenBM();
+    crp.BitMap = &penBM;
+    SetAPen(&crp,15);
+    PushGrDest(&crp,&screenBox); /* any large box with x=y=0 will do */
+    PFillCirc(rx,ry,rx);
+    PopGrDest();
+    FixUpPen();
+    }
+
+OneBitPen() {
+    MakeBox(&curpenob.pict.box,0,0,1,1);
+    NewSizeBitMap(&penBM,1,1,1);
+    *((SHORT *)penBM.Planes[0]) = 0x8000;
+    FixUpPen();
+    }
+
+    
+/*---------------- Square Pen side s ------------- */ 
+SquarePen(s) SHORT s; {
+    struct RastPort crp;
+    SHORT pw = PMapX(s);
+    SHORT ph = PMapY(s);
+    MakeBox(&curpenob.pict.box,0,0,pw,ph);
+    InitRastPort(&crp);
+    SizePenBM();
+    crp.BitMap = &penBM;
+    SetAPen(&crp,15);
+    WaitBlit();
+    RectFill(&crp,0,0,pw-1,ph-1);
+    FixUpPen();
+    }
+
+#define NPENS  9
+
+#ifdef fromprism_h
+/* Pen TYPE ENcoding */
+#define USERBRUSH -1
+#define ROUND_B                1
+#define SQUARE_B       2
+#define DOT_B          3
+#define AIR_B          4    
+#define RoundB(n)      ((ROUND_B<<12)|n)
+#define SquareB(n)     ((SQUARE_B<<12)|n)
+#define DotB(n)                ((DOT_B<<12)|n)
+#define AirB           AIR_B<<12
+
+#endif
+
+
+
+/* dot pens ---------------- */
+extern UWORD dots10[],dots20[],dots30[],dots40[],dots50[],dots60[];
+UWORD *dotbms[] = { dots10, dots20, dots30, dots40, dots50, dots60};
+
+DotBFromRad(r) int r; {  return( DotB(r/2));  }
+
+DotsPen(s) int s; {
+    int pensz;
+    s = MIN(6, MAX(1,s));
+    pensz = 4*s+1;
+    MakeBox(&curpenob.pict.box,0,0,pensz,pensz);
+    SizePenBM();
+    movmem(dotbms[s-1], penBM.Planes[0], BytesNeeded(pensz)*pensz);
+    FixUpPen();
+    }
+
+/** Select a builtin Pen --------------- */
+        
+void SelPen(n) int n; {
+    int type,size;
+    if (n==USERBRUSH) { 
+       if (!BrushDefined()) return; 
+       else UseBrush(); 
+       }
+    else {
+       if (n==0) OneBitPen(); 
+       else {
+           type = (n>>12)&0xf;
+           size = n&0xfff;
+           switch(type) {
+               case ROUND_B: size = MIN(size,50); RoundPen(VMapY(size)); break;
+               case SQUARE_B: size = MIN(size,100); SquarePen(VMapY(size)); break;
+               case DOT_B: DotsPen(size); break;
+               default: break;
+               }
+           n = (n&0xf000)|size;
+           }
+       if (curpen==USERBRUSH){
+           curpen=n;   /* have to do this first so LegalMode() works right*/
+           if (modeHelp) SetModeMenu(Color);
+           }
+       UsePen();
+       }
+    curpen = n;
+    FixUsePen();       /* this updates the usePen variable*/
+    ResetCursor();
+    }
+
diff --git a/CURSBMS.C b/CURSBMS.C
new file mode 100644 (file)
index 0000000..df3aecc
--- /dev/null
+++ b/CURSBMS.C
@@ -0,0 +1,188 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*        cursbms.c -- Sprite Bitmaps for different cursors            */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+/* Bitmap name = fill,  Amiga-Sprite format.   */
+/* Width = 13, Height = 17 */ 
+
+short fillCurs[38] = { 
+  0x0000,  0x0000,       /* position and control info*/
+   0x200,   0x0, 
+  0x700,   0x200, 
+  0xF80,   0x700, 
+  0x1FC0,   0xF80, 
+  0x3FE0,   0x1FC0, 
+  0x7FF0,   0x3FE0, 
+  0xFFF8,   0x7FE0, 
+  0x7FF0,   0x3FC0, 
+  0x3FE0,   0x1F80, 
+  0x1FC0,   0xF00, 
+  0xF80,   0x600, 
+  0x700,   0x0, 
+  0x700,   0x200, 
+  0x1740,   0x200, 
+  0xF80,   0x700, 
+  0x700,   0x200, 
+  0x1DC0,   0x1DC0, 
+  0xFFFF,   0xFFFF       /* end markers */ 
+  }; 
+
+
+
+/* Bitmap name = cross,  Amiga-Sprite format.   */
+/* Width = 15, Height = 15 */ 
+
+short crossCurs[34] = { 
+  0x0000,  0x0000,       /* position and control info*/
+   0x100,   0x0, 
+  0x0,   0x100, 
+  0x100,   0x0, 
+  0x0,   0x100, 
+  0x100,   0x0, 
+  0x0,   0x100, 
+  0x0,   0x0, 
+  0xA82A,   0x5454, 
+  0x0,   0x0, 
+  0x0,   0x100, 
+  0x100,   0x0, 
+  0x0,   0x100, 
+  0x100,   0x0, 
+  0x0,   0x100, 
+  0x100,   0x0, 
+  0xFFFF,   0xFFFF       /* end markers */ 
+  }; 
+
+
+
+/* Bitmap name = zzz,  Amiga-Sprite format.   */
+/* Width = 16, Height = 25 */ 
+
+short zzz [54] = { 
+  0x0000,  0x0000,       /* position and control info*/
+   0x0,   0xFE0, 
+  0x740,   0x18B0, 
+  0xFE0,   0x7018, 
+  0x3FF0,   0xC008, 
+  0x7FF0,   0x9E0C, 
+  0x7FF8,   0x8406, 
+  0x7FFC,   0x8802, 
+  0xFFFC,   0x1E03, 
+  0x7FFE,   0x80F1, 
+  0x7FFE,   0x8021, 
+  0x3FFF,   0x4040, 
+  0x7FFE,   0x80F1, 
+  0x3FFE,   0xC001, 
+  0x1FFC,   0x6003, 
+  0xFF8,   0x3006, 
+  0x3F0,   0x1C0C, 
+  0xE0,   0x718, 
+  0x780,   0x870, 
+  0xFE0,   0x1010, 
+  0x740,   0x820, 
+  0x0,   0xFE0, 
+  0x1C0,   0x220, 
+  0x3E0,   0x410, 
+  0xC0,   0x330, 
+  0x0,   0xE0, 
+  0xFFFF,   0xFFFF       /* end markers */ 
+  }; 
+
+
+
+/* Bitmap name = size,  Amiga-Sprite format.   */
+/* Width = 8, Height = 31 */ 
+
+short size[66] = { 
+  0x0000,  0x0000,       /* position and control info*/
+   0x7800,   0x7C00, 
+  0x8400,   0xC600, 
+  0x8000,   0xC000, 
+  0x7800,   0x7C00, 
+  0x400,   0x600, 
+  0x8400,   0xC600, 
+  0x7800,   0x7C00, 
+  0x0,   0x0, 
+  0x3800,   0x3C00, 
+  0x1000,   0x1800, 
+  0x1000,   0x1800, 
+  0x1000,   0x1800, 
+  0x1000,   0x1800, 
+  0x1000,   0x1800, 
+  0x3800,   0x3C00, 
+  0x0,   0x0, 
+  0x7E00,   0x7F00, 
+  0x400,   0x600, 
+  0x800,   0xC00, 
+  0x1000,   0x1800, 
+  0x2000,   0x3000, 
+  0x4000,   0x6000, 
+  0x7E00,   0x7F00, 
+  0x0,   0x0, 
+  0x7E00,   0x7F00, 
+  0x4000,   0x6000, 
+  0x4000,   0x6000, 
+  0x7800,   0x7C00, 
+  0x4000,   0x6000, 
+  0x4000,   0x6000, 
+  0x7E00,   0x7F00, 
+  0xFFFF,   0xFFFF       /* end markers */ 
+  }; 
+
+
+
+
+/* Bitmap name = pick,  Amiga-Sprite format.   */
+/* Width = 11, Height = 43 */ 
+
+short pick[90] = { 
+  0x0000,  0x0000,       /* position and control info*/
+   0x0,   0x7C00, 
+  0x7C00,   0xFE00, 
+  0x7C00,   0x8600, 
+  0x7800,   0x8C00, 
+  0x7C00,   0x8600, 
+  0x5E00,   0xA300, 
+  0xF00,   0xD180, 
+  0x780,   0x8C0, 
+  0x3C0,   0x460, 
+  0x1C0,   0x220, 
+  0x80,   0x140, 
+  0x0,   0x80, 
+  0x7C00,   0x7E00, 
+  0x4200,   0x6300, 
+  0x4200,   0x6300, 
+  0x7C00,   0x7E00, 
+  0x4000,   0x6000, 
+  0x4000,   0x6000, 
+  0x4000,   0x6000, 
+  0x0,   0x0, 
+  0x7000,   0x7800, 
+  0x2000,   0x3000, 
+  0x2000,   0x3000, 
+  0x2000,   0x3000, 
+  0x2000,   0x3000, 
+  0x2000,   0x3000, 
+  0x7000,   0x7800, 
+  0x0,   0x0, 
+  0x7800,   0x7C00, 
+  0x8400,   0xC600, 
+  0x8000,   0xC000, 
+  0x8000,   0xC000, 
+  0x8000,   0xC000, 
+  0x8400,   0xC600, 
+  0x7800,   0x7C00, 
+  0x0,   0x0, 
+  0x8400,   0xC600, 
+  0x8800,   0xCC00, 
+  0x9000,   0xD800, 
+  0xE000,   0xF000, 
+  0x9000,   0xD800, 
+  0x8800,   0xCC00, 
+  0x8400,   0xC600, 
+  0xFFFF,   0xFFFF       /* end markers */ 
+  }; 
+
+
+
diff --git a/CURSOR.C b/CURSOR.C
new file mode 100644 (file)
index 0000000..aa731d0
--- /dev/null
+++ b/CURSOR.C
@@ -0,0 +1,73 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*        cursor.c -- Plug in different cursors                                */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+extern struct Window *mainW;
+extern BOOL inside;
+extern SHORT curpen;
+
+extern UWORD fillCurs[],crossCurs[],zzz[],size[], pick[];
+
+typedef struct { SHORT w,h,xoffs,yoffs; UWORD *bits; } CursDesc;
+
+CursDesc cursDir[] = { 
+    {13,17,7,16, fillCurs},
+    {15,15,8,7, crossCurs},
+    {16,25,8,12, zzz},
+    {8,31,0,0, size},
+    {11,43,1,0, pick}
+    };
+
+    
+static SHORT nullSprite[2] = {0};
+
+SHORT curCursor = DEFCURSOR;   /* the actual cursor now showing */
+SHORT curPaintCursor = DEFCURSOR;      /* the painting cursor */
+SHORT paintCursOn = YES;               /* is the painting cursor showing */
+
+    
+/* these ignore the Painting cursor */
+HideCursor() { SetPointer(mainW, nullSprite, 0, 0, 0, 0);}
+DefaultCursor() {ClearPointer(mainW);}
+
+JamCursor(n) int n; {
+    CursDesc *cd = &cursDir[n-2];
+    SetPointer(mainW, cd->bits,cd->h,cd->w,-cd->xoffs,-cd->yoffs); 
+    }
+
+void SetCursor(n) {
+    curCursor = n;
+    if (n==NOCURSOR) HideCursor();
+    else if (n==DEFCURSOR) DefaultCursor();  else JamCursor(n);
+    }
+    
+/* this affects the Painting cursor */
+void SetPaintCursor(n) int n; {
+    curPaintCursor = n;
+    if (!inside) SetCursor(DEFCURSOR); 
+    else SetCursor((paintCursOn||!((n==DEFCURSOR)||(n==CROSSCURSOR)))? n: NOCURSOR);
+    }
+
+DefaultPaintCursor() {
+    SetPaintCursor( (curpen==USERBRUSH)? DEFCURSOR: CROSSCURSOR);
+    }
+
+/* restore cursor to current Paint Cursor state */
+ResetCursor() { 
+    if ( (curPaintCursor ==DEFCURSOR) || (curPaintCursor == CROSSCURSOR))
+       DefaultPaintCursor();
+    else SetPaintCursor(curPaintCursor); 
+    }
+
+/* Change the Paint Cursor from showing to not or vice versa */
+TogCursor() {  paintCursOn = !paintCursOn;  ResetCursor();  }
+
+/* These must work event outside of paint window */
+
+ZZZCursor() {  JamCursor(ZZZCURSOR); }
+UnZZZCursor() { SetCursor(curCursor); }
diff --git a/DALLOC.C b/DALLOC.C
new file mode 100644 (file)
index 0000000..7db858c
--- /dev/null
+++ b/DALLOC.C
@@ -0,0 +1,38 @@
+/*--------------------------------------------------------------*/
+/*                                                             */
+/*             dalloc.c                                        */
+/*                                                             */
+/*     lets you specify flags but remembers the length for     */
+/*     freeing.                                                */
+/*--------------------------------------------------------------*/
+
+#include <exec\types.h>
+#include <exec\nodes.h>
+#include <exec\memory.h>
+
+/* first 4 bytes of allocated area contain the length of the area.
+This length is the number of bytes allocated by AllocMem, ie includes
+the 4 bytes for itself */
+    
+/* size in bytes */
+UBYTE *DAlloc(size,flags) LONG size; USHORT flags; {
+    LONG *p;
+    LONG asize = size+4;
+    p = (LONG *)AllocMem(asize,flags);
+    if (p==NULL){
+       return((UBYTE *)p);
+       }
+    *p++ = asize;      /* post-bump p to point at clients area*/
+    return((UBYTE *)p);
+    }
+    
+UBYTE *ChipAlloc(size) LONG size; {
+    return(DAlloc(size,MEMF_PUBLIC|MEMF_CHIP));
+    }
+    
+DFree(p) UBYTE *p; {
+    if (p!=NULL) {
+       p -= 4;
+       return(FreeMem(p, *((LONG *)p))); 
+       }
+    }
diff --git a/DISPNUM.C b/DISPNUM.C
new file mode 100644 (file)
index 0000000..554c0e0
--- /dev/null
+++ b/DISPNUM.C
@@ -0,0 +1,144 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*             dispnum.c --Coordinate readout                          */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+extern SHORT xShft, yShft;
+extern BOOL titleShowing;
+extern struct RastPort screenRP;
+extern SHORT curFormat;
+extern SHORT curMBarH;     
+#define local static
+
+/*--------------------------------------------------- */
+/* pad string a out (on left) to n chars and store in b */
+
+strpad(a,b,n,neg) char *a,*b; SHORT n; BOOL neg; {
+    SHORT i,m,pad;
+    m = MIN(n,strlen(a));
+    pad = n-m;
+    for (i=pad; i<n; i++) b[i] = *a++;
+    b[n] = 0;
+    for(i=0; i<pad; i++) b[i] = ' ';
+    if (neg &&(pad>0)) b[pad-1] = '-';
+    }
+
+TextXY(s,x,y) char *s; SHORT x,y; {
+    Move(&screenRP,PMapX(x),PMapY(y));
+    Text(&screenRP,s,strlen(s));
+    }
+/*
+DispColStr(s,x,y,col) char *s; SHORT x,y,col; {
+    SetAPen(&screenRP,col);
+    SetDrMd(&screenRP,JAM1);
+    TextXY(s,x,y);
+    }
+*/
+    
+DispStr(s,x,y) char *s; SHORT x,y; {
+    SetAPen(&screenRP,0);
+    SetBPen(&screenRP,1);
+    SetDrMd(&screenRP,JAM2);
+    TextXY(s,x,y);
+    }
+    
+DispNum(n,x,y,ln) {
+    char str[12],rtjust[12];
+    BOOL neg;
+    if (n<0) { neg = YES; n = -n;} else neg = NO;
+    stcu_d(str,n,9);
+    strpad(str,rtjust,ln,neg);
+    DispStr(rtjust,x,y);       /* draw text */
+    }
+
+/* Bitmap name = xarrow,  Amiga-BOB format.   */
+/* Width = 11, Height = 5 */ 
+
+
+/* Bitmap name = xarrow,  Amiga-BOB format. */
+/* Width = 11, Height = 5 */ 
+
+short xarrow[5] = {  0xFE60,  0xFF20,  0x0,  0xFF20,  0xFE60  }; 
+
+/* Bitmap name = yarrow,  Amiga-BOB format. */
+/* Width = 5, Height = 10 */ 
+
+short yarrow[10] = {  0xD800,  0xD800,  0xD800,  0xD800,  0xD800, 
+  0xD800,  0x5000,  0x0,  0x8800,  0xD800  }; 
+
+local struct Image xarrIm = {0,2,11,5,1,xarrow,1,1,NULL};
+local struct Image yarrIm = {0,0,5,10,1,yarrow,1,1,NULL};
+
+UBYTE *modeNames[] = { "Object","Color","Replace","Smear","Shade",
+"Blend","Cycle" };
+
+extern PaintMode userPntMode;
+
+local SHORT pntx[3] = { 232, 134, 158 };
+local SHORT pnty[3] = { 14, 14, 7 };
+
+#define titleY   
+DispPntMode()  {
+    SHORT vx,vy;
+    if (titleShowing) {
+       SetAPen(&screenRP,1);
+       vx = pntx[curFormat];
+       vy = pnty[curFormat];
+       RectFill(&screenRP,PMapX(vx), 0, PMapX(vx+220), curMBarH-2);
+       DispStr(modeNames[userPntMode], vx, vy);
+/**
+       if (curFormat == 2) {
+           SetAPen(&screenRP,0);
+           Move(&screenRP, 0, curMBarH-2);
+           Draw(&screenRP, 639, curMBarH-2);
+           }
+**/
+       }
+    }
+
+ClearXY() {
+    if (titleShowing) {
+       SetAPen(&screenRP,1);
+       RectFill(&screenRP,PMapX(388), PMapY(0), PMapX(564), curMBarH-2);
+       }
+   }
+
+/***
+extern char dpaintTitle[];
+DispDPaint() { 
+    if (titleShowing) DispColStr(dpaintTitle,VMapX(3),VMapY(7),2);  }
+***/
+
+extern char version[];
+DispAvailMem() {
+    int m,vy,l;
+    if (titleShowing) {
+       vy = pnty[curFormat];
+       DispStr(version,0,vy);
+       l = TextLength(&screenRP, version, strlen(version));
+       m = AvailMem(MEMF_PUBLIC);
+       DispNum(m,VMapX(l),vy,7);
+       }
+    }
+
+#define XMIDP 452
+#define YMIDP 544
+SHORT numW[] =  { 3*8*2,3*8,3*9};
+
+DispXY(x,y) {
+    SHORT vy,w;
+    if (titleShowing) {
+       vy = pnty[curFormat];
+       w = numW[curFormat];
+       DispNum(x, XMIDP - w, vy, 3);
+       DrawImage(&screenRP,&xarrIm, PMapX(XMIDP), PMapY(0));
+       DispNum(y, YMIDP - w, vy, 3);
+       DrawImage(&screenRP,&yarrIm, PMapX(YMIDP), PMapY(0));
+       }
+    }
+
+
diff --git a/DISTANCE.C b/DISTANCE.C
new file mode 100644 (file)
index 0000000..a79ffe1
--- /dev/null
@@ -0,0 +1,20 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*        distance.c -- Euclidean Distance                             */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+#include <exec\types.h>
+
+/*----------------------------------------------------------------------*/
+/* returns sqroot(dx*dx + dy*dy);                                      */
+/*----------------------------------------------------------------------*/
+SHORT Distance(dx,dy) SHORT dx,dy; {
+    SHORT v,t,i;
+    long n;
+    n = (long)dx*(long)dx + (long)dy*(long)dy;
+    i = 1024; 
+    v = 0;
+    while (i!=0) { t = v+i; if ( ((long)t*(long)t) <= n ) v = t; i >>= 1; }
+    return(v);
+    }
+
diff --git a/DOPALETT.C b/DOPALETT.C
new file mode 100644 (file)
index 0000000..db85b3e
--- /dev/null
@@ -0,0 +1,66 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*      dopalette -- invoke the palette tool                           */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+extern SHORT nColors;
+extern Range cycles[];
+extern struct Window *mainW;
+extern Range *shadeRange;
+extern Box bigBox;
+extern BOOL skipRefresh;
+extern PaletteGlobals *paletteGlobals;
+
+/* map a  number i, in [0..63], to logarithmic range  */
+/* this maps 63 to 8192(OnePerTick), and maps 0 to 36, about 227 ticks 
+    per change, i.e. nearly 4 seconds . */
+    
+rateFromIndex(i) int i; {
+    int base;
+    i++;
+    base = 1 << ((i >> 3) + 5);
+    return (base + ((i & 7) * base) / 8);
+    }
+
+/* this is the exact inverse of the above function*/
+indexFromRate(n) int n; {
+    int j;
+    int hibit, mod;
+    hibit = (1 << 15);
+    for (j = 15;  j >= 0;  j--)        {
+       if (hibit & n)  {
+           mod = n - hibit;
+           return ((j - 5) * 8 + (mod * 8) / hibit - 1);
+           }
+       hibit >>= 1;
+       }
+    }  
+/* ----- Display color pallet Control ----- */
+void ShowPallet() { 
+    int i;
+    BOOL res;
+    UndoSave();
+    PauseCCyc();
+    for (i=1; i<MAXNCYCS; i++) cycles[i].rate = indexFromRate(cycles[i].rate);
+    FreeTmpRas();
+    for (;;) { 
+       res = PaletteTool(mainW,&paletteGlobals);
+       WaitRefrMessage();
+       if (res) break;
+       UpdtDisplay();
+       }
+    skipRefresh = YES; /* where this extra refresh comes from I don't  know */
+    AllocTmpRas();
+    PaneRefresh(&bigBox);
+    for (i=1; i<MAXNCYCS; i++) cycles[i].rate = rateFromIndex(cycles[i].rate);
+    ResumeCCyc();
+    SetCycPaint();
+    DispPntMode();
+    if (cycles[0].low ==cycles[0].high) shadeRange = NULL;
+      else shadeRange = cycles;
+    }
+
diff --git a/DOSYMREQ.C b/DOSYMREQ.C
new file mode 100644 (file)
index 0000000..e0bf4ee
--- /dev/null
@@ -0,0 +1,25 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*             dosymreq.c --                                           */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+extern Box screenBox;
+extern struct Window *mainW;
+extern SHORT cpWidth;
+extern SHORT xShft,yShft;
+extern BOOL mirror;
+extern SHORT nSym;
+
+DoSymReq() {
+    BOOL mir = mirror;
+    SHORT n = nSym;
+    FreeTmpRas();
+    UndoSave(); /* because use UpdtDisplay to restore screen */
+    SymRequest(mainW, screenBox.w - cpWidth - 180, PMapY(120), &n, &mir);
+    UpdtDisplay();
+    SymSetNMir(n,mir);
+    AllocTmpRas();
+    }
diff --git a/DOTBMS.C b/DOTBMS.C
new file mode 100644 (file)
index 0000000..f4f8f5d
--- /dev/null
+++ b/DOTBMS.C
@@ -0,0 +1,138 @@
+/* Bitmap name = dots1,  Amiga-BOB format.   */
+/* Width = 5, Height = 5 */ 
+
+short dots10[5] = { 
+  0x8000, 
+  0x0, 
+  0x800, 
+  0x0, 
+  0x4000
+  }; 
+
+
+
+/* Bitmap name = dots2,  Amiga-BOB format.   */
+/* Width = 9, Height = 9 */ 
+
+short dots20[9] = { 
+  0x800, 
+  0x0, 
+  0x0, 
+  0x80, 
+  0x8800, 
+  0x0, 
+  0x0, 
+  0x0, 
+  0x400
+  }; 
+
+
+
+/* Bitmap name = dots3,  Amiga-BOB format.   */
+/* Width = 13, Height = 13 */ 
+
+short dots30[13] = { 
+  0x400, 
+  0x0, 
+  0x40, 
+  0x4000, 
+  0x208, 
+  0x0, 
+  0x0, 
+  0x400, 
+  0x8010, 
+  0x0, 
+  0x0, 
+  0x800, 
+  0x80
+  }; 
+
+
+
+/* Bitmap name = dots4,  Amiga-BOB format.   */
+/* Width = 17, Height = 17 */ 
+
+short dots40[34] = { 
+  0x40,   0x0, 
+  0x0,   0x0, 
+  0x1000,   0x0, 
+  0x4,   0x0, 
+  0x0,   0x0, 
+  0x100,   0x0, 
+  0x0,   0x0, 
+  0x8000,   0x0, 
+  0x0,   0x8000, 
+  0x40,   0x0, 
+  0x0,   0x0, 
+  0x0,   0x0, 
+  0x2000,   0x0, 
+  0x8,   0x0, 
+  0x0,   0x0, 
+  0x0,   0x0, 
+  0x100,   0x0
+  }; 
+
+
+
+/* Bitmap name = dots5,  Amiga-BOB format.   */
+/* Width = 21, Height = 21 */ 
+
+short dots50[42] = { 
+  0x80,   0x0, 
+  0x0,   0x0, 
+  0x1,   0x0, 
+  0x2000,   0x0, 
+  0x0,   0x0, 
+  0x40,   0x0, 
+  0x0,   0x0, 
+  0x4,   0x0, 
+  0x0,   0x800, 
+  0x400,   0x0, 
+  0x0,   0x0, 
+  0x8000,   0x0, 
+  0x0,   0x0, 
+  0x82,   0x0, 
+  0x0,   0x1000, 
+  0x2000,   0x0, 
+  0x0,   0x0, 
+  0x0,   0x0, 
+  0x0,   0x0, 
+  0x8,   0x0, 
+  0x100,   0x0
+  }; 
+
+
+
+/* Bitmap name = dots6,  Amiga-BOB format.   */
+/* Width = 25, Height = 25 */ 
+
+short dots60[50] = { 
+  0x10,   0x0, 
+  0x0,   0x0, 
+  0x0,   0x0, 
+  0x1000,   0x0, 
+  0x0,   0x800, 
+  0x80,   0x0, 
+  0x4,   0x0, 
+  0x0,   0x0, 
+  0x0,   0x2000, 
+  0x0,   0x0, 
+  0x8000,   0x0, 
+  0x80,   0x0, 
+  0x0,   0x80, 
+  0x0,   0x0, 
+  0x801,   0x0, 
+  0x0,   0x0, 
+  0x0,   0x0, 
+  0x0,   0x0, 
+  0x10,   0x0, 
+  0x0,   0x0, 
+  0x800,   0x800, 
+  0x0,   0x0, 
+  0x0,   0x0, 
+  0x0,   0x0, 
+  0x10,   0x0
+  }; 
+
+
+
diff --git a/DPHOOK.H b/DPHOOK.H
new file mode 100644 (file)
index 0000000..bd80843
--- /dev/null
+++ b/DPHOOK.H
@@ -0,0 +1,16 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*     dphook.h                                                                */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+typedef struct {
+    struct BitMap *bitmap;  /* the bitmap to be shared by DPaint */
+    struct BitMap *dpScreenBitMap;  /* DPaint's screen bitmap */
+    struct ViewPort *vport;    /* DPaint's ViewPort */
+    SHORT format;      /* 0: 320x200,  1:640x200, 2: 640x400 */
+    SHORT refCount;    /* initialize to zero: don't free bitmap if > 0 */ 
+    SHORT version;     /* = 1 for DPaint version 1.0 */
+    BMOB *brush;       /* pointer to DPaints brush: for possible
+                               future enhancements */
+    } DPHook;
diff --git a/DPIFF.C b/DPIFF.C
new file mode 100644 (file)
index 0000000..1cb1937
--- /dev/null
+++ b/DPIFF.C
@@ -0,0 +1,341 @@
+/** dpiff.c ******************************************************************/
+/*                                                                           */
+/* DPAINT IFF file I/O procedures                                            */
+/*                                                                           */
+/* Date      Who Changes                                                     */
+/* --------- --- ----------------------------------------------------------- */
+/* 01-Sep-85 mrp created                                                     */
+/* 27-Sep-85 jhm & sss rewrote using ilbm.h, packer.h, & iff.h               */
+/* 01-Oct-85 dds  modified for DPaint.                                       */
+/* 07-Nov-85 sss  Dive into non-ILBM FORMs looking for an ILBM.              */
+/*****************************************************************************/
+#include "system.h"
+#include "prism.h"
+#include "dpiff.h" 
+
+#define MaxDepth 5
+static IFFP ifferror = 0;
+
+extern Box screenBox;
+
+#define CkErr(expression)  {if (ifferror == IFF_OKAY) ifferror = (expression);}
+    
+/*****************************************************************************/
+/* IffErr                                                                    */
+/*                                                                           */
+/* Returns the iff error code and resets it to zero                          */
+/*                                                                           */
+/*****************************************************************************/
+IFFP IffErr()
+   {
+   IFFP i;
+   i = ifferror;
+   ifferror = 0;
+   return(i);
+   }
+
+/*------------ ILBM reader -----------------------------------------------*/
+/* DVCS' number of planes in a bitmap. Could use MaxAmDepth. */
+
+/* Here's our "client frame" for reading an IFF file, looking for ILBMs.
+ * We use it to stack BMHD & CMAP properties. */
+typedef struct {
+   ClientFrame clientFrame;
+   UBYTE foundBMHD;
+   UBYTE nColorRegs;
+   BitMapHeader bmHdr;
+   Color4 colorMap[1<<MaxDepth];
+   /* [TBD] Place to store any other shared PROPs encountered in a LIST.*/
+   } ILBMFrame;
+
+
+/* GetPicture communicates with GetFoILBM via these.*/
+static struct BitMap *gpBitmap = NULL;
+static WORD *gpColorMap = NULL;
+static BYTE *gpBuffer = NULL;
+static LONG gpBufsize = 0;
+static BOOL picNotFit = FALSE;
+
+#if 0
+prbmHdr(bmHdr)  BitMapHeader *bmHdr; {
+    printf("bmHdr->w %ld  ",bmHdr->w);  printf("bmHdr->h %ld\n",bmHdr->h);
+    printf("bmHdr->x %ld  ",bmHdr->x);   printf("bmHdr->y %ld\n",bmHdr->y);
+    printf("bmHdr->depth %ld  ",bmHdr->depth);  printf("bmHdr->nPlanes %ld\n",bmHdr->nPlanes);
+    printf("bmHdr->masking %ld  ",bmHdr->masking);
+    printf("bmHdr->pixelFormat %ld\n",bmHdr->pixelFormat);
+    printf("bmHdr->compression %ld\n",bmHdr->compression);
+    printf("bmHdr->pad1 %ld",bmHdr->pad1);
+    printf("bmHdr->transparentColor %ld\n",bmHdr->transparentColor);
+    }
+#endif
+
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/* MBMGetFoILBM()                                                      */
+/* Used by GetMaskBM to handle every FORM in an IFF file.              */
+/* Reads FORM ILBMs and skips all other FORMs.                         */
+/* Inside a FORM ILBM,                                                 */
+/* ILBMs with no BODY.                                                 */
+/*                                                                     */
+/* Once we find a BODY chunk, we'll start reading into client's BitMap. */
+/* if it turns out to be malformed, we'll be sorry.                    */
+/*----------------------------------------------------------------------*/
+static MaskBM *gpMaskBM;
+static SHORT rngCnt;
+ResizeProc gpReSize;
+
+IFFP MBMGetFoILBM(parent)  GroupContext *parent; {
+    /*compilerBug register*/ IFFP iffp;
+    GroupContext formContext;
+    ILBMFrame ilbmFrame;
+    register int i;
+    BOOL resizeFail;
+
+    /* Dive into any non-ILBM FORM looking for an ILBM.*/
+    if (parent->subtype != ID_ILBM) {
+       /* Open a non-ILBM FORM.*/
+       iffp = OpenRGroup(parent, &formContext);
+       CheckIFFP();
+       do {
+           iffp = GetF1ChunkHdr(&formContext);
+           } while (iffp >= IFF_OKAY);
+       if (iffp == END_MARK)
+           iffp = IFF_OKAY;    /* then continue scanning the file */
+       CloseRGroup(&formContext);
+       return(iffp);
+       }
+
+    /* Open an ILBM FORM.*/
+    iffp = OpenRGroup(parent, &formContext);
+    CheckIFFP();
+
+    /* Place to store any ILBM properties that are found, starting from
+     * any values found in ancestors.*/
+    ilbmFrame = *(ILBMFrame *)parent->clientFrame;
+
+    do switch (iffp = GetFChunkHdr(&formContext)) {
+       case ID_BMHD: {
+           ilbmFrame.foundBMHD = TRUE;
+            iffp = GetBMHD(&formContext, &ilbmFrame.bmHdr);
+           break; }
+       case ID_CMAP: {
+           ilbmFrame.nColorRegs = 1 << MaxDepth;  /* we have room for this many */
+           iffp = GetCMAP(
+               &formContext, (WORD *)&ilbmFrame.colorMap, &ilbmFrame.nColorRegs);
+           gpMaskBM->flags |= MBM_HAS_CMAP;
+           break; 
+           }
+       case ID_GRAB: {
+           iffp = IFFReadBytes(&formContext, (BYTE *)&gpMaskBM->grab, 
+                   sizeof(Point2D));
+           gpMaskBM->flags |= MBM_HAS_GRAB;
+           break; }
+
+       case ID_CRNG:
+           if (( gpMaskBM->ranges != NULL) && (rngCnt<gpMaskBM->nRange)) 
+               iffp = IFFReadBytes(&formContext, 
+                   (BYTE *)&gpMaskBM->ranges[rngCnt++], sizeof(Range));
+           break; 
+       
+       case ID_BODY: {
+           if (!ilbmFrame.foundBMHD)  return(BAD_FORM);
+
+           gpMaskBM->pos.x = ilbmFrame.bmHdr.x;
+           gpMaskBM->pos.y = ilbmFrame.bmHdr.y;
+           gpMaskBM->xAspect = ilbmFrame.bmHdr.xAspect;
+           gpMaskBM->yAspect = ilbmFrame.bmHdr.yAspect;
+           gpMaskBM->masking = ilbmFrame.bmHdr.masking;
+           gpMaskBM->xpcolor = ilbmFrame.bmHdr.transparentColor;
+
+           if (gpMaskBM->grab.x > ilbmFrame.bmHdr.w)
+               gpMaskBM->grab.x = ilbmFrame.bmHdr.w;
+           if (gpMaskBM->grab.y > ilbmFrame.bmHdr.h)
+               gpMaskBM->grab.y = ilbmFrame.bmHdr.h;
+
+         /*  Compare bmHdr dimensions with gpBitmap dimensions! */
+           if( (RowBytes(ilbmFrame.bmHdr.w) != gpBitmap->BytesPerRow)||
+           (ilbmFrame.bmHdr.h != gpBitmap->Rows) ||
+           (ilbmFrame.bmHdr.nPlanes != gpBitmap->Depth) )              {
+               /* didn't fit: must resize the destination */
+               resizeFail = (*gpReSize)(gpMaskBM,&ilbmFrame.bmHdr); 
+               if (resizeFail ) return(BAD_FIT);
+               }
+           
+         iffp = GetBODY(
+           &formContext, gpMaskBM->bitmap, gpMaskBM->mask, 
+           &ilbmFrame.bmHdr, gpBuffer, gpBufsize);
+         if (iffp == IFF_OKAY) iffp = IFF_DONE;        /* Eureka */
+         break; }
+      case END_MARK: { iffp = BAD_FORM; break; } /* No BODY chunk! */
+      } while (iffp >= IFF_OKAY);  /* loop if valid ID of ignored chunk or a
+                         * subroutine returned IFF_OKAY, i.e., no errors.*/
+
+   if (iffp != IFF_DONE)  return(iffp);
+   CloseRGroup(&formContext);
+
+   /* It's a good ILBM, return the properties to the client.*/
+
+   /* Copy CMAP into client's storage.*/
+   /* nColorRegs is 0 if no CMAP;  no data will be copied to gpColorMap.
+    * That's ok; client is left with whatever colors she had before.*/
+    if (gpColorMap!=NULL)   for (i = 0;  i < ilbmFrame.nColorRegs;  i++)
+      gpColorMap[i] = ilbmFrame.colorMap[i];
+   return(iffp);
+   }
+
+/*****************************************************************************/
+/* MBMGetLiILBM()                                                            */
+/* Used by GetMaskBM to handle every LIST in an IFF file.                    */
+/*                                                                           */
+/*****************************************************************************/
+IFFP MBMGetLiILBM(parent)  GroupContext *parent; {
+    ILBMFrame newFrame;        /* allocate a new Frame */
+
+    newFrame = *(ILBMFrame *)parent->clientFrame;  /* copy parent frame */
+
+    return( ReadIList(parent, (ClientFrame *)&newFrame) );
+    }
+
+/*****************************************************************************/
+/* MBMGetPrILBM()                                                            */
+/* Used by GetMaskBM to handle every PROP in an IFF file.                    */
+/* Reads PROP ILBMs and skips all others.                                    */
+/*                                                                           */
+/*****************************************************************************/
+IFFP MBMGetPrILBM(parent)  GroupContext *parent; {
+   /*compilerBug register*/ IFFP iffp;
+   GroupContext propContext;
+   ILBMFrame *ilbmFrame = (ILBMFrame *)parent->clientFrame;
+
+   iffp = OpenRGroup(parent, &propContext);
+   CheckIFFP();
+
+   switch (parent->subtype)  {
+
+      case ID_ILBM: {
+         do switch (iffp = GetPChunkHdr(&propContext)) {
+            case ID_BMHD: {
+              ilbmFrame->foundBMHD = TRUE;
+              iffp = GetBMHD(&propContext, &ilbmFrame->bmHdr);
+              break; }
+            case ID_CMAP: {
+              ilbmFrame->nColorRegs = 1 << MaxDepth; /* room for this many */
+              iffp = GetCMAP(&propContext, (WORD *)&ilbmFrame->colorMap,
+                            &ilbmFrame->nColorRegs);
+             gpMaskBM->flags |= MBM_HAS_CMAP;
+              break; }
+            } while (iffp >= IFF_OKAY);  /* loop if valid ID of ignored chunk
+                     * or a subroutine returned IFF_OKAY, i.e., no errors.*/
+         break;
+         }
+
+      default: iffp = IFF_OKAY;        /* just continue scanning the file */
+      }
+
+   CloseRGroup(&propContext);
+   return(iffp == END_MARK ? IFF_OKAY : iffp);
+   }
+
+/*****************************************************************************/
+/* GetMaskBM()                                                              */
+/*                                                                           */
+/* Get a picture from an IFF file                                            */
+/*                                                                           */
+/*****************************************************************************/
+BOOL GetMaskBM(file, maskBM, colorMap, reSize, buffer, bufsize)
+      LONG file;  MaskBM *maskBM;  WORD *colorMap;
+       ResizeProc reSize; BYTE *buffer;  LONG bufsize;
+    {
+    ILBMFrame iFrame;
+    iFrame.clientFrame.getList = &MBMGetLiILBM;
+    iFrame.clientFrame.getProp = &MBMGetPrILBM;
+    iFrame.clientFrame.getForm = &MBMGetFoILBM;
+    iFrame.foundBMHD = FALSE;
+    iFrame.nColorRegs = 0;
+    
+    gpReSize = reSize;
+    gpMaskBM = maskBM;
+    gpBitmap = maskBM->bitmap;
+    gpColorMap = colorMap;
+    gpBuffer = buffer;
+    gpBufsize = bufsize;
+    rngCnt = 0;
+    picNotFit = FALSE;
+    maskBM->grab.x = maskBM->grab.y = 0;
+
+    ifferror = ReadIFF(file, (ClientFrame *)&iFrame);
+    return( (BOOL)(ifferror != IFF_DONE) );
+    }    
+
+/*****************************************************************************/
+/* PutMaskBM()                                                               */
+/*                                                                           */
+/* Put a picture into an IFF file                                            */
+/* This procedure is specific to VCS. It writes an entire BitMap.            */
+/* Pass in mask == NULL for no mask.                                         */
+/*                                                                           */
+/* Buffer should be big enough for one packed scan line                      */
+/*                                                                           */
+/*****************************************************************************/
+BOOL dorng = YES;
+    
+BOOL PutMaskBM(file, maskBM, colorMap, buffer, bufsize)
+      LONG file; MaskBM *maskBM;  WORD *colorMap;
+      BYTE *buffer;  LONG bufsize;
+
+    {
+    BitMapHeader bmHdr;
+    GroupContext fileContext, formContext;
+    IFFP tmpifferror;
+    int i;
+           
+    ifferror = InitBMHdr(&bmHdr,
+       maskBM->bitmap, 
+       (int)maskBM->masking, 
+       (maskBM->w <= 64)? (int)cmpNone : (int)cmpByteRun1, 
+       (int)maskBM->xpcolor,
+       (int)screenBox.w, 
+       (int)screenBox.h );
+       
+    bmHdr.x = maskBM->pos.x;   
+    bmHdr.y = maskBM->pos.y;
+    bmHdr.w = maskBM->w;
+
+#define BODY_BUFSIZE 512
+
+    if (bufsize > 2*BODY_BUFSIZE) {
+       GWriteDeclare(file, buffer+BODY_BUFSIZE, bufsize-BODY_BUFSIZE);
+       bufsize = BODY_BUFSIZE;
+       }
+    
+    CkErr(OpenWIFF(file, &fileContext, szNotYetKnown) );
+    CkErr(StartWGroup(&fileContext, FORM, szNotYetKnown, ID_ILBM, &formContext) );
+
+    CkErr(PutCk(&formContext, ID_BMHD, sizeof(BitMapHeader), (BYTE *)&bmHdr));
+
+    if (colorMap!=NULL)
+       CkErr( PutCMAP(&formContext, colorMap, (UBYTE)maskBM->bitmap->Depth) );
+    if (maskBM->flags&MBM_HAS_GRAB) {
+       tmpifferror = PutCk(&formContext, ID_GRAB, sizeof(Point2D), 
+           (BYTE *)&maskBM->grab); 
+       CkErr(tmpifferror); 
+       }
+    if (maskBM->flags&MBM_HAS_RANGES) {
+       for (i=0; i<maskBM->nRange; i++) {
+           tmpifferror = PutCk(&formContext, ID_CRNG, sizeof(Range),
+               (BYTE *)&maskBM->ranges[i]);
+           CkErr(tmpifferror); 
+           }
+       }
+    tmpifferror =  PutBODY(&formContext, maskBM->bitmap, 
+       (BYTE *)((maskBM->masking == mskHasMask)? maskBM->mask: NULL),
+       &bmHdr, buffer, bufsize);
+    CkErr(tmpifferror); 
+    
+    CkErr( EndWGroup(&formContext) );
+    CkErr( CloseWGroup(&fileContext) );
+    GWriteDeclare(NULL, NULL, 0);
+    return( (BOOL)(ifferror != IFF_OKAY) );
+    }    
+
+
diff --git a/DPIFF.H b/DPIFF.H
new file mode 100644 (file)
index 0000000..614558d
--- /dev/null
+++ b/DPIFF.H
@@ -0,0 +1,44 @@
+/** dpiff.h ******************************************************************/
+/*                                                                           */
+/* DPAINT IFF file I/O procedures                                            */
+/*                                                                           */
+/*****************************************************************************/
+#ifndef DPIFF_H
+#define DPIFF_H
+
+#include "iff\ilbm.h"
+
+#define BAD_FIT  -9
+
+extern IFFP IffErr();  /* returns an IFFP error code; see IFF.H */
+
+/* FLAGS */
+#define MBM_HAS_GRAB 1
+#define MBM_HAS_PUSE 2
+#define MBM_HAS_CMAP 4
+#define MBM_HAS_RANGES 8
+
+/* Range id */
+#define ID_CRNG                MakeID('C','R','N','G')
+
+typedef BOOL (*ResizeProc)();
+
+typedef struct {
+    LONG flags;
+    struct BitMap *bitmap;
+    SHORT w;                   /* pixel width of bitmap */
+    UBYTE xAspect, yAspect;
+    Masking masking;
+    UBYTE *mask;
+    UBYTE xpcolor;
+    Point2D pos;
+    Point2D grab;
+    Range *ranges;
+    SHORT nRange;
+    } MaskBM;
+    
+extern BOOL PutMaskBM(LONG, MaskBM *, WORD *, BYTE *, LONG);
+/*                  file, maskBM, colorMap, buffer, bufsize */
+extern BOOL GetMaskBM(LONG, MaskBM *, WORD *, ResizeProc,  BYTE *,LONG );
+/*     file  maskBM  colorMap   reSize()  buffer  bufsize      */
diff --git a/DPINIT.C b/DPINIT.C
new file mode 100644 (file)
index 0000000..b36912a
--- /dev/null
+++ b/DPINIT.C
@@ -0,0 +1,438 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*             dpinit.c -- initialization code                         */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+#include <librarie\dosexten.h>
+#include <dphook.h>
+#include <workbenc\startup.h>
+       
+#define CLOSEWBNCH
+
+#define local static
+#define MaxWidth       640
+#define MaxHeight      400
+
+extern BOOL modeHelp;
+extern void mainRefresh();
+extern struct Menu *MainMenu; 
+extern BMOB curpenob,curbr,origBr;
+extern void mainCproc(),mainPproc(),mainMproc();
+extern long GfxBase;
+extern long IntuitionBase;
+extern long IconBase;
+
+struct Window *OpenWindow();
+struct InputEvent *Intuition();
+struct Screen *OpenScreen();
+
+extern struct Window *mainW;
+extern struct Screen *screen;
+extern struct RastPort *mainRP;
+extern struct ViewPort *vport;
+extern BOOL haveWBench;
+extern BOOL underWBench;
+extern Box mainBox;
+extern Pane mainP;
+extern SHORT curFormat;                /* current screen format */
+extern SHORT curDepth;
+extern SHORT curMBarH;
+extern SHORT xShft,yShft;
+extern SHORT nColors;
+    
+extern SHORT prevColors[32];
+extern UBYTE initBGCol[], initFGCol[];
+extern Box screenBox;
+extern struct BitMap hidbm;
+extern struct TmpRas tmpRas;
+extern struct RastPort tempRP;
+extern struct RastPort screenRP;
+
+extern UBYTE picname[];
+extern struct TextAttr TestFont;
+extern SHORT fmt,deep;
+extern struct Process *myProcess;
+extern struct Window *svWindowPtr;
+extern UBYTE dpaintTitle[];
+
+local struct NewScreen ns = {
+    0, 0,              /* start position               */
+    640, 200, 3,       /* width, height, depth         */
+    0, 1,              /* detail pen, block pen        */
+    HIRES,             /* viewing mode                 */
+    CUSTOMSCREEN,      /* screen type                  */
+    &TestFont,         /* font to use                  */
+    dpaintTitle,       /* default title for screen     */
+    NULL               /* pointer to additional gadgets */
+    };
+
+local struct NewWindow nw = {0};
+
+TryOpenLib(name) char *name; {
+    LONG libadr = OpenLibrary(name, 0);
+    if (libadr == NULL) { InfoMessage("Can't open library",name); exit(); }
+    return(libadr);
+    }
+
+CloseWB() {
+    struct Window *tw,*dosWin;
+    if (!underWBench) {
+       nw.Type = WBENCHSCREEN;
+       nw.Width = nw.Height = 1;
+       tw = OpenWindow(&nw);
+       dosWin = tw->Parent;
+       CloseWindow(tw);
+       CloseWindow(dosWin);
+       }
+    if (CloseWorkBench()) haveWBench = NO;
+    else InfoMessage(" Couldn't close", "WorkBench");
+    }
+
+BailOut() { 
+    myProcess->pr_WindowPtr = (APTR)svWindowPtr;
+    OpenWorkBench(); 
+    CloseLibrary(GfxBase);
+    CloseLibrary(IntuitionBase);
+    exit(); 
+    }
+
+extern MagContext magCntxt;
+extern Pane magP;
+extern void magRefresh();
+extern void RecChange();
+
+InitMag() {
+    magCntxt.srcRP = mainRP;
+    magCntxt.srcBox = &mainP.box;
+    magCntxt.magBM = mainRP->BitMap;
+    magCntxt.magBox = &magP.box;
+    magCntxt.updtProc = &RecChange;
+    magCntxt.srcPos.x = 0;
+    magCntxt.srcPos.y = curMBarH;
+    magCntxt.magN = PMapX(10);
+    PaneCreate(&magP, &screenBox ,HANGON, mainCproc, mainMproc, magRefresh, MAGWIN);
+    SetMagContext(&magCntxt);
+    MagState(NO);
+    }
+
+struct TextFont *screenFont= NULL;
+        
+InitScreenFont() {
+    screenFont = (struct TextFont *)OpenFont(&TestFont);
+    SetFont(&screenRP, screenFont);
+    }
+
+/*------initialize current brush ----------------*/
+extern struct BitMap brSVBM,brBM,penSVBM,penBM;
+extern BMOB curbr,curpenob;
+
+/** init default picture path **/
+extern UBYTE picpath[], *picpths[];
+local UBYTE *picpths[3] = {"lo-res","med-res","hi-res"};
+InitPicPath() {strcpy(picpath,picpths[curFormat]); }
+
+extern struct BitMap *clientBitMap;
+extern DPHook *dphook;
+extern BOOL myDPHook;
+extern UBYTE DPName[];
+extern BOOL largeMemory, loadAFile;
+
+#ifdef DOWB
+extern struct WBStartup *WBenchMsg;
+#endif
+#define HALFMEG (1<<19)
+    
+DPInit(argc,argv) int argc; char *argv[]; {
+    SHORT fmt,deep;
+    SHORT initbg,initfg;
+    BOOL closeWB= NO,doOverlay = NO, keepWB = NO;
+    LONG avMem;
+    
+    FreeUpMem(); /* free up any memory with 0 ref count */
+    
+    avMem = AvailMem(MEMF_PUBLIC);
+    largeMemory =  (avMem>(256*1024));
+    
+    GfxBase = TryOpenLib("graphics.library");
+    IntuitionBase = TryOpenLib("intuition.library");
+    IconBase = TryOpenLib("icon.library");
+
+    myProcess = (struct Process *)FindTask(0);
+    svWindowPtr = (struct Window *)myProcess->pr_WindowPtr;
+
+    fmt = 0; deep = 5;         /* default to LORES, 5 planes */
+
+#ifdef DOWB
+    /* --- Test if we were called from the CLI or WORKBENCH --- */
+    if (argc==0) {
+       underWBench = YES;
+       if (WBenchMsg->sm_NumArgs>0) {
+           strcpy(picname,WBenchMsg->sm_ArgList->wa_Name);
+           loadAFile = YES;
+           }                       
+       }
+    else { underWBench = NO;   }
+#endif    
+    
+    /* -----  See if Deluxe Video or anybody has planted hook */
+
+    dphook = (DPHook *)FindHook(DPName);
+    
+    if ((dphook!=NULL)/*&&largeMemory*/) {
+       fmt = dphook->format;
+       clientBitMap = dphook->bitmap;
+       if (clientBitMap != NULL) {
+           hidbm = *clientBitMap; /* copy record, not pointer */
+           deep = MIN(hidbm.Depth,5);
+           doOverlay = YES;
+           }
+       else InfoMessage(" Null Client"," Bitmap");
+       }
+    else {
+       if (argc>1)
+           switch(*argv[1]) {
+               case 'l': fmt = 0; break;
+               case 'm': fmt = 1; break;
+               case 'h': fmt = 2; break;
+               }
+    
+       if (argc>2) deep = MAX(MIN((*argv[2]-'0'),5),1);
+
+       if (argc>3)  switch (*argv[3]) {
+           case 'c': closeWB = YES; break;
+           case 'o': doOverlay = YES; break;
+           case 'n': keepWB = YES; break;
+           default: doOverlay = closeWB = YES; break;
+           }
+               
+       if (!largeMemory) { /* 256K machine */
+           if (fmt==2) BailOut(); /* no way */
+           else closeWB = doOverlay = YES;
+           }
+
+       else if ((avMem<HALFMEG)&&(fmt==2)&&(deep>3)) closeWB = doOverlay = YES;
+    
+       }
+
+    if (closeWB&&(!keepWB)) CloseWB();
+
+    SetOverlay(doOverlay);
+    
+    SetFormat(fmt,deep); /* opens Screen, mainW, allocs hidbm, tmpRas */
+
+    
+    if (dphook==NULL) { /* --- plant my own hook --- */
+       myDPHook = YES;
+       dphook = (DPHook *)DAlloc(sizeof(DPHook),MEMF_PUBLIC);
+       dphook->bitmap = &hidbm;
+       dphook->dpScreenBitMap = mainRP->BitMap;
+       dphook->format = fmt;
+       dphook->refCount = 0;
+       dphook->version = 1;
+       SetHook(DPName,dphook);
+       }
+    else {
+       myDPHook = NO;
+       dphook->refCount++;
+       }
+    
+    dphook->vport = vport;
+    dphook->brush = &curbr;
+    
+    InitMenu(); 
+    
+    BasicBandW();
+
+    SetMenuStrip(mainW, MainMenu);
+
+    InitRastPort(&tempRP);     /* multi-purpose RasterPort */
+    InitRastPort(&screenRP);   /* always points at bare screen bitmap */
+    screenRP.BitMap = mainRP->BitMap;
+   
+    InitScreenFont();
+    initbg = initBGCol[curDepth];
+    initfg = initFGCol[curDepth];
+    SetRast(mainRP,initbg);
+    tempRP.BitMap = &hidbm;
+
+    if (clientBitMap==NULL) SetRast(&tempRP,initbg);
+
+    PaneCreate(&mainP,&mainBox,HANGON,mainCproc,mainMproc,
+               mainRefresh,MAINWIN);
+    PaneInstall(&mainP);
+
+    InitPGraph();
+    PushGrDest(mainRP,&mainBox);
+    SolidPattern();
+
+    CPInit();  
+    InitMag();
+
+    CPChgPen(0);
+    CPChgCol(initfg);
+    CPChgBg(initbg);
+
+    SymSet(6, YES, PMapX(MaxWidth/2), PMapY(MaxHeight/2));
+
+    TogBoth(); /* show the control panel initially */
+    ResetCursor();
+    SetModeMenu(modeHelp ? Color: Mask);
+    DispPntMode();
+       }
+
+local USHORT fmtMode[3] = {0,HIRES,HIRES|LACE};
+local SHORT fmtXShft[3] = {1,0,0};
+local SHORT fmtYShft[3] = {1,1,0};
+
+#ifdef ldkfg
+CloseDisp() {        
+    ShowTitle(screen,NO);
+    ClearMenuStrip(mainW);
+    CloseFont(screenFont);
+    KillCCyc();
+    FreeSpare();
+    BMOBFreeTmp();
+    FreeBMOB(&origBr);
+    FreeBMOB(&curbr);
+    FreeBMOB(&curpenob);
+    FreeBitMap(&hidbm);
+    FreeTmpRas();
+    myProcess->pr_WindowPtr = (APTR)svWindowPtr;
+    CloseWindow(mainW);
+    CloseScreen(screen); 
+    }
+
+ShutDown() {
+    FreeFonts();
+    CloseLibrary(GfxBase);
+    CloseLibrary(IntuitionBase);
+    OpenWorkBench();
+    }
+
+#endif
+    
+CloseDisplay() {
+    ShowTitle(screen,NO);
+    ClearMenuStrip(mainW);
+    FreeFonts();
+    KillCCyc();
+    FreeSpare();
+    BMOBFreeTmp();
+    FreeBMOB(&origBr);
+    FreeBMOB(&curbr);
+    FreeBMOB(&curpenob);
+    
+    if (clientBitMap == NULL) FreeBitMap(&hidbm);
+    if (myDPHook){ RemHook(DPName);DFree(dphook);}
+    else dphook->refCount--;
+    
+    FreeTmpRas();
+    myProcess->pr_WindowPtr = (APTR)svWindowPtr;
+    CloseWindow(mainW);
+    CloseScreen(screen); 
+    CloseLibrary(GfxBase);
+    CloseLibrary(IntuitionBase);
+    OpenWorkBench();
+    }
+
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*  Memory requirement                                                 */
+/*
+    2*depth*pagesize   for visible display and hidbm
+    pagesize           for tmpRas
+    (depth*pagesize)/WorkSpaceFactor   for brush (minimal)
+    MINSPACE           spare for overlays,menus, etc, fixed size
+
+    total = depth*(2*pagesize + pagesize/WorkSpaceFactor) + MINSPACE + pagesize;
+    max depth = (memavail-pagesize-MINSPACE)/(2*pagesize + pagesize/WorkSpaceFactor);
+
+                           (mem-pagesize-MINSPACE)
+       =       -----------------------------------------
+                 (2*pagesize + pagesize/WorkSpaceFactor)
+------------------------------------------------------------------------*/
+
+/* require 1/3 of screen worth of workspace */
+#define WorkSpaceFactor 3
+
+/* minimum additional space of 12k */
+#define MINSPACE 12*1024
+
+/*----assumes screenBox already setup */
+int MaxDepth(fmt) SHORT fmt; {
+    ULONG psz = PlaneSize(screenBox.w,screenBox.h);
+    ULONG mem = AvailMem(MEMF_CHIP|MEMF_PUBLIC);
+    return((int) ( (mem-psz-MINSPACE)/(2*psz + psz/WorkSpaceFactor)) );
+    }
+SetFormat(fmt,depth) 
+    SHORT fmt;   /* 0 => 320x200xn, 1 => 640x200xn, 2 => 640x400xn*/
+    SHORT depth;  /* number of planes  */ 
+    {
+    if (fmt>0) depth = MIN(depth,4);
+    ns.ViewModes = fmtMode[fmt];
+    curFormat = fmt;
+    xShft = fmtXShft[fmt];
+    yShft = fmtYShft[fmt];
+    screenBox.w = ns.Width = PMapX(MaxWidth);
+    screenBox.h = ns.Height = PMapY(MaxHeight);
+    curMBarH =  /*(curFormat==2)? 19:*/ 11;
+    mainBox.x = 0;
+    mainBox.y = curMBarH;
+    mainBox.w = screenBox.w;
+    mainBox.h = screenBox.h - mainBox.y;
+
+    depth = MIN(MaxDepth(fmt),depth);
+    if (depth==0) BailOut(); 
+    
+    ns.Depth = curDepth = depth;
+    
+    screen = OpenScreen(&ns); 
+    if (screen == NULL)  BailOut();
+    
+    nw.Screen = screen;        
+    nw.DetailPen = 0;
+    nw.BlockPen = 1;
+
+#ifdef THEIRWAY
+    nw.LeftEdge = screenBox.x;
+    nw.TopEdge = screenBox.y + curMBarH ;
+    nw.Width = screenBox.w;
+    nw.Height = screenBox.h - curMBarH;
+#else
+    nw.LeftEdge = screenBox.x;
+    nw.TopEdge = screenBox.y;
+    nw.Width = screenBox.w;
+    nw.Height = screenBox.h;
+#endif
+
+    nw.IDCMPFlags = RAWKEY |MOUSEBUTTONS |MENUPICK |
+       MENUVERIFY | REFRESHWINDOW| ACTIVEWINDOW | INACTIVEWINDOW;
+    nw.Flags = ACTIVATE |BACKDROP |BORDERLESS |REPORTMOUSE|
+       /* NOCAREREFRESH |*/  SIMPLE_REFRESH | RMBTRAP; 
+    nw.Type = CUSTOMSCREEN;    /* type of screen in which to open */   
+    mainW = OpenWindow(&nw);   /* open a window */
+
+    if (mainW == NULL) BailOut();
+
+    /* fix so Dos message requestors come up in my window */
+    myProcess->pr_WindowPtr = (APTR)mainW; 
+    
+    mainRP = mainW->RPort;
+    vport = &mainW->WScreen->ViewPort;
+    
+    nColors = 1<<depth;
+
+    /* initialize hidden raster */
+    if (clientBitMap==NULL) NewSizeBitMap(&hidbm,depth,screenBox.w,screenBox.h); 
+    AllocTmpRas();
+    mainRP->TmpRas = &tmpRas;  /* temp raster for area filling*/
+    InitPicPath();
+    DefaultPalette();
+    }
+
+
diff --git a/DPINIT2.C b/DPINIT2.C
new file mode 100644 (file)
index 0000000..cbfe0fa
--- /dev/null
+++ b/DPINIT2.C
@@ -0,0 +1,126 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*             dpinit2.c -- initialization                             */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+#include <system.h>
+#include <prism.h>
+
+#define local static
+#define fudgeFact 10
+
+extern struct Menu *MainMenu;
+extern SHORT curFormat;
+
+extern struct RastPort *mainRP;
+extern struct TextAttr curMIFont;
+extern SHORT xShft,yShft;
+extern struct Menu menus[];
+extern struct Screen *screen;
+
+SHORT widCorrect[3] = {-4,0,12};
+SHORT menuHeight[3] = {10,10,16};
+SHORT checkW[3] = {LOWCHECKWIDTH,CHECKWIDTH,CHECKWIDTH};
+SHORT curMIH;
+
+SHORT ComWidth() { return((SHORT)( (curFormat>0)? COMMWIDTH: LOWCOMMWIDTH)); }
+
+SHORT MaxMiLength(mi) struct MenuItem *mi; {
+    struct IntuiText *it;
+    SHORT w,max;
+    for (max = 0; mi != NULL;  mi = mi->NextItem) {
+       it = (struct IntuiText *)(mi->ItemFill);
+       w = TextLength(mainRP,it->IText,strlen(it->IText))+12;
+       if (mi->Flags&COMMSEQ) w += ComWidth();
+       if (mi->Flags&CHECKIT) w += checkW[curFormat];
+       max = MAX(w,max);
+       }
+    return((SHORT)(max-10));
+    }
+    
+InitMItems(mi,minW) struct MenuItem *mi; SHORT minW; {
+    SHORT i , y, x;
+    SHORT wid = MAX(MaxMiLength(mi) /*+widCorrect[curFormat]*/, minW );
+    y = mi->TopEdge;
+    x = mi->LeftEdge;
+    for ( i=0 ; mi != NULL;  ++i, mi = mi->NextItem) {
+       if ((mi->Flags&ITEMTEXT)&&(mi->Flags&CHECKIT))
+        ((struct IntuiText *)(mi->ItemFill))->LeftEdge = checkW[curFormat];
+       mi->TopEdge = y; 
+       mi->LeftEdge = x; 
+       mi->Width = wid;
+       if (mi->Flags&COMMSEQ) mi->Width += ComWidth();
+       mi->Height = curMIH;
+       ((struct IntuiText *)(mi->ItemFill))->ITextFont = &curMIFont;
+       y += curMIH;
+       if (mi->SubItem!=NULL) InitMItems(mi->SubItem,0);
+       }
+    }
+
+
+InitMenu() {
+    SHORT i = 0,xl = PMapX(12);
+    struct Menu *mn = MainMenu;
+    curMIH =  menuHeight[curFormat];
+    for (mn = menus; mn != NULL; ++i,mn = mn->NextMenu ) {
+       mn->LeftEdge = xl; 
+       mn->Width = TextLength(screen->BarLayer->rp,
+           mn->MenuName,strlen(mn->MenuName)) +
+           widCorrect[curFormat] + fudgeFact;
+       xl += mn->Width;
+       mn->Flags = MENUENABLED;
+       InitMItems(mn->FirstItem, mn->Width);
+       }
+    }
+
+
+
+/* ----------------- Control Panel Inititialization -------------------*/
+    
+local BYTE nrowTab[] = {1,2,4,4,8,8};
+local BYTE ncolTab[] = {1,1,1,2,2,4};
+
+extern SHORT NXMag,NYMag;
+extern BOOL cpShowing;
+extern SHORT penH,actH,colDspH,colBoxH,actUH,colNRows,curDepth,colNColumns;
+extern SHORT colUW,penUW,actUW,cpWidth;
+extern Pane penwin,actwin,cdspwin,colwin;
+extern void penMproc(), PenWPaint(), actMproc(), ActWPaint();
+extern void cDspMproc(), cDspPaint(),colMproc();
+extern void mainCproc(), ColWPaint();
+
+/* Initialize the control panel geometry and create Windows */
+
+CPInit(){
+    Box bx;
+    SHORT colBoxH;
+    cpShowing = NO;
+    NXMag =  NYMag = 1;
+    if (curFormat==2) NYMag = 2;
+    if (curFormat!=0) NXMag = 2;
+
+    /* penH + actH + colDspH = colBoxH = 400 */
+
+    penH = PMapY(40);
+    actH = PMapY(216); 
+
+    colDspH = PMapY(24);
+    colBoxH = PMapY(120);
+
+    actUH = PMapY(24);
+    colNRows = nrowTab[curDepth];
+    colNColumns = ncolTab[curDepth];
+    cpWidth = PMapX(48)+1;
+    colUW = (cpWidth-1)/colNColumns;
+    penUW = (cpWidth-1)/3;
+    actUW = (cpWidth-1)/2;
+    PaneCreate(&penwin,MakeBox(&bx,0,0,cpWidth,penH),HANGON,&mainCproc,
+       penMproc,PenWPaint,NULL);
+    PaneCreate(&actwin,MakeBox(&bx,0,penH,cpWidth,actH),HANGON,&mainCproc,actMproc,
+       ActWPaint,NULL);
+    PaneCreate(&cdspwin,MakeBox(&bx,0,penH+actH,cpWidth,colDspH),HANGON,&mainCproc,
+       cDspMproc, cDspPaint,NULL);
+    PaneCreate(&colwin,MakeBox(&bx,0,penH+actH+colDspH,cpWidth,colBoxH),HANGON,
+       mainCproc,colMproc,ColWPaint,NULL);
+    }
+
diff --git a/DPIO.C b/DPIO.C
new file mode 100644 (file)
index 0000000..b62677b
--- /dev/null
+++ b/DPIO.C
@@ -0,0 +1,351 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*             dpio.c -- Picture and Brush IO                          */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+#include "librarie\dos.h" /* for file io */
+#include <dpiff.h>
+#include <fnreq.h>
+
+extern struct Window *mainW;
+extern SHORT nColors;
+extern struct TmpRas tmpRas;
+extern SHORT  xShft, yShft, nColors;
+extern struct ViewPort *vport;
+extern BMOB curbr;
+extern struct BitMap hidbm;
+extern Box screenBox;
+extern BOOL skipRefresh;
+extern SHORT curFormat,curxpc,curpen,curDepth;
+extern SHORT LoadBrColors[], prevColors[];
+extern Range cycles[];
+    
+UBYTE loadStr[] = "Load";
+UBYTE saveStr[] = "Save";
+
+#define local static
+
+
+BOOL CombPathName(comb,path,finame) UBYTE *comb,*path,*finame; {
+    if (strlen(finame) <= 0) return(NO);
+    strcpy(comb,path);
+    ConcatPath(comb,finame);
+    return(YES);
+    }
+
+BOOL DoFnReq(title,doname,path,name) UBYTE *title,*doname,*path,*name; {
+    BOOL res;
+    UndoSave();
+    FreeTmpRas(); /* make room for Intuition to save screen under req*/
+    res = (BOOL)FN_Request(mainW,PMapX(20),PMapY(24),
+                               path,name,NULL,title,NULL, doname);
+    AllocTmpRas();
+    magRefresh();
+    mainRefresh();
+    return(res);
+    }
+
+/*----------------------------------------------------------------------*/
+/*  Picture                                                            */
+/*----------------------------------------------------------------------*/
+extern UBYTE picpath[31];
+extern UBYTE picname[31];
+    
+ZapPicName() { picname[0] = 0; }
+
+BOOL MakePicName(nm) UBYTE nm[]; {return(CombPathName(nm,picpath, picname));}
+
+BOOL DoPicFnReq(title,doname) UBYTE *title, *doname;{
+    return(DoFnReq(title,doname,picpath,picname)); 
+    }
+
+    
+/* ILBM IO */
+
+/* try to resize the pic to fit the one being read in */
+local BOOL badFit;
+BOOL ResizePic(mbm,bmhdr) MaskBM *mbm; BitMapHeader *bmhdr; {
+    if ((bmhdr->h == hidbm.Rows)&&(bmhdr->w == hidbm.BytesPerRow*8))
+       {
+       if (bmhdr->nPlanes< hidbm.Depth) ClearBitMap(&hidbm);
+       return(SUCCESS);
+       }
+    else return(FAIL);
+    }
+
+NoOpen(name) char *name; { InfoMessage(" Couldn't Open file:",name); }
+    
+NoSave(name) char *name; { InfoMessage(" Couldn't Save to file:",name); }
+    
+LoadPicNamed(name) char *name; {
+    LONG file;
+    MaskBM mbm;
+    WORD colors[32];
+    file = Open(name, MODE_OLDFILE);
+    if (file==0) { NoOpen(name); picname[0]=0; return(FAIL);}
+    ZZZCursor();
+    GetColors(colors); /* default values if fewer planes loaded */
+    mbm.flags = MBM_HAS_CMAP;
+    mbm.bitmap = &hidbm;
+    mbm.ranges = cycles;
+    mbm.nRange = MAXNCYCS;
+    badFit = NO;
+    if (SUCCESS == GetMaskBM(file, &mbm, colors,
+                        &ResizePic,tmpRas.RasPtr, tmpRas.Size)) {
+       KillCCyc();
+       GetColors(prevColors);
+       LoadRGB4(vport,colors,nColors);
+       }
+    else {
+       if (IffErr()==BAD_FIT) InfoMessage(" Wrong format:", name);
+       else InfoMessage(" Couldn't load file",name);
+       ZapPicName();
+       }
+    Close(file);
+    UnZZZCursor();
+    }
+
+local BYTE xAspRat[3] = {x320x200Aspect,x640x200Aspect,x640x400Aspect};
+local BYTE yAspRat[3] = {y320x200Aspect,y640x200Aspect,y640x400Aspect};
+
+BOOL SavePicNamed(name) char *name; {
+    LONG file;
+    WORD colors[32];
+    BOOL res;
+    MaskBM mbm;
+    GetColors(colors);
+    ZZZCursor();
+    file = Open(name, MODE_NEWFILE);
+    if (file==0) { NoSave(name); return(FAIL); }
+    mbm.flags = MBM_HAS_CMAP|MBM_HAS_RANGES;
+    mbm.nRange = MAXNCYCS;
+    mbm.ranges = cycles;
+    mbm.bitmap = &hidbm;
+    mbm.w = hidbm.BytesPerRow*8;
+    mbm.mask = NULL;
+    mbm.masking = mskHasTransparentColor;
+    mbm.xpcolor = curxpc;
+    mbm.pos.x = mbm.pos.y = 0;
+    res  = PutMaskBM(file, &mbm, colors, (UBYTE *)tmpRas.RasPtr, tmpRas.Size);
+    if (res) {
+       InfoMessage(" Couldn't save file",name);
+       ZapPicName();
+       }
+    else WriteProjectIcon(picpath,picname);
+    Close(file);
+    UnZZZCursor();
+    return(res);
+    }
+
+ChkFNRes(res) BOOL res; {
+    if (res== FN_NoSuchDrawer) {
+       InfoMessage(" Non existent drawer","");
+       }
+    }
+
+#ifdef DOWB
+LoadPic() {
+    UBYTE nm[60];
+    OffRefrAfterOv();
+    if (MakePicName(nm)) {
+       LoadPicNamed(nm);
+       Str(picname);
+       }
+    OnRefrAfterOv();
+    PaneRefrAll();
+    }
+#endif
+    
+OpenPic() {  UBYTE nm[60];
+    BOOL res;
+    InitRead(); /* bring in the reader overlay*/
+    res  = DoPicFnReq("Load Picture",loadStr);
+    if (res == FN_OK) {
+       if (MakePicName(nm)) {
+           LoadPicNamed(nm);
+           StuffSaveStr(picname);
+           }
+       }
+    else ChkFNRes(res);
+    PaneRefrAll();
+    }
+
+local UBYTE bkdotpic[] = "backup.pic";
+
+extern BOOL largeMemory;
+    
+
+void SaveCurPic() {
+    UBYTE nm[60],bkupname[60];  
+    LONG lock;
+    LONG err;
+    if (MakePicName(nm)) {
+       lock = Lock(nm, ACCESS_WRITE);
+       if (lock) {
+           CombPathName(bkupname,picpath,bkdotpic);
+           UnLock(lock);
+           if (DeleteFile(bkupname) == 0) {
+               err = IoErr();
+               if (err != ERROR_OBJECT_NOT_FOUND)    return;
+               }
+           if (Rename(nm,bkupname) == 0) return;
+           }
+       SavePicNamed(nm);   
+       StuffSaveStr(picname);
+       }
+    else InfoMessage("Invalid File name", "");
+    }
+
+SavePicAs() {
+    BOOL res;
+    InitWrite(); /* bring in the writer overlay*/
+    res = DoPicFnReq("Save Picture", saveStr);
+    if (res == FN_OK)  SaveCurPic();
+    else ChkFNRes(res);
+    PaneRefrAll();
+    }
+
+SavePic() {  
+    InitWrite(); /* bring in the writer overlay*/
+    UndoSave();
+       if (strlen(picname) == 0) SavePicAs();
+    else {
+       if (!largeMemory) InfoMessage(" Insert data disk","in disk drive");
+       SaveCurPic();
+       }
+    PaneRefrAll();
+    }
+
+/*----------------------------------------------------------------------*/
+/*  Brush IO                                                           */
+/*----------------------------------------------------------------------*/
+extern UBYTE brspath[31];
+extern UBYTE brsname[31];
+
+ZapBrushName() { brsname[0] = 0; }
+BOOL MakeBrsName(nm) UBYTE nm[]; {return(CombPathName(nm,brspath, brsname));}
+BOOL DoBrsFnReq(title,doname) UBYTE *title,*doname;{return(DoFnReq(title,doname,brspath,
+       brsname));}
+
+
+SaveBrsNamed(name) char *name; {
+    LONG file; 
+    BOOL res;
+    WORD colors[32];
+    MaskBM mbm;
+    GetColors(colors);
+    ZZZCursor();
+    file = Open(name, MODE_NEWFILE);
+    if (file==0) { NoSave(name); return(FAIL); }
+    mbm.flags = MBM_HAS_CMAP|MBM_HAS_GRAB;
+    mbm.bitmap = curbr.pict.bm;
+    mbm.w = curbr.pict.box.w;
+    mbm.masking = mskHasTransparentColor;
+    mbm.mask = NULL;
+    mbm.xpcolor = curbr.xpcolor;
+    mbm.pos.x = mbm.pos.y = 0;
+    mbm.grab.x = curbr.xoffs;
+    mbm.grab.y = curbr.yoffs;
+    res = PutMaskBM(file, &mbm, colors,(UBYTE *)tmpRas.RasPtr,tmpRas.Size);
+    if (res) { brsname[0] = 0; InfoMessage(" Couldn't save file",name);}
+    else WriteBrushIcon(brspath,brsname);
+    Close(file);
+    UnZZZCursor();
+    }
+
+/* try to resize the brush to fit the one being read in */
+
+local BOOL cantFit;
+
+#ifdef SIMPLEWAY
+BOOL ResizeBrush(mbm,bmhdr) MaskBM *mbm; BitMapHeader *bmhdr; {
+    if (BMOBNewSize(&curbr, bmhdr->nPlanes, bmhdr->w,bmhdr->h)) {
+       cantFit = YES;
+       return(FAIL);
+       }
+    ClearBitMap(curbr.pict.bm);
+    mbm->mask = curbr.mask;
+    return(SUCCESS);
+    }
+
+#else
+BOOL ResizeBrush(mbm,bmhdr) MaskBM *mbm; BitMapHeader *bmhdr; {
+    SHORT depth = bmhdr->nPlanes;
+    do  {if (!BMOBNewSize(&curbr, depth, bmhdr->w, bmhdr->h)) 
+          goto alldone;
+       } while ((--depth)>=curDepth);
+    cantFit = YES;
+    return(FAIL);
+    alldone:
+       ClearBitMap(curbr.pict.bm);
+       mbm->mask = curbr.mask;
+       return(SUCCESS);
+    }
+#endif
+
+LoadBrsNamed(name) char *name; {
+    LONG file;
+    MaskBM mbm;
+    file = Open(name, MODE_OLDFILE);
+    if (file==0) { NoOpen(name); brsname[0] = 0; return(FAIL); }
+    ZZZCursor();
+    mbm.flags = 0;
+    mbm.bitmap = curbr.pict.bm;
+    mbm.mask = curbr.mask;
+    GetColors(LoadBrColors); /* default values if fewer planes loaded */
+    RestoreBrush();
+    cantFit = NO;
+    if (SUCCESS == GetMaskBM(file, &mbm, LoadBrColors,
+                        &ResizeBrush,tmpRas.RasPtr, tmpRas.Size))
+       {
+       if (mbm.flags&MBM_HAS_GRAB) {
+           curbr.xoffs = mbm.grab.x;
+           curbr.yoffs = mbm.grab.y; 
+           }
+       else {
+           curbr.xoffs = curbr.pict.bm->BytesPerRow*4;
+           curbr.yoffs = curbr.pict.bm->Rows/2;
+           }
+       curbr.xpcolor = mbm.xpcolor;
+       if (mbm.masking == (UBYTE)mskHasTransparentColor) BMOBMask(&curbr);
+       UserBr();
+       }
+    else { 
+       InfoMessage(" Couldn't load brush",name); 
+       if (cantFit) {
+           SelPen(0); 
+           SetNextIMode(IM_draw); 
+           }
+       else ZapBrushName(); 
+       }
+    Close(file);
+    UnZZZCursor();
+    }
+    
+GetBrs() { BOOL res;
+    UBYTE nm[60];
+    InitRead(); /* bring in the reader overlay*/
+    res = DoBrsFnReq("Load Brush",loadStr);
+    if (res==FN_OK) {if (MakeBrsName(nm)) LoadBrsNamed(nm);}
+    else ChkFNRes(res);
+    PaneRefrAll();
+    }
+
+void SaveBrsAs() {  UBYTE nm[60];
+    BOOL res;
+    InitWrite(); /* bring in the writer overlay*/
+    if (curpen!=USERBRUSH) {
+       InfoMessage(" Cant save Built-in", "   brushes ");
+       }
+    else {
+       res = DoBrsFnReq("Save Brush", saveStr);
+       if (res == FN_OK) {if (MakeBrsName(nm)) SaveBrsNamed(nm);}
+       else ChkFNRes(res);
+       }
+     PaneRefrAll();
+    }
+
+
diff --git a/FILL.C b/FILL.C
new file mode 100644 (file)
index 0000000..ea77a3b
--- /dev/null
+++ b/FILL.C
@@ -0,0 +1,197 @@
+/*--------------------------------------------------------------*/
+/*                     Basic Seed Fill                         */
+/*                                                             */
+/*     FillArea: fills all pixels which are the same color as  */
+/*     and 4-connected to the seed pixel                       */
+/*--------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+#define STSIZE 160
+#define UP     1
+#define DN     -1
+
+#define local static
+
+extern SHORT ReadPixel();
+
+extern struct TmpRas tmpRas;
+extern struct RastPort *curRP, tempRP;
+extern Box clipBox;
+extern UWORD masks[];
+extern BOOL abortFlag;
+
+local SHORT fxmax,fymax,fxmin,fymin;
+local SHORT intoCol;
+
+
+OvflMsg() { KPrintF(" FILL Overflow"); }
+
+/** --------- Stack ----------------- */
+
+typedef struct{SHORT dir,xl,xr,y;} Span;
+local Span *stack;
+
+
+/* ----------Queue----------------- */
+SHORT oldest, nextVacant;
+local initStack(ps) Span *ps; { stack = ps; oldest = nextVacant = 0; }    
+
+#define StackNotEmpty  (oldest != nextVacant)
+
+local popSpan(d,xll,xrr,yy) SHORT *d,*xll,*xrr,*yy; {
+    Span *spn = &(stack[oldest]);
+    *d = spn->dir;
+    *xll = spn->xl;
+    *xrr = spn->xr;
+    *yy = spn->y;
+    oldest = (oldest+1)%STSIZE;
+    }
+
+local pushSpan(d,xll,xrr,yy) SHORT d,xll,xrr,yy; {
+    Span *spn = &(stack[nextVacant]);
+    spn->dir = d;
+    spn->xl = xll;
+    spn->xr = xrr;
+    spn->y =yy;
+    nextVacant = (nextVacant+1)%STSIZE;
+    if (nextVacant == oldest) {
+       if (--nextVacant<0) nextVacant = STSIZE-1;
+       OvflMsg();
+       }
+    }
+
+#ifdef slowButCorrect
+
+/* ----- "Inside" test for area fill  */
+#define Inside(x,y) (ReadPixel(&tempRP,x,y)==intoCol)
+
+local SHORT  firstRight(x,y) SHORT x,y; {
+    while( (x<=fxmax)&&(!Inside(x,y))) x++ ;  return(x); }
+local SHORT firstLeft(x,y) SHORT x,y; {
+    while( (x>=fxmin)&&(!Inside(x,y))) x-- ;  return(x);  }
+local SHORT lastRight(x,y) SHORT x,y; {
+    while( (x<=fxmax)&&Inside(x,y)) x++ ; return((SHORT)(x-1)); }
+local SHORT lastLeft(x,y) SHORT x,y; {
+    while( (x>=fxmin)&&Inside(x,y)) x-- ;  return((SHORT)(x+1)); }
+
+#else /* fast and complicated */
+
+local UWORD *WrdAddr(x,y) SHORT x,y; {
+    return((UWORD *)( ((ULONG)(tempRP.BitMap->Planes[0])) +
+           (ULONG)(y*tempRP.BitMap->BytesPerRow) +((x>>3)&0xfffe)));
+    }
+
+/* Search for the first bit not matching 'pat'  to the right */
+local SHORT searchRight(x,y,pat) register SHORT x; SHORT y; register UWORD pat; {
+    register UWORD *wp,wrd;
+    wp = WrdAddr(x,y);
+    wrd = (pat^(*wp++))&masks[x&15]; /* turns all pat bits to 0's */
+    x = (x+16)&0xfff0;
+    while ( (wrd == 0) && (x <= fxmax) ) {wrd = pat^(*wp++); x += 16; }
+    x -= 16;
+    if (wrd) while ( (wrd & 0x8000) == 0 ) { wrd <<= 1; x++; }
+    else return((SHORT)(fxmax+1));
+    return((SHORT)MIN(x,fxmax+1));
+    }
+
+/* Search for the first bit not matching 'pat'  to the left */
+local SHORT searchLeft(x,y,pat) register SHORT x; SHORT y; register UWORD pat; {
+    register UWORD *wp,wrd;
+    wp = WrdAddr(x,y);
+    wrd = (pat^(*wp--))&(~masks[(x&15)+1]);
+    x = (x&0xfff0) - 1;
+    while ( (wrd == 0) && (x >= fxmin) ) { wrd = pat^(*wp--); x -= 16; }
+    x += 16;
+    if (wrd) while ( (wrd & 1) == 0 ) { wrd >>= 1; x--; }
+    else return((SHORT)(fxmin-1));
+    return((SHORT)MAX(x,fxmin-1));
+    }
+
+/* --- find the first '0' i.e. "inside" bit to left (right) */
+#define firstLeft(x,y)  searchLeft(x,y,0xffff)
+#define firstRight(x,y)  searchRight(x,y,0xffff)
+
+/* --- find the last contiguous '0' i.e. "inside" bit to left (right) */
+#define lastLeft(x,y)  (searchLeft(x,y,0) + 1)
+#define lastRight(x,y)  (searchRight(x,y,0) - 1)
+    
+#endif
+
+local fillStrip(xl,y,xr) SHORT xl,y,xr; {
+    PatHLine(xl,y,xr-xl+1);
+    Move(&tempRP,xl,y); Draw(&tempRP,xr,y);
+    }
+
+void FillArea(sx,sy) 
+    SHORT sx,sy;               /* seed point */
+    {
+    SHORT y,xr,xl,yn,xml,xmr,xtl,xtr,dir;    
+    struct BitMap tempBM,*curbm;
+    Span dstack[STSIZE];
+    
+    intoCol = ReadPixel(curRP,sx,sy);
+    if (intoCol==curRP->FgPen) return;
+    fxmin = clipBox.x;
+    fymin = clipBox.y;
+    fxmax = clipBox.x + clipBox.w -1;
+    fymax = clipBox.y + clipBox.h -1;
+    if ( sx<fxmin || sx>fxmax || sy<fymin || sy>fymax ) return;
+    
+/* make a mask in the TmpRas that has 1's where the target bitmap is NOT
+   the color of the area being filled */
+    curbm = curRP->BitMap;
+    MakeMask(curbm, tmpRas.RasPtr, intoCol, NEGATIVE);
+    movmem(curbm,&tempBM,sizeof(struct BitMap));
+    tempBM.Depth = 1;
+    tempBM.Planes[0] = tmpRas.RasPtr;
+    tempRP.BitMap = &tempBM;
+    intoCol = 0;
+    SetAPen(&tempRP,1);
+    
+    initStack(&dstack);
+    xl = lastLeft(sx,sy);  
+    xr = lastRight(sx,sy);
+    fillStrip(xl,sy,xr);
+    pushSpan(DN,xl,xr,sy);  
+    pushSpan(UP,xl,xr,sy);
+    while (StackNotEmpty) {
+
+       if (CheckAbort()) {  UnDisplay(); break;}
+
+       popSpan(&dir,&xl,&xr,&y);
+       yn =  y + dir;
+       if ((yn<fymin)|(yn>fymax)) continue;
+
+/** Note to me:  this search can run all the way to the edge if we are 
+    hitting a horiz wall, and the outside is all non fill-color.  The 
+    solution is to limit the search to the interval xl,xr.  **/
+
+       /*-- find first 'inside' pixel on new line at or to right
+           of left pixel of old line */
+       if ((xml = firstRight(xl,yn)) > xr) continue;
+
+/**  the firstLeft need not search past xl, and if it hits 
+nothing then the lastRight need not be done at all */
+
+       /* -- find last pixel of last interval of 'inside' pixels
+           on new line and adjoining old line */
+       xmr = lastRight(firstLeft(xr,yn),yn);
+
+       /* -- find the left end of the left most adjoining interval*/
+       xtl = xml = lastLeft(xml,yn);
+       for (;;) {
+           xtr = lastRight(xtl,yn);
+           pushSpan(dir,xtl,xtr,yn);
+           fillStrip(xtl,yn,xtr);
+           if (xtr==xmr) break;
+           xtl = firstRight(xtr+1,yn);
+           } 
+       xl -=2; xr +=2;
+       /* check for u-turns */
+       if ( (xml<=xl) && (firstLeft(xl,y)>=xml) ) pushSpan(-dir,xml,xl,yn);
+       if ( (xmr>=xr) && (firstRight(xr,y)<=xmr) ) pushSpan(-dir,xr,xmr,yn);
+       }
+    }
+           
diff --git a/FNBMS.C b/FNBMS.C
new file mode 100644 (file)
index 0000000..20cb7b9
--- /dev/null
+++ b/FNBMS.C
@@ -0,0 +1,43 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*        fnbms.c --  Bitmaps for file name requestor arrows   */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+short up0[16] = { 
+  0x0, 
+  0x7FFE, 
+  0x7E7E, 
+  0x7C3E, 
+  0x781E, 
+  0x700E, 
+  0x6006, 
+  0x4002, 
+  0x7E7E, 
+  0x7E7E, 
+  0x7E7E, 
+  0x7E7E, 
+  0x7E7E, 
+  0x7E7E, 
+  0x7FFE, 
+  0x0
+  };   
+
+short down0[16] = { 
+  0x0, 
+  0x7FFE, 
+  0x7E7E, 
+  0x7E7E, 
+  0x7E7E, 
+  0x7E7E, 
+  0x7E7E, 
+  0x7E7E, 
+  0x4002, 
+  0x6006, 
+  0x700E, 
+  0x781E, 
+  0x7C3E, 
+  0x7E7E, 
+  0x7FFE, 
+  0x0
+  }; 
diff --git a/FNREQ.C b/FNREQ.C
new file mode 100644 (file)
index 0000000..c99bcc5
--- /dev/null
+++ b/FNREQ.C
@@ -0,0 +1,794 @@
+/** fnreq.c ******************************************************************/
+/*                                                                           */
+/* A file name requester                                                     */
+/*                                                                           */
+/* Date      Who Changes                                                     */
+/* --------- --- ----------------------------------------------------------- */
+/* 28-Aug-85 mrp created from imagedit's dos requester                       */
+/* 15-Sep-85 DDS modified to do own event processing, take x,y coord.        */
+/*                                                                           */
+/*****************************************************************************/
+/*  1) define a file and a drawer                                            */
+/*                                                                           */
+/*     UBYTE mydrawer[31] = {""};                                            */
+/*     UBYTE myfile[31] = {"test.vcs"};                                      */
+/*                                                                           */
+/*  2) Issue a request, when the user picks your Load menu item              */
+/*                                                                           */
+/*  res  = FN_Request(mywindow,x,y,mydrawer,myfile,NULL,NULL,NULL,"Load");   */
+/*      where res = TRUE if user did action, FALSE if he cancelled           */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <system.h>
+#include <librarie\dos.h>
+#include <fnreq.h>
+#include <clib\ctype.h>
+
+#define local
+
+#define YES 1
+#define NO 0
+
+#define MAX(a,b)       ((a)>(b)?(a):(b))
+#define MIN(a,b)       ((a)<(b)?(a):(b))
+
+#define FN_GADGMIN 10  /* minimum gadget number used by this requester */
+#define FN_GADGMAX 29  /* maximum gadget number used by this requester */
+
+#define FN_CANCEL  10  /* user canceled the requester */
+#define FN_GOTNAME 11  /* user pressed return on name or picked OK gadget */
+#define FN_FILE    12  /* user selected filename gadget */
+#define FN_DRAWER  13  /* user selected drawer name gadget */
+#define FN_UP      14  /* user selected up one name gadget */
+#define FN_DOWN    15  /* user selected down one name gadget */
+#define FN_SLIDE   16  /* user did something to proportional gadget */
+
+#define HIWIDTH 320
+#define LOWIDTH 264
+#define REQW  LOWIDTH                 /* width of requester */ 
+#define REQH  147                      /* height of requester */
+
+#define MAXFNAMES 50   /* max number of file names in a dir */
+#define MAXSHOW 8      /* max number of file names visible in req*/
+
+local struct Window *reqwindow;       /* window requester is in */
+local struct Requester fn_req = {0};        /* the requester */
+local LONG forbug = 0;         /* fix 1.06 Intuition bug */
+local struct IntuiText fn_text[3];    /* requester text */
+local struct IntuiText gadg_text[2];  /* gadget text */
+
+local UBYTE deftitle[] = "FR";
+local UBYTE defcancel[] = "Cancel";
+local UBYTE defdoverb[] = "Ok";
+
+local LONG firstname=0;                 /* index of first name in the list */
+
+BOOL fndbg = NO;
+                                                        
+struct TextAttr reqfont = {            /* font to use for requester text */
+   "topaz.font",
+   TOPAZ_SIXTY,                        /* will be set to user's preference */
+   0,
+   0};
+
+local UBYTE undofile[26];
+local UBYTE undodrawer[26];
+
+local SHORT reqX = 0;                      /* leftedge of requester */
+local SHORT reqY = 0;                      /* topedge of requester */
+local SHORT reqWidth = LOWIDTH;
+
+local BOOL dosready = FALSE;          /* TRUE after requester is initialized */
+
+local UWORD reqpts[] = {              /* xy table of border and reqion lines */
+   2,1,
+   2,REQH-2,
+   REQW-3,REQH-2,
+   REQW-3,12,
+   2,12,
+   2,1,
+   REQW-3,1,
+   REQW-3,93,
+    2,93
+    };
+        
+local struct Border reqborder = {     /* border for the requester */
+   0,0,
+   0,1,
+   JAM1,
+   9,
+   (SHORT *)&reqpts,
+   NULL};
+
+/*=======================*/
+/*== CANCEL GADGET ======*/
+/*=======================*/
+
+local UWORD dt0box1[] = {0,0,0,0,0,0,0,0,0,0};
+local UWORD dt0box2[] = {1,2,0,2,0,0,1,0,1,2};
+   
+local struct Border dt0bor2 = {    /* Blue box */
+   0,0,
+   0,1,
+   JAM1,
+   5,
+   (SHORT *)&dt0box2,
+   NULL};
+local struct Border dt0bor1 = {    /* Orange box */
+   0,0,
+   3,0,
+   JAM1,
+   5,
+   (SHORT *)&dt0box1,
+   &dt0bor2};
+
+local struct Gadget cancelgadget = {
+   NULL,          
+   -58,-20,
+   48,17,         
+   GADGHCOMP | GRELBOTTOM | GRELRIGHT,     
+   RELVERIFY | GADGIMMEDIATE | ENDGADGET, 
+   REQGADGET | BOOLGADGET, 
+   (APTR)&dt0bor1,         
+   NULL,         
+   &gadg_text[0],
+   0,            
+   NULL,         
+   FN_CANCEL,    
+   NULL };       
+
+/*=========================*/
+/*== GOTNAME, GADGET ======*/
+/*=========================*/
+
+local UWORD dt1box1[] = {0,0,0,0,0,0,0,0,0,0};
+local UWORD dt1box2[] = {1,2,0,2,0,0,1,0,1,2};
+   
+local struct Border dt1bor2 = {     /* Blue box */
+   0,0,
+   0,1,
+   JAM1,
+   5,
+   (SHORT *)&dt1box2,
+   NULL};
+local struct Border dt1bor1 = {     /* Orange box */
+   0,0,
+   3,0,
+   JAM1,
+   5,
+   (SHORT *)&dt1box1,
+   &dt1bor2};
+
+local struct Gadget gotnamegadget = {
+   &cancelgadget,
+   10,-20,
+   64,17,          
+   GADGHCOMP | GRELBOTTOM,        
+   RELVERIFY | GADGIMMEDIATE | ENDGADGET, 
+   REQGADGET | BOOLGADGET, 
+   (APTR)&dt1bor1,         
+   NULL,          
+   &gadg_text[1], 
+   0,          
+   NULL,       
+   FN_GOTNAME, 
+   NULL };
+
+
+/*======================*/
+/*== FILE, GADGET ======*/
+/*======================*/
+
+#define FG_WIDTH 184
+#define FG_HEIGHT 13       
+
+
+local UWORD dt2box1[] = {
+   -2,-2,
+   FG_WIDTH+1,-2,
+   FG_WIDTH+1,FG_HEIGHT-3,
+   -2,FG_HEIGHT-3,
+   -2,-2};
+
+local struct Border dt2bor1 = {
+   0,0,
+   0,1,
+   JAM1,
+   5,
+   (SHORT *)&dt2box1,
+   NULL};
+
+local struct StringInfo filestr = {
+   NULL,          /* default and final string */
+   &undofile[0],  /* optional undo buffer (later) */
+   0,             /* character position in buffer */
+   25,            /* max characters in buffer */
+   0,             /* buffer position of first displayed character */
+   0,0,0,0,0,NULL,0,NULL };     /* intuition local variables */
+
+local struct Gadget filegadget = {
+   &gotnamegadget,
+   -FG_WIDTH-12,-33,
+   FG_WIDTH,FG_HEIGHT,
+   GADGHCOMP | GRELBOTTOM | GRELRIGHT,
+   RELVERIFY | GADGIMMEDIATE /* | ENDGADGET */ , 
+   REQGADGET | STRGADGET,
+   (APTR) &dt2bor1,      
+   NULL,                 
+   NULL,                 
+   0,                    
+   (APTR)&filestr,    
+   FN_FILE,           
+   NULL };            
+
+/*========================*/
+/*== DRAWER, GADGET ======*/
+/*========================*/
+
+#define DG_WIDTH 184
+#define DG_HEIGHT 13       
+
+
+local UWORD dt3box1[] = {
+   -2,-2,
+   DG_WIDTH+1,-2,
+   DG_WIDTH+1,DG_HEIGHT-3,
+   -2,DG_HEIGHT-3,
+   -2,-2};
+
+local struct Border dt3bor1 = {
+   0,0,
+   0,1,
+   JAM1,
+   5,
+   (SHORT *)&dt3box1,
+   NULL};
+
+local struct StringInfo drawerstr = {
+   NULL,          
+   &undodrawer[0],
+   0,             
+   25,            
+   0,             
+   0,0,0,0,0,NULL,0,NULL };
+
+local struct Gadget drawergadget = {
+   &filegadget,         
+   -DG_WIDTH-12,-48,
+   DG_WIDTH,DG_HEIGHT,  
+   GADGHCOMP | GRELBOTTOM | GRELRIGHT,
+   RELVERIFY | GADGIMMEDIATE, 
+   REQGADGET | STRGADGET,
+   (APTR) &dt3bor1,      
+   NULL,                 
+   NULL,                 
+   0,                    
+   (APTR)&drawerstr,     
+   FN_DRAWER,            
+   NULL };               
+
+
+/*========================*/
+/*== SLIDER, GADGET ======*/
+/*========================*/
+
+local struct Image slideknob = {
+   0,0,
+   0,
+   0,0,
+   0,
+   0,
+   0,
+   NULL};
+
+local struct PropInfo slideprop =
+   {
+   AUTOKNOB | FREEVERT,
+   0,0,
+   0xffff,0x5555,
+   12,52,
+   0,0,
+   2,0
+   };
+         
+struct Gadget slidegadget =
+   {
+   &drawergadget,
+   -19,27,
+   20,52,
+   GRELRIGHT | GADGIMAGE | GADGHCOMP | GADGHBOX,
+   RELVERIFY | GADGIMMEDIATE,
+   PROPGADGET| REQGADGET,
+   (APTR) &slideknob,
+   NULL,
+   NULL,
+   NULL,
+   (APTR) &slideprop,
+   FN_SLIDE,
+   NULL
+   };
+
+/*====================*/
+/*== UP, GADGET ======*/
+/*====================*/
+extern SHORT up0[];
+
+local struct Image uparrow = {
+   0,0,
+   16,
+   16,1,
+   (USHORT *)&up0,
+   0x01,
+   0x00,
+   NULL};
+
+local struct Gadget upgadget = {
+   &slidegadget,
+   -17,12,
+   16,16,          
+   GADGHCOMP | GRELRIGHT | GADGIMAGE, 
+   RELVERIFY | GADGIMMEDIATE, 
+   REQGADGET | BOOLGADGET, 
+   (APTR)&uparrow,         
+   NULL,          
+   NULL,      
+   0,         
+   NULL,      
+   FN_UP,     
+   NULL };
+
+/*======================*/
+/*== DOWN, GADGET ======*/
+/*======================*/
+extern SHORT down0[];
+
+local struct Image downarrow = {
+   0,0,
+   16,
+   16,1,
+   (USHORT *)&down0,
+   0x01,
+   0x00,
+   NULL};
+
+local struct Gadget downgadget = {
+   &upgadget,
+   -17,78,
+   16,16,          
+   GADGHCOMP | GRELRIGHT | GADGIMAGE,
+   RELVERIFY | GADGIMMEDIATE, 
+   REQGADGET | BOOLGADGET, 
+   (APTR)&downarrow,          
+   NULL,     
+   NULL,     
+   0,        
+   NULL,     
+   FN_DOWN,  
+   NULL };
+
+              
+/*========================*/
+/*== NAMES, GADGETS ======*/
+/*========================*/
+
+SHORT NFNames = 0;     /* The number of file names in currren dir */
+UBYTE *names[MAXFNAMES] = {NULL};
+UBYTE namedir[MAXFNAMES];
+
+local struct IntuiText nametext[MAXSHOW];
+
+#define MAXCHARS 30
+typedef UBYTE NameStr[MAXCHARS];
+NameStr  *showNames;
+
+local struct Gadget namegadget[MAXSHOW] = {0};
+
+AllocShowNames() {
+    showNames = (NameStr *)DAlloc(MAXSHOW*sizeof(NameStr), MEMF_PUBLIC);
+    }
+    
+FreeShowNames() {  DFree(showNames);  }
+    
+FN_InitReq()
+   {
+   LONG n;
+   InitRequester(&fn_req);
+   fn_req.LeftEdge = reqX;
+   fn_req.TopEdge = reqY;
+   fn_req.Width = reqWidth;
+   fn_req.Height = REQH;
+   fn_req.ReqGadget = &namegadget[MAXSHOW-1];
+   fn_req.ReqBorder = &reqborder;
+   fn_req.ReqText = &fn_text[2];   
+   fn_req.BackFill = 1;
+
+   fn_text[0].FrontPen = 3;
+   fn_text[0].BackPen = 1;
+   fn_text[0].DrawMode = JAM2;
+   fn_text[0].ITextFont = &reqfont;
+   fn_text[0].NextText = NULL;
+   fn_text[0].IText = NULL;
+   fn_text[0].LeftEdge = 0;
+   fn_text[0].TopEdge = 3;
+
+   fn_text[1].FrontPen = 0;
+   fn_text[1].BackPen = 1;
+   fn_text[1].DrawMode = JAM2;
+   fn_text[1].ITextFont = &reqfont;
+   fn_text[1].NextText = &fn_text[0];
+   fn_text[1].LeftEdge = 5;
+   fn_text[1].TopEdge = REQH-49;
+   fn_text[1].IText = (UBYTE *)"Drawer:";
+
+   fn_text[2].FrontPen = 0;
+   fn_text[2].BackPen = 1;
+   fn_text[2].DrawMode = JAM2;
+   fn_text[2].ITextFont = &reqfont;
+   fn_text[2].NextText = &fn_text[1];
+   fn_text[2].LeftEdge = 21;
+   fn_text[2].TopEdge = REQH-34;
+   fn_text[2].IText = (UBYTE *)"File:";
+   
+   for(n=0;n<MAXSHOW;n++)     {
+       nametext[n].FrontPen = 0;
+       nametext[n].BackPen = 1;
+       nametext[n].DrawMode = JAM2;
+       nametext[n].ITextFont = &reqfont;
+       nametext[n].NextText = NULL;
+       nametext[n].LeftEdge = 2;
+       nametext[n].TopEdge = 1;   
+       }
+    reqpts[4] = reqpts[6] = reqpts[12] = reqpts[14] = reqWidth-3;
+    }
+
+/*****************************************************************************/
+/* FN_FixBox                                                                 */
+/*                                                                           */
+/* Adjust a box's corners to a specified width and height                    */
+/*                                                                           */
+/*****************************************************************************/
+
+VOID FN_FixBox(box1,box2,width,height)
+UWORD box1[],box2[];
+UWORD width,height;
+   {
+   box1[2] = width-1;
+   box1[4] = width-1;
+   box1[5] = height-1;
+   box1[7] = height-1;
+   box2[2] = width-2;
+   box2[4] = width-2;
+   box2[5] = height-3;
+   box2[7] = height-3;
+   }               
+                                                         
+/*****************************************************************************/
+/* FN_InitText                                                               */
+/*                                                                           */
+/* Initialize text used in this requester                                    */
+/*                                                                           */
+/*****************************************************************************/
+VOID FN_InitText()
+   {
+   SHORT n;
+   for(n=0; n<2; n++)
+      {
+      gadg_text[n].FrontPen = 0;
+      gadg_text[n].BackPen = 1;
+      gadg_text[n].DrawMode = JAM2;
+      gadg_text[n].ITextFont = &reqfont;
+      gadg_text[n].NextText = NULL;
+      gadg_text[n].LeftEdge = 4;
+      gadg_text[n].TopEdge = 4;
+      }
+   gadg_text[0].IText = NULL;
+   gadg_text[1].IText = NULL;   
+
+   for(n=0;n<MAXSHOW;n++)
+      {
+      if (n==0) namegadget[n].NextGadget = &downgadget;
+      else namegadget[n].NextGadget = &namegadget[n-1];
+      namegadget[n].LeftEdge = 3;
+      namegadget[n].TopEdge = 13+(n*10);
+      namegadget[n].Width = REQW-22;
+      namegadget[n].Height = 9;
+      namegadget[n].Flags = GADGHCOMP;
+      namegadget[n].Activation = RELVERIFY | GADGIMMEDIATE;
+      namegadget[n].GadgetType = REQGADGET | BOOLGADGET;
+      namegadget[n].GadgetID = FN_SLIDE + 1 + n;
+      namegadget[n].GadgetText = &nametext[n];
+      }
+   }               
+
+UBYTE emptyName[] = "";
+int nrange = 0;
+#define MAXCHWIDE 20
+StuffReqNames() {
+    int i,n,j;
+    int newpot,newbody;
+    if (firstname<0) firstname = 0;
+    if (NFNames<=MAXSHOW) firstname = 0;
+    else if (firstname > (NFNames-MAXSHOW)) firstname = NFNames-MAXSHOW;
+    n = firstname;
+    for (i=0; i<MAXSHOW; i++)  {
+       if (n<NFNames)  strncpy(showNames[i],names[n],MAXCHARS);
+       else showNames[i][0] = 0;
+       nametext[i].IText = showNames[i];
+       for (j = strlen(showNames[i]); j<MAXCHARS-1; j++)
+               showNames[i][j] = ' ';
+       showNames[i][MAXCHARS-1] = 0;
+       n++;
+       }
+    nrange = NFNames - MAXSHOW + 1;
+    if (nrange<=0)   {  newpot = 0x0;  newbody = 0xffff;   }
+    else  {
+       newpot = (firstname<<16)/nrange;
+       newbody = (MAXSHOW<<16)/NFNames;
+       }
+#ifdef foob
+    printf("newpot, newbody = %4lx %4lx\n",newpot,newbody);
+    printf("NFNames = %ld\n",NFNames);
+    printf("firstname = %ld\n",firstname);                 
+#endif
+    slideprop.VertBody = newbody;
+    slideprop.VertPot = newpot;
+    }
+    
+
+FreeFileNames() {
+    int n;
+    for(n=0; n<MAXFNAMES; n++)         {
+       if (names[n] != NULL) DFree(names[n]);
+       names[n] = NULL;
+       namedir[n] = FALSE;
+       }
+    }
+
+local BOOL okDrawer;
+
+strToLower(d,s) char *d,*s; {
+    char c;
+    do { c = *s++;  *d++ = tolower(c); } while(c!=0);
+    }
+    
+CmpStr(s,t) char *s,*t; {
+    char a[40],b[40];
+    strToLower(a,s);
+    strToLower(b,t);
+    return(stscmp(a,b));
+    }
+
+local UBYTE dotinfo[] = ".info";
+
+DotInfo(nm) char *nm; {
+    int l = strlen(nm);
+    if (l<5) return(NO);
+    return( strcmp(dotinfo,nm+l-5) == 0);
+    }
+/*----------------------------------------------------------------------*/
+/* GetFileNames                                                        */
+/*         Read in all the file names, allocating space for them       */
+/*----------------------------------------------------------------------*/
+VOID GetFileNames(drawername) UBYTE drawername[];   {                     
+    BOOL success;
+    LONG lock;                     
+    LONG n, ln, t, bound;
+    UBYTE *tmp, tmpb;
+    struct FileInfoBlock *fib;                      
+    
+    ZZZCursor();
+    FreeFileNames();
+    okDrawer = NO;
+    NFNames = 0;
+    lock = Lock(drawername,SHARED_LOCK);
+    success = (lock!=0);
+    if (success) {                      
+       fib = (struct FileInfoBlock *)DAlloc(sizeof(struct FileInfoBlock),MEMF_PUBLIC);
+       success = Examine(lock,fib);
+       if (success)   {
+           okDrawer = YES;
+           n = 0;
+           while (success) {
+               success = ExNext(lock,fib);
+               if (success&&(n<MAXFNAMES))    {
+                   ln = strlen(fib->fib_FileName);
+                   if (fib->fib_DirEntryType>0) { 
+                       namedir[n] = TRUE;
+                       ln += 6;
+                       }
+                   else {
+                       if (DotInfo(fib->fib_FileName)) continue;
+                       namedir[n] = FALSE;
+                       }
+                   names[n] = (UBYTE *)DAlloc(ln+1,MEMF_PUBLIC);
+                   strcpy(names[n],fib->fib_FileName);
+                   if (namedir[n]) strcat(names[n]," (Dir)");
+                   n++;
+                   }
+               } /* end while */                         
+           NFNames = n;
+           }
+       DFree(fib);
+       UnLock(lock);  
+       }
+    /** bubble sort file names **/
+    t = NFNames-1;
+    while (t>0) {
+       bound = t; 
+       t = 0;
+       for (n=0; n<bound; n++) {
+           if (CmpStr(names[n],names[n+1])>0) {
+               tmp = names[n]; names[n] = names[n+1]; names[n+1] = tmp;
+               tmpb = namedir[n]; namedir[n] = namedir[n+1];
+               namedir[n+1] = tmpb;
+               t = n;
+               }
+           }
+       }
+    UnZZZCursor();
+    } /* end GetFileNames() */
+
+local BOOL doAction;
+
+/*****************************************************************************/
+/* FN_GadgUp                                                                 */
+/*                                                                           */
+/* Handle gadget up events                                                   */
+/*                                                                           */
+/*****************************************************************************/
+
+RedoNames() {
+    StuffReqNames();
+    RefreshGadgets(&namegadget[MAXSHOW-1],reqwindow,&fn_req);
+    }
+
+VOID FN_GadgUp(gid,x,y) UWORD gid; int x,y;   {     
+    LONG n;
+    UBYTE tmp[31];
+    /* ---- names in the directory display */
+    if ((gid >= (FN_SLIDE+1)) && (gid <= (FN_SLIDE+MAXSHOW)))      {
+       n = gid - FN_SLIDE - 1 + firstname;
+       if (namedir[n]) {
+           strncpy(tmp,names[n],strlen(names[n])-6);
+           ConcatPath(drawerstr.Buffer,tmp);
+           GetFileNames(drawerstr.Buffer);
+           drawerstr.BufferPos = 0; /*strlen(drawerstr.Buffer);*/
+           filestr.DispPos = 0;
+           firstname = 0;
+           StuffReqNames();
+           }             
+       else {
+           strcpy(filestr.Buffer,names[n]);
+           filestr.BufferPos = 0; /*strlen(filestr.Buffer);*/
+           filestr.DispPos = 0;
+           }
+       /*RefreshGadgets(&namegadget[MAXSHOW-1],reqwindow,&fn_req); */
+       /* try to keep it from redrawing whole thing-- didnt work */
+       RefreshGadgets(&filegadget,reqwindow,&fn_req); 
+       }
+    if (gid==FN_SLIDE) {
+       firstname = ((slideprop.VertPot*nrange)>>16);
+       RedoNames();
+       }
+    if (gid==FN_DRAWER)  {
+       GetFileNames(drawerstr.Buffer);
+       firstname = 0;
+       RedoNames();
+       }
+    if ((gid==FN_UP)||(gid==FN_DOWN) ) {
+       if (gid==FN_UP) firstname--;    else  firstname++;
+       RedoNames();
+       }
+   }
+
+/*****************************************************************************/
+/* Handle events for the File Name requester                                */
+/*****************************************************************************/
+local BOOL FN_HandleEvent(event) struct IntuiMessage *event; {                                
+    WORD gadgetid;
+    BOOL keepGoing = YES;
+    switch(event->Class)
+       {
+       case GADGETUP:
+           gadgetid = ((struct Gadget *)event->IAddress)->GadgetID;
+           if (gadgetid == FN_CANCEL)  keepGoing = NO;
+           else if (gadgetid==FN_GOTNAME) { doAction = TRUE;
+               keepGoing = NO;
+               }
+           else if ((gadgetid>=FN_GADGMIN) && (gadgetid<=FN_GADGMAX))
+               FN_GadgUp(gadgetid);
+           break;
+       }
+    return(keepGoing);
+    }
+
+
+/*****************************************************************************/
+/* FN_Request                                                                */
+/*                                                                           */
+/* Initialize and display the requester                                      */
+/* Returns TRUE if do, FALSE if cancel                                       */
+/*****************************************************************************/
+BOOL FN_Request(w,x,y,drawername,filename,extension,title,cancelverb,doverb)
+struct Window *w; SHORT x,y;
+    UBYTE drawername[]; UBYTE filename[]; UBYTE extension[]; UBYTE title[];
+    UBYTE doverb[]; UBYTE cancelverb[];                       
+    {
+    UWORD width0,width1,width,height;
+    ULONG saveIDCMP;
+    
+    
+    FixMenCols();
+    AllocShowNames();
+    reqX = x;
+    reqY = y;
+    reqwindow = w;
+    saveIDCMP = w->IDCMPFlags;
+    
+    reqWidth = ( (w->WScreen->ViewPort.Modes & (HIRES|LACE)) == 
+     (HIRES|LACE)) ? HIWIDTH: LOWIDTH;
+    
+    /* --- What class of events do we want to know about? --- */
+
+    ModifyIDCMP( reqwindow, RAWKEY | MOUSEBUTTONS |  GADGETUP | GADGETDOWN);
+
+    if (!dosready) {                   
+       /* Initialize stuff the first time through */
+       GetPrefs(&reqfont.ta_YSize,2); 
+       FN_InitReq();
+       FN_InitText();
+       dosready = TRUE;
+       }
+    drawerstr.Buffer = drawername;
+    filestr.Buffer = filename;
+
+    if (title==NULL) fn_text[0].IText = deftitle;
+    else fn_text[0].IText = title;
+    fn_text[0].LeftEdge = (reqWidth-10*strlen(fn_text[0].IText))/2;
+    
+    if (cancelverb==NULL) gadg_text[0].IText = defcancel;
+    else gadg_text[0].IText = cancelverb;
+
+    if (doverb==NULL) gadg_text[1].IText = defdoverb;
+    else gadg_text[1].IText = doverb;
+
+    width0 = strlen(gadg_text[0].IText)*10+10;
+    width1 = strlen(gadg_text[1].IText)*10+10;
+    width = MAX(width0,width1);
+    height = 17;            
+
+    cancelgadget.LeftEdge = -10-width;
+    cancelgadget.Width = width;
+    cancelgadget.Height = height;
+    FN_FixBox(&dt0box1,&dt0box2,width,height);
+
+    gotnamegadget.Width = width;
+    gotnamegadget.Height = height;
+    FN_FixBox(&dt1box1,&dt1box2,width,height);
+    
+    GetFileNames(drawerstr.Buffer);
+
+    StuffReqNames();
+
+    ZZZCursor();
+    
+    Request(&fn_req,w);
+    
+    UnZZZCursor();
+
+    doAction = FALSE;
+
+    ReqListen(w->UserPort,&FN_HandleEvent);
+   
+    FreeFileNames();
+
+    /* restore the IDCMP to its original state */
+    ModifyIDCMP(reqwindow, saveIDCMP);
+
+    FreeShowNames();    
+    UnFixMenCols();
+    return( (BOOL)
+       (doAction? ( okDrawer? FN_OK: FN_NoSuchDrawer): FN_Cancel ));
+    }                    
+
diff --git a/FNREQ.H b/FNREQ.H
new file mode 100644 (file)
index 0000000..02f468f
--- /dev/null
+++ b/FNREQ.H
@@ -0,0 +1,11 @@
+/** fnreq.h ******************************************************************/
+/*                                                                           */
+/* A module that opens and handles a file name requester.                    */
+/*                                                                           */
+/*                                                                           */
+/*****************************************************************************/
+
+/* Error values returned :*/
+#define        FN_OK           0
+#define FN_Cancel      1
+#define FN_NoSuchDrawer 2
diff --git a/FONTINIT.C b/FONTINIT.C
new file mode 100644 (file)
index 0000000..63b94e8
--- /dev/null
@@ -0,0 +1,177 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*             fontinit.c                                              */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <librarie\dosexten.h>
+#include <prism.h>
+#include <librarie\diskfont.h>
+
+#define local static
+extern LONG DiskfontBase;
+extern struct TmpRas tmpRas;
+extern struct AvailFonts *fontDir;
+extern SHORT nFonts;
+extern SHORT curFontNum;
+extern struct TextFont *font;
+extern struct Menu *FontMenu;
+extern struct Window *mainW;
+extern struct Menu *MainMenu;
+
+#ifdef junkjunkjunkjunk
+
+------- STUFF from <librarie\diskfont.h> for reference :
+
+#define                AFB_MEMORY      0
+#define                AFF_MEMORY      1
+#define                AFB_DISK        1
+#define                AFF_DISK        2
+/****** TextAttr node, matches text attributes in RastPort **********/
+struct TextAttr {
+    STRPTR  ta_Name;           /* name of the font */
+    UWORD   ta_YSize;          /* height of the font */
+    UBYTE   ta_Style;          /* intrinsic font style */
+    UBYTE   ta_Flags;          /* font preferences and flags */
+};
+
+struct AvailFonts {
+       UWORD   af_Type;                /* MEMORY or DISK */
+       struct  TextAttr af_Attr;       /* text attributes for font */
+       };
+
+struct AvailFontsHeader {
+       UWORD   afh_NumEntries;         /* number of AvailFonts elements */
+    /* struct  AvailFonts afh_AF[]; */
+    };
+#endif
+/*----------------------------------------------------------------------*/
+
+#define BUFSIZE 800
+
+
+local CopyPrefix(to,from) UBYTE *to,*from; {
+    UBYTE c;
+    while ( (c = *from++) != '.')  *to++ = c; 
+    *to++ = '-';
+    *to = '\0';
+    }
+
+/* -----------initialize font directory */
+local void InitFonts() {
+    int i,err,fontType;
+    UBYTE *str, name[20], sHigh[5],*buffer;
+    struct AvailFonts *avFonts;
+    struct AvailFontsHeader *avh = (struct AvailFontsHeader *)tmpRas.RasPtr;
+    buffer = (UBYTE *)tmpRas.RasPtr;
+    
+    fontType = AFF_MEMORY;
+    DiskfontBase = OpenLibrary("diskfont.library",0);
+    if (DiskfontBase== NULL){
+       InfoMessage("Couldn't open","diskfont.library" );
+       return;
+       }
+    else fontType |= AFF_DISK;
+
+    ZZZCursor();
+    err = AvailFonts(avh, tmpRas.Size, fontType);
+    nFonts = avh->afh_NumEntries;
+
+#if 0
+    printf("err = %ld, #found = %ld\n", err, nFonts);
+#endif
+
+    avFonts = (struct AvailFonts *)&(buffer[2]); 
+    fontDir = (struct AvailFonts *)DAlloc(nFonts*sizeof(struct AvailFonts), MEMF_PUBLIC);
+
+    movmem(avFonts,fontDir,nFonts*sizeof(struct AvailFonts));
+
+    /* copy the font names into strings allocated with AllocMem,
+       adding the size to the name */
+    for (i=0; i<nFonts; i++)  {
+
+#if 0
+       printf("Font '%s', type = %lx\n",avFonts[i].af_Attr.ta_Name,
+          avFonts[i].af_Type);
+#endif
+
+#define SAVINGSPACE
+
+#ifdef SAVINGSPACE
+       CopyPrefix(name, avFonts[i].af_Attr.ta_Name);
+       stcu_d(sHigh,avFonts[i].af_Attr.ta_YSize,3);
+       strcat(name,sHigh); 
+       str =(UBYTE *)AllocMem(strlen(name)+1,MEMF_PUBLIC);
+       strcpy(str,name);
+#else
+       str =(UBYTE *)AllocMem(strlen(avFonts[i].af_Attr.ta_Name)+1,MEMF_PUBLIC);
+       strcpy(str,avFonts[i].af_Attr.ta_Name);
+#endif
+       fontDir[i].af_Attr.ta_Name = str;
+       }
+    InitFontMenu();
+    UnZZZCursor();
+    }
+
+static struct IntuiText itInit = {0,1,JAM1,0,1,NULL,NULL,NULL};
+
+#define AllocStruct(astr) (struct astr *)AllocMem( sizeof(struct astr), MEMF_PUBLIC);
+
+    
+/* Build a font menu, allocating a MenuItem and IntuiText (which points 
+at the same name as the font Directory) */
+local InitFontMenu() {
+    int i;
+    struct MenuItem *mi, *nextMI;
+    struct IntuiText *it;
+    LONG mutExSet = (1 << nFonts) -1;
+    nextMI = NULL;
+    for (i = nFonts-1; i>=0; i--) {
+       mi = (struct MenuItem *)AllocStruct(MenuItem);
+       it = (struct IntuiText *)AllocStruct(IntuiText);
+       movmem(&itInit,it,sizeof(struct IntuiText));
+       it->IText = fontDir[i].af_Attr.ta_Name,
+       mi->TopEdge = 0;
+       mi->SelectFill = (APTR)NULL;
+       mi->ItemFill = (APTR)it;
+       mi->Flags = (CHECKIT | ITEMTEXT | ITEMENABLED | HIGHCOMP);
+       mi->MutualExclude = mutExSet & ( ~(1<<i) );
+       mi->NextItem = nextMI;
+       mi->SubItem = NULL;
+       nextMI = mi;
+       }
+    FontMenu->FirstItem = nextMI; 
+    FontMenu->FirstItem->NextItem->Flags |= CHECKED;
+    }
+
+#define FreeString(s)  FreeMem((s),strlen(s)+1)
+    
+void FreeFonts() {
+    int i;
+    struct MenuItem *mi, *nextMI=NULL;
+    MyCloseFont(font);
+    if (fontDir == NULL) return;
+    /* free the font MenuItems and IntuiText's  */
+    for (mi = FontMenu->FirstItem; mi != NULL; mi = nextMI) {
+       nextMI = mi->NextItem;
+       FreeMem( mi->ItemFill, sizeof(struct IntuiText));
+       FreeMem( mi, sizeof(struct MenuItem));
+       }
+    FontMenu->FirstItem = NULL;
+    for (i=0; i<nFonts; i++) FreeString(fontDir[i].af_Attr.ta_Name);
+    DFree(fontDir);
+    CloseLibrary(DiskfontBase);
+    }
+
+void LoadFontDir() {
+    UndoSave();
+    InitFonts();
+    ClearMenuStrip(mainW);
+    InitMenu(); 
+    SetMenuStrip(mainW, MainMenu);
+    PaneRefrAll(); /* in case it put up requestor to switch disks*/
+    /* may have made storage tight by loading the font directory:
+      if so deallocate the brush */
+    if (AvailMem(MEMF_PUBLIC|MEMF_CHIP) < 17000) GunTheBrush();
+    }
diff --git a/GEOM.C b/GEOM.C
new file mode 100644 (file)
index 0000000..fb68044
--- /dev/null
+++ b/GEOM.C
@@ -0,0 +1,119 @@
+/*--------------------------------------------------------------*/
+/*        geom.c   -- geometric primitives                     */
+/*     lines, circles, filled circles                          */
+/* Coordinates are in Virtual Device Coords (640x400)          */
+/*--------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+extern SHORT xShft,yShft;
+extern void (*CurPWritePix)();
+#define local 
+
+extern struct RastPort *curRP;
+
+    
+/*-----------Line drawing functions------------------*/
+/* note: fun must take Physical Device coords        */
+
+void PLineWith(x1,y1,x2,y2,fun) SHORT (*fun)(), x1,y1,x2,y2;     {
+    SHORT i,dx,dy,incr1,incr2,del,xinc,yinc,linex,liney;
+    dx = x2-x1;
+    dy = y2-y1;
+    if (dx<0) {xinc = -1; dx = -dx;} else xinc = 1;
+    if (dy<0) {yinc = -1; dy = -dy;} else yinc = 1;
+    linex=x1; liney=y1;
+    (*fun)(linex,liney);
+    if (dx>dy) {
+       incr1 = dy+dy;  del = incr1-dx;  incr2= del-dx;
+       for (i=0; i<dx; i++) {
+           linex += xinc;
+           if (del<0) del += incr1; else { liney += yinc; del += incr2; }
+           (*fun)(linex,liney);
+           if (CheckAbort()) return;
+           }
+       }
+    else {
+       incr1 = dx+dx;  del = incr1-dy;  incr2= del-dy;
+       for (i=0; i<dy; i++) {
+           liney += yinc;
+           if (del<0) del += incr1; else { linex += xinc; del += incr2; }
+           (*fun)(linex,liney);
+           if (CheckAbort()) return;
+           }
+       }
+    }
+
+/* some cheapo clipping */
+extern SHORT clipMaxX;
+void PLine(x1,y1,x2,y2) SHORT x1,y1,x2,y2;  { 
+    if (x2>clipMaxX) { 
+       if (x1>clipMaxX) return;
+       y2 = y1 +(clipMaxX-x1)*(y2-y1)/(x2-x1); 
+       x2 = clipMaxX;
+       }
+    else if (x1>clipMaxX) { 
+       y1 = y2 + (clipMaxX-x2)*(y1-y2)/(x1-x2); 
+       x1 =  clipMaxX;
+       }
+    Move(curRP,x1,y1); Draw(curRP,x2,y2);
+    }
+    
+/* ---------------- Circle Drawing -----------------------*/
+SHORT xcen,ycen;
+SHORT (*curfunc)();
+
+void quadpts(x,y) SHORT x,y; {
+    (*curfunc)(xcen+x,ycen+y);   
+    if (y) (*curfunc)(xcen+x,ycen-y);
+    if (x) {
+       (*curfunc)(xcen-x,ycen+y);
+       if (y) (*curfunc)(xcen-x,ycen-y);
+       }
+    }
+
+local octpts(x,y) SHORT x,y; { quadpts(x,y);  if (x!=y) quadpts(y,x);  }
+    
+local octfillfunc(x,y) SHORT x,y; {
+    SHORT w = 2*x+1;    SHORT h = 2*y+1;
+    PatHLine(xcen-x,ycen+y,w);
+    PatHLine(xcen-x,ycen-y,w);
+    PatHLine(xcen-y,ycen+x,h);
+    PatHLine(xcen-y,ycen-x,h);
+    }
+    
+/* generates 1/8 of a circle and calls func at each point */        
+/* this should ONLY be called if xShft == yShft          */
+/* ie square pixels                                      */
+
+void PCircOct(xc,yc,rad,func) SHORT xc,yc,rad,(*func)(); {
+    SHORT d,x,y;
+    y = rad; x=0;
+    xcen=xc;   ycen = yc;
+    for (d = 3 - (rad<<1); x<y; x++) {
+       (*func)(x,y);
+       if (d<0) d += (x<<2) + 5;
+       else { d += ((x-y)<<2) + 10; y--; }
+       if (CheckAbort()) return;
+       }
+    if (x == y) (*func)(x,y);
+    }
+
+PCircWith(xc,yc,rad,func) SHORT xc,yc,rad,(*func)(); {
+    if (xShft==yShft) { curfunc = func;        PCircOct(xc,yc,rad,octpts);}
+    else PEllpsWith(xc,yc,rad,PMapY(VMapX(rad)),func);
+    }
+    
+PFillCirc(xc,yc,rad)   SHORT xc,yc,rad;   {
+    if (xShft==yShft) PCircOct(xc,yc,rad,octfillfunc); 
+    else PFillEllps(xc,yc,rad,PMapY(VMapX(rad)));
+    }
+
+PCircle(xc,yc,rad) SHORT xc,yc,rad; {
+    if (xShft==yShft)  PCircWith(xc,yc,rad,CurPWritePix);
+    else PEllpse(xc,yc,rad,PMapY(VMapX(rad)));
+    }
+    
+    
+   
\ No newline at end of file
diff --git a/GRDEFS.H b/GRDEFS.H
new file mode 100644 (file)
index 0000000..2feea40
--- /dev/null
+++ b/GRDEFS.H
@@ -0,0 +1,330 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*                     grdefs.h -- Graphics Definitions                */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#define BIGNUM 32767
+#define ALLONES        0xffff
+#define NIL    0
+#define MXLWRD 160     /* number of words in line buffers              */
+
+typedef char Boolean;
+#define        TRUE    0xff
+#define FALSE  0
+#define        YES     0xff
+#define NO     0
+#define local  static
+#define FAIL   -1
+#define SUCCESS 0
+
+typedef char Byte;
+typedef unsigned int Word;
+typedef char *String;
+typedef long longFrac;
+
+/* Utility functions */
+#define BitNot(v)      (v^0xffff)
+#define swap(a,b)      a ^= b;  b ^= a;  a ^= b;
+#define order(a,b)     if ((a)>(b)) {swap(a,b); }
+#define max(a,b)       ((a)>(b)?(a):(b))
+#define min(a,b)       ((a)<(b)?(a):(b))
+#define abs(a)         ((a)>0?(a):-(a))
+#define signum(a)      ((a)>0)
+
+/* ----------------Rasterop Modes ---------- */
+#define REPMODE 0      /* REPLACE pixels with new values               */
+#define XORMODE 1      /* XOR source into dest                         */
+#define ORMODE         2       /* OR source into dest                          */
+#define XPMODE         3       /* current transparent color doesnt paint, 
+                           other colors write                          */
+#define ANDMODE        4       /* AND source into dest                         */
+#define ERSMODE        5       /* ERASE: and complement of source into dest    */
+#define COLMODE        6       /* use source as mask through which current 
+                           color is painted into dest                  */
+
+
+#define BLACK  0
+#define WHITE  0xffff
+#define BLUE   0x5555
+#define MAGENTA 0xaaaa
+#define BGROUND 0xc3c3
+
+/* ------ offset in bytes of word containing pixel #x */
+
+#define xword(x)       (((x)>>LGPPB)&0xfffe)
+
+/*  ------ offset in bytes of byte containing pixel #x */
+
+#define xbyte(x)       (x>>LGPPB)
+
+/* ------ words required for w pixels */
+
+#define wrdsrqd(w)     ((w+PPWM1)>>LGPPW)
+
+/*  ------ set up current color word for scan line y */
+
+#define colForY(y)     colw = curpat[y&3] 
+
+\f
+
+/*--------------------------------------------------------------*/
+/*                                                             */
+/*             Graphics Data Structures                        */
+/*                                                             */
+/*--------------------------------------------------------------*/
+
+typedef union {
+    struct { char lo,hi; } b;
+    int w;
+    } Wrdovl;
+
+typedef struct{ int x,y; } Point;
+       
+typedef struct{ int w,h; } Dims;
+       
+typedef struct{ int x,y,w,h; } Box;
+       
+typedef struct{
+       Word segment;   /* segment addr of bitmap               */
+       Word *base;     /* addr of start of data                */
+       Word width;     /* width in words                       */
+       Box box;        /* image bounds                         */
+       Word *ytab;     /* pointer to table  of y offsets       */
+       Byte xpcolor;   /* transparent  color                   */
+       Byte mode;      /* paint mode                           */
+       } Bitmap;
+
+#define INITBM {NIL,NIL,0,{0,0,0,0},NIL,0,XPMODE}
+
+/* General Displayable Object  DOB                     */
+
+typedef struct {
+    int (*display)();  /* pointer to display proc      */
+    int x,y;           /* present coords of upper left */
+    int xoffs,yoffs;   /* offset of grab point         */
+    Boolean showing;   /* is it displayed?             */
+    Bitmap svbm;       /* save bitmap                  */
+    } DOB;
+
+/* Bitmap Object: if mbm is defined (segment != NIL)  */
+typedef struct {
+    DOB hdr;           /* header inherited from DOB    */
+    Bitmap sbm;                /* source bitmap                */
+    Bitmap mbm;                /* mask bitmap(optional)        */
+    } BMObj;
+
+#define INITDOB   {NIL,0,0,0,0,FALSE,INITBM}
+#define INITPSB   {INITBM,INITBM,INITBM,INITBM}
+#define INITBMOB  {INITDOB,INITBM,INITBM}
+
+typedef struct{
+    int curcol;
+    int curxpc;
+    Box box;
+    int curmode;
+    Bitmap *curbm;
+    } GrState;
+
+/* window: definitions */
+typedef struct {
+    unsigned border : 1; /* draw border */
+    unsigned always : 1; /* call even if mouse didnt move */
+    unsigned hangOn : 1; /* keep control while button down */
+    } WFlags;
+    
+struct Winrec{
+    Word client;       /* client context */
+    Box box;           /* rectangle on screen */
+    WFlags flags;      /* booleans */
+    Boolean border;    /* does it have a border */
+    int (*charProc)();  /* called with all typing      */
+    int (*mouseProc)();        /* called on all mouse actions */
+    int (*paintProc)();        /* called to repaint window */
+    struct Winrec *next;
+    };
+
+typedef struct Winrec Window;
+
+typedef Byte MouseEvent;
+
+/* mouse events: you can choose to be called when the program loops 
+    even though the mouse didnt move */
+
+#define NONE   0       /* nothing happened (i dont call you) */    
+#define LOOPED 1       /* you wanted me to call you every time*/
+#define        MOVED   2       /* the mouse moved while in this window */
+#define        BDOWN   3       /* button went down */
+#define        BUP     4       /* button went up */
+#define ENTER  5       /* entered window */
+#define LEAVE  6       /* left window */
+
+/* Magnified Bitmap window   (subclassed off of Window)                 */
+
+struct MagWinGr {
+    Bitmap *bbm;
+    struct MagWinRec *first;
+    };
+
+struct MagWinRec{
+    Window win;
+    Point wb;                  /* coords of window rel to bitmap */
+    int        mag;                    /* magnification */
+    struct MagWinGr *group;    /* pointer to group sharing backing bitmap */
+    struct MagWinRec *sib;     /* sister in group */
+    };
+    
+typedef struct MagWinGr MWGroup;
+typedef struct MagWinRec MagWindow;
+        
+typedef struct {
+    Bitmap *bm;
+    Box box;
+    int xorg,yorg;
+    } GrCntxt;
+
+/* ----- Activities -------*/
+#define        nullAct         0
+#define        shadeAct        1
+#define drawAct                2
+#define vectAct                3
+#define curvAct                4
+#define rectAct                5
+#define frectAct       6
+#define circAct                7
+#define fcircAct       8
+#define ovalAct                9
+#define fovalAct       10
+#define selbAct                11
+#define magAct         12
+#define fillAct                13
+#define textAct                14
+#define gridAct                15
+#define symAct         16
+#define ioAct          17
+#define clearAct       18
+
+#define NPENS  9
+#define USERPEN        -1
+
+\f
+/*--------------------------------------------------------------*/
+/*                                                             */
+/*             Menu Box                                        */
+/*                                                             */
+/*--------------------------------------------------------------*/
+
+struct MenuRec {
+    Box                box;    /*window - relative */
+    int                type;   /* what kind of item */
+    struct MenuRec  *next;
+    };  
+
+typedef struct MenuRec MenuItem, *MIPtr;
+
+typedef struct {
+    Window     win;
+    Boolean    showing; /* is it on the screen? */
+    Boolean    isTemp;
+    MenuItem   *curmi;
+    MenuItem   *items;
+    int                effNWIDE; /* set to 320 initially */
+    } MBox;
+
+/*------ Passive Types----- */
+
+#define        LablTyp         0
+typedef struct {
+    MenuItem   hdr;
+    char       *name;
+    } Labl;
+
+#define        ColBoxTyp       1       
+typedef struct {
+    MenuItem   hdr;
+    Word       fillPat;
+    } ColBx;
+           
+/* -------  Active Types----- */
+
+#define        ButnTyp         2
+typedef struct {
+    MenuItem   hdr;
+    char       *name;
+    Boolean    islit;
+    int                (*proc)();
+    } Butn;
+           
+#define        TBoxTyp         3
+typedef struct {
+    MenuItem   hdr;
+    char       *string;
+    int                nmax;
+    int                (*proc)();
+    } TBox;
+
+#define MarTyp         4
+typedef struct {
+    MenuItem   hdr;
+    char       **names;
+    Boolean    dolines;
+    Boolean    vertical;
+    int                spacing;        /* used only by horizontal */
+    int                (*proc)();
+    int                curitem,lit,nitems; /* used by menu processr */
+    } Mar;
+                   
+#define        ScBarTyp        5
+typedef struct {
+    MenuItem   hdr;
+    int                (*proc)();
+    } ScBar;
+
+#define        NBoxTyp         6
+typedef struct {
+    MenuItem   hdr;
+    int        pval;           /*  value to be displayed*/
+    int                nmax;           /*  max num of chars */
+    int                (*proc)();
+    } NBox;
+
+#define MAXCHRS                9
+#define NEWITEM                10
+#define NullItem       -1
+
+
+#define USERBRUSH      255
+
+/* configuration */
+#define NCONFIG 6
+
+#define MED2   0
+#define ART4   1
+#define LOW4   2
+#define        HRBW    3
+#define TEC1   4       /* 320x200x4 */
+#define TEC2   5       /* 640x200x4 */
+
+typedef int CursID;
+#define        Arrow   0
+#define        FillCan 1
+#define Pencil  2
+
+/* input device types */
+#define NoDev          0
+#define Joystick       1
+#define        Koala           2
+#define        MMouse          3
+
+/* input device vector*/
+
+extern int (*rdInDev)();
+#define rdmouse(xaddr,yaddr)   ((*rdInDev)(xaddr,yaddr))
+
+/* Hardware Type*/
+#define        PCSR    0       /*  IBM PC  */
+#define        PCJR    1       /*  IBM PC/jr */
+#define PCXT   2       /*  IBM PC/XT */
+#define IBMAT  3       /*  IBM AT */
+#define TA1000 4       /*  Tandy 1000 */
+
diff --git a/HOOK.C b/HOOK.C
new file mode 100644 (file)
index 0000000..4da80a6
--- /dev/null
+++ b/HOOK.C
@@ -0,0 +1,38 @@
+/*--------------------------------------------------------------*/
+/*                                                             */
+/*     hook.c                                                  */
+/*                                                             */
+/*--------------------------------------------------------------*/
+
+#include <system.h>
+
+typedef struct {
+    struct MsgPort msgport;
+    UWORD *pointer;
+    } Hook;
+
+SetHook(name,ptr) char *name; UWORD *ptr; {
+    Hook *hook = (Hook *)AllocMem(sizeof(Hook),MEMF_CLEAR|MEMF_PUBLIC);
+    struct MsgPort *p = (struct MsgPort *)hook;
+    p->mp_Flags = 0;
+    p->mp_Node.ln_Pri = 0;
+    p->mp_Node.ln_Name = name;
+    p->mp_Node.ln_Type = NT_MSGPORT;
+    AddPort(p);
+    hook->pointer = ptr;
+    }
+
+UWORD *FindHook(name) UBYTE *name; {
+    Hook *hook = (Hook *)FindPort(name);
+    return((hook != NULL)? hook->pointer: NULL);
+    }
+
+RemHook(name) UBYTE *name; {
+    Hook *hook = (Hook *)FindPort(name);
+    if (hook!=NULL) {
+       RemPort(hook);
+       FreeMem(hook,sizeof(Hook));
+       }
+    }
+
+
diff --git a/HSV.C b/HSV.C
new file mode 100644 (file)
index 0000000..64e867b
--- /dev/null
+++ b/HSV.C
@@ -0,0 +1,215 @@
+/*--------------------------------------------------------------------*/
+/*
+       RGB - HSV Conversion 
+       
+       Author:         Gordon Knopes.
+
+       Calling Seq.:   rgb2hsv (src, dst)
+       Description:    Convert RGB color to HSV.
+       Input:          src =   Pointer to source RGB color structure.
+                       dst =   Pointer to source HSV color structure.
+       Returns:        Nothing.
+
+
+       Calling Seq.:   hsv2rgb (src, dst)
+       Description:    Convert HSV color to RGB.
+       Input:          src =   Pointer to source HSV color structure.
+                       dst =   Pointer to source RGB color structure.
+       Returns:        Nothing.
+
+       Creation Date:  8/6/85                                          */      
+/*----------------------------------------------------------------------*/
+
+#include <exec\types.h>
+#define local static
+
+#define SCLEXP 8
+       /* normalize factor = 256                       */
+
+#define MAXINT 0xefff
+#define MAXRGB 15
+#define MAXH 255
+       /* normalized max h = 6 << SCLEXP               */
+#define        MAXSV 255
+#define SCLH ((6 << SCLEXP) / MAXH)
+
+#define LMAXRGB 15L
+#define LMAXSV 255L
+
+#define LROUND 0x80L
+       /* (1 << (SCLEXP - 1))L                         */
+#define UNDEFINED -1
+#define F1 (1 << SCLEXP)
+#define F2 (2 << SCLEXP)
+#define F4 (4 << SCLEXP)
+
+typedef struct { SHORT r, g, b; } rgb;
+typedef struct { SHORT h, s, v; } hsv;
+
+local long r,g,b;
+local long tmp;
+
+local int mul(a, b) int a, b;    {
+    tmp = ((long) a * (long) b) >> SCLEXP;
+    return ((int) tmp);
+    }
+
+local int div(a, b) int a, b;   {
+    if (b == 0)        tmp = MAXINT;
+    else tmp = ((long) a << SCLEXP) / (long) b;
+    return ((int) tmp);
+    }
+
+/*     assign triplet to RGB.  */
+local void triplet(x, y, z) int x, y, z;    {
+    r = x;    g = y;    b = z;
+    }
+
+local int normrgb(x) SHORT x;    {
+    tmp = ((long) x << SCLEXP) / LMAXRGB;
+    return ((int) tmp);
+    }
+
+local SHORT unnormrgb(x) int x;    {
+    tmp = ((long) x * LMAXRGB + LROUND) >> SCLEXP;
+    return ((SHORT) tmp);
+    }
+
+local int normsv(x) SHORT x;    {
+    tmp = ((long) x << SCLEXP) / LMAXSV;
+    return ((int) tmp);
+    }
+
+local SHORT unnormsv(x) int x;    {
+    tmp = ((long) x * LMAXSV + LROUND) >> SCLEXP;
+    if (tmp > LMAXSV)  tmp = LMAXSV;
+    return ((SHORT) tmp);
+    }
+
+local int normh(h) SHORT h;    {
+    if (h >= MAXH) h = 0;
+    return ((int) (h * SCLH) );        /* h is now [0, 6] */
+    }
+
+local SHORT unnormh(h) int h;    {
+    h /= SCLH; /* convert to degrees */
+    if (h < 0)         /* make nonnegative */
+       h +=MAXH;
+    if (h >= MAXH)     h = 0;
+    return ((SHORT) h);
+    }
+
+/*----------------------------------------------------------------------*/
+/*
+    RGB_TO_HSV.
+           
+    Given: r, g, b, each in [0, 255]
+    Desired: h, s and v in [0, 255], except if s = 0,
+    then h = UNDEFINED which is a definrd constant not in [0, 255].
+                                                                       */
+/*----------------------------------------------------------------------*/
+    
+rgb2hsv(src, dst) rgb *src; hsv *dst;    {
+    int h, s, v, rc, gc, bc, max, min, diff;
+
+    r = normrgb (src->r);
+    g = normrgb (src->g);
+    b = normrgb (src->b);
+    max = (r > g) ? ((r > b) ? r : b) : (g > b) ? g : b;
+    min = (r < g) ? ((r < b) ? r : b) : (g < b) ? g : b;
+    v = max;                   /* value */
+    diff = div (F1, max-min);
+    if (max != 0)
+       s = div (F1, mul (diff, max));  /* saturation */
+    else s = 0;
+    s = (int) unnormsv(s);
+    if (s == 0)
+       h = (SHORT) UNDEFINED;
+    else
+       {                       /* saturation not zero, so determine hue */
+       rc = mul (max - r, diff); /* rc measures distance of color from red */
+       gc = mul (max - g,  diff);
+       bc = mul (max - b, diff);
+       if (r == max)
+           h = bc - gc;        /* color between yellow & magenta */
+       else
+           {
+           if (g == max)
+               h = F2 + rc - bc; /* color between cyan & yellow */
+           else
+               {
+               if (b == max)
+                   h = F4 + gc - rc; /* color between magenta & cyan */
+               }
+           }
+       h = unnormh(h);
+       }       /* chromatic case */
+    dst->h = h;
+    dst->s = (SHORT) s;
+    dst->v = unnormsv (v);
+    
+    if (dst->h < 3)    /* Rgb2hsv doesn't return 0. */
+       dst->h = 0;
+    if (dst->s < 3)
+       dst->s = 0;
+    if (dst->s < 3)
+       dst->s = 0;
+    }
+
+/*----------------------------------------------------------------------*/
+/*
+       HSV_TO_RGB.
+           
+       Given: h, s and v in [0, 255]
+       Desired: r, g, b, each in [0, 255].                             */
+/*----------------------------------------------------------------------*/
+hsv2rgb(src, dst) hsv *src; rgb *dst;    {
+    int h, s, v, f, p, q, t;
+    int i;
+
+    if (src->h >= MAXH)
+       src->h = 0;
+    h = (int) src->h;
+    s = normsv (src->s);
+    v = normsv (src->v);
+    if (s == 0)
+       triplet (v, v, v);      /* achromatic case */
+/*
+       {                       * achromatic color: no hue *
+       if (h < 0)
+           triplet (v, v, v);  * achromatic case *
+       else
+           {
+           printf ("\n*** error (if s = 0 and h has value) ***\n");
+           exit (0);
+           }
+       }
+*/
+    else
+       {                               /* chromatic color: hue */
+       h = normh(h);
+       i = (int) (h >> SCLEXP);        /* largest integer <= h */
+       f = h - (i << SCLEXP);          /* fractional part of h */
+       p = mul (v, F1 - s);
+       q = mul (v, F1 - mul (s, f));
+       t = mul (v, F1 - mul (s, F1 - f));
+       switch (i)
+           {                           /* triplet assignment */
+           case 0: triplet (v, t, p);
+                   break;
+           case 1: triplet (q, v, p);
+                   break;
+           case 2: triplet (p, v, t);
+                   break;
+           case 3: triplet (p, q, v);
+                   break;
+           case 4: triplet (t, p, v);
+                   break;
+           case 5: triplet (v, p, q);
+           }   /* case */
+       }       /* hue */
+    dst->r = unnormrgb (r);
+    dst->g = unnormrgb (g);
+    dst->b = unnormrgb (b);
+
+    }
diff --git a/IFFR.C b/IFFR.C
new file mode 100644 (file)
index 0000000..26cb214
--- /dev/null
+++ b/IFFR.C
@@ -0,0 +1,295 @@
+/*----------------------------------------------------------------------*/
+/* IFFR.C  Support routines for reading IFF-85 files.          10/10/85 */
+/* (IFF is Interchange Format File.)                                   */
+/*                                                                     */
+/* By Jerry Morrison and Steve Shaw, Electronic Arts.                  */
+/* This software is in the public domain.                              */
+/*----------------------------------------------------------------------*/
+#include "iff\iff.h"
+
+/* ---------- Read -----------------------------------------------------*/
+
+/* ---------- OpenRIFF --------------------------------------------------*/
+IFFP OpenRIFF(file0, new0, clientFrame)
+       BPTR file0;   GroupContext *new0;  ClientFrame *clientFrame; {
+    register BPTR file = file0;
+    register GroupContext *new = new0;
+    IFFP iffp = IFF_OKAY;
+
+    new->parent       = NULL;          /* "whole file" has no parent.*/
+    new->clientFrame  = clientFrame;
+    new->file         = file;
+    new->position     = 0;
+    new->ckHdr.ckID   = new->subtype    = NULL_CHUNK;
+    new->ckHdr.ckSize = new->bytesSoFar = 0;
+
+    /* Set new->bound. AmigaDOS specific code.*/
+    if (file <= 0)   return(NO_FILE);
+    Seek(file, 0, OFFSET_END);                 /* Seek to end of file.*/
+    new->bound = Seek(file, 0, OFFSET_CURRENT);        /* Pos'n == #bytes in file.*/
+    if (new->bound < 0)   return(DOS_ERROR);   /* DOS being absurd.*/
+    Seek(file, 0, OFFSET_BEGINNING);           /* Go to file start.*/
+    /* Would just do this if Amiga DOS maintained fh_End: */
+    /* new->bound = (FileHandle *)BADDR(file)->fh_End; */
+
+    if ( new->bound < sizeof(ChunkHeader) )
+       iffp = NOT_IFF;
+    return(iffp);
+    }
+
+/* ---------- OpenRGroup -----------------------------------------------*/
+IFFP OpenRGroup(parent0, new0)   GroupContext *parent0, *new0; {
+    register GroupContext *parent = parent0;
+    register GroupContext *new    = new0;
+    IFFP iffp = IFF_OKAY;
+
+    new->parent       = parent;
+    new->clientFrame  = parent->clientFrame;
+    new->file         = parent->file;
+    new->position     = parent->position;
+    new->bound        = parent->position + ChunkMoreBytes(parent);
+    new->ckHdr.ckID   = new->subtype    = NULL_CHUNK;
+    new->ckHdr.ckSize = new->bytesSoFar = 0;
+
+    if ( new->bound > parent->bound  ||  IS_ODD(new->bound) )
+       iffp = BAD_IFF;
+    return(iffp);
+    }
+
+/* ---------- CloseRGroup -----------------------------------------------*/
+IFFP CloseRGroup(context)   GroupContext *context; {
+    register LONG position;
+
+    if (context->parent == NULL) {
+       }  /* Context for whole file.*/
+    else {
+       position = context->position;
+       context->parent->bytesSoFar += position - context->parent->position;
+       context->parent->position = position;
+       }
+    return(IFF_OKAY);
+    }
+
+/* ---------- SkipFwd --------------------------------------------------*/
+/* Skip over bytes in a context. Won't go backwards.*/
+/* Updates context->position but not context->bytesSoFar.*/
+/* This implementation is AmigaDOS specific.*/
+IFFP SkipFwd(context, bytes)   GroupContext *context;  LONG bytes; {
+    IFFP iffp = IFF_OKAY;
+
+    if (bytes > 0) {
+       if (-1 == Seek(context->file, bytes, OFFSET_CURRENT))
+           iffp = BAD_IFF;     /* Ran out of bytes before chunk complete.*/
+       else
+           context->position += bytes;
+       }
+    return(iffp);
+    }
+
+/* ---------- GetChunkHdr ----------------------------------------------*/
+ID GetChunkHdr(context0)   GroupContext *context0;  {
+    register GroupContext *context = context0;
+    register IFFP iffp;
+    LONG remaining;
+
+    /* Skip remainder of previous chunk & padding. */
+    iffp = SkipFwd(context,
+       ChunkMoreBytes(context) + IS_ODD(context->ckHdr.ckSize));
+    CheckIFFP();
+
+    /* Set up to read the new header. */
+    context->ckHdr.ckID = BAD_IFF;     /* Until we know it's okay, mark it BAD.*/
+    context->subtype    = NULL_CHUNK;
+    context->bytesSoFar = 0;
+
+    /* Generate a psuedo-chunk if at end-of-context. */
+    remaining = context->bound - context->position;
+    if (remaining == 0) {
+       context->ckHdr.ckSize = 0;
+       context->ckHdr.ckID   = END_MARK;
+       }
+
+    /* BAD_IFF if not enough bytes in the context for a ChunkHeader.*/
+    else if (sizeof(ChunkHeader) > remaining) {
+       context->ckHdr.ckSize = remaining;
+       }
+
+    /* Read the chunk header (finally). */
+    else {
+        switch (Read(context->file, &context->ckHdr, sizeof(ChunkHeader))) {
+           case -1: return(context->ckHdr.ckID = DOS_ERROR);
+           case 0:  return(context->ckHdr.ckID = BAD_IFF);
+           }
+
+       /* Check: Top level chunk must be LIST or FORM or CAT. */
+       if (context->parent == NULL)
+           switch(context->ckHdr.ckID) {
+               case FORM:  case LIST:  case CAT:  break;
+               default:    return(context->ckHdr.ckID = NOT_IFF);
+               }
+
+       /* Update the context. */
+       context->position += sizeof(ChunkHeader);
+       remaining         -= sizeof(ChunkHeader);
+
+       /* Non-positive ID values are illegal and used for error codes.*/
+       /* We could check for other illegal IDs...*/
+       if (context->ckHdr.ckID <= 0)
+            context->ckHdr.ckID = BAD_IFF;
+
+       /* Check: ckSize negative or larger than # bytes left in context? */
+       else if (context->ckHdr.ckSize < 0  ||
+                context->ckHdr.ckSize > remaining) {
+           context->ckHdr.ckSize = remaining;
+           context->ckHdr.ckID   = BAD_IFF;
+           }
+
+       /* Automatically read the LIST, FORM, PROP, or CAT subtype ID */
+       else switch (context->ckHdr.ckID) {
+           case LIST:  case FORM:  case PROP:  case CAT:  {
+               iffp = IFFReadBytes(context,
+                                   (BYTE *)&context->subtype,
+                                   sizeof(ID));
+               if (iffp != IFF_OKAY)
+                   context->ckHdr.ckID = iffp;
+               break; }
+           }
+
+       }
+    return(context->ckHdr.ckID);
+    }
+
+/* ---------- IFFReadBytes ---------------------------------------------*/
+IFFP IFFReadBytes(context, buffer, nBytes)
+    GroupContext *context;   BYTE *buffer;   LONG nBytes; {
+    register IFFP iffp = IFF_OKAY;
+
+    if (nBytes < 0)
+       iffp = CLIENT_ERROR;
+    else if (nBytes > ChunkMoreBytes(context))
+       iffp = SHORT_CHUNK;
+    else if (nBytes > 0)
+       switch ( Read(context->file, buffer, nBytes) ) {
+           case -1: {iffp = DOS_ERROR; break; }
+           case 0:  {iffp = BAD_IFF;   break; }
+           default: {
+               context->position   += nBytes;
+               context->bytesSoFar += nBytes;
+               }
+           }
+
+    return(iffp);
+    }
+
+/* ---------- SkipGroup ------------------------------------------------*/
+IFFP SkipGroup(context)  GroupContext *context;  {
+    }  /* Nothing to do, thanks to GetChunkHdr */
+
+/* ---------- ReadIFF --------------------------------------------------*/
+IFFP ReadIFF(file, clientFrame)  BPTR file;  ClientFrame *clientFrame;  {
+    /*CompilerBug register*/ IFFP iffp;
+    GroupContext context;
+
+    iffp = OpenRIFF(file, &context);
+    context.clientFrame = clientFrame;
+
+    if (iffp == IFF_OKAY)
+       switch (iffp = GetChunkHdr(&context)) {
+           case FORM: { iffp = (*clientFrame->getForm)(&context); break; }
+           case LIST: { iffp = (*clientFrame->getList)(&context); break; }
+           case CAT : { iffp = (*clientFrame->getCat )(&context); break; }
+           /* default: Includes IFF_DONE, BAD_IFF, NOT_IFF... */
+           }
+
+    CloseRGroup(&context);
+
+    if (iffp > 0)              /* Make sure we don't return an ID.*/
+       iffp = NOT_IFF;         /* GetChunkHdr should've caught this.*/
+    return(iffp);
+    }
+
+/* ---------- ReadIList ------------------------------------------------*/
+IFFP ReadIList(parent, clientFrame)
+    GroupContext *parent;  ClientFrame *clientFrame; {
+    GroupContext listContext;
+    IFFP iffp;
+    BOOL propOk = TRUE;
+
+    iffp = OpenRGroup(parent, &listContext);
+    CheckIFFP();
+
+    /* One special case test lets us handle CATs as well as LISTs.*/
+    if (parent->ckHdr.ckID == CAT)
+       propOk = FALSE;
+    else
+       listContext.clientFrame = clientFrame;
+
+    do {
+       switch (iffp = GetChunkHdr(&listContext)) {
+           case PROP: {
+               if (propOk)
+                   iffp = (*clientFrame->getProp)(&listContext);
+               else
+                   iffp = BAD_IFF;
+               break;
+               }
+           case FORM: { iffp = (*clientFrame->getForm)(&listContext); break; }
+           case LIST: { iffp = (*clientFrame->getList)(&listContext); break; }
+           case CAT : { iffp = (*clientFrame->getCat )(&listContext); break; }
+           /* default: Includes END_MARK, IFF_DONE, BAD_IFF, NOT_IFF... */
+           }
+       if (listContext.ckHdr.ckID != PROP)
+           propOk = FALSE;     /* No PROPs allowed after this point.*/
+       } while (iffp == IFF_OKAY);
+
+    CloseRGroup(&listContext);
+
+    if (iffp > 0)      /* Only chunk types above are allowed in a LIST/CAT.*/
+       iffp = BAD_IFF;
+    return(iffp == END_MARK ? IFF_OKAY : iffp);
+    }
+
+/* ---------- ReadICat -------------------------------------------------*/
+/* By special arrangement with the ReadIList implement'n, this is trivial.*/
+IFFP ReadICat(parent)  GroupContext *parent;  {
+    return( ReadIList(parent, NULL) );
+    }
+
+/* ---------- GetFChunkHdr ---------------------------------------------*/
+ID GetFChunkHdr(context)   GroupContext *context; {
+    register ID id;
+
+    id = GetChunkHdr(context);
+    if (id == PROP)
+       context->ckHdr.ckID = id = BAD_IFF;
+    return(id);
+    }
+
+/* ---------- GetF1ChunkHdr ---------------------------------------------*/
+ID GetF1ChunkHdr(context)   GroupContext *context; {
+    register ID id;
+    register ClientFrame *clientFrame = context->clientFrame;
+
+    switch (id = GetChunkHdr(context))  {
+       case PROP: { id = BAD_IFF; break; }
+       case FORM: { id = (*clientFrame->getForm)(context); break; }
+       case LIST: { id = (*clientFrame->getList)(context); break; }
+       case CAT : { id = (*clientFrame->getCat )(context); break; }
+       /* Default: let the caller handle other chunks */
+       }
+    return(context->ckHdr.ckID = id);
+    }
+
+/* ---------- GetPChunkHdr ---------------------------------------------*/
+ID GetPChunkHdr(context)   GroupContext *context; {
+    register ID id;
+
+    id = GetChunkHdr(context);
+    switch (id) {
+       case LIST:  case FORM:  case PROP:  case CAT:  {
+           id = context->ckHdr.ckID = BAD_IFF;
+           break; }
+       }
+    return(id);
+    }
+
diff --git a/IFFW.C b/IFFW.C
new file mode 100644 (file)
index 0000000..7969317
--- /dev/null
+++ b/IFFW.C
@@ -0,0 +1,310 @@
+/*----------------------------------------------------------------------*
+ * IFFW.C  Support routines for writing IFF-85 files.          12/02/85
+ * (IFF is Interchange Format File.)
+ *
+ * By Jerry Morrison and Steve Shaw, Electronic Arts.
+ * This software is in the public domain.
+ *
+ * This version for the Commodore-Amiga computer.
+ *----------------------------------------------------------------------*/
+#include "iff/iff.h"
+
+/* ---------- IFF Writer -----------------------------------------------*/
+
+/* A macro to test if a chunk size is definite, i.e. not szNotYetKnown.*/
+#define Known(size)   ( (size) != szNotYetKnown )
+
+/* Yet another weird macro to make the source code simpler...*/
+#define IfIffp(expr)  {if (iffp == IFF_OKAY)  iffp = (expr);}
+
+
+/* ---------- Generic I/O Speed Up Package -----------------------------*/
+
+#define local /*TBD static*/
+
+local BPTR wFile = NULL;
+local BYTE *wBuffer = NULL;
+local LONG wNBytes=0;   /* buffer size in bytes.*/
+local LONG wIndex=0;    /* index of next available byte.*/
+local LONG wWaterline=0; /* Count of # bytes to be written.
+                         * Different than wIndex because of GSeek.*/
+
+/* ---------- GWriteFlush ----------------------------------------------*/
+/* Writes out any data in write buffer above.
+ * NOTE WHEN have Seeked into middle of buffer:
+ * GWriteFlush causes current position to be the end of the data written.
+ * -1 on error from Write.*/
+int GWriteFlush() {
+    int gWrite = 0;
+    if (wFile != NULL  &&  wBuffer != NULL  &&  wIndex > 0)
+       gWrite = Write(wFile, wBuffer, wWaterline);
+    wWaterline = wIndex = 0;   /* No matter what, make sure this happens.*/
+    return( gWrite );
+    }
+
+/* ---------- GWriteDeclare --------------------------------------------*/
+/* Sets up variables above to describe a write buffer.*/
+/* -1 on error from Write.*/
+int GWriteDeclare(file, buffer, nBytes)
+    BPTR file;  BYTE *buffer;  LONG nBytes; {
+    int gWrite = GWriteFlush();
+    if ( file==NULL  ||  buffer==NULL  ||  nBytes<=3) {
+       wFile = NULL;   wBuffer = NULL;     wNBytes = 0; }
+    else {
+       wFile = file;   wBuffer = buffer;   wNBytes = nBytes; }
+    return( gWrite );
+    }
+
+/* ---------- GWrite ---------------------------------------------------*/
+/* ANY PROGRAM WHICH USES "GWrite" MUST USE "GSeek" rather than "Seek"
+ * TO SEEK ON A FILE BEING WRITTEN WITH "GWrite".
+ * "Write" with Generic speed-up.
+ * -1 on error from Write.  else returns # bytes written to disk.*/
+int GWrite(file, buffer, nBytes)   BPTR file;  BYTE *buffer;  int nBytes; {
+    int gWrite = 0;
+
+    if (file == wFile  &&  wBuffer != NULL) {
+       if (wNBytes >= wIndex + nBytes) {
+           /* Append to wBuffer.*/
+           movmem(buffer, wBuffer+wIndex, nBytes);
+           wIndex += nBytes;
+           if (wIndex > wWaterline)
+               wWaterline = wIndex;
+           nBytes = 0;         /* Indicate data has been swallowed.*/
+           }
+       else {
+           wWaterline = wIndex;     /* We are about to overwrite any
+               * data above wIndex, up to at least the buffer end.*/
+           gWrite = GWriteFlush();  /* Write data out in proper order.*/
+           }
+       }
+    if (nBytes > 0  &&  gWrite >= 0)
+       gWrite += Write(file, buffer, nBytes);
+    return( gWrite );
+    }
+
+/* ---------- GSeek ----------------------------------------------------*/
+/* "Seek" with Generic speed-up, for a file being written with GWrite.*/
+/* Returns what Seek returns, which appears to be the position BEFORE
+ * seeking, though the documentation says it returns the NEW position.*/
+/* CURRENTLY RETURNS 0 WHEN SEEKING WITHIN THE BUFFER.*/
+int GSeek(file, position, mode)
+    BPTR file;   BYTE *position;   int mode; {
+    int gSeek = -2;
+    int newWIndex = wIndex + (int)position;
+
+    if (file == wFile  &&  wBuffer != NULL) {
+       if (mode == OFFSET_CURRENT  &&
+           newWIndex >= 0  &&  newWIndex <= wWaterline) {
+           wIndex = newWIndex;
+           gSeek = 0;          /* Okay */
+           }
+       else {
+           /* Can't optimize it.*/
+           gSeek = GWriteFlush();
+           if (gSeek >= 0)   gSeek = -2;  /* OK so far */
+           }
+       }
+    if (gSeek == -2)
+       gSeek = Seek(file, position, mode);
+    return( gSeek );
+    }
+
+/* ---------- OpenWIFF -------------------------------------------------*/
+
+IFFP OpenWIFF(file, new0, limit)  BPTR file; GroupContext *new0; LONG limit; {
+    register GroupContext *new = new0;
+    register IFFP iffp = IFF_OKAY;
+
+    new->parent       = NULL;
+    new->clientFrame  = NULL;
+    new->file         = file;
+    new->position     = 0;
+    new->bound        = limit;
+    new->ckHdr.ckID   = NULL_CHUNK;  /* indicates no current chunk */
+    new->ckHdr.ckSize = new->bytesSoFar = 0;
+
+    if (0 > Seek(file, 0, OFFSET_BEGINNING))   /* Go to start of the file.*/
+       iffp = DOS_ERROR;
+    else if ( Known(limit) && IS_ODD(limit) )
+       iffp = CLIENT_ERROR;
+    return(iffp);
+    }
+
+/* ---------- StartWGroup ----------------------------------------------*/
+IFFP StartWGroup(parent, groupType, groupSize, subtype, new)
+      GroupContext *parent, *new; ID groupType, subtype; LONG groupSize;  {
+    register IFFP iffp;
+
+    iffp = PutCkHdr(parent, groupType, groupSize);
+    IfIffp( IFFWriteBytes(parent, (BYTE *)&subtype, sizeof(ID)) );
+    IfIffp( OpenWGroup(parent, new) );
+    return(iffp);
+    }
+
+/* ---------- OpenWGroup -----------------------------------------------*/
+IFFP OpenWGroup(parent0, new0)  GroupContext *parent0, *new0; {
+    register GroupContext *parent = parent0;
+    register GroupContext *new    = new0;
+    register LONG ckEnd;
+    register IFFP iffp = IFF_OKAY;
+
+    new->parent       = parent;
+    new->clientFrame  = parent->clientFrame;
+    new->file         = parent->file;
+    new->position     = parent->position;
+    new->bound        = parent->bound;
+    new->ckHdr.ckID   = NULL_CHUNK;
+    new->ckHdr.ckSize = new->bytesSoFar = 0;
+
+    if ( Known(parent->ckHdr.ckSize) ) {
+       ckEnd = new->position + ChunkMoreBytes(parent);
+       if ( new->bound == szNotYetKnown || new->bound > ckEnd )
+           new->bound = ckEnd;
+       };
+
+    if ( parent->ckHdr.ckID == NULL_CHUNK || /* not currently writing a chunk*/
+        IS_ODD(new->position) ||
+         (Known(new->bound) && IS_ODD(new->bound)) )
+       iffp = CLIENT_ERROR;
+    return(iffp);
+    }
+
+/* ---------- CloseWGroup ----------------------------------------------*/
+IFFP CloseWGroup(old0)  GroupContext *old0; {
+    register GroupContext *old = old0;
+
+    if ( old->ckHdr.ckID != NULL_CHUNK )  /* didn't close the last chunk */
+       return(CLIENT_ERROR);
+    if ( old->parent == NULL ) {         /* top level file context */
+       /* [TBD] set logical EOF */
+       /* [TBD] GWriteEOF(old->file); */
+       GWriteFlush();          /* Good enough.*/
+       }
+    else {
+       old->parent->bytesSoFar += old->position - old->parent->position;
+       old->parent->position = old->position;
+       };
+    return(IFF_OKAY);
+    }
+
+/* ---------- EndWGroup ------------------------------------------------*/
+IFFP EndWGroup(old)  GroupContext *old;  {
+    register GroupContext *parent = old->parent;
+    register IFFP iffp;
+
+    iffp = CloseWGroup(old);
+    IfIffp( PutCkEnd(parent) );
+    return(iffp);
+    }
+
+/* ---------- PutCk ----------------------------------------------------*/
+IFFP PutCk(context, ckID, ckSize, data)
+      GroupContext *context; ID ckID; LONG ckSize; BYTE *data; {
+    register IFFP iffp = IFF_OKAY;
+
+    if ( ckSize == szNotYetKnown )
+       iffp = CLIENT_ERROR;
+    IfIffp( PutCkHdr(context, ckID, ckSize) );
+    IfIffp( IFFWriteBytes(context, data, ckSize) );
+    IfIffp( PutCkEnd(context) );
+    return(iffp);
+    }
+
+/* ---------- PutCkHdr -------------------------------------------------*/
+IFFP PutCkHdr(context0, ckID, ckSize)
+      GroupContext *context0;  ID ckID;  LONG ckSize; {
+    register GroupContext *context = context0;
+    LONG minPSize = sizeof(ChunkHeader); /* physical chunk >= minPSize bytes*/
+
+    /* CLIENT_ERROR if we're already inside a chunk or asked to write
+     * other than one FORM, LIST, or CAT at the top level of a file */
+    /* Also, non-positive ID values are illegal and used for error codes.*/
+    /* (We could check for other illegal IDs...)*/
+    if ( context->ckHdr.ckID != NULL_CHUNK  ||  ckID <= 0 )
+       return(CLIENT_ERROR);
+    else if (context->parent == NULL)  {
+       switch (ckID)  {
+           case FORM:  case LIST:  case CAT:  break;
+           default: return(CLIENT_ERROR);
+           }
+       if (context->position != 0)
+           return(CLIENT_ERROR);
+       }
+
+    if ( Known(ckSize) ) {
+       if ( ckSize < 0 )
+           return(CLIENT_ERROR);
+       minPSize += ckSize;
+       };
+    if ( Known(context->bound)  &&
+         context->position + minPSize > context->bound )
+       return(CLIENT_ERROR);
+
+    context->ckHdr.ckID   = ckID;
+    context->ckHdr.ckSize = ckSize;
+    context->bytesSoFar   = 0;
+    if (0 > GWrite(context->file, &context->ckHdr, sizeof(ChunkHeader)))
+       return(DOS_ERROR);
+    context->position += sizeof(ChunkHeader);
+    return(IFF_OKAY);
+    }
+
+/* ---------- IFFWriteBytes ---------------------------------------------*/
+IFFP IFFWriteBytes(context0, data, nBytes)
+      GroupContext *context0;  BYTE *data;  LONG nBytes; {
+    register GroupContext *context = context0;
+
+    if ( context->ckHdr.ckID == NULL_CHUNK  || /* not in a chunk */
+        nBytes < 0  ||                         /* negative nBytes */
+        (Known(context->bound)  &&             /* overflow context */
+           context->position + nBytes > context->bound)  ||
+        (Known(context->ckHdr.ckSize)  &&      /* overflow chunk */
+           context->bytesSoFar + nBytes > context->ckHdr.ckSize) )
+       return(CLIENT_ERROR);
+
+    if (0 > GWrite(context->file, data, nBytes))
+       return(DOS_ERROR);
+
+    context->bytesSoFar += nBytes;
+    context->position   += nBytes;
+    return(IFF_OKAY);
+    }
+
+/* ---------- PutCkEnd -------------------------------------------------*/
+IFFP PutCkEnd(context0)  GroupContext *context0; {
+    register GroupContext *context = context0;
+    WORD zero = 0;     /* padding source */
+
+    if ( context->ckHdr.ckID == NULL_CHUNK )  /* not in a chunk */
+       return(CLIENT_ERROR);
+
+    if ( context->ckHdr.ckSize == szNotYetKnown ) {
+       /* go back and set the chunk size to bytesSoFar */
+       if ( 0 > GSeek(context->file,
+                     -(context->bytesSoFar + sizeof(LONG)),
+                     OFFSET_CURRENT)  ||
+            0 > GWrite(context->file, &context->bytesSoFar, sizeof(LONG))  ||
+            0 > GSeek(context->file, context->bytesSoFar, OFFSET_CURRENT)  )
+           return(DOS_ERROR);
+       }
+    else {  /* make sure the client wrote as many bytes as planned */
+       if ( context->ckHdr.ckSize != context->bytesSoFar )
+           return(CLIENT_ERROR);
+       };
+
+    /* Write a pad byte if needed to bring us up to an even boundary.
+     * Since the context end must be even, and since we haven't
+     * overwritten the context, if we're on an odd position there must
+     * be room for a pad byte. */
+    if ( IS_ODD(context->bytesSoFar) ) {
+       if ( 0 > GWrite(context->file, &zero, 1) )
+           return(DOS_ERROR);
+       context->position += 1;
+       };
+
+    context->ckHdr.ckID   = NULL_CHUNK;
+    context->ckHdr.ckSize = context->bytesSoFar = 0;
+    return(IFF_OKAY);
+    }
+
diff --git a/ILBMR.C b/ILBMR.C
new file mode 100644 (file)
index 0000000..1e126bb
--- /dev/null
+++ b/ILBMR.C
@@ -0,0 +1,144 @@
+/*----------------------------------------------------------------------*/
+/* ILBMR.C  Support routines for reading ILBM files.           11/07/85 */
+/* (IFF is Interchange Format File.)                                   */
+/*                                                                     */
+/* By Jerry Morrison and Steve Shaw, Electronic Arts.                  */
+/* This software is in the public domain.                              */
+/*----------------------------------------------------------------------*/
+#include "iff\packer.h"
+#include "iff\ilbm.h"
+
+
+/* ---------- GetCMAP ------------------------------------------------*/
+/* pNColorRegs is passed in as a pointer to the number of ColorRegisters
+ * caller has space to hold.  GetCMAP sets to the number actually read.*/
+IFFP GetCMAP(ilbmContext, colorMap, pNColorRegs)   
+      GroupContext *ilbmContext;  WORD *colorMap;  UBYTE *pNColorRegs;
+   {
+   register int nColorRegs;   
+   register IFFP iffp;
+   ColorRegister colorReg;
+
+   nColorRegs = ilbmContext->ckHdr.ckSize / sizeofColorRegister;
+   if (*pNColorRegs < nColorRegs)   nColorRegs = *pNColorRegs;
+   *pNColorRegs = nColorRegs;  /* Set to the number actually there.*/
+
+   for ( ;  nColorRegs > 0;  --nColorRegs)  {
+      iffp = IFFReadBytes(ilbmContext, (BYTE *)&colorReg,sizeofColorRegister);
+      CheckIFFP();
+      *colorMap++ = ( ( colorReg.red   >> 4 ) << 8 ) |
+                   ( ( colorReg.green >> 4 ) << 4 ) |
+                   ( ( colorReg.blue  >> 4 )      );
+      }
+   return(IFF_OKAY);
+   }
+
+/*---------- GetBODY ---------------------------------------------------*/
+/* NOTE: This implementation could be a LOT faster if it used more of the
+ * supplied buffer. It would make far fewer calls to IFFReadBytes (and
+ * therefore to DOS Read) and to movemem. */
+IFFP GetBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
+      GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
+      BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
+   {
+   register IFFP iffp;
+   UBYTE srcPlaneCnt = bmHdr->nPlanes;   /* Haven't counted for mask plane yet*/
+   LONG srcRowBytes = RowBytes(bmHdr->w);
+   LONG bufRowBytes = MaxPackedSize(srcRowBytes);
+   int nRows = bmHdr->h;
+   Compression compression = bmHdr->compression;
+   register int iPlane, iRow, nEmpty, nFilled;
+   BYTE *buf, *nullDest, *nullBuf, **pDest;
+   BYTE *planes[MaxSrcPlanes]; /* array of ptrs to planes & mask */
+
+   if (compression > cmpByteRun1)
+      return(CLIENT_ERROR);
+
+   /* Complain if client asked for a conversion GetBODY doesn't handle.*/
+   if ( srcRowBytes  !=  bitmap->BytesPerRow  ||
+         bufsize < bufRowBytes * 2  ||
+         srcPlaneCnt > MaxSrcPlanes )
+      return(CLIENT_ERROR);
+
+   if (nRows > bitmap->Rows)
+      nRows = bitmap->Rows;
+   
+   /* Initialize array "planes" with bitmap ptrs; NULL in empty slots.*/
+   for (iPlane = 0; iPlane < bitmap->Depth; iPlane++)
+      planes[iPlane] = (BYTE *)bitmap->Planes[iPlane];
+   for ( ;  iPlane < MaxSrcPlanes;  iPlane++)
+      planes[iPlane] = NULL;
+
+   /* Copy any mask plane ptr into corresponding "planes" slot.*/
+   if (bmHdr->masking == mskHasMask) {
+      if (mask != NULL)
+         planes[srcPlaneCnt] = mask;  /* If there are more srcPlanes than
+               * dstPlanes, there will be NULL plane-pointers before this.*/
+      else
+         planes[srcPlaneCnt] = NULL;  /* In case more dstPlanes than src.*/
+      srcPlaneCnt += 1;  /* Include mask plane in count.*/
+      }
+
+   /* Setup a sink for dummy destination of rows from unwanted planes.*/
+   nullDest = buffer;
+   buffer  += srcRowBytes;
+   bufsize -= srcRowBytes;
+
+   /* Read the BODY contents into client's bitmap.
+    * De-interleave planes and decompress rows.
+    * MODIFIES: Last iteration modifies bufsize.*/
+   buf = buffer + bufsize;  /* Buffer is currently empty.*/
+   for (iRow = nRows; iRow > 0; iRow--)  {
+      for (iPlane = 0; iPlane < srcPlaneCnt; iPlane++)  {
+
+         pDest = &planes[iPlane];
+
+         /* Establish a sink for any unwanted plane.*/
+         if (*pDest == NULL) {
+           nullBuf = nullDest;
+            pDest   = &nullBuf;
+            }
+
+         /* Read in at least enough bytes to uncompress next row.*/
+         nEmpty  = buf - buffer;         /* size of empty part of buffer.*/
+         nFilled = bufsize - nEmpty;     /* this part has data.*/
+        if (nFilled < bufRowBytes) {
+           /* Need to read more.*/
+
+           /* Move the existing data to the front of the buffer.*/
+           /* Now covers range buffer[0]..buffer[nFilled-1].*/
+            movmem(buf, buffer, nFilled);  /* Could be moving 0 bytes.*/
+
+            if (nEmpty > ChunkMoreBytes(context)) {
+               /* There aren't enough bytes left to fill the buffer.*/
+               nEmpty = ChunkMoreBytes(context);
+               bufsize = nFilled + nEmpty;  /* heh-heh */
+               }
+
+           /* Append new data to the existing data.*/
+            iffp = IFFReadBytes(context, &buffer[nFilled], nEmpty);
+            CheckIFFP();
+
+            buf     = buffer;
+           nFilled = bufsize;
+           nEmpty  = 0;
+           }
+
+         /* Copy uncompressed row to destination plane.*/
+         if (compression == cmpNone) {
+            if (nFilled < srcRowBytes)  return(BAD_FORM);
+           movmem(buf, *pDest, srcRowBytes);
+           buf    += srcRowBytes;
+            *pDest += srcRowBytes;
+            }
+        else
+         /* Decompress row to destination plane.*/
+            if ( UnPackRow(&buf, pDest, nFilled,  srcRowBytes) )
+                    /*  pSource, pDest, srcBytes, dstBytes  */
+               return(BAD_FORM);
+         }
+      }
+
+   return(IFF_OKAY);
+   }
+
diff --git a/ILBMW.C b/ILBMW.C
new file mode 100644 (file)
index 0000000..c5ec37b
--- /dev/null
+++ b/ILBMW.C
@@ -0,0 +1,140 @@
+/*----------------------------------------------------------------------*/
+/* ILBMW.C  Support routines for writing ILBM files.           11/06/85 */
+/* (IFF is Interchange Format File.)                                   */
+/*                                                                     */
+/* By Jerry Morrison and Steve Shaw, Electronic Arts.                  */
+/* This software is in the public domain.                              */
+/*----------------------------------------------------------------------*/
+#include "iff\packer.h"
+#include "iff\ilbm.h"
+
+/*---------- InitBMHdr -------------------------------------------------*/
+IFFP InitBMHdr(bmHdr0, bitmap, masking, compression, transparentColor,
+           pageWidth, pageHeight)
+        BitMapHeader *bmHdr0;  struct BitMap *bitmap;
+        int masking, compression, transparentColor, pageWidth, pageHeight;
+        /*  Masking, Compression, UWORD,            WORD,      WORD  */
+    {
+    register BitMapHeader *bmHdr = bmHdr0;
+    register WORD rowBytes = bitmap->BytesPerRow;
+
+    bmHdr->w = rowBytes << 3;
+    bmHdr->h = bitmap->Rows;
+    bmHdr->x = bmHdr->y = 0;   /* Default position is (0,0).*/
+    bmHdr->nPlanes = bitmap->Depth;
+    bmHdr->masking = masking;
+    bmHdr->compression = compression;
+    bmHdr->pad1 = 0;
+    bmHdr->transparentColor = transparentColor;
+    bmHdr->xAspect = bmHdr->yAspect = 1;
+    bmHdr->pageWidth = pageWidth;
+    bmHdr->pageHeight = pageHeight;
+
+    if (pageWidth = 320)
+       switch (pageHeight) {
+           case 200: {bmHdr->xAspect = x320x200Aspect;
+                      bmHdr->yAspect = y320x200Aspect; break;}
+           case 400: {bmHdr->xAspect = x320x400Aspect;
+                      bmHdr->yAspect = y320x400Aspect; break;}
+           }
+    else if (pageWidth = 640)
+       switch (pageHeight) {
+           case 200: {bmHdr->xAspect = x640x200Aspect;
+                      bmHdr->yAspect = y640x200Aspect; break;}
+           case 400: {bmHdr->xAspect = x640x400Aspect;
+                      bmHdr->yAspect = y640x400Aspect; break;}
+           }
+
+    return( IS_ODD(rowBytes) ? CLIENT_ERROR : IFF_OKAY );
+    }
+
+/*---------- PutCMAP ---------------------------------------------------*/
+IFFP PutCMAP(context, colorMap, depth)   
+      GroupContext *context;  WORD *colorMap;  UBYTE depth;
+   {
+   register LONG nColorRegs;   
+   IFFP iffp;
+   ColorRegister colorReg;
+
+   if (depth > MaxAmDepth)   depth = MaxAmDepth;
+   nColorRegs = 1 << depth;
+
+   iffp = PutCkHdr(context, ID_CMAP, nColorRegs * sizeofColorRegister);
+   CheckIFFP();
+
+   for ( ;  nColorRegs;  --nColorRegs)  {
+      colorReg.red   = ( *colorMap >> 4 ) & 0xf0;
+      colorReg.green = ( *colorMap      ) & 0xf0;
+      colorReg.blue  = ( *colorMap << 4 ) & 0xf0;
+      iffp = IFFWriteBytes(context, (BYTE *)&colorReg, sizeofColorRegister);
+      CheckIFFP();
+      ++colorMap;
+      }
+
+   iffp = PutCkEnd(context);
+   return(iffp);
+   }
+
+/*---------- PutBODY ---------------------------------------------------*/
+/* NOTE: This implementation could be a LOT faster if it used more of the
+ * supplied buffer. It would make far fewer calls to IFFWriteBytes (and
+ * therefore to DOS Write). */
+IFFP PutBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
+      GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
+      BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
+   {         
+   IFFP iffp;
+   LONG rowBytes = bitmap->BytesPerRow;
+   int dstDepth = bmHdr->nPlanes;
+   Compression compression = bmHdr->compression;
+   int planeCnt;               /* number of bit planes including mask */
+   register int iPlane, iRow;
+   register LONG packedRowBytes;
+   BYTE *buf;
+   BYTE *planes[MaxAmDepth + 1]; /* array of ptrs to planes & mask */
+
+   if ( bufsize < MaxPackedSize(rowBytes)  ||  /* Must buffer a comprsd row*/
+        compression > cmpByteRun1  ||          /* bad arg */
+       bitmap->Rows != bmHdr->h   ||           /* inconsistent */
+       rowBytes != RowBytes(bmHdr->w)  ||      /* inconsistent*/
+       bitmap->Depth < dstDepth   ||           /* inconsistent */
+       dstDepth > MaxAmDepth )                 /* too many for this routine*/
+      return(CLIENT_ERROR);
+
+   planeCnt = dstDepth + (mask == NULL ? 0 : 1);
+
+   /* Copy the ptrs to bit & mask planes into local array "planes" */
+   for (iPlane = 0; iPlane < dstDepth; iPlane++)
+      planes[iPlane] = (BYTE *)bitmap->Planes[iPlane];
+   if (mask != NULL)
+      planes[dstDepth] = mask;
+
+   /* Write out a BODY chunk header */
+   iffp = PutCkHdr(context, ID_BODY, szNotYetKnown);
+   CheckIFFP();
+
+   /* Write out the BODY contents */
+   for (iRow = bmHdr->h; iRow > 0; iRow--)  {
+      for (iPlane = 0; iPlane < planeCnt; iPlane++)  {
+
+         /* Write next row.*/
+         if (compression == cmpNone) {
+            iffp = IFFWriteBytes(context, planes[iPlane], rowBytes);
+            planes[iPlane] += rowBytes;
+            }
+
+         /* Compress and write next row.*/
+         else {
+            buf = buffer;
+            packedRowBytes = PackRow(&planes[iPlane], &buf, rowBytes);
+            iffp = IFFWriteBytes(context, buffer, packedRowBytes);
+            }
+
+         CheckIFFP();
+         }
+      }
+
+   /* Finish the chunk */
+   iffp = PutCkEnd(context);
+   return(iffp);
+   }
diff --git a/INITOVS.C b/INITOVS.C
new file mode 100644 (file)
index 0000000..7dc9623
--- /dev/null
+++ b/INITOVS.C
@@ -0,0 +1,10 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*             initovs.c                                               */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+/* Dummy call which is trapped by the overlay manager to setup 
+the overlay parameters. */
+
+InitOVS() {}
diff --git a/INITREAD.C b/INITREAD.C
new file mode 100644 (file)
index 0000000..dfa0f43
--- /dev/null
@@ -0,0 +1,10 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*             initread.c --                                           */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+/* the sole purpose is to bring in the reader overlay BEFORE the user
+  puts in his data disk */ 
+
+InitRead() {}
\ No newline at end of file
diff --git a/INITWRIT.C b/INITWRIT.C
new file mode 100644 (file)
index 0000000..0809441
--- /dev/null
@@ -0,0 +1,10 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*             initwrite.c --                                          */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+/* the sole purpose is to bring in the writer overlay BEFORE the user
+  puts in his data disk */ 
+
+InitWrite() {}
\ No newline at end of file
diff --git a/INTUALL.H b/INTUALL.H
new file mode 100644 (file)
index 0000000..96882ee
--- /dev/null
+++ b/INTUALL.H
@@ -0,0 +1,34 @@
+#include <exec\types.h>
+#include <exec\nodes.h> 
+#include <exec\lists.h>
+#include <exec\interrupts.h>
+#include <exec\memory.h>
+#include <exec\tasks.h>
+#include <exec\ports.h>
+#include <exec\libraries.h>
+#include <exec\io.h>
+#include <exec\devices.h>
+#include <clib\macros.h>
+#include <devices\timer.h>
+#include <librarie\dos.h>
+#include <graphics\gfx.h>
+#include <hardware\blit.h>
+#include <graphics\copper.h>
+#include <graphics\display.h>
+#include <graphics\gels.h>
+#include <graphics\regions.h>
+#include <graphics\clip.h>
+#include <graphics\rastport.h>
+#include <graphics\view.h>
+#include <graphics\gfxbase.h>
+#include <graphics\text.h>
+#include <graphics\gfxmacros.h>
+#include <graphics\layers.h>
+#include <intuition\intuition.h>
+#include <devices\inputevent.h>
+#include <devices\keymap.h>
+#include <workbench\startup.h>
+
+
+
+
diff --git a/KEYJUNK.C b/KEYJUNK.C
new file mode 100644 (file)
index 0000000..0138391
--- /dev/null
+++ b/KEYJUNK.C
@@ -0,0 +1,109 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*             keyjunk.c                                                       */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include "system.h"
+
+#define local static
+
+SHORT ShiftKey = 0;
+SHORT AltKey = 0;
+SHORT Lshift = 0, Rshift = 0;
+SHORT Ctrl = 0;
+SHORT Caps = 0;
+SHORT LeftAlt = 0;
+SHORT RightAlt = 0;
+SHORT LeftCom = 0;
+SHORT RightCom = 0;
+    
+local char unshChars[] = {
+/*0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f */
+0x60,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x30,0x2d,0x3d,0x5c,0x08,0x00,
+0x71,0x77,0x65,0x72,0x74,0x79,0x75,0x69,0x6f,0x70,0x5b,0x5d,0x0d,0x31,0x32,0x33,
+0x61,0x73,0x64,0x66,0x67,0x68,0x6a,0x6b,0x6c,0x3b,0x27,0x00,0x00,0x34,0x35,0x36,
+0x00,0x7a,0x78,0x63,0x76,0x62,0x6e,0x6d,0x2c,0x2e,0x2f,0x00,0x2e,0x37,0x38,0x39,
+0x20,0x08,0x09,0x0d,0x0d,0x1b,0x7f,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x00,0x00
+};
+       
+local char shftChars[] = {
+0x7e,0x21,0x40,0x23,0x24,0x25,0x5e,0x26,0x2a,0x28,0x29,0x5f,0x2b,0x7c,0x08,0x00,
+0x51,0x57,0x45,0x52,0x54,0x59,0x55,0x49,0x4f,0x50,0x7b,0x7d,0x0d,0x31,0x32,0x33,
+0x41,0x53,0x44,0x46,0x47,0x48,0x4a,0x4b,0x4c,0x3a,0x22,0x00,0x00,0x34,0x35,0x36,
+0x00,0x5a,0x58,0x43,0x56,0x42,0x4e,0x4d,0x3c,0x3e,0x3f,0x00,0x2e,0x37,0x38,0x39,
+0x20,0x08,0x09,0x0d,0x0d,0x1b,0x7f,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x00,0x00
+};
+
+#define NoChar 0xff
+
+
+InitBoard() {}
+
+/****************************************************************/
+/*                                                             */
+/*  MGetCh: equivalent to the old MayGetCh();                  */
+/*     returns(0xff) if no keys have been hit, otherwise       */
+/*   returns the key.                                          */
+/*                                                             */
+/*   Special Keys (non-ascii) are returned as 2 chars:         */
+/*      a null (0) character, followed by a character specific */
+/*     to the key hit. The codes returned following the        */
+/*     null are:                                               */
+/*             Function Key Fn: 0x3a + n                       */
+/*             Cursor Up:      0x50                            */
+/*             Cursor Down:    0x48                            */
+/*             Cursor Right:   0x4d                            */
+/*             Cursor Left:    0x4b                            */
+/*                                                             */
+/****************************************************************/
+SHORT dbgkbd = 0;
+
+local SHORT specChar;
+local SHORT specialKey = FALSE;
+local BYTE cursChar[4] = {0x50,0x48,0x4d,0x4b};
+local Special(c) BYTE c; { specialKey = TRUE; specChar = c; }
+
+#define ESC 0x1b
+
+/* use this for getting second char of 2 char sequence */
+SHORT GetNextCh() {
+    if (specialKey) { specialKey = FALSE; return(specChar); }
+    else return(NoChar);
+    }
+
+SHORT CharFromKeyCode(rcode) UBYTE rcode; {
+    UBYTE code,key;
+    SHORT downStroke;
+/*  if (rcode ==NULL) return(NoChar); */ 
+    if (dbgkbd)  KPrintF(" rcode = %lx \n",rcode); 
+    code = 0x7f&rcode;
+    if ( (code&0x70) == 0x70) return(NoChar);
+    downStroke = ((rcode&0x80)==0);
+    if (code<0x4b) {
+       if (!downStroke) return(NoChar);
+       key = (Caps||(Lshift|Rshift))? shftChars[code]: unshChars[code];
+       return((SHORT)key);
+       }
+    switch (code) {
+       case 0x45: return(ESC); break;
+       case 0x60: Lshift = downStroke; ShiftKey = Lshift|Rshift; return(NoChar); break;
+       case 0x61: Rshift = downStroke; ShiftKey = Lshift|Rshift;return(NoChar); break;
+       case 0x62: Caps = downStroke; return(NoChar); break;
+       case 0x63: Ctrl = downStroke; return(NoChar); break;
+       case 0x64: LeftAlt = downStroke; AltKey = LeftAlt|RightAlt; return(NoChar); break;
+       case 0x65: RightAlt = downStroke; AltKey = LeftAlt|RightAlt;return(NoChar); break;
+       case 0x66: LeftCom = downStroke; return(NoChar); break;
+       case 0x67: RightCom = downStroke; return(NoChar); break;
+       case 0x5f: Special(0x01); return(NULL); break; /*HELP key*/
+       default:
+           if (!downStroke) return(NoChar);
+           if ((0x50<=code)&&(code <= 0x59))  /* function keys */
+               { Special(0x3b + code-0x50); return(NULL); }
+           if ((0x4c<=code)&&(code <= 0x4f))  /* cursor keys */
+               { Special(cursChar[code - 0x4c]); return(NULL); }
+           return(NoChar);
+           break;
+       }
+    }
+
diff --git a/MAGBITS.C b/MAGBITS.C
new file mode 100644 (file)
index 0000000..7407f4e
--- /dev/null
+++ b/MAGBITS.C
@@ -0,0 +1,233 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*     magbits.c  -- Integer Bitmap Magnification  (c)Electronic Arts  */
+/*                                                                     */
+/*                                                                     */
+/*     6/26/85   Created       Dan Silva  -- Electronic Arts           */
+/*     7/13/85   v27 Mods      Dan Silva  -- Electronic Arts           */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+#define method1
+
+#ifdef method1
+/* CLIPPED stretch by integer multiple in X and Y direction --
+    
+    This version does the final y-stretch by "tricking" BltBitMap into 
+    outputting each line N times in one call. It requires H calls to 
+    BltBitMap, wher H is the number of "fat bit" scan lines visible in 
+    the clipping window.   It is thus slow for small magnifications, 
+    but quite fast for high magnifications.  Even at small 
+    magnifications the updates have a much smoother appearance than the 
+    other algorithm. */
+    
+short MagBits(sbm,sbox,dbm,dx,dy,NX,NY,clip)
+    struct BitMap *sbm, *dbm;
+    Box *sbox;
+    int dx,dy; /* upper left corner in dbm */
+    int NX,NY;         /* magnify factor */
+    Box *clip;         /* clip box in destination bm */
+    {
+    SHORT xs,xd,yd,ys,sxmax,i,nout,lx,clymax, depth,bpr,nrep,ydcl;
+    static SHORT dw;
+    static Box c,fr;
+    struct BitMap tmpBM,tmpBM2;
+    depth = dbm->Depth;
+    
+    /* clip in source bitmap to avoid unnecessary work */
+    
+    fr.x = (clip->x - dx)/NX  + sbox->x;
+    fr.y = (clip->y - dy)/NY  + sbox->y;
+    fr.w = (clip->w + NX - 1)/NX;
+    fr.h = (clip->h + NY - 1)/NY;
+    
+    if (!BoxAnd(&c,&fr,sbox)) return(0);
+
+    dx += NX*(c.x - sbox->x);
+    dy += NY*(c.y - sbox->y);
+    dw = c.w*NX;
+
+    if ( (NX==1)&&(NY==1)) 
+      { BltBitMap(sbm,c.x,c.y,dbm,dx,dy,c.w,c.h,REPOP,0xff,NULL); return(0); }
+    
+    tmpBM.Planes[0] = tmpBM2.Planes[0] = 0;
+
+    InitBitMap(&tmpBM,depth,dw,c.h);
+    InitBitMap(&tmpBM2,depth,dw,c.h);
+
+    if (TmpAllocBitMap(&tmpBM)) {
+       GunTheBrush();
+       if (TmpAllocBitMap(&tmpBM));
+       return(FAIL); 
+       }
+    if (TmpAllocBitMap(&tmpBM2)) { 
+       GunTheBrush();
+       if (TmpAllocBitMap(&tmpBM2)) { 
+           FreeBitMap(&tmpBM); 
+           return(FAIL);
+           }
+       }
+    ClearBitMap(&tmpBM); ClearBitMap(&tmpBM2);
+
+    /*--------- stretch horizontally first--------------*/
+    sxmax = c.x + c.w; 
+    xd = 0;
+    for (xs = c.x; xs < sxmax; xs++ ) {
+       BltBitMap(sbm,xs,c.y,&tmpBM,xd,0,1,c.h,REPOP,0xff,NULL);
+       xd += NX;
+       }
+    for (i=0; i<NX; i++) 
+       BltBitMap(&tmpBM,0,0,&tmpBM2,i,0,dw-NX+1,c.h,OROP,0xff,NULL);
+    
+    /*--------- prepare to stretch Vertically--------------*/
+    lx = 0;
+    if ( (nout = clip->x - dx) >0) { lx += nout; dx+=nout; dw -= nout; }
+    if ( (nout = dx+dw - (clip->x+clip->w)) > 0) { dw -= nout; } 
+
+    yd = dy;
+    clymax = clip->y + clip->h;
+
+    /**--------- Stretch vertically into destination Raster Port -----***/
+    /* Mess around with width of tmpBM2 to trick BltBitMap   -----     */
+    /* into outputting the same line many times                        */
+
+    bpr = tmpBM2.BytesPerRow;
+    tmpBM2.BytesPerRow = 0;
+    
+    for (ys = 0; ys < c.h; ys++) {
+       nrep = NY;
+       ydcl = yd;
+       if (ys==0) if (( nout=(clip->y-ydcl))>0) { nrep-= nout; ydcl += nout;}
+       if (ys==c.h-1) if (( nout = ( yd+NY - clymax)) > 0) nrep -= nout;
+       BltBitMap(&tmpBM2,lx,0,dbm,dx,ydcl,dw,nrep, REPOP,0xff,NULL);
+       for (i = 0; i<depth; i++) tmpBM2.Planes[i] += bpr;
+       yd += NY;
+       }
+    
+    /* --------- restore bitmap pointers to original state -----*/
+    for (i=0; i<depth; i++) tmpBM2.Planes[i] -= c.h*bpr;
+    tmpBM2.BytesPerRow = bpr;
+    FreeBitMap(&tmpBM);
+    FreeBitMap(&tmpBM2);
+    return(SUCCESS);
+    }
+
+
+/* CLIPPED stretch by integer multiple in X and Y direction --
+    
+    This version does the final y-stretch by "tricking" BltRaster into 
+    spacing scan lines out by N lines.  Thus it only takes N calls to 
+    BltRaster, and is quite fast, especially for low magnifications. 
+    The resulting updates to the screen have a ragged appearance 
+    however, since the changes occur to every Nth scan line on each 
+    blit.
+
+*/
+
+#else
+
+SHORT dbgmgb = NO;
+
+short MagBits(sbm,sbox,dbm,dx,dy,NX,NY,clip)
+    struct BitMap *sbm, *dbm;
+    Box *sbox;
+    int dx,dy; /* upper left corner in dbm */
+    int NX,NY;         /* magnify factor */
+    Box *clip;         /* clip box in destination bm */
+    {
+    
+    SHORT xs,xd,yd,ys,sxmax,i,nout,lx,clymax, depth;
+    SHORT svbpr,magbpr,magyd,pixper,magpixper,magydcl,shcl,ydbot;
+    static SHORT dw;
+    static Box c,fr;
+    struct BitMap tmpBM,tmpBM2;
+
+
+    depth = dbm->Depth;
+    
+    /* clip in source bitmap to avoid unnecessary work */
+    
+    fr.x = (clip->x - dx)/NX  + sbox->x;
+    fr.y = (clip->y - dy)/NY  + sbox->y;
+    fr.w = (clip->w + NX - 1)/NX;
+    fr.h = (clip->h + NY - 1)/NY;
+    
+    if (!BoxAnd(&c,&fr,sbox)) return(0);
+
+    dx += NX*(c.x - sbox->x);
+    dy += NY*(c.y - sbox->y);
+    dw = c.w*NX;
+
+    if ( (NX==1)&&(NY==1)) { BltBitMap(sbm,c.x,c.y,dbm,dx,dy,c.w,c.h,REPOP,0xff,NULL); return(0); }
+    
+    tmpBM.Planes[0] = tmpBM2.Planes[0] = 0;
+
+    InitBitMap(&tmpBM,depth,dw,c.h);
+    InitBitMap(&tmpBM2,depth,dw,c.h);
+
+    if (TmpAllocBitMap(&tmpBM)) return(-1);
+    if (TmpAllocBitMap(&tmpBM2)) {FreeBitMap(&tmpBM); return(-1);}
+
+    ClearBitMap(&tmpBM); ClearBitMap(&tmpBM2);
+
+    /*--------- stretch horizontally first--------------*/
+    sxmax = c.x + c.w; 
+    xd = 0;
+    for (xs = c.x; xs < sxmax; xs++ ) {
+       BltBitMap(sbm,xs,c.y,&tmpBM,xd,0,1,c.h,REPOP,0xff,NULL);
+       xd += NX;
+       }
+    for (i=0; i<NX; i++) 
+       BltBitMap(&tmpBM,0,0,&tmpBM2,i,0,dw-NX+1,c.h,OROP,0xff,NULL);
+    
+
+    /*--------- prepare to stretch Vertically--------------*/
+    lx = 0;
+    if ( (nout = clip->x - dx) >0) { lx += nout; dx+=nout; dw -= nout; }
+    if ( (nout = dx+dw - (clip->x+clip->w)) > 0) { dw -= nout; } 
+    yd = dy;
+    clymax = clip->y + clip->h;
+
+    /*---- mess around with width of dbm to trick BltBitMap----- */
+
+    svbpr = dbm->BytesPerRow;
+    magbpr = svbpr*NY;
+    dbm->BytesPerRow = magbpr;  /* Make it skip N lines at a time
+           by saying the destination bitmap is NY times as wide
+           as it really is */
+    
+    yd = dy;
+    magyd = (yd>=0) ? yd/NY : yd/NY - 1;
+    pixper = 8*svbpr;
+    magpixper = 8*magbpr;
+    dx +=  pixper*(yd - magyd*NY);
+    ydbot = yd + NY*(c.h-1);
+
+#ifdef asdas
+    if (dbgmgb) printf("NY=%ld,yd=%ld,magyd=%ld,dx=%ld,svbpr=%ld\n",
+       NY,yd,magyd,dx,svbpr);
+#endif
+    
+    /**--------- Stretch vertically into destination Raster Port ***/
+    for (i = 0; i < NY; i++)     {
+       magydcl = magyd;  shcl = c.h; ys = 0;
+       if (yd < clip->y) { magydcl++; shcl--; ys++; }
+       if (ydbot >= clymax) shcl--;  
+       BltBitMap(&tmpBM2,lx,ys,dbm,dx,magydcl, dw,shcl,REPOP,0xff,NULL);
+       dx += pixper;
+       if (dx>magpixper) { dx -= magpixper; ++magyd; }
+       ++yd; 
+       ++ydbot;
+       }
+           
+    dbm->BytesPerRow = svbpr;
+    FreeBitMap(&tmpBM);
+    FreeBitMap(&tmpBM2);
+    return(0);
+    }
+
+#endif
+
diff --git a/MAGOPS.C b/MAGOPS.C
new file mode 100644 (file)
index 0000000..2159997
--- /dev/null
+++ b/MAGOPS.C
@@ -0,0 +1,140 @@
+/*----------------------------------------------------------------------*/
+/*                                                                     */
+/*        magops.c -- this is essentially an extension to cgraph       */
+/*  which implements the graphics ops in magnified windows.            */
+/*                                                                     */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+
+#define local static
+
+extern SHORT curxpc;
+extern BMOB *curob;
+extern Box bigBox;
+extern struct RastPort *curRP;
+extern BOOL usePen;
+extern void (*CurPWritePix)();
+extern SHORT xorg,yorg,magN;
+extern BOOL firstDown;
+extern SHORT clipMaxX;
+
+Box bx;
+
+mReadPix(x,y) SHORT x,y; { return(PReadPix(x+xorg,y+yorg)); }
+
+/*------------ Paint current object------------*/
+
+dispob(x,y) SHORT x,y; { DispBMOB(curob,x,y); }
+
+ProcHandle SplatOp() {
+    return((usePen==0)? CurPWritePix: &dispob);
+    }
+
+UpdtPtBox(x,y) SHORT x,y; {  UpdtSibs(MakeBox(&bx,x,y,1,1));   }
+
+mDispOB(x,y) SHORT x,y; {
+    (*SplatOp())(x+xorg,y+yorg);
+    UpdtPtBox(x,y);
+    }
+
+mDrawDot(x,y) {  (*CurPWritePix)(x+xorg,y+yorg); UpdtPtBox(x,y); }
+
+mMoveOB(x,y)  SHORT x,y; {
+    SHORT oldx,oldy;
+    oldx = curob->pict.box.x - xorg + curob->xoffs;
+    oldy = curob->pict.box.y - yorg + curob->yoffs;
+    MoveBMOB(curob, x+xorg, y+yorg); /*go to screen directly*/
+    UpdtSibs(BoxTwoPts(&bx,x,y,oldx,oldy)); 
+    }
+
+mClearOB() {
+    SHORT oldx,oldy;
+    oldx = curob->pict.box.x - xorg + curob->xoffs;
+    oldy = curob->pict.box.y - yorg + curob->yoffs;
+    ClearBMOB(curob);
+    UpdtPtBox(oldx,oldy);
+    }
+
+/*---------------magnified Line ------------*/
+mLine(x1,y1,x2,y2) SHORT x1,y1,x2,y2; {
+    firstDown = YES;
+    if (usePen==0) PLine(x1+xorg, y1+yorg, x2+xorg, y2+yorg);
+    else PLineWith(x1+xorg,y1+yorg, x2+xorg, y2 +yorg, SplatOp());
+    UpdtSibs(BoxTwoPts(&bx,x1,y1,x2,y2));
+    }
+       
+/* --------------magnified Rectangle -----------*/
+mRect(b) Box *b; {
+    PFillBox(MakeBox(&bx,b->x+xorg, b->y+yorg,b->w,b->h));
+    UpdtSibs(b);
+    }
+
+/*---------------magnified Curve ------------*/
+mCurve(x0,y0,x1,y1,x2,y2) SHORT x0,y0,x1,y1,x2,y2; {
+    firstDown = YES;
+    PCurve(x0+xorg,y0+yorg,x1+xorg,y1+yorg,x2+xorg,y2+yorg,64,SplatOp());
+    UpdtSibs(BoxThreePts(&bx,x0,y0,x1,y1,x2,y2));
+    }
+    
+local OvalUpdt(x,y,a,b) SHORT x,y,a,b; {
+    UpdtSibs(MakeBox(&bx,x-a,y-b,2*a+4,2*b+4));
+    }
+
+/*---------------magnified Circle ------------*/
+mCircle(x,y,rad) SHORT x,y,rad; { 
+    firstDown = YES;
+    PCircWith(x + xorg, y + yorg, rad, SplatOp()); 
+    OvalUpdt(x,y,rad,rad);
+    }
+
+mFillCircle(x,y,rad) SHORT x,y,rad; {
+    PFillCirc(x + xorg, y + yorg ,rad);
+    OvalUpdt(x,y,rad,rad);
+    }
+
+iabs(x) int x; { return( (x>0)? x: -x ); }
+
+/*---------------magnified Ellipse ------------*/
+mOval(x1,y1,x2,y2) SHORT x1,y1,x2,y2; {
+    SHORT halfw,halfh;
+    firstDown = YES;
+    halfw = iabs(x2-x1); halfh = iabs(y2-y1);
+    PEllpsWith(x1 +xorg, y1 + yorg, halfw, halfh, SplatOp());
+    OvalUpdt(x1,y1,halfw,halfh);
+    }
+
+mFillOval(x1,y1,x2,y2) SHORT x1,y1,x2,y2; {
+    SHORT halfw,halfh;
+    halfw = iabs(x2-x1); halfh = iabs(y2-y1);
+    PFillEllps(x1 +xorg, y1 + yorg, halfw, halfh);
+    OvalUpdt(x1,y1,halfw,halfh); 
+    }
+
+/*---------------Magnified Area Flood ------------*/
+mFillArea(Bndry,x,y) BOOL Bndry;SHORT x,y; {
+    UpdtON();
+    if (Bndry) PFloodBndry(x+xorg,y+yorg); else  PFloodArea(x+xorg,y+yorg);
+    UpdtSibs(&bigBox);
+    UpdtOFF();
+    }
+
+/* Frame rectangle with border of thickness 1 */
+mFrame(b) Box *b; {
+    firstDown = YES;
+    MakeBox(&bx,b->x + xorg,b->y + yorg,b->w,b->h);    
+    PThinFrame(&bx);
+    UpdtSibs(b);
+    } 
+
+/* Frame rectangle with border using current brush */
+mOBFrame(b) Box *b; {
+    SHORT xm = b->x + b->w -1;
+    SHORT ym = b->y + b->h -1;
+    mLine(b->x, b->y, xm, b->y);
+    mLine(xm, b->y, xm, ym);
+    mLine(xm, ym, b->x, ym);
+    mLine(b->x,ym, b->x, b->y);
+    } 
+
diff --git a/MAGWIN.C b/MAGWIN.C
new file mode 100644 (file)
index 0000000..ba10f63
--- /dev/null
+++ b/MAGWIN.C
@@ -0,0 +1,215 @@
+/*----------------------------------------------------------------------*/
+/*        magwin.c -- implements a magnify window object               */
+/*----------------------------------------------------------------------*/
+#include <system.h>
+#include <prism.h>
+
+extern Pane mainP;
+extern SHORT curpen,curxpc;
+extern BMOB *curob;
+extern struct BitMap hidbm;
+extern Box bigBox;
+extern SHORT xShft,yShft;
+extern SHORT xcen,ycen;
+extern void PWritePix();
+extern Box screenBox;
+extern struct RastPort *mainRP,*curRP,tempRP;
+extern Box clipBox,bigBox;
+extern SHORT  curIMFlags;
+extern SHORT usePen;
+
+#define local static;
+
+SHORT xorg=0, yorg=0;
+/* This Boolean tells whether we are actually painting or just showing 
+feedback while the user adjusts the graphic */
+BOOL Painting =NO;
+
+
+SHORT curWin = MAINWIN; /* = MAGWIN or MAINWIN */
+
+short magN = 1;
+    
+/*----------------------------------------------------------------------*/
+/*----------------------------------------------------------------------
+All coordinates passed to the routines mLine, etc are backing bitmap 
+relative (bbmX, bbmY). To get view relative coordinates
+ srcX = bbmX - srcPos.x;
+ srcY = bbmY - srcPos.y;
+
+To get screen coordinates:
+  screenX = bbmX + xorg;
+  screenY = bbmY + yorg;
+
+Where
+    xorg = srcBox.x - srcPos.x;
+    yorg = srcBox.y - srcPos.y;
+
+The backing bitmap is not necessary: it is used for implementing
+scrolling and undo in the main painting window.  In the case of using 
+the magnifier to edit a tile pattern, the updtBackBM() call could 
+display an array of NxM tiles.
+----------------------------------------------------------------------*/
+
+#ifdef floofloo
+/*----------------------------------------------------------------------*/
+/*   magnify Context                                                   */
+/*----------------------------------------------------------------------*/
+typedef struct {
+SHORT magN;            /* magnification factor                 */
+struct RastPort *srcRP;        /* The source RasterPort                */                              
+Box  *srcBox;          /* The clip box of source in its Raster */      
+Point srcPos;          /* The position of the view box relative*/
+                       /* to the backing bitmap                */
+struct BitMap *magBM;  /* The magnify BitMap                   */
+Box *magBox;           /* Clip Box of magnify view in magBM.   */
+Point magPos;          /* The position of magnify view rel     */
+                       /* to backing bitmap                    */
+void (*updtProc)();   /* Procedure to call to update the       */
+                       /* backing bitmap. (takes *Box as       */
+                       /* parameter, BBM relative);            */
+} MagContext;
+/*----------------------------------------------------------------------*/
+#endif 
+
+BOOL magShowing = NO;
+MagContext *mgc = NULL;
+
+MagErr(s) char *s; { KPrintF(" Null magcontext  in %s \n",s); }
+
+UpdtCach() {
+    if (mgc == NULL) MagErr("UpdtCache");
+    FixUsePen();
+    xorg = mgc->srcBox->x - mgc->srcPos.x;
+    yorg = mgc->srcBox->y - mgc->srcPos.y;
+    PopGrDest();
+    PushGrDest(mgc->srcRP,mgc->srcBox);
+    }
+
+    
+UpdtOFF() { Painting = NO;  UpdtCach(); }
+UpdtON() { Painting = YES;  UpdtCach(); }
+
+static void noop(){}
+ProcHandle curUpdt = &noop;
+
+/*----------------------------------------------------------------------*/
+/* Plug in a new Magnify context                                       */
+/*----------------------------------------------------------------------*/
+void SetMagContext(magc) MagContext *magc; {
+    mgc  = magc;
+    magN = mgc->magN;
+    curUpdt = magc->updtProc;
+    if (curUpdt==NULL) curUpdt = &noop;
+    UpdtOFF();
+    }
+
+SetMag(nmag) SHORT nmag; {
+    mgc->magN = magN = nmag;
+    }
+    
+MagState(onoff) BOOL onoff; { 
+    if (mgc == NULL) MagErr("Magstate");
+    magShowing = onoff; 
+    }
+    
+UnMag(z) SHORT z; { return (( z + magN - 1)/magN); }
+    
+/*----------- Box "b" is in Backing Bitmap coords ---------------------*/
+
+void MagUpdate(b) Box *b; {
+    Box sbox; 
+    SHORT dx,dy,pix;
+    if (!magShowing) return;
+    sbox.x = b->x + xorg;      sbox.y = b->y + yorg;
+    sbox.w = b->w;             sbox.h = b->h;
+    dx = (b->x - mgc->magPos.x) * magN + mgc->magBox->x;
+    dy = (b->y - mgc->magPos.y) * magN + mgc->magBox->y;
+       
+/* this does give a fair speedup, and costs about 240 Bytes */
+
+    if ((sbox.w == 1) && (sbox.h==1)) { /* special speedup for dots */
+       pix = ReadPixel(mgc->srcRP, sbox.x,sbox.y);
+       tempRP.BitMap = mgc->magBM;
+       SetAPen(&tempRP,pix);
+       PushGrDest(&tempRP, mgc->magBox);
+       PFillBox(MakeBox(&sbox,dx,dy,magN,magN));
+       PopGrDest();
+       return;
+       }
+       
+    MagBits(
+       mgc->srcRP->BitMap,     /* source bitmap */
+       &sbox,          /* box on screen in unMagnified source window*/
+       mgc->magBM,     /* bitmap containing mag window         */
+       dx,             /* position of the magnified version of */
+       dy,             /* sbox in mag bitmap  */
+       magN,magN,      /* amount of magnification */
+       mgc->magBox     /* clipping box of the Mag window */
+       );
+    }
+
+/*------- b is in Physical coords, in the screen bitmap----*/
+UpdtSibs(b) Box *b; {
+    Box updtBox;
+    updtBox = *b;
+    if ((usePen!=0)&& ((curIMFlags&NOBR)==0)) { 
+       updtBox.x -= curob->xoffs;
+       updtBox.y -= curob->yoffs;
+       updtBox.w += curob->pict.box.w-1;
+       updtBox.h += curob->pict.box.h-1;
+       }
+    if (magShowing) MagUpdate(&updtBox);
+    (*curUpdt)(&updtBox);
+    }
+
+/* clip a point to the CurrentBBM box */
+SHORT limit(a,l,u,d) SHORT a,l,u,d; {  if (a<l) a+=d; if (a>u) a-=d; 
+       return(a); }
+
+/* not yet implemented
+MWClipPt(x,y,dx,dy) SHORT *x,*y,dx,dy; { 
+    Box *bx = &screenBox;
+    *x = limit(*x,0,bx->w-1,dx);
+    *y = limit(*y,0,bx->h-1,dy);
+    }
+*/
+
+SetCurWin(pn) Pane *pn; { curWin = pn->client;   }
+
+/* convert window rel coords to bbm-rel magnified coords */        
+MagCoords(x,y) SHORT *x,*y; { 
+    if (curWin == MAGWIN) {
+       *x = mgc->magPos.x + (*x)/magN;
+       *y = mgc->magPos.y + (*y)/magN;
+       }
+    else { *x += mgc->srcPos.x; *y += mgc->srcPos.y; }
+    }
+
+#define BIG 4000
+magRect(b) Box *b; {
+    Box c,d;
+    c.x = (b->x - mgc->magPos.x) * magN + mgc->magBox->x;
+    c.y = (b->y - mgc->magPos.y) * magN + mgc->magBox->y;
+    c.w = magN * b->w;
+    c.h = magN * b->h;
+    BoxAnd(&d,mgc->magBox,&c);
+    c = clipBox;
+    SetClipBox(&bigBox);
+    PFillBox(&d);
+    SetClipBox(&c);
+    }
+    
+minvXHair(x,y) SHORT x,y; {
+    Box bx;
+    WaitTOF();
+    if (curWin == MAINWIN) PInvertXHair(x + xorg, y + yorg);
+    else {
+       TempXOR();
+       magRect(MakeBox(&bx,0,y,screenBox.w,1));
+       magRect(MakeBox(&bx,x,0,1,screenBox.h));
+       RestoreMode();
+       }
+    }
+       
+
diff --git a/MAINMAG.C b/MAINMAG.C
new file mode 100644 (file)
index 0000000..e6fa58b
--- /dev/null
+++ b/MAINMAG.C
@@ -0,0 +1,450 @@
+/*----------------------------------------------------------------------*/
+/*   Main magnify window                                               */
+/*----------------------------------------------------------------------*/
+
+#include <system.h>
+#include <prism.h>
+#include <pnts.h>
+
+extern PointRec pnts; /* contains mx,my,sx,sy, etc */
+
+extern void (*thisMode)(), (*nop)(), (*killMode)();
+extern struct Window *mainW;
+extern Box bigBox,screenBox;
+extern struct RastPort tempRP, *mainRP, tempRP, *curRP,screenRP;
+extern struct BitMap hidbm;
+extern Pane mainP;
+extern SHORT xorg,yorg,curMBarH,curxpc;
+extern void mainCproc(), mainMproc();
+extern Box mainBox;
+extern SHORT xShft;
+extern SHORT checkpat[];
+extern struct Screen *screen;
+extern BOOL wasCtrl;
+extern BOOL Painting;    
+extern PaintMode paintMode;
+    
+BOOL isUndoOn = NO;
+UndoOn() { isUndoOn = YES; }
+UndoOff() { isUndoOn = NO; }
+
+MagContext magCntxt = {0};
+Pane magP = {0};
+BOOL magOn = NO;
+BOOL updatePending; /* have changed the screen but not copied to hidbm yet */
+Box chgB = {0};
+Box tmpChgBox = {0};
+
+SHORT didClearCol;
+
+/* clips a change box against the non-magnified window */
+/* this is done in backing bitmap coords */
+ClipChgBox(clip,chgbx) {
+    Box b; 
+    b.x = magCntxt.srcPos.x; b.y = magCntxt.srcPos.y;
+    b.w = magCntxt.srcBox->w; b.h = magCntxt.srcBox->h;
+    return(BoxAnd(clip,chgbx,&b));
+    }
+
+/* records changes so UndoSave knows how big a rectangle to save */
+
+void RecChange(b) Box *b; {
+    EncloseBox(Painting ? & chgB: &tmpChgBox,b);
+    updatePending = YES;
+    }
+
+void RecTempChg(b) Box *b; { EncloseBox(&tmpChgBox,b);  }
+
+CopyBack(b,op) Box *b; SHORT op; {
+    tempRP.BitMap = &hidbm;
+    ClipBlit(mainRP, b->x +xorg, b->y + yorg,
+       &tempRP, b->x, b->y, b->w, b->h, op);
+    } 
+
+CopyFwd(b,op) Box *b; SHORT op; {
+    tempRP.BitMap = &hidbm;
+    ClipBlit( &tempRP, b->x, b->y,
+               mainRP,b->x +xorg, b->y + yorg, b->w, b->h, op); 
+    } 
+
+/* make previous change permanent */
+SHORT didType = DIDNothing;
+    
+#ifdef hobaaaho
+UndoSave() { 
+    Box cb;
+    if (didClear) {
+       tempRP.BitMap = &hidbm; SetRast(&tempRP,didClearCol);
+       didClear = NO;
+       }
+    else if (didMerge)  MrgSpareUpdt();
+    if (ClipChgBox(&cb,&chgB)) CopyBack(&cb,REPOP); chgB.w = 0; 
+    }
+#endif
+
+/* this should be called "MakeChangePermanent" */
+/* it copies changed area from the screen to the hidbm */
+UndoSave() { 
+    Box cb;
+    ClearFB();
+    switch(didType) {
+       case DIDClear:
+           tempRP.BitMap = &hidbm; SetRast(&tempRP,didClearCol);
+           break;
+       case DIDMerge:   MrgSpareUpdt(); break;
+       }
+    if (ClipChgBox(&cb,&chgB)) CopyBack(&cb,REPOP); chgB.w = 0; 
+    didType = DIDNothing;
+    updatePending = NO;
+    }
+
+/* swap hidden bitmap and screen in chgB */
+SwapHidScr() {
+    Box cb;
+    if (ClipChgBox(&cb,&chgB)) {
+       CopyFwd(&cb,XOROP); 
+       CopyBack(&cb,XOROP); 
+       CopyFwd(&cb,XOROP);
+       MagUpdate(&chgB);
+       }
+    }
+
+Undo() { 
+    switch(didType) {
+       case DIDClear: case DIDMerge:  UpdtDisplay(); didType = DIDNothing; break;
+       case DIDHPoly: SwapHidScr();  UndoHPoly(); didType = DIDNothing; break;
+       case DIDNothing: SwapHidScr();   break;
+       }
+    }
+
+/* this is called when operations are aborted in midstream */
+UnDisplay() { UpdtDisplay(); UndoSave(); }
+
+EraseBox(b) Box *b; {
+    Box clb;
+    if (ClipChgBox(&clb,b)) { CopyFwd(&clb,REPOP); MagUpdate(&clb);}
+    }
+    
+/* this erases feedback from the screen */
+EraseTempChg() {
+    if (wasCtrl) { EncloseBox(&chgB, &tmpChgBox);
+       CycPaint();     /* A cheap effect... */    
+       }
+    else EraseBox(&tmpChgBox); 
+    tmpChgBox.w = 0;
+    }
+
+/**-------------------------- **/
+
+#define BIG 1000;
+
+
+void magPaint() {
+    Box sbx; 
+    if (magOn) {
+       sbx.x = magCntxt.magPos.x;
+       sbx.y = magCntxt.magPos.y;
+       sbx.w = sbx.h = BIG;
+       MagBits(&hidbm, &sbx, mainRP->BitMap,magP.box.x, magP.box.y,
+           magCntxt.magN, magCntxt.magN, &magP.box);
+       }
+    }
+
+mClearToBg()  {
+    UndoSave();
+    TempErase();
+    PFillBox(&screenBox);
+    ClearErase();
+    didType = DIDClear;
+    didClearCol = curxpc;
+    MagUpdate(&screenBox);
+    }
+
+#define DivWidth 6
+PaintDivider() {
+    Box dbox;
+    if (magOn) {
+       dbox.x = mainBox.w/3;
+       dbox.y = mainBox.y;
+       dbox.w = DivWidth;
+       dbox.h = mainBox.h;
+       
+       PushGrDest(&screenRP,&screenBox);
+       PPatternBox(&dbox, checkpat, 1, 0, 0);
+       PopGrDest();
+       }
+    }
+
+
+void magRefresh() {  magPaint();  PaintDivider();  }
+
+void mainRefresh() {
+    tempRP.BitMap = &hidbm;
+    ClipBlit(&tempRP,magCntxt.srcPos.x,magCntxt.srcPos.y,
+       mainRP, mainP.box.x, mainP.box.y, mainP.box.w, mainP.box.h, REPOP);
+    }
+
+UpdtDisplay() {ClearFB(); mainRefresh(); magPaint(); }
+
+
+#ifdef THEIRWAY /*---------------------------------*/
+MoveWinTo(win,x,y) struct Window *win; int x,y; {
+    MoveWindow(win, x - win->LeftEdge, y - win->TopEdge);
+    }
+
+SizeWinTo(win,w,h) struct Window *win; int w,h; {
+    SizeWindow(win, w - win->Width, h - win->Height);
+    }
+    
+SizeAndMove(win,b) struct Window *win; Box *b; {
+    if (win->Height != b->h) {
+       if (b->h > win->Height) { /* getting higher: move first */
+           MoveWinTo(win, win->LeftEdge, b->y);
+           SizeWinTo(win, win->Height, b->h);
+           }
+       else {
+           SizeWinTo(win, win->Height, b->h);
+           MoveWinTo(win, win->LeftEdge, b->y);
+           }
+       }
+    if (win->Width != b->w) 
+       {
+       if (b->w > win->Width) { /* getting wider:move first */
+           MoveWinTo(win, b->x, win->TopEdge);
+           SizeWinTo(win, b->w, win->Height);
+           }
+       else {
+           SizeWinTo(win, b->w, win->Height);
+           MoveWinTo(win, b->x, win->TopEdge);
+           }
+       }
+    }
+
+#endif /* ------------------------------------------ */
+
+ResizeWins() {
+    SHORT magx;
+    Box mbox;
+    mbox = mainBox;
+    mbox.w = (magOn)? mainBox.w/3: mainBox.w; 
+
+#ifdef THEIRWAY
+    SizeAndMove(mainW,&mbox);
+    KPrintF(" After SizeAndMOve mainW = %ld, %ld, %ld, %ld\n",
+           mainW->LeftEdge,mainW->TopEdge,mainW->Width, mainW->Height);
+#endif
+
+    PaneSize(&mainP, mainBox.x, mainBox.y, mbox.w, mainBox.h);
+    magx = mbox.w + DivWidth;
+    PaneSize(&magP, magx, mainBox.y, mainBox.w - magx, mainBox.h);
+    }
+       
+MagCnst(b,p) Box *b; Point *p; {
+    Box c;
+    c.x = p->x;    c.y = p->y;
+    c.w = b->w;    c.h = b->h;
+    BoxBeInside(&c,&screenBox);
+    p->x = c.x;    p->y = c.y;
+    b->w = c.w;    b->h = c.h;
+    }
+    
+/* make sure that the magnified portion of the bitmap is visible in
+   the main window */
+
+BOOL FixMag() {
+    SHORT nout;
+    Box mf;
+    BOOL srcChg = NO;
+    /* first make sure mag and src  views are inside the hidbm*/
+    MagCnst(magCntxt.srcBox,&magCntxt.srcPos);
+    if (magOn) {
+       mf.x = magCntxt.magPos.x;
+       mf.y = magCntxt.magPos.y;
+       mf.w = UnMag(magCntxt.magBox->w);
+       mf.h = UnMag(magCntxt.magBox->h);
+
+       BoxBeInside(&mf,&screenBox);
+       magCntxt.magPos.x = mf.x;
+       magCntxt.magPos.y = mf.y;
+
+       if (magCntxt.magPos.x < magCntxt.srcPos.x)
+           { srcChg = YES; magCntxt.srcPos.x = magCntxt.magPos.x; }
+       
+       if (magCntxt.magPos.y < magCntxt.srcPos.y)
+           { srcChg = YES; magCntxt.srcPos.y = magCntxt.magPos.y; }
+    
+       nout = (mf.x + mf.w) - (magCntxt.srcPos.x + magCntxt.srcBox->w); 
+       if (nout>0) { srcChg = YES; magCntxt.srcPos.x += nout; }
+    
+       nout = (mf.y + mf.h) - (magCntxt.srcPos.y + magCntxt.srcBox->h); 
+       if (nout>0) { srcChg = YES; magCntxt.srcPos.y += nout; }
+
+       }
+    UpdtCach();
+    return(srcChg);
+    }
+
+FixMagAndPaint(p) Pane *p; {
+    BOOL srcChg = FixMag();
+    if (p == &magP) { magPaint(); if (srcChg) mainRefresh(); }
+    else mainRefresh();
+    }
+
+Point svSrcPos;
+    
+CenterPoint(x,y) SHORT x,y; {
+    UndoSave();
+    /*------- center mag box at x,y----*/
+    magCntxt.magPos.x = x - ( UnMag(magP.box.w) >> 1);
+    magCntxt.magPos.y = y - ( UnMag(magP.box.h) >> 1);
+
+    /* -- and try to center main box at x,y--- */
+    magCntxt.srcPos.x = x - magCntxt.srcBox->w/2;
+    magCntxt.srcPos.y = y - magCntxt.srcBox->h/2;
+    
+    MagState(YES);
+    FixMag();
+    
+    UpdtDisplay();
+    }
+
+ShowMag(x,y) SHORT x,y; {
+    if (!magOn) {
+       UndoSave();
+       svSrcPos = magCntxt.srcPos;
+       magOn = YES;
+       ResizeWins();
+       PaneInstall(&magP);
+       PaintDivider();
+       }
+    CenterPoint(x,y);
+    }
+    
+void RemoveMag() {
+    if (!magOn) return;
+    UndoSave();
+    magOn = NO;
+    PaneRemove(&magP);
+    ResizeWins();
+    MagState(NO);
+    magCntxt.srcPos = svSrcPos;
+    FixMag();
+    PaneRefresh(&bigBox);
+    UpdtCach();
+    }
+
+ToggleMag() {if (magOn) RemoveMag(); else ShowMag(mx,my); } 
+
+BOOL titleShowing = YES;
+static BOOL titleWasUp = YES;
+BOOL skipRefresh = NO;
+RepaintEverything() {
+    ResizeWins();
+    FixMag();
+    PaneRefresh(&bigBox);
+    skipRefresh = YES;
+    UpdtCach();
+    DispPntMode();
+/*    DispDPaint(); */
+    }
+
+FixTitle() {
+    ShowTitle(screen,titleShowing);
+    if (titleShowing) {
+       mainBox.y = curMBarH; 
+       mainBox.h = screenBox.h - curMBarH; 
+       magCntxt.srcPos.y += curMBarH;
+       }
+    else { 
+       mainBox.y = 0; 
+       mainBox.h = screenBox.h; 
+       magCntxt.srcPos.y -= curMBarH;
+       }
+    }
+    
+TogTitle() {
+    titleWasUp = titleShowing = !titleShowing;
+    UndoSave();
+    FixTitle();
+    RepaintEverything();
+    }
+
+extern SHORT cpWidth;
+extern BOOL cpShowing;
+TogBoth() {
+    cpShowing = !cpShowing;
+    UndoSave();
+    if (cpShowing) { 
+       titleShowing = titleWasUp; 
+       mainBox.w -= cpWidth; 
+       InstCP();
+       }
+    else { 
+       titleWasUp = titleShowing;
+       titleShowing = NO;
+       RmvCP(); 
+       mainBox.w += cpWidth; 
+       }
+    FixTitle();
+    RepaintEverything();
+    }
+    
+/* scroll window: dx and dy are the amount the contents of the window
+will slide to the right and down respectively */
+MWScroll(p,dx,dy) Pane *p; SHORT dx,dy; {
+    UndoSave();
+    if (p == &mainP ) {
+       magCntxt.srcPos.x -= dx;
+       magCntxt.srcPos.y -= dy;
+       }
+    else if ( p == &magP) {
+       magCntxt.magPos.x -=dx;
+       magCntxt.magPos.y -=dy;
+       }
+    FixMagAndPaint(p);
+    }
+
+/* Zoom window:  */
+void MWZoom(dmag)   SHORT dmag; 
+    {
+    SHORT x,y;
+    SHORT newmag = magCntxt.magN + dmag;
+    newmag = MAX(2,newmag);
+    if (newmag>24) return;
+    UndoSave();
+    x = magCntxt.magPos.x + UnMag(magCntxt.magBox->w)/2;
+    y = magCntxt.magPos.y + UnMag(magCntxt.magBox->h)/2;
+    SetMag(newmag);
+    magCntxt.magPos.x = x - UnMag(magCntxt.magBox->w)/2;
+    magCntxt.magPos.y = y - UnMag(magCntxt.magBox->h)/2;
+    FixMag();
+    UpdtDisplay();
+    }
+
+
+/**-----(From Menu) Specify Magnify Window Position */
+
+static SHORT mgw,mgh;
+
+domag() { UpdtOFF();  ShowMag(mx,my); }
+
+void killMag() { CPInvAct(magAct); }
+xmagbox() { 
+    Box bx;
+    TempXOR(); 
+    mFrame(MakeBox(&bx,mx-mgw/2,my-mgh/2,mgw,mgh));
+    RestoreMode(); 
+    }
+
+void IMMagSpec() {
+    mgw = UnMag(2*mainBox.w/3);
+    mgh = UnMag(mainBox.h);
+    killMode = killMag;
+    IModeProcs(&xmagbox,nop,&xmagbox,nop,&xmagbox,nop,&xmagbox,&domag);
+    }
+    
+ToglMagw(){ 
+    CPInvAct(magAct);
+    if (magOn) RemoveMag(); else NewIMode(IM_magSpec);
+    }
+
diff --git a/MAKEICON.C b/MAKEICON.C
new file mode 100644 (file)
index 0000000..22e1e1b
--- /dev/null
@@ -0,0 +1,236 @@
+/****************************************************************************/
+/*                                                                          */
+/*  FILENAME: makeicon.c                                                     */
+/*                                                                          */
+/*  FUNCTION: Project Icon Routines