
/***************************   WBPat.c   ******************************/

/////////////////////////// © ASWARE '91 ///////////////////////////////
///////////////////////// by: Ekke Verheul /////////////////////////////

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <graphics/gfxbase.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <dos.h>
#include <libraries/dos.h>
#include <libraries/filehandler.h>
#include <libraries/dosextens.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include "win2.data"

#define INTUI struct IntuitionBase
#define GFX struct GFXBase
#define LIB struct Library

#define MYFLAGS SIMPLE_REFRESH | ACTIVATE | BORDERLESS | WINDOWDRAG | RMBTRAP
#define IDCMP MOUSEBUTTONS | RAWKEY | REFRESHWINDOW | ACTIVEWINDOW | INACTIVEWINDOW
#define WWIDTH  152
#define WHEIGHT 82

struct TextAttr Topaz8 = { "topaz.font",8,FS_NORMAL,FPF_ROMFONT };

struct NewWindow NewWindow =
    { 0,100,WWIDTH,WHEIGHT,0,1,IDCMP,MYFLAGS,
    NULL,NULL,"WBPat",NULL,NULL,-1,-1,-1,-1,WBENCHSCREEN };

UBYTE *testout[] = { "RAM:env/sys/wb.pat","RAM:env/sys/win.pat" };
UBYTE *saveout[] = { "SYS:prefs/Env-Archive/sys/wb.pat","SYS:prefs/Env-Archive/sys/win.pat" };
WORD dest = 0;

struct Window *Window = NULL;

UBYTE chip buf[84] = {  0x00,0x00,0x00,0x00,
                        0x00,0x00,0x00,0x00,
                        0x00,0x00,0x00,0x00,
                        0x00,0x00,0x00,0x00,
                        0x00,0x40,0x00,0x02, };

struct BitMap bm = { 2,16,0,2,0,{ (PLANEPTR)&buf[20],(PLANEPTR)&buf[52], } };

UBYTE wbbuf[84],winbuf[84];

UBYTE vtag[] = "\0$VER: WBPat 1.0 (10-12-91)";


/**** proto's
**********************************************************************
****/

void    Interface   (void);
void    NewPat      (ULONG,WORD);
void    FillBuf     (ULONG);
void    PlacePat    (void);
UBYTE   mirror      (UBYTE);
int     GetGadID    (GAD *,WORD,WORD,WORD);
void    SelectGad   (struct RastPort *,GAD *);
void    PaintBits   (struct RastPort *,ULONG );
void    InitBits    (void);


/**** main
**********************************************************************
****/
void main(int argc,char **argv)
{
int seed;

/* LIBRARIES:  */
    if (IntuitionBase = (INTUI *)OpenLibrary("intuition.library",36))
    {   if (GfxBase = (GFX *)OpenLibrary("graphics.library",36))
        {   NewWindow.LeftEdge = (GfxBase->NormalDisplayColumns - WWIDTH) / 2;
            if (Window = OpenWindow(&NewWindow))
            {   DrawImage(Window->RPort,&image,0,0);
                SelectGad(Window->RPort,&gads[dest]);
                time(&seed);
                srand(seed);
                Interface();
                CloseWindow(Window);
            }
            CloseLibrary((LIB *)GfxBase);
        }
        CloseLibrary((LIB *)IntuitionBase);
    }
    XCEXIT(0);
}

/**** Interface
**********************************************************************
****/
void Interface()
{
struct  IntuiMessage *message ;
ULONG   class,t;
WORD code,rs = 32,x,y,qualifier,bit;
WORD id,sel=-1,menu=-1;
BPTR file;

    t = rand();
    NewPat(t,rs);
    InitBits();

    // KEEP OLD PATTERNS
    if (file = Open(testout[0],1005))
    {   Read(file,wbbuf,84);         // why test? :-)
        Close(file);
    }
    if (file = Open(testout[1],1005))
    {   Read(file,winbuf,84);
        Close(file);
    }

    for (;;)
    {   Wait ( 1<<Window->UserPort->mp_SigBit);
        while(message = (struct IntuiMessage *)GetMsg(Window->UserPort))
        {   class     = message->Class  ;
            code      = message->Code;
            x         = message->MouseX;
            y         = message->MouseY;
            qualifier = message->Qualifier;
            ReplyMsg((struct Message *)message);

            switch (class)
            {   case INACTIVEWINDOW:
                case ACTIVEWINDOW:
                case REFRESHWINDOW:
                {   DrawImage(Window->RPort,&image,0,0);
                    SelectGad(Window->RPort,&gads[dest]);
                    NewPat(t,rs);
                    break;
                }
                case RAWKEY:
                {   switch (code)
                    {   case 79:   // <-
                        {   rs++;
                            NewPat(t,rs);
                            break;
                        }
                        case 78:   // ->
                        {   rs--;
                            NewPat(t,rs);
                            break;
                        }
                        case 95:   // HELP
                        {   t = rand();
                            rs = 0;
                            NewPat(t,rs);
                            break;
                        }
                        case 16:    // Quit
                        {   goto quit;
                        }
                        case 20:    // Test
                        {   if (file = Open(testout[dest],1006))
                            {   Write(file,buf,84);
                                Close(file);
                            }
                            break;
                        }
                        case 19:    // Rnd
                        {   t = rand();
                            rs = 0;
                            NewPat(t,rs);
                            break;
                        }
                        case 33:    // Save
                        {   goto save;
                        }
                        case 22:    // Use
                        {   return;
                        }
                    }
                }
                case MOUSEBUTTONS:
                {   id = GetGadID(gads,x,y,GADGETS);
                    if (code == SELECTDOWN && id >= 0)
                    {   SelectGad(Window->RPort,&gads[id]);
                        sel = id;
                        if (id < 2 && id != dest)
                        {   SelectGad(Window->RPort,&gads[id^1]);
                            dest = id;
                            sel = -1;
                        }
                        else if (id == 4)
                        {   rs++;
                            NewPat(t,rs);
                        }
                        else if (id == 5)
                        {   rs--;
                            NewPat(t,rs);
                        }
                    }
                    else if (code == SELECTDOWN && (bit = GetGadID(bits,x,y,32)) >= 0)
                    {   t ^= (0x80000000L >> ((rs+bit) & 31));
                        NewPat(t,rs);
                    }
                    else if (code == SELECTUP && sel >= 0)
                    {   SelectGad(Window->RPort,&gads[sel]);
                        if (id == sel)
                        {   switch(id)
                            {   case 2: // TEST
                                {   if (file = Open(testout[dest],1006))
                                    {   Write(file,buf,84);
                                        Close(file);
                                    }
                                    break;
                                }
                                case 3: // RND
                                {   t = rand();
                                    rs = 0;
                                    NewPat(t,rs);
                                    break;
                                }
                                case 6:  // SAVE
                                {   save:
                                    if (file = Open(saveout[dest],1006))
                                    {   Write(file,buf,84);
                                        Close(file);
                                    }
                                    return;
                                }
                                case 7: // USE
                                {   return;
                                }
                                case 8: // QUIT
                                {   quit:
                                    if (file = Open(testout[0],1006))
                                    {   Write(file,wbbuf,84);
                                        Close(file);
                                    }
                                    if (file = Open(testout[1],1006))
                                    {   Write(file,winbuf,84);
                                        Close(file);
                                    }
                                    return;
                                }
                            }
                        }
                        sel = -1;
                    }
                    else if (code == MENUDOWN && id >= 0)
                    {   SelectGad(Window->RPort,&gads[id]);
                        menu = id;
                    }
                    else if (code == MENUUP && menu >= 0)
                    {   SelectGad(Window->RPort,&gads[menu]);
                        menu = -1;
                    }
                    break;
                }
            }
        }
    }
}

/**** NewPat  // create and show new pattern
**********************************************************************
****/
void NewPat(ULONG rnd,WORD shift)
{
register ULONG t;

    shift &= 31;
    t = ( (rnd >> (32-shift)) | (rnd << shift) );
    FillBuf(t);
    PlacePat();
    PaintBits(Window->RPort,t);
}

/**** FillBuf // create 64 bytes of bitmat data
**********************************************************************
****/
void FillBuf(ULONG rnd)
{
register ULONG t;
register WORD i,k;

    t = rnd;
    for (i=20,k=0; k<8; k++)
    {   t >>=1;
        buf[102-i] = buf[i++] = (0xFF & t);
        buf[104-i] = buf[i++] = mirror(0xFF & t);
    }
    t = (rnd << 16) | (rnd >> 16);
    for (k=0; k<8;k++)
    {   buf[102-i] = buf[i++] = (0xFF & (t>>8));
        buf[104-i] = buf[i++] = mirror(0xFF & (t>>8));
        t <<= 1;
    }
}

/**** mirror // a byte
**********************************************************************
****/
UBYTE mirror(UBYTE b)
{
register UBYTE r,i;

    for (r=0,i=0; i<8; i++)
    {   r <<= 1;
        r |= (b & 0x01);
        b >>= 1;
    }
    return(r);
}

/**** PlacePat  //  copy the pattern to our window
**********************************************************************
****/
void PlacePat()
{
WORD x,y;

    WaitTOF();
    for (x = 44; x < 43 + 4 * 16 ; x += 16)
    {   for (y = 17; y < 16 + 3 * 16; y += 16)
        {   BltBitMapRastPort(&bm,0,0,Window->RPort,x,y,16,16,0xC0);
        }
    }
}

/**** GetGadID  //  I love those easy gadgets...
**********************************************************************
****/
int GetGadID(GAD *gad,WORD x,WORD y,WORD gads)
{
register int i;

    for (i=0; i<gads; i++)
    {   if ( (gad[i].left < x) &&
                (gad[i].top < y) &&
                    (gad[i].right > x) &&
                        (gad[i].down > y) )
        {   return(i);
        }
    }
    return(-1);
}

/**** SelectGad  //  switch colors of this gadget (black <-> white)
**********************************************************************
****/
void SelectGad(struct RastPort *rp,GAD *gad)
{
UBYTE lt,rb;

    lt = ReadPixel(rp,gad->left,gad->top);
    rb = ReadPixel(rp,gad->right,gad->down);

    SetAPen(rp,rb);
    Move(rp,gad->left,gad->down-1);
    Draw(rp,gad->left,gad->top);
    Draw(rp,gad->right-1,gad->top);

    SetAPen(rp,lt);
    Move(rp,gad->left+1,gad->down);
    Draw(rp,gad->right,gad->down);
    Draw(rp,gad->right,gad->top+1);
}

#define BITSY 71
#define BITSW 2
#define BITSH 3
#define BITSLEFT 12
#define BITSSTEP 4

/**** PaintBits  // Hmmm, weird little function (..)
*****            // the painting of 32 white or black blocks.
**********************************************************************
****/
void PaintBits(struct RastPort *rp,ULONG pat)
{
register ULONG bits = pat,max = 0x80000000L;
register WORD i,x;

    for (x = BITSLEFT,i = 0; i<32; i++)
    {   SetAPen(rp,1 + (bits >= max));
        RectFill(rp,x,BITSY,x+BITSW,BITSY+BITSH);
        x += BITSSTEP;
        bits <<= 1;
    }
}

/**** InitBits  // calculate the positions of the blocks
**********************************************************************
****/
void InitBits()
{
register WORD i,x;

    for (x = BITSLEFT,i = 0; i<32; i++)
    {   bits[i].left    = x - 1;
        bits[i].top     = BITSY - 2;
        bits[i].right   = x + BITSW + 2;
        bits[i].down    = BITSY + BITSH + 2;
        x += BITSSTEP;
    }
}














