/* SMEAR2.c    (P) Public Domain
 * 28-Jan-1989
 * Joe Porkka
 * jap@syssun.cl.msu.edu
*/

/* This is a little WorkBench hack I came up with.
 * enjoy.
 * Compiles with Lattice 3.10
 * For help, type 'smear2 help'
*/

#include <stdlib.h>
#include <intuition/intuition.h>

long GfxBase=0,IntuitionBase=0;

struct NewWindow nw={
    0,0,1,1,1,1,0,SIMPLE_REFRESH,0,0,"",0,0,1,1,1,1,WBENCHSCREEN};
struct Window *win,*OpenWindow();

struct NewScreen ns={
    0,0,640,-1,2,
    -1,-1,
    HIRES,
    CUSTOMSCREEN|SCREENBEHIND|SCREENQUIET,
    0,
    0,
    0,
    0
};

struct Screen *scr,*OpenScreen();
struct RastPort *myrp,*wrp;
struct BitMap *mybits,*wbits;
int minterm,delay,multiminterm,nodiag;

#define NTERMS 6
int terms[NTERMS]={0x22,0xcc,0x33,0x88,0x44,0xee};

/* This is to remove the program
 * it works even if the program aborts before finishing setup stuff.
*/
vanish(){
    if(win) CloseWindow(win);
    if(scr) CloseScreen(scr);
    if(GfxBase)CloseLibrary(GfxBase);
    if(IntuitionBase)CloseLibrary(IntuitionBase);
    exit(1);
}

main(ac,av) int ac; char **av; {

    int len,a,b,err=0;

    win=0;scr=0;GfxBase=IntuitionBase=0;
    a=1;ac--;
    delay=0;
    minterm=0x00;
    multiminterm=0;
    nodiag=0;
/* Im sure this arg parsing could be done better, but I just hacked it
 * out in five minutes
*/
    while(ac>0) {
        if(stricmp(av[a],"?")==0) {
            printf("%s HELP,MINTERM,DELAY,NODIAG/S\n",av[0]);
            exit(0);
        }
        if(stricmp(av[a],"HELP")==0) {
            printf("\tHELP          Gets help\n");
            printf("\t   with no args, the program picks randomly which minterm\n\t to use for each block move\n");
            printf("\tMINTERM xx    specify a minterm to use (Hexidecimal)\n");
            printf("\t              Try using `cc' for the minterm\n");
            printf("\tDELAY nn      slow down the operations; large nn is slow\n");
            printf("\tNODIAG        prevents diagonal block movements\n");
            printf("\t CTRL-C to exit\n");
            printf("\n");
            exit(0);
        }
        if(stricmp(av[a],"MINTERM")==0) {
            a++;ac--;
            if(ac && minterm==0) {
                sscanf(av[a],"%x",&minterm);
                if(minterm<=0 || minterm>255) {
                    err=1;
                    break;
                }
            } else {
                err=1;
                break;
            }
        } else if(stricmp(av[a],"DELAY")==0) {
            a++;ac--;
            if(ac && delay==0) {
                sscanf(av[a],"%d",&delay);
                if(delay<=0)  {
                    err=1;
                    break;
                }
            } else {
                err=1;
                break;
            }
        } else if(stricmp(av[a],"NODIAG")==0) {
            nodiag=1;
        } else if(minterm==0) {
            sscanf(av[a],"%x",&minterm);
            if(minterm<=0 || minterm>255) {
                err=1;
                break;
            }
        } else if(delay==0) {
            sscanf(av[a],"%d",&delay);
            if(delay<=0)  {
                err=1;
                break;
            }
        } else {err=1;break;}
        a++;ac--;
    }
    if(err) {
        printf("Bad args. Use `%s ?' for help\n",av[0]);
        exit(15);
    }
    if(delay<0) delay=0;
    if(minterm==0) multiminterm=1;
    printf("Minterm=0x%X  delay=%d \n",minterm,delay);

    printf("Smear 2.0 January 89 by  Joe Porkka (PUBLIC DOMAIN)\n");

    onbreak(vanish);
    IntuitionBase=OpenLibrary("intuition.library",30);
    if(IntuitionBase==0) {
        printf("No intuition!\n");
        exit(15);
    }
    GfxBase=OpenLibrary("graphics.library",30);
    if(GfxBase==0) {
        printf("No graphics system.\n");
        CloseLibrary(IntuitionBase);
        exit(15);
    }
    win=OpenWindow(&nw);
    scr=OpenScreen(&ns);
    if (scr==0||win==0) {
        printf("Out Of MEMORY!.\n");
        vanish();
    }
    myrp=&scr->RastPort;
    wrp=win->RPort;
    mybits=myrp->BitMap;
    wbits=wrp->BitMap;

    CloseWindow(win);
    win=0;
    len=640*200/8/4; /* size of a bitplane in longwords */
    BltBitMap(wbits,0,0,mybits,0,0,640,200,0xC0,3,0);
/*
    copyit(wbits->Planes[0],mybits->Planes[0],len);
    copyit(wbits->Planes[1],mybits->Planes[1],len);
 */
    ScreenToFront(scr);
    smear();
    vanish();
}

smear() {
    int d,x,y,lx,ly;
    int q,w,dirs;
    char *a;

    a=malloc(100);

    if(nodiag) dirs=4; else dirs=8;
    do {
        if(delay) Delay(delay);
        d=rand()%dirs;
        x=rand()%639;
        y=rand()%199;
        q=639-x;w=199-y;
        if(q>200) q=200;
        if(w>100) w=100;
        lx=rand()%q;
        ly=rand()%w;

        if(lx==0 || ly==0) continue;
        if(multiminterm) {
            minterm=terms[rand()%NTERMS];
        }
        switch(d) {
            case 0: /* left one bit */
                BltBitMap(mybits,x+1,y,mybits,x,y,lx,ly,minterm,3,a);
                break;
            case 1: /* right one bit */
                BltBitMap(mybits,x,y,mybits,x+1,y,lx,ly,minterm,3,a);
                break;
            case 2: /* up one bit */
                BltBitMap(mybits,x,y+1,mybits,x,y,lx,ly,minterm,3,a);
                break;
            case 3: /* down one bit */
                BltBitMap(mybits,x,y,mybits,x,y+1,lx,ly,minterm,3,a);
                break;

            case 4: /* left,up one bit */
                BltBitMap(mybits,x+1,y+1,mybits,x,y,lx,ly,minterm,3,a);
                break;
            case 5: /* right,down one bit */
                BltBitMap(mybits,x,y,mybits,x+1,y+1,lx,ly,minterm,3,a);
                break;
            case 6: /* right,up one bit */
                BltBitMap(mybits,x,y+1,mybits,x+1,y,lx,ly,minterm,3,a);
                break;
            case 7: /* left,down one bit */
                BltBitMap(mybits,x+1,y,mybits,x,y+1,lx,ly,minterm,3,a);
                break;
        }
        chkabort();
    } while(1);
}
