/********************************************************************
*                                                                   *
* Joukowski Airfoil Generator with Streamlines and Pressure         *
* Distribution Algorithm                                            *
*                                                                   *
* Written by:   Russell Leighton      15 March 1987                 *
*               Lancaster, CA                                       *
*                                                                   *
********************************************************************/

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/devices.h>
#include <devices/keymap.h>
#include <graphics/regions.h>
#include <graphics/copper.h>
#include <graphics/gels.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/gfx.h>
#include <graphics/clip.h>
#include <graphics/view.h>
#include <graphics/rastport.h>
#include <graphics/layers.h>
#include <intuition/intuition.h>
#include <hardware/blit.h>
#include <math.h>
#include <libraries/mathffp.h>

#undef NULL
#define NULL  ((void *)0)
#define XMIN  0
#define YMIN  0
#define XMAX  639
#define YMAX  399
#define XCEN  320
#define YCEN  210
#define SFAC  100
#define TOL   1.0e-8
#define PENUP    (PEN = 0)
#define PENDOWN  (PEN = 1)

unsigned int mask = 0;             /* one bit set for each open */

#define INTUITION  0x0001
#define GRAPHICS   0x0002
#define SCREEN     0x0004
#define WINDOW     0x0008
#define AREAFILL   0x0010
#define DMREQUEST  0x0020

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct IntuiMessage *message;
struct Message *GetMsg();
struct ViewPort *vp;
struct RastPort *rp;
struct Screen *s;
struct Window *w;
struct Requester AirRequest;
struct TmpRas trp;
struct AreaInfo area;

WORD buffer[625];
ULONG camber = 4,thickness = 6,angle = 0,velocity = 8;
float a,b,c,t,r,alpha;
int PEN,FILL,Continue = TRUE,mode = TRUE,title = FALSE;
long ixo,iyo;

char *about[] = {
"        Airfoil Generator Utilizing the Joukowski Transformation",
" ",
"        Written by:  Russell Leighton",
"                     Lancaster, CA",
"                     March 1987",
" ",
"        To use this program bring up the requester by double clicking",
"        the right mouse button (the menu button).  This requester can be",
"        brought up at any time (even during plotting) by double clicking",
"        the right mouse button.  The requester gadgets are located and",
"        described as follows.",
" ",
"        Gadget     Location                Description",
"        ------     --------                -----------",
" ",
"        Quit       Upper left corner       Exits from program",
"        Close      Upper right corner      Starts or continues plot",
"        ShowTitle  Upper center            Toggles screen title bar",
"        Airfoil    Below ShowTitle gadget  Toggles streamline/pressure plot",
"        Camber     Below Airfoil gadget    Mid-chord camber entry",
"        Thickness  Below Camber gadget     Mid-chord thickness entry",
"        Angle      Below Thickness gadget  Angle of attack entry",
"        Velocity   Bottom edge             Slider for velocity entry",
" "
};

UWORD colors[] = {
0x046, 0x000, 0xC00, 0xC60,
0xC90, 0xCC0, 0x0C0, 0x0C7,
0x0CC, 0x09C, 0x06C, 0x00C,
0x009, 0x006, 0x000, 0xCCC
};

UWORD closeimage[] = {
/* plane 0 */
0x3FFF, 0xFC00,
0x3000, 0x0C00,
0x33FF, 0xCC00,
0x33FF, 0xCC00,
0x33C3, 0xCC00,
0x33C3, 0xCC00,
0x33FF, 0xCC00,
0x33FF, 0xCC00,
0x3000, 0x0C00,
0x3FFF, 0xFC00
};

UWORD streamimage[] = {
/* plane 0 */
0x0000, 0x0000, 0x0000, 0x0000,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFF0, 0x000F,
0xFC00, 0xFFE1, 0x003F, 0xFFFC,
0x03FF, 0xFFFE, 0x7FFF, 0xFFFE,
0x0000, 0xFFFC, 0x0000, 0x0000,
0xFFFE, 0x0003, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0x0000, 0x0000,
/* plane 1 */
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x00FF, 0xFFF8,
0xFFF0, 0x000F, 0xFC0F, 0xFFF1,
0x03FF, 0x001E, 0xFFC0, 0x0003,
0xFC00, 0x0001, 0x8000, 0x0001,
0xFFFF, 0x0003, 0xFFFF, 0xFFFF,
0x0001, 0xFFFC, 0xFFFE, 0x0003,
0xFFFF, 0xFFFF, 0x0000, 0x01FE,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
/* plane 2 */
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0xFFFF, 0xFFFF,
0xFF00, 0x0007, 0x00FF, 0xFFF8,
0xFFF0, 0x000F, 0xFC00, 0x0001,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0xFFFE, 0x0003,
0xFFFF, 0xFFFF, 0x0000, 0x01FE,
0xFFFF, 0xFE01, 0xFFFF, 0xFFFF,
0x0000, 0x0000, 0x0000, 0x0000
};

UWORD pressureimage[] = {
/* plane 0 */
0x0000, 0xFF80, 0x0007, 0x0060,
0x0038, 0x0010, 0x00C0, 0x0008,
0x0100, 0x0004, 0x0200, 0x0002,
0x0400, 0x0002, 0x0800, 0x0001,
0x1000, 0xFFE1, 0x203F, 0xFFFD,
0x43FF, 0xFFFE, 0x7FFF, 0xFFFE,
0x4000, 0xFFFD, 0x2000, 0x0001,
0x1000, 0x0002, 0x0C00, 0x0004,
0x0380, 0x0008, 0x0070, 0x0030,
0x000F, 0x00C0, 0x0000, 0xFF00,
0x0000, 0x0000, 0x0000, 0x0000,
/* plane 1 */
0x0000, 0x0000, 0x0000, 0xFF80,
0x0007, 0xFFE0, 0x003F, 0xFFF0,
0x00FF, 0xFFF8, 0x01FF, 0xFFFC,
0x03FF, 0xFFFC, 0x07FF, 0xFFFE,
0x0FFF, 0x001E, 0x1FC0, 0x0002,
0x3C00, 0x0000, 0x0000, 0x0000,
0x3FFF, 0x0002, 0x1FFF, 0xFFFE,
0x0FFF, 0xFFFC, 0x03FF, 0xFFF8,
0x007F, 0xFFF0, 0x000F, 0xFFC0,
0x0000, 0xFF00, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000
};

SHORT title_xy[] = {
     0,   0,
   151,   0,
   151,  10,
     0,  10,
     0,   0
};

struct Border title_border = {
   0L, 0L,                      /* LeftEdge, TopEdge */
   1L, 1L, JAM1,                /* FrontPen, BackPen, DrawMode */
   5L,                          /* Count (no. of vertices) */
   &title_xy[0],                /* Pointer to coordinates */
   NULL                         /* No NextBorder */
};

struct Image quit_image = {
   0L, 0L,                      /* LeftEdge, TopEdge */
   24L, 10L, 1L,                /* Width, Height, Depth */
   &closeimage[0],              /* Pointer to bit image */
   0x2, 0x0,                    /* PlanePick, PlaneOnOff */
   NULL                         /* No other images */
};

struct Image close_image = {
   0L, 0L,                      /* LeftEdge, TopEdge */
   24L, 10L, 1L,                /* Width, Height, Depth */
   &closeimage[0],              /* Pointer to bit image */
   0x1, 0x0,                    /* PlanePick, PlaneOnOff */
   NULL                         /* No other images */
};

struct Image stream_image = {
   0L, 0L,                      /* LeftEdge, TopEdge */
   32L, 22L, 3L,                /* Width, Height, Depth */
   &streamimage[0],             /* Pointer to bit image */
   0xD, 0x0,                    /* PlanePick, PlaneOnOff */
   NULL                         /* No other images */
};

struct Image pressure_image = {
   0L, 0L,                      /* LeftEdge, TopEdge */
   32L, 22L, 2L,                /* Width, Height, Depth */
   &pressureimage[0],           /* Pointer to bit image */
   0x3, 0x0,                    /* PlanePick, PlaneOnOff */
   NULL                         /* No other images */
};

struct Image prop_image;

struct IntuiText camber_text = {1L,1L,JAM1,2L,-11L,NULL,
   (UBYTE *)"Camber (% of chord):",NULL};

struct IntuiText thick_text = {1L,1L,JAM1,2L,-11L,NULL,
   (UBYTE *)"Thickness (% of chord):",NULL};

struct IntuiText angle_text = {1L,1L,JAM1,2L,-11L,NULL,
   (UBYTE *)"Angle of attack (deg):",NULL};

struct IntuiText velocity_text = {1L,1L,JAM1,2L,-11L,NULL,
   (UBYTE *)"+       Velocity       -",NULL};

#define BUFSIZE 16
UBYTE CambBuf[BUFSIZE] = "4";
UBYTE ThicBuf[BUFSIZE] = "6";
UBYTE AnglBuf[BUFSIZE] = "0";
UBYTE UndoBuf[BUFSIZE];

struct StringInfo camber_string = {
   CambBuf,                     /* Buffer */
   UndoBuf,                     /* UndoBuffer */
   0L,                          /* BufferPos */
   BUFSIZE,                     /* MaxChars */
   0L,0L,                       /* DispPos, UndoPos */
   8L,                          /* NumChars */
   0L,0L,0L,                    /* Posn Vars calc by intuition */
   NULL,                        /* No pointer to layer */
   0L,                          /* Longint value returned */
   NULL                         /* No AltKeyMap */
};

struct StringInfo thick_string = {
   ThicBuf,                     /* Buffer */
   UndoBuf,                     /* UndoBuffer */
   0L,                          /* BufferPos */
   BUFSIZE,                     /* MaxChars */
   0L,0L,                       /* DispPos, UndoPos */
   8L,                          /* NumChars */
   0L,0L,0L,                    /* Posn Vars calc by intuition */
   NULL,                        /* No pointer to layer */
   0L,                          /* Longint value returned */
   NULL                         /* No AltKeyMap */
};

struct StringInfo angle_string = {
   AnglBuf,                     /* Buffer */
   UndoBuf,                     /* UndoBuffer */
   0L,                          /* BufferPos */
   BUFSIZE,                     /* MaxChars */
   0L,0L,                       /* DispPos, UndoPos */
   8L,                          /* NumChars */
   0L,0L,0L,                    /* Posn Vars calc by intuition */
   NULL,                        /* No pointer to layer */
   0L,                          /* Longint value returned */
   NULL                         /* No AltKeyMap */
};

struct PropInfo velocity_prop = {
   AUTOKNOB |                   /* Select auto-knob gadget */
   FREEHORIZ,                   /* Knob can move horizontal */
   0x7FFF, 0x0000,              /* Initially knob is at center */
   0x0800, 0x0000,              /* HorizBody, VertBody */
   200L,11L,                    /* CWidth, CHeight */
   1L,1L,                       /* HPotRes, VPotRes */
   0L,0L                        /* LeftBorder, TopBorder */
};

#define CAMBER_GAD 0
struct Gadget camber_gad = {
   NULL,                        /* First gadget */
   10L,50L,100L,11L,            /* LeftEdge, TopEdge, Width, Height */
   GADGHCOMP,                   /* Complement image for select */
   LONGINT |                    /* This is an integer gadget */
   RELVERIFY,                   /* Release verify */
   STRGADGET |                  /* This is a string gadget */
   REQGADGET,                   /* This is a requester gadget */
   NULL,                        /* No gadget image */
   NULL,                        /* No selected image */
   &camber_text,                /* GadgetText */
   0,                           /* No mutual exclusion */
   (APTR)&camber_string,        /* SpecialInfo */
   CAMBER_GAD,                  /* Gadget id */
   NULL                         /* No user data */
};

#define THICK_GAD 1
struct Gadget thick_gad = {
   &camber_gad,                 /* NextGadget */
   10L,80L,100L,11L,            /* LeftEdge, TopEdge, Width, Height */
   GADGHCOMP,                   /* Complement image for select */
   LONGINT |                    /* This is an integer gadget */
   RELVERIFY,                   /* Release verify */
   STRGADGET |                  /* This is a string gadget */
   REQGADGET,                   /* This is a requester gadget */
   NULL,                        /* No gadget image */
   NULL,                        /* No selected image */
   &thick_text,                 /* GadgetText */
   0,                           /* No mutual exclusion */
   (APTR)&thick_string,         /* SpecialInfo */
   THICK_GAD,                   /* Gadget id */
   NULL                         /* No user data */
};

#define ANGLE_GAD 2
struct Gadget angle_gad = {
   &thick_gad,                  /* NextGadget */
   10L,110L,100L,11L,           /* LeftEdge, TopEdge, Width, Height */
   GADGHCOMP,                   /* Complement image for select */
   LONGINT |                    /* This is an integer gadget */
   RELVERIFY,                   /* Release verify */
   STRGADGET |                  /* This is a string gadget */
   REQGADGET,                   /* This is a requester gadget */
   NULL,                        /* No gadget image */
   NULL,                        /* No selected image */
   &angle_text,                 /* GadgetText */
   0,                           /* No mutual exclusion */
   (APTR)&angle_string,         /* SpecialInfo */
   ANGLE_GAD,                   /* Gadget id */
   NULL                         /* No user data */
};

#define VELOCITY_GAD 3
struct Gadget velocity_gad = {
   &angle_gad,                  /* NextGadget */
   0L,138L,199L,11L,            /* LeftEdge, TopEdge, Width, Height */
   GADGHCOMP,                   /* Complement image for select */
   RELVERIFY,                   /* Release verify */
   PROPGADGET |                 /* This is a proportional gadget */
   REQGADGET,                   /* This is a requester gadget */
   (APTR)&prop_image,           /* Gadget image */
   NULL,                        /* No selected image */
   &velocity_text,              /* GadgetText */
   0,                           /* No mutual exclusion */
   (APTR)&velocity_prop,        /* SpecialInfo */
   VELOCITY_GAD,                /* Gadget id */
   NULL                         /* No user data */
};

#define AIRFOIL_GAD 4
struct Gadget airfoil_gad = {
   &velocity_gad,               /* NextGadget */
   84L,15L,32L,22L,             /* LeftEdge, TopEdge, Width, Height */
   GADGHIMAGE |                 /* Use alternate image for select */
   GADGIMAGE,                   /* Render gadget as an image */
   TOGGLESELECT |               /* Toggle gadget each time it is selected */
   GADGIMMEDIATE,               /* Signal me when user selects gadget */
   BOOLGADGET |                 /* This is a boolean gadget */
   REQGADGET,                   /* This is a requester gadget */
   (APTR)&stream_image,         /* Pointer to gadget image */
   (APTR)&pressure_image,       /* Pointer to selected image */
   NULL,                        /* No text */
   0,                           /* No mutual exclusion */
   NULL,                        /* No special info */
   AIRFOIL_GAD,                 /* Gadget id */
   NULL                         /* No user data */
};

#define TITLE_GAD 5
struct Gadget title_gad = {
   &airfoil_gad,                /* NextGadget */
   24L,0L,151L,10L,             /* LeftEdge, TopEdge, Width, Height */
   GADGHCOMP,                   /* Complement image for select */
   TOGGLESELECT |               /* Toggle gadget each time it is selected */
   GADGIMMEDIATE,               /* Signal me when user selects gadget */
   BOOLGADGET |                 /* This is a boolean gadget */
   REQGADGET,                   /* This is a requester gadget */
   (APTR)&title_border,         /* Pointer to gadget image */
   NULL,                        /* No selected image */
   NULL,                        /* No text */
   0,                           /* No mutual exclusion */
   NULL,                        /* No special info */
   TITLE_GAD,                   /* Gadget id */
   NULL                         /* No user data */
};

#define CLOSE_GAD 6
struct Gadget close_gad = {
   &title_gad,                  /* NextGadget */
   176L,0L,24L,10L,             /* LeftEdge, TopEdge, Width, Height */
   GADGHCOMP |                  /* Complement image for select */
   GADGIMAGE,                   /* Render gadget as an image */
   GADGIMMEDIATE |              /* Signal me when user selects gadget */
   RELVERIFY |                  /* Release verify */
   ENDGADGET,                   /* This gadget ends requester */
   BOOLGADGET |                 /* This is a boolean gadget */
   REQGADGET,                   /* This is a requester gadget */
   (APTR)&close_image,          /* Pointer to gadget image */
   NULL,                        /* No selected image */
   NULL,                        /* No text */
   0,                           /* No mutual exclusion */
   NULL,                        /* No special info */
   CLOSE_GAD,                   /* Gadget id */
   NULL                         /* No user data */
};

#define QUIT_GAD 7
struct Gadget quit_gad = {
   &close_gad,                  /* NextGadget */
   0L,0L,24L,10L,               /* LeftEdge, TopEdge, Width, Height */
   GADGHCOMP |                  /* Complement image for select */
   GADGIMAGE,                   /* Render gadget as an image */
   GADGIMMEDIATE |              /* Signal me when user selects gadget */
   RELVERIFY |                  /* Release verify */
   ENDGADGET,                   /* This gadget ends requester */
   BOOLGADGET |                 /* This is a boolean gadget */
   REQGADGET,                   /* This is a requester gadget */
   (APTR)&quit_image,           /* Pointer to gadget image */
   NULL,                        /* No selected image */
   NULL,                        /* No text */
   0,                           /* No mutual exclusion */
   NULL,                        /* No special info */
   QUIT_GAD,                    /* Gadget id */
   NULL                         /* No user data */
};

struct NewScreen ns = {
   0L, 0L,                      /* LeftEdge, TopEdge */
   640L, 400L, 4L,              /* Width, Height, Depth */
   0L, 1L,                      /* DetailPen, BlockPen */
   HIRES |                      /* ViewMode flags */
   LACE,
   CUSTOMSCREEN,                /* Type */
   NULL,                        /* Default Font */

   (UBYTE *)"JOUKOWSKI AIRFOIL GENERATOR",

   NULL,                        /* No custom gadgets */
   NULL                         /* No CustomBitMap */
};

struct NewWindow nw = {
   0L, 0L,                      /* LeftEdge, TopEdge */
   640L, 400L,                  /* Width, Height */
   0L, 1L,                      /* DetailPen, BlockPen */
   GADGETDOWN |                 /* IDCMP flags */
   GADGETUP |
   REQVERIFY |
   REQCLEAR,
   SMART_REFRESH |              /* Flags */
   ACTIVATE |
   BACKDROP,
   NULL,                        /* No gadgets in window */
   NULL,                        /* Use default checkmark */
   NULL,                        /* No Title */
   NULL,                        /* Pointer to screen, to be set later */
   NULL,                        /* No superbitmap is used */
   0L, 0L, 0L, 0L,              /* Window is not resizable */
   CUSTOMSCREEN                 /* Screen Type */
};
