home *** CD-ROM | disk | FTP | other *** search
-
- /*+---------------------------------------------------------------------------+*/
- /* */
- /* fractz */
- /* a fractal generater */
- /* Copyright (c) Tom Stokes 1993, 1994 */
- /*+---------------------------------------------------------------------------+*/
-
-
- /*+--------------------------------------------------------------------------+*/
- /*| System and library header files. |*/
- /*+--------------------------------------------------------------------------+*/
-
- #define _FP_INLINE /* generate inline FPU code */
- #define INCL_WIN
- #define INCL_DEV
- #define INCL_GPI
- #define INCL_DOS
-
- #include <os2.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- //#include <math.h>
- //#include <bsememf.h>
- #include <complex.h>
-
- /*+--------------------------------------------------------------------------+*/
- /*| Application header files. |*/
- /*+--------------------------------------------------------------------------+*/
-
- #include "fractz.h"
-
- /*+--------------------------------------------------------------------------+*/
- /*| Internal function prototypes. |*/
- /*+--------------------------------------------------------------------------+*/
-
- static void DrawingThread(void); // thread
- static void Sleeper(void); // thread
- static void Colorer(void); // thread
-
- static void InitTitle( HAB, HWND, char *, char *);
- static void UpdateTitle(HWND, char *, char *);
-
- static MRESULT EXPENTRY ClientWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
- static MRESULT EXPENTRY SettingsDlg(HWND, ULONG, MPARAM, MPARAM);
- static MRESULT EXPENTRY HelpDlgProc( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2 );
-
- static void DisplayMessage( HAB, ULONG );
-
- /*+--------------------------------------------------------------------------+*/
- /*| Static global variables and local constants. |*/
- /*+--------------------------------------------------------------------------+*/
-
- #define WINDOW_CLASS "My_Window" /* window class name */
- #define MSG_BOX_ID 256 /* error message box id */
- #define STRING_LENGTH 128 /* size of buffer used for strings*/
- #define STACK_SIZE 8192UL /* stack size for second thread */
- #define PERIOD_CHECK /* check for periodicity */
-
- //////////////////////////////////////////////////////////////////////////////////
- // note on C/set++ & __BCPLUSPLUS__
- // C/set++ defines PCSZ as: typedef const char *PCSZ and then uses it
- // as the parameter type in many APIs. BCOS2, on the other hand, does not
- // define PCSZ but instead uses: typedef unsigned char *PSZ.
- // Thus the following typedef within the __BCPLUSPLUS__ pre-defined macro
- // allows living in both worlds.
- //////////////////////////////////////////////////////////////////////////////////
-
- #ifdef __BCPLUSPLUS__
- #define min(x,y) (((x<y) ? x:y))
- #define max(x,y) (((x<y) ? y:x))
- typedef unsigned char *PCSZ;
- #endif
-
- /*+---------------------------------------------------------------------------+*/
- /*| defines for some of the classic fractal types |*/
- /*+---------------------------------------------------------------------------+*/
-
- #define MANDEL 1
- #define MANDELZ "Mandelbrot"
- #define LAMBDA 2
- #define LAMBDAZ "Lambda"
- #define CMPLXNEWT 3
- #define CMPLXNEWTZ "Cmplx Newton"
- #define JULIA1 4
- #define JULIAZ "Julia"
- #define COMPLEXMAND 5
- #define COMPLEXMANDZ "Cmplx Mark's Mandelbrot"
- #define JULIACLICK 6 // swith to via mouse click (NOT IN MENU)
- //#define JULIAZ "Julia" already defined
- #define MAGNETJ1 7
- #define MAGNETJ1Z "Magnetism Julia I"
- #define TETRATION 8
- #define TETRATIONZ "Tetration"
- #define SPIDER 9
- #define SPIDERZ "Spider"
-
- static HWND hwndFrame = NULLHANDLE; // frame window handle
- static HWND hwndClient = NULLHANDLE; // client window handle
- static HWND hwndMenu = NULLHANDLE; // menu window handle
- static HMQ hmqThread2 = NULLHANDLE; // message queue handle for thread
- static HPS hpsMem = NULLHANDLE; // for bitmap
- static HBITMAP hbm;
- static PBITMAPFILEHEADER2 pbmpfileheader2; // now for read bitmap from file
- static PBITMAPINFO2 pbmp2; // file
- static HPS hpsfile = NULLHANDLE; // file
- static PBYTE pBitsfile; // bitmap data from file
- static HBITMAP hbmfile; // bitmap handle
- static SHORT cxClient, cyClient; // client window X and Y size
- static SHORT cxCold, cyCold;
- static SHORT cxfilebmp, cyfilebmp; // size of bmp from file
- static TID tidDrawing; // drawing thread identifier
- static TID tidSleeper; // sleeper thread id. */
- static TID tidColorer;
- static char szAppName[ MAXNAMEL + 1 ]; // application name string
- static CHAR fractnamestr[40];
- static CHAR FullTitleText[100]; // concat of appname + fractname
- static LONG rdown[256], // boolean for color intensity going down
- gdown[256],
- bdown[256];
-
- static HPS hpsorb;
- static HAB hab = NULLHANDLE; // PM anchor block handle
- static HDC hdcMem;
- static PBYTE pBitmap = NULL; // creater stores into this
- static HMTX sema4; // mutex sem
- static HMTX semsleeper; // mutex sem
- static HMTX semcolorer; // mutex sem
- static PID pidProcess; // process ident
- static APIRET semrslt; // result of sem op (create,.etc.)
- static PCSZ semname = "\\SEM32\\STARTUP"; // name of semaphore
- static PCSZ sem2name = "\\SEM32\\SLEEPER"; // name of semaphore 2
- static PCSZ sem3name = "\\SEM32\\COLORER"; // name of semaphore 3
- static PBITMAPINFO2 pbmi;
-
- static int
- showorbits = 0,
- colorit = 1,
- changecolors = 0,
- ix,
- iy,
- color,
- insidecolor = 1,
- usepotential = 0,
- iter,
- maxiter = 255,
- maxcolor1,
- maxxp,
- maxyp,
- periodicity,
- lastperiod,
- checkevery,
- finiteattractor, // we use this 'cause has own convergence criteria
- fractype,
- three_d = 0;
-
- static ULONG // globals for remembering what menu items have checks
- CurrentFractalChecked,
- CurrentMapChecked,
- CurrentImageOrbitsChecked,
- CurrentFixChangeColorsChecked,
- databytes; // size of bitmap
-
-
- static BOOL
- CheckComplementAgain = FALSE, // on/off toggle
- spherical = FALSE,
- sphere_covers_180 = FALSE, // 180 or 360
- autoscale = TRUE;
-
-
- static double
- x,
- y,
- savedx,
- savedy,
- xperturb = 0.0, // perturbations - can be applied to z, c, p...
- yperturb = 0.0,
- xl, // xleft, xright,ybottom, ytop in fractal units
- xr,
- yb,
- yt,
- dx,
- dy,
- xlv,
- xrv,
- ytv,
- ybv,
- dxv, // xr - xl
- dyv, // yt - yb
- rmaxxp,
- rmaxyp,
- pixelepsilon, // convergence criteria - name means the value is pixel/zoom based
- potential,
- bailout = 2.0,
- maxheight,
- alpha,
- beta,
- phi,
- sa, // sin(alpha)
- ca, // cos(alpha)
- sb, // sin(beta)
- cb, // cos(beta)
- sp, // sin(phi)
- cp, // cos(phi)
- pi,
- rpd,
- sphererad = 1.0,
- theta,
- rho,
- xlp, // these are the 6 min,max pts. of the zoom box in the 3-d system
- xrp, // x-right-primed....
- ybp,
- ytp,
- zbp,
- ztp,
- dxvp, // xr-xl etc. but in primed (3-d rotated) coord. system
- dyvp,
- dzvp,
- xlps, // 3-d rotated sphere
- xrps,
- ybps,
- ytps,
- zbps,
- ztps,
- dxvps,
- dyvps,
- dzvps;
-
- static complex
- z,
- c,
- c0, // constant c for Julias
- savedz, // previos z for periodicity checking
- t1, t2, // temporaries to simplify expressions
- zperturb; // perturbation z
-
- static QMSG qmsgThread2; // message queue
-
- static LONG blTable[256], // color tables
- alTable[256];
-
- /*+--------------------------------------------------------------------------+*/
- /*| Dummy argument parsing routine so that real one does not get linked in. |*/
- /*+--------------------------------------------------------------------------+*/
-
- void _setuparg( void ) {}
-
- /*+--------------------------------------------------------------------------+*/
- /*| Main control procedure. |*/
- /*+--------------------------------------------------------------------------+*/
-
- int main( void )
- {
- HMQ hmq = NULLHANDLE;
- ULONG flCreate = 0UL;
- QMSG qmsg;
- int rc = 1;
-
- do
- {
- // sem requests must be early on.
-
- semrslt = DosCreateMutexSem(semname, &sema4, 0, FALSE);
- semrslt = DosRequestMutexSem(sema4, SEM_INDEFINITE_WAIT);
-
- semrslt = DosCreateMutexSem(sem2name, &semsleeper, 0, FALSE);
- semrslt = DosRequestMutexSem(semsleeper, SEM_INDEFINITE_WAIT);
-
- semrslt = DosCreateMutexSem(sem3name, &semcolorer, 0, FALSE);
- semrslt = DosRequestMutexSem(semcolorer, SEM_INDEFINITE_WAIT);
-
- // Initialize PM and create a message queue of default size.
-
- if ( ( hab = WinInitialize( 0UL ) ) == NULLHANDLE )
- break;
-
- if ( ( hmq = WinCreateMsgQueue( hab, 0UL ) ) == NULLHANDLE )
- break;
-
- // Register client window class
-
- if ( !WinRegisterClass( hab, // PM anchor block handle
- WINDOW_CLASS, // window class name
- ClientWindowProc, // address of window procedure
- CS_SIZEREDRAW,// size changes cause redrawing
- 0UL ) ) // window data
- {
- DisplayMessage( hab, IDS_NOREGISTER );
- break;
- }
-
- flCreate = FCF_STANDARD & ~FCF_TASKLIST;
-
- hwndFrame =
- WinCreateStdWindow( HWND_DESKTOP, // make desktop window the parent
- WS_VISIBLE, // frame window class style
- &flCreate, // frame control flags
- WINDOW_CLASS, // client window class name
- "", // title bar text
- CS_SIZEREDRAW, // client window class style
- 0UL, // resource file handle - in EXE
- ID_WINDOW, // resources identifier
- &hwndClient ); // client window handle
-
- if ( hwndFrame == NULLHANDLE )
- {
- DisplayMessage( hab, IDS_NOSTDWINDOWS );
- break;
- }
-
- hpsorb = WinGetPS(hwndClient); // ps for drawing orbits
-
- // Initialize the window title and task switch list
-
- InitTitle( hab, hwndFrame, szAppName, MANDELZ );
-
- // Create the thread that will draw the lines.
-
- if ( DosCreateThread( &tidDrawing, (PFNTHREAD)DrawingThread, 0UL, 0UL, STACK_SIZE ) )
- {
- DisplayMessage( hab, IDS_NOTHREAD );
- break;
- }
-
- if ( DosCreateThread( &tidSleeper, (PFNTHREAD)Sleeper, 0UL, 0UL, STACK_SIZE ) )
- {
- DisplayMessage( hab, IDS_NOTHREAD );
- break;
- }
-
- if ( DosCreateThread( &tidColorer, (PFNTHREAD)Colorer, 0UL, 0UL, STACK_SIZE ) )
- {
- DisplayMessage( hab, IDS_NOTHREAD );
- break;
- }
-
- // While the WM_QUIT message is not received, dispatch the message.
-
- while( WinGetMsg( hab, &qmsg, 0UL, 0UL, 0UL ) )
- WinDispatchMsg( hab, &qmsg );
- rc = 0;
- break;
-
- } while ( FALSE );
-
- if ( hwndFrame != NULLHANDLE )
- WinDestroyWindow( hwndFrame );
- if ( hmq != NULLHANDLE )
- WinDestroyMsgQueue( hmq );
- if ( hab != NULLHANDLE )
- WinTerminate( hab );
-
- return rc;
- }
-
- /*+--------------------------------------------------------------------------+*/
- /* start of thread2 code */
- /*+--------------------------------------------------------------------------+*/
- ixp(double x) /* return x-pixel value given x */
- {
- return(maxxp * (x-xlv)/dxv);
- }
-
- iyp(double y) /* return y-pixel value given y */
- {
- return(maxyp * (y-ybv)/dyv);
- }
-
- // as above, but in primed (rotated) coord system
- ixpp(double x) /* return x-pixel value given x */
- {
- return(maxxp * (x-xlp)/dxvp);
- }
-
- iypp(double y) //
- {
- return(maxyp * (y-ybp)/dyvp);
- }
-
- izpp(double z)
- {
- return(maxyp * (z-zbp)/dzvp);
- }
-
- // as above, but now a sphere in primed (rotated) coord system
- ixpps(double x) /* return x-pixel value given x */
- {
- return(maxxp * (x-xlps)/dxvps);
- }
-
- iypps(double y) //
- {
- return(maxyp * (y-ybps)/dyvps);
- }
-
- izpps(double z)
- {
- return(maxyp * (z-zbps)/dzvps);
- }
-
- void rotpoint(double x1, double y1, double z1, double *x2, double *y2, double *z2 )
- {
- *x2 = x1*cb*cp - y1*cb*sp + z1*sb;
- *y2 = x1*(sa*sb*cp+sp*ca) + y1*(ca*cp-sa*sb*sp) - z1*sa*cb;
- *z2 = x1*(sa*sp-ca*sb*cp) + y1*(sa*cp+ca*sb*sp) + z1*ca*cb;
- return;
- }
-
- void sphericalpoint(double x1, double y1, double z1, double *x2, double *y2, double *z2)
- {
- double rrad, trad;
- double sr,cr,st,ct;
- if (sphere_covers_180)
- theta = (x1-xl)/dx*180.0 - 90.0; // 180
- else
- theta = (x1-xl)/dx*360.0 - 180.0; // 360
- rho = (y1-yb)/dy*180.0 - 90.0; // +- 90
- trad = theta * rpd;
- rrad = rho * rpd;
- cr = cos(rrad);
- sr = sin(rrad);
- st = sin(trad);
- ct = cos(trad);
- *x2 = (sphererad+z1)*cr*st;
- *y2 = (-sphererad+z1)*cr*ct;
- *z2 = (sphererad+z1)*sr;
- }
-
- void initializechecking(void) /* used in periodicity checking for early bailout */
- {
- savedz = complex(0,0);
- periodicity = lastperiod = 1;
- checkevery = 3;
- }
-
- periodicitycheck(void)
- {
- complex dz;
- dz = z - savedz;
- if (abs(dz)< pixelepsilon) {
- if (lastperiod==periodicity)
- return periodicity;
- else {
- lastperiod = periodicity;
- periodicity = 1;
- }
- }
- else {
- if (periodicity++ > checkevery) {
- checkevery *= 2;
- periodicity = 1;
- savedz = z;
- }
- }
- return 0;
- }
-
-
- fractalpoint(double cx, double cy, int fractype)
- {
- POINTL ptl;
- complex n,r,p,zprev,deltaz;
- double arg, x2;
- int ret;
- iter = 0;
- potential = maxheight;
- #ifdef PERIOD_CHECK
- initializechecking(); /* look for periodicity */
- #endif
- switch (fractype) {
- case MANDEL: // mandelbrot
- c = complex(cx, cy);
- z = complex(xperturb,yperturb);
- break;
- case LAMBDA: // lambda
- c = complex(xperturb, yperturb);
- z = complex(cx, cy);
- break;
- case JULIA1: // julia example - no choice on 'c'
- c = complex(xperturb, yperturb);
- z = complex(cx, cy);
- break;
- case CMPLXNEWT: // complex newton
- n = complex(10,3);
- r = complex(xperturb, yperturb);
- z = complex(cx,cy);
- break;
- case COMPLEXMAND: // complex mandelbrot
- c = complex(cx,cy);
- p = complex(xperturb, yperturb);
- z = complex(0,0);
- break;
- case JULIACLICK: // switch to Julia via mouse click
- z = complex(cx, cy); // note - we already have c0 from mouse click pos
- break;
- case MAGNETJ1:
- c = complex(xperturb, yperturb);
- z = complex(cx, cy);
- break;
- case TETRATION:
- z = complex(cx, cy);
- c = z;
- break;
- case SPIDER :
- z = complex(cx,cy);
- c = z;
- break;
- default :
- break;
- } // end switch
- while (iter < maxiter) { // iteration loop starts here
- switch (fractype) {
- case MANDEL:
- z = z*z + c;
- break;
- case LAMBDA:
- z = c*z*(1.0-z);
- break;
- case JULIA1:
- z = z*z + c;
- break;
- case CMPLXNEWT:
- zprev = z;
- z = ((n-1.0)*pow(z,n)+r)/(n*pow(z,n-1));
- deltaz = z - zprev;
- break;
- case COMPLEXMAND:
- z = z*z*pow(c,p-1) + c;
- break;
- case JULIACLICK: // switch to Julia
- z = z*z + c0;
- break;
- case MAGNETJ1:
- t1 = z*z+c-1.0;
- t1 = t1*t1;
- t2 = 2.0*z+c-2.0;
- t2 = t2*t2;
- z = t1/t2;
- break;
- case TETRATION:
- z = pow(c,z);
- break;
- case SPIDER :
- z = z*z + c;
- c = c/2.0 + z;
- break;
- default:
- break;
- } // end switch
- if ((showorbits) && (iter>0)) {
- x = real(z);
- y = imag(z);
- ptl.x = (x-xlv)/dxv*maxxp;
- ptl.y = (y-ytv)/dyv*rmaxyp+rmaxyp;
- GpiMove(hpsorb,&ptl);
- GpiSetColor(hpsorb, iter%maxcolor1);
- GpiSetPel(hpsorb, &ptl);
- }
- iter++;
- #ifdef PERIOD_CHECK // can't check periodicity with finit attracters
- if ((iter % checkevery == 0) && (!finiteattractor) && (!usepotential)) {
- if (periodicitycheck())
- return insidecolor;
- }
- #endif
- if (finiteattractor) {
- if ( abs(deltaz) < pixelepsilon)
- return iter % maxcolor1;
- }
- else {
- if (abs(z) > bailout) {
- if (usepotential) {
- //potential = maxcolor1*(1.0-log(abs(z))/pow(2.0, iter));
- arg = min(abs(z)/bailout, 1.0);
- potential = maxcolor1*(1.0-log(arg));
- ret = (int)ceil(potential) % maxcolor1;
- }
- else
- ret = iter % maxcolor1;
- return ret;
- }
- }
- } // end while
- return insidecolor;
- }
-
-
- void fractalx(void)
- {
- /* - this operates on x. (does one y-line then checks msgs) -*/
- double
- cx,
- cy,
- cxparam,
- cyparam,
- czparam,
- xprime,
- yprime,
- zprime; // 3-D rotated pts. Do Not confuse with type complex
- POINTL
- ptl;
- int
- xpixel,
- ypixel,
- pinx;
- PBYTE pBitmaptemp, // aviod excessive indexing
- pBitmapditherup, // needs dithering both directions, highly non-linear
- pBitmapditherahead;
- maxxp = cxClient-1;
- maxyp = cyClient-1;
- rmaxxp = (double) maxxp;
- rmaxyp = (double) maxyp;
- xl = xlv;
- xr = xrv;
- yb = ybv;
- yt = ytv;
- dx = xr - xl;
- dxv = xrv - xlv;
- dyv = ytv - ybv;
- if (!spherical)
- dy = yt - yb;
- else
- {
- // use this for square squares, round spheres, etc.
- dy = dx * rmaxyp / rmaxxp;
- yt = dy/2.0;
- yb = -yt;
- }
- pixelepsilon = dx/(2.0*rmaxxp); // ref. Bert Tyler - the 2.0 is from 1/2 pixel
- cy = ytv + (double)(iy - maxyp) * dyv/rmaxyp;
- ix = 0;
- finiteattractor = (fractype == CMPLXNEWT); // or in some more if needed
- while (ix <= maxxp) {
- cx = dxv * (double) ix/rmaxxp + xlv;
- color = fractalpoint(cx, cy, fractype);
- // cxparam, etc, are cx, etc. for switched co-ord systems.
- cxparam = dx * (double) ix/rmaxxp + xl;
- cyparam = yt + (double)(iy-maxyp) * dy/rmaxyp;
-
- if ((three_d) && (!spherical)) {
- if (usepotential)
- czparam = potential/maxheight;
- else
- czparam = (double) color/maxheight;
- rotpoint(cxparam, cyparam, czparam, &xprime, &yprime, &zprime);
- if (autoscale) {
- xpixel = ixpp(xprime);
- ypixel = izpp(zprime);
- }
- else {
- xpixel = ixp(xprime);
- ypixel = iyp(zprime);
- }
- pinx = xpixel + cxClient*ypixel;
- pBitmaptemp = &pBitmap[pinx]; // saves on index op (below)
- if ((xpixel > 0) && (xpixel < maxxp) // prevent an access violation
- && (ypixel > 0) && (ypixel < maxyp)
- && (*pBitmaptemp == 0) ) // this line for ray tracing
- *pBitmaptemp = (UCHAR) color;
- }
- if (spherical) {
- if (usepotential)
- czparam = potential/maxheight*sphererad/10.0; // cut by 1/10 if spherical
- else
- czparam = (double) color/maxheight*sphererad/10.0;
- sphericalpoint(cxparam, cyparam, czparam, &xprime, &yprime, &zprime);
- if (three_d)
- rotpoint(xprime, yprime, zprime, &xprime, &yprime, &zprime);
- if (yprime <= 0.0) { // show near side only
- if (autoscale) {
- xpixel = ixpps(xprime);
- ypixel = izpps(zprime);
- }
- else {
- xpixel = ixp(xprime);
- ypixel = iyp(zprime);
- }
- // since another thread could be allocating/deallocating the
- // bitmap array, it must be protected. A mutex sem would probably
- // be too expensive just to protect an index-store type op.
- DosEnterCritSec();
- pinx = xpixel + cxClient*ypixel;
- pBitmaptemp = &pBitmap[pinx];
- pBitmapditherahead = pBitmaptemp;
- pBitmapditherup = pBitmaptemp;
- if ((xpixel > 0) && (xpixel < maxxp) // prevent an access violation
- && (ypixel > 0) && (ypixel < maxyp) )
- *pBitmaptemp = (UCHAR) color;
-
- // now dither twice - both up and ahead
- if ((xpixel > 0) && (xpixel < maxxp)
- && (ypixel+2 > 0) && (ypixel+2 < maxyp)) // up
- {
- pBitmapditherup += cxClient;
- *pBitmapditherup = (UCHAR) color;
- pBitmapditherup += cxClient;
- *pBitmapditherup = (UCHAR) color;
- }
- if ((xpixel+2 > 0) && (xpixel+2 < maxxp) // ahead
- && (ypixel > 0) && (ypixel < maxyp))
- {
- pBitmapditherahead++;
- *pBitmapditherahead = (UCHAR) color;
- pBitmapditherahead++;
- *pBitmapditherahead = (UCHAR) color;
- }
- DosExitCritSec();
- } // end if y<=0
- }
- if ((!spherical) && (!three_d)) {
- DosEnterCritSec();
- // several things could happen here. cxClient, cyClient could change,
- // and the bitmap array could be de-allocated.
- if ((ix < cxClient) && (iy < cyClient))
- pBitmap[ix+cxClient*iy] = color;
- DosExitCritSec();
- }
- ix++;
- } // end while(ix..)
- iy++;
- if (iy > maxyp)
- iy = 0;
- return;
- }
-
- /*+--------------------------------------------------------------------------+*/
- /*| DrawingThread - Procedure that draws in the client window. |*/
- /*+--------------------------------------------------------------------------+*/
-
- static void DrawingThread( void )
- {
- HAB habThread2 = NULLHANDLE; /* anchor block handle for thread */
- HPS hps = NULLHANDLE; /* presentation Space handle */
- RECTL rclClient; /* rectangle for client window */
-
- int ci, i;
-
- // Change the priority class of this thread
- // PRTYC_REGULAR, PRTYC_IDLETIME, PRTYC_TIMECRITICAL, PRTYC_NOCHANGE
- DosSetPriority( PRTYS_THREAD, PRTYC_IDLETIME, 0L, 0UL );
-
- habThread2 = WinInitialize( 0UL );
- hmqThread2 = WinCreateMsgQueue( habThread2, 0UL );
-
- hps = WinGetPS( hwndClient );
-
- GpiSavePS(hps);
-
- semrslt = DosRequestMutexSem(sema4, SEM_INDEFINITE_WAIT);
- semrslt = DosReleaseMutexSem(sema4);
-
- qmsgThread2.msg = WM_PAINT; // value = anything != WM_USER_END_THREAD
-
- /* Run fractal line (y=const) in thread2, then check msgs */
-
- while ( qmsgThread2.msg != WM_USER_END_THREAD ) {
- fractalx();
- WinPeekMsg( habThread2, &qmsgThread2, NULLHANDLE, 0UL, 0UL, PM_REMOVE );
- }
-
- /* Clean up and terminate drawing thread. */
-
- GpiRestorePS(hps, -1L);
- WinReleasePS( hps );
- WinReleasePS(hpsorb);
- WinDestroyMsgQueue( hmqThread2 );
- WinTerminate( habThread2 );
- DosExit( EXIT_THREAD, 0UL );
- }
-
- /*+--------------------------------------------------------------------------+*/
- /* End of thread2 +*/
- /*+--------------------------------------------------------------------------+*/
-
- /*---------------------------------------------------------------------------+*/
- /* Start of threads 3 & 4 */
- /*+--------------------------------------------------------------------------+*/
-
- static void Sleeper(void) /* #3 */
- {
- semrslt = DosRequestMutexSem(semsleeper, SEM_INDEFINITE_WAIT);
- semrslt = DosReleaseMutexSem(semsleeper);
- while(1) {
- DosSleep(3000);
- WinInvalidateRect(hwndClient, NULL, FALSE);
- }
- }
-
- static void Colorer(void) /* #4 */
- {
- int i;
- LONG r,g,b, rswitch, gswitch, bswitch;
-
- // these are delta colors that get added or subtracted to the rgb table entries.
- // They are small prime numbers to defer periodicity. You could think of them
- // as causing traveling waves up and down the table and traveling at different speeds.
- #define dr 3
- #define dg 5
- #define db 7
-
- semrslt = DosRequestMutexSem(semcolorer, SEM_INDEFINITE_WAIT);
- semrslt = DosReleaseMutexSem(semcolorer);
- while(1) {
- DosSleep(2523); // weird number just so won't get harmonic with Sleeper thread
- if (changecolors) {
- for (i=1; i<maxcolor1; i++) {
- r = (blTable[i] & 0x00ff0000) >> 16;
- g = (blTable[i] & 0x0000ff00) >> 8;
- b = (blTable[i] & 0x000000ff);
-
- rswitch = ((r >= 255-dr) & !rdown[i]) | ((r <= dr) & rdown[i]);
- gswitch = ((g >= 255-dg) & !gdown[i]) | ((g <= dg) & gdown[i]);
- bswitch = ((b >= 255-db) & !bdown[i]) | ((b <= db) & bdown[i]);
-
- if (rswitch) rdown[i] = !rdown[i];
- if (gswitch) gdown[i] = !gdown[i];
- if (bswitch) bdown[i] = !bdown[i];
-
- if (rdown[i]) r-=dr-1; else r+=dr;
- if (gdown[i]) g-=dg-1; else g+=dg;
- if (bdown[i]) b-=db-1; else b+=db;
-
- blTable[i] = (r<<16) + (g<<8) + b;
-
- }
- }// end if
- } // end while
- }
-
-
- /*+--------------------------------------------------------------------------+*/
- /* End of threads 3 & 4 +*/
- /*+--------------------------------------------------------------------------+*/
-
- /*---------------------------------------------------------------------------+*/
- /* Back to thread1 */
- /*+--------------------------------------------------------------------------+*/
-
- /*+--------------------------------------------------------------------------+*/
- /*| InitTitle - Initializes window title and task switch list. |*/
- /*+--------------------------------------------------------------------------+*/
-
-
- static void InitTitle( HAB hab, HWND hwnd, char *szTitle, char *fractname )
- {
- SWCNTRL tSwcntrl; /* task switch structure */
-
- /* Load the application name from the resources in the EXE. Set the title */
- /* bar text to this name. Then add this application to the task manager */
- /* list with the loaded application name. */
-
- WinLoadString( hab, 0UL, IDS_APPNAME, MAXNAMEL, szTitle );
- UpdateTitle(hwnd, szTitle, fractname);
-
- tSwcntrl.hwnd = hwnd;
- tSwcntrl.hwndIcon = NULLHANDLE;
- tSwcntrl.hprog = NULLHANDLE;
- tSwcntrl.idProcess = 0;
- tSwcntrl.idSession = 0;
- tSwcntrl.uchVisibility = SWL_VISIBLE;
- tSwcntrl.fbJump = SWL_JUMPABLE;
- strcpy( tSwcntrl.szSwtitle, szTitle );
- tSwcntrl.bProgType = PROG_PM;
- WinAddSwitchEntry( &tSwcntrl );
-
- return;
- }
-
- static void UpdateTitle(HWND hwnd, char * szAppName, char * fractname)
- {
- strcpy(FullTitleText, szAppName);
- strcat(FullTitleText, " - ");
- strcat(FullTitleText, fractname);
- WinSetWindowText(hwnd, FullTitleText);
- }
-
- BOOL GetFileName(ULONG WichDialog, char szFullPath[])
- {
- FILEDLG
- fdlg;
-
- fdlg.cbSize = sizeof(FILEDLG); // Size of FILEDLG structure.
- // FDS_ flags. Alter behavior of dlg.
- // FDS_SAVEAS_DIALOG or FDS_OPEN_DIALOG
- // are args to this func
- fdlg.fl = WichDialog | FDS_ENABLEFILELB;
- fdlg.ulUser = 0; // User defined field.
- fdlg.lReturn = 0; // Result code from dialog dismissal.
- fdlg.lSRC = 0; // System return code.
- fdlg.pszTitle = NULL; // String to display in title bar.
- fdlg.pszOKButton = NULL; // String to display in OK button.
- // Entry point to custom dialog proc.
- fdlg.pfnDlgProc = (PFNWP)NULL;
- fdlg.pszIType = NULL; // Pointer to string containing
- // initial EA type filter. Type
- // does not have to exist in list.
- fdlg.papszITypeList = NULL; // Pointer to table of pointers that
- // point to null terminated Type
- // strings. End of table is marked
- // by a NULL pointer.
- fdlg.pszIDrive = NULL; // Pointer to string containing // initial drive. Drive does not
- // have to exist in drive list.
- fdlg.papszIDriveList = NULL; // Pointer to table of pointers that
- // point to null terminated Drive
- // strings. End of table is marked
- // by a NULL pointer.
- fdlg.hMod = (HMODULE)0; // Custom File Dialog template.
- strcpy(fdlg.szFullFile, "*.BMP"); // Initial or selected fully
- // qualified path and file.
- fdlg.papszFQFilename = NULL; // Pointer to table of pointers that
- // point to null terminated FQFname
- // strings. End of table is marked
- // by a NULL pointer.
- fdlg.ulFQFCount = 0; // Number of files selected
- fdlg.usDlgId = 0; // Custom dialog id.
- fdlg.x = 0; // X coordinate of the dialog
- fdlg.y = 0; // Y coordinate of the dialog
- fdlg.sEAType = 0; // Selected file's EA Type.
-
- // call up file dialog
- if (!WinFileDlg(HWND_DESKTOP, hwndClient, (PFILEDLG)&fdlg))
- return TRUE;
-
- if (fdlg.lReturn != DID_OK)
- return TRUE;
-
- strcpy(szFullPath, fdlg.szFullFile);
-
- return FALSE; // aok
-
- } // End of GetFileName()
-
- VOID DrawBoxOutline(HWND hwnd, POINTL *pptlStart, POINTL *pptlEnd)
- {
- HPS hps;
-
- hps = WinGetPS(hwnd);
- GpiSetMix(hps, FM_INVERT);
- GpiMove(hps, pptlStart);
- GpiBox(hps, DRO_OUTLINE, pptlEnd, 0L, 0L);
- WinReleasePS(hps);
- }
-
-
- LoadColorTable(char *fn, LONG *cTable, int maxcolor1)
- {
- FILE *fin;
- int
- index,
- count,
- red,
- green,
- blue;
- #ifdef __BCPLUSPLUS__
- const char *openmode = "rt";
- #else
- const char *openmode = "r";
- #endif
-
- #define MAXLINELENGTH 90
- char line[MAXLINELENGTH];
- if ( (fin=fopen(fn, openmode)) == NULL)
- return 1;
-
- index = 0;
- while (index < maxcolor1) {
- if (fgets(line, MAXLINELENGTH,fin) == NULL) {
- fclose(fin);
- return 1;
- }
- count = sscanf(line,"%d %d %d %d",&red, &green, &blue);
- if (count < 3) {
- fclose(fin);
- return 1;
- }
- cTable[index] = ((red & 0xff) << 16) +
- ((green & 0xff) << 8) +
- (blue & 0xff);
- index++;
- }
- fclose(fin);
- if (index < maxcolor1)
- return 1;
- return 0;
- }
-
- VOID LoadColors(char *fn, LONG* blTable, int maxcolor1)
- {
- int i;
-
- if (LoadColorTable(fn, blTable, maxcolor1)) { // if fails, make it random
- blTable[0] = 0;
- for (i=1; i<maxcolor1; i++)
- {
- blTable[i] = ((rand() & 0xff) << 16) +
- ((rand() & 0xff) << 8) +
- (rand() & 0xff);
-
- }
- }
- }
-
- VOID CheckMenu(ULONG id, BOOL fCheck)
- {
- WinSendMsg(hwndMenu, //global main menu handle
- MM_SETITEMATTR, // set menu attribute
- MPFROM2SHORT(id, TRUE), //menu id
- MPFROM2SHORT(MIA_CHECKED, // mask = check bit
- fCheck ? MIA_CHECKED : ~MIA_CHECKED)); // turn on/off
-
- } /* end CheckMenu() */
-
- VOID SwitchCheck(ULONG id, ULONG *CurrentId)
- {
- CheckMenu(*CurrentId, FALSE); // uncheck prev.
- CheckMenu(id, TRUE); // check this one
- *CurrentId = id;
- }
-
- SaveAsBitmap(VOID)
- {
- #define OPEN_FILE 0x01
- #define CREATE_FILE 0x10
- #define FILE_ARCHIVE 0x20
- #define FILE_EXISTS OPEN_FILE
- #define FILE_NOXISTS CREATE_FILE
- #define DASD_FLAG 0
- #define INHERIT 0x80
- #define WRITE_THRU 0
- #define FAIL_FLAG 0
- #define SHARE_FLAG 0x10
- #define ACCESS_FLAG 0x02
- #define FILE_ATTRIBUTE FILE_ARCHIVE
-
- CHAR FileName[256];
- ULONG Wrote0, Wrote1, Wrote2;
- ULONG Action;
- ULONG FileHeaderSize;
- ULONG BmpHeaderSize;
- ULONG RGBTableSize;
- LONG lScansReturned;
- HFILE FileHandle;
- APIRET rc;
- BITMAPFILEHEADER2 FileHeader;
- PBITMAPINFO2 pbmi2InfoTable;
- PBYTE pBuff; // copy of bitmap
-
-
- FileHeaderSize = sizeof(BITMAPFILEHEADER2);
- BmpHeaderSize = sizeof(BITMAPINFOHEADER2);
- RGBTableSize = maxcolor1 * sizeof(RGB2);
-
- // build the file header
- FileHeader.usType = (USHORT) BFT_BMAP;
- FileHeader.cbSize = sizeof(BITMAPFILEHEADER2) + RGBTableSize + databytes;
- FileHeader.offBits = sizeof(BITMAPFILEHEADER2) + RGBTableSize;
-
- while (1)
- {
- if (GetFileName(FDS_SAVEAS_DIALOG, FileName))
- return 1; // fail or DID_CANCEL
-
- DosAllocMem((PPVOID)&pbmi2InfoTable,
- sizeof(BITMAPINFOHEADER2) + RGBTableSize,
- PAG_COMMIT | PAG_READ | PAG_WRITE);
- DosAllocMem((PPVOID)&pBuff,
- databytes,
- PAG_COMMIT | PAG_READ | PAG_WRITE);
-
- // these must be initted
- pbmi2InfoTable->cbFix = sizeof(BITMAPINFOHEADER2);
- pbmi2InfoTable->cPlanes = pbmi->cPlanes;
- pbmi2InfoTable->cBitCount = pbmi->cBitCount;
- pbmi2InfoTable->ulCompression = BCA_UNCOMP;
- pbmi2InfoTable->usReserved = 0;
- pbmi2InfoTable->usRecording = BRA_BOTTOMUP;
- pbmi2InfoTable->usRendering = BRH_NOTHALFTONED;
- pbmi2InfoTable->ulColorEncoding = BCE_RGB;
- // now put it the current RGB table
- memcpy(&pbmi2InfoTable->ulIdentifier+sizeof(ULONG), blTable, RGBTableSize);
-
- lScansReturned = GpiQueryBitmapBits( hpsMem,
- 0L, // lScanStart
- cyClient, // lScans
- pBuff,
- pbmi2InfoTable);
- if (lScansReturned == 0)
- break;
-
- rc = DosOpen ( FileName,
- &FileHandle,
- &Action,
- FileHeaderSize + RGBTableSize + databytes,
- FILE_ATTRIBUTE,
- OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS,
- DASD_FLAG | INHERIT | SHARE_FLAG | ACCESS_FLAG,
- 0L);
- if (rc)
- break;
-
- rc = DosWrite( FileHandle,
- (PVOID) (&FileHeader),
- FileHeaderSize - BmpHeaderSize, // cause they are in sep locations
- &Wrote0);
- if (rc)
- break;
- rc = DosWrite( FileHandle,
- (PVOID) pbmi2InfoTable,
- BmpHeaderSize + RGBTableSize, // cause they are in sep locations
- &Wrote0);
- if (rc)
- break;
-
-
- rc = DosWrite( FileHandle,
- pBuff, //pBitmap
- databytes,
- &Wrote2);
- if (rc)
- break;
-
-
- rc = DosClose(FileHandle);
-
- if (rc)
- break;
-
- DosFreeMem(pbmi2InfoTable);
- DosFreeMem(pBuff);
-
- return 0; // passed
-
- } // end while (1)
-
- return 1; // failed
- }
-
- LoadFractalBitmap(VOID)
- {
- #define EABUF 0L
- CHAR FileName[256];
- FILESTATUS3 filestatus3;
- ULONG cBytes;
- ULONG cbImageData;
- APIRET rc;
- ULONG Action;
- HFILE FileHandle;
- SWP winpos;
- LONG lScansReturned;
- BITMAPINFOHEADER2 bmp;
-
- while(1)
- {
- if (GetFileName(FDS_OPEN_DIALOG, FileName))
- return 1; // fail or DID_CANCEL
-
- rc = DosOpen ( FileName,
- &FileHandle,
- &Action,
- 0L,
- FILE_ATTRIBUTE,
- OPEN_ACTION_OPEN_IF_EXISTS,
- DASD_FLAG | INHERIT | SHARE_FLAG | ACCESS_FLAG,
- 0L);
- if (rc)
- break;
- rc = DosQueryFileInfo(FileHandle, FIL_STANDARD,
- (PVOID)&filestatus3, sizeof( filestatus3 ));
- // alloc memory for entire bitmap file read
- DosAllocMem((PPVOID)&pbmpfileheader2,
- filestatus3.cbFile,
- PAG_COMMIT | PAG_READ | PAG_WRITE);
- rc = DosRead( FileHandle, (PVOID)pbmpfileheader2, filestatus3.cbFile, &cBytes );
- if( rc != 0 || cBytes == 0 )
- {
- free( pbmpfileheader2 );
- DosClose( FileHandle );
- //WinPostMsg( hwndToAck, WM_NACK_FILE_READING_ERROR,
- // (MPARAM)msg, (MPARAM)0L );
- return 1;
- }
- DosClose( FileHandle );
- // set pbmp2 to point to the BITMAPINFO2 structure within the file
- pbmp2 = (PBITMAPINFO2)(&pbmpfileheader2->bmp2);
- pBitsfile = (PBYTE)pbmpfileheader2 + pbmpfileheader2->offBits;
-
- cxfilebmp = pbmp2->cx; //need these as globals
- cyfilebmp = pbmp2->cy;
-
- return 0; // pass
- }
- return 1; // fail
- }
-
- /*+--------------------------------------------------------------------------+*/
- /*| ClientWindowProc - Client window procedure. |*/
- /*+--------------------------------------------------------------------------+*/
-
- static MRESULT EXPENTRY ClientWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
- {
- HPS hps = NULLHANDLE; /* presentation space handle */
- int killer;
- int i;
- USHORT red,
- blue,
- green;
-
- static BOOL fCapture, fShowBox;
- static POINTL ptlStart, ptlEnd, ptlBoxStart, ptlBoxEnd;
-
- /* params for WinDrawBitmap */
- RECTL rectl;
-
- int ixl, ixr, iyb, iyt, temp;
-
- /* stuff for bitmap draws */
- static HDC hdcMem;
- static HDC hdcMemfile;
- PSZ pszData[4] = {"Display", NULL, NULL, NULL};
- SIZEL sizlPage = {0, 0};
- SIZEL sizlFilePage = {0, 0};
- static BITMAPINFOHEADER2 bmp;
- static HBITMAP hbmOld;
-
- POINTL aptl[4];
- POINTL textat;
- POINTL aptflFile[4];
- LONG rc;
-
- LONG alData[2];
- LONG ix0, iy0;
- double cx0, cy0;
-
- PID pidowner;
- TID tidowner;
- ULONG claimcount;
-
- static ULONG headerbytes;
- SWP swp;
-
- switch( msg )
- {
- case WM_CREATE:
- //The client window has been created but is not visible yet.
- // Initialize the window here. Also, set up device context, etc.,
-
- hwndMenu = WinWindowFromID( WinQueryWindow( hwnd, QW_PARENT),
- FID_MENU);
-
- hdcMem = DevOpenDC(hab, OD_MEMORY, "*", 4, (PDEVOPENDATA) pszData, NULLHANDLE);
-
- hpsMem = GpiCreatePS(hab, hdcMem, &sizlPage, PU_PELS | GPIT_MICRO | GPIA_ASSOC );
-
- DevQueryCaps(hdcMem, CAPS_COLORS, 256L, alTable);
- maxcolor1 = alTable[0];
- maxheight = (double) (maxcolor1 + maxcolor1/5);
-
- hps = WinGetPS(hwnd);
-
- GpiQueryLogColorTable(hps, 0L, 0L, maxcolor1, blTable); /*-- what's loaded */
-
- headerbytes = (ULONG)sizeof(BITMAPINFOHEADER2) + maxcolor1*sizeof(RGB2);
-
- DosAllocMem((PPVOID)&pbmi, headerbytes, PAG_COMMIT | PAG_READ | PAG_WRITE);
-
- LoadColors(".\\DEFAULT.MAP", blTable, maxcolor1);
-
- //GpiQueryRealColors(hps, 0, 16L, maxcolor1-16L, blTable); // physical device table
- blTable[0] = 0; // must be black
- GpiCreateLogColorTable(hps, 0L, LCOLF_CONSECRGB, 0L, maxcolor1, blTable);
- WinReleasePS(hps);
-
- // initialize size of fractal window in real x,y coords. also iy
- iy = 0;
- xlv = -2.5;
- xrv = 1.5;
- ybv = -1.5;
- ytv = 1.5;
- dxv = xrv - xlv;
- fractype = MANDEL; // initial default
- strcpy(fractnamestr, MANDELZ);
- CurrentFractalChecked = IDM_MANDEL;
- CurrentMapChecked = IDM_DEFAULT;
- CurrentImageOrbitsChecked = IDM_IMAGE;
- CurrentFixChangeColorsChecked = IDM_FIXCOLORS;
- three_d = 0;
- spherical = FALSE;
- usepotential = 0;
- pi = M_PI;
- rpd = pi/180.0;
- alpha = 20.0;
- beta = 10.0;
- phi = 10.0;
- sa = sin(alpha*rpd);
- ca = cos(alpha*rpd);
- sb = sin(beta*rpd);
- cb = cos(beta*rpd);
- sp = sin(phi*rpd);
- cp = cos(phi*rpd);
-
- break;
-
- case WM_SIZE:
- /* Window is being resized so get new client window size */
- hps = WinGetPS(hwnd);
-
- cxCold = cxClient;
- cyCold = cyClient;
- cxClient = (((LOUSHORT( mp2 )+7)/8)*8); /* Get new client window size */
- cyClient = (((HIUSHORT( mp2 )+7)/8)*8); /* has to be 32-bit word alligned */
-
- // make cx even # of words * 4 bytes/word * height * number of color planes
- if (pBitmap != NULL)
- DosFreeMem(pBitmap);
- databytes = (cxClient+1+31)/32*4*cyClient*8;
- DosAllocMem((PPVOID)&pBitmap, databytes, PAG_COMMIT | PAG_READ | PAG_WRITE);
-
- // determine the device's plane/bit count format
- GpiQueryDeviceBitmapFormats(hpsMem, 2, alData);
-
- bmp.cbFix = (ULONG)sizeof(BITMAPINFOHEADER2);
- bmp.cx = cxClient;
- bmp.cy = cyClient;
- bmp.cPlanes = alData[0];
- bmp.cBitCount = alData[1];
- bmp.ulCompression = BCA_UNCOMP;
- bmp.cbImage = cxClient;
- bmp.cxResolution = 70;
- bmp.cyResolution = 70;
- bmp.cclrUsed = maxcolor1;
- bmp.cclrImportant = 0;
- bmp.usUnits = BRU_METRIC;
- bmp.usReserved = 0;
- bmp.usRecording = BRA_BOTTOMUP;
- bmp.usRendering = BRH_NOTHALFTONED;
- bmp.cSize1 = 0;
- bmp.cSize2 = 0;
- bmp.ulColorEncoding = BCE_RGB;
- bmp.ulIdentifier = 0;
-
- pbmi->cbFix = bmp.cbFix;
- pbmi->cx = cxClient;
- pbmi->cy = cyClient;
- pbmi->cPlanes = alData[0];
- pbmi->cBitCount = alData[1];
- pbmi->ulCompression = BCA_UNCOMP;
- pbmi->cbImage = ((cxClient+31)/32)*4;
- pbmi->cbImage = bmp.cbImage;
- pbmi->cxResolution = 70;
- pbmi->cyResolution = 70;
- pbmi->cclrUsed = bmp.cclrUsed;
- pbmi->cclrImportant = 0;
- pbmi->usUnits = BRU_METRIC;
- pbmi->usReserved = 0;
- pbmi->usRecording = BRA_BOTTOMUP;
- pbmi->usRendering = BRH_NOTHALFTONED;
- pbmi->cSize1 = 0;
- pbmi->cSize2 = 0;
- pbmi->ulColorEncoding = BCE_RGB;
- pbmi->ulIdentifier = 0;
- for (i=0; i<maxcolor1; i++) {
- pbmi->argbColor[i].bBlue = blTable[i] & 0x000000ff;
- pbmi->argbColor[i].bGreen = (blTable[i] & 0x0000ff00) >> 8;
- pbmi->argbColor[i].bRed = (blTable[i] & 0x00ff0000) >> 16;
- }
-
- // now create a bitmap which is compatible with display
- hbm = GpiCreateBitmap(hpsMem, &bmp, FALSE, NULL, NULL);
-
- // associate the bitmap and the memory presentation space
- hbmOld = GpiSetBitmap(hpsMem, hbm);
- GpiSetBitmapBits(hpsMem, 0L, cyClient, pBitmap, pbmi);
- GpiDeleteBitmap(hbmOld);
-
-
- // turn thread2 loose
- semrslt = DosQueryMutexSem(sema4, &pidowner, &tidowner, &claimcount);
- if ((tidowner == 1) && (claimcount > 0)) // does thread #1 own it?
- semrslt = DosReleaseMutexSem(sema4);
-
- /* turn thread3 loose */
- semrslt = DosQueryMutexSem(semsleeper, &pidowner, &tidowner, &claimcount);
- if ((tidowner == 1) && (claimcount > 0)) /* does thread #1 own it? */
- semrslt = DosReleaseMutexSem(semsleeper);
-
- /* turn thread4 loose */
- semrslt = DosQueryMutexSem(semcolorer, &pidowner, &tidowner, &claimcount);
- if ((tidowner == 1) && (claimcount > 0)) /* does thread #1 own it? */
- semrslt = DosReleaseMutexSem(semcolorer);
-
- WinReleasePS(hps);
-
- break;
-
- case WM_CLOSE:
- /* Tell the main procedure to terminate the message loop. */
-
- WinPostMsg( hwnd, WM_QUIT, NULL, NULL );
- DosFreeMem((PPVOID)&pbmi);
- GpiDestroyPS(hpsMem);
- DevCloseDC(hdcMem);
- GpiDeleteBitmap(hbm);
- break;
-
- case WM_PAINT:
- hps = WinBeginPaint( hwnd, NULLHANDLE, NULL );
- for (i=0; i<maxcolor1; i++) {
- pbmi->argbColor[i].bBlue = blTable[i] & 0x000000ff;
- pbmi->argbColor[i].bGreen = (blTable[i] & 0x0000ff00) >> 8;
- pbmi->argbColor[i].bRed = (blTable[i] & 0x00ff0000) >> 16;
- }
-
- aptl[0].x = 0;
- aptl[0].y = 0;
- aptl[1].x = cxClient-1;
- aptl[1].y = cyClient-1;
- aptl[2].x = 0;
- aptl[2].y = 0;
- aptl[3].x = cxCold-1;
- aptl[3].y = cyCold-1;
-
- // set up the file rectangle
- aptflFile[0].x = 0;
- aptflFile[0].y = 0;
- aptflFile[1].x = cxClient-1;
- aptflFile[1].y = cyClient-1;
- aptflFile[2].x = 0;
- aptflFile[2].y = 0;
- aptflFile[3].x = cxfilebmp-1;
- aptflFile[3].y = cyfilebmp-1;
-
- GpiSetBitmapBits(hpsMem, 0L, cyClient, pBitmap, pbmi);
-
-
- if (colorit) {
- if (hpsfile == NULLHANDLE)
- GpiBitBlt(hps, hpsMem, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
- else { // we are viewing a bitmap from a file
- // blast from hpsfile (load bitmap from file)
- GpiBitBlt(hps, hpsfile, 4L, aptflFile, ROP_SRCCOPY, BBO_IGNORE);
- }
- }
- else {
- WinQueryWindowRect(hwnd, &rectl); // gonna draw orbits
- WinFillRect(hps, &rectl, CLR_BLACK);
- }
-
- // now draw the zoom box - if needed
- if (fCapture || fShowBox) {
- GpiSetMix(hps, FM_INVERT);
- GpiMove(hps, &ptlStart);
- GpiBox(hps, DRO_OUTLINE, &ptlEnd, 0L, 0L);
- }
-
- WinEndPaint( hps );
-
- break;
-
- case WM_COMMAND:
- // The user has chosen a menu item. Process the selection.
- switch ( SHORT1FROMMP( mp1 ) )
- {
- case IDM_EXITPROG:
- // Post a close message.
- WinPostMsg( hwnd, WM_CLOSE, NULL, NULL );
- break;
-
- case IDM_RESUME:
- WinPostQueueMsg( hmqThread2, WM_USER_REPAINT, 0UL, 0UL );
- break;
-
- case IDM_MANDEL :
- fractype = MANDEL;
- SwitchCheck(IDM_MANDEL, &CurrentFractalChecked);
- UpdateTitle(hwndFrame, szAppName, MANDELZ);
- break;
- case IDM_LAMBDA:
- fractype = LAMBDA;
- SwitchCheck(IDM_LAMBDA, &CurrentFractalChecked);
- UpdateTitle(hwndFrame, szAppName, LAMBDAZ);
- break;
- case IDM_CMPLXNEWT:
- fractype = CMPLXNEWT;
- SwitchCheck(IDM_CMPLXNEWT, &CurrentFractalChecked);
- UpdateTitle(hwndFrame, szAppName, CMPLXNEWTZ);
- break;
- case IDM_JULIA1:
- fractype = JULIA1;
- SwitchCheck(IDM_JULIA1, &CurrentFractalChecked);
- UpdateTitle(hwndFrame, szAppName, JULIAZ);
- break;
- case IDM_CMPLXMAN:
- fractype = COMPLEXMAND;
- SwitchCheck(IDM_CMPLXMAN, &CurrentFractalChecked);
- UpdateTitle(hwndFrame, szAppName, COMPLEXMANDZ);
- break;
- case IDM_MAGNETJ1:
- fractype = MAGNETJ1;
- SwitchCheck(IDM_MAGNETJ1, &CurrentFractalChecked);
- UpdateTitle(hwndFrame, szAppName, MAGNETJ1Z);
- break;
- case IDM_TETRATION:
- fractype = TETRATION;
- SwitchCheck(IDM_TETRATION, &CurrentFractalChecked);
- UpdateTitle(hwndFrame, szAppName, TETRATIONZ);
- break;
- case IDM_SPIDER :
- fractype = SPIDER;
- SwitchCheck(IDM_SPIDER, &CurrentFractalChecked);
- UpdateTitle(hwndFrame, szAppName, SPIDERZ);
- break;
- case IDM_RESET :
- if (hpsfile != NULLHANDLE)
- GpiDestroyPS(hpsfile); // make sure it's deceased
- hpsfile = NULLHANDLE;
- iy = 0;
- xlv = -2.5;
- xrv = 1.5;
- ybv = -1.5;
- ytv = 1.5;
- dxv = xrv - xlv;
- dyv = ytv - ybv;
- showorbits = 0;
- xperturb = 0.0;
- yperturb = 0.0;
- three_d = 0;
- usepotential = 0;
- spherical = FALSE;
- fractype = MANDEL; // initial default
- SwitchCheck(IDM_MANDEL, &CurrentFractalChecked);
- UpdateTitle(hwndFrame, szAppName, MANDELZ);
- break;
-
- case IDM_SAVE :
- if (SaveAsBitmap() )
- DisplayMessage(hab, IDS_FAILCREATE );
- break;
-
- case IDM_VIEW :
- CheckMenu(IDM_VIEW, TRUE);
- CheckMenu(IDM_UNVIEW, FALSE);
- if (LoadFractalBitmap() ) {
- DisplayMessage(hab, IDS_FAILOPEN);
- break;
- }
- hdcMemfile = DevOpenDC(hab, OD_MEMORY, "*", 4,
- (PDEVOPENDATA) pszData, NULLHANDLE);
- hpsfile = GpiCreatePS(hab, hdcMemfile, &sizlFilePage,
- PU_PELS | GPIT_MICRO | GPIA_ASSOC );
- hbmfile = GpiCreateBitmap(hpsfile, (PBITMAPINFOHEADER2) pbmp2,
- 0, NULL, NULL);
- // associate the bitmap and the memory presentation space
- GpiSetBitmap(hpsfile, hbmfile);
- GpiSetBitmapBits(hpsfile,
- 0L, // scanstart
- pbmp2->cy, // #of scans
- pBitsfile, // the bitmap
- pbmp2);
- break;
-
- case IDM_UNVIEW :
- CheckMenu(IDM_VIEW, FALSE);
- CheckMenu(IDM_UNVIEW, TRUE);
- GpiDestroyPS(hpsfile);
- DevCloseDC(hdcMemfile);
- GpiDeleteBitmap(hbmfile);
- hpsfile = NULLHANDLE;
- DosFreeMem(pbmpfileheader2); // allocated in LoadFractalBitmap
- break;
-
- case IDM_ORBIT :
- SwitchCheck(IDM_ORBIT, &CurrentImageOrbitsChecked);
- showorbits = 1;
- colorit = 0;
- break;
- case IDM_IMAGE :
- SwitchCheck(IDM_IMAGE, &CurrentImageOrbitsChecked);
- showorbits = 0;
- colorit = 1;
- break;
- case IDM_FIXCOLORS :
- SwitchCheck(IDM_FIXCOLORS, &CurrentFixChangeColorsChecked);
- changecolors = 0;
- break;
- case IDM_CHANGECOLORS :
- SwitchCheck(IDM_CHANGECOLORS, &CurrentFixChangeColorsChecked);
- changecolors = 1;
- break;
-
- case IDM_DEFAULT : // start of color maps
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_DEFAULT, &CurrentMapChecked);
- LoadColors(".\\default.map", blTable, maxcolor1);
- break;
- case IDM_ALTERN :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_ALTERN, &CurrentMapChecked);
- LoadColors(".\\altern.map", blTable, maxcolor1);
- break;
- case IDM_BLUES :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_BLUES, &CurrentMapChecked);
- LoadColors(".\\blues.map", blTable, maxcolor1);
- break;
- case IDM_CHROMA :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_CHROMA, &CurrentMapChecked);
- LoadColors(".\\chroma.map", blTable, maxcolor1);
- break;
- case IDM_DARKGREY :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_DARKGREY, &CurrentMapChecked);
- LoadColors(".\\darkgrey.map", blTable, maxcolor1);
- break;
- case IDM_FIRESTRM :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_FIRESTRM, &CurrentMapChecked);
- LoadColors(".\\firestrm.map", blTable, maxcolor1);
- break;
- case IDM_GAMMA1 :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_GAMMA1, &CurrentMapChecked);
- LoadColors(".\\gamma1.map", blTable, maxcolor1);
- break;
- case IDM_GAMMA2 :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_GAMMA2, &CurrentMapChecked);
- LoadColors(".\\gamma2.map", blTable, maxcolor1);
- break;
- case IDM_GREEN :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_GREEN, &CurrentMapChecked);
- LoadColors(".\\green.map", blTable, maxcolor1);
- break;
- case IDM_GREY :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_GREY, &CurrentMapChecked);
- LoadColors(".\\grey.map", blTable, maxcolor1);
- break;
- case IDM_LANDSCAP :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_LANDSCAP, &CurrentMapChecked);
- LoadColors(".\\landscap.map", blTable, maxcolor1);
- break;
- case IDM_NEON :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_NEON, &CurrentMapChecked);
- LoadColors(".\\neon.map", blTable, maxcolor1);
- break;
- case IDM_PAINTJET :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_PAINTJET, &CurrentMapChecked);
- LoadColors (".\\paintjet", blTable, maxcolor1);
- break;
- case IDM_ROYAL :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_ROYAL, &CurrentMapChecked);
- LoadColors(".\\royal.map", blTable, maxcolor1);
- break;
- case IDM_TOPO :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_TOPO, &CurrentMapChecked);
- LoadColors(".\\topo.map", blTable, maxcolor1);
- break;
- case IDM_VOLCANO :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_VOLCANO, &CurrentMapChecked);
- LoadColors(".\\volcano.map", blTable, maxcolor1);
- break;
- case IDM_RANDOM :
- CheckMenu(IDM_COMPLEMENT, FALSE);
- CheckComplementAgain = FALSE;
- SwitchCheck(IDM_RANDOM, &CurrentMapChecked);
- LoadColors(".\\random.map", blTable, maxcolor1);
- break;
- case IDM_COMPLEMENT :
- CheckComplementAgain ^= TRUE;
- CheckMenu(IDM_COMPLEMENT, CheckComplementAgain);
- for (i=1; i<maxcolor1; i++)
- blTable[i] = (~blTable[i]) & 0xffffff;
- break;
-
- case IDM_SETTINGS:
- WinDlgBox(HWND_DESKTOP, hwnd, SettingsDlg, 0, DLG_SETTINGS, 0);
- return 0;
-
- case IDM_HELPINSTRUCTIONS:
- /* Display the help dialog box. */
-
- WinMessageBox( HWND_DESKTOP, /* desktop is the parent */
- hwnd, /* owned by client window */
- INSTRUCTIONS, /* pointer to message text */
- szAppName, /* pointer to title text */
- 1UL, /* message box identifier */
- MB_OK | MB_INFORMATION | /* message box style */
- MB_APPLMODAL | MB_MOVEABLE );
-
- break;
-
- case IDM_HELPABOUT:
- /* Display the help dialog box. */
-
- WinDlgBox( HWND_DESKTOP, /* make the desktop the parent */
- hwnd, /* owned by client window */
- HelpDlgProc, /* address of dialog procedure */
- 0UL, /* module handle */
- IDD_HELP, /* dialog identifier in resource */
- NULL ); /* initialization data */
-
- break;
- }
- WinInvalidateRect(hwndClient, NULL, FALSE);
- break;
-
-
- case WM_BUTTON1DOWN:
- WinSetFocus( HWND_DESKTOP, hwnd );
- ptlStart.x = ptlEnd.x = MOUSEMSG(&msg)->x;
- ptlStart.y = ptlEnd.y = MOUSEMSG(&msg)->y;
-
- DrawBoxOutline(hwnd, &ptlStart, &ptlEnd);
-
- WinSetCapture(HWND_DESKTOP, hwnd);
- fCapture = TRUE;
-
- return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
-
- case WM_BUTTON1DBLCLK:
- // The user has double clicked mouse button 1 which means
- // clear to black and redraw
- iy = 0;
- memset(pBitmap, 0, databytes);
- WinInvalidateRect(hwnd, NULL, FALSE);
- break;
-
- case WM_BUTTON2DOWN: // switch to Julia
- ix0 = MOUSEMSG(&msg)->x;
- iy0 = MOUSEMSG(&msg)->y;
- cy0 = ytv + (double)(iy0 - maxyp) * dyv/rmaxyp;
- cx0 = dxv * (double) ix0/rmaxxp + xlv;
- xperturb = cx0; // these two mostly for dialog box field
- yperturb = cy0;
- c0 = complex(cx0, cy0);
- fractype = JULIACLICK;
- UpdateTitle(hwndFrame, szAppName, JULIAZ);
- SwitchCheck(IDM_JULIA1, &CurrentFractalChecked);
- xlv = -2.0; // now start it big again
- xrv = 2.0;
- ybv = -1.5;
- ytv = 1.5;
- dxv = xrv - xlv;
- dyv = ytv - ybv;
- return (MRESULT) TRUE;
-
- case WM_BUTTON1UP:
- if (fCapture) {
- ptlBoxStart = ptlStart;
- ptlBoxEnd.x = MOUSEMSG(&msg)->x;
- ptlBoxEnd.y = MOUSEMSG(&msg)->y;
- WinSetCapture(HWND_DESKTOP, NULLHANDLE); // off
- fCapture = FALSE;
- fShowBox = FALSE;
- ixl = ptlBoxStart.x;
- ixr = ptlBoxEnd.x;
- iyt = ptlBoxStart.y;
- iyb = ptlBoxEnd.y;
- if (ixl > ixr) {
- temp = ixl;
- ixl = ixr;
- ixr = temp;
- }
- if (iyb > iyt) {
- temp = iyb;
- iyb = iyt;
- iyt = temp;
- }
- // check for small box - user reject or clear box
- if (((ixl - ixr) < 8) && ((iyt - iyb) < 8)) {
- fShowBox = FALSE;
- fCapture = FALSE;
- break;
- }
- dxv = xrv - xlv;
- dyv = ytv - ybv;
- rmaxxp = (double) (cxClient-1);
- rmaxyp = (double) (cyClient-1);
-
- xrv = dxv * (double) ixr / rmaxxp + xlv;
- xlv = dxv * (double) ixl / rmaxxp + xlv;
-
- ybv = ytv + ((double)iyb - rmaxyp)/rmaxyp * dyv;
- ytv = ytv + ((double)iyt - rmaxyp)/rmaxyp * dyv;
- dxv = xrv - xlv;
- dyv = ytv - ybv;
- WinInvalidateRect(hwnd, NULL, FALSE);
- }
- break;
-
- case WM_MOUSEMOVE:
- if (fCapture) {
- DrawBoxOutline(hwnd, &ptlStart, &ptlEnd);
- ptlEnd.x = MOUSEMSG(&msg)->x;
- ptlEnd.y = MOUSEMSG(&msg)->y;
- DrawBoxOutline(hwnd, &ptlStart, &ptlEnd);
- }
- return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
-
- case WM_DESTROY:
- /* The client window is being destroyed so tell the second thread to */
- /* stop running. */
-
- WinPostQueueMsg( hmqThread2, WM_USER_END_THREAD, 0UL, 0UL );
-
- /* Wait for the drawing thread to terminate before returning. */
-
- DosWaitThread( &tidDrawing, DCWW_WAIT );
-
- break;
- default:
- /* For all other messages, let the default window procedure */
- /* process them. */
-
- return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
-
- }
- return 0;
- }
- /*+--------------------------------------------------------------------------+*/
- /*| BasicSettingsDlg - |*/
- /*+--------------------------------------------------------------------------+*/
-
- static MRESULT EXPENTRY BasicSettingsDlg ( HWND hwndSettings, ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- static HWND hwndlbox;
- char
- xpstr[20],
- ypstr[20], // perturbation strings
- xlstr[20],
- xrstr[20],
- ybstr[20],
- ytstr[20], // input/output params for four fields
- iterstr[20],
- bailoutstr[20],
- examplestr[30],
- formulastr[40];
-
- switch(msg)
- {
- case WM_INITDLG:
- hwndlbox = HWNDFROMMP(mp1);
- sprintf(xlstr, "%lf", xlv);
- sprintf(xrstr, "%lf", xrv);
- sprintf(ybstr, "%lf", ybv);
- sprintf(ytstr, "%lf", ytv);
- sprintf(iterstr, "%ld", maxiter);
- sprintf(bailoutstr, "%3.1lf", bailout);
- sprintf(xpstr, "%lf", xperturb);
- sprintf(ypstr, "%lf", yperturb);
-
- switch (fractype) {
- case MANDEL:
- strcpy(fractnamestr, MANDELZ);
- strcpy(formulastr, "z = z^2 + c");
- strcpy(examplestr, "(0,0)");
- break;
- case LAMBDA:
- strcpy(fractnamestr, LAMBDAZ);
- strcpy(formulastr, "z = c*z*(1-z)");
- strcpy(examplestr, "(0.85,0.6)");
- break;
- case CMPLXNEWT:
- strcpy(fractnamestr, CMPLXNEWTZ);
- strcpy(formulastr, "z = ((n-1)z^n+r)/(n*z^(n-1))");
- strcpy(examplestr, "(3,0)");
- break;
- case JULIA1:
- strcpy(fractnamestr, JULIAZ);
- strcpy(formulastr, "z = z*z + c");
- strcpy(examplestr, "(var,var)");
- break;
- case COMPLEXMAND:
- strcpy(fractnamestr, COMPLEXMANDZ);
- strcpy(formulastr, "z = z*z*c^(p-1)+c");
- strcpy(examplestr, "(1,0)");
- break;
- case JULIACLICK: // switch to Julia
- strcpy(fractnamestr, JULIAZ);
- strcpy(formulastr, "z = z^2 + c");
- strcpy(examplestr, "(clk_x,clk_y)");
- break;
- case MAGNETJ1:
- strcpy(fractnamestr, MAGNETJ1Z);
- strcpy(formulastr, "(see ref. 1)");
- strcpy(examplestr, "(0.3,0.6)");
- break;
- case TETRATION:
- strcpy(fractnamestr, TETRATIONZ);
- strcpy(formulastr, "z = c^z");
- strcpy(examplestr, "(0,0) see ref");
- break;
- case SPIDER :
- strcpy(fractnamestr, SPIDERZ);
- strcpy(formulastr, "z=z^2+c;c=c/2+z");
- strcpy(examplestr, "(0,0)");
- default:
- break;
- }
- WinSetDlgItemText(hwndSettings, DLG_FRACTNAME, fractnamestr);
- WinSetDlgItemText(hwndSettings, DLG_FORMULA, formulastr);
- WinSetDlgItemText(hwndSettings, DLG_EXAMPLEPERTS, examplestr);
-
- WinSetDlgItemText(hwndSettings, DLG_XLEFT, xlstr);
- WinSetDlgItemText(hwndSettings, DLG_XRIGHT, xrstr);
- WinSetDlgItemText(hwndSettings, DLG_YBOTTOM, ybstr);
- WinSetDlgItemText(hwndSettings, DLG_YTOP, ytstr);
- WinSetDlgItemText(hwndSettings, DLG_REALNO, xpstr);
- WinSetDlgItemText(hwndSettings, DLG_IMAGNO, ypstr);
- WinSetDlgItemText(hwndSettings, DLG_MAXITER, iterstr);
- WinSetDlgItemText(hwndSettings, DLG_BAILOUT, bailoutstr);
- return (MRESULT)TRUE;
-
- case WM_COMMAND:
- switch( SHORT1FROMMP( mp1 ) ) // Extract the command value
- {
- case DID_OK:
- WinQueryDlgItemText(hwndSettings, DLG_XLEFT, 20, xlstr);
- WinQueryDlgItemText(hwndSettings, DLG_XRIGHT, 20, xrstr);
- WinQueryDlgItemText(hwndSettings, DLG_YBOTTOM, 20, ybstr);
- WinQueryDlgItemText(hwndSettings, DLG_YTOP, 20, ytstr);
- xlv = atof(xlstr);
- xrv = atof(xrstr);
- ybv = atof(ybstr);
- ytv = atof(ytstr);
- dxv = xrv - xlv;
- dyv = ytv - ybv;
- WinQueryDlgItemText(hwndSettings, DLG_REALNO, 20, xpstr);
- WinQueryDlgItemText(hwndSettings, DLG_IMAGNO, 20, ypstr);
- xperturb = atof(xpstr);
- yperturb = atof(ypstr);
- WinQueryDlgItemText(hwndSettings, DLG_MAXITER, 20, iterstr);
- WinQueryDlgItemText(hwndSettings, DLG_BAILOUT, 20, bailoutstr);
- maxiter = atoi(iterstr);
- bailout = atof(bailoutstr);
- return 0;
- case DID_CANCEL:
- return 0;
- }
- break;
-
- default:
- break;
- }
- mp2; // not referenced
- return (MRESULT) 0;
- }
-
-
- LONG ReadSliderPosition(HWND hwnd, int Which1)
- {
- return (LONG) WinSendDlgItemMsg(
- hwnd,
- Which1,
- SLM_QUERYSLIDERINFO,
- MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE),
- NULL);
- }
-
- BOOL InitializeSlider(HWND hwnd, int Which1)
- {
- USHORT index;
- LONG degrees;
- CHAR acBuffer[4];
- CHAR *cData;
-
- cData = ltoa(0, acBuffer, 10);
- WinSetDlgItemText(hwnd, Which1, cData);
- /*--------------------------------------
- if (!WinSendDlgItemMsg(hwnd, this is very dense. use if desired
- Which1,
- SLM_SETTICKSIZE,
- MPFROM2SHORT(SMA_SETALLTICKS, 3),
- NULL) )
- return FALSE;
- ------------------------------------------------*/
- for (index = 0; index <= 180; index+=10){
- degrees = -90 + index;
- cData = ltoa(degrees, acBuffer, 10);
- if (!WinSendDlgItemMsg(hwnd,
- Which1,
- SLM_SETSCALETEXT,
- MPFROMSHORT(index),
- MPFROMP(cData) ) )
- return FALSE;
- if (!WinSendDlgItemMsg(hwnd,
- Which1,
- SLM_SETTICKSIZE,
- MPFROM2SHORT(index, 7),
- NULL) )
- return FALSE;
- }
- for (index = 5; index <= 175; index+=10){ // now set some smaller ticks
- if (!WinSendDlgItemMsg(hwnd,
- Which1,
- SLM_SETTICKSIZE,
- MPFROM2SHORT(index, 4),
- NULL) )
- return FALSE;
- }
-
- switch(Which1) {
- case DLGA_ALPHA :
- index = ((SHORT) alpha + 90);
- break;
- case DLGA_BETA :
- index = ((SHORT) beta + 90);
- break;
- case DLGA_PHI :
- index = ((SHORT) phi + 90);
- break;
- default :
- break;
- }
- WinSendDlgItemMsg( // now move the slider to alpha, beta, phi
- hwnd,
- Which1,
- SLM_SETSLIDERINFO,
- MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE),
- MPFROMSHORT(index));
-
- return TRUE;
- }
-
- static MRESULT EXPENTRY AdvancedSettingsDlg ( HWND hwndSettings, ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- static HWND hwndlbox;
- char
- maxhtstr[20],
- insidecolorstr[20],
- bailoutstr[20];
-
- LONG
- ulalpha,
- ulbeta,
- ulphi;
-
- switch(msg)
- {
- case WM_INITDLG:
- hwndlbox = HWNDFROMMP(mp1);
- sprintf(maxhtstr, "%4.1lf", maxheight);
- sprintf(insidecolorstr, "%3ld", insidecolor);
- sprintf(bailoutstr, "%6.1lf", bailout);
- WinSetDlgItemText(hwndSettings, DLGA_MAXHT, maxhtstr);
- WinSetDlgItemText(hwndSettings, DLGA_INSIDECOLOR, insidecolorstr);
-
- WinCheckButton(hwndSettings, DLGA_THREED, three_d);
- WinCheckButton(hwndSettings, DLGA_USEPOTENTIAL, usepotential);
-
- if (autoscale) {
- WinCheckButton(hwndSettings, DLG_AUTOYES, TRUE);
- WinCheckButton(hwndSettings, DLG_AUTONO, FALSE);
- }
- else {
- WinCheckButton(hwndSettings, DLG_AUTOYES, FALSE);
- WinCheckButton(hwndSettings, DLG_AUTONO, TRUE);
- }
-
- InitializeSlider(hwndSettings, DLGA_ALPHA);
- InitializeSlider(hwndSettings, DLGA_BETA);
- InitializeSlider(hwndSettings, DLGA_PHI);
-
- return (MRESULT)0;
- case WM_COMMAND:
- switch( SHORT1FROMMP( mp1 ) ) // Extract the command value
- {
- case DID_OK:
- ulalpha = ReadSliderPosition(hwndSettings, DLGA_ALPHA);
- alpha = (double) (ulalpha - 90);
- ulbeta = ReadSliderPosition(hwndSettings, DLGA_BETA);
- beta = (double) (ulbeta - 90);
- ulphi = ReadSliderPosition(hwndSettings, DLGA_PHI);
- phi = (double) (ulphi - 90);
- three_d = WinQueryButtonCheckstate(hwndSettings, DLGA_THREED);
- usepotential = WinQueryButtonCheckstate(hwndSettings, DLGA_USEPOTENTIAL);
- autoscale = WinQueryButtonCheckstate(hwndSettings, DLG_AUTOYES);
- WinQueryDlgItemText(hwndSettings, DLGA_MAXHT, 20, maxhtstr);
- WinQueryDlgItemText(hwndSettings, DLGA_INSIDECOLOR, 20, insidecolorstr);
- maxheight = atof(maxhtstr);
- insidecolor = atoi(insidecolorstr);
- return 0;
- case DID_CANCEL:
- return 0;
- }
- break;
-
- default:
- break;
- }
- mp2; // not referenced
- return (MRESULT) 0;
- }
-
- static MRESULT EXPENTRY SpecialSettingsDlg(HWND hwndSettings, ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- static HWND hwndlbox;
- char
- radiusstr[20];
-
- switch(msg)
- {
- case WM_INITDLG :
- hwndlbox = HWNDFROMMP(mp1);
-
- if (sphere_covers_180) {
- WinCheckButton(hwndSettings, DLG_360, FALSE);
- WinCheckButton(hwndSettings, DLG_180, TRUE);
- }
- else {
- WinCheckButton(hwndSettings, DLG_180, FALSE);
- WinCheckButton(hwndSettings, DLG_360, TRUE);
- }
- sprintf(radiusstr, "%6.3lg", sphererad);
- WinSetDlgItemText(hwndSettings, DLG_SPHERERAD, radiusstr);
-
- WinCheckButton(hwndSettings, DLG_SPHERICAL, spherical);
-
- return (MRESULT) 0;
- case WM_COMMAND :
- switch(SHORT1FROMMP(mp1))
- {
- case DID_OK:
- WinQueryDlgItemText(hwndSettings, DLG_SPHERERAD, 20, radiusstr);
- sphererad = atof(radiusstr);
- sphere_covers_180 = WinQueryButtonCheckstate(hwndSettings, DLG_180);
- spherical = WinQueryButtonCheckstate(hwndSettings, DLG_SPHERICAL);
- return 0;
- case DID_CANCEL :
- return 0;
- }
- break;
-
- default :
- break;
- }
- mp2; // not referenced
- return (MRESULT) 0;
- }
-
- /*+--------------------------------------------------------------------------+*/
- /*| SettingsDlg - Main Settings dialog procedure |*/
- /*+--------------------------------------------------------------------------+*/
-
- static MRESULT EXPENTRY SettingsDlg(HWND hwndSettings, ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- int
- corner; //corners of zoom box. there are 8 in 3-d space
- double
- xpc,
- ypc,
- zpc,
- znc,
- zxc; // stuff to rotate the zoom box if 3-D
-
- switch(msg)
-
- {
- case WM_INITDLG:
- BasicSettingsDlg(hwndSettings, msg, mp1, mp2);
- AdvancedSettingsDlg(hwndSettings, msg, mp1, mp2);
- SpecialSettingsDlg(hwndSettings, msg, mp1, mp2);
- break;
-
- case WM_COMMAND:
- switch( SHORT1FROMMP( mp1 ) ) // Extract the command value
- {
- case DID_OK:
- BasicSettingsDlg(hwndSettings, msg, mp1, mp2);
- AdvancedSettingsDlg(hwndSettings, msg, mp1, mp2);
- SpecialSettingsDlg(hwndSettings, msg, mp1, mp2);
- if (three_d) { // rotate the zoom box
- sa = sin(alpha*rpd);
- ca = cos(alpha*rpd);
- sb = sin(beta*rpd);
- cb = cos(beta*rpd);
- sp = sin(phi*rpd);
- cp = cos(phi*rpd);
- if (!spherical) {
- xlp = 1.0e7;
- xrp = -xlp;
- ybp = xlp;
- ytp = xrp;
- znc = 0.0; // min y
- if (usepotential) {
- //zxc = potential/maxheight; // Oh boy, need to estimate this
- zxc = 2.0*bailout/maxheight;
- }
- else
- zxc = (double) maxcolor1/maxheight;
- zbp = xlp;
- ztp = -zbp;
- for (corner=1; corner<=8; corner++) {
- switch (corner) // go through 8 corners of 3-d zoom box
- {
- case 1:
- rotpoint(xlv, ybv, znc, &xpc, &ypc, &zpc);
- break;
- case 2:
- rotpoint(xlv, ybv, zxc, &xpc, &ypc, &zpc);
- break;
- case 3:
- rotpoint(xrv, ybv, zxc, &xpc, &ypc, &zpc);
- break;
- case 4:
- rotpoint(xrv, ybv, znc, &xpc, &ypc, &zpc);
- break;
- case 5:
- rotpoint(xlv, ytv, znc, &xpc, &ypc, &zpc);
- break;
- case 6:
- rotpoint(xlv, ytv, zxc, &xpc, &ypc, &zpc);
- break;
- case 7:
- rotpoint(xrv, ytv, zxc, &xpc, &ypc, &zpc);
- break;
- case 8:
- rotpoint(xrv, ytv, znc, &xpc, &ypc, &zpc);
- default :
- break;
- } // end switch
- xlp = min(xlp, xpc);
- xrp = max(xrp, xpc);
- ybp = min(ybp, ypc);
- ytp = max(ytp, ypc);
- zbp = min(zbp, zpc);
- ztp = max(ztp, zpc);
- } // end for
- dxvp = xrp - xlp; // we now have the top, bottom, left, right pts
- dyvp = ytp - ybp; // of the rotated zoom box. Get lengths
- dzvp = ztp - zbp;
- //iy = 0; // need a re-draw or ray-trace won't work
- //memset(pBitmap, 0, databytes);
- } // end (!spherical)
- else // it is spherical
- {
- dxv = xrv - xlv;
- sphererad = dxv/(2.0*pi); // dxv is the circumference
- if (sphere_covers_180)
- sphererad *= 2.0;
- ybps = -1.3*sphererad; // arbitrarily add 30 percent margin
- ytps = 1.3*sphererad;
- zbps = ybps;
- ztps = ytps;
- dyvps = ytps - ybps;
- dzvps = ztps - zbps;
- // now make the sphere round
- dxvps = dyvps * rmaxxp/rmaxyp;
- xrps = dxvps/2.0;
- xlps = -xrps;
- //iy = 0; // re-draw
- //memset(pBitmap, 0, databytes); don't think I like this
- } // end else (spherical)
- } // end if 3-d
- WinDismissDlg(hwndSettings, TRUE);
- return 0;
- case DID_CANCEL:
- WinDismissDlg(hwndSettings, TRUE);
- return 0;
- default :
- break;
- }
-
- default:
- return WinDefDlgProc(hwndSettings, msg, mp1, mp2);
- }
- return (MRESULT) 0;
- }
-
-
- /*+--------------------------------------------------------------------------+*/
- /*| HelpDlgProc - Help Dialog Procedure |*/
- /*+--------------------------------------------------------------------------+*/
-
- static MRESULT EXPENTRY HelpDlgProc( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2 )
- {
- switch( msg )
- {
- case WM_COMMAND:
- switch( SHORT1FROMMP( mp1 ) ) /* Extract the command value */
- {
- case DID_OK: /* The Enter pushbutton or key */
- WinDismissDlg( hwndDlg, TRUE );
- break;
-
- default:
- break;
- }
- break;
-
- default:
- return WinDefDlgProc( hwndDlg, msg, mp1, mp2 );
- }
- return NULL;
- }
-
-
- /*+--------------------------------------------------------------------------+*/
- /*| DisplayMessage - display an error message in a message box. |*/
- /*+--------------------------------------------------------------------------+*/
-
- static void DisplayMessage( HAB hab, ULONG ulStringNum )
- {
- char szTemp[ STRING_LENGTH ];
-
- WinLoadString( hab, 0UL, ulStringNum, STRING_LENGTH, szTemp );
-
- WinAlarm( HWND_DESKTOP, /* desktop window handle */
- WA_ERROR ); /* type of alarm */
-
- WinMessageBox( HWND_DESKTOP, /* parent window handle */
- HWND_DESKTOP, /* owner window handle */
- szTemp, /* pointer to message text */
- szAppName, /* pointer to title text */
- MSG_BOX_ID, /* message box identifier */
- MB_OK | MB_ERROR | /* message box style */
- MB_SYSTEMMODAL );
-
- return;
- }
-